ReactOS 0.4.16-dev-334-g4d9f67c
mrulist.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS shdocvw
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Implement MRU List of shdocvw.dll
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#define COBJMACROS
9
10#include "objects.h"
11#include <tchar.h>
12#include <strsafe.h>
13
14#include <wine/debug.h>
16
17class CSafeMutex;
18class CMruBase;
19 class CMruShortList;
20 class CMruLongList;
21 class CMruNode;
22 class CMruPidlList;
24
25// The flags for SLOTITEMDATA.dwFlags
26#define SLOT_LOADED 0x1
27#define SLOT_SET 0x2
28
29// The flags for CMruBase.m_dwFlags
30#define COMPARE_BY_MEMCMP 0x0
31#define COMPARE_BY_STRCMPIW 0x1
32#define COMPARE_BY_STRCMPW 0x2
33#define COMPARE_BY_IEILISEQUAL 0x3
34#define COMPARE_BY_MASK 0xF
35
37{
38protected:
40
41public:
43 {
44 }
46 {
47 if (m_hMutex)
48 {
50 m_hMutex = NULL;
51 }
52 }
53
55 {
57 if (wait != WAIT_OBJECT_0)
58 return E_FAIL;
59
61 return S_OK;
62 }
63};
64
66 : public IMruDataList
67{
68protected:
69 LONG m_cRefs = 1; // Reference count
70 DWORD m_dwFlags = 0; // The COMPARE_BY_... flags
71 BOOL m_bNeedSave = FALSE; // The flag that indicates whether it needs saving
72 BOOL m_bChecked = FALSE; // The checked flag
73 HKEY m_hKey = NULL; // A registry key
74 DWORD m_cSlotRooms = 0; // Rooms for slots
75 DWORD m_cSlots = 0; // The # of slots
76 SLOTCOMPARE m_fnCompare = NULL; // The comparison function
77 SLOTITEMDATA * m_pSlots = NULL; // Slot data
78
79 HRESULT _LoadItem(UINT iSlot);
80 HRESULT _AddItem(UINT iSlot, LPCVOID pvData, DWORD cbData);
81 HRESULT _GetItem(UINT iSlot, SLOTITEMDATA **ppItem);
82 void _DeleteItem(UINT iSlot);
83
84 HRESULT _GetSlotItem(UINT iSlot, SLOTITEMDATA **ppItem);
85 void _CheckUsedSlots();
86 HRESULT _UseEmptySlot(UINT *piSlot);
87
88public:
89 CMruBase();
90 virtual ~CMruBase();
91
92 // IUnknown methods
93 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
95 {
96 return ::InterlockedIncrement(&m_cRefs);
97 }
99
100 // IMruDataList methods
102 LPCWSTR pszSubKey OPTIONAL,
103 SLOTCOMPARE fnCompare OPTIONAL) override;
104 STDMETHODIMP AddData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override;
105 STDMETHODIMP FindData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override;
106 STDMETHODIMP GetData(UINT iSlot, LPVOID pvData, DWORD cbData) override;
107 STDMETHODIMP QueryInfo(UINT iSlot, UINT *piGotSlot, DWORD *pcbData) override;
108 STDMETHODIMP Delete(UINT iSlot) override;
109
110 // Non-standard methods
111 virtual BOOL _IsEqual(const SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData) const;
112 virtual DWORD _DeleteValue(LPCWSTR pszValue);
113 virtual HRESULT _InitSlots() = 0;
114 virtual void _SaveSlots() = 0;
115 virtual UINT _UpdateSlots(UINT iSlot) = 0;
116 virtual void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) = 0;
117 virtual HRESULT _GetSlot(UINT iSlot, UINT *puSlot) = 0;
118 virtual HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) = 0;
119
120 static void* operator new(size_t size)
121 {
122 return ::LocalAlloc(LPTR, size);
123 }
124 static void operator delete(void *ptr)
125 {
127 }
128};
129
131{
133}
134
136{
137 if (m_hKey)
138 {
140 m_hKey = NULL;
141 }
142
143 if (m_pSlots)
144 {
145 for (UINT iSlot = 0; iSlot < m_cSlots; ++iSlot)
146 {
147 m_pSlots[iSlot].pvData = ::LocalFree(m_pSlots[iSlot].pvData);
148 }
149
151 }
152
154}
155
157{
158 if (!ppvObj)
159 return E_POINTER;
160 if (IsEqualGUID(riid, IID_IMruDataList) || IsEqualGUID(riid, IID_IUnknown))
161 {
162 *ppvObj = static_cast<IMruDataList*>(this);
163 AddRef();
164 return S_OK;
165 }
166 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
167 return E_NOINTERFACE;
168}
169
170STDMETHODIMP_(ULONG) CMruBase::Release()
171{
173 {
174 _SaveSlots();
175 delete this;
176 return 0;
177 }
178 return m_cRefs;
179}
180
182{
183 DWORD cbData;
184 WCHAR szValue[12];
185
186 SLOTITEMDATA *pItem = &m_pSlots[iSlot];
187 _SlotString(iSlot, szValue, _countof(szValue));
188
189 if (SHGetValueW(m_hKey, NULL, szValue, NULL, NULL, &cbData) == ERROR_SUCCESS &&
190 cbData > 0)
191 {
192 pItem->pvData = ::LocalAlloc(LPTR, cbData);
193 if (pItem->pvData)
194 {
195 pItem->cbData = cbData;
196 if (SHGetValueW(m_hKey, NULL, szValue, NULL, pItem->pvData, &cbData) != ERROR_SUCCESS)
197 pItem->pvData = ::LocalFree(pItem->pvData);
198 }
199 }
200
201 pItem->dwFlags |= SLOT_LOADED;
202 if (!pItem->pvData)
203 return E_FAIL;
204
205 return S_OK;
206}
207
209{
210 if (!(m_pSlots[iSlot].dwFlags & SLOT_LOADED))
211 _LoadItem(iSlot);
212
213 SLOTITEMDATA *pItem = &m_pSlots[iSlot];
214 if (!pItem->pvData)
215 return E_OUTOFMEMORY;
216
217 *ppItem = pItem;
218 return S_OK;
219}
220
222{
223 HRESULT hr = _GetSlot(iSlot, &iSlot);
224 if (FAILED(hr))
225 return hr;
226 return _GetSlotItem(iSlot, ppItem);
227}
228
230{
231 WCHAR szBuff[12];
232
233 _SlotString(iSlot, szBuff, _countof(szBuff));
234 _DeleteValue(szBuff);
235
236 m_pSlots[iSlot].pvData = ::LocalFree(m_pSlots[iSlot].pvData);
237}
238
240{
241 UINT iGotSlot;
242 for (UINT iSlot = 0; iSlot < m_cSlots; ++iSlot)
243 _GetSlot(iSlot, &iGotSlot);
244
246}
247
249{
250 SLOTITEMDATA *pItem = &m_pSlots[iSlot];
251
252 WCHAR szBuff[12];
253 _SlotString(iSlot, szBuff, _countof(szBuff));
254
255 if (SHSetValueW(m_hKey, NULL, szBuff, REG_BINARY, pvData, cbData) != ERROR_SUCCESS)
256 return E_OUTOFMEMORY;
257
258 if (cbData >= pItem->cbData || !pItem->pvData)
259 {
260 ::LocalFree(pItem->pvData);
261 pItem->pvData = ::LocalAlloc(LPTR, cbData);
262 }
263
264 if (!pItem->pvData)
265 return E_FAIL;
266
267 pItem->cbData = cbData;
268 pItem->dwFlags = (SLOT_LOADED | SLOT_SET);
269 CopyMemory(pItem->pvData, pvData, cbData);
270 return S_OK;
271}
272
275 UINT cCapacity,
276 UINT flags,
277 HKEY hKey,
278 LPCWSTR pszSubKey OPTIONAL,
279 SLOTCOMPARE fnCompare OPTIONAL)
280{
282 m_fnCompare = fnCompare;
283 m_cSlotRooms = cCapacity;
284
285 if (pszSubKey)
287 else
289
290 if (!m_hKey)
291 return E_FAIL;
292
294 if (!m_pSlots)
295 return E_OUTOFMEMORY;
296
297 return _InitSlots();
298}
299
301{
302 UINT iSlot;
303 HRESULT hr = FindData(pvData, cbData, &iSlot);
304 if (FAILED(hr))
305 {
306 iSlot = _UpdateSlots(m_cSlots);
307 hr = _AddItem(iSlot, pvData, cbData);
308 if (FAILED(hr))
309 return hr;
310 }
311 else
312 {
313 iSlot = _UpdateSlots(iSlot);
314 hr = S_OK;
315 }
316
317 if (piSlot)
318 *piSlot = iSlot;
319
320 return hr;
321}
322
324{
325 if (m_cSlots <= 0)
326 return E_FAIL;
327
328 UINT iSlot = 0;
329 SLOTITEMDATA *pItem;
330 while (FAILED(_GetItem(iSlot, &pItem)) || !_IsEqual(pItem, pvData, cbData))
331 {
332 if (++iSlot >= m_cSlots)
333 return E_FAIL;
334 }
335
336 *piSlot = iSlot;
337 return S_OK;
338}
339
341{
342 SLOTITEMDATA *pItem;
343 HRESULT hr = _GetItem(iSlot, &pItem);
344 if (FAILED(hr))
345 return hr;
346
347 if (cbData < pItem->cbData)
349
350 CopyMemory(pvData, pItem->pvData, pItem->cbData);
351 return hr;
352}
353
355{
356 UINT iGotSlot;
357 HRESULT hr = _GetSlot(iSlot, &iGotSlot);
358 if (FAILED(hr))
359 return hr;
360
361 if (piGotSlot)
362 *piGotSlot = iGotSlot;
363
364 if (pcbData)
365 {
366 SLOTITEMDATA *pItem;
367 hr = _GetSlotItem(iGotSlot, &pItem);
368 if (SUCCEEDED(hr))
369 *pcbData = pItem->cbData;
370 }
371
372 return hr;
373}
374
376{
377 UINT uSlot;
378 HRESULT hr = _RemoveSlot(iSlot, &uSlot);
379 if (FAILED(hr))
380 return hr;
381
382 _DeleteItem(uSlot);
383 return hr;
384}
385
387{
388 if (m_fnCompare)
389 return m_fnCompare(pvData, pItem->pvData, cbData) == 0;
390
391 switch (m_dwFlags & COMPARE_BY_MASK)
392 {
394 if (pItem->cbData != cbData)
395 return FALSE;
396 return memcmp(pvData, pItem->pvData, cbData) == 0;
397
399 return StrCmpIW((LPCWSTR)pvData, (LPCWSTR)pItem->pvData) == 0;
400
402 return StrCmpW((LPCWSTR)pvData, (LPCWSTR)pItem->pvData) == 0;
403
406
407 default:
408 ERR("0x%08X\n", m_dwFlags);
409 return FALSE;
410 }
411}
412
414{
415 return SHDeleteValueW(m_hKey, NULL, pszValue);
416}
417
419{
420 if (!m_bChecked)
422
423 if (!m_cSlotRooms)
424 return E_FAIL;
425
426 UINT iSlot = 0;
427 for (SLOTITEMDATA *pItem = m_pSlots; (pItem->dwFlags & SLOT_SET); ++pItem)
428 {
429 if (++iSlot >= m_cSlotRooms)
430 return E_FAIL;
431 }
432
433 m_pSlots[iSlot].dwFlags |= SLOT_SET;
434 *piSlot = iSlot;
435 ++m_cSlots;
436
437 return S_OK;
438}
439
441 : public CMruBase
442{
443protected:
445
446 HRESULT _InitSlots() override;
447 void _SaveSlots() override;
448 UINT _UpdateSlots(UINT iSlot) override;
449 void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override;
450 HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override;
451 HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override;
452 friend class CMruLongList;
453
454public:
456 {
457 }
458
459 ~CMruShortList() override
460 {
462 }
463};
464
466{
467 DWORD cbData = (m_cSlotRooms + 1) * sizeof(WCHAR);
469 if (!m_pszSlotData)
470 return E_OUTOFMEMORY;
471
472 if (SHGetValueW(m_hKey, NULL, L"MRUList", NULL, m_pszSlotData, &cbData) == ERROR_SUCCESS)
473 m_cSlots = (cbData / sizeof(WCHAR)) - 1;
474
476 return S_OK;
477}
478
480{
481 if (m_bNeedSave)
482 {
483 DWORD cbData = (m_cSlots + 1) * sizeof(WCHAR);
484 SHSetValueW(m_hKey, NULL, L"MRUList", REG_SZ, m_pszSlotData, cbData);
486 }
487}
488
489// NOTE: MRUList uses lowercase alphabet for history of most recently used items.
491{
492 UINT iData, cDataToMove = iSlot;
493
494 if (iSlot == m_cSlots)
495 {
496 if (SUCCEEDED(_UseEmptySlot(&iData)))
497 {
498 ++cDataToMove;
499 }
500 else
501 {
502 // This code is getting the item index from a lowercase letter.
503 iData = m_pszSlotData[m_cSlots - 1] - L'a';
504 --cDataToMove;
505 }
506 }
507 else
508 {
509 iData = m_pszSlotData[iSlot] - L'a';
510 }
511
512 if (cDataToMove)
513 {
514 MoveMemory(m_pszSlotData + 1, m_pszSlotData, cDataToMove * sizeof(WCHAR));
515 m_pszSlotData[0] = (WCHAR)(L'a' + iData);
517 }
518
519 return iData;
520}
521
523{
524 if (cch >= 2)
525 {
526 psz[0] = (WCHAR)(L'a' + iSlot);
527 psz[1] = UNICODE_NULL;
528 }
529}
530
532{
533 if (iSlot >= m_cSlots)
534 return E_FAIL;
535
536 UINT iData = m_pszSlotData[iSlot] - L'a';
537 if (iData >= m_cSlotRooms)
538 return E_FAIL;
539
540 *puSlot = iData;
541 m_pSlots[iData].dwFlags |= SLOT_SET;
542 return S_OK;
543}
544
546{
547 HRESULT hr = _GetSlot(iSlot, puSlot);
548 if (FAILED(hr))
549 return hr;
550
551 MoveMemory(&m_pszSlotData[iSlot], &m_pszSlotData[iSlot + 1], (m_cSlots - iSlot) * sizeof(WCHAR));
552 --m_cSlots;
553 m_pSlots->dwFlags &= ~SLOT_SET;
555
556 return hr;
557}
558
560 : public CMruBase
561{
562protected:
563 UINT *m_puSlotData = NULL; // The slot data
564
565 void _ImportShortList();
566
567 HRESULT _InitSlots() override;
568 void _SaveSlots() override;
569 UINT _UpdateSlots(UINT iSlot) override;
570 void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override;
571 HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override;
572 HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override;
573
574public:
576 {
577 }
578
579 ~CMruLongList() override
580 {
582 }
583};
584
586{
587 DWORD cbData = (m_cSlotRooms + 1) * sizeof(UINT);
588 m_puSlotData = (UINT*)LocalAlloc(LPTR, cbData);
589 if (!m_puSlotData)
590 return E_OUTOFMEMORY;
591
592 if (SHGetValueW(m_hKey, NULL, L"MRUListEx", NULL, m_puSlotData, &cbData) == ERROR_SUCCESS)
593 m_cSlots = (cbData / sizeof(UINT)) - 1;
594 else
596
598 return S_OK;
599}
600
602{
603 if (m_bNeedSave)
604 {
606 (m_cSlots + 1) * sizeof(UINT));
608 }
609}
610
612{
613 UINT cSlotsToMove, uSlotData;
614
615 cSlotsToMove = iSlot;
616 if (iSlot == m_cSlots)
617 {
618 if (SUCCEEDED(_UseEmptySlot(&uSlotData)))
619 {
620 ++cSlotsToMove;
621 }
622 else
623 {
624 uSlotData = m_puSlotData[m_cSlots - 1];
625 --cSlotsToMove;
626 }
627 }
628 else
629 {
630 uSlotData = m_puSlotData[iSlot];
631 }
632
633 if (cSlotsToMove > 0)
634 {
635 MoveMemory(m_puSlotData + 1, m_puSlotData, cSlotsToMove * sizeof(UINT));
636 m_puSlotData[0] = uSlotData;
638 }
639
640 return uSlotData;
641}
642
644{
645 StringCchPrintfW(psz, cch, L"%d", iSlot);
646}
647
649{
650 if (iSlot >= m_cSlots)
651 return E_FAIL;
652
653 UINT uSlotData = m_puSlotData[iSlot];
654 if (uSlotData >= m_cSlotRooms)
655 return E_FAIL;
656
657 *puSlot = uSlotData;
658 m_pSlots[uSlotData].dwFlags |= SLOT_SET;
659 return S_OK;
660}
661
663{
664 HRESULT hr = _GetSlot(iSlot, puSlot);
665 if (FAILED(hr))
666 return hr;
667
668 MoveMemory(&m_puSlotData[iSlot], &m_puSlotData[iSlot + 1], (m_cSlots - iSlot) * sizeof(UINT));
669 --m_cSlots;
670 m_pSlots[0].dwFlags &= ~SLOT_SET;
672
673 return hr;
674}
675
677{
678 CMruShortList *pShortList = new CMruShortList();
679 if (!pShortList)
680 return;
681
682 HRESULT hr = pShortList->InitData(m_cSlotRooms, 0, m_hKey, NULL, NULL);
683 if (SUCCEEDED(hr))
684 {
685 for (;;)
686 {
687 UINT iSlot;
688 hr = pShortList->_GetSlot(m_cSlots, &iSlot);
689 if (FAILED(hr))
690 break;
691
692 SLOTITEMDATA *pItem;
693 hr = pShortList->_GetSlotItem(iSlot, &pItem);
694 if (FAILED(hr))
695 break;
696
697 _AddItem(iSlot, pItem->pvData, pItem->cbData);
698 pShortList->_DeleteItem(iSlot);
699
700 m_puSlotData[m_cSlots++] = iSlot;
701 }
702
704 }
705
706 SHDeleteValueW(m_hKey, NULL, L"MRUList");
707 pShortList->Release();
708}
709
712{
713 UNREFERENCED_PARAMETER(dwUnused1);
714 UNREFERENCED_PARAMETER(dwUnused3);
715
716 TRACE("%p %p %p\n", dwUnused1, ppv, dwUnused3);
717
718 if (!ppv)
719 return E_POINTER;
720
721 CMruLongList *pMruList = new CMruLongList();
722 *ppv = static_cast<IMruDataList*>(pMruList);
723 TRACE("%p\n", *ppv);
724
725 return S_OK;
726}
727
729 : public CMruLongList
730{
731protected:
732 UINT m_iSlot = 0; // The slot index
733 CMruNode *m_pParent = NULL; // The parent
734 IShellFolder *m_pShellFolder = NULL; // The shell folder
735
736 BOOL _InitLate();
737 BOOL _IsEqual(SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData);
738 DWORD _DeleteValue(LPCWSTR pszValue) override;
739
740 HRESULT _CreateNode(UINT iSlot, CMruNode **ppNewNode);
741 HRESULT _AddPidl(UINT iSlot, LPCITEMIDLIST pidl);
742 HRESULT _FindPidl(LPCITEMIDLIST pidl, UINT *piSlot);
743 HRESULT _GetPidlSlot(LPCITEMIDLIST pidl, BOOL bAdd, UINT *piSlot);
744
745public:
747 CMruNode(CMruNode *pParent, UINT iSlot);
748 ~CMruNode() override;
749
751
752 HRESULT BindToSlot(UINT iSlot, IShellFolder **ppSF);
753 HRESULT GetNode(BOOL bAdd, LPCITEMIDLIST pidl, CMruNode **pNewNode);
754 HRESULT GetNodeSlot(UINT *pnNodeSlot);
755 HRESULT SetNodeSlot(UINT nNodeSlot);
756
757 HRESULT RemoveLeast(UINT *pnNodeSlot);
759};
760
762{
763 m_iSlot = iSlot;
765 pParent->AddRef();
766}
767
769{
770 if (m_pParent)
771 {
772 m_pParent->Release();
773 m_pParent = NULL;
774 }
775
776 if (m_pShellFolder)
777 {
780 }
781}
782
784{
785 if (m_pParent)
786 m_pParent->AddRef();
787 return m_pParent;
788}
789
791{
792 CMruNode *pNewNode = new CMruNode(this, iSlot);
793 if (!pNewNode)
794 return E_OUTOFMEMORY;
795
796 WCHAR szSubKey[12];
797 _SlotString(iSlot, szSubKey, _countof(szSubKey));
798
799 HRESULT hr = pNewNode->InitData(m_cSlotRooms, 0, m_hKey, szSubKey, NULL);
800 if (FAILED(hr))
801 pNewNode->Release();
802 else
803 *ppNewNode = pNewNode;
804
805 return hr;
806}
807
809{
810 if (!pidl || !pidl->mkid.cb)
811 {
812 *ppNewNode = this;
813 AddRef();
814 return S_OK;
815 }
816
817 if (!_InitLate())
818 return E_FAIL;
819
820 UINT iSlot;
821 HRESULT hr = _GetPidlSlot(pidl, bAdd, &iSlot);
822 if (FAILED(hr))
823 {
824 if (!bAdd)
825 {
826 *ppNewNode = this;
827 AddRef();
828 return S_FALSE;
829 }
830 return hr;
831 }
832
833 CMruNode *pNewNode;
834 hr = _CreateNode(iSlot, &pNewNode);
835 if (SUCCEEDED(hr))
836 {
837 _SaveSlots();
838
839 LPCITEMIDLIST pidl2 = (LPCITEMIDLIST)((LPBYTE)pidl + pidl->mkid.cb);
840 pNewNode->GetNode(bAdd, pidl2, ppNewNode);
841 pNewNode->Release();
842 }
843
844 return hr;
845}
846
848{
849 SLOTITEMDATA *pItem;
850 HRESULT hr = _GetSlotItem(iSlot, &pItem);
851 if (FAILED(hr))
852 return hr;
853
855 NULL,
856 IID_IShellFolder,
857 (void **)ppSF);
858}
859
861{
862 if (!m_pShellFolder)
863 {
864 if (m_pParent)
866 else
868 }
869 return !!m_pShellFolder;
870}
871
873{
874 return m_pShellFolder->CompareIDs(0x10000000,
875 (LPITEMIDLIST)pItem->pvData,
876 (LPCITEMIDLIST)pvData) == 0;
877}
878
880{
881 DWORD dwData, cbData = sizeof(dwData);
882 DWORD error = SHGetValueW(m_hKey, NULL, L"NodeSlot", NULL, &dwData, (pnNodeSlot ? &cbData : NULL));
883 if (error != ERROR_SUCCESS)
884 return E_FAIL;
885 *pnNodeSlot = (UINT)dwData;
886 return S_OK;
887}
888
890{
891 DWORD dwData = nNodeSlot;
892 if (SHSetValueW(m_hKey, NULL, L"NodeSlot", REG_DWORD, &dwData, sizeof(dwData)) != ERROR_SUCCESS)
893 return E_FAIL;
894 return S_OK;
895}
896
898{
899 return CMruBase::_AddItem(iSlot, pidl, sizeof(WORD) + pidl->mkid.cb);
900}
901
903{
904 CMruBase::_DeleteValue(pszValue);
905 return SHDeleteKeyW(m_hKey, pszValue);
906}
907
909{
910 return FindData(pidl, sizeof(WORD) + pidl->mkid.cb, piSlot);
911}
912
914{
915 LPITEMIDLIST pidlFirst = ILCloneFirst(pidl);
916 if (!pidlFirst)
917 return E_OUTOFMEMORY;
918
919 UINT iSlot;
920 HRESULT hr = _FindPidl(pidlFirst, &iSlot);
921 if (SUCCEEDED(hr))
922 {
923 *piSlot = _UpdateSlots(iSlot);
924 hr = S_OK;
925 }
926 else if (bAdd)
927 {
928 *piSlot = _UpdateSlots(m_cSlots);
929 hr = _AddPidl(*piSlot, pidlFirst);
930 }
931
932 ILFree(pidlFirst);
933 return hr;
934}
935
937{
938 if (!m_cSlots)
939 {
940 GetNodeSlot(pnNodeSlot);
941 return S_FALSE;
942 }
943
944 UINT uSlot;
945 HRESULT hr = _GetSlot(m_cSlots - 1, &uSlot);
946 if (FAILED(hr))
947 return hr;
948
949 CMruNode *pNode;
950 hr = _CreateNode(uSlot, &pNode);
951 if (SUCCEEDED(hr))
952 {
953 hr = pNode->RemoveLeast(pnNodeSlot);
954 pNode->Release();
955 }
956
957 if (hr == S_FALSE)
958 {
959 Delete(m_cSlots - 1);
960 if (m_cSlots || SUCCEEDED(GetNodeSlot(0)))
961 return S_OK;
962 }
963
964 return hr;
965}
966
968 : public CMruNode
969 , public IMruPidlList
970{
971protected:
972 LPBYTE m_pbNodeSlots = NULL; // The node slots (contains SLOT_... flags)
973 DWORD m_cMaxNodeSlots = 0; // The upper bound of the node slot index
974 HANDLE m_hMutex = NULL; // The mutex (for sync)
975
977 void _SaveNodeSlots();
979
980public:
982 ~CMruPidlList() override;
983
984 HRESULT GetEmptySlot(UINT *pnNodeSlot);
985 void EmptyNodeSlot(UINT nNodeSlot);
986
987 // IUnknown methods
988 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
990 {
991 return CMruBase::AddRef();
992 }
994 {
995 return CMruBase::Release();
996 }
997
998 // IMruPidlList methods
999 STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszSubKey) override;
1000 STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot) override;
1002 LPCITEMIDLIST pidl,
1003 UINT cSlots,
1004 UINT *pnNodeSlots,
1005 UINT *pcNodeSlots) override;
1006 STDMETHODIMP PruneKids(LPCITEMIDLIST pidl) override;
1007};
1008
1010{
1012 if (m_hMutex)
1013 {
1015 m_hMutex = NULL;
1016 }
1017}
1018
1020{
1021 if (!ppvObj)
1022 return E_POINTER;
1023
1024 if (::IsEqualGUID(riid, IID_IMruPidlList) || ::IsEqualGUID(riid, IID_IUnknown))
1025 {
1026 *ppvObj = static_cast<IMruPidlList*>(this);
1027 AddRef();
1028 return S_OK;
1029 }
1030
1031 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
1032 return E_NOINTERFACE;
1033}
1034
1036{
1037 DWORD cbNodeSlots = m_cSlotRooms * sizeof(BYTE);
1038 if (SHGetValueW(m_hKey, NULL, L"NodeSlots", NULL, m_pbNodeSlots, &cbNodeSlots) != ERROR_SUCCESS)
1039 return FALSE;
1040 m_cMaxNodeSlots = cbNodeSlots / sizeof(BYTE);
1041 return TRUE;
1042}
1043
1045{
1046 DWORD cbNodeSlots = m_cMaxNodeSlots * sizeof(BYTE);
1047 SHSetValueW(m_hKey, NULL, L"NodeSlots", REG_BINARY, m_pbNodeSlots, cbNodeSlots);
1048}
1049
1051{
1053 if (!m_pbNodeSlots)
1054 return E_OUTOFMEMORY;
1055
1057 m_bNeedSave = TRUE;
1059
1060 return S_OK;
1061}
1062
1064{
1065 *pnNodeSlot = 0;
1066
1067 if (!_LoadNodeSlots())
1068 return E_FAIL;
1069
1071 {
1073 *pnNodeSlot = ++m_cMaxNodeSlots;
1075 return S_OK;
1076 }
1077
1078 for (UINT iNodeSlot = 0; iNodeSlot < m_cMaxNodeSlots; ++iNodeSlot)
1079 {
1080 if (m_pbNodeSlots[iNodeSlot] & SLOT_SET)
1081 continue;
1082
1083 m_pbNodeSlots[iNodeSlot] = SLOT_SET;
1084 *pnNodeSlot = iNodeSlot + 1; // nNodeSlot is 1-base
1086 return S_OK;
1087 }
1088
1089 HRESULT hr = E_FAIL;
1090 if (SUCCEEDED(RemoveLeast(pnNodeSlot)) && *pnNodeSlot)
1091 hr = S_OK;
1092
1094 return hr;
1095}
1096
1098{
1099 TRACE("%p -> %u %p %s\n", this, cMRUSize, hKey, debugstr_w(pszSubKey));
1100
1101 HRESULT hr = InitData(cMRUSize, 0, hKey, pszSubKey, NULL);
1102 if (FAILED(hr))
1103 {
1104 ERR("0x%08lX\n", hr);
1105 return hr;
1106 }
1107
1108 hr = _InitNodeSlots();
1109 if (FAILED(hr))
1110 {
1111 ERR("0x%08lX\n", hr);
1112 return hr;
1113 }
1114
1115 m_hMutex = ::CreateMutexW(NULL, FALSE, L"Shell.CMruPidlList");
1116 if (!m_hMutex)
1117 {
1119 ERR("0x%08lX\n", hr);
1120 }
1121
1122 return hr;
1123}
1124
1126{
1127 TRACE("%p -> %p %p\n", this, pidl, pnNodeSlot);
1128
1130 HRESULT hr = mutex.Enter(m_hMutex);
1131 if (FAILED(hr))
1132 {
1133 ERR("0x%08lX\n", hr);
1134 return hr;
1135 }
1136
1137 *pnNodeSlot = 0;
1138
1139 CMruNode *pNode;
1140 hr = GetNode(TRUE, pidl, &pNode);
1141 if (FAILED(hr))
1142 {
1143 ERR("0x%08lX\n", hr);
1144 return hr;
1145 }
1146
1147 hr = pNode->GetNodeSlot(pnNodeSlot);
1148 if (FAILED(hr))
1149 {
1150 hr = GetEmptySlot(pnNodeSlot);
1151 if (SUCCEEDED(hr))
1152 {
1153 hr = pNode->SetNodeSlot(*pnNodeSlot);
1154 }
1155 }
1156
1157 pNode->Release();
1158 return hr;
1159}
1160
1162 LPCITEMIDLIST pidl,
1163 UINT cSlots,
1164 UINT *pnNodeSlots,
1165 UINT *pcNodeSlots)
1166{
1167 TRACE("%p -> %p %u %p %p\n", this, pidl, cSlots, pnNodeSlots, pcNodeSlots);
1168
1170 HRESULT hr = mutex.Enter(m_hMutex);
1171 if (FAILED(hr))
1172 {
1173 ERR("0x%08lX\n", hr);
1174 return hr;
1175 }
1176
1177 *pcNodeSlots = 0;
1178
1179 CMruNode *pNode;
1180 hr = GetNode(FALSE, pidl, &pNode);
1181 if (FAILED(hr))
1182 {
1183 ERR("0x%08lX\n", hr);
1184 return hr;
1185 }
1186
1187 while (pNode && *pcNodeSlots < cSlots)
1188 {
1189 CMruNode *pParent = pNode->GetParent();
1190 if (SUCCEEDED(pNode->GetNodeSlot(&pnNodeSlots[*pcNodeSlots])))
1191 ++(*pcNodeSlots);
1192 else if (hr == S_OK && !*pcNodeSlots)
1193 hr = S_FALSE;
1194
1195 pNode->Release();
1196 pNode = pParent;
1197 }
1198
1199 if (pNode)
1200 pNode->Release();
1201
1202 if (SUCCEEDED(hr) && !*pcNodeSlots)
1203 hr = E_FAIL;
1204
1205 return hr;
1206}
1207
1209{
1210 TRACE("%p -> %p\n", this, pidl);
1211
1213 HRESULT hr = mutex.Enter(m_hMutex);
1214 if (FAILED(hr))
1215 {
1216 ERR("0x%08lX\n", hr);
1217 return hr;
1218 }
1219
1220 if (!_LoadNodeSlots())
1221 return hr;
1222
1223 CMruNode *pNode;
1224 hr = GetNode(FALSE, pidl, &pNode);
1225 if (FAILED(hr))
1226 return hr;
1227
1228 if (hr == S_OK)
1229 hr = pNode->Clear(this);
1230 else
1231 hr = E_FAIL;
1232
1233 pNode->Release();
1234
1236 return hr;
1237}
1238
1240{
1241 m_pbNodeSlots[nNodeSlot - 1] = 0; // nNodeSlot is 1-base
1242 m_bNeedSave = TRUE;
1243}
1244
1246{
1247 UNREFERENCED_PARAMETER(dwUnused1);
1248 UNREFERENCED_PARAMETER(dwUnused3);
1249
1250 TRACE("%p %p %p\n", dwUnused1, ppv, dwUnused3);
1251
1252 if (!ppv)
1253 return E_POINTER;
1254
1255 *ppv = NULL;
1256
1257 CMruPidlList *pMruList = new CMruPidlList();
1258 if (pMruList == NULL)
1259 return E_OUTOFMEMORY;
1260
1261 *ppv = static_cast<IMruPidlList*>(pMruList);
1262 TRACE("%p\n", *ppv);
1263 return S_OK;
1264}
1265
1267{
1268 UINT uSlot, nNodeSlot;
1269 HRESULT hr;
1270
1271 while (SUCCEEDED(_GetSlot(0, &uSlot)))
1272 {
1273 CMruNode *pNode;
1274 hr = _CreateNode(uSlot, &pNode);
1275 if (SUCCEEDED(hr))
1276 {
1277 hr = pNode->GetNodeSlot(&nNodeSlot);
1278 if (SUCCEEDED(hr))
1279 pList->EmptyNodeSlot(nNodeSlot);
1280
1281 pNode->Clear(pList);
1282 pNode->Release();
1283 }
1284 Delete(0);
1285 }
1286
1287 return S_OK;
1288}
1289
1291{
1292protected:
1294
1295public:
1297 {
1299 }
1301 {
1303 }
1304
1305 // IUnknown methods
1306 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
1308 {
1309 return ::InterlockedIncrement(&m_cRefs);
1310 }
1312 {
1314 {
1315 delete this;
1316 return 0;
1317 }
1318 return m_cRefs;
1319 }
1320
1321 // IClassFactory methods
1324
1325 static void* operator new(size_t size)
1326 {
1327 return ::LocalAlloc(LPTR, size);
1328 }
1329 static void operator delete(void *ptr)
1330 {
1332 }
1333};
1334
1336{
1337 if (!ppvObj)
1338 return E_POINTER;
1340 {
1341 *ppvObj = static_cast<IClassFactory*>(this);
1342 AddRef();
1343 return S_OK;
1344 }
1345 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
1346 return E_NOINTERFACE;
1347}
1348
1350{
1351 if (pUnkOuter)
1352 return CLASS_E_NOAGGREGATION;
1353
1354 if (IsEqualGUID(riid, IID_IMruDataList))
1356
1357 if (IsEqualGUID(riid, IID_IMruPidlList))
1359
1360 return E_NOINTERFACE;
1361}
1362
1364{
1365 if (fLock)
1367 else
1369 return S_OK;
1370}
1371
1373{
1374 CMruClassFactory *pFactory = new CMruClassFactory();
1375 if (!pFactory)
1376 return E_OUTOFMEMORY;
1377
1378 HRESULT hr = pFactory->QueryInterface(riid, ppv);
1379 pFactory->Release();
1380 return hr;
1381}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ERR(fmt,...)
Definition: precomp.h:57
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODIMP
Definition: basetyps.h:43
#define STDMETHODIMP_(t)
Definition: basetyps.h:44
const GUID IID_IUnknown
const GUID IID_IClassFactory
#define RegCloseKey(hKey)
Definition: registry.h:49
_In_ BOOLEAN Release
Definition: cdrom.h:920
HKEY m_hKey
Definition: mrulist.cpp:73
DWORD m_cSlots
Definition: mrulist.cpp:75
STDMETHODIMP AddData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override
Definition: mrulist.cpp:300
DWORD m_dwFlags
Definition: mrulist.cpp:70
virtual ~CMruBase()
Definition: mrulist.cpp:135
virtual HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot)=0
void _DeleteItem(UINT iSlot)
Definition: mrulist.cpp:229
BOOL m_bNeedSave
Definition: mrulist.cpp:71
CMruBase()
Definition: mrulist.cpp:130
HRESULT _LoadItem(UINT iSlot)
Definition: mrulist.cpp:181
STDMETHODIMP_(ULONG) Release() override
SLOTITEMDATA * m_pSlots
Definition: mrulist.cpp:77
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:156
HRESULT _GetItem(UINT iSlot, SLOTITEMDATA **ppItem)
Definition: mrulist.cpp:221
LONG m_cRefs
Definition: mrulist.cpp:69
virtual DWORD _DeleteValue(LPCWSTR pszValue)
Definition: mrulist.cpp:413
STDMETHODIMP Delete(UINT iSlot) override
Definition: mrulist.cpp:375
virtual BOOL _IsEqual(const SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData) const
Definition: mrulist.cpp:386
virtual UINT _UpdateSlots(UINT iSlot)=0
HRESULT _GetSlotItem(UINT iSlot, SLOTITEMDATA **ppItem)
Definition: mrulist.cpp:208
virtual HRESULT _GetSlot(UINT iSlot, UINT *puSlot)=0
SLOTCOMPARE m_fnCompare
Definition: mrulist.cpp:76
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:94
virtual void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch)=0
HRESULT _UseEmptySlot(UINT *piSlot)
Definition: mrulist.cpp:418
BOOL m_bChecked
Definition: mrulist.cpp:72
STDMETHODIMP GetData(UINT iSlot, LPVOID pvData, DWORD cbData) override
Definition: mrulist.cpp:340
STDMETHODIMP FindData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override
Definition: mrulist.cpp:323
void _CheckUsedSlots()
Definition: mrulist.cpp:239
STDMETHODIMP InitData(UINT cCapacity, UINT flags, HKEY hKey, LPCWSTR pszSubKey OPTIONAL, SLOTCOMPARE fnCompare OPTIONAL) override
Definition: mrulist.cpp:274
DWORD m_cSlotRooms
Definition: mrulist.cpp:74
virtual HRESULT _InitSlots()=0
STDMETHODIMP QueryInfo(UINT iSlot, UINT *piGotSlot, DWORD *pcbData) override
Definition: mrulist.cpp:354
virtual void _SaveSlots()=0
HRESULT _AddItem(UINT iSlot, LPCVOID pvData, DWORD cbData)
Definition: mrulist.cpp:248
STDMETHODIMP LockServer(BOOL fLock)
Definition: mrulist.cpp:1363
STDMETHODIMP_(ULONG) Release()
Definition: mrulist.cpp:1311
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:1307
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:1335
STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
Definition: mrulist.cpp:1349
virtual ~CMruClassFactory()
Definition: mrulist.cpp:1300
UINT _UpdateSlots(UINT iSlot) override
Definition: mrulist.cpp:611
void _ImportShortList()
Definition: mrulist.cpp:676
~CMruLongList() override
Definition: mrulist.cpp:579
void _SaveSlots() override
Definition: mrulist.cpp:601
UINT * m_puSlotData
Definition: mrulist.cpp:563
HRESULT _InitSlots() override
Definition: mrulist.cpp:585
HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:648
HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:662
void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override
Definition: mrulist.cpp:643
HRESULT SetNodeSlot(UINT nNodeSlot)
Definition: mrulist.cpp:889
HRESULT Clear(CMruPidlList *pList)
Definition: mrulist.cpp:1266
HRESULT _GetPidlSlot(LPCITEMIDLIST pidl, BOOL bAdd, UINT *piSlot)
Definition: mrulist.cpp:913
CMruNode * m_pParent
Definition: mrulist.cpp:733
HRESULT BindToSlot(UINT iSlot, IShellFolder **ppSF)
Definition: mrulist.cpp:847
HRESULT RemoveLeast(UINT *pnNodeSlot)
Definition: mrulist.cpp:936
HRESULT _CreateNode(UINT iSlot, CMruNode **ppNewNode)
Definition: mrulist.cpp:790
BOOL _InitLate()
Definition: mrulist.cpp:860
CMruNode()
Definition: mrulist.cpp:746
BOOL _IsEqual(SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData)
Definition: mrulist.cpp:872
UINT m_iSlot
Definition: mrulist.cpp:732
IShellFolder * m_pShellFolder
Definition: mrulist.cpp:734
HRESULT _AddPidl(UINT iSlot, LPCITEMIDLIST pidl)
Definition: mrulist.cpp:897
HRESULT GetNode(BOOL bAdd, LPCITEMIDLIST pidl, CMruNode **pNewNode)
Definition: mrulist.cpp:808
~CMruNode() override
Definition: mrulist.cpp:768
HRESULT GetNodeSlot(UINT *pnNodeSlot)
Definition: mrulist.cpp:879
DWORD _DeleteValue(LPCWSTR pszValue) override
Definition: mrulist.cpp:902
HRESULT _FindPidl(LPCITEMIDLIST pidl, UINT *piSlot)
Definition: mrulist.cpp:908
CMruNode * GetParent()
Definition: mrulist.cpp:783
STDMETHODIMP QueryPidl(LPCITEMIDLIST pidl, UINT cSlots, UINT *pnNodeSlots, UINT *pcNodeSlots) override
Definition: mrulist.cpp:1161
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:1019
STDMETHODIMP PruneKids(LPCITEMIDLIST pidl) override
Definition: mrulist.cpp:1208
HRESULT _InitNodeSlots()
Definition: mrulist.cpp:1050
STDMETHODIMP_(ULONG) Release() override
Definition: mrulist.cpp:993
DWORD m_cMaxNodeSlots
Definition: mrulist.cpp:973
HANDLE m_hMutex
Definition: mrulist.cpp:974
void EmptyNodeSlot(UINT nNodeSlot)
Definition: mrulist.cpp:1239
void _SaveNodeSlots()
Definition: mrulist.cpp:1044
STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot) override
Definition: mrulist.cpp:1125
~CMruPidlList() override
Definition: mrulist.cpp:1009
HRESULT GetEmptySlot(UINT *pnNodeSlot)
Definition: mrulist.cpp:1063
BOOL _LoadNodeSlots()
Definition: mrulist.cpp:1035
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:989
STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszSubKey) override
Definition: mrulist.cpp:1097
LPBYTE m_pbNodeSlots
Definition: mrulist.cpp:972
void _SaveSlots() override
Definition: mrulist.cpp:479
LPWSTR m_pszSlotData
Definition: mrulist.cpp:444
void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override
Definition: mrulist.cpp:522
HRESULT _InitSlots() override
Definition: mrulist.cpp:465
HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:531
HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:545
~CMruShortList() override
Definition: mrulist.cpp:459
UINT _UpdateSlots(UINT iSlot) override
Definition: mrulist.cpp:490
HRESULT Enter(HANDLE hMutex)
Definition: mrulist.cpp:54
CSafeMutex()
Definition: mrulist.cpp:42
HANDLE m_hMutex
Definition: mrulist.cpp:39
~CSafeMutex()
Definition: mrulist.cpp:45
ULONG __inline AddRef(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:826
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
EXTERN_C BOOL WINAPI IEILIsEqual(_In_ LPCITEMIDLIST pidl1, _In_ LPCITEMIDLIST pidl2, _In_ BOOL bUnknown)
Definition: utility.cpp:84
DWORD WINAPI SHDeleteValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue)
Definition: reg.c:1762
DWORD WINAPI SHDeleteKeyW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1546
DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1236
HKEY WINAPI SHRegDuplicateHKey(HKEY hKey)
Definition: reg.c:2214
DWORD WINAPI SHSetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, DWORD dwType, LPCVOID pvData, DWORD cbData)
Definition: reg.c:1306
int WINAPI StrCmpIW(LPCWSTR lpszStr, LPCWSTR lpszComp)
Definition: string.c:353
int WINAPI StrCmpW(LPCWSTR lpszStr, LPCWSTR lpszComp)
Definition: string.c:434
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxChildList * pList
FxObject * pParent
Definition: fxdpcapi.cpp:86
FxAutoRegKey hKey
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT BindToObject([in] PCUIDLIST_RELATIVE pidl, [in] LPBC pbcReserved, [in] REFIID riid, [out, iid_is(riid)] void **ppvOut)
HRESULT CompareIDs([in] LPARAM lParam, [in] PCUIDLIST_RELATIVE pidl1, [in] PCUIDLIST_RELATIVE pidl2)
ULONG AddRef()
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
#define error(str)
Definition: mkdosfs.c:1605
static PVOID ptr
Definition: dispmode.c:27
HANDLE hMutex
Definition: mutex.c:11
static void Clear(void)
Definition: treeview.c:388
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
static HANDLE ULONG_PTR dwData
Definition: file.c:35
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
#define COMPARE_BY_STRCMPIW
Definition: mrulist.cpp:31
#define COMPARE_BY_MEMCMP
Definition: mrulist.cpp:30
EXTERN_C HRESULT CMruPidlList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, DWORD_PTR dwUnused3)
Definition: mrulist.cpp:1245
EXTERN_C HRESULT CMruLongList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, DWORD_PTR dwUnused3)
Definition: mrulist.cpp:711
#define SLOT_LOADED
Definition: mrulist.cpp:26
#define COMPARE_BY_MASK
Definition: mrulist.cpp:34
#define COMPARE_BY_STRCMPW
Definition: mrulist.cpp:32
EXTERN_C HRESULT CMruClassFactory_CreateInstance(REFIID riid, void **ppv)
Definition: mrulist.cpp:1372
#define SLOT_SET
Definition: mrulist.cpp:27
#define COMPARE_BY_IEILISEQUAL
Definition: mrulist.cpp:33
unsigned int UINT
Definition: ndis.h:50
#define REG_BINARY
Definition: nt_native.h:1496
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define MAXDWORD
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1042
LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
Definition: pidl.c:262
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define REG_DWORD
Definition: sdbapi.c:596
static void SHDOCVW_LockModule(void)
Definition: shdocvw.h:59
static void SHDOCVW_UnlockModule(void)
Definition: shdocvw.h:60
HRESULT hr
Definition: shlfolder.c:183
INT(CALLBACK * SLOTCOMPARE)(LPCVOID pvData1, LPCVOID pvData2, UINT cbData)
Definition: shlobj_undoc.h:36
LONG WINAPI RegCreateKeyExWrapW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
Definition: module.h:456
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LPTR
Definition: winbase.h:407
#define CopyMemory
Definition: winbase.h:1735
#define MoveMemory
Definition: winbase.h:1734
#define WAIT_OBJECT_0
Definition: winbase.h:432
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4950
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3749
CONST void * LPCVOID
Definition: windef.h:191
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193