https://git.reactos.org/?p=reactos.git;a=commitdiff;h=db39a50c732a016965f67fe93b848663da6121f8

commit db39a50c732a016965f67fe93b848663da6121f8
Author:     Mark Jansen <mark.jan...@reactos.org>
AuthorDate: Fri Dec 17 05:01:03 2021 +0100
Commit:     GitHub <nore...@github.com>
CommitDate: Fri Dec 17 13:01:03 2021 +0900

    Simplify CDefaultContextMenu by using CAtlList (#3405)
---
 dll/win32/shell32/CDefaultContextMenu.cpp | 244 ++++++++++++------------------
 dll/win32/shell32/precomp.h               |   1 +
 2 files changed, 97 insertions(+), 148 deletions(-)

diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp 
b/dll/win32/shell32/CDefaultContextMenu.cpp
index dde98873390..fc1e5e97ff2 100644
--- a/dll/win32/shell32/CDefaultContextMenu.cpp
+++ b/dll/win32/shell32/CDefaultContextMenu.cpp
@@ -15,15 +15,13 @@ typedef struct _DynamicShellEntry_
     UINT iIdCmdFirst;
     UINT NumIds;
     CLSID ClassID;
-    IContextMenu *pCM;
-    struct _DynamicShellEntry_ *pNext;
+    CComPtr<IContextMenu> pCM;
 } DynamicShellEntry, *PDynamicShellEntry;
 
 typedef struct _StaticShellEntry_
 {
-    LPWSTR szVerb;
+    CStringW Verb;
     HKEY hkClass;
-    struct _StaticShellEntry_ *pNext;
 } StaticShellEntry, *PStaticShellEntry;
 
 
@@ -69,10 +67,10 @@ class CDefaultContextMenu :
         UINT m_cKeys;
         PIDLIST_ABSOLUTE m_pidlFolder;
         DWORD m_bGroupPolicyActive;
-        PDynamicShellEntry m_pDynamicEntries; /* first dynamic shell extension 
entry */
+        CAtlList<DynamicShellEntry> m_DynamicEntries;
         UINT m_iIdSHEFirst; /* first used id */
         UINT m_iIdSHELast; /* last used id */
-        PStaticShellEntry m_pStaticEntries; /* first static shell extension 
entry */
+        CAtlList<StaticShellEntry> m_StaticEntries;
         UINT m_iIdSCMFirst; /* first static used id */
         UINT m_iIdSCMLast; /* last static used id */
         UINT m_iIdCBFirst; /* first callback used id */
@@ -83,8 +81,8 @@ class CDefaultContextMenu :
         HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam);
         void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
         void AddStaticEntriesForKey(HKEY hKey);
-        BOOL IsShellExtensionAlreadyLoaded(const CLSID *pclsid);
-        HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid);
+        BOOL IsShellExtensionAlreadyLoaded(REFCLSID clsid);
+        HRESULT LoadDynamicContextMenuHandler(HKEY hKey, REFCLSID clsid);
         BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey);
         UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT 
idCmdFirst, UINT idCmdLast);
         UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT 
iIdCmdFirst, UINT iIdCmdLast);
@@ -145,41 +143,21 @@ CDefaultContextMenu::CDefaultContextMenu() :
     m_cKeys(NULL),
     m_pidlFolder(NULL),
     m_bGroupPolicyActive(0),
-    m_pDynamicEntries(NULL),
     m_iIdSHEFirst(0),
     m_iIdSHELast(0),
-    m_pStaticEntries(NULL),
     m_iIdSCMFirst(0),
     m_iIdSCMLast(0),
     m_iIdCBFirst(0),
     m_iIdCBLast(0),
     m_iIdDfltFirst(0),
     m_iIdDfltLast(0)
