diff --git a/reactos/dll/win32/shell32/folders.cpp b/reactos/dll/win32/shell32/folders.cpp index bde3801dce6..9e5a987ac2b 100644 --- a/reactos/dll/win32/shell32/folders.cpp +++ b/reactos/dll/win32/shell32/folders.cpp @@ -192,88 +192,6 @@ GetIconOverlay(LPCITEMIDLIST pidl, WCHAR * wTemp, int* pIndex) return FALSE; } -HRESULT CGuidItemExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut) -{ - CComPtr initIcon; - HRESULT hr; - GUID const * riid; - int icon_idx; - WCHAR wTemp[MAX_PATH]; - - hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon)); - if (FAILED(hr)) - return hr; - - if (_ILIsDesktop(pidl)) - { - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP); - return initIcon->QueryInterface(iid, ppvOut); - } - - riid = _ILGetGUIDPointer(pidl); - if (!riid) - return E_FAIL; - - /* my computer and other shell extensions */ - static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\', - '{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-', - '%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x', - '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0 - }; - WCHAR xriid[50]; - - swprintf(xriid, fmt, - riid->Data1, riid->Data2, riid->Data3, - riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], - riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); - - const WCHAR* iconname = NULL; - if (_ILIsBitBucket(pidl)) - { - static const WCHAR szFull[] = {'F','u','l','l',0}; - static const WCHAR szEmpty[] = {'E','m','p','t','y',0}; - CComPtr EnumIDList; - CoInitialize(NULL); - - CComPtr psfRecycleBin; - CComPtr psfDesktop; - hr = SHGetDesktopFolder(&psfDesktop); - - if (SUCCEEDED(hr)) - hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder2, &psfRecycleBin)); - if (SUCCEEDED(hr)) - hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList); - - ULONG itemcount; - LPITEMIDLIST pidl = NULL; - if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK) - { - CoTaskMemFree(pidl); - iconname = szFull; - } else { - iconname = szEmpty; - } - } - - if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx)) - { - initIcon->SetNormalIcon(wTemp, icon_idx); - } - else - { - if (IsEqualGUID(*riid, CLSID_MyComputer)) - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER); - else if (IsEqualGUID(*riid, CLSID_MyDocuments)) - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS); - else if (IsEqualGUID(*riid, CLSID_NetworkPlaces)) - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES); - else - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER); - } - - return initIcon->QueryInterface(iid, ppvOut); -} - HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut) { CComPtr initIcon; diff --git a/reactos/dll/win32/shell32/folders/CRegFolder.cpp b/reactos/dll/win32/shell32/folders/CRegFolder.cpp index 3f431225b1b..5663a581c67 100644 --- a/reactos/dll/win32/shell32/folders/CRegFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CRegFolder.cpp @@ -22,6 +22,88 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell); +HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut) +{ + CComPtr initIcon; + HRESULT hr; + GUID const * riid; + int icon_idx; + WCHAR wTemp[MAX_PATH]; + + hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon)); + if (FAILED(hr)) + return hr; + + if (_ILIsDesktop(pidl)) + { + initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP); + return initIcon->QueryInterface(iid, ppvOut); + } + + riid = _ILGetGUIDPointer(pidl); + if (!riid) + return E_FAIL; + + /* my computer and other shell extensions */ + static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\', + '{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-', + '%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x', + '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0 + }; + WCHAR xriid[50]; + + swprintf(xriid, fmt, + riid->Data1, riid->Data2, riid->Data3, + riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], + riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); + + const WCHAR* iconname = NULL; + if (_ILIsBitBucket(pidl)) + { + static const WCHAR szFull[] = {'F','u','l','l',0}; + static const WCHAR szEmpty[] = {'E','m','p','t','y',0}; + CComPtr EnumIDList; + CoInitialize(NULL); + + CComPtr psfRecycleBin; + CComPtr psfDesktop; + hr = SHGetDesktopFolder(&psfDesktop); + + if (SUCCEEDED(hr)) + hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder2, &psfRecycleBin)); + if (SUCCEEDED(hr)) + hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList); + + ULONG itemcount; + LPITEMIDLIST pidl = NULL; + if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK) + { + CoTaskMemFree(pidl); + iconname = szFull; + } else { + iconname = szEmpty; + } + } + + if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx)) + { + initIcon->SetNormalIcon(wTemp, icon_idx); + } + else + { + if (IsEqualGUID(*riid, CLSID_MyComputer)) + initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER); + else if (IsEqualGUID(*riid, CLSID_MyDocuments)) + initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS); + else if (IsEqualGUID(*riid, CLSID_NetworkPlaces)) + initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES); + else + initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER); + } + + return initIcon->QueryInterface(iid, ppvOut); +} + class CRegFolder : public CComObjectRootEx, public IShellFolder2 @@ -31,6 +113,7 @@ class CRegFolder : CAtlStringW m_rootPath; CComHeapPtr m_pidlRoot; + HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes); public: CRegFolder(); ~CRegFolder(); @@ -90,10 +173,67 @@ HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, return S_OK; } +HRESULT CRegFolder::GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes) +{ + /* 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 psf2; + if (SUCCEEDED(BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2)))) + { + return psf2->GetAttributesOf(0, NULL, pdwAttributes); + } + } + + *pdwAttributes &= SFGAO_CANLINK; + return S_OK; +} + HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes) { - return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes); + LPITEMIDLIST pidl; + + if (!lpszDisplayName || !ppidl) + return E_INVALIDARG; + + *ppidl = 0; + + if (pchEaten) + *pchEaten = 0; + + UINT cch = wcslen(lpszDisplayName); + if (cch < 39 || lpszDisplayName[0] != L':' || lpszDisplayName[1] != L':') + return E_FAIL; + + pidl = _ILCreateGuidFromStrW(lpszDisplayName + 2); + if (pidl == NULL) + return E_FAIL; + + if (cch < 41) + { + *ppidl = pidl; + if (pdwAttributes && *pdwAttributes) + { + GetGuidItemAttributes(*ppidl, pdwAttributes); + } + } + else + { + HRESULT hr = SHELL32_ParseNextElement(this, hwndOwner, pbc, &pidl, lpszDisplayName + 41, pchEaten, pdwAttributes); + if (SUCCEEDED(hr)) + { + *ppidl = pidl; + } + return hr; + } + + return S_OK; } HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) @@ -103,7 +243,39 @@ HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLI HRESULT WINAPI CRegFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) { - return SHELL32_BindToGuidItem(m_pidlRoot, pidl, pbcReserved, riid, ppvOut); + CComPtr pFolder; + HRESULT hr; + + if (!ppvOut || !pidl || !pidl->mkid.cb) + return E_INVALIDARG; + + *ppvOut = NULL; + + GUID *pGUID = _ILGetGUIDPointer(pidl); + if (!pGUID) + { + ERR("CRegFolder::BindToObject called for non guid item!\n"); + return E_INVALIDARG; + } + + LPITEMIDLIST pidlChild = ILCloneFirst (pidl); + if (!pidlChild) + return E_OUTOFMEMORY; + + CComPtr psf; + hr = SHELL32_CoCreateInitSF(m_pidlRoot, NULL, pidlChild, pGUID, -1, IID_PPV_ARG(IShellFolder, &psf)); + ILFree(pidlChild); + if (FAILED(hr)) + return hr; + + if (_ILIsPidlSimple (pidl)) + { + return psf->QueryInterface(riid, ppvOut); + } + else + { + return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut); + } } HRESULT WINAPI CRegFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) @@ -113,7 +285,27 @@ HRESULT WINAPI CRegFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserv HRESULT WINAPI CRegFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) { - return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2); + if (!pidl1 || !pidl2 || pidl1->mkid.cb == 0 || pidl2->mkid.cb == 0) + { + ERR("Got an empty pidl!\n"); + return E_INVALIDARG; + } + + BOOL bIsGuidFolder1 = _ILIsSpecialFolder(pidl1); + BOOL bIsGuidFolder2 = _ILIsSpecialFolder(pidl2); + + if (!bIsGuidFolder1 && !bIsGuidFolder2) + { + ERR("Got no guid pidl!\n"); + return E_INVALIDARG; + } + else if (bIsGuidFolder1 && bIsGuidFolder2) + { + return SHELL32_CompareDetails(this, lParam, pidl1, pidl2); + } + + /* Guid folders come first compared to everything else */ + return MAKE_COMPARE_HRESULT(bIsGuidFolder1 ? -1 : 1); } HRESULT WINAPI CRegFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut) @@ -132,7 +324,7 @@ HRESULT WINAPI CRegFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apid while(cidl > 0 && *apidl) { if (_ILIsSpecialFolder(*apidl)) - SHELL32_GetGuidItemAttributes(this, *apidl, rgfInOut); + GetGuidItemAttributes(*apidl, rgfInOut); else ERR("Got an unkown pidl here!\n"); apidl++; @@ -158,7 +350,7 @@ HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1)) { - hr = CGuidItemExtractIcon_CreateInstance(this, apidl[0], riid, &pObj); + hr = CGuidItemExtractIcon_CreateInstance(apidl[0], riid, &pObj); } else hr = E_NOINTERFACE; @@ -190,20 +382,119 @@ HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, return S_OK; } - if (pidl->mkid.cb) + HRESULT hr; + GUID const *clsid = _ILGetGUIDPointer (pidl); + + /* First of all check if we need to query the name from the child item */ + if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING && + GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) { - return SHELL32_GetDisplayNameOfGUIDItem(this, m_rootPath, pidl, dwFlags, strRet); + int bWantsForParsing = FALSE; + + /* + * 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 (bWantsForParsing) + { + /* + * we need the filesystem path to the destination folder. + * Only the folder itself can know it + */ + return SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags, strRet); + } } - return E_FAIL; + /* Allocate the buffer for the result */ + LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); + if (!pszPath) + return E_OUTOFMEMORY; + + hr = S_OK; + + if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING) + { + wcscpy(pszPath, m_rootPath); + PWCHAR pItemName = &pszPath[wcslen(pszPath)]; + + /* parsing name like ::{...} */ + pItemName[0] = ':'; + pItemName[1] = ':'; + SHELL32_GUIDToStringW (*clsid, &pItemName[2]); + } + else + { + /* user friendly name */ + if (!HCR_GetClassNameW (*clsid, pszPath, MAX_PATH)) + hr = E_FAIL; + } + + if (SUCCEEDED(hr)) + { + strRet->uType = STRRET_WSTR; + strRet->pOleStr = pszPath; + } + else + { + CoTaskMemFree(pszPath); + } + + return hr; } HRESULT WINAPI CRegFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */ LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) { - return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut); + GUID const *clsid = _ILGetGUIDPointer (pidl); + LPOLESTR pStr; + HRESULT hr; + WCHAR szName[100]; + + if (!clsid) + { + ERR("Pidl is not reg item!\n"); + return E_FAIL; + } + + hr = StringFromCLSID(*clsid, &pStr); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr); + + DWORD cbData = (wcslen(lpName) + 1) * sizeof(WCHAR); + LONG res = SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData); + + CoTaskMemFree(pStr); + + if (res == ERROR_SUCCESS) + { + *pPidlOut = ILClone(pidl); + return S_OK; + } + + return E_FAIL; } + HRESULT WINAPI CRegFolder::GetDefaultSearchGUID(GUID *pguid) { return E_NOTIMPL; @@ -242,7 +533,30 @@ HRESULT WINAPI CRegFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHEL if (!psd || iColumn >= 2) return E_INVALIDARG; - return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd); + GUID const *clsid = _ILGetGUIDPointer (pidl); + + if (!clsid) + { + ERR("Pidl is not reg item!\n"); + return E_INVALIDARG; + } + + switch(iColumn) + { + case 0: /* name */ + return GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str); + case 1: /* comment */ + HKEY hKey; + if (HCR_RegOpenClassIDKey(*clsid, &hKey)) + { + psd->str.cStr[0] = 0x00; + psd->str.uType = STRRET_CSTR; + RegLoadMUIStringA(hKey, "InfoTip", psd->str.cStr, MAX_PATH, NULL, 0, NULL); + RegCloseKey(hKey); + return S_OK; + } + } + return E_FAIL; } HRESULT WINAPI CRegFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid) @@ -250,6 +564,7 @@ HRESULT WINAPI CRegFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid) return E_NOTIMPL; } +/* In latest windows version this is exported but it takes different arguments! */ HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv) { return ShellObjectCreatorInit(pGuid, pidlRoot, lpszPath, riid, ppv); diff --git a/reactos/dll/win32/shell32/shfldr.h b/reactos/dll/win32/shell32/shfldr.h index 17953b34591..54ed1b45a2a 100644 --- a/reactos/dll/win32/shell32/shfldr.h +++ b/reactos/dll/win32/shell32/shfldr.h @@ -49,34 +49,10 @@ HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot, 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); - -HRESULT SHELL32_SetNameOfGuidItem(PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut); - -HRESULT SHELL32_GetDetailsOfGuidItem(IShellFolder2* psf, PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd); - -HRESULT SH_ParseGuidDisplayName(IShellFolder2 * pFolder, - HWND hwndOwner, - LPBC pbc, - LPOLESTR lpszDisplayName, - DWORD *pchEaten, - PIDLIST_RELATIVE *ppidl, - DWORD *pdwAttributes); - HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2); -HRESULT SHELL32_CompareGuidItems(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2); - HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot, LPCITEMIDLIST pidlChild, const GUID* clsid, int csidl, REFIID riid, LPVOID *ppvOut); @@ -107,8 +83,6 @@ static __inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str) void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags); BOOL SHELL_FS_HideExtension(LPWSTR pwszPath); -HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv); - #ifdef __cplusplus HRESULT inline SHSetStrRet(LPSTRRET pStrRet, DWORD resId) diff --git a/reactos/dll/win32/shell32/shlfolder.cpp b/reactos/dll/win32/shell32/shlfolder.cpp index 77cdbb5fc1f..b0ac4487348 100644 --- a/reactos/dll/win32/shell32/shlfolder.cpp +++ b/reactos/dll/win32/shell32/shlfolder.cpp @@ -287,47 +287,6 @@ HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot, return hr; } -HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot, - PCUIDLIST_RELATIVE pidl, - LPBC pbcReserved, - REFIID riid, - LPVOID *ppvOut) -{ - CComPtr pFolder; - HRESULT hr; - - if (!pidlRoot || !ppvOut || !pidl || !pidl->mkid.cb) - return E_INVALIDARG; - - *ppvOut = NULL; - - GUID *pGUID = _ILGetGUIDPointer(pidl); - if (!pGUID) - { - ERR("SHELL32_BindToGuidItem called for non guid item!\n"); - return E_INVALIDARG; - } - - LPITEMIDLIST pidlChild = ILCloneFirst (pidl); - if (!pidlChild) - return E_OUTOFMEMORY; - - CComPtr psf; - hr = SHELL32_CoCreateInitSF(pidlRoot, NULL, pidlChild, pGUID, -1, IID_PPV_ARG(IShellFolder, &psf)); - ILFree(pidlChild); - if (FAILED(hr)) - return hr; - - if (_ILIsPidlSimple (pidl)) - { - return psf->QueryInterface(riid, ppvOut); - } - else - { - return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut); - } -} - /*********************************************************************** * SHELL32_GetDisplayNameOfChild * @@ -371,89 +330,6 @@ HRESULT HCR_GetClassName(REFIID riid, LPSTRRET strRet) return SHSetStrRet(strRet, wstrName); } -HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPath, PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) -{ - HRESULT hr; - GUID const *clsid = _ILGetGUIDPointer (pidl); - - if (!strRet) - return E_INVALIDARG; - - /* First of all check if we need to query the name from the child item */ - if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING && - GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) - { - int bWantsForParsing = FALSE; - - /* - * 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 (bWantsForParsing) - { - /* - * we need the filesystem path to the destination folder. - * Only the folder itself can know it - */ - return SHELL32_GetDisplayNameOfChild (psf, pidl, dwFlags, strRet); - } - } - - /* Allocate the buffer for the result */ - LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); - if (!pszPath) - return E_OUTOFMEMORY; - - hr = S_OK; - - if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING) - { - wcscpy(pszPath, pszFolderPath); - PWCHAR pItemName = &pszPath[wcslen(pszPath)]; - - /* parsing name like ::{...} */ - pItemName[0] = ':'; - pItemName[1] = ':'; - SHELL32_GUIDToStringW (*clsid, &pItemName[2]); - } - else - { - /* user friendly name */ - if (!HCR_GetClassNameW (*clsid, pszPath, MAX_PATH)) - hr = E_FAIL; - } - - if (SUCCEEDED(hr)) - { - strRet->uType = STRRET_WSTR; - strRet->pOleStr = pszPath; - } - else - { - CoTaskMemFree(pszPath); - } - - return hr; -} - /*********************************************************************** * SHELL32_GetItemAttributes * @@ -490,40 +366,6 @@ static const DWORD dwSupportedAttr= 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) - { - WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr)); - *pdwAttributes &= dwSupportedAttr; - } - - /* 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 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 dwFileAttributes, dwShellAttributes; @@ -607,139 +449,6 @@ HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST return MAKE_COMPARE_HRESULT(ret); } -HRESULT SHELL32_CompareGuidItems(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) -{ - if (pidl1->mkid.cb == 0 || pidl2->mkid.cb == 0) - { - ERR("Got an empty pidl!\n"); - return E_INVALIDARG; - } - - BOOL bIsGuidFolder1 = _ILIsSpecialFolder(pidl1); - BOOL bIsGuidFolder2 = _ILIsSpecialFolder(pidl2); - - if (!bIsGuidFolder1 && !bIsGuidFolder2) - { - ERR("Got no guid pidl!\n"); - return E_INVALIDARG; - } - else if (bIsGuidFolder1 && bIsGuidFolder2) - { - return SHELL32_CompareDetails(isf, lParam, pidl1, pidl2); - } - - /* Guid folders come first compared to everything else */ - return MAKE_COMPARE_HRESULT(bIsGuidFolder1 ? -1 : 1); -} - -HRESULT SH_ParseGuidDisplayName(IShellFolder2 * pFolder, - HWND hwndOwner, - LPBC pbc, - LPOLESTR lpszDisplayName, - DWORD *pchEaten, - PIDLIST_RELATIVE *ppidl, - DWORD *pdwAttributes) -{ - LPITEMIDLIST pidl; - - if (!lpszDisplayName || !ppidl) - return E_INVALIDARG; - - *ppidl = 0; - - if (pchEaten) - *pchEaten = 0; - - UINT cch = wcslen(lpszDisplayName); - if (cch < 39 || lpszDisplayName[0] != L':' || lpszDisplayName[1] != L':') - return E_FAIL; - - pidl = _ILCreateGuidFromStrW(lpszDisplayName + 2); - if (pidl == NULL) - return E_FAIL; - - if (cch < 41) - { - *ppidl = pidl; - if (pdwAttributes && *pdwAttributes) - { - SHELL32_GetGuidItemAttributes(pFolder, *ppidl, pdwAttributes); - } - } - else - { - HRESULT hr = SHELL32_ParseNextElement(pFolder, hwndOwner, pbc, &pidl, lpszDisplayName + 41, pchEaten, pdwAttributes); - if (SUCCEEDED(hr)) - { - *ppidl = pidl; - } - return hr; - } - - return S_OK; -} - -HRESULT SHELL32_SetNameOfGuidItem(PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) -{ - GUID const *clsid = _ILGetGUIDPointer (pidl); - LPOLESTR pStr; - HRESULT hr; - WCHAR szName[100]; - - if (!clsid) - { - ERR("Pidl is not reg item!\n"); - return E_FAIL; - } - - hr = StringFromCLSID(*clsid, &pStr); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr); - - DWORD cbData = (wcslen(lpName) + 1) * sizeof(WCHAR); - LONG res = SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData); - - CoTaskMemFree(pStr); - - if (res == ERROR_SUCCESS) - { - *pPidlOut = ILClone(pidl); - return S_OK; - } - - return E_FAIL; -} - -HRESULT SHELL32_GetDetailsOfGuidItem(IShellFolder2* psf, PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd) -{ - GUID const *clsid = _ILGetGUIDPointer (pidl); - - if (!clsid) - { - ERR("Pidl is not reg item!\n"); - return E_FAIL; - } - - switch(iColumn) - { - case 0: /* name */ - return psf->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str); - case 1: /* comment */ - HKEY hKey; - if (HCR_RegOpenClassIDKey(*clsid, &hKey)) - { - psd->str.cStr[0] = 0x00; - psd->str.uType = STRRET_CSTR; - RegLoadMUIStringA(hKey, "InfoTip", psd->str.cStr, MAX_PATH, NULL, 0, NULL); - RegCloseKey(hKey); - return S_OK; - } - } - return E_FAIL; -} - /*********************************************************************** * SHCreateLinks * diff --git a/reactos/dll/win32/shell32/wine/shell32_main.h b/reactos/dll/win32/shell32/wine/shell32_main.h index 1a2827bdb51..1a74cba6a56 100644 --- a/reactos/dll/win32/shell32/wine/shell32_main.h +++ b/reactos/dll/win32/shell32/wine/shell32_main.h @@ -80,9 +80,10 @@ HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN; HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN; -HRESULT CGuidItemExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut); HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut); +HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv); + /* initialisation for FORMATETC */ #define InitFormatEtc(fe, cf, med) \ {\