📄 pidl.c
字号:
pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
filename = _ILGetTextPointer(pidl);
shortname = _ILGetSTextPointer(pidl);
if (filename)
lstrcpynA(pfd->cFileName, filename, MAX_PATH);
else
pfd->cFileName[0] = '\0';
if (shortname)
lstrcpynA(pfd->cAlternateFileName, shortname, MAX_PATH);
else
pfd->cAlternateFileName[0] = '\0';
return NOERROR;
case SHGDFIL_NETRESOURCE:
case SHGDFIL_DESCRIPTIONID:
FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
break;
default:
ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
}
return E_INVALIDARG;
}
/*************************************************************************
* SHGetDataFromIDListW [SHELL32.248]
*
*/
HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl,
int nFormat, LPVOID dest, int len)
{
LPSTR filename, shortname;
WIN32_FIND_DATAW * pfd = dest;
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))
return E_INVALIDARG;
if (len < sizeof(WIN32_FIND_DATAW))
return E_INVALIDARG;
ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
_ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
filename = _ILGetTextPointer(pidl);
shortname = _ILGetSTextPointer(pidl);
if (!filename)
pfd->cFileName[0] = '\0';
else if (!MultiByteToWideChar(CP_ACP, 0, filename, -1, pfd->cFileName, MAX_PATH))
pfd->cFileName[MAX_PATH-1] = 0;
if (!shortname)
pfd->cAlternateFileName[0] = '\0';
else if (!MultiByteToWideChar(CP_ACP, 0, shortname, -1, pfd->cAlternateFileName, 14))
pfd->cAlternateFileName[13] = 0;
return NOERROR;
case SHGDFIL_NETRESOURCE:
case SHGDFIL_DESCRIPTIONID:
FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
break;
default:
ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
}
return E_INVALIDARG;
}
/*************************************************************************
* SHGetPathFromIDListA [SHELL32.@][NT 4.0: SHELL32.220]
*
* PARAMETERS
* pidl, [IN] pidl
* pszPath [OUT] path
*
* RETURNS
* path from a passed PIDL.
*
* NOTES
* NULL returns FALSE
* desktop pidl gives path to desktop directory back
* special pidls returning FALSE
*/
BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
{
WCHAR wszPath[MAX_PATH];
BOOL bSuccess;
bSuccess = SHGetPathFromIDListW(pidl, wszPath);
if (bSuccess)
WideCharToMultiByte(CP_ACP, 0, wszPath, -1, pszPath, MAX_PATH, NULL, NULL);
return bSuccess;
}
/*************************************************************************
* SHGetPathFromIDListW [SHELL32.@]
*
* See SHGetPathFromIDListA.
*/
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
{
HRESULT hr;
LPCITEMIDLIST pidlLast;
LPSHELLFOLDER psfFolder;
DWORD dwAttributes;
STRRET strret;
TRACE_(shell)("(pidl=%p,%p)\n", pidl, debugstr_w(pszPath));
pdump(pidl);
if (!pidl)
return FALSE;
hr = SHBindToParent(pidl, &IID_IShellFolder, (VOID**)&psfFolder, &pidlLast);
if (FAILED(hr)) return FALSE;
dwAttributes = SFGAO_FILESYSTEM;
hr = IShellFolder_GetAttributesOf(psfFolder, 1, &pidlLast, &dwAttributes);
if (FAILED(hr) || !(dwAttributes & SFGAO_FILESYSTEM)) {
IShellFolder_Release(psfFolder);
return FALSE;
}
hr = IShellFolder_GetDisplayNameOf(psfFolder, pidlLast, SHGDN_FORPARSING, &strret);
IShellFolder_Release(psfFolder);
if (FAILED(hr)) return FALSE;
hr = StrRetToBufW(&strret, pidlLast, pszPath, MAX_PATH);
TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr);
return SUCCEEDED(hr);
}
/*************************************************************************
* SHBindToParent [shell version 5.0]
*/
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
{
IShellFolder * psfDesktop;
HRESULT hr=E_FAIL;
TRACE_(shell)("pidl=%p\n", pidl);
pdump(pidl);
if (!pidl || !ppv)
return E_INVALIDARG;
*ppv = NULL;
if (ppidlLast)
*ppidlLast = NULL;
hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED(hr))
return hr;
if (_ILIsPidlSimple(pidl))
{
/* we are on desktop level */
hr = IShellFolder_QueryInterface(psfDesktop, riid, ppv);
}
else
{
LPITEMIDLIST pidlParent = ILClone(pidl);
ILRemoveLastID(pidlParent);
hr = IShellFolder_BindToObject(psfDesktop, pidlParent, NULL, riid, ppv);
SHFree (pidlParent);
}
IShellFolder_Release(psfDesktop);
if (SUCCEEDED(hr) && ppidlLast)
*ppidlLast = ILFindLastID(pidl);
TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
return hr;
}
/**************************************************************************
*
* internal functions
*
* ### 1. section creating pidls ###
*
*************************************************************************
*/
LPITEMIDLIST _ILAlloc(PIDLTYPE type, unsigned int size)
{
LPITEMIDLIST pidlOut = NULL;
pidlOut = SHAlloc(size + 5);
if(pidlOut)
{
LPPIDLDATA pData;
LPITEMIDLIST pidlNext;
ZeroMemory(pidlOut, size + 5);
pidlOut->mkid.cb = size + 3;
pData = _ILGetDataPointer(pidlOut);
if (pData)
pData->type = type;
pidlNext = ILGetNext(pidlOut);
if (pidlNext)
pidlNext->mkid.cb = 0x00;
TRACE("-- (pidl=%p, size=%u)\n", pidlOut, size);
}
return pidlOut;
}
LPITEMIDLIST _ILCreateDesktop()
{
LPITEMIDLIST ret;
TRACE("()\n");
ret = SHAlloc(2);
if (ret)
ret->mkid.cb = 0;
return ret;
}
LPITEMIDLIST _ILCreateMyComputer()
{
TRACE("()\n");
return _ILCreateGuid(PT_GUID, &CLSID_MyComputer);
}
LPITEMIDLIST _ILCreateIExplore()
{
TRACE("()\n");
return _ILCreateGuid(PT_GUID, &CLSID_Internet);
}
LPITEMIDLIST _ILCreateControlPanel()
{
LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL;
TRACE("()\n");
if (parent)
{
LPITEMIDLIST cpl = _ILCreateGuid(PT_SHELLEXT, &CLSID_ControlPanel);
if (cpl)
{
ret = ILCombine(parent, cpl);
SHFree(cpl);
}
SHFree(parent);
}
return ret;
}
LPITEMIDLIST _ILCreatePrinters()
{
LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL;
TRACE("()\n");
if (parent)
{
LPITEMIDLIST printers = _ILCreateGuid(PT_YAGUID, &CLSID_Printers);
if (printers)
{
ret = ILCombine(parent, printers);
SHFree(printers);
}
SHFree(parent);
}
return ret;
}
LPITEMIDLIST _ILCreateNetwork()
{
TRACE("()\n");
return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces);
}
LPITEMIDLIST _ILCreateBitBucket()
{
TRACE("()\n");
return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin);
}
LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid)
{
LPITEMIDLIST pidlOut;
if (type == PT_SHELLEXT || type == PT_GUID || type == PT_YAGUID)
{
pidlOut = _ILAlloc(type, sizeof(GUIDStruct));
if (pidlOut)
{
LPPIDLDATA pData = _ILGetDataPointer(pidlOut);
memcpy(&(pData->u.guid.guid), guid, sizeof(GUID));
TRACE("-- create GUID-pidl %s\n",
debugstr_guid(&(pData->u.guid.guid)));
}
}
else
{
WARN("%d: invalid type for GUID\n", type);
pidlOut = NULL;
}
return pidlOut;
}
LPITEMIDLIST _ILCreateGuidFromStrA(LPCSTR szGUID)
{
IID iid;
if (!SUCCEEDED(SHCLSIDFromStringA(szGUID, &iid)))
{
ERR("%s is not a GUID\n", szGUID);
return NULL;
}
return _ILCreateGuid(PT_GUID, &iid);
}
LPITEMIDLIST _ILCreateGuidFromStrW(LPCWSTR szGUID)
{
IID iid;
if (!SUCCEEDED(SHCLSIDFromStringW(szGUID, &iid)))
{
ERR("%s is not a GUID\n", debugstr_w(szGUID));
return NULL;
}
return _ILCreateGuid(PT_GUID, &iid);
}
LPITEMIDLIST _ILCreateFromFindDataW( WIN32_FIND_DATAW *wfd )
{
/* FIXME: should make unicode PIDLs */
WIN32_FIND_DATAA fda;
memset( &fda, 0, sizeof fda );
fda.dwFileAttributes = wfd->dwFileAttributes;
fda.ftCreationTime = wfd->ftCreationTime;
fda.ftLastAccessTime = wfd->ftLastAccessTime;
fda.ftLastWriteTime = wfd->ftLastWriteTime;
fda.nFileSizeHigh = wfd->nFileSizeHigh;
fda.nFileSizeLow = wfd->nFileSizeLow;
fda.dwReserved0 = wfd->dwReserved0;
fda.dwReserved1 = wfd->dwReserved1;
WideCharToMultiByte( CP_ACP, 0, wfd->cFileName, -1,
fda.cFileName, MAX_PATH, NULL, NULL );
return _ILCreateFromFindDataA( &fda );
}
LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA * stffile )
{
char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
char * pbuff = buff;
size_t len, len1;
LPITEMIDLIST pidl;
PIDLTYPE type;
if (!stffile)
return NULL;
TRACE("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);
/* prepare buffer with both names */
len = strlen (stffile->cFileName) + 1;
memcpy (pbuff, stffile->cFileName, len);
pbuff += len;
len1 = strlen (stffile->cAlternateFileName)+1;
memcpy (pbuff, stffile->cAlternateFileName, len1);
type = (stffile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? PT_FOLDER : PT_VALUE;
/*
* FileStruct already has one byte for the first name, so use len - 1 in
* size calculation
*/
pidl = _ILAlloc(type, sizeof(FileStruct) + (len - 1) + len1);
if (pidl)
{
LPPIDLDATA pData;
LPSTR pszDest;
/* set attributes */
pData = _ILGetDataPointer(pidl);
if (pData)
{
pData->type = type;
FileTimeToDosDateTime( &(stffile->ftLastWriteTime),
&pData->u.file.uFileDate, &pData->u.file.uFileTime);
pData->u.file.dwFileSize = stffile->nFileSizeLow;
pData->u.file.uFileAttribs = (WORD)stffile->dwFileAttributes;
}
pszDest = _ILGetTextPointer(pidl);
if (pszDest)
{
memcpy(pszDest, buff, len + len1);
TRACE("-- create Value: %s\n",debugstr_a(pszDest));
}
}
return pidl;
}
HRESULT _ILCreateFromPathA(LPCSTR szPath, LPITEMIDLIST* ppidl)
{
HANDLE hFile;
WIN32_FIND_DATAA stffile;
if (!ppidl)
return E_INVALIDARG;
hFile = FindFirstFileA(szPath, &stffile);
if (hFile == INVALID_HANDLE_VALUE)
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
FindClose(hFile);
*ppidl = _ILCreateFromFindDataA(&stffile);
return *ppidl ? S_OK : E_OUTOFMEMORY;
}
HRESULT _ILCreateFromPathW(LPCWSTR szPath, LPITEMIDLIST* ppidl)
{
HANDLE hFile;
WIN32_FIND_DATAW stffile;
if (!ppidl)
return E_INVALIDARG;
hFile = FindFirstFileW(szPath, &stffile);
if (hFile == INVALID_HANDLE_VALUE)
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
FindClose(hFile);
*ppidl = _ILCreateFromFindDataW(&stffile);
return *ppidl ? S_OK : E_OUTOFMEMORY;
}
LPITEMIDLIST _ILCreateDrive(LPCWSTR lpszNew)
{
LPITEMIDLIST pidlOut;
TRACE("(%s)\n",debugstr_w(lpszNew));
pidlOut = _ILAlloc(PT_DRIVE, sizeof(DriveStruct));
if (pidlOut)
{
LPSTR pszDest;
pszDest = _ILGetTextPointer(pidlOut);
if (pszDest)
{
strcpy(pszDest, "x:\\");
pszDest[0]=toupperW(lpszNew[0]);
TRACE("-- create Drive: %s\n", debugstr_a(pszDest));
}
}
return pidlOut;
}
/**************************************************************************
* _ILGetDrive()
*
* Gets the text for the drive eg. 'c:\'
*
* RETURNS
* strlen (lpszText)
*/
DWORD _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT uSize)
{
TRACE("(%p,%p,%u)\n",pidl,pOut,uSize);
if(_ILIsMyComputer(pidl))
pidl = ILGetNext(pidl);
if (pidl && _ILIsDrive(pidl))
return _ILSimpleGetText(pidl, pOut, uSize);
return 0;
}
/**************************************************************************
*
* ### 2. section testing pidls ###
*
**************************************************************************
* _ILIsDesktop()
* _ILIsMyComputer()
* _ILIsSpecialFolder()
* _ILIsDrive()
* _ILIsFolder()
* _ILIsValue()
* _ILIsPidlSimple()
*/
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
{
TRACE("(%p)\n",pidl);
return pidl && pidl->mkid.cb ? 0 : 1;
}
BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
{
REFIID iid = _ILGetGUIDPointer(pidl);
TRACE("(%p)\n",pidl);
if (iid)
return IsEqualIID(iid, &CLSID_MyComputer);
return FALSE;
}
BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl)
{
LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
TRACE("(%p)\n",pidl);
return (pidl && ( (lpPData && (PT_GUID== lpPData->type || PT_SHELLEXT== lpPData->type || PT_YAGUID == lpPData->type)) ||
(pidl && pidl->mkid.cb == 0x00)
));
}
BOOL _ILIsDrive(LPCITEMIDLIST pidl)
{
LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
TRACE("(%p)\n",pidl);
return (pidl && lpPData && (PT_DRIVE == lpPData->type ||
PT_DRIVE1 == lpPData->type ||
PT_DRIVE2 == lpPData->type ||
PT_DRIVE3 == lpPData->type));
}
BOOL _ILIsFolder(LPCITEMIDLIST pidl)
{
LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
TRACE("(%p)\n",pidl);
return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -