⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pidl.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
        _ILSimpleGetText(pChild, szData2, MAX_PATH);

        if (strcasecmp( szData1, szData2 ))
            return FALSE;

        pParent = ILGetNext(pParent);
        pChild = ILGetNext(pChild);
    }

    /* child shorter or has equal length to parent */
    if (pParent->mkid.cb || !pChild->mkid.cb)
        return FALSE;

    /* not immediate descent */
    if ( ILGetNext(pChild)->mkid.cb && bImmediate)
        return FALSE;

    return TRUE;
}

/*************************************************************************
 * ILFindChild               [SHELL32.24]
 *
 *  Compares elements from pidl1 and pidl2.
 *
 * PARAMS
 *  pidl1      [I]
 *  pidl2      [I]
 *
 * RETURNS
 *  pidl1 is desktop      pidl2
 *  pidl1 shorter pidl2   pointer to first different element of pidl2
 *                        if there was at least one equal element
 *  pidl2 shorter pidl1   0
 *  pidl2 equal pidl1     pointer to last 0x00-element of pidl2
 *
 * NOTES
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
    char    szData1[MAX_PATH];
    char    szData2[MAX_PATH];

    LPCITEMIDLIST pidltemp1 = pidl1;
    LPCITEMIDLIST pidltemp2 = pidl2;
    LPCITEMIDLIST ret=NULL;

    TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);

    /* explorer reads from registry directly (StreamMRU),
       so we can only check here */
    if ((!pcheck (pidl1)) || (!pcheck (pidl2)))
        return FALSE;

    pdump (pidl1);
    pdump (pidl2);

    if (_ILIsDesktop(pidl1))
    {
        ret = pidl2;
    }
    else
    {
        while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
        {
            _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
            _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);

            if (strcasecmp(szData1,szData2))
                break;

            pidltemp1 = ILGetNext(pidltemp1);
            pidltemp2 = ILGetNext(pidltemp2);
            ret = pidltemp2;
        }

        if (pidltemp1->mkid.cb)
            ret = NULL; /* elements of pidl1 left*/
    }
    TRACE_(shell)("--- %p\n", ret);
    return (LPITEMIDLIST)ret; /* pidl 1 is shorter */
}

/*************************************************************************
 * ILCombine                 [SHELL32.25]
 *
 * Concatenates two complex ItemIDLists.
 *
 * PARAMS
 *  pidl1      [I]   first complex ItemIDLists
 *  pidl2      [I]   complex ItemIDLists to append
 *
 * RETURNS
 *  if both pidl's == NULL      NULL
 *  if pidl1 == NULL            cloned pidl2
 *  if pidl2 == NULL            cloned pidl1
 *  otherwise new pidl with pidl2 appended to pidl1
 *
 * NOTES
 *  exported by ordinal.
 *  Does not destroy the passed in ItemIDLists!
 */
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
    DWORD    len1,len2;
    LPITEMIDLIST  pidlNew;

    TRACE("pidl=%p pidl=%p\n",pidl1,pidl2);

    if (!pidl1 && !pidl2) return NULL;

    pdump (pidl1);
    pdump (pidl2);

    if (!pidl1)
    {
        pidlNew = ILClone(pidl2);
        return pidlNew;
    }

    if (!pidl2)
    {
        pidlNew = ILClone(pidl1);
        return pidlNew;
    }

    len1  = ILGetSize(pidl1)-2;
    len2  = ILGetSize(pidl2);
    pidlNew  = SHAlloc(len1+len2);

    if (pidlNew)
    {
        memcpy(pidlNew,pidl1,len1);
        memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
    }

    /*  TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
    return pidlNew;
}

/*************************************************************************
 *  SHGetRealIDL [SHELL32.98]
 *
 * NOTES
 */