-
 {
 }
 
 CDefaultContextMenu::~CDefaultContextMenu()
 {
-    /* Free dynamic shell extension entries */
-    PDynamicShellEntry pDynamicEntry = m_pDynamicEntries, pNextDynamic;
-    while (pDynamicEntry)
-    {
-        pNextDynamic = pDynamicEntry->pNext;
-        pDynamicEntry->pCM->Release();
-        HeapFree(GetProcessHeap(), 0, pDynamicEntry);
-        pDynamicEntry = pNextDynamic;
-    }
-
-    /* Free static shell extension entries */
-    PStaticShellEntry pStaticEntry = m_pStaticEntries, pNextStatic;
-    while (pStaticEntry)
-    {
-        pNextStatic = pStaticEntry->pNext;
-        HeapFree(GetProcessHeap(), 0, pStaticEntry->szVerb);
-        HeapFree(GetProcessHeap(), 0, pStaticEntry);
-        pStaticEntry = pNextStatic;
-    }
+    m_DynamicEntries.RemoveAll();
+    m_StaticEntries.RemoveAll();
 
     for (UINT i = 0; i < m_cKeys; i++)
         RegCloseKey(m_aKeys[i]);
@@ -253,40 +231,28 @@ HRESULT CDefaultContextMenu::_DoCallback(UINT uMsg, 
WPARAM wParam, LPVOID lParam
 
 void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR 
*szVerb)
 {
-    PStaticShellEntry pEntry = m_pStaticEntries, pLastEntry = NULL;
-    while(pEntry)
+    POSITION it = m_StaticEntries.GetHeadPosition();
+    while (it != NULL)
     {
-        if (!wcsicmp(pEntry->szVerb, szVerb))
+        const StaticShellEntry& info = m_StaticEntries.GetNext(it);
+        if (info.Verb.CompareNoCase(szVerb) == 0)
         {
             /* entry already exists */
             return;
         }
-        pLastEntry = pEntry;
-        pEntry = pEntry->pNext;
     }
 
     TRACE("adding verb %s\n", debugstr_w(szVerb));
 
-    pEntry = (StaticShellEntry *)HeapAlloc(GetProcessHeap(), 0, 
sizeof(StaticShellEntry));
-    if (pEntry)
-    {
-        pEntry->pNext = NULL;
-        pEntry->szVerb = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, 
(wcslen(szVerb) + 1) * sizeof(WCHAR));
-        if (pEntry->szVerb)
-            wcscpy(pEntry->szVerb, szVerb);
-        pEntry->hkClass = hkeyClass;
-    }
-
     if (!wcsicmp(szVerb, L"open"))
     {
         /* open verb is always inserted in front */
-        pEntry->pNext = m_pStaticEntries;
-        m_pStaticEntries = pEntry;
+        m_StaticEntries.AddHead({ szVerb, hkeyClass });
     }
-    else if (pLastEntry)
-        pLastEntry->pNext = pEntry;
     else
-        m_pStaticEntries = pEntry;
+    {
+        m_StaticEntries.AddTail({ szVerb, hkeyClass });
+    }
 }
 
 void CDefaultContextMenu::AddStaticEntriesForKey(HKEY hKey)
@@ -333,35 +299,33 @@ HasClipboardData()
 }
 
 BOOL
-CDefaultContextMenu::IsShellExtensionAlreadyLoaded(const CLSID *pclsid)
+CDefaultContextMenu::IsShellExtensionAlreadyLoaded(REFCLSID clsid)
 {
-    PDynamicShellEntry pEntry = m_pDynamicEntries;
-
-    while (pEntry)
+    POSITION it = m_DynamicEntries.GetHeadPosition();
+    while (it != NULL)
     {
-        if (!memcmp(&pEntry->ClassID, pclsid, sizeof(CLSID)))
+        const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
+        if (info.ClassID == clsid)
             return TRUE;
-        pEntry = pEntry->pNext;
     }
 
     return FALSE;
 }
 
 HRESULT
-CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID 
*pclsid)
+CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, REFCLSID clsid)
 {
     HRESULT hr;
+    TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid 
%s\n", this, hKey, wine_dbgstr_guid(&clsid));
 
-    TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid 
%s\n", this, hKey, wine_dbgstr_guid(pclsid));
-
-    if (IsShellExtensionAlreadyLoaded(pclsid))
+    if (IsShellExtensionAlreadyLoaded(clsid))
         return S_OK;
 
     CComPtr<IContextMenu> pcm;
-    hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_PPV_ARG(IContextMenu, 
&pcm));
+    hr = SHCoCreateInstance(NULL, &clsid, NULL, IID_PPV_ARG(IContextMenu, 
&pcm));
     if (FAILED(hr))
     {
-        ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", 
wine_dbgstr_guid(pclsid), hr);
+        ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", 
wine_dbgstr_guid(&clsid), hr);
         return hr;
     }
 
@@ -369,41 +333,21 @@ CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY 
hKey, const CLSID *pclsi
     hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
     if (FAILED(hr))
     {
-        ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 
0x%x\n", wine_dbgstr_guid(pclsid), hr);
+        ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 
0x%x\n", wine_dbgstr_guid(&clsid), hr);
         return hr;
     }
 
     hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
     if (FAILED(hr))
     {
-        WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", 
wine_dbgstr_guid(pclsid), hr);
+        WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", 
wine_dbgstr_guid(&clsid), hr);
         return hr;
     }
 
     if (m_site)
         IUnknown_SetSite(pcm, m_site);
 
-    PDynamicShellEntry pEntry = (DynamicShellEntry 
*)HeapAlloc(GetProcessHeap(), 0, sizeof(DynamicShellEntry));
-    if (!pEntry)
-        return E_OUTOFMEMORY;
-
-    pEntry->iIdCmdFirst = 0;
-    pEntry->pNext = NULL;
-    pEntry->NumIds = 0;
-    pEntry->pCM = pcm.Detach();
-    memcpy(&pEntry->ClassID, pclsid, sizeof(CLSID));
-
-    if (m_pDynamicEntries)
-    {
-        PDynamicShellEntry pLastEntry = m_pDynamicEntries;
-
-        while (pLastEntry->pNext)
-            pLastEntry = pLastEntry->pNext;
-
-        pLastEntry->pNext = pEntry;
-    }
-    else
-        m_pDynamicEntries = pEntry;
+    m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
 
     return S_OK;
 }
@@ -463,7 +407,7 @@ 
CDefaultContextMenu::EnumerateDynamicContextHandlerForKey(HKEY hRootKey)
             }
         }
 
-        hr = LoadDynamicContextMenuHandler(hKey, &clsid);
+        hr = LoadDynamicContextMenuHandler(hKey, clsid);
         if (FAILED(hr))
             WARN("Failed to get context menu entires from shell extension! 
clsid: %S\n", pwszClsid);
     }
@@ -477,27 +421,27 @@ CDefaultContextMenu::AddShellExtensionsToMenu(HMENU 
hMenu, UINT* pIndexMenu, UIN
 {
     UINT cIds = 0;
 
-    if (!m_pDynamicEntries)
+    if (m_DynamicEntries.IsEmpty())
         return cIds;
 
-    PDynamicShellEntry pEntry = m_pDynamicEntries;
-    do
+    POSITION it = m_DynamicEntries.GetHeadPosition();
+    while (it != NULL)
     {
-        HRESULT hr = pEntry->pCM->QueryContextMenu(hMenu, *pIndexMenu, 
idCmdFirst + cIds, idCmdLast, CMF_NORMAL);
+        DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
+
+        HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst 
+ cIds, idCmdLast, CMF_NORMAL);
         if (SUCCEEDED(hr))
         {
-            pEntry->iIdCmdFirst = cIds;
-            pEntry->NumIds = LOWORD(hr);
-            (*pIndexMenu) += pEntry->NumIds;
+            info.iIdCmdFirst = cIds;
+            info.NumIds = LOWORD(hr);
+            (*pIndexMenu) += info.NumIds;
 
-            cIds += pEntry->NumIds;
-            if(idCmdFirst + cIds >= idCmdLast)
+            cIds += info.NumIds;
+            if (idCmdFirst + cIds >= idCmdLast)
                 break;
         }
-        TRACE("pEntry %p hr %x contextmenu %p cmdfirst %x num ids %x\n", 
pEntry, hr, pEntry->pCM, pEntry->iIdCmdFirst, pEntry->NumIds);
-        pEntry = pEntry->pNext;
-    } while (pEntry);
-
+        TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, 
info.pCM.p, info.iIdCmdFirst, info.NumIds);
+    }
     return cIds;
 }
 
@@ -519,50 +463,53 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
     mii.fType = MFT_STRING;
     mii.dwTypeData = NULL;
 
-    PStaticShellEntry pEntry = m_pStaticEntries;
-
-    while (pEntry)
+    POSITION it = m_StaticEntries.GetHeadPosition();
+    bool first = true;
+    while (it != NULL)
     {
+        StaticShellEntry& info = m_StaticEntries.GetNext(it);
+
         fState = MFS_ENABLED;
         mii.dwTypeData = NULL;
 
         /* set first entry as default */
-        if (pEntry == m_pStaticEntries)
+        if (first)
+        {
             fState |= MFS_DEFAULT;
+            first = false;
+        }
 
-        if (!wcsicmp(pEntry->szVerb, L"open"))
+        if (info.Verb.CompareNoCase(L"open") == 0)
         {
             /* override default when open verb is found */
             fState |= MFS_DEFAULT;
             idResource = IDS_OPEN_VERB;
         }
-        else if (!wcsicmp(pEntry->szVerb, L"explore"))
+        else if (info.Verb.CompareNoCase(L"explore") == 0)
             idResource = IDS_EXPLORE_VERB;
-        else if (!wcsicmp(pEntry->szVerb, L"runas"))
+        else if (info.Verb.CompareNoCase(L"runas") == 0)
             idResource = IDS_RUNAS_VERB;
-        else if (!wcsicmp(pEntry->szVerb, L"edit"))
+        else if (info.Verb.CompareNoCase(L"edit") == 0)
             idResource = IDS_EDIT_VERB;
-        else if (!wcsicmp(pEntry->szVerb, L"find"))
+        else if (info.Verb.CompareNoCase(L"find") == 0)
             idResource = IDS_FIND_VERB;
-        else if (!wcsicmp(pEntry->szVerb, L"print"))
+        else if (info.Verb.CompareNoCase(L"print") == 0)
             idResource = IDS_PRINT_VERB;
-        else if (!wcsicmp(pEntry->szVerb, L"printto"))
+        else if (info.Verb.CompareNoCase(L"printto") == 0)
         {
-            pEntry = pEntry->pNext;
             continue;
         }
         else
             idResource = 0;
 
         /* By default use verb for menu item name */
-        mii.dwTypeData = pEntry->szVerb;
+        mii.dwTypeData = (LPWSTR)info.Verb.GetString();
 
         WCHAR wszKey[256];
         HRESULT hr;
-        hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", 
pEntry->szVerb);
+        hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", 
info.Verb.GetString());
         if (FAILED_UNEXPECTEDLY(hr))
         {
-            pEntry = pEntry->pNext;
             continue;
         }
 
@@ -575,7 +522,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
             else
                 ERR("Failed to load string\n");
 
-            LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
+            LONG res = RegOpenKeyW(info.hkClass, wszKey, &hkVerb);
             if (res == ERROR_SUCCESS)
             {
                 res = RegQueryValueExW(hkVerb, L"Extended", NULL, NULL, NULL, 
NULL);
@@ -586,7 +533,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
         }
         else
         {
-            LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
+            LONG res = RegOpenKeyW(info.hkClass, wszKey, &hkVerb);
             if (res == ERROR_SUCCESS)
             {
                 DWORD cbVerb = sizeof(wszVerb);
@@ -614,8 +561,6 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
             cIds++;
         }
 
-        pEntry = pEntry->pNext;
-
         if (mii.wID >= iIdCmdLast)
             break;
     }
@@ -1001,18 +946,21 @@ CDefaultContextMenu::DoCreateNewFolder(
 
 PDynamicShellEntry CDefaultContextMenu::GetDynamicEntry(UINT idCmd)
 {
-    PDynamicShellEntry pEntry = m_pDynamicEntries;
+    POSITION it = m_DynamicEntries.GetHeadPosition();
+    while (it != NULL)
+    {
+        DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
 
-    while(pEntry && idCmd >= pEntry->iIdCmdFirst + pEntry->NumIds)
-        pEntry = pEntry->pNext;
+        if (idCmd >= info.iIdCmdFirst + info.NumIds)
+            continue;
 
-    if (!pEntry)
-        return NULL;
+        if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
+            return NULL;
 
-    if (idCmd < pEntry->iIdCmdFirst || idCmd > pEntry->iIdCmdFirst + 
pEntry->NumIds)
-        return NULL;
+        return &info;
+    }
 
-    return pEntry;
+    return NULL;
 }
 
 // FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
@@ -1093,7 +1041,7 @@ 
CDefaultContextMenu::BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticSh
         FlagsName = L"BrowserFlags";
 
     /* Try to get the flag from the verb */
-    hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->szVerb);
+    hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", 
pEntry->Verb.GetString());
     if (FAILED_UNEXPECTEDLY(hr))
         return 0;
 
@@ -1152,7 +1100,7 @@ CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFO 
lpcmi, LPCITEMIDLIST pidl,
     sei.cbSize = sizeof(sei);
     sei.hwnd = lpcmi->hwnd;
     sei.nShow = SW_SHOWNORMAL;
