📄 pidl.c
字号:
_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 + -