mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 21:45:41 +00:00
[SHELL32][NTOBJSHEX] CDefaultContextMenu cannot close keys it does not own (#8233)
This commit is contained in:
parent
3fb2905c37
commit
8edf4f0926
7 changed files with 50 additions and 104 deletions
|
@ -422,7 +422,7 @@ public:
|
|||
|
||||
LPCITEMIDLIST child;
|
||||
|
||||
int nkeys = _countof(keys);
|
||||
UINT nkeys = 0;
|
||||
if (cidl == 1 && IsSymLink(apidl[0]))
|
||||
{
|
||||
const TItemId * info;
|
||||
|
@ -452,16 +452,15 @@ public:
|
|||
|
||||
if (cidl == 1 && IsFolder(apidl[0]))
|
||||
{
|
||||
res = RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
|
||||
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Folder", 0, KEY_READ, &keys[0]);
|
||||
if (!NT_SUCCESS(res))
|
||||
return HRESULT_FROM_NT(res);
|
||||
}
|
||||
else
|
||||
{
|
||||
nkeys = 0;
|
||||
return HRESULT_FROM_WIN32(res);
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
HRESULT hr = CDefFolderMenu_Create2(parent, hwndOwner, cidl, apidl, psfParent, DefCtxMenuCallback, nkeys, keys, &pcm);
|
||||
for (UINT i = 0; i < nkeys; ++i)
|
||||
RegCloseKey(keys[i]);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ class CDefaultContextMenu :
|
|||
UINT m_cidl;
|
||||
PCUITEMID_CHILD_ARRAY m_apidl;
|
||||
CComPtr<IDataObject> m_pDataObj;
|
||||
HKEY* m_aKeys;
|
||||
HKEY m_aKeys[16]; // This limit is documented for both the old API and for DEFCONTEXTMENU
|
||||
UINT m_cKeys;
|
||||
PIDLIST_ABSOLUTE m_pidlFolder;
|
||||
DWORD m_bGroupPolicyActive;
|
||||
|
@ -387,8 +387,7 @@ CDefaultContextMenu::CDefaultContextMenu() :
|
|||
m_cidl(0),
|
||||
m_apidl(NULL),
|
||||
m_pDataObj(NULL),
|
||||
m_aKeys(NULL),
|
||||
m_cKeys(NULL),
|
||||
m_cKeys(0),
|
||||
m_pidlFolder(NULL),
|
||||
m_bGroupPolicyActive(0),
|
||||
m_iIdQCMFirst(0),
|
||||
|
@ -417,7 +416,6 @@ CDefaultContextMenu::~CDefaultContextMenu()
|
|||
|
||||
for (UINT i = 0; i < m_cKeys; i++)
|
||||
RegCloseKey(m_aKeys[i]);
|
||||
HeapFree(GetProcessHeap(), 0, m_aKeys);
|
||||
|
||||
if (m_pidlFolder)
|
||||
CoTaskMemFree(m_pidlFolder);
|
||||
|
@ -428,6 +426,7 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm, LPFND
|
|||
{
|
||||
TRACE("cidl %u\n", pdcm->cidl);
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
if (!pdcm->pcmcb && !lpfn)
|
||||
{
|
||||
ERR("CDefaultContextMenu needs a callback!\n");
|
||||
|
@ -443,13 +442,14 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm, LPFND
|
|||
m_pfnmcb = lpfn;
|
||||
m_hwnd = pdcm->hwnd;
|
||||
|
||||
m_cKeys = pdcm->cKeys;
|
||||
if (pdcm->cKeys)
|
||||
for (UINT i = 0; i < pdcm->cKeys; ++i)
|
||||
{
|
||||
m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
|
||||
if (!m_aKeys)
|
||||
return E_OUTOFMEMORY;
|
||||
memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
|
||||
if (i >= _countof(m_aKeys))
|
||||
hr = E_INVALIDARG;
|
||||
else if ((m_aKeys[i] = SHRegDuplicateHKey(pdcm->aKeys[i])) != NULL)
|
||||
m_cKeys++;
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
|
||||
|
@ -469,7 +469,7 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm, LPFND
|
|||
TRACE("pidlFolder %p\n", m_pidlFolder);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CDefaultContextMenu::_DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
|
||||
|
|
|
@ -657,21 +657,10 @@ HRESULT WINAPI CDesktopFolder::CreateViewObject(
|
|||
}
|
||||
else if (IsEqualIID (riid, IID_IContextMenu))
|
||||
{
|
||||
HKEY hKeys[16];
|
||||
UINT cKeys = 0;
|
||||
AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
|
||||
|
||||
DEFCONTEXTMENU dcm;
|
||||
dcm.hwnd = hwndOwner;
|
||||
dcm.pcmcb = this;
|
||||
dcm.pidlFolder = pidlRoot;
|
||||
dcm.psf = this;
|
||||
dcm.cidl = 0;
|
||||
dcm.apidl = NULL;
|
||||
dcm.cKeys = cKeys;
|
||||
dcm.aKeys = hKeys;
|
||||
dcm.punkAssociationInfo = NULL;
|
||||
hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
|
||||
CRegKeyHandleArray keys;
|
||||
AddClassKeyToArray(L"Directory\\Background", keys, keys);
|
||||
DEFCONTEXTMENU dcm = { hwndOwner, this, pidlRoot, this, 0, NULL, NULL, keys, keys };
|
||||
hr = SHCreateDefaultContextMenu(&dcm, riid, ppvOut);
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IShellView))
|
||||
{
|
||||
|
@ -795,29 +784,19 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
|
|||
/* 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 */
|
||||
HKEY hKeys[16];
|
||||
UINT cKeys = 0;
|
||||
CRegKeyHandleArray keys;
|
||||
if (self)
|
||||
{
|
||||
AddClsidKeyToArray(CLSID_ShellDesktop, hKeys, &cKeys);
|
||||
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
|
||||
AddClsidKeyToArray(CLSID_ShellDesktop, keys, keys);
|
||||
AddClassKeyToArray(L"Folder", keys, keys);
|
||||
}
|
||||
else if (cidl > 0)
|
||||
{
|
||||
AddFSClassKeysToArray(cidl, apidl, hKeys, &cKeys);
|
||||
AddFSClassKeysToArray(cidl, apidl, keys, keys);
|
||||
}
|
||||
|
||||
DEFCONTEXTMENU dcm;
|
||||
dcm.hwnd = hwndOwner;
|
||||
dcm.pcmcb = this;
|
||||
dcm.pidlFolder = pidlRoot;
|
||||
dcm.psf = this;
|
||||
dcm.cidl = cidl;
|
||||
dcm.apidl = apidl;
|
||||
dcm.cKeys = cKeys;
|
||||
dcm.aKeys = hKeys;
|
||||
dcm.punkAssociationInfo = NULL;
|
||||
hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
|
||||
DEFCONTEXTMENU dcm = { hwndOwner, this, pidlRoot, this, cidl, apidl, NULL, keys, keys };
|
||||
hr = SHCreateDefaultContextMenu(&dcm, riid, &pObj);
|
||||
}
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
|
||||
|
|
|
@ -459,12 +459,10 @@ HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
|
|||
IShellFolder *psf,
|
||||
IContextMenu **ppcm)
|
||||
{
|
||||
HKEY hKeys[2];
|
||||
UINT cKeys = 0;
|
||||
AddClassKeyToArray(L"Drive", hKeys, &cKeys);
|
||||
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
|
||||
|
||||
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, cKeys, hKeys, ppcm);
|
||||
CRegKeyHandleArray keys;
|
||||
AddClassKeyToArray(L"Drive", keys, keys);
|
||||
AddClassKeyToArray(L"Folder", keys, keys);
|
||||
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, keys, keys, ppcm);
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
|
|
|
@ -1237,29 +1237,18 @@ HRESULT WINAPI CFSFolder::CreateViewObject(HWND hwndOwner,
|
|||
{
|
||||
hr = CFSDropTarget_CreateInstance(m_sPathTarget, riid, ppvOut);
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IContextMenu))
|
||||
{
|
||||
HKEY hKeys[16];
|
||||
UINT cKeys = 0;
|
||||
AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
|
||||
|
||||
DEFCONTEXTMENU dcm;
|
||||
dcm.hwnd = hwndOwner;
|
||||
dcm.pcmcb = this;
|
||||
dcm.pidlFolder = m_pidlRoot;
|
||||
dcm.psf = this;
|
||||
dcm.cidl = 0;
|
||||
dcm.apidl = NULL;
|
||||
dcm.cKeys = cKeys;
|
||||
dcm.aKeys = hKeys;
|
||||
dcm.punkAssociationInfo = NULL;
|
||||
hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
|
||||
}
|
||||
else if (bIsShellView)
|
||||
{
|
||||
SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this, NULL, this};
|
||||
SFV_CREATE sfvparams = { sizeof(SFV_CREATE), this, NULL, this };
|
||||
hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
|
||||
}
|
||||
else if (IsEqualIID(riid, IID_IContextMenu))
|
||||
{
|
||||
CRegKeyHandleArray keys;
|
||||
AddClassKeyToArray(L"Directory\\Background", keys, keys);
|
||||
DEFCONTEXTMENU dcm = { hwndOwner, this, m_pidlRoot, this, 0, NULL, NULL, keys, keys };
|
||||
hr = SHCreateDefaultContextMenu(&dcm, riid, ppvOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
|
@ -1383,21 +1372,10 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
|
|||
|
||||
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
|
||||
{
|
||||
HKEY hKeys[16];
|
||||
UINT cKeys = 0;
|
||||
AddFSClassKeysToArray(cidl, apidl, hKeys, &cKeys);
|
||||
|
||||
DEFCONTEXTMENU dcm;
|
||||
dcm.hwnd = hwndOwner;
|
||||
dcm.pcmcb = this;
|
||||
dcm.pidlFolder = m_pidlRoot;
|
||||
dcm.psf = this;
|
||||
dcm.cidl = cidl;
|
||||
dcm.apidl = apidl;
|
||||
dcm.cKeys = cKeys;
|
||||
dcm.aKeys = hKeys;
|
||||
dcm.punkAssociationInfo = NULL;
|
||||
hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
|
||||
CRegKeyHandleArray keys;
|
||||
AddFSClassKeysToArray(cidl, apidl, keys, keys);
|
||||
DEFCONTEXTMENU dcm = { hwndOwner, this, m_pidlRoot, this, cidl, apidl, NULL, keys, keys };
|
||||
hr = SHCreateDefaultContextMenu(&dcm, riid, &pObj);
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IDataObject))
|
||||
{
|
||||
|
|
|
@ -435,11 +435,10 @@ HRESULT WINAPI CNetFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH
|
|||
|
||||
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
|
||||
{
|
||||
CRegKeyHandleArray keys;
|
||||
IContextMenu * pCm = NULL;
|
||||
HKEY hkey;
|
||||
UINT cKeys = 0;
|
||||
AddClassKeyToArray(L"Folder", &hkey, &cKeys);
|
||||
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, this, NetFolderMenuCallback, cKeys, &hkey, &pCm);
|
||||
AddClassKeyToArray(L"Folder", keys, keys);
|
||||
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, this, NetFolderMenuCallback, keys, keys, &pCm);
|
||||
pObj = pCm;
|
||||
}
|
||||
else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1))
|
||||
|
|
|
@ -972,17 +972,10 @@ static HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf, HWND hwn
|
|||
static HRESULT CRegItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl,
|
||||
PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, IContextMenu **ppcm)
|
||||
{
|
||||
HKEY hKeys[3];
|
||||
UINT cKeys = 0;
|
||||
|
||||
CRegKeyHandleArray keys;
|
||||
const GUID *pGuid = _ILGetGUIDPointer(apidl[0]);
|
||||
if (pGuid)
|
||||
{
|
||||
WCHAR key[sizeof("CLSID\\") + 38];
|
||||
wcscpy(key, L"CLSID\\");
|
||||
StringFromGUID2(*pGuid, &key[6], 39);
|
||||
AddClassKeyToArray(key, hKeys, &cKeys);
|
||||
}
|
||||
AddClsidKeyToArray(*pGuid, keys, keys);
|
||||
|
||||
// FIXME: CRegFolder should be aggregated by its outer folder and should
|
||||
// provide the attributes for all required non-registry folders.
|
||||
|
@ -993,9 +986,9 @@ static HRESULT CRegItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
|
|||
|
||||
SFGAOF att = (psf && cidl) ? SHGetAttributes(pOuterSF ? pOuterSF.p : psf, apidl[0], SFGAO_FOLDER) : 0;
|
||||
if ((att & SFGAO_FOLDER) && (!pGuid || !HasCLSIDShellFolderValue(*pGuid, L"HideFolderVerbs")))
|
||||
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
|
||||
AddClassKeyToArray(L"Folder", keys, keys);
|
||||
|
||||
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, RegFolderContextMenuCallback, cKeys, hKeys, ppcm);
|
||||
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, RegFolderContextMenuCallback, keys, keys, ppcm);
|
||||
}
|
||||
|
||||
/* In latest windows version this is exported but it takes different arguments! */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue