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

commit fd626dc163ce2c5a49385bb515c5bdc4c2d93a54
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Sep 17 19:52:50 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sun Sep 17 19:52:50 2023 +0900

    [SHDOCVW] Implement MRU List for Shell Bag, Part 5 (#5691)
    
    Follow-up to #5686.
    Implement CSafeMutex and CMruPidlList classes.
    CORE-9283
---
 dll/win32/shdocvw/mrulist.cpp      | 348 +++++++++++++++++++++++++++----------
 dll/win32/shdocvw/shdocvw.h        |   1 +
 dll/win32/shdocvw/shdocvw_main.c   |   4 +
 sdk/include/reactos/shlobj_undoc.h |   6 +-
 4 files changed, 266 insertions(+), 93 deletions(-)

diff --git a/dll/win32/shdocvw/mrulist.cpp b/dll/win32/shdocvw/mrulist.cpp
index f17f4069ff2..a81aa01315a 100644
--- a/dll/win32/shdocvw/mrulist.cpp
+++ b/dll/win32/shdocvw/mrulist.cpp
@@ -24,6 +24,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
 
+class CSafeMutex;
 class CMruBase;
     class CMruShortList;
     class CMruLongList;
@@ -57,6 +58,35 @@ BOOL IEILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, 
BOOL bUnknown)
 #define COMPARE_BY_IEILISEQUAL  0x3
 #define COMPARE_BY_MASK         0xF
 
+class CSafeMutex
+{
+protected:
+    HANDLE m_hMutex;
+
+public:
+    CSafeMutex() : m_hMutex(NULL)
+    {
+    }
+    ~CSafeMutex()
+    {
+        if (m_hMutex)
+        {
+            ::ReleaseMutex(m_hMutex);
+            m_hMutex = NULL;
+        }
+    }
+
+    HRESULT Enter(HANDLE hMutex)
+    {
+        DWORD wait = ::WaitForSingleObject(hMutex, 500);
+        if (wait != WAIT_OBJECT_0)
+            return E_FAIL;
+
+        m_hMutex = hMutex;
+        return S_OK;
+    }
+};
+
 class CMruBase
     : public IMruDataList
 {
@@ -72,7 +102,7 @@ protected:
     SLOTITEMDATA *  m_pSlots        = NULL;     // Slot data
 
     HRESULT _LoadItem(UINT iSlot);
-    HRESULT _AddItem(UINT iSlot, const BYTE *pbData, DWORD cbData);
+    HRESULT _AddItem(UINT iSlot, LPCVOID pvData, DWORD cbData);
     HRESULT _GetItem(UINT iSlot, SLOTITEMDATA **ppItem);
     void _DeleteItem(UINT iSlot);
 
@@ -96,9 +126,9 @@ public:
     STDMETHODIMP InitData(UINT cCapacity, UINT flags, HKEY hKey,
                           LPCWSTR pszSubKey OPTIONAL,
                           SLOTCOMPARE fnCompare OPTIONAL) override;
-    STDMETHODIMP AddData(const BYTE *pbData, DWORD cbData, UINT *piSlot) 
override;
-    STDMETHODIMP FindData(const BYTE *pbData, DWORD cbData, UINT *piSlot) 
override;
-    STDMETHODIMP GetData(UINT iSlot, BYTE *pbData, DWORD cbData) override;
+    STDMETHODIMP AddData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override;
+    STDMETHODIMP FindData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override;
+    STDMETHODIMP GetData(UINT iSlot, LPVOID pvData, DWORD cbData) override;
     STDMETHODIMP QueryInfo(UINT iSlot, UINT *puSlot, DWORD *pcbData) override;
     STDMETHODIMP Delete(UINT iSlot) override;
 
@@ -241,14 +271,14 @@ void CMruBase::_CheckUsedSlots()
     m_bChecked = TRUE;
 }
 
-HRESULT CMruBase::_AddItem(UINT iSlot, const BYTE *pbData, DWORD cbData)
+HRESULT CMruBase::_AddItem(UINT iSlot, LPCVOID pvData, DWORD cbData)
 {
     SLOTITEMDATA *pItem = &m_pSlots[iSlot];
 
     WCHAR szBuff[12];
     _SlotString(iSlot, szBuff, _countof(szBuff));
 
-    if (SHSetValueW(m_hKey, NULL, szBuff, REG_BINARY, pbData, cbData) != 
ERROR_SUCCESS)
+    if (SHSetValueW(m_hKey, NULL, szBuff, REG_BINARY, pvData, cbData) != 
ERROR_SUCCESS)
         return E_OUTOFMEMORY;
 
     if (cbData >= pItem->cbData || !pItem->pvData)
@@ -262,7 +292,7 @@ HRESULT CMruBase::_AddItem(UINT iSlot, const BYTE *pbData, 
DWORD cbData)
 
     pItem->cbData = cbData;
     pItem->dwFlags = (SLOT_LOADED | SLOT_SET);
-    CopyMemory(pItem->pvData, pbData, cbData);
+    CopyMemory(pItem->pvData, pvData, cbData);
     return S_OK;
 }
 
@@ -293,14 +323,14 @@ CMruBase::InitData(
     return _InitSlots();
 }
 
-STDMETHODIMP CMruBase::AddData(const BYTE *pbData, DWORD cbData, UINT *piSlot)
+STDMETHODIMP CMruBase::AddData(LPCVOID pvData, DWORD cbData, UINT *piSlot)
 {
     UINT iSlot;
-    HRESULT hr = FindData(pbData, cbData, &iSlot);
+    HRESULT hr = FindData(pvData, cbData, &iSlot);
     if (FAILED(hr))
     {
         iSlot = _UpdateSlots(m_cSlots);
-        hr = _AddItem(iSlot, pbData, cbData);
+        hr = _AddItem(iSlot, pvData, cbData);
         if (FAILED(hr))
             return hr;
     }
@@ -316,14 +346,14 @@ STDMETHODIMP CMruBase::AddData(const BYTE *pbData, DWORD 
cbData, UINT *piSlot)
     return hr;
 }
 
-STDMETHODIMP CMruBase::FindData(const BYTE *pbData, DWORD cbData, UINT *piSlot)
+STDMETHODIMP CMruBase::FindData(LPCVOID pvData, DWORD cbData, UINT *piSlot)
 {
     if (m_cSlots <= 0)
         return E_FAIL;
 
     UINT iSlot = 0;
     SLOTITEMDATA *pItem;
-    while (FAILED(_GetItem(iSlot, &pItem)) || !_IsEqual(pItem, pbData, cbData))
+    while (FAILED(_GetItem(iSlot, &pItem)) || !_IsEqual(pItem, pvData, cbData))
     {
         if (++iSlot >= m_cSlots)
             return E_FAIL;
@@ -333,7 +363,7 @@ STDMETHODIMP CMruBase::FindData(const BYTE *pbData, DWORD 
cbData, UINT *piSlot)
     return S_OK;
 }
 
-STDMETHODIMP CMruBase::GetData(UINT iSlot, BYTE *pbData, DWORD cbData)
+STDMETHODIMP CMruBase::GetData(UINT iSlot, LPVOID pvData, DWORD cbData)
 {
     SLOTITEMDATA *pItem;
     HRESULT hr = _GetItem(iSlot, &pItem);
@@ -343,7 +373,7 @@ STDMETHODIMP CMruBase::GetData(UINT iSlot, BYTE *pbData, 
DWORD cbData)
     if (cbData < pItem->cbData)
         return 0x8007007A; // FIXME: Magic number
 
-    CopyMemory(pbData, pItem->pvData, pItem->cbData);
+    CopyMemory(pvData, pItem->pvData, pItem->cbData);
     return hr;
 }
 
@@ -694,7 +724,7 @@ void CMruLongList::_ImportShortList()
             if (FAILED(hr))
                 break;
 
-            _AddItem(iSlot, (const BYTE*)pItem->pvData, pItem->cbData);
+            _AddItem(iSlot, pItem->pvData, pItem->cbData);
             pShortList->_DeleteItem(iSlot);
 
             m_puSlotData[m_cSlots++] = iSlot;
@@ -751,10 +781,10 @@ public:
 
     HRESULT BindToSlot(UINT iSlot, IShellFolder **ppSF);
     HRESULT GetNode(BOOL bAdd, LPCITEMIDLIST pidl, CMruNode **pNewNode);
-    HRESULT GetNodeSlot(UINT *piSlot);
-    HRESULT SetNodeSlot(UINT iSlot);
+    HRESULT GetNodeSlot(UINT *pnNodeSlot);
+    HRESULT SetNodeSlot(UINT nNodeSlot);
 
-    HRESULT RemoveLeast(UINT *piSlot);
+    HRESULT RemoveLeast(UINT *pnNodeSlot);
     HRESULT Clear(CMruPidlList *pList);
 };
 
@@ -793,10 +823,10 @@ HRESULT CMruNode::_CreateNode(UINT iSlot, CMruNode 
**ppNewNode)
     if (!pNewNode)
         return E_OUTOFMEMORY;
 
-    WCHAR szBuff[12];
-    _SlotString(iSlot, szBuff, _countof(szBuff));
+    WCHAR szSubKey[12];
+    _SlotString(iSlot, szSubKey, _countof(szSubKey));
 
-    HRESULT hr = pNewNode->InitData(m_cSlotRooms, 0, m_hKey, szBuff, NULL);
+    HRESULT hr = pNewNode->InitData(m_cSlotRooms, 0, m_hKey, szSubKey, NULL);
     if (FAILED(hr))
         pNewNode->Release();
     else
@@ -876,19 +906,19 @@ BOOL CMruNode::_IsEqual(SLOTITEMDATA *pItem, LPCVOID 
pvData, UINT cbData)
                                       (LPCITEMIDLIST)pvData) == 0;
 }
 
-HRESULT CMruNode::GetNodeSlot(UINT *piSlot)
+HRESULT CMruNode::GetNodeSlot(UINT *pnNodeSlot)
 {
     DWORD dwData, cbData = sizeof(dwData);
-    DWORD error = SHGetValueW(m_hKey, NULL, L"NodeSlot", NULL, &dwData, 
(piSlot ? &cbData : NULL));
+    DWORD error = SHGetValueW(m_hKey, NULL, L"NodeSlot", NULL, &dwData, 
(pnNodeSlot ? &cbData : NULL));
     if (error != ERROR_SUCCESS)
         return E_FAIL;
-    *piSlot = (UINT)dwData;
+    *pnNodeSlot = (UINT)dwData;
     return S_OK;
 }
 
-HRESULT CMruNode::SetNodeSlot(UINT iSlot)
+HRESULT CMruNode::SetNodeSlot(UINT nNodeSlot)
 {
-    DWORD dwData = iSlot;
+    DWORD dwData = nNodeSlot;
     if (SHSetValueW(m_hKey, NULL, L"NodeSlot", REG_DWORD, &dwData, 
sizeof(dwData)) != ERROR_SUCCESS)
         return E_FAIL;
     return S_OK;
@@ -896,7 +926,7 @@ HRESULT CMruNode::SetNodeSlot(UINT iSlot)
 
 HRESULT CMruNode::_AddPidl(UINT iSlot, LPCITEMIDLIST pidl)
 {
-    return CMruBase::_AddItem(iSlot, (const BYTE*)pidl, sizeof(WORD) + 
pidl->mkid.cb);
+    return CMruBase::_AddItem(iSlot, pidl, sizeof(WORD) + pidl->mkid.cb);
 }
 
 DWORD CMruNode::_DeleteValue(LPCWSTR pszValue)
@@ -907,7 +937,7 @@ DWORD CMruNode::_DeleteValue(LPCWSTR pszValue)
 
 HRESULT CMruNode::_FindPidl(LPCITEMIDLIST pidl, UINT *piSlot)
 {
-    return FindData((const BYTE *)pidl, sizeof(WORD) + pidl->mkid.cb, piSlot);
+    return FindData(pidl, sizeof(WORD) + pidl->mkid.cb, piSlot);
 }
 
 HRESULT CMruNode::_GetPidlSlot(LPCITEMIDLIST pidl, BOOL bAdd, UINT *piSlot)
@@ -933,11 +963,11 @@ HRESULT CMruNode::_GetPidlSlot(LPCITEMIDLIST pidl, BOOL 
bAdd, UINT *piSlot)
     return hr;
 }
 
-HRESULT CMruNode::RemoveLeast(UINT *piSlot)
+HRESULT CMruNode::RemoveLeast(UINT *pnNodeSlot)
 {
     if (!m_cSlots)
     {
-        CMruNode::GetNodeSlot(piSlot);
+        GetNodeSlot(pnNodeSlot);
         return S_FALSE;
     }
 
@@ -947,10 +977,10 @@ HRESULT CMruNode::RemoveLeast(UINT *piSlot)
         return hr;
 
     CMruNode *pNode;
-    hr = CMruNode::_CreateNode(uSlot, &pNode);
+    hr = _CreateNode(uSlot, &pNode);
     if (SUCCEEDED(hr))
     {
-        hr = pNode->RemoveLeast(piSlot);
+        hr = pNode->RemoveLeast(pnNodeSlot);
         pNode->Release();
     }
 
@@ -965,42 +995,24 @@ HRESULT CMruNode::RemoveLeast(UINT *piSlot)
 }
 
 class CMruPidlList
-    : public IMruPidlList
-    , public CMruNode
+    : public CMruNode
+    , public IMruPidlList
 {
 protected:
-    LPBYTE m_pbSlots = NULL;        // The data
-    DWORD m_cbSlots = 0;            // The data size
+    LPBYTE m_pbNodeSlots = NULL;    // The node slots (contains SLOT_... flags)
+    DWORD m_cMaxNodeSlots = 0;      // The upper bound of the node slot index
     HANDLE m_hMutex = NULL;         // The mutex (for sync)
 
-    BOOL _LoadNodeSlots()
-    {
-        DWORD cbSlots = m_cbSlots;
-        if (SHGetValueW(m_hKey, NULL, L"NodeSlots", NULL, m_pbSlots, &cbSlots) 
!= ERROR_SUCCESS)
-            return FALSE;
-        m_cbSlots = cbSlots;
-        return TRUE;
-    }
-
-    void _SaveNodeSlots()
-    {
-        SHSetValueW(m_hKey, NULL, L"NodeSlots", REG_BINARY, m_pbSlots, 
m_cbSlots);
-    }
+    BOOL _LoadNodeSlots();
+    void _SaveNodeSlots();
+    HRESULT _InitNodeSlots();
 
 public:
-    CMruPidlList()
-    {
-    }
+    CMruPidlList() { }
+    ~CMruPidlList() override;
 
-    virtual ~CMruPidlList()
-    {
-        m_pbSlots = (LPBYTE)::LocalFree(m_pbSlots);
-        if (m_hMutex)
-        {
-            ::CloseHandle(m_hMutex);
-            m_hMutex = NULL;
-        }
-    }
+    HRESULT GetEmptySlot(UINT *pnNodeSlot);
+    void EmptyNodeSlot(UINT nNodeSlot);
 
     // IUnknown methods
     STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
@@ -1014,18 +1026,26 @@ public:
     }
 
     // IMruPidlList methods
-    STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszName) override;
-    STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *puSlots) override;
+    STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszSubKey) 
override;
+    STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot) override;
     STDMETHODIMP QueryPidl(
         LPCITEMIDLIST pidl,
         UINT cSlots,
-        UINT *puSlots,
-        UINT *pcSlots) override;
+        UINT *pnNodeSlots,
+        UINT *pcNodeSlots) override;
     STDMETHODIMP PruneKids(LPCITEMIDLIST pidl) override;
-
-    void EmptyNodeSlot(UINT iSlot);
 };
 
+CMruPidlList::~CMruPidlList()
+{
+    m_pbNodeSlots = (LPBYTE)::LocalFree(m_pbNodeSlots);
+    if (m_hMutex)
+    {
+        ::CloseHandle(m_hMutex);
+        m_hMutex = NULL;
+    }
+}
+
 STDMETHODIMP CMruPidlList::QueryInterface(REFIID riid, void **ppvObj)
 {
     if (!ppvObj)
@@ -1042,32 +1062,182 @@ STDMETHODIMP CMruPidlList::QueryInterface(REFIID riid, 
void **ppvObj)
     return E_NOINTERFACE;
 }
 
-STDMETHODIMP CMruPidlList::InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszName)
+BOOL CMruPidlList::_LoadNodeSlots()
+{
+    DWORD cbNodeSlots = m_cSlotRooms * sizeof(BYTE);
+    if (SHGetValueW(m_hKey, NULL, L"NodeSlots", NULL, m_pbNodeSlots, 
&cbNodeSlots) != ERROR_SUCCESS)
+        return FALSE;
+    m_cMaxNodeSlots = m_cSlotRooms;
+    return TRUE;
+}
+
+void CMruPidlList::_SaveNodeSlots()
+{
+    DWORD cbNodeSlots = m_cSlotRooms * sizeof(BYTE);
+    SHSetValueW(m_hKey, NULL, L"NodeSlots", REG_BINARY, m_pbNodeSlots, 
cbNodeSlots);
+}
+
+HRESULT CMruPidlList::_InitNodeSlots()
+{
+    m_pbNodeSlots = (BYTE*)LocalAlloc(LPTR, m_cSlotRooms * sizeof(BYTE));
+    if (!m_pbNodeSlots)
+        return E_OUTOFMEMORY;
+
+    _LoadNodeSlots();
+    m_bNeedSave = TRUE;
+    _SaveNodeSlots();
+
+    return S_OK;
+}
+
+HRESULT CMruPidlList::GetEmptySlot(UINT *pnNodeSlot)
+{
+    *pnNodeSlot = 0;
+
+    if (!_LoadNodeSlots())
+        return E_FAIL;
+
+    if (m_cMaxNodeSlots < m_cSlotRooms)
+    {
+        m_pbNodeSlots[m_cMaxNodeSlots] = SLOT_SET;
+        *pnNodeSlot = ++m_cMaxNodeSlots;
+        _SaveNodeSlots();
+        return S_OK;
+    }
+
+    for (UINT iNodeSlot = 0; iNodeSlot < m_cMaxNodeSlots; ++iNodeSlot)
+    {
+        if (m_pbNodeSlots[iNodeSlot] & SLOT_SET)
+            continue;
+
+        m_pbNodeSlots[iNodeSlot] = SLOT_SET;
+        *pnNodeSlot = iNodeSlot + 1; // nNodeSlot is 1-base
+        _SaveNodeSlots();
+        return S_OK;
+    }
+
+    HRESULT hr = E_FAIL;
+    if (SUCCEEDED(RemoveLeast(pnNodeSlot)) && *pnNodeSlot)
+        hr = S_OK;
+
+    _SaveNodeSlots();
+    return hr;
+}
+
+STDMETHODIMP CMruPidlList::InitList(UINT cMRUSize, HKEY hKey, LPCWSTR 
pszSubKey)
 {
-    FIXME("Stub\n");
-    return E_NOTIMPL;
+    HRESULT hr = InitData(cMRUSize, 0, hKey, pszSubKey, NULL);
+    if (FAILED(hr))
+        return hr;
+
+    hr = _InitNodeSlots();
+    if (FAILED(hr))
+        return hr;
+
+    m_hMutex = ::CreateMutexW(NULL, FALSE, L"Shell.CMruPidlList");
+    if (!m_hMutex)
+        hr = HRESULT_FROM_WIN32(GetLastError());
+
+    return hr;
 }
 
-STDMETHODIMP CMruPidlList::UsePidl(LPCITEMIDLIST pidl, UINT *puSlots)
+STDMETHODIMP CMruPidlList::UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot)
 {
-    FIXME("Stub\n");
-    return E_NOTIMPL;
+    CSafeMutex mutex;
+    HRESULT hr = mutex.Enter(m_hMutex);
+    if (FAILED(hr))
+        return hr;
+
+    *pnNodeSlot = 0;
+
+    CMruNode *pNode;
+    hr = GetNode(TRUE, pidl, &pNode);
+    if (FAILED(hr))
+        return hr;
+
+    hr = pNode->GetNodeSlot(pnNodeSlot);
+    if (FAILED(hr))
+    {
+        hr = GetEmptySlot(pnNodeSlot);
+        if (SUCCEEDED(hr))
+        {
+            hr = pNode->SetNodeSlot(*pnNodeSlot);
+        }
+    }
+
+    pNode->Release();
+    return hr;
 }
 
 STDMETHODIMP CMruPidlList::QueryPidl(
     LPCITEMIDLIST pidl,
     UINT cSlots,
-    UINT *puSlots,
-    UINT *pcSlots)
+    UINT *pnNodeSlots,
+    UINT *pcNodeSlots)
 {
-    FIXME("Stub\n");
-    return E_NOTIMPL;
+    CSafeMutex mutex;
+    HRESULT hr = mutex.Enter(m_hMutex);
+    if (FAILED(hr))
+        return hr;
+
+    *pcNodeSlots = 0;
+
+    CMruNode *pNode;
+    hr = GetNode(FALSE, pidl, &pNode);
+    if (FAILED(hr))
+        return hr;
+
+    while (pNode && *pcNodeSlots < cSlots)
+    {
+        CMruNode *pParent = pNode->GetParent();
+        if (SUCCEEDED(pNode->GetNodeSlot(&pnNodeSlots[*pcNodeSlots])))
+            ++(*pcNodeSlots);
+        else if (hr == S_OK && !*pcNodeSlots)
+            hr = S_FALSE;
+
+        pNode->Release();
+        pNode = pParent;
+    }
+
+    if (pNode)
+        pNode->Release();
+
+    if (SUCCEEDED(hr) && !*pcNodeSlots)
+        hr = E_FAIL;
+
+    return hr;
 }
 
 STDMETHODIMP CMruPidlList::PruneKids(LPCITEMIDLIST pidl)
 {
-    FIXME("Stub\n");
-    return E_NOTIMPL;
+    CSafeMutex mutex;
+    HRESULT hr = mutex.Enter(m_hMutex);
+    if (FAILED(hr))
+        return hr;
+
+    if (!_LoadNodeSlots())
+        return hr;
+
+    CMruNode *pNode;
+    hr = GetNode(FALSE, pidl, &pNode);
+    if (FAILED(hr))
+        return hr;
+
+    if (hr == S_OK)
+        hr = pNode->Clear(this);
+    else
+        hr = E_FAIL;
+
+    pNode->Release();
+
+    _SaveNodeSlots();
+    return hr;
+}
+
+void CMruPidlList::EmptyNodeSlot(UINT nNodeSlot)
+{
+    m_pbNodeSlots[nNodeSlot - 1] = 0; // nNodeSlot is 1-base
+    m_bNeedSave = TRUE;
 }
 
 EXTERN_C HRESULT CMruPidlList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, 
DWORD_PTR dwUnused3)
@@ -1091,29 +1261,27 @@ EXTERN_C HRESULT CMruPidlList_CreateInstance(DWORD_PTR 
dwUnused1, void **ppv, DW
     return S_OK;
 }
 
