ReactOS 0.4.15-dev-8116-gf69e256
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 <windef.h>
11#include <winbase.h>
12#include <winreg.h>
13#include <objbase.h>
14#include <oleauto.h>
15#include <shlobj.h>
16#include <shlobj_undoc.h>
17#include <shlguid_undoc.h>
18#include <shlwapi.h>
19#include <shlwapi_undoc.h>
20#include <strsafe.h>
21#include "shdocvw.h"
22
23#include <wine/debug.h>
24
26
27class CSafeMutex;
28class CMruBase;
29 class CMruShortList;
30 class CMruLongList;
31 class CMruNode;
32 class CMruPidlList;
34
35extern "C" void __cxa_pure_virtual(void)
36{
37 ERR("__cxa_pure_virtual\n");
39}
40
42{
43 UINT cb1 = ILGetSize(pidl1), cb2 = ILGetSize(pidl2);
44 if (cb1 == cb2 && memcmp(pidl1, pidl2, cb1) == 0)
45 return TRUE;
46
47 FIXME("%p, %p\n", pidl1, pidl2);
48 return FALSE;
49}
50
51// The flags for SLOTITEMDATA.dwFlags
52#define SLOT_LOADED 0x1
53#define SLOT_SET 0x2
54
55// The flags for CMruBase.m_dwFlags
56#define COMPARE_BY_MEMCMP 0x0
57#define COMPARE_BY_STRCMPIW 0x1
58#define COMPARE_BY_STRCMPW 0x2
59#define COMPARE_BY_IEILISEQUAL 0x3
60#define COMPARE_BY_MASK 0xF
61
63{
64protected:
66
67public:
69 {
70 }
72 {
73 if (m_hMutex)
74 {
76 m_hMutex = NULL;
77 }
78 }
79
81 {
83 if (wait != WAIT_OBJECT_0)
84 return E_FAIL;
85
87 return S_OK;
88 }
89};
90
92 : public IMruDataList
93{
94protected:
95 LONG m_cRefs = 1; // Reference count
96 DWORD m_dwFlags = 0; // The COMPARE_BY_... flags
97 BOOL m_bNeedSave = FALSE; // The flag that indicates whether it needs saving
98 BOOL m_bChecked = FALSE; // The checked flag
99 HKEY m_hKey = NULL; // A registry key
100 DWORD m_cSlotRooms = 0; // Rooms for slots
101 DWORD m_cSlots = 0; // The # of slots
102 SLOTCOMPARE m_fnCompare = NULL; // The comparison function
103 SLOTITEMDATA * m_pSlots = NULL; // Slot data
104
105 HRESULT _LoadItem(UINT iSlot);
106 HRESULT _AddItem(UINT iSlot, LPCVOID pvData, DWORD cbData);
107 HRESULT _GetItem(UINT iSlot, SLOTITEMDATA **ppItem);
108 void _DeleteItem(UINT iSlot);
109
110 HRESULT _GetSlotItem(UINT iSlot, SLOTITEMDATA **ppItem);
111 void _CheckUsedSlots();
112 HRESULT _UseEmptySlot(UINT *piSlot);
113
114public:
115 CMruBase();
116 virtual ~CMruBase();
117
118 // IUnknown methods
119 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
121 {
122 return ::InterlockedIncrement(&m_cRefs);
123 }
125
126 // IMruDataList methods
128 LPCWSTR pszSubKey OPTIONAL,
129 SLOTCOMPARE fnCompare OPTIONAL) override;
130 STDMETHODIMP AddData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override;
131 STDMETHODIMP FindData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override;
132 STDMETHODIMP GetData(UINT iSlot, LPVOID pvData, DWORD cbData) override;
133 STDMETHODIMP QueryInfo(UINT iSlot, UINT *piGotSlot, DWORD *pcbData) override;
134 STDMETHODIMP Delete(UINT iSlot) override;
135
136 // Non-standard methods
137 virtual BOOL _IsEqual(const SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData) const;
138 virtual DWORD _DeleteValue(LPCWSTR pszValue);
139 virtual HRESULT _InitSlots() = 0;
140 virtual void _SaveSlots() = 0;
141 virtual UINT _UpdateSlots(UINT iSlot) = 0;
142 virtual void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) = 0;
143 virtual HRESULT _GetSlot(UINT iSlot, UINT *puSlot) = 0;
144 virtual HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) = 0;
145
146 static void* operator new(size_t size)
147 {
148 return ::LocalAlloc(LPTR, size);
149 }
150 static void operator delete(void *ptr)
151 {
153 }
154};
155
157{
159}
160
162{
163 if (m_hKey)
164 {
166 m_hKey = NULL;
167 }
168
169 if (m_pSlots)
170 {
171 for (UINT iSlot = 0; iSlot < m_cSlots; ++iSlot)
172 {
173 m_pSlots[iSlot].pvData = ::LocalFree(m_pSlots[iSlot].pvData);
174 }
175
177 }
178
180}
181
183{
184 if (!ppvObj)
185 return E_POINTER;
186 if (IsEqualGUID(riid, IID_IMruDataList) || IsEqualGUID(riid, IID_IUnknown))
187 {
188 *ppvObj = static_cast<IMruDataList*>(this);
189 AddRef();
190 return S_OK;
191 }
192 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
193 return E_NOINTERFACE;
194}
195
196STDMETHODIMP_(ULONG) CMruBase::Release()
197{
199 {
200 _SaveSlots();
201 delete this;
202 return 0;
203 }
204 return m_cRefs;
205}
206
208{
209 DWORD cbData;
210 WCHAR szValue[12];
211
212 SLOTITEMDATA *pItem = &m_pSlots[iSlot];
213 _SlotString(iSlot, szValue, _countof(szValue));
214
215 if (SHGetValueW(m_hKey, NULL, szValue, NULL, NULL, &cbData) == ERROR_SUCCESS &&
216 cbData > 0)
217 {
218 pItem->pvData = ::LocalAlloc(LPTR, cbData);
219 if (pItem->pvData)
220 {
221 pItem->cbData = cbData;
222 if (SHGetValueW(m_hKey, NULL, szValue, NULL, pItem->pvData, &cbData) != ERROR_SUCCESS)
223 pItem->pvData = ::LocalFree(pItem->pvData);
224 }
225 }
226
227 pItem->dwFlags |= SLOT_LOADED;
228 if (!pItem->pvData)
229 return E_FAIL;
230
231 return S_OK;
232}
233
235{
236 if (!(m_pSlots[iSlot].dwFlags & SLOT_LOADED))
237 _LoadItem(iSlot);
238
239 SLOTITEMDATA *pItem = &m_pSlots[iSlot];
240 if (!pItem->pvData)
241 return E_OUTOFMEMORY;
242
243 *ppItem = pItem;
244 return S_OK;
245}
246
248{
249 HRESULT hr = _GetSlot(iSlot, &iSlot);
250 if (FAILED(hr))
251 return hr;
252 return _GetSlotItem(iSlot, ppItem);
253}
254
256{
257 WCHAR szBuff[12];
258
259 _SlotString(iSlot, szBuff, _countof(szBuff));
260 _DeleteValue(szBuff);
261
262 m_pSlots[iSlot].pvData = ::LocalFree(m_pSlots[iSlot].pvData);
263}
264
266{
267 UINT iGotSlot;
268 for (UINT iSlot = 0; iSlot < m_cSlots; ++iSlot)
269 _GetSlot(iSlot, &iGotSlot);
270
272}
273
275{
276 SLOTITEMDATA *pItem = &m_pSlots[iSlot];
277
278 WCHAR szBuff[12];
279 _SlotString(iSlot, szBuff, _countof(szBuff));
280
281 if (SHSetValueW(m_hKey, NULL, szBuff, REG_BINARY, pvData, cbData) != ERROR_SUCCESS)
282 return E_OUTOFMEMORY;
283
284 if (cbData >= pItem->cbData || !pItem->pvData)
285 {
286 ::LocalFree(pItem->pvData);
287 pItem->pvData = ::LocalAlloc(LPTR, cbData);
288 }
289
290 if (!pItem->pvData)
291 return E_FAIL;
292
293 pItem->cbData = cbData;
294 pItem->dwFlags = (SLOT_LOADED | SLOT_SET);
295 CopyMemory(pItem->pvData, pvData, cbData);
296 return S_OK;
297}
298
301 UINT cCapacity,
302 UINT flags,
303 HKEY hKey,
304 LPCWSTR pszSubKey OPTIONAL,
305 SLOTCOMPARE fnCompare OPTIONAL)
306{
308 m_fnCompare = fnCompare;
309 m_cSlotRooms = cCapacity;
310
311 if (pszSubKey)
313 else
315
316 if (!m_hKey)
317 return E_FAIL;
318
320 if (!m_pSlots)
321 return E_OUTOFMEMORY;
322
323 return _InitSlots();
324}
325
327{
328 UINT iSlot;
329 HRESULT hr = FindData(pvData, cbData, &iSlot);
330 if (FAILED(hr))
331 {
332 iSlot = _UpdateSlots(m_cSlots);
333 hr = _AddItem(iSlot, pvData, cbData);
334 if (FAILED(hr))
335 return hr;
336 }
337 else
338 {
339 iSlot = _UpdateSlots(iSlot);
340 hr = S_OK;
341 }
342
343 if (piSlot)
344 *piSlot = iSlot;
345
346 return hr;
347}
348
350{
351 if (m_cSlots <= 0)
352 return E_FAIL;
353
354 UINT iSlot = 0;
355 SLOTITEMDATA *pItem;
356 while (FAILED(_GetItem(iSlot, &pItem)) || !_IsEqual(pItem, pvData, cbData))
357 {
358 if (++iSlot >= m_cSlots)
359 return E_FAIL;
360 }
361
362 *piSlot = iSlot;
363 return S_OK;
364}
365
367{
368 SLOTITEMDATA *pItem;
369 HRESULT hr = _GetItem(iSlot, &pItem);
370 if (FAILED(hr))
371 return hr;
372
373 if (cbData < pItem->cbData)
375
376 CopyMemory(pvData, pItem->pvData, pItem->cbData);
377 return hr;
378}
379
381{
382 UINT iGotSlot;
383 HRESULT hr = _GetSlot(iSlot, &iGotSlot);
384 if (FAILED(hr))
385 return hr;
386
387 if (piGotSlot)
388 *piGotSlot = iGotSlot;
389
390 if (pcbData)
391 {
392 SLOTITEMDATA *pItem;
393 hr = _GetSlotItem(iGotSlot, &pItem);
394 if (SUCCEEDED(hr))
395 *pcbData = pItem->cbData;
396 }
397
398 return hr;
399}
400
402{
403 UINT uSlot;
404 HRESULT hr = _RemoveSlot(iSlot, &uSlot);
405 if (FAILED(hr))
406 return hr;
407
408 _DeleteItem(uSlot);
409 return hr;
410}
411
413{
414 if (m_fnCompare)
415 return m_fnCompare(pvData, pItem->pvData, cbData) == 0;
416
417 switch (m_dwFlags & COMPARE_BY_MASK)
418 {
420 if (pItem->cbData != cbData)
421 return FALSE;
422 return memcmp(pvData, pItem->pvData, cbData) == 0;
423
425 return StrCmpIW((LPCWSTR)pvData, (LPCWSTR)pItem->pvData) == 0;
426
428 return StrCmpW((LPCWSTR)pvData, (LPCWSTR)pItem->pvData) == 0;
429
432
433 default:
434 ERR("0x%08X\n", m_dwFlags);
435 return FALSE;
436 }
437}
438
440{
441 return SHDeleteValueW(m_hKey, NULL, pszValue);
442}
443
445{
446 if (!m_bChecked)
448
449 if (!m_cSlotRooms)
450 return E_FAIL;
451
452 UINT iSlot = 0;
453 for (SLOTITEMDATA *pItem = m_pSlots; (pItem->dwFlags & SLOT_SET); ++pItem)
454 {
455 if (++iSlot >= m_cSlotRooms)
456 return E_FAIL;
457 }
458
459 m_pSlots[iSlot].dwFlags |= SLOT_SET;
460 *piSlot = iSlot;
461 ++m_cSlots;
462
463 return S_OK;
464}
465
467 : public CMruBase
468{
469protected:
471
472 HRESULT _InitSlots() override;
473 void _SaveSlots() override;
474 UINT _UpdateSlots(UINT iSlot) override;
475 void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override;
476 HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override;
477 HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override;
478 friend class CMruLongList;
479
480public:
482 {
483 }
484
485 ~CMruShortList() override
486 {
488 }
489};
490
492{
493 DWORD cbData = (m_cSlotRooms + 1) * sizeof(WCHAR);
495 if (!m_pszSlotData)
496 return E_OUTOFMEMORY;
497
498 if (SHGetValueW(m_hKey, NULL, L"MRUList", NULL, m_pszSlotData, &cbData) == ERROR_SUCCESS)
499 m_cSlots = (cbData / sizeof(WCHAR)) - 1;
500
502 return S_OK;
503}
504
506{
507 if (m_bNeedSave)
508 {
509 DWORD cbData = (m_cSlots + 1) * sizeof(WCHAR);
510 SHSetValueW(m_hKey, NULL, L"MRUList", REG_SZ, m_pszSlotData, cbData);
512 }
513}
514
515// NOTE: MRUList uses lowercase alphabet for history of most recently used items.
517{
518 UINT iData, cDataToMove = iSlot;
519
520 if (iSlot == m_cSlots)
521 {
522 if (SUCCEEDED(_UseEmptySlot(&iData)))
523 {
524 ++cDataToMove;
525 }
526 else
527 {
528 // This code is getting the item index from a lowercase letter.
529 iData = m_pszSlotData[m_cSlots - 1] - L'a';
530 --cDataToMove;
531 }
532 }
533 else
534 {
535 iData = m_pszSlotData[iSlot] - L'a';
536 }
537
538 if (cDataToMove)
539 {
540 MoveMemory(m_pszSlotData + 1, m_pszSlotData, cDataToMove * sizeof(WCHAR));
541 m_pszSlotData[0] = (WCHAR)(L'a' + iData);
543 }
544
545 return iData;
546}
547
549{
550 if (cch >= 2)
551 {
552 psz[0] = (WCHAR)(L'a' + iSlot);
553 psz[1] = UNICODE_NULL;
554 }
555}
556
558{
559 if (iSlot >= m_cSlots)
560 return E_FAIL;
561
562 UINT iData = m_pszSlotData[iSlot] - L'a';
563 if (iData >= m_cSlotRooms)
564 return E_FAIL;
565
566 *puSlot = iData;
567 m_pSlots[iData].dwFlags |= SLOT_SET;
568 return S_OK;
569}
570
572{
573 HRESULT hr = _GetSlot(iSlot, puSlot);
574 if (FAILED(hr))
575 return hr;
576
577 MoveMemory(&m_pszSlotData[iSlot], &m_pszSlotData[iSlot + 1], (m_cSlots - iSlot) * sizeof(WCHAR));
578 --m_cSlots;
579 m_pSlots->dwFlags &= ~SLOT_SET;
581
582 return hr;
583}
584
586 : public CMruBase
587{
588protected:
589 UINT *m_puSlotData = NULL; // The slot data
590
591 void _ImportShortList();
592
593 HRESULT _InitSlots() override;
594 void _SaveSlots() override;
595 UINT _UpdateSlots(UINT iSlot) override;
596 void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override;
597 HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override;
598 HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override;
599
600public:
602 {
603 }
604
605 ~CMruLongList() override
606 {
608 }
609};
610
612{
613 DWORD cbData = (m_cSlotRooms + 1) * sizeof(UINT);
614 m_puSlotData = (UINT*)LocalAlloc(LPTR, cbData);
615 if (!m_puSlotData)
616 return E_OUTOFMEMORY;
617
618 if (SHGetValueW(m_hKey, NULL, L"MRUListEx", NULL, m_puSlotData, &cbData) == ERROR_SUCCESS)
619 m_cSlots = (cbData / sizeof(UINT)) - 1;
620 else
622
624 return S_OK;
625}
626
628{
629 if (m_bNeedSave)
630 {
632 (m_cSlots + 1) * sizeof(UINT));
634 }
635}
636
638{
639 UINT cSlotsToMove, uSlotData;
640
641 cSlotsToMove = iSlot;
642 if (iSlot == m_cSlots)
643 {
644 if (SUCCEEDED(_UseEmptySlot(&uSlotData)))
645 {
646 ++cSlotsToMove;
647 }
648 else
649 {
650 uSlotData = m_puSlotData[m_cSlots - 1];
651 --cSlotsToMove;
652 }
653 }
654 else
655 {
656 uSlotData = m_puSlotData[iSlot];
657 }
658
659 if (cSlotsToMove > 0)
660 {
661 MoveMemory(m_puSlotData + 1, m_puSlotData, cSlotsToMove * sizeof(UINT));
662 m_puSlotData[0] = uSlotData;
664 }
665
666 return uSlotData;
667}
668
670{
671 StringCchPrintfW(psz, cch, L"%d", iSlot);
672}
673
675{
676 if (iSlot >= m_cSlots)
677 return E_FAIL;
678
679 UINT uSlotData = m_puSlotData[iSlot];
680 if (uSlotData >= m_cSlotRooms)
681 return E_FAIL;
682
683 *puSlot = uSlotData;
684 m_pSlots[uSlotData].dwFlags |= SLOT_SET;
685 return S_OK;
686}
687
689{
690 HRESULT hr = _GetSlot(iSlot, puSlot);
691 if (FAILED(hr))
692 return hr;
693
694 MoveMemory(&m_puSlotData[iSlot], &m_puSlotData[iSlot + 1], (m_cSlots - iSlot) * sizeof(UINT));
695 --m_cSlots;
696 m_pSlots[0].dwFlags &= ~SLOT_SET;
698
699 return hr;
700}
701
703{
704 CMruShortList *pShortList = new CMruShortList();
705 if (!pShortList)
706 return;
707
708 HRESULT hr = pShortList->InitData(m_cSlotRooms, 0, m_hKey, NULL, NULL);
709 if (SUCCEEDED(hr))
710 {
711 for (;;)
712 {
713 UINT iSlot;
714 hr = pShortList->_GetSlot(m_cSlots, &iSlot);
715 if (FAILED(hr))
716 break;
717
718 SLOTITEMDATA *pItem;
719 hr = pShortList->_GetSlotItem(iSlot, &pItem);
720 if (FAILED(hr))
721 break;
722
723 _AddItem(iSlot, pItem->pvData, pItem->cbData);
724 pShortList->_DeleteItem(iSlot);
725
726 m_puSlotData[m_cSlots++] = iSlot;
727 }
728
730 }
731
732 SHDeleteValueW(m_hKey, NULL, L"MRUList");
733 pShortList->Release();
734}
735
738{
739 UNREFERENCED_PARAMETER(dwUnused1);
740 UNREFERENCED_PARAMETER(dwUnused3);
741
742 TRACE("%p %p %p\n", dwUnused1, ppv, dwUnused3);
743
744 if (!ppv)
745 return E_POINTER;
746
747 CMruLongList *pMruList = new CMruLongList();
748 *ppv = static_cast<IMruDataList*>(pMruList);
749 TRACE("%p\n", *ppv);
750
751 return S_OK;
752}
753
755 : public CMruLongList
756{
757protected:
758 UINT m_iSlot = 0; // The slot index
759 CMruNode *m_pParent = NULL; // The parent
760 IShellFolder *m_pShellFolder = NULL; // The shell folder
761
762 BOOL _InitLate();
763 BOOL _IsEqual(SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData);
764 DWORD _DeleteValue(LPCWSTR pszValue) override;
765
766 HRESULT _CreateNode(UINT iSlot, CMruNode **ppNewNode);
767 HRESULT _AddPidl(UINT iSlot, LPCITEMIDLIST pidl);
768 HRESULT _FindPidl(LPCITEMIDLIST pidl, UINT *piSlot);
769 HRESULT _GetPidlSlot(LPCITEMIDLIST pidl, BOOL bAdd, UINT *piSlot);
770
771public:
773 CMruNode(CMruNode *pParent, UINT iSlot);
774 ~CMruNode() override;
775
777
778 HRESULT BindToSlot(UINT iSlot, IShellFolder **ppSF);
779 HRESULT GetNode(BOOL bAdd, LPCITEMIDLIST pidl, CMruNode **pNewNode);
780 HRESULT GetNodeSlot(UINT *pnNodeSlot);
781 HRESULT SetNodeSlot(UINT nNodeSlot);
782
783 HRESULT RemoveLeast(UINT *pnNodeSlot);
785};
786
788{
789 m_iSlot = iSlot;
791 pParent->AddRef();
792}
793
795{
796 if (m_pParent)
797 {
798 m_pParent->Release();
799 m_pParent = NULL;
800 }
801
802 if (m_pShellFolder)
803 {
806 }
807}
808
810{
811 if (m_pParent)
812 m_pParent->AddRef();
813 return m_pParent;
814}
815
817{
818 CMruNode *pNewNode = new CMruNode(this, iSlot);
819 if (!pNewNode)
820 return E_OUTOFMEMORY;
821
822 WCHAR szSubKey[12];
823 _SlotString(iSlot, szSubKey, _countof(szSubKey));
824
825 HRESULT hr = pNewNode->InitData(m_cSlotRooms, 0, m_hKey, szSubKey, NULL);
826 if (FAILED(hr))
827 pNewNode->Release();
828 else
829 *ppNewNode = pNewNode;
830
831 return hr;
832}
833
835{
836 if (!pidl || !pidl->mkid.cb)
837 {
838 *ppNewNode = this;
839 AddRef();
840 return S_OK;
841 }
842
843 if (!_InitLate())
844 return E_FAIL;
845
846 UINT iSlot;
847 HRESULT hr = _GetPidlSlot(pidl, bAdd, &iSlot);
848 if (FAILED(hr))
849 {
850 if (!bAdd)
851 {
852 *ppNewNode = this;
853 AddRef();
854 return S_FALSE;
855 }
856 return hr;
857 }
858
859 CMruNode *pNewNode;
860 hr = _CreateNode(iSlot, &pNewNode);
861 if (SUCCEEDED(hr))
862 {
863 _SaveSlots();
864
865 LPCITEMIDLIST pidl2 = (LPCITEMIDLIST)((LPBYTE)pidl + pidl->mkid.cb);
866 pNewNode->GetNode(bAdd, pidl2, ppNewNode);
867 pNewNode->Release();
868 }
869
870 return hr;
871}
872
874{
875 SLOTITEMDATA *pItem;
876 HRESULT hr = _GetSlotItem(iSlot, &pItem);
877 if (FAILED(hr))
878 return hr;
879
881 NULL,
882 IID_IShellFolder,
883 (void **)ppSF);
884}
885
887{
888 if (!m_pShellFolder)
889 {
890 if (m_pParent)
892 else
894 }
895 return !!m_pShellFolder;
896}
897
899{
900 return m_pShellFolder->CompareIDs(0x10000000,
901 (LPITEMIDLIST)pItem->pvData,
902 (LPCITEMIDLIST)pvData) == 0;
903}
904
906{
907 DWORD dwData, cbData = sizeof(dwData);
908 DWORD error = SHGetValueW(m_hKey, NULL, L"NodeSlot", NULL, &dwData, (pnNodeSlot ? &cbData : NULL));
909 if (error != ERROR_SUCCESS)
910 return E_FAIL;
911 *pnNodeSlot = (UINT)dwData;
912 return S_OK;
913}
914
916{
917 DWORD dwData = nNodeSlot;
918 if (SHSetValueW(m_hKey, NULL, L"NodeSlot", REG_DWORD, &dwData, sizeof(dwData)) != ERROR_SUCCESS)
919 return E_FAIL;
920 return S_OK;
921}
922
924{
925 return CMruBase::_AddItem(iSlot, pidl, sizeof(WORD) + pidl->mkid.cb);
926}
927
929{
930 CMruBase::_DeleteValue(pszValue);
931 return SHDeleteKeyW(m_hKey, pszValue);
932}
933
935{
936 return FindData(pidl, sizeof(WORD) + pidl->mkid.cb, piSlot);
937}
938
940{
941 LPITEMIDLIST pidlFirst = ILCloneFirst(pidl);
942 if (!pidlFirst)
943 return E_OUTOFMEMORY;
944
945 UINT iSlot;
946 HRESULT hr = _FindPidl(pidlFirst, &iSlot);
947 if (SUCCEEDED(hr))
948 {
949 *piSlot = _UpdateSlots(iSlot);
950 hr = S_OK;
951 }
952 else if (bAdd)
953 {
954 *piSlot = _UpdateSlots(m_cSlots);
955 hr = _AddPidl(*piSlot, pidlFirst);
956 }
957
958 ILFree(pidlFirst);
959 return hr;
960}
961
963{
964 if (!m_cSlots)
965 {
966 GetNodeSlot(pnNodeSlot);
967 return S_FALSE;
968 }
969
970 UINT uSlot;
971 HRESULT hr = _GetSlot(m_cSlots - 1, &uSlot);
972 if (FAILED(hr))
973 return hr;
974
975 CMruNode *pNode;
976 hr = _CreateNode(uSlot, &pNode);
977 if (SUCCEEDED(hr))
978 {
979 hr = pNode->RemoveLeast(pnNodeSlot);
980 pNode->Release();
981 }
982
983 if (hr == S_FALSE)
984 {
985 Delete(m_cSlots - 1);
986 if (m_cSlots || SUCCEEDED(GetNodeSlot(0)))
987 return S_OK;
988 }
989
990 return hr;
991}
992
994 : public CMruNode
995 , public IMruPidlList
996{
997protected:
998 LPBYTE m_pbNodeSlots = NULL; // The node slots (contains SLOT_... flags)
999 DWORD m_cMaxNodeSlots = 0; // The upper bound of the node slot index
1000 HANDLE m_hMutex = NULL; // The mutex (for sync)
1001
1003 void _SaveNodeSlots();
1005
1006public:
1008 ~CMruPidlList() override;
1009
1010 HRESULT GetEmptySlot(UINT *pnNodeSlot);
1011 void EmptyNodeSlot(UINT nNodeSlot);
1012
1013 // IUnknown methods
1014 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
1016 {
1017 return CMruBase::AddRef();
1018 }
1020 {
1021 return CMruBase::Release();
1022 }
1023
1024 // IMruPidlList methods
1025 STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszSubKey) override;
1026 STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot) override;
1028 LPCITEMIDLIST pidl,
1029 UINT cSlots,
1030 UINT *pnNodeSlots,
1031 UINT *pcNodeSlots) override;
1032 STDMETHODIMP PruneKids(LPCITEMIDLIST pidl) override;
1033};
1034
1036{
1038 if (m_hMutex)
1039 {
1041 m_hMutex = NULL;
1042 }
1043}
1044
1046{
1047 if (!ppvObj)
1048 return E_POINTER;
1049
1050 if (::IsEqualGUID(riid, IID_IMruPidlList) || ::IsEqualGUID(riid, IID_IUnknown))
1051 {
1052 *ppvObj = static_cast<IMruPidlList*>(this);
1053 AddRef();
1054 return S_OK;
1055 }
1056
1057 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
1058 return E_NOINTERFACE;
1059}
1060
1062{
1063 DWORD cbNodeSlots = m_cSlotRooms * sizeof(BYTE);
1064 if (SHGetValueW(m_hKey, NULL, L"NodeSlots", NULL, m_pbNodeSlots, &cbNodeSlots) != ERROR_SUCCESS)
1065 return FALSE;
1066 m_cMaxNodeSlots = cbNodeSlots / sizeof(BYTE);
1067 return TRUE;
1068}
1069
1071{
1072 DWORD cbNodeSlots = m_cMaxNodeSlots * sizeof(BYTE);
1073 SHSetValueW(m_hKey, NULL, L"NodeSlots", REG_BINARY, m_pbNodeSlots, cbNodeSlots);
1074}
1075
1077{
1079 if (!m_pbNodeSlots)
1080 return E_OUTOFMEMORY;
1081
1083 m_bNeedSave = TRUE;
1085
1086 return S_OK;
1087}
1088
1090{
1091 *pnNodeSlot = 0;
1092
1093 if (!_LoadNodeSlots())
1094 return E_FAIL;
1095
1097 {
1099 *pnNodeSlot = ++m_cMaxNodeSlots;
1101 return S_OK;
1102 }
1103
1104 for (UINT iNodeSlot = 0; iNodeSlot < m_cMaxNodeSlots; ++iNodeSlot)
1105 {
1106 if (m_pbNodeSlots[iNodeSlot] & SLOT_SET)
1107 continue;
1108
1109 m_pbNodeSlots[iNodeSlot] = SLOT_SET;
1110 *pnNodeSlot = iNodeSlot + 1; // nNodeSlot is 1-base
1112 return S_OK;
1113 }
1114
1115 HRESULT hr = E_FAIL;
1116 if (SUCCEEDED(RemoveLeast(pnNodeSlot)) && *pnNodeSlot)
1117 hr = S_OK;
1118
1120 return hr;
1121}
1122
1124{
1125 TRACE("%p -> %u %p %s\n", this, cMRUSize, hKey, debugstr_w(pszSubKey));
1126
1127 HRESULT hr = InitData(cMRUSize, 0, hKey, pszSubKey, NULL);
1128 if (FAILED(hr))
1129 {
1130 ERR("0x%08lX\n", hr);
1131 return hr;
1132 }
1133
1134 hr = _InitNodeSlots();
1135 if (FAILED(hr))
1136 {
1137 ERR("0x%08lX\n", hr);
1138 return hr;
1139 }
1140
1141 m_hMutex = ::CreateMutexW(NULL, FALSE, L"Shell.CMruPidlList");
1142 if (!m_hMutex)
1143 {
1145 ERR("0x%08lX\n", hr);
1146 }
1147
1148 return hr;
1149}
1150
1152{
1153 TRACE("%p -> %p %p\n", this, pidl, pnNodeSlot);
1154
1156 HRESULT hr = mutex.Enter(m_hMutex);
1157 if (FAILED(hr))
1158 {
1159 ERR("0x%08lX\n", hr);
1160 return hr;
1161 }
1162
1163 *pnNodeSlot = 0;
1164
1165 CMruNode *pNode;
1166 hr = GetNode(TRUE, pidl, &pNode);
1167 if (FAILED(hr))
1168 {
1169 ERR("0x%08lX\n", hr);
1170 return hr;
1171 }
1172
1173 hr = pNode->GetNodeSlot(pnNodeSlot);
1174 if (FAILED(hr))
1175 {
1176 hr = GetEmptySlot(pnNodeSlot);
1177 if (SUCCEEDED(hr))
1178 {
1179 hr = pNode->SetNodeSlot(*pnNodeSlot);
1180 }
1181 }
1182
1183 pNode->Release();
1184 return hr;
1185}
1186
1188 LPCITEMIDLIST pidl,
1189 UINT cSlots,
1190 UINT *pnNodeSlots,
1191 UINT *pcNodeSlots)
1192{
1193 TRACE("%p -> %p %u %p %p\n", this, pidl, cSlots, pnNodeSlots, pcNodeSlots);
1194
1196 HRESULT hr = mutex.Enter(m_hMutex);
1197 if (FAILED(hr))
1198 {
1199 ERR("0x%08lX\n", hr);
1200 return hr;
1201 }
1202
1203 *pcNodeSlots = 0;
1204
1205 CMruNode *pNode;
1206 hr = GetNode(FALSE, pidl, &pNode);
1207 if (FAILED(hr))
1208 {
1209 ERR("0x%08lX\n", hr);
1210 return hr;
1211 }
1212
1213 while (pNode && *pcNodeSlots < cSlots)
1214 {
1215 CMruNode *pParent = pNode->GetParent();
1216 if (SUCCEEDED(pNode->GetNodeSlot(&pnNodeSlots[*pcNodeSlots])))
1217 ++(*pcNodeSlots);
1218 else if (hr == S_OK && !*pcNodeSlots)
1219 hr = S_FALSE;
1220
1221 pNode->Release();
1222 pNode = pParent;
1223 }
1224
1225 if (pNode)
1226 pNode->Release();
1227
1228 if (SUCCEEDED(hr) && !*pcNodeSlots)
1229 hr = E_FAIL;
1230
1231 return hr;
1232}
1233
1235{
1236 TRACE("%p -> %p\n", this, pidl);
1237
1239 HRESULT hr = mutex.Enter(m_hMutex);
1240 if (FAILED(hr))
1241 {
1242 ERR("0x%08lX\n", hr);
1243 return hr;
1244 }
1245
1246 if (!_LoadNodeSlots())
1247 return hr;
1248
1249 CMruNode *pNode;
1250 hr = GetNode(FALSE, pidl, &pNode);
1251 if (FAILED(hr))
1252 return hr;
1253
1254 if (hr == S_OK)
1255 hr = pNode->Clear(this);
1256 else
1257 hr = E_FAIL;
1258
1259 pNode->Release();
1260
1262 return hr;
1263}
1264
1266{
1267 m_pbNodeSlots[nNodeSlot - 1] = 0; // nNodeSlot is 1-base
1268 m_bNeedSave = TRUE;
1269}
1270
1272{
1273 UNREFERENCED_PARAMETER(dwUnused1);
1274 UNREFERENCED_PARAMETER(dwUnused3);
1275
1276 TRACE("%p %p %p\n", dwUnused1, ppv, dwUnused3);
1277
1278 if (!ppv)
1279 return E_POINTER;
1280
1281 *ppv = NULL;
1282
1283 CMruPidlList *pMruList = new CMruPidlList();
1284 if (pMruList == NULL)
1285 return E_OUTOFMEMORY;
1286
1287 *ppv = static_cast<IMruPidlList*>(pMruList);
1288 TRACE("%p\n", *ppv);
1289 return S_OK;
1290}
1291
1293{
1294 UINT uSlot, nNodeSlot;
1295 HRESULT hr;
1296
1297 while (SUCCEEDED(_GetSlot(0, &uSlot)))
1298 {
1299 CMruNode *pNode;
1300 hr = _CreateNode(uSlot, &pNode);
1301 if (SUCCEEDED(hr))
1302 {
1303 hr = pNode->GetNodeSlot(&nNodeSlot);
1304 if (SUCCEEDED(hr))
1305 pList->EmptyNodeSlot(nNodeSlot);
1306
1307 pNode->Clear(pList);
1308 pNode->Release();
1309 }
1310 Delete(0);
1311 }
1312
1313 return S_OK;
1314}
1315
1317{
1318protected:
1320
1321public:
1323 {
1325 }
1327 {
1329 }
1330
1331 // IUnknown methods
1332 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
1334 {
1335 return ::InterlockedIncrement(&m_cRefs);
1336 }
1338 {
1340 {
1341 delete this;
1342 return 0;
1343 }
1344 return m_cRefs;
1345 }
1346
1347 // IClassFactory methods
1350
1351 static void* operator new(size_t size)
1352 {
1353 return ::LocalAlloc(LPTR, size);
1354 }
1355 static void operator delete(void *ptr)
1356 {
1358 }
1359};
1360
1362{
1363 if (!ppvObj)
1364 return E_POINTER;
1366 {
1367 *ppvObj = static_cast<IClassFactory*>(this);
1368 AddRef();
1369 return S_OK;
1370 }
1371 ERR("%s: E_NOINTERFACE\n", debugstr_guid(&riid));
1372 return E_NOINTERFACE;
1373}
1374
1376{
1377 if (pUnkOuter)
1378 return CLASS_E_NOAGGREGATION;
1379
1380 if (IsEqualGUID(riid, IID_IMruDataList))
1382
1383 if (IsEqualGUID(riid, IID_IMruPidlList))
1385
1386 return E_NOINTERFACE;
1387}
1388
1390{
1391 if (fLock)
1393 else
1394 ::InterlockedDecrement(&SHDOCVW_refCount);
1395 return S_OK;
1396}
1397
1399{
1400 CMruClassFactory *pFactory = new CMruClassFactory();
1401 if (!pFactory)
1402 return E_OUTOFMEMORY;
1403
1404 HRESULT hr = pFactory->QueryInterface(riid, ppv);
1405 pFactory->Release();
1406 return hr;
1407}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#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 FIXME(fmt,...)
Definition: debug.h:114
#define ERR(fmt,...)
Definition: debug.h:113
#define RegCloseKey(hKey)
Definition: registry.h:49
_In_ BOOLEAN Release
Definition: cdrom.h:920
HKEY m_hKey
Definition: mrulist.cpp:99
DWORD m_cSlots
Definition: mrulist.cpp:101
STDMETHODIMP AddData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override
Definition: mrulist.cpp:326
DWORD m_dwFlags
Definition: mrulist.cpp:96
virtual ~CMruBase()
Definition: mrulist.cpp:161
virtual HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot)=0
void _DeleteItem(UINT iSlot)
Definition: mrulist.cpp:255
BOOL m_bNeedSave
Definition: mrulist.cpp:97
CMruBase()
Definition: mrulist.cpp:156
HRESULT _LoadItem(UINT iSlot)
Definition: mrulist.cpp:207
STDMETHODIMP_(ULONG) Release() override
SLOTITEMDATA * m_pSlots
Definition: mrulist.cpp:103
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:182
HRESULT _GetItem(UINT iSlot, SLOTITEMDATA **ppItem)
Definition: mrulist.cpp:247
LONG m_cRefs
Definition: mrulist.cpp:95
virtual DWORD _DeleteValue(LPCWSTR pszValue)
Definition: mrulist.cpp:439
STDMETHODIMP Delete(UINT iSlot) override
Definition: mrulist.cpp:401
virtual BOOL _IsEqual(const SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData) const
Definition: mrulist.cpp:412
virtual UINT _UpdateSlots(UINT iSlot)=0
HRESULT _GetSlotItem(UINT iSlot, SLOTITEMDATA **ppItem)
Definition: mrulist.cpp:234
virtual HRESULT _GetSlot(UINT iSlot, UINT *puSlot)=0
SLOTCOMPARE m_fnCompare
Definition: mrulist.cpp:102
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:120
virtual void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch)=0
HRESULT _UseEmptySlot(UINT *piSlot)
Definition: mrulist.cpp:444
BOOL m_bChecked
Definition: mrulist.cpp:98
STDMETHODIMP GetData(UINT iSlot, LPVOID pvData, DWORD cbData) override
Definition: mrulist.cpp:366
STDMETHODIMP FindData(LPCVOID pvData, DWORD cbData, UINT *piSlot) override
Definition: mrulist.cpp:349
void _CheckUsedSlots()
Definition: mrulist.cpp:265
STDMETHODIMP InitData(UINT cCapacity, UINT flags, HKEY hKey, LPCWSTR pszSubKey OPTIONAL, SLOTCOMPARE fnCompare OPTIONAL) override
Definition: mrulist.cpp:300
DWORD m_cSlotRooms
Definition: mrulist.cpp:100
virtual HRESULT _InitSlots()=0
STDMETHODIMP QueryInfo(UINT iSlot, UINT *piGotSlot, DWORD *pcbData) override
Definition: mrulist.cpp:380
virtual void _SaveSlots()=0
HRESULT _AddItem(UINT iSlot, LPCVOID pvData, DWORD cbData)
Definition: mrulist.cpp:274
STDMETHODIMP LockServer(BOOL fLock)
Definition: mrulist.cpp:1389
STDMETHODIMP_(ULONG) Release()
Definition: mrulist.cpp:1337
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:1333
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:1361
STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
Definition: mrulist.cpp:1375
virtual ~CMruClassFactory()
Definition: mrulist.cpp:1326
UINT _UpdateSlots(UINT iSlot) override
Definition: mrulist.cpp:637
void _ImportShortList()
Definition: mrulist.cpp:702
~CMruLongList() override
Definition: mrulist.cpp:605
void _SaveSlots() override
Definition: mrulist.cpp:627
UINT * m_puSlotData
Definition: mrulist.cpp:589
HRESULT _InitSlots() override
Definition: mrulist.cpp:611
HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:674
HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:688
void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override
Definition: mrulist.cpp:669
HRESULT SetNodeSlot(UINT nNodeSlot)
Definition: mrulist.cpp:915
HRESULT Clear(CMruPidlList *pList)
Definition: mrulist.cpp:1292
HRESULT _GetPidlSlot(LPCITEMIDLIST pidl, BOOL bAdd, UINT *piSlot)
Definition: mrulist.cpp:939
CMruNode * m_pParent
Definition: mrulist.cpp:759
HRESULT BindToSlot(UINT iSlot, IShellFolder **ppSF)
Definition: mrulist.cpp:873
HRESULT RemoveLeast(UINT *pnNodeSlot)
Definition: mrulist.cpp:962
HRESULT _CreateNode(UINT iSlot, CMruNode **ppNewNode)
Definition: mrulist.cpp:816
BOOL _InitLate()
Definition: mrulist.cpp:886
CMruNode()
Definition: mrulist.cpp:772
BOOL _IsEqual(SLOTITEMDATA *pItem, LPCVOID pvData, UINT cbData)
Definition: mrulist.cpp:898
UINT m_iSlot
Definition: mrulist.cpp:758
IShellFolder * m_pShellFolder
Definition: mrulist.cpp:760
HRESULT _AddPidl(UINT iSlot, LPCITEMIDLIST pidl)
Definition: mrulist.cpp:923
HRESULT GetNode(BOOL bAdd, LPCITEMIDLIST pidl, CMruNode **pNewNode)
Definition: mrulist.cpp:834
~CMruNode() override
Definition: mrulist.cpp:794
HRESULT GetNodeSlot(UINT *pnNodeSlot)
Definition: mrulist.cpp:905
DWORD _DeleteValue(LPCWSTR pszValue) override
Definition: mrulist.cpp:928
HRESULT _FindPidl(LPCITEMIDLIST pidl, UINT *piSlot)
Definition: mrulist.cpp:934
CMruNode * GetParent()
Definition: mrulist.cpp:809
STDMETHODIMP QueryPidl(LPCITEMIDLIST pidl, UINT cSlots, UINT *pnNodeSlots, UINT *pcNodeSlots) override
Definition: mrulist.cpp:1187
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: mrulist.cpp:1045
STDMETHODIMP PruneKids(LPCITEMIDLIST pidl) override
Definition: mrulist.cpp:1234
HRESULT _InitNodeSlots()
Definition: mrulist.cpp:1076
STDMETHODIMP_(ULONG) Release() override
Definition: mrulist.cpp:1019
DWORD m_cMaxNodeSlots
Definition: mrulist.cpp:999
HANDLE m_hMutex
Definition: mrulist.cpp:1000
void EmptyNodeSlot(UINT nNodeSlot)
Definition: mrulist.cpp:1265
void _SaveNodeSlots()
Definition: mrulist.cpp:1070
STDMETHODIMP UsePidl(LPCITEMIDLIST pidl, UINT *pnNodeSlot) override
Definition: mrulist.cpp:1151
~CMruPidlList() override
Definition: mrulist.cpp:1035
HRESULT GetEmptySlot(UINT *pnNodeSlot)
Definition: mrulist.cpp:1089
BOOL _LoadNodeSlots()
Definition: mrulist.cpp:1061
STDMETHODIMP_(ULONG) AddRef() override
Definition: mrulist.cpp:1015
STDMETHODIMP InitList(UINT cMRUSize, HKEY hKey, LPCWSTR pszSubKey) override
Definition: mrulist.cpp:1123
LPBYTE m_pbNodeSlots
Definition: mrulist.cpp:998
void _SaveSlots() override
Definition: mrulist.cpp:505
LPWSTR m_pszSlotData
Definition: mrulist.cpp:470
void _SlotString(UINT iSlot, LPWSTR psz, DWORD cch) override
Definition: mrulist.cpp:548
HRESULT _InitSlots() override
Definition: mrulist.cpp:491
HRESULT _GetSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:557
HRESULT _RemoveSlot(UINT iSlot, UINT *puSlot) override
Definition: mrulist.cpp:571
~CMruShortList() override
Definition: mrulist.cpp:485
UINT _UpdateSlots(UINT iSlot) override
Definition: mrulist.cpp:516
HRESULT Enter(HANDLE hMutex)
Definition: mrulist.cpp:80
CSafeMutex()
Definition: mrulist.cpp:68
HANDLE m_hMutex
Definition: mrulist.cpp:65
~CSafeMutex()
Definition: mrulist.cpp:71
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
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:386
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:57
#define COMPARE_BY_MEMCMP
Definition: mrulist.cpp:56
void __cxa_pure_virtual(void)
Definition: mrulist.cpp:35
EXTERN_C HRESULT CMruPidlList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, DWORD_PTR dwUnused3)
Definition: mrulist.cpp:1271
EXTERN_C HRESULT CMruLongList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, DWORD_PTR dwUnused3)
Definition: mrulist.cpp:737
BOOL IEILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, BOOL bUnknown)
Definition: mrulist.cpp:41
#define SLOT_LOADED
Definition: mrulist.cpp:52
#define COMPARE_BY_MASK
Definition: mrulist.cpp:60
#define COMPARE_BY_STRCMPW
Definition: mrulist.cpp:58
EXTERN_C HRESULT CMruClassFactory_CreateInstance(REFIID riid, void **ppv)
Definition: mrulist.cpp:1398
#define SLOT_SET
Definition: mrulist.cpp:53
#define COMPARE_BY_IEILISEQUAL
Definition: mrulist.cpp:59
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:317
#define MAXDWORD
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:938
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
LONG SHDOCVW_refCount
Definition: shdocvw_main.c:44
#define ILGetSize
Definition: shellclasses.h:638
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:381
void WINAPI DebugBreak(void)
#define CopyMemory
Definition: winbase.h:1710
#define MoveMemory
Definition: winbase.h:1709
#define WAIT_OBJECT_0
Definition: winbase.h:406
_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