[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
This commit is contained in:
Rafal Harabien 2012-01-16 19:54:24 +00:00
parent 1c69ba02dd
commit e7f2a28453
5 changed files with 65 additions and 54 deletions

View file

@ -144,7 +144,7 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm)
if (!pdcm->cidl) 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) if (pdcm->pidlFolder)
m_pidlFolder = ILClone(pdcm->pidlFolder); m_pidlFolder = ILClone(pdcm->pidlFolder);
else else
@ -513,7 +513,7 @@ CDefaultContextMenu::BuildBackgroundContextMenu(
TRACE("BuildBackgroundContextMenu entered\n"); TRACE("BuildBackgroundContextMenu entered\n");
if (!_ILIsDesktop(m_Dcm.pidlFolder)) if (!_ILIsDesktop(m_pidlFolder))
{ {
WCHAR wszBuf[MAX_PATH]; WCHAR wszBuf[MAX_PATH];
@ -552,18 +552,24 @@ CDefaultContextMenu::BuildBackgroundContextMenu(
DisablePasteOptions(hMenu); DisablePasteOptions(hMenu);
} }
/* Load context menu handlers */ /* Directory is progid of filesystem folders only */
HKEY hKey; LPITEMIDLIST pidlFolderLast = ILFindLastID(m_pidlFolder);
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Directory\\Background", 0, KEY_READ, &hKey) == ERROR_SUCCESS) if (_ILIsDesktop(pidlFolderLast) || _ILIsDrive(pidlFolderLast) || _ILIsFolder(pidlFolderLast))
{ {
EnumerateDynamicContextHandlerForKey(hKey); /* Load context menu handlers */
RegCloseKey(hKey); 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)) if (InsertMenuItemsOfDynamicContextMenuExtension(hMenu, GetMenuItemCount(hMenu) - 1, iIdCmdFirst, iIdCmdLast))
{ {
/* seperate dynamic context menu items */ /* seperate dynamic context menu items */
_InsertMenuItemW(hMenu, GetMenuItemCount(hMenu) - 1, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED); _InsertMenuItemW(hMenu, GetMenuItemCount(hMenu) - 1, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED);
}
} }
return iIdCmdLast; return iIdCmdLast;
@ -795,24 +801,30 @@ CDefaultContextMenu::BuildShellItemContextMenu(
rfg = 0; rfg = 0;
} }
if ((rfg & SFGAO_FOLDER) || _ILIsControlPanel(m_Dcm.apidl[0])) if (rfg & SFGAO_FOLDER)
{ {
/* add the default verbs open / explore */ /* add the default verbs open / explore */
AddStaticEntryForFileClass(L"Folder"); AddStaticEntryForFileClass(L"Folder");
AddStaticEntryForFileClass(L"Directory");
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Folder", 0, KEY_READ, &hKey) == ERROR_SUCCESS) if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Folder", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{ {
EnumerateDynamicContextHandlerForKey(hKey); EnumerateDynamicContextHandlerForKey(hKey);
RegCloseKey(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); AddStaticEntryForFileClass(L"Directory");
RegCloseKey(hKey); 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) if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"AllFilesystemObjects", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{ {

View file

@ -540,17 +540,18 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf(
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
static const DWORD dwDesktopAttributes = static const DWORD dwDesktopAttributes =
SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER; SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE | SFGAO_CANLINK;
static const DWORD dwMyComputerAttributes = static const DWORD dwMyComputerAttributes =
SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER; 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", TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
if (!rgfInOut)
return E_INVALIDARG;
if (cidl && !apidl) if (cidl && !apidl)
return E_INVALIDARG; return E_INVALIDARG;
@ -558,23 +559,21 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf(
*rgfInOut = ~0; *rgfInOut = ~0;
if(cidl == 0) if(cidl == 0)
{
*rgfInOut &= dwDesktopAttributes; *rgfInOut &= dwDesktopAttributes;
}
else else
{ {
while (cidl > 0 && *apidl) /* TODO: always add SFGAO_CANLINK */
for (UINT i = 0; i < cidl; ++i)
{ {
pdump(*apidl); pdump(*apidl);
if (_ILIsDesktop(*apidl)) if (_ILIsDesktop(*apidl))
*rgfInOut &= dwDesktopAttributes; *rgfInOut &= dwDesktopAttributes;
else if (_ILIsMyComputer(*apidl)) else if (_ILIsMyComputer(apidl[i]))
*rgfInOut &= dwMyComputerAttributes; *rgfInOut &= dwMyComputerAttributes;
else if (_ILIsNetHood(apidl[i]))
*rgfInOut &= dwMyNetPlacesAttributes;
else else
SHELL32_GetItemAttributes((IShellFolder *)this, *apidl, rgfInOut); SHELL32_GetItemAttributes((IShellFolder *)this, apidl[i], rgfInOut);
apidl++;
cidl--;
} }
} }
/* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */

View file

@ -365,39 +365,48 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO
*/ */
HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
{ {
HRESULT hr = S_OK;
static const DWORD dwComputerAttributes = static const DWORD dwComputerAttributes =
SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_CANCOPY | SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE; 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", TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
if (!rgfInOut)
return E_INVALIDARG;
if (cidl && !apidl) if (cidl && !apidl)
return E_INVALIDARG; return E_INVALIDARG;
if (*rgfInOut == 0) if (*rgfInOut == 0)
*rgfInOut = ~0; *rgfInOut = ~0;
/* FIXME: always add SFGAO_CANLINK */
if(cidl == 0) if(cidl == 0)
*rgfInOut &= dwComputerAttributes; *rgfInOut &= dwComputerAttributes;
else else
{ {
while (cidl > 0 && *apidl) for (UINT i = 0; i < cidl; ++i)
{ {
pdump (*apidl); if (_ILIsDrive(apidl[i]))
SHELL32_GetItemAttributes (this, *apidl, rgfInOut); *rgfInOut &= dwDriveAttributes;
apidl++; else if (_ILIsControlPanel(apidl[i]))
cidl--; *rgfInOut &= dwControlPanelAttributes;
else
{
pdump(apidl[i]);
SHELL32_GetItemAttributes(this, apidl[i], rgfInOut);
}
} }
} }
/* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
*rgfInOut &= ~SFGAO_VALIDATE; *rgfInOut &= ~SFGAO_VALIDATE;
TRACE ("-- result=0x%08x\n", *rgfInOut); TRACE ("-- result=0x%08x\n", *rgfInOut);
return hr; return S_OK;
} }
/************************************************************************** /**************************************************************************

View file

@ -643,6 +643,7 @@ HRESULT WINAPI
CNewMenu::Initialize(LPCITEMIDLIST pidlFolder, CNewMenu::Initialize(LPCITEMIDLIST pidlFolder,
IDataObject *pdtobj, HKEY hkeyProgID) 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); HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON, 0, 0, LR_SHARED);
m_hbmFolder = hIcon ? IconToBitmap(hIcon) : NULL; m_hbmFolder = hIcon ? IconToBitmap(hIcon) : NULL;
hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 0, 0, LR_SHARED); hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 0, 0, LR_SHARED);

View file

@ -397,17 +397,7 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO
dwAttributes = *pdwAttributes; dwAttributes = *pdwAttributes;
/* Attributes of some special folders are hardcoded */ if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes))
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))
*pdwAttributes = dwAttributes; *pdwAttributes = dwAttributes;
else if (_ILGetDataPointer(pidl)) else if (_ILGetDataPointer(pidl))
{ {