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/CDefault…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/shlfolde…
==============================================================================
--- 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
*