HRESULT WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPCITEMIDLIST pidlSimple, LPITEMIDLIST *pidlReal)
{
    IDataObject* pDataObj;
    HRESULT hr;

    hr = IShellFolder_GetUIObjectOf(lpsf, 0, 1, &pidlSimple,
                             &IID_IDataObject, 0, (LPVOID*)&pDataObj);
    if (SUCCEEDED(hr))
    {
        STGMEDIUM medium;
        FORMATETC fmt;

        fmt.cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
        fmt.ptd = NULL;
        fmt.dwAspect = DVASPECT_CONTENT;
        fmt.lindex = -1;
        fmt.tymed = TYMED_HGLOBAL;

        hr = IDataObject_GetData(pDataObj, &fmt, &medium);

        IDataObject_Release(pDataObj);

        if (SUCCEEDED(hr))
        {
            /*assert(pida->cidl==1);*/
            LPIDA pida = (LPIDA)GlobalLock(medium.u.hGlobal);

            LPCITEMIDLIST pidl_folder = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
            LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);

            *pidlReal = ILCombine(pidl_folder, pidl_child);

            if (!*pidlReal)
                hr = E_OUTOFMEMORY;

            GlobalUnlock(medium.u.hGlobal);
            GlobalFree(medium.u.hGlobal);
        }
    }

    return hr;
}

/*************************************************************************
 *  SHLogILFromFSIL [SHELL32.95]
 *
 * NOTES
 *  pild = CSIDL_DESKTOP    ret = 0
 *  pild = CSIDL_DRIVES     ret = 0
 */
LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
{
    FIXME("(pidl=%p)\n",pidl);

    pdump(pidl);

    return 0;
}

/*************************************************************************
 * ILGetSize                 [SHELL32.152]
 *
 * Gets the byte size of an ItemIDList including zero terminator
 *
 * PARAMS
 *  pidl       [I]   ItemIDList
 *
 * RETURNS
 *  size of pidl in bytes
 *
 * NOTES
 *  exported by ordinal
 */
UINT WINAPI ILGetSize(LPCITEMIDLIST pidl)
{
    LPCSHITEMID si = &(pidl->mkid);
    UINT len=0;

    if (pidl)
    {
        while (si->cb)
        {
            len += si->cb;
            si  = (LPCSHITEMID)(((const BYTE*)si)+si->cb);
        }
        len += 2;
    }
    TRACE("pidl=%p size=%u\n",pidl, len);
    return len;
}

/*************************************************************************
 * ILGetNext                 [SHELL32.153]
 *
 * Gets the next ItemID of an ItemIDList
 *
 * PARAMS
 *  pidl       [I]   ItemIDList
 *
 * RETURNS
 *  null -> null
 *  desktop -> null
 *  simple pidl -> pointer to 0x0000 element
 *
 * NOTES
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
{
    WORD len;

    TRACE("%p\n", pidl);

    if (pidl)
    {
        len =  pidl->mkid.cb;
        if (len)
        {
            pidl = (LPCITEMIDLIST) (((const BYTE*)pidl)+len);
            TRACE("-- %p\n", pidl);
            return (LPITEMIDLIST)pidl;
        }
    }
    return NULL;
}

/*************************************************************************
 * ILAppend                  [SHELL32.154]
 *
 * Adds the single ItemID item to the ItemIDList indicated by pidl.
 * If bEnd is FALSE, inserts the item in the front of the list,
 * otherwise it adds the item to the end. (???)
 *
 * PARAMS
 *  pidl       [I]   ItemIDList to extend
 *  item       [I]   ItemID to prepend/append
 *  bEnd       [I]   Indicates if the item should be appended
 *
 * NOTES
 *  Destroys the passed in idlist! (???)
 */
LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl, LPCITEMIDLIST item, BOOL bEnd)
{
    LPITEMIDLIST idlRet;

    WARN("(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd);

    pdump (pidl);
    pdump (item);

    if (_ILIsDesktop(pidl))
    {
        idlRet = ILClone(item);
        if (pidl)
            SHFree (pidl);
        return idlRet;
    }

    if (bEnd)
        idlRet = ILCombine(pidl, item);
    else
        idlRet = ILCombine(item, pidl);

    SHFree(pidl);
    return idlRet;
}

/*************************************************************************
 * ILFree                    [SHELL32.155]
 *
 * Frees memory (if not NULL) allocated by SHMalloc allocator
 *
 * PARAMS
 *  pidl         [I]
 *
 * RETURNS
 *  Nothing
 *
 * NOTES
 *  exported by ordinal
 */
void WINAPI ILFree(LPITEMIDLIST pidl)
{
    TRACE("(pidl=%p)\n",pidl);
    if (pidl)
        SHFree(pidl);
}

/*************************************************************************
 * ILGlobalFree              [SHELL32.156]
 *
 * Frees memory (if not NULL) allocated by Alloc allocator
 *
 * PARAMS
 *  pidl         [I]
 *
 * RETURNS
 *  Nothing
 *
 * NOTES
 *  exported by ordinal.
 */
void WINAPI ILGlobalFree( LPITEMIDLIST pidl)
{
    TRACE("%p\n", pidl);

    if (pidl)
        Free(pidl);
}

/*************************************************************************
 * ILCreateFromPathA         [SHELL32.189]
 *
 * Creates a complex ItemIDList from a path and returns it.
 *
 * PARAMS
 *  path         [I]
 *
 * RETURNS
 *  the newly created complex ItemIDList or NULL if failed
 *
 * NOTES
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI ILCreateFromPathA (LPCSTR path)
{
    LPITEMIDLIST pidlnew = NULL;

    TRACE_(shell)("%s\n", debugstr_a(path));

    if (SUCCEEDED(SHILCreateFromPathA(path, &pidlnew, NULL)))
        return pidlnew;
    return NULL;
}

/*************************************************************************
 * ILCreateFromPathW         [SHELL32.190]
 *
 * See ILCreateFromPathA.
 */
LPITEMIDLIST WINAPI ILCreateFromPathW (LPCWSTR path)
{
    LPITEMIDLIST pidlnew = NULL;

    TRACE_(shell)("%s\n", debugstr_w(path));

    if (SUCCEEDED(SHILCreateFromPathW(path, &pidlnew, NULL)))
        return pidlnew;
    return NULL;
}

/*************************************************************************
 * ILCreateFromPath          [SHELL32.157]
 */
LPITEMIDLIST WINAPI ILCreateFromPathAW (LPCVOID path)
{
    if ( SHELL_OsIsUnicode())
        return ILCreateFromPathW (path);
    return ILCreateFromPathA (path);
}

/*************************************************************************
 * _ILParsePathW             [internal]
 *
 * Creates an ItemIDList from a path and returns it.
 *
 * PARAMS
 *  path         [I]   path to parse and convert into an ItemIDList
 *  lpFindFile   [I]   pointer to buffer to initialize the FileSystem
 *                     Bind Data object with
 *  bBindCtx     [I]   indicates to create a BindContext and assign a
 *                     FileSystem Bind Data object
 *  ppidl        [O]   the newly create ItemIDList
 *  prgfInOut    [I/O] requested attributes on input and actual
 *                     attributes on return
 *
 * RETURNS
 *  NO_ERROR on success or an OLE error code
 *
 * NOTES
 *  If either lpFindFile is non-NULL or bBindCtx is TRUE, this function
 *  creates a BindContext object and assigns a FileSystem Bind Data object
 *  to it, passing the BindContext to IShellFolder_ParseDisplayName. Each
 *  IShellFolder uses that FileSystem Bind Data object of the BindContext
 *  to pass data about the current path element to the next object. This
 *  is used to avoid having to verify the current path element on disk, so
 *  that creating an ItemIDList from a nonexistent path still can work.
 */
static HRESULT WINAPI _ILParsePathW(LPCWSTR path, LPWIN32_FIND_DATAW lpFindFile,
                             BOOL bBindCtx, LPITEMIDLIST *ppidl, LPDWORD prgfInOut)
{
    LPSHELLFOLDER pSF = NULL;
    LPBC pBC = NULL;
    HRESULT ret;

    TRACE("%s %p %d (%p)->%p (%p)->0x%lx\n", debugstr_w(path), lpFindFile, bBindCtx,
                                             ppidl, ppidl ? *ppidl : NULL,
                                             prgfInOut, prgfInOut ? *prgfInOut : 0);

    ret = SHGetDesktopFolder(&pSF);
    if (FAILED(ret))
        return ret;

    if (lpFindFile || bBindCtx)
        ret = IFileSystemBindData_Constructor(lpFindFile, &pBC);

    if (SUCCEEDED(ret))
    {
        ret = IShellFolder_ParseDisplayName(pSF, 0, pBC, (LPOLESTR)path, NULL, ppidl, prgfInOut);
    }

    if (pBC)
    {
        IBindCtx_Release(pBC);
        pBC = NULL;
    }

    IShellFolder_Release(pSF);

    if (!SUCCEEDED(ret) && ppidl)
        *ppidl = NULL;

    TRACE("%s %p 0x%lx\n", debugstr_w(path), ppidl ? *ppidl : NULL, prgfInOut ? *prgfInOut : 0);

    return ret;
}

/*************************************************************************
 * SHSimpleIDListFromPath    [SHELL32.162]
 *
 * Creates a simple ItemIDList from a path and returns it. This function
 * does not fail on nonexistent paths.
 *
 * PARAMS
 *  path         [I]   path to parse and convert into an ItemIDList
 *
 * RETURNS
 *  the newly created simple ItemIDList
 *
 * NOTES
 *  Simple in the name does not mean a relative ItemIDList but rather a
 *  fully qualified list, where only the file name is filled in and the
 *  directory flag for those ItemID elements this is known about, eg.
 *  it is not the last element in the ItemIDList or the actual directory
 *  exists on disk.
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI SHSimpleIDListFromPathA(LPCSTR lpszPath)
{
    LPITEMIDLIST pidl = NULL;
    LPWSTR wPath = NULL;
    int len;

    TRACE("%s\n", debugstr_a(lpszPath));

    if (lpszPath)
    {
        len = MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, NULL, 0);
        wPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, wPath, len);
    }

    _ILParsePathW(wPath, NULL, TRUE, &pidl, NULL);

    HeapFree(GetProcessHeap(), 0, wPath);
    TRACE("%s %p\n", debugstr_a(lpszPath), pidl);
    return pidl;
}

LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR lpszPath)
{
    LPITEMIDLIST pidl = NULL;

    TRACE("%s\n", debugstr_w(lpszPath));

    _ILParsePathW(lpszPath, NULL, TRUE, &pidl, NULL);
    TRACE("%s %p\n", debugstr_w(lpszPath), pidl);
    return pidl;
}

LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW(LPCVOID lpszPath)
{
    if ( SHELL_OsIsUnicode())
        return SHSimpleIDListFromPathW (lpszPath);
    return SHSimpleIDListFromPathA (lpszPath);
}

/*************************************************************************
 * SHGetDataFromIDListA [SHELL32.247]
 *
 * NOTES
 *  the pidl can be a simple one. since we can't get the path out of the pidl
 *  we have to take all data from the pidl
 */
HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl,
                                    int nFormat, LPVOID dest, int len)
{
    LPSTR filename, shortname;
    WIN32_FIND_DATAA * pfd;

    TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);

    pdump(pidl);
    if (!psf || !dest)
        return E_INVALIDARG;

    switch (nFormat)
    {
    case SHGDFIL_FINDDATA:
        pfd = dest;

        if (_ILIsDrive(pidl) || _ILIsSpecialFolder(pidl))
            return E_INVALIDARG;

        if (len < sizeof(WIN32_FIND_DATAA))
            return E_INVALIDARG;

        ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
        _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
        pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -