ReactOS 0.4.16-dev-2491-g3dc6630
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);
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
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;
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;
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{
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
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,
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{
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
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);
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);
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 using CMruBase::_IsEqual;
740
741 HRESULT _CreateNode(UINT iSlot, CMruNode **ppNewNode);
742 HRESULT _AddPidl(UINT iSlot, LPCITEMIDLIST pidl);
743 HRESULT _FindPidl(LPCITEMIDLIST pidl, UINT *piSlot);
744 HRESULT _GetPidlSlot(LPCITEMIDLIST pidl, BOOL bAdd, UINT *piSlot);
745
746public:
748 CMruNode(CMruNode *pParent, UINT iSlot);
749 ~CMruNode() override;
750
752
753 HRESULT BindToSlot(UINT iSlot, IShellFolder **ppSF);
754 HRESULT GetNode(BOOL bAdd, LPCITEMIDLIST pidl, CMruNode **pNewNode);
755 HRESULT GetNodeSlot(UINT *pnNodeSlot);
756 HRESULT SetNodeSlot(UINT nNodeSlot);
757
758 HRESULT RemoveLeast(UINT *pnNodeSlot);
760};
761
763{
764 m_iSlot = iSlot;
766 pParent->AddRef();
767}
768
770{
771 if (m_pParent)
772 {
773 m_pParent->Release();
774 m_pParent = NULL;
775 }
776
777 if (m_pShellFolder)
778 {
781 }
782}
783
785{
786 if (m_pParent)
787 m_pParent->AddRef();
788 return m_pParent;
789}
790
792{
793 CMruNode *pNewNode = new CMruNode(this, iSlot);
794 if (!pNewNode)
795 return E_OUTOFMEMORY;
796
797 WCHAR szSubKey[12];
798 _SlotString(iSlot, szSubKey, _countof(szSubKey));
799
800 HRESULT hr = pNewNode->InitData(m_cSlotRooms, 0, m_hKey, szSubKey, NULL);
801 if (FAILED(hr))
802 pNewNode->Release();
803 else
804 *ppNewNode = pNewNode;
805
806 return hr;
807}
808
810{
811 if (!pidl || !pidl->mkid.cb)
812 {
813 *ppNewNode = this;
814 AddRef();
815 return S_OK;
816 }
817
818 if (!_InitLate())
819 return E_FAIL;
820
821 UINT iSlot;
822 HRESULT hr = _GetPidlSlot(pidl, bAdd, &iSlot);
823 if (FAILED(hr))
824 {
825 if (!bAdd)
826 {
827 *ppNewNode = this;
828 AddRef();
829 return S_FALSE;
830 }
831 return hr;
832 }
833
834 CMruNode *pNewNode;
835 hr = _CreateNode(iSlot, &pNewNode);
836 if (SUCCEEDED(hr))
837 {
838 _SaveSlots();
839
840 LPCITEMIDLIST pidl2 = (LPCITEMIDLIST)((LPBYTE)pidl + pidl->mkid.cb);
841 pNewNode->GetNode(bAdd, pidl2, ppNewNode);
842 pNewNode->Release();
843 }
844
845 return hr;
846}
847
849{
850 SLOTITEMDATA *pItem;
851 HRESULT hr = _GetSlotItem(iSlot, &pItem);
852 if (FAILED(hr))
853 return hr;
854
856 NULL,
857 IID_IShellFolder,
858 (void **)ppSF);
859}
860
862{
863 if (!m_pShellFolder)
864 {
865 if (m_pParent)
867 else
869 }
870 return !!m_pShellFolder;
871}
872
874{
875 return m_pShellFolder->CompareIDs(0x10000000,
876 (LPITEMIDLIST)pItem->pvData,
877 (LPCITEMIDLIST)pvData) == 0;
878}
879
881{
882 DWORD dwData, cbData = sizeof(dwData);
883 DWORD error = SHGetValueW(m_hKey, NULL, L"NodeSlot", NULL, &dwData, (pnNodeSlot ? &cbData : NULL));
884 if (error != ERROR_SUCCESS)
885 return E_FAIL;
886 *pnNodeSlot = (UINT)dwData;
887 return S_OK;
888}
889
891{
892 DWORD dwData = nNodeSlot;
893 if (SHSetValueW(m_hKey, NULL, L"NodeSlot", REG_DWORD, &dwData, sizeof(dwData)) != ERROR_SUCCESS)
894 return E_FAIL;
895 return S_OK;
896}
897
899{
900 return CMruBase::_AddItem(iSlot, pidl, sizeof(WORD) + pidl->mkid.cb);
901}
902
904{
907}
908
910{
911 return FindData(pidl, sizeof(WORD) + pidl->mkid.cb, piSlot);
912}
913
915{
916 LPITEMIDLIST pidlFirst = ILCloneFirst(pidl);
917 if (!pidlFirst)
918 return E_OUTOFMEMORY;
919
920 UINT iSlot;
921 HRESULT hr = _FindPidl(pidlFirst, &iSlot);
922 if (SUCCEEDED(hr))
923 {
924 *piSlot = _UpdateSlots(iSlot);
925 hr = S_OK;
926 }
927 else if (bAdd)
928 {
929 *piSlot = _UpdateSlots(m_cSlots);
930 hr = _AddPidl(*piSlot, pidlFirst);
931 }
932
933 ILFree(pidlFirst);
934 return hr;
935}
936
938{
939 if (!m_cSlots)
940 {
941 GetNodeSlot(pnNodeSlot);
942 return S_FALSE;
943 }
944
945 UINT uSlot;
946 HRESULT hr = _GetSlot(m_cSlots - 1, &uSlot);
947 if (FAILED(hr))
948 return hr;
949
950 CMruNode *pNode;
951 hr = _CreateNode(uSlot, &pNode);
952 if (SUCCEEDED(hr))
953 {
954 hr = pNode->RemoveLeast(pnNodeSlot);
955 pNode->Release();
956 }
957
958 if (hr == S_FALSE)
959 {
960 Delete(m_cSlots - 1);
961 if (m_cSlots || SUCCEEDED(GetNodeSlot(0)))
962 return S_OK;
963 }
964
965 return hr;
966}
967
969 : public CMruNode
970 , public IMruPidlList
971{
972protected:
973 LPBYTE m_pbNodeSlots = NULL; // The node slots (contains SLOT_... flags)
974 DWORD m_cMaxNodeSlots = 0; // The upper bound of the node slot index
975 HANDLE m_hMutex = NULL; // The mutex (for sync)
976
978 void _SaveNodeSlots();
980
981public:
983 ~CMruPidlList() override;
984
985 HRESULT GetEmptySlot(UINT *pnNodeSlot);
986 void EmptyNodeSlot(UINT nNodeSlot);
987
988 // IUnknown methods
989 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
991 {
992 return CMruBase::AddRef();
993 }
995 {
996 return CMruBase::Release();
997 }
998
999 // IMruPidlList methods
1000 STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszSubKey) override;
1001 STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot) override;
1003 LPCITEMIDLIST pidl,
1004 UINT cSlots,
1005 UINT *pnNodeSlots,
1006 UINT *pcNodeSlots) override;
1007 STDMETHODIMP PruneKids(LPCITEMIDLIST pidl) override;
1008};
1009
1011{
1013 if (m_hMutex)
1014 {
1016 m_hMutex = NULL;
1017 }
1018}
1019
1021{
1022 if (!ppvObj)
1023 return E_POINTER;
1024
1025 if (::IsEqualGUID(riid, IID_IMruPidlList) || ::IsEqualGUID(riid, IID_IUnknown))
1026 {
1027 *ppvObj = static_cast<IMruPidlList*>(this);
1028 AddRef();
1029 return S_OK;
1030 }
1031
1032 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
1033 return E_NOINTERFACE;
1034}
1035
1037{
1038 DWORD cbNodeSlots = m_cSlotRooms * sizeof(BYTE);
1039 if (SHGetValueW(m_hKey, NULL, L"NodeSlots", NULL, m_pbNodeSlots, &cbNodeSlots) != ERROR_SUCCESS)
1040 return FALSE;
1041 m_cMaxNodeSlots = cbNodeSlots / sizeof(BYTE);
1042 return TRUE;
1043}
1044
1046{
1047 DWORD cbNodeSlots = m_cMaxNodeSlots * sizeof(BYTE);
1048 SHSetValueW(m_hKey, NULL, L"NodeSlots", REG_BINARY, m_pbNodeSlots, cbNodeSlots);
1049}
1050
1052{
1054 if (!m_pbNodeSlots)
1055 return E_OUTOFMEMORY;
1056
1058 m_bNeedSave = TRUE;
1060
1061 return S_OK;
1062}
1063
1065{
1066 *pnNodeSlot = 0;
1067
1068 if (!_LoadNodeSlots())
1069 return E_FAIL;
1070
1072 {
1074 *pnNodeSlot = ++m_cMaxNodeSlots;
1076 return S_OK;
1077 }
1078
1079 for (UINT iNodeSlot = 0; iNodeSlot < m_cMaxNodeSlots; ++iNodeSlot)
1080 {
1081 if (m_pbNodeSlots[iNodeSlot] & SLOT_SET)
1082 continue;
1083
1084 m_pbNodeSlots[iNodeSlot] = SLOT_SET;
1085 *pnNodeSlot = iNodeSlot + 1; // nNodeSlot is 1-base
1087 return S_OK;
1088 }
1089
1090 HRESULT hr = E_FAIL;
1091 if (SUCCEEDED(RemoveLeast(pnNodeSlot)) && *pnNodeSlot)
1092 hr = S_OK;
1093
1095 return hr;
1096}
1097
1099{
1100 TRACE("%p -> %u %p %s\n", this, cMRUSize, hKey, debugstr_w(pszSubKey));
1101
1102 HRESULT hr = InitData(cMRUSize, 0, hKey, pszSubKey, NULL);
1103 if (FAILED(hr))
1104 {
1105 ERR("0x%08lX\n", hr);
1106 return hr;
1107 }
1108
1109 hr = _InitNodeSlots();
1110 if (FAILED(hr))
1111 {
1112 ERR("0x%08lX\n", hr);
1113 return hr;
1114 }
1115
1116 m_hMutex = ::CreateMutexW(NULL, FALSE, L"Shell.CMruPidlList");
1117 if (!m_hMutex)
1118 {
1120 ERR("0x%08lX\n", hr);
1121 }
1122
1123 return hr;
1124}
1125
1127{
1128 TRACE("%p -> %p %p\n", this, pidl, pnNodeSlot);
1129
1131 HRESULT hr = mutex.Enter(m_hMutex);
1132 if (FAILED(hr))
1133 {
1134 ERR("0x%08lX\n", hr);
1135 return hr;
1136 }
1137
1138 *pnNodeSlot = 0;
1139
1140 CMruNode *pNode;
1141 hr = GetNode(TRUE, pidl, &pNode);
1142 if (FAILED(hr))
1143 {
1144 ERR("0x%08lX\n", hr);
1145 return hr;
1146 }
1147
1148 hr = pNode->GetNodeSlot(pnNodeSlot);
1149 if (FAILED(hr))
1150 {
1151 hr = GetEmptySlot(pnNodeSlot);
1152 if (SUCCEEDED(hr))
1153 {
1154 hr = pNode->SetNodeSlot(*pnNodeSlot);
1155 }
1156 }
1157
1158 pNode->Release();
1159 return hr;
1160}
1161
1163 LPCITEMIDLIST pidl,
1164 UINT cSlots,
1165 UINT *pnNodeSlots,
1166 UINT *pcNodeSlots)
1167{
1168 TRACE("%p -> %p %u %p %p\n", this, pidl, cSlots, pnNodeSlots, pcNodeSlots);
1169
1171 HRESULT hr = mutex.Enter(m_hMutex);
1172 if (FAILED(hr))
1173 {
1174 ERR("0x%08lX\n", hr);
1175 return hr;
1176 }
1177
1178 *pcNodeSlots = 0;
1179
1180 CMruNode *pNode;
1181 hr = GetNode(FALSE, pidl, &pNode);
1182 if (FAILED(hr))
1183 {
1184 ERR("0x%08lX\n", hr);
1185 return hr;
1186 }
1187
1188 while (pNode && *pcNodeSlots < cSlots)
1189 {
1190 CMruNode *pParent = pNode->GetParent();
1191 if (SUCCEEDED(pNode->GetNodeSlot(&pnNodeSlots[*pcNodeSlots])))
1192 ++(*pcNodeSlots);
1193 else if (hr == S_OK && !*pcNodeSlots)
1194 hr = S_FALSE;
1195
1196 pNode->Release();
1197 pNode = pParent;
1198 }
1199
1200 if (pNode)
1201 pNode->Release();
1202
1203 if (SUCCEEDED(hr) && !*pcNodeSlots)
1204 hr = E_FAIL;
1205
1206 return hr;
1207}
1208
1210{
1211 TRACE("%p -> %p\n", this, pidl);
1212
1214 HRESULT hr = mutex.Enter(m_hMutex);
1215 if (FAILED(hr))
1216 {
1217 ERR("0x%08lX\n", hr);
1218 return hr;
1219 }
1220
1221 if (!_LoadNodeSlots())
1222 return hr;
1223
1224 CMruNode *pNode;
1225 hr = GetNode(FALSE, pidl, &pNode);
1226 if (FAILED(hr))
1227 return hr;
1228
1229 if (hr == S_OK)
1230 hr = pNode->Clear(this);
1231 else
1232 hr = E_FAIL;
1233
1234 pNode->Release();
1235
1237 return hr;
1238}
1239
1241{
1242 m_pbNodeSlots[nNodeSlot - 1] = 0; // nNodeSlot is 1-base
1243 m_bNeedSave = TRUE;
1244}
1245
1247{
1248 UNREFERENCED_PARAMETER(dwUnused1);
1249 UNREFERENCED_PARAMETER(dwUnused3);
1250
1251 TRACE("%p %p %p\n", dwUnused1, ppv, dwUnused3);
1252
1253 if (!ppv)
1254 return E_POINTER;
1255
1256 *ppv = NULL;
1257
1258 CMruPidlList *pMruList = new CMruPidlList();
1259 if (pMruList == NULL)
1260 return E_OUTOFMEMORY;
1261
1262 *ppv = static_cast<IMruPidlList*>(pMruList);
1263 TRACE("%p\n", *ppv);
1264 return S_OK;
1265}
1266
1268{
1269 UINT uSlot, nNodeSlot;
1270 HRESULT hr;
1271
1272 while (SUCCEEDED(_GetSlot(0, &uSlot)))
1273 {
1274 CMruNode *pNode;
1275 hr = _CreateNode(uSlot, &pNode);
1276 if (SUCCEEDED(hr))
1277 {
1278 hr = pNode->GetNodeSlot(&nNodeSlot);
1279 if (SUCCEEDED(hr))
1280 pList->EmptyNodeSlot(nNodeSlot);
1281
1282 pNode->Clear(pList);
1283 pNode->Release();
1284 }
1285 Delete(0);
1286 }
1287
1288 return S_OK;
1289}
1290
1292{
1293protected:
1295
1296public:
1298 {
1300 }
1302 {
1304 }
1305
1306 // IUnknown methods
1307 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
1309 {
1310 return ::InterlockedIncrement(&m_cRefs);
1311 }
1313 {
1315 {
1316 delete this;
1317 return 0;
1318 }
1319 return m_cRefs;
1320 }
1321
1322 // IClassFactory methods
1323 STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
1325
1326 static void* operator new(size_t size)
1327 {
1328 return ::LocalAlloc(LPTR, size);
1329 }
1330 static void operator delete(void *ptr)
1331 {
1333 }
1334};
1335
1337{
1338 if (!ppvObj)
1339 return E_POINTER;
1341 {
1342 *ppvObj = static_cast<IClassFactory*>(this);
1343 AddRef();
1344 return S_OK;
1345 }
1346 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
1347 return E_NOINTERFACE;
1348}
1349
1351{
1352 if (pUnkOuter)
1353 return CLASS_E_NOAGGREGATION;
1354
1355 if (IsEqualGUID(riid, IID_IMruDataList))
1356 return CMruLongList_CreateInstance(0, ppvObject, 0);
1357
1358 if (IsEqualGUID(riid, IID_IMruPidlList))
1359 return CMruPidlList_CreateInstance(0, ppvObject, 0);
1360
1361 return E_NOINTERFACE;
1362}
1363
1365{
1366 if (fLock)
1368 else
1370 return S_OK;
1371}
1372
1374{
1375 CMruClassFactory *pFactory = new CMruClassFactory();
1376 if (!pFactory)
1377 return E_OUTOFMEMORY;
1378
1379 HRESULT hr = pFactory->QueryInterface(riid, ppv);
1380 pFactory->Release();
1381 return hr;
1382}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#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:1364
STDMETHODIMP_(ULONG) Release()
Definition: mrulist.cpp:1312
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:1308
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:1336
STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
Definition: mrulist.cpp:1350
virtual ~CMruClassFactory()
Definition: mrulist.cpp:1301
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:890
HRESULT Clear(CMruPidlList *pList)
Definition: mrulist.cpp:1267
HRESULT _GetPidlSlot(LPCITEMIDLIST pidl, BOOL bAdd, UINT *piSlot)
Definition: mrulist.cpp:914
CMruNode * m_pParent
Definition: mrulist.cpp:733
HRESULT BindToSlot(UINT iSlot, IShellFolder **ppSF)
Definition: mrulist.cpp:848
HRESULT RemoveLeast(UINT *pnNodeSlot)
Definition: mrulist.cpp:937
HRESULT _CreateNode(UINT iSlot, CMruNode **ppNewNode)
Definition: mrulist.cpp:791
BOOL _InitLate()
Definition: mrulist.cpp:861
CMruNode()
Definition: mrulist.cpp:747
BOOL _IsEqual(SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData)
Definition: mrulist.cpp:873
UINT m_iSlot
Definition: mrulist.cpp:732
IShellFolder * m_pShellFolder
Definition: mrulist.cpp:734
HRESULT _AddPidl(UINT iSlot, LPCITEMIDLIST pidl)
Definition: mrulist.cpp:898
HRESULT GetNode(BOOL bAdd, LPCITEMIDLIST pidl, CMruNode **pNewNode)
Definition: mrulist.cpp:809
~CMruNode() override
Definition: mrulist.cpp:769
HRESULT GetNodeSlot(UINT *pnNodeSlot)
Definition: mrulist.cpp:880
DWORD _DeleteValue(LPCWSTR pszValue) override
Definition: mrulist.cpp:903
HRESULT _FindPidl(LPCITEMIDLIST pidl, UINT *piSlot)
Definition: mrulist.cpp:909
CMruNode * GetParent()
Definition: mrulist.cpp:784
STDMETHODIMP QueryPidl(LPCITEMIDLIST pidl, UINT cSlots, UINT *pnNodeSlots, UINT *pcNodeSlots) override
Definition: mrulist.cpp:1162
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:1020
STDMETHODIMP PruneKids(LPCITEMIDLIST pidl) override
Definition: mrulist.cpp:1209
HRESULT _InitNodeSlots()
Definition: mrulist.cpp:1051
STDMETHODIMP_(ULONG) Release() override
Definition: mrulist.cpp:994
DWORD m_cMaxNodeSlots
Definition: mrulist.cpp:974
HANDLE m_hMutex
Definition: mrulist.cpp:975
void EmptyNodeSlot(UINT nNodeSlot)
Definition: mrulist.cpp:1240
void _SaveNodeSlots()
Definition: mrulist.cpp:1045
STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot) override
Definition: mrulist.cpp:1126
~CMruPidlList() override
Definition: mrulist.cpp:1010
HRESULT GetEmptySlot(UINT *pnNodeSlot)
Definition: mrulist.cpp:1064
BOOL _LoadNodeSlots()
Definition: mrulist.cpp:1036
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:990
STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszSubKey) override
Definition: mrulist.cpp:1098
LPBYTE m_pbNodeSlots
Definition: mrulist.cpp:973
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
HRESULT hr
Definition: delayimp.cpp:573
#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
int WINAPI StrCmpW(const WCHAR *str, const WCHAR *comp)
Definition: string.c:450
int WINAPI StrCmpIW(const WCHAR *str, const WCHAR *comp)
Definition: string.c:456
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
EXTERN_C BOOL WINAPI IEILIsEqual(_In_ LPCITEMIDLIST pidl1, _In_ LPCITEMIDLIST pidl2, _In_ BOOL bUnknown)
Definition: utility.cpp:132
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
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
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
static CInternetFolder * CreateInstance(void)
Definition: inetfolder.c:330
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 LPTR
Definition: minwinbase.h:93
#define CopyMemory
Definition: minwinbase.h:29
#define MoveMemory
Definition: minwinbase.h:28
CONST void * LPCVOID
Definition: minwindef.h:164
#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 ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:83
#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:1246
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:1373
#define SLOT_SET
Definition: mrulist.cpp:27
#define COMPARE_BY_IEILISEQUAL
Definition: mrulist.cpp:33
unsigned int UINT
Definition: ndis.h:50
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
_In_ LPWSTR _In_ DWORD _In_ LPCVOID pvData
Definition: netsh.h:116
#define REG_BINARY
Definition: nt_native.h:1499
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define MAXDWORD
static HANDLE ULONG_PTR dwData
Definition: pipe.c:83
long LONG
Definition: pedump.c:60
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1051
LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
Definition: pidl.c:263
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
_In_ _Out_writes_opt_ pcchValueName _Inout_opt_ LPDWORD _Out_opt_ _Out_writes_bytes_to_opt_ pcbData _Inout_opt_ LPDWORD pcbData
Definition: shlwapi.h:757
_In_opt_ LPCSTR pszSubKey
Definition: shlwapi.h:783
_In_opt_ LPCSTR _In_opt_ LPCSTR pszValue
Definition: shlwapi.h:783
#define REG_DWORD
Definition: sdbapi.c:615
static void SHDOCVW_LockModule(void)
Definition: shdocvw.h:59
static void SHDOCVW_UnlockModule(void)
Definition: shdocvw.h:60
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
INT(CALLBACK * SLOTCOMPARE)(LPCVOID pvData1, LPCVOID pvData2, UINT cbData)
Definition: shlobj_undoc.h:25
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:525
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:554
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 WAIT_OBJECT_0
Definition: winbase.h:383
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define E_POINTER
Definition: winerror.h:3480
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193