From e7f2a284530a06c7043d11a6223958a71d3ca10e Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 16 Jan 2012 19:54:24 +0000 Subject: [PATCH] [SHELL32] - Load shell extensions from Directory key only for file system directories. Fixes New menu being added to special folders context menu (for example My Computer or Control Panel) - Load shell extensions from AllFilesystemObjects only for files and directories - Hardcode special folders attributes in proper place svn path=/trunk/; revision=54985 --- reactos/dll/win32/shell32/defcontextmenu.cpp | 48 ++++++++++++------- reactos/dll/win32/shell32/folders/desktop.cpp | 27 +++++------ reactos/dll/win32/shell32/folders/mycomp.cpp | 31 +++++++----- reactos/dll/win32/shell32/newmenu.cpp | 1 + reactos/dll/win32/shell32/shlfolder.cpp | 12 +---- 5 files changed, 65 insertions(+), 54 deletions(-) diff --git a/reactos/dll/win32/shell32/defcontextmenu.cpp b/reactos/dll/win32/shell32/defcontextmenu.cpp index 15bf229d8f6..a9788f3e7b4 100644 --- a/reactos/dll/win32/shell32/defcontextmenu.cpp +++ b/reactos/dll/win32/shell32/defcontextmenu.cpp @@ -144,7 +144,7 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm) if (!pdcm->cidl) { - /* Init pidlFolder only if is background context menu. See IShellExtInit::Initialize */ + /* Init pidlFolder only if it is background context menu. See IShellExtInit::Initialize */ if (pdcm->pidlFolder) m_pidlFolder = ILClone(pdcm->pidlFolder); else @@ -513,7 +513,7 @@ CDefaultContextMenu::BuildBackgroundContextMenu( TRACE("BuildBackgroundContextMenu entered\n"); - if (!_ILIsDesktop(m_Dcm.pidlFolder)) + if (!_ILIsDesktop(m_pidlFolder)) { WCHAR wszBuf[MAX_PATH]; @@ -552,18 +552,24 @@ CDefaultContextMenu::BuildBackgroundContextMenu( DisablePasteOptions(hMenu); } - /* Load context menu handlers */ - HKEY hKey; - if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Directory\\Background", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + /* Directory is progid of filesystem folders only */ + LPITEMIDLIST pidlFolderLast = ILFindLastID(m_pidlFolder); + if (_ILIsDesktop(pidlFolderLast) || _ILIsDrive(pidlFolderLast) || _ILIsFolder(pidlFolderLast)) { - EnumerateDynamicContextHandlerForKey(hKey); - RegCloseKey(hKey); - } + /* Load context menu handlers */ + TRACE("Add background handlers: %p\n", m_pidlFolder); + HKEY hKey; + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Directory\\Background", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + EnumerateDynamicContextHandlerForKey(hKey); + RegCloseKey(hKey); + } - if (InsertMenuItemsOfDynamicContextMenuExtension(hMenu, GetMenuItemCount(hMenu) - 1, iIdCmdFirst, iIdCmdLast)) - { - /* seperate dynamic context menu items */ - _InsertMenuItemW(hMenu, GetMenuItemCount(hMenu) - 1, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED); + if (InsertMenuItemsOfDynamicContextMenuExtension(hMenu, GetMenuItemCount(hMenu) - 1, iIdCmdFirst, iIdCmdLast)) + { + /* seperate dynamic context menu items */ + _InsertMenuItemW(hMenu, GetMenuItemCount(hMenu) - 1, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED); + } } return iIdCmdLast; @@ -795,24 +801,30 @@ CDefaultContextMenu::BuildShellItemContextMenu( rfg = 0; } - if ((rfg & SFGAO_FOLDER) || _ILIsControlPanel(m_Dcm.apidl[0])) + if (rfg & SFGAO_FOLDER) { /* add the default verbs open / explore */ AddStaticEntryForFileClass(L"Folder"); - AddStaticEntryForFileClass(L"Directory"); if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Folder", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { EnumerateDynamicContextHandlerForKey(hKey); RegCloseKey(hKey); } - if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Directory", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + + /* Directory is only loaded for real filesystem directories */ + if (_ILIsFolder(m_Dcm.apidl[0])) { - EnumerateDynamicContextHandlerForKey(hKey); - RegCloseKey(hKey); + AddStaticEntryForFileClass(L"Directory"); + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Directory", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + EnumerateDynamicContextHandlerForKey(hKey); + RegCloseKey(hKey); + } } } - if (rfg & SFGAO_FILESYSTEM) + /* AllFilesystemObjects class is loaded only for files and directories */ + if (_ILIsFolder(m_Dcm.apidl[0]) || _ILIsValue(m_Dcm.apidl[0])) { if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"AllFilesystemObjects", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { diff --git a/reactos/dll/win32/shell32/folders/desktop.cpp b/reactos/dll/win32/shell32/folders/desktop.cpp index 72202a3bc87..124c91e978e 100644 --- a/reactos/dll/win32/shell32/folders/desktop.cpp +++ b/reactos/dll/win32/shell32/folders/desktop.cpp @@ -540,17 +540,18 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf( { HRESULT hr = S_OK; static const DWORD dwDesktopAttributes = - SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | - SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER; + SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | + SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE | SFGAO_CANLINK; static const DWORD dwMyComputerAttributes = - SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | - SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER; + SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | + SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK; + static DWORD dwMyNetPlacesAttributes = + SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | + SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK; TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); - if (!rgfInOut) - return E_INVALIDARG; if (cidl && !apidl) return E_INVALIDARG; @@ -558,23 +559,21 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf( *rgfInOut = ~0; if(cidl == 0) - { *rgfInOut &= dwDesktopAttributes; - } else { - while (cidl > 0 && *apidl) + /* TODO: always add SFGAO_CANLINK */ + for (UINT i = 0; i < cidl; ++i) { pdump(*apidl); if (_ILIsDesktop(*apidl)) *rgfInOut &= dwDesktopAttributes; - else if (_ILIsMyComputer(*apidl)) + else if (_ILIsMyComputer(apidl[i])) *rgfInOut &= dwMyComputerAttributes; + else if (_ILIsNetHood(apidl[i])) + *rgfInOut &= dwMyNetPlacesAttributes; else - SHELL32_GetItemAttributes((IShellFolder *)this, *apidl, rgfInOut); - - apidl++; - cidl--; + SHELL32_GetItemAttributes((IShellFolder *)this, apidl[i], rgfInOut); } } /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ diff --git a/reactos/dll/win32/shell32/folders/mycomp.cpp b/reactos/dll/win32/shell32/folders/mycomp.cpp index 001f5c9a44c..0dbd0479d08 100644 --- a/reactos/dll/win32/shell32/folders/mycomp.cpp +++ b/reactos/dll/win32/shell32/folders/mycomp.cpp @@ -365,39 +365,48 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO */ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) { - HRESULT hr = S_OK; static const DWORD dwComputerAttributes = - SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_CANCOPY | - SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE; + SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | + SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK; + static const DWORD dwControlPanelAttributes = + SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK; + static const DWORD dwDriveAttributes = + SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | + SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK; TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); - if (!rgfInOut) - return E_INVALIDARG; if (cidl && !apidl) return E_INVALIDARG; if (*rgfInOut == 0) *rgfInOut = ~0; + /* FIXME: always add SFGAO_CANLINK */ if(cidl == 0) *rgfInOut &= dwComputerAttributes; else { - while (cidl > 0 && *apidl) + for (UINT i = 0; i < cidl; ++i) { - pdump (*apidl); - SHELL32_GetItemAttributes (this, *apidl, rgfInOut); - apidl++; - cidl--; + if (_ILIsDrive(apidl[i])) + *rgfInOut &= dwDriveAttributes; + else if (_ILIsControlPanel(apidl[i])) + *rgfInOut &= dwControlPanelAttributes; + else + { + pdump(apidl[i]); + SHELL32_GetItemAttributes(this, apidl[i], rgfInOut); + } } } + /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ *rgfInOut &= ~SFGAO_VALIDATE; TRACE ("-- result=0x%08x\n", *rgfInOut); - return hr; + return S_OK; } /************************************************************************** diff --git a/reactos/dll/win32/shell32/newmenu.cpp b/reactos/dll/win32/shell32/newmenu.cpp index 350bcd10899..a9410114e97 100644 --- a/reactos/dll/win32/shell32/newmenu.cpp +++ b/reactos/dll/win32/shell32/newmenu.cpp @@ -643,6 +643,7 @@ HRESULT WINAPI CNewMenu::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID) { + /* Load folder and shortcut icons */ HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON, 0, 0, LR_SHARED); m_hbmFolder = hIcon ? IconToBitmap(hIcon) : NULL; hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 0, 0, LR_SHARED); diff --git a/reactos/dll/win32/shell32/shlfolder.cpp b/reactos/dll/win32/shell32/shlfolder.cpp index b170a7e9a16..d4e53214ded 100644 --- a/reactos/dll/win32/shell32/shlfolder.cpp +++ b/reactos/dll/win32/shell32/shlfolder.cpp @@ -397,17 +397,7 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO dwAttributes = *pdwAttributes; - /* Attributes of some special folders are hardcoded */ - if (_ILIsDrive(pidl)) - *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| - SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME; - else if (_ILIsMyComputer(pidl) || _ILIsNetHood(pidl)) - *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| - SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANDELETE| - SFGAO_CANRENAME|SFGAO_CANLINK; - else if (_ILIsControlPanel(pidl)) - *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_CANLINK; - else if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) + if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) *pdwAttributes = dwAttributes; else if (_ILGetDataPointer(pidl)) {