Author: gadamopoulos Date: Mon Aug 17 11:36:56 2015 New Revision: 68729
URL: http://svn.reactos.org/svn/reactos?rev=68729&view=rev Log: [SHELL32] - Split SHELL32_GetItemAttributes to SHELL32_GetGuidItemAttributes and SHELL32_GetFSItemAttributes. - Add a couple helper functions that will reduce code duplication in folders with reg items: SHELL32_BindToGuidItem, SHELL32_GetDisplayNameOfGUIDItem
Modified: trunk/reactos/dll/win32/shell32/shfldr.h trunk/reactos/dll/win32/shell32/shlfolder.cpp trunk/reactos/dll/win32/shell32/wine/classes.c
Modified: trunk/reactos/dll/win32/shell32/shfldr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr.h?... ============================================================================== --- trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] Mon Aug 17 11:36:56 2015 @@ -52,6 +52,21 @@ HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2); LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
+HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot, + PCUIDLIST_RELATIVE pidl, + LPBC pbcReserved, + REFIID riid, + LPVOID *ppvOut); + +HRESULT SHELL32_GetGuidItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes); + +HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes); + +HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPath, PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet); + +extern "C" +BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey); + static __inline int SHELL32_GUIDToStringA (REFGUID guid, LPSTR str) { return sprintf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
Modified: trunk/reactos/dll/win32/shell32/shlfolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfolder... ============================================================================== --- trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] Mon Aug 17 11:36:56 2015 @@ -330,6 +330,45 @@ return hr; }
+HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot, + PCUIDLIST_RELATIVE pidl, + LPBC pbcReserved, + REFIID riid, + LPVOID *ppvOut) +{ + CComPtr<IPersistFolder> pFolder; + HRESULT hr; + + GUID *pGUID = _ILGetGUIDPointer(pidl); + if (!pGUID) + { + ERR("SHELL32_BindToGuidItem called for non guid item!\n"); + return E_FAIL; + } + + hr = SHCoCreateInstance(NULL, pGUID, NULL, IID_PPV_ARG(IPersistFolder, &pFolder)); + if (FAILED(hr)) + return hr; + + hr = pFolder->Initialize(ILCombine(pidlRoot, pidl)); + if (FAILED(hr)) + return hr; + + if (_ILIsPidlSimple (pidl)) + { + return pFolder->QueryInterface(riid, ppvOut); + } + else + { + CComPtr<IShellFolder> psf; + hr = pFolder->QueryInterface(IID_PPV_ARG(IShellFolder, &psf)); + if (FAILED(hr)) + return hr; + + return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut); + } +} + /*********************************************************************** * SHELL32_GetDisplayNameOfChild * @@ -376,6 +415,85 @@ hr = E_OUTOFMEMORY;
TRACE ("-- ret=0x%08x %s\n", hr, debugstr_w(szOut)); + + return hr; +} + +HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPath, PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) +{ + HRESULT hr = S_OK; + GUID const *clsid = _ILGetGUIDPointer (pidl); + + if (!strRet) + return E_INVALIDARG; + + LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); + if (!pszPath) + return E_OUTOFMEMORY; + + if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING) + { + int bWantsForParsing; + + /* + * We can only get a filesystem path from a shellfolder if the + * value WantsFORPARSING in CLSID\{...}\shellfolder exists. + * + * Exception: The MyComputer folder doesn't have this key, + * but any other filesystem backed folder it needs it. + */ + if (IsEqualIID (*clsid, CLSID_MyComputer)) + { + bWantsForParsing = TRUE; + } + else + { + HKEY hkeyClass; + if (HCR_RegOpenClassIDKey(*clsid, &hkeyClass)) + { + LONG res = SHGetValueW(hkeyClass, L"Shellfolder", L"WantsForParsing", NULL, NULL, NULL); + bWantsForParsing = (res == ERROR_SUCCESS); + RegCloseKey(hkeyClass); + } + } + + if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && + bWantsForParsing) + { + /* + * we need the filesystem path to the destination folder. + * Only the folder itself can know it + */ + hr = SHELL32_GetDisplayNameOfChild (psf, pidl, dwFlags, + pszPath, + MAX_PATH); + } + else + { + wcscpy(pszPath, pszFolderPath); + PWCHAR pItemName = &pszPath[wcslen(pszPath)]; + + /* parsing name like ::{...} */ + pItemName[0] = ':'; + pItemName[1] = ':'; + SHELL32_GUIDToStringW (*clsid, &pItemName[2]); + } + } + else + { + /* user friendly name */ + HCR_GetClassNameW (*clsid, pszPath, MAX_PATH); + } + + if (SUCCEEDED(hr)) + { + strRet->uType = STRRET_WSTR; + strRet->pOleStr = pszPath; + } + else + { + CoTaskMemFree(pszPath); + }
return hr; } @@ -399,27 +517,31 @@ * According to the MSDN documentation this function should not set flags. It claims only to reset flags when necessary. * However it turns out the native shell32.dll _sets_ flags in several cases - so do we. */ -HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) -{ - DWORD dwAttributes; - BOOL has_guid; - static const DWORD dwSupportedAttr= - SFGAO_CANCOPY | /*0x00000001 */ - SFGAO_CANMOVE | /*0x00000002 */ - SFGAO_CANLINK | /*0x00000004 */ - SFGAO_CANRENAME | /*0x00000010 */ - SFGAO_CANDELETE | /*0x00000020 */ - SFGAO_HASPROPSHEET | /*0x00000040 */ - SFGAO_DROPTARGET | /*0x00000100 */ - SFGAO_LINK | /*0x00010000 */ - SFGAO_READONLY | /*0x00040000 */ - SFGAO_HIDDEN | /*0x00080000 */ - SFGAO_FILESYSANCESTOR | /*0x10000000 */ - SFGAO_FOLDER | /*0x20000000 */ - SFGAO_FILESYSTEM | /*0x40000000 */ - SFGAO_HASSUBFOLDER; /*0x80000000 */ - - TRACE ("0x%08x\n", *pdwAttributes); + +static const DWORD dwSupportedAttr= + SFGAO_CANCOPY | /*0x00000001 */ + SFGAO_CANMOVE | /*0x00000002 */ + SFGAO_CANLINK | /*0x00000004 */ + SFGAO_CANRENAME | /*0x00000010 */ + SFGAO_CANDELETE | /*0x00000020 */ + SFGAO_HASPROPSHEET | /*0x00000040 */ + SFGAO_DROPTARGET | /*0x00000100 */ + SFGAO_LINK | /*0x00010000 */ + SFGAO_READONLY | /*0x00040000 */ + SFGAO_HIDDEN | /*0x00080000 */ + SFGAO_FILESYSANCESTOR | /*0x10000000 */ + SFGAO_FOLDER | /*0x20000000 */ + SFGAO_FILESYSTEM | /*0x40000000 */ + SFGAO_HASSUBFOLDER; /*0x80000000 */ + +HRESULT SHELL32_GetGuidItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) +{ + if (!_ILIsSpecialFolder(pidl)) + { + ERR("Got wrong type of pidl!\n"); + *pdwAttributes &= SFGAO_CANLINK; + return S_OK; + }
if (*pdwAttributes & ~dwSupportedAttr) { @@ -427,79 +549,114 @@ *pdwAttributes &= dwSupportedAttr; }
- has_guid = _ILGetGUIDPointer(pidl) != NULL; - - dwAttributes = *pdwAttributes; - - if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) - *pdwAttributes = dwAttributes; - else if (_ILGetDataPointer(pidl)) - { - dwAttributes = _ILGetFileAttributes(pidl, NULL, 0); - - if (!dwAttributes && has_guid) - { - WCHAR path[MAX_PATH]; - STRRET strret; - - /* File attributes are not present in the internal PIDL structure, so get them from the file system. */ - - HRESULT hr = psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret); - - if (SUCCEEDED(hr)) + /* First try to get them from the registry */ + if (HCR_GetFolderAttributes(pidl, pdwAttributes) && *pdwAttributes) + { + return S_OK; + } + else + { + /* If we can't get it from the registry we have to query the child */ + CComPtr<IShellFolder> psf2; + if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2)))) + { + return psf2->GetAttributesOf(0, NULL, pdwAttributes); + } + } + + *pdwAttributes &= SFGAO_CANLINK; + return S_OK; +} + +HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) +{ + DWORD dwAttributes; + + if (*pdwAttributes & ~dwSupportedAttr) + { + WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr)); + *pdwAttributes &= dwSupportedAttr; + } + + dwAttributes = _ILGetFileAttributes(pidl, NULL, 0); + if (!dwAttributes) + { + ERR("Got 0 attrs!\n"); + *pdwAttributes &= SFGAO_CANLINK; + return S_OK; + } + + /* Set common attributes */ + *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | + SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY; + + if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + *pdwAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); + } + else + *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); + + if (dwAttributes & FILE_ATTRIBUTE_HIDDEN) + *pdwAttributes |= SFGAO_HIDDEN; + else + *pdwAttributes &= ~SFGAO_HIDDEN; + + if (dwAttributes & FILE_ATTRIBUTE_READONLY) + *pdwAttributes |= SFGAO_READONLY; + else + *pdwAttributes &= ~SFGAO_READONLY; + + if (SFGAO_LINK & *pdwAttributes) + { + char ext[MAX_PATH]; + + if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk")) + *pdwAttributes &= ~SFGAO_LINK; + } + + if (SFGAO_HASSUBFOLDER & *pdwAttributes) + { + CComPtr<IShellFolder> psf2; + if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2)))) + { + CComPtr<IEnumIDList> pEnumIL; + if (SUCCEEDED(psf2->EnumObjects(0, SHCONTF_FOLDERS, &pEnumIL))) { - hr = StrRetToBufW(&strret, pidl, path, MAX_PATH); - - /* call GetFileAttributes() only for file system paths, not for parsing names like "::{...}" */ - if (SUCCEEDED(hr) && path[0]!=':') - dwAttributes = GetFileAttributesW(path); + if (pEnumIL->Skip(1) != S_OK) + *pdwAttributes &= ~SFGAO_HASSUBFOLDER; } } - + } + + TRACE ("-- 0x%08x\n", *pdwAttributes); + return S_OK; +} + +HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) +{ + TRACE ("0x%08x\n", *pdwAttributes); + + if (*pdwAttributes & ~dwSupportedAttr) + { + WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr)); + *pdwAttributes &= dwSupportedAttr; + } + + if (_ILIsSpecialFolder(pidl)) + { + return SHELL32_GetGuidItemAttributes(psf, pidl, pdwAttributes); + } + else if(_ILIsFolder(pidl) || _ILIsValue(pidl)) + { + return SHELL32_GetFSItemAttributes(psf, pidl, pdwAttributes); + } + else + { /* Set common attributes */ - *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | - SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY; - - if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - *pdwAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); - } - else - *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); - - if (dwAttributes & FILE_ATTRIBUTE_HIDDEN) - *pdwAttributes |= SFGAO_HIDDEN; - else - *pdwAttributes &= ~SFGAO_HIDDEN; - - if (dwAttributes & FILE_ATTRIBUTE_READONLY) - *pdwAttributes |= SFGAO_READONLY; - else - *pdwAttributes &= ~SFGAO_READONLY; - - if (SFGAO_LINK & *pdwAttributes) - { - char ext[MAX_PATH]; - - if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk")) - *pdwAttributes &= ~SFGAO_LINK; - } - - if (SFGAO_HASSUBFOLDER & *pdwAttributes) - { - CComPtr<IShellFolder> psf2; - if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2)))) - { - CComPtr<IEnumIDList> pEnumIL; - if (SUCCEEDED(psf2->EnumObjects(0, SHCONTF_FOLDERS, &pEnumIL))) - { - if (pEnumIL->Skip(1) != S_OK) - *pdwAttributes &= ~SFGAO_HASSUBFOLDER; - } - } - } - } else - *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK; + ERR("We got a pidl that is neither a guid or an FS item!!! Type=0x%x\n",pidl->mkid.abID[0]); + *pdwAttributes &= SFGAO_CANLINK; + }
TRACE ("-- 0x%08x\n", *pdwAttributes); return S_OK;
Modified: trunk/reactos/dll/win32/shell32/wine/classes.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/wine/clas... ============================================================================== --- trunk/reactos/dll/win32/shell32/wine/classes.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/wine/classes.c [iso-8859-1] Mon Aug 17 11:36:56 2015 @@ -222,7 +222,7 @@ * * Gets the icon for a filetype */ -static BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey) +BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey) { char xriid[50]; sprintf( xriid, "CLSID\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",