mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 12:52:58 +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;
|
LPCITEMIDLIST child;
|
||||||
|
|
||||||
int nkeys = _countof(keys);
|
UINT nkeys = 0;
|
||||||
if (cidl == 1 && IsSymLink(apidl[0]))
|
if (cidl == 1 && IsSymLink(apidl[0]))
|
||||||
{
|
{
|
||||||
const TItemId * info;
|
const TItemId * info;
|
||||||
|
@ -452,16 +452,15 @@ public:
|
||||||
|
|
||||||
if (cidl == 1 && IsFolder(apidl[0]))
|
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))
|
if (!NT_SUCCESS(res))
|
||||||
return HRESULT_FROM_NT(res);
|
return HRESULT_FROM_WIN32(res);
|
||||||
}
|
nkeys++;
|
||||||
else
|
|
||||||
{
|
|
||||||
nkeys = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = CDefFolderMenu_Create2(parent, hwndOwner, cidl, apidl, psfParent, DefCtxMenuCallback, nkeys, keys, &pcm);
|
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))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,7 @@ class CDefaultContextMenu :
|
||||||
UINT m_cidl;
|
UINT m_cidl;
|
||||||
PCUITEMID_CHILD_ARRAY m_apidl;
|
PCUITEMID_CHILD_ARRAY m_apidl;
|
||||||
CComPtr<IDataObject> m_pDataObj;
|
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;
|
UINT m_cKeys;
|
||||||
PIDLIST_ABSOLUTE m_pidlFolder;
|
PIDLIST_ABSOLUTE m_pidlFolder;
|
||||||
DWORD m_bGroupPolicyActive;
|
DWORD m_bGroupPolicyActive;
|
||||||
|
@ -387,8 +387,7 @@ CDefaultContextMenu::CDefaultContextMenu() :
|
||||||
m_cidl(0),
|
m_cidl(0),
|
||||||
m_apidl(NULL),
|
m_apidl(NULL),
|
||||||
m_pDataObj(NULL),
|
m_pDataObj(NULL),
|
||||||
m_aKeys(NULL),
|
m_cKeys(0),
|
||||||
m_cKeys(NULL),
|
|
||||||
m_pidlFolder(NULL),
|
m_pidlFolder(NULL),
|
||||||
m_bGroupPolicyActive(0),
|
m_bGroupPolicyActive(0),
|
||||||
m_iIdQCMFirst(0),
|
m_iIdQCMFirst(0),
|
||||||
|
@ -417,7 +416,6 @@ CDefaultContextMenu::~CDefaultContextMenu()
|
||||||
|
|
||||||
for (UINT i = 0; i < m_cKeys; i++)
|
for (UINT i = 0; i < m_cKeys; i++)
|
||||||
RegCloseKey(m_aKeys[i]);
|
RegCloseKey(m_aKeys[i]);
|
||||||
HeapFree(GetProcessHeap(), 0, m_aKeys);
|
|
||||||
|
|
||||||
if (m_pidlFolder)
|
if (m_pidlFolder)
|
||||||
CoTaskMemFree(m_pidlFolder);
|
CoTaskMemFree(m_pidlFolder);
|
||||||
|
@ -428,6 +426,7 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm, LPFND
|
||||||
{
|
{
|
||||||
TRACE("cidl %u\n", pdcm->cidl);
|
TRACE("cidl %u\n", pdcm->cidl);
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
if (!pdcm->pcmcb && !lpfn)
|
if (!pdcm->pcmcb && !lpfn)
|
||||||
{
|
{
|
||||||
ERR("CDefaultContextMenu needs a callback!\n");
|
ERR("CDefaultContextMenu needs a callback!\n");
|
||||||
|
@ -443,13 +442,14 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm, LPFND
|
||||||
m_pfnmcb = lpfn;
|
m_pfnmcb = lpfn;
|
||||||
m_hwnd = pdcm->hwnd;
|
m_hwnd = pdcm->hwnd;
|
||||||
|
|
||||||
m_cKeys = pdcm->cKeys;
|
for (UINT i = 0; i < pdcm->cKeys; ++i)
|
||||||
if (pdcm->cKeys)
|
|
||||||
{
|
{
|
||||||
m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
|
if (i >= _countof(m_aKeys))
|
||||||
if (!m_aKeys)
|
hr = E_INVALIDARG;
|
||||||
return E_OUTOFMEMORY;
|
else if ((m_aKeys[i] = SHRegDuplicateHKey(pdcm->aKeys[i])) != NULL)
|
||||||
memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
|
m_cKeys++;
|
||||||
|
else
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
|
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);
|
TRACE("pidlFolder %p\n", m_pidlFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CDefaultContextMenu::_DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
|
HRESULT CDefaultContextMenu::_DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
|
||||||
|
|
|
@ -657,21 +657,10 @@ HRESULT WINAPI CDesktopFolder::CreateViewObject(
|
||||||
}
|
}
|
||||||
else if (IsEqualIID (riid, IID_IContextMenu))
|
else if (IsEqualIID (riid, IID_IContextMenu))
|
||||||
{
|
{
|
||||||
HKEY hKeys[16];
|
CRegKeyHandleArray keys;
|
||||||
UINT cKeys = 0;
|
AddClassKeyToArray(L"Directory\\Background", keys, keys);
|
||||||
AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
|
DEFCONTEXTMENU dcm = { hwndOwner, this, pidlRoot, this, 0, NULL, NULL, keys, keys };
|
||||||
|
hr = SHCreateDefaultContextMenu(&dcm, riid, ppvOut);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else if (IsEqualIID (riid, IID_IShellView))
|
else if (IsEqualIID (riid, IID_IShellView))
|
||||||
{
|
{
|
||||||
|
@ -795,29 +784,19 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
|
||||||
/* Do not use the context menu of the CFSFolder here. */
|
/* 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 */
|
/* 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 */
|
/* Otherwise operations like that involve items from both user and shared desktop will not work */
|
||||||
HKEY hKeys[16];
|
CRegKeyHandleArray keys;
|
||||||
UINT cKeys = 0;
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
AddClsidKeyToArray(CLSID_ShellDesktop, hKeys, &cKeys);
|
AddClsidKeyToArray(CLSID_ShellDesktop, keys, keys);
|
||||||
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
|
AddClassKeyToArray(L"Folder", keys, keys);
|
||||||
}
|
}
|
||||||
else if (cidl > 0)
|
else if (cidl > 0)
|
||||||
{
|
{
|
||||||
AddFSClassKeysToArray(cidl, apidl, hKeys, &cKeys);
|
AddFSClassKeysToArray(cidl, apidl, keys, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFCONTEXTMENU dcm;
|
DEFCONTEXTMENU dcm = { hwndOwner, this, pidlRoot, this, cidl, apidl, NULL, keys, keys };
|
||||||
dcm.hwnd = hwndOwner;
|
hr = SHCreateDefaultContextMenu(&dcm, riid, &pObj);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
|
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
|
||||||
|
|
|
@ -459,12 +459,10 @@ HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
|
||||||
IShellFolder *psf,
|
IShellFolder *psf,
|
||||||
IContextMenu **ppcm)
|
IContextMenu **ppcm)
|
||||||
{
|
{
|
||||||
HKEY hKeys[2];
|
CRegKeyHandleArray keys;
|
||||||
UINT cKeys = 0;
|
AddClassKeyToArray(L"Drive", keys, keys);
|
||||||
AddClassKeyToArray(L"Drive", hKeys, &cKeys);
|
AddClassKeyToArray(L"Folder", keys, keys);
|
||||||
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
|
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, keys, keys, ppcm);
|
||||||
|
|
||||||
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, cKeys, hKeys, ppcm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT
|
static HRESULT
|
||||||
|
|
|
@ -1237,29 +1237,18 @@ HRESULT WINAPI CFSFolder::CreateViewObject(HWND hwndOwner,
|
||||||
{
|
{
|
||||||
hr = CFSDropTarget_CreateInstance(m_sPathTarget, riid, ppvOut);
|
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)
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
hr = E_INVALIDARG;
|
hr = E_INVALIDARG;
|
||||||
|
@ -1383,21 +1372,10 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
|
||||||
|
|
||||||
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
|
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
|
||||||
{
|
{
|
||||||
HKEY hKeys[16];
|
CRegKeyHandleArray keys;
|
||||||
UINT cKeys = 0;
|
AddFSClassKeysToArray(cidl, apidl, keys, keys);
|
||||||
AddFSClassKeysToArray(cidl, apidl, hKeys, &cKeys);
|
DEFCONTEXTMENU dcm = { hwndOwner, this, m_pidlRoot, this, cidl, apidl, NULL, keys, keys };
|
||||||
|
hr = SHCreateDefaultContextMenu(&dcm, riid, &pObj);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else if (IsEqualIID (riid, IID_IDataObject))
|
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))
|
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
|
||||||
{
|
{
|
||||||
|
CRegKeyHandleArray keys;
|
||||||
IContextMenu * pCm = NULL;
|
IContextMenu * pCm = NULL;
|
||||||
HKEY hkey;
|
AddClassKeyToArray(L"Folder", keys, keys);
|
||||||
UINT cKeys = 0;
|
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, this, NetFolderMenuCallback, keys, keys, &pCm);
|
||||||
AddClassKeyToArray(L"Folder", &hkey, &cKeys);
|
|
||||||
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, this, NetFolderMenuCallback, cKeys, &hkey, &pCm);
|
|
||||||
pObj = pCm;
|
pObj = pCm;
|
||||||
}
|
}
|
||||||
else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1))
|
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,
|
static HRESULT CRegItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl,
|
||||||
PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, IContextMenu **ppcm)
|
PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, IContextMenu **ppcm)
|
||||||
{
|
{
|
||||||
HKEY hKeys[3];
|
CRegKeyHandleArray keys;
|
||||||
UINT cKeys = 0;
|
|
||||||
|
|
||||||
const GUID *pGuid = _ILGetGUIDPointer(apidl[0]);
|
const GUID *pGuid = _ILGetGUIDPointer(apidl[0]);
|
||||||
if (pGuid)
|
if (pGuid)
|
||||||
{
|
AddClsidKeyToArray(*pGuid, keys, keys);
|
||||||
WCHAR key[sizeof("CLSID\\") + 38];
|
|
||||||
wcscpy(key, L"CLSID\\");
|
|
||||||
StringFromGUID2(*pGuid, &key[6], 39);
|
|
||||||
AddClassKeyToArray(key, hKeys, &cKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: CRegFolder should be aggregated by its outer folder and should
|
// FIXME: CRegFolder should be aggregated by its outer folder and should
|
||||||
// provide the attributes for all required non-registry folders.
|
// 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;
|
SFGAOF att = (psf && cidl) ? SHGetAttributes(pOuterSF ? pOuterSF.p : psf, apidl[0], SFGAO_FOLDER) : 0;
|
||||||
if ((att & SFGAO_FOLDER) && (!pGuid || !HasCLSIDShellFolderValue(*pGuid, L"HideFolderVerbs")))
|
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! */
|
/* In latest windows version this is exported but it takes different arguments! */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue