Author: gadamopoulos Date: Tue Nov 15 20:14:56 2016 New Revision: 73237
URL: http://svn.reactos.org/svn/reactos?rev=73237&view=rev Log: [SHELL32] - Implement filling in needed keys passed to CDefFolderMenu_Create2. - CDefaultContextMenu: Remove the code that filled the array of keys as this is now moved to the implementation of the shell folder.
Modified: trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp trunk/reactos/dll/win32/shell32/shfldr.h trunk/reactos/dll/win32/shell32/shlfolder.cpp
Modified: trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CDefaultC... ============================================================================== --- trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp [iso-8859-1] Tue Nov 15 20:14:56 2016 @@ -1571,96 +1571,10 @@ * */
-static void AddClassKey(const WCHAR * szClass, HKEY* buffer, UINT* cKeys) -{ - LSTATUS result; - HKEY hkey; - result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szClass, 0, KEY_READ | KEY_QUERY_VALUE, &hkey); - if (result != ERROR_SUCCESS) - return; - - buffer[*cKeys] = hkey; - *cKeys +=1; -} - -void HackFillKeys(DEFCONTEXTMENU *pdcm, HKEY* buffer) -{ - PCUITEMID_CHILD pidl = pdcm->apidl[0]; - pdcm->cKeys = 0; - pdcm->aKeys = buffer; - - if (_ILIsValue(pidl)) - { - FileStructW* pFileData = _ILGetFileStructW(pidl); - LPWSTR extension = PathFindExtension(pFileData->wszName); - - if (extension) - { - AddClassKey(extension, buffer, &pdcm->cKeys); - - WCHAR wszClass[40], wszClass2[40]; - DWORD dwSize = sizeof(wszClass); - if (RegGetValueW(HKEY_CLASSES_ROOT, extension, NULL, RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS) - { - swprintf(wszClass2, L"%s//%s", extension, wszClass); - - AddClassKey(wszClass, buffer, &pdcm->cKeys); - AddClassKey(wszClass2, buffer, &pdcm->cKeys); - } - - swprintf(wszClass2, L"SystemFileAssociations//%s", extension); - AddClassKey(wszClass2, buffer, &pdcm->cKeys); - - if (RegGetValueW(HKEY_CLASSES_ROOT, extension, L"PerceivedType ", RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS) - { - swprintf(wszClass2, L"SystemFileAssociations//%s", wszClass); - AddClassKey(wszClass2, buffer, &pdcm->cKeys); - } - } - - AddClassKey(L"AllFilesystemObjects", buffer, &pdcm->cKeys); - AddClassKey(L"*", buffer, &pdcm->cKeys); - } - else if (_ILIsSpecialFolder(pidl)) - { - GUID *pGuid = _ILGetGUIDPointer(pidl); - if (pGuid) - { - LPOLESTR pwszCLSID; - WCHAR key[60]; - - wcscpy(key, L"CLSID\"); - HRESULT hr = StringFromCLSID(*pGuid, &pwszCLSID); - if (hr == S_OK) - { - wcscpy(&key[6], pwszCLSID); - AddClassKey(key, buffer, &pdcm->cKeys); - } - } - AddClassKey(L"Folder", buffer, &pdcm->cKeys); - } - else if (_ILIsFolder(pidl)) - { - AddClassKey(L"AllFilesystemObjects", buffer, &pdcm->cKeys); - AddClassKey(L"Directory", buffer, &pdcm->cKeys); - AddClassKey(L"Folder", buffer, &pdcm->cKeys); - } - else if (_ILIsDrive(pidl)) - { - AddClassKey(L"Drive", buffer, &pdcm->cKeys); - AddClassKey(L"Folder", buffer, &pdcm->cKeys); - } -} - HRESULT WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv) { - /* HACK: move to the shell folders implementation */ - HKEY hkeyHack[16]; - if (!pdcm->aKeys && pdcm->cidl) - HackFillKeys((DEFCONTEXTMENU *)pdcm, hkeyHack); - HRESULT hr = CDefaultContextMenu_CreateInstance(pdcm, riid, ppv); if (FAILED_UNEXPECTEDLY(hr)) return hr;
Modified: trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp [iso-8859-1] Tue Nov 15 20:14:56 2016 @@ -486,7 +486,7 @@ if (bHasCpl) hr = ShellObjectCreatorInit<CCPLItemMenu>(cidl, apidl, riid, &pObj); else - hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj); + hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj); } else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) { hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj); } else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) {
Modified: trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] Tue Nov 15 20:14:56 2016 @@ -639,7 +639,21 @@
if (IsEqualIID (riid, IID_IContextMenu)) { - hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder *)this, NULL, 0, NULL, (IContextMenu **)&pObj); + if (_ILIsSpecialFolder(apidl[0])) + { + hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj); + } + else + { + /* Do not use the context menu of the CFSFolder here. */ + /* We need to pass a pointer of the CDesktopFolder so as the data object that the context menu gets is rooted to the desktop */ + /* Otherwise operations like that involve items from both user and shared desktop will not work */ + IContextMenu * pCm = NULL; + HKEY hKeys[16]; + UINT cKeys = 0; + AddFSClassKeysToArray(apidl[0], hKeys, &cKeys); + hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, cKeys, hKeys, &pCm); + } } else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1)) { @@ -817,14 +831,15 @@ { TRACE ("(%p)->(%p)\n", this, pidl);
- return E_NOTIMPL; + return E_INVALIDARG; }
HRESULT WINAPI CDesktopFolder::GetCurFolder(LPITEMIDLIST * pidl) { TRACE ("(%p)->(%p)\n", this, pidl);
- if (!pidl) return E_POINTER; + if (!pidl) + return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */ *pidl = ILClone (pidlRoot); return S_OK; }
Modified: trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] Tue Nov 15 20:14:56 2016 @@ -39,6 +39,22 @@ * IShellFolder implementation */
+HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, + HWND hwnd, + UINT cidl, + PCUITEMID_CHILD_ARRAY apidl, + IShellFolder *psf, + IContextMenu **ppcm) +{ + HKEY hKeys[2]; + UINT cKeys = 0; + AddClassKeyToArray(L"Drive", hKeys, &cKeys); + AddClassKeyToArray(L"Folder", hKeys, &cKeys); + + /* TODO: also pass a callback here */ + return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, NULL, cKeys, hKeys, ppcm); +} + HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut) { CComPtr<IDefaultExtractIconInit> initIcon; @@ -536,7 +552,10 @@
if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1)) { - hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj); + if (_ILIsDrive(apidl[0])) + hr = CDrivesContextMenu_CreateInstance(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj); + else + hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj); } else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1)) { @@ -812,12 +831,6 @@ */ HRESULT WINAPI CDrivesFolder::Initialize(LPCITEMIDLIST pidl) { - TRACE ("(%p)->(%p)\n", this, pidl); - - if (pidlRoot) - SHFree((LPVOID)pidlRoot); - - pidlRoot = ILClone(pidl); return S_OK; }
@@ -829,7 +842,7 @@ TRACE("(%p)->(%p)\n", this, pidl);
if (!pidl) - return E_POINTER; + return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
*pidl = ILClone(pidlRoot); return S_OK;
Modified: trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] Tue Nov 15 20:14:56 2016 @@ -490,7 +490,10 @@ if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1)) { IContextMenu * pCm = NULL; - hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, 0, NULL, &pCm); + HKEY hKeys[16]; + UINT cKeys = 0; + AddFSClassKeysToArray(apidl[0], hKeys, &cKeys); + hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, cKeys, hKeys, &pCm); pObj = pCm; } else if (IsEqualIID (riid, IID_IDataObject))
Modified: trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] Tue Nov 15 20:14:56 2016 @@ -22,6 +22,35 @@
WINE_DEFAULT_DEBUG_CHANNEL (shell);
+HRESULT CGuidItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, + HWND hwnd, + UINT cidl, + PCUITEMID_CHILD_ARRAY apidl, + IShellFolder *psf, + IContextMenu **ppcm) +{ + HKEY hKeys[10]; + UINT cKeys = 0; + + GUID *pGuid = _ILGetGUIDPointer(apidl[0]); + if (pGuid) + { + LPOLESTR pwszCLSID; + WCHAR key[60]; + + wcscpy(key, L"CLSID\"); + HRESULT hr = StringFromCLSID(*pGuid, &pwszCLSID); + if (hr == S_OK) + { + wcscpy(&key[6], pwszCLSID); + AddClassKeyToArray(key, hKeys, &cKeys); + } + } + AddClassKeyToArray(L"Folder", hKeys, &cKeys); + + return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, NULL, cKeys, hKeys, ppcm); +} + HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut) { CComPtr<IDefaultExtractIconInit> initIcon; @@ -175,13 +204,26 @@
HRESULT CRegFolder::GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { + DWORD dwAttributes = *pdwAttributes; + /* First try to get them from the registry */ - if (HCR_GetFolderAttributes(pidl, pdwAttributes) && *pdwAttributes) - { - return S_OK; - } - - *pdwAttributes &= SFGAO_CANLINK; + if (!HCR_GetFolderAttributes(pidl, pdwAttributes)) + { + /* We couldn't get anything */ + *pdwAttributes = 0; + } + + /* Items have more attributes when on desktop */ + if (_ILIsDesktop(m_pidlRoot)) + { + *pdwAttributes |= (dwAttributes & (SFGAO_CANLINK|SFGAO_CANDELETE|SFGAO_CANRENAME|SFGAO_HASPROPSHEET)); + } + + /* In any case, links can be created */ + if (*pdwAttributes == NULL) + { + *pdwAttributes |= (dwAttributes & SFGAO_CANLINK); + } return S_OK; }
@@ -346,8 +388,20 @@ { hr = CGuidItemExtractIcon_CreateInstance(apidl[0], riid, &pObj); } + else if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1)) + { + if (!_ILGetGUIDPointer (apidl[0])) + { + ERR("Got non guid item!\n"); + return E_FAIL; + } + + hr = CGuidItemContextMenu_CreateInstance(m_pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj); + } else + { hr = E_NOINTERFACE; + }
*ppvOut = pObj; return hr;
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] Tue Nov 15 20:14:56 2016 @@ -61,6 +61,8 @@ extern "C" BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey);
+void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys); + 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] Tue Nov 15 20:14:56 2016 @@ -501,6 +501,52 @@ *cKeys += 1; }
+void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys) +{ + if (_ILIsValue(pidl)) + { + FileStructW* pFileData = _ILGetFileStructW(pidl); + LPWSTR extension = PathFindExtension(pFileData->wszName); + + if (extension) + { + AddClassKeyToArray(extension, array, cKeys); + + WCHAR wszClass[40], wszClass2[40]; + DWORD dwSize = sizeof(wszClass); + if (RegGetValueW(HKEY_CLASSES_ROOT, extension, NULL, RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS) + { + swprintf(wszClass2, L"%s//%s", extension, wszClass); + + AddClassKeyToArray(wszClass, array, cKeys); + AddClassKeyToArray(wszClass2, array, cKeys); + } + + swprintf(wszClass2, L"SystemFileAssociations//%s", extension); + AddClassKeyToArray(wszClass2, array, cKeys); + + if (RegGetValueW(HKEY_CLASSES_ROOT, extension, L"PerceivedType ", RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS) + { + swprintf(wszClass2, L"SystemFileAssociations//%s", wszClass); + AddClassKeyToArray(wszClass2, array, cKeys); + } + } + + AddClassKeyToArray(L"AllFilesystemObjects", array, cKeys); + AddClassKeyToArray(L"*", array, cKeys); + } + else if (_ILIsFolder(pidl)) + { + AddClassKeyToArray(L"AllFilesystemObjects", array, cKeys); + AddClassKeyToArray(L"Directory", array, cKeys); + AddClassKeyToArray(L"Folder", array, cKeys); + } + else + { + ERR("Got non FS pidl\n"); + } +} + /*********************************************************************** * SHCreateLinks *