-void CMruPidlList::EmptyNodeSlot(UINT iSlot)
-{
-    m_pbSlots[iSlot - 1] = 0;
-    m_bNeedSave = TRUE;
-}
-
 HRESULT CMruNode::Clear(CMruPidlList *pList)
 {
-    UINT uSlot;
+    UINT uSlot, nNodeSlot;
+    HRESULT hr;
+
     while (SUCCEEDED(_GetSlot(0, &uSlot)))
     {
         CMruNode *pNode;
-        if (SUCCEEDED(CMruNode::_CreateNode(uSlot, &pNode)))
+        hr = _CreateNode(uSlot, &pNode);
+        if (SUCCEEDED(hr))
         {
-            UINT iSlot;
-            if (SUCCEEDED(pNode->GetNodeSlot(&iSlot)))
-                pList->EmptyNodeSlot(iSlot);
+            hr = pNode->GetNodeSlot(&nNodeSlot);
+            if (SUCCEEDED(hr))
+                pList->EmptyNodeSlot(nNodeSlot);
 
             pNode->Clear(pList);
             pNode->Release();
         }
         Delete(0);
     }
+
     return S_OK;
 }
 
diff --git a/dll/win32/shdocvw/shdocvw.h b/dll/win32/shdocvw/shdocvw.h
index d58ee69384f..4569fe7e171 100644
--- a/dll/win32/shdocvw/shdocvw.h
+++ b/dll/win32/shdocvw/shdocvw.h
@@ -61,6 +61,7 @@ static inline void SHDOCVW_UnlockModule(void) { 
InterlockedDecrement( &SHDOCVW_r
 
 #ifdef __REACTOS__
 EXTERN_C HRESULT CMruLongList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, 
DWORD_PTR dwUnused3);
+EXTERN_C HRESULT CMruPidlList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, 
DWORD_PTR dwUnused3);
 EXTERN_C HRESULT CMruClassFactory_CreateInstance(REFIID riid, void **ppv);
 #endif
 
diff --git a/dll/win32/shdocvw/shdocvw_main.c b/dll/win32/shdocvw/shdocvw_main.c
index 8cab06cce77..5994e88c58a 100644
--- a/dll/win32/shdocvw/shdocvw_main.c
+++ b/dll/win32/shdocvw/shdocvw_main.c
@@ -105,6 +105,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID 
riid, void **ppv)
     {
         return CMruLongList_CreateInstance(0, ppv, 0);
     }
+    else if (IsEqualGUID(riid, &IID_IMruPidlList))
+    {
+        return CMruPidlList_CreateInstance(0, ppv, 0);
+    }
 #endif
 
     /* As a last resort, figure if the CLSID belongs to a 'Shell Instance 
Object' */
diff --git a/sdk/include/reactos/shlobj_undoc.h 
b/sdk/include/reactos/shlobj_undoc.h
index 0601d6fbd7b..40a5a576b88 100644
--- a/sdk/include/reactos/shlobj_undoc.h
+++ b/sdk/include/reactos/shlobj_undoc.h
@@ -699,9 +699,9 @@ DECLARE_INTERFACE_(IMruDataList, IUnknown)
     STDMETHOD_(ULONG,Release)(THIS) PURE;
     /*** IMruDataList ***/
     STDMETHOD(InitData)(THIS_ UINT, UINT, HKEY, LPCWSTR, SLOTCOMPARE) PURE;
-    STDMETHOD(AddData)(THIS_ const BYTE *, DWORD, UINT*) PURE;
-    STDMETHOD(FindData)(THIS_ const BYTE*, DWORD, UINT*) PURE;
-    STDMETHOD(GetData)(THIS_ UINT, BYTE*, DWORD) PURE;
+    STDMETHOD(AddData)(THIS_ LPCVOID , DWORD, UINT*) PURE;
+    STDMETHOD(FindData)(THIS_ LPCVOID , DWORD, UINT*) PURE;
+    STDMETHOD(GetData)(THIS_ UINT, LPVOID, DWORD) PURE;
     STDMETHOD(QueryInfo)(THIS_ UINT, UINT*, DWORD*) PURE;
     STDMETHOD(Delete)(THIS_ UINT) PURE;
 };

Reply via email to