-    sei.lpVerb = pEntry->szVerb;
+    sei.lpVerb = pEntry->Verb;
     sei.lpDirectory = wszDir;
     sei.lpIDList = pidlFull;
     sei.hkeyClass = pEntry->hkClass;
@@ -1173,16 +1121,16 @@ HRESULT
 CDefaultContextMenu::InvokeRegVerb(
     LPCMINVOKECOMMANDINFO lpcmi)
 {
-    PStaticShellEntry pEntry = m_pStaticEntries;
-    INT iCmd = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst;
+    INT iCmd = LOWORD(lpcmi->lpVerb);
     HRESULT hr;
     UINT i;
 
-    while (pEntry && (iCmd--) > 0)
-        pEntry = pEntry->pNext;
+    POSITION it = m_StaticEntries.FindIndex(iCmd);
 
-    if (iCmd > 0)
-        return E_FAIL;
+    if (it == NULL)
+        return E_INVALIDARG;
+
+    PStaticShellEntry pEntry = &m_StaticEntries.GetAt(it);
 
     /* Get the browse flags to see if we need to browse */
     DWORD wFlags = BrowserFlagsFromVerb(lpcmi, pEntry);
@@ -1236,14 +1184,14 @@ CDefaultContextMenu::InvokeCommand(
 
     CmdId = LOWORD(LocalInvokeInfo.lpVerb);
 
-    if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
+    if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < 
m_iIdSHELast)
     {
         LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
         Result = InvokeShellExt(&LocalInvokeInfo);
         return Result;
     }
 
-    if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
+    if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < 
m_iIdSCMLast)
     {
         LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
         Result = InvokeRegVerb(&LocalInvokeInfo);
@@ -1332,7 +1280,7 @@ CDefaultContextMenu::GetCommandString(
 
     UINT CmdId = LOWORD(idCommand);
 
-    if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
+    if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < 
m_iIdSHELast)
     {
         idCommand -= m_iIdSHEFirst;
         PDynamicShellEntry pEntry = GetDynamicEntry(idCommand);
@@ -1347,7 +1295,7 @@ CDefaultContextMenu::GetCommandString(
                                              uMaxNameLen);
     }
 
-    if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
+    if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < 
m_iIdSCMLast)
     {
         /* Validation just returns S_OK on a match. The id exists. */
         if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
@@ -1355,19 +1303,19 @@ CDefaultContextMenu::GetCommandString(
 
         CmdId -= m_iIdSCMFirst;
 
-        PStaticShellEntry pEntry = m_pStaticEntries;
-        while (pEntry && (CmdId--) > 0)
-            pEntry = pEntry->pNext;
+        POSITION it = m_StaticEntries.FindIndex(CmdId);
 
-        if (!pEntry)
+        if (it == NULL)
             return E_INVALIDARG;
 
+        PStaticShellEntry pEntry = &m_StaticEntries.GetAt(it);
+
         if (uFlags == GCS_VERBW)
-            return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, 
pEntry->szVerb);
+            return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
 
         if (uFlags == GCS_VERBA)
         {
-            if (SHUnicodeToAnsi(pEntry->szVerb, lpszName, uMaxNameLen))
+            if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
                 return S_OK;
         }
 
@@ -1464,11 +1412,11 @@ CDefaultContextMenu::HandleMenuMsg2(
 {
     if (uMsg == WM_INITMENUPOPUP)
     {
-        PDynamicShellEntry pEntry = m_pDynamicEntries;
-        while (pEntry)
+        POSITION it = m_DynamicEntries.GetHeadPosition();
+        while (it != NULL)
         {
-            SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, 
plResult, TRUE);
-            pEntry = pEntry->pNext;
+            DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
+            SHForwardContextMenuMsg(info.pCM, uMsg, wParam, lParam, plResult, 
TRUE);
         }
         return S_OK;
     }
diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h
index 9ae77f4b794..9b422353e6c 100644
--- a/dll/win32/shell32/precomp.h
+++ b/dll/win32/shell32/precomp.h
@@ -32,6 +32,7 @@
 #include <atlwin.h>
 #include <atlstr.h>
 #include <atlsimpcoll.h>
+#include <atlcoll.h>
 #include <powrprof.h>
 #include <winnetwk.h>
 #include <objsafe.h>

Reply via email to