ReactOS 0.4.17-dev-357-ga8f14ff
propbag.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Shell
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Implement shell property bags
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#define _ATL_NO_EXCEPTIONS
9#include "precomp.h"
10#include <shlwapi.h>
11#include <shlwapi_undoc.h>
12#include <shlobj_undoc.h>
13#include <shlguid_undoc.h>
14#include <atlstr.h> // for CStringW
15#include <atlsimpcoll.h> // for CSimpleMap
16#include <atlcomcli.h> // for CComVariant
17#include <atlconv.h> // for CA2W and CW2A
18#include <strsafe.h> // for StringC... functions
19#include <cstdlib> // __min
20#include <new> // std::nothrow
21
23
24#define MODE_CAN_READ(dwMode) \
25 (((dwMode) & (STGM_READ | STGM_WRITE | STGM_READWRITE)) != STGM_WRITE)
26#define MODE_CAN_WRITE(dwMode) \
27 (((dwMode) & (STGM_READ | STGM_WRITE | STGM_READWRITE)) != STGM_READ)
28
30 : public IPropertyBag
31#if (_WIN32_WINNT < _WIN32_WINNT_VISTA) || defined(__REACTOS__)
32 , public IPropertyBag2
33#endif
34{
35protected:
36 LONG m_cRefs; // reference count
37 DWORD m_dwMode; // STGM_* flags
38
39public:
41 : m_cRefs(0)
42 , m_dwMode(dwMode)
43 {
44 }
45
46 virtual ~CBasePropertyBag() { }
47
48 // IUnknown interface
49 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
50 {
51 if (!ppvObject)
52 return E_POINTER;
53
55 {
56 if (::IsEqualGUID(riid, IID_IPropertyBag2))
57 {
58 AddRef();
59 *ppvObject = static_cast<IPropertyBag2*>(this);
60 return S_OK;
61 }
62 }
63
65 {
66 AddRef();
67 *ppvObject = static_cast<IPropertyBag*>(this);
68 return S_OK;
69 }
70
71 ERR("%p: %s: E_NOINTERFACE\n", this, debugstr_guid(&riid));
72 return E_NOINTERFACE;
73 }
75 {
76 return ::InterlockedIncrement(&m_cRefs);
77 }
79 {
81 {
82 delete this;
83 return 0;
84 }
85 return m_cRefs;
86 }
87
88#if (_WIN32_WINNT < _WIN32_WINNT_VISTA) || defined(__REACTOS__)
89 // IPropertyBag2 interface (stubs)
91 _In_ ULONG cProperties,
92 _In_ PROPBAG2 *pPropBag,
93 _In_opt_ IErrorLog *pErrorLog,
94 _Out_ VARIANT *pvarValue,
95 _Out_ HRESULT *phrError) override
96 {
97 return E_NOTIMPL;
98 }
100 _In_ ULONG cProperties,
101 _In_ PROPBAG2 *pPropBag,
102 _In_ VARIANT *pvarValue)
103 {
104 return E_NOTIMPL;
105 }
106 STDMETHODIMP CountProperties(_Out_ ULONG *pcProperties) override
107 {
108 return E_NOTIMPL;
109 }
110 STDMETHODIMP GetPropertyInfo(
111 _In_ ULONG iProperty,
112 _In_ ULONG cProperties,
113 _Out_ PROPBAG2 *pPropBag,
114 _Out_ ULONG *pcProperties) override
115 {
116 return E_NOTIMPL;
117 }
118 STDMETHODIMP LoadObject(
119 _In_z_ LPCWSTR pstrName,
120 _In_ DWORD dwHint,
121 _In_ IUnknown *pUnkObject,
122 _In_opt_ IErrorLog *pErrorLog) override
123 {
124 return E_NOTIMPL;
125 }
126#endif
127};
128
130{
131 static bool IsEqualKey(const ATL::CStringW& k1, const ATL::CStringW& k2)
132 {
133 return k1.CompareNoCase(k2) == 0;
134 }
135
137 {
138 return false;
139 }
140};
141
143{
144protected:
146
147public:
149
150 STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari,
151 _Inout_opt_ IErrorLog *pErrorLog) override;
152 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
153};
154
157 _In_z_ LPCWSTR pszPropName,
158 _Inout_ VARIANT *pvari,
159 _Inout_opt_ IErrorLog *pErrorLog)
160{
161 UNREFERENCED_PARAMETER(pErrorLog);
162
163 TRACE("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
164
165 VARTYPE vt = V_VT(pvari);
166
167 ::VariantInit(pvari);
168
170 {
172 {
173 ERR("%p: 0x%X\n", this, m_dwMode);
174 return E_ACCESSDENIED;
175 }
176 }
177
178 if (!pszPropName || !pvari)
179 {
180 ERR("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
181 return E_INVALIDARG;
182 }
183
184 INT iItem = m_PropMap.FindKey(pszPropName);
185 if (iItem == -1)
186 {
187 ERR("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
188 return E_FAIL;
189 }
190
191 HRESULT hr = ::VariantCopy(pvari, &m_PropMap.GetValueAt(iItem));
192 if (FAILED(hr))
193 {
194 ERR("%p: 0x%08X %p\n", this, hr, pvari);
195 return hr;
196 }
197
198 hr = ::VariantChangeTypeForRead(pvari, vt);
199 if (FAILED(hr))
200 {
201 ERR("%p: 0x%08X %p\n", this, hr, pvari);
202 return hr;
203 }
204
205 return hr;
206}
207
210 _In_z_ LPCWSTR pszPropName,
211 _In_ VARIANT *pvari)
212{
213 TRACE("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
214
216 {
218 {
219 ERR("%p: 0x%X\n", this, m_dwMode);
220 return E_ACCESSDENIED;
221 }
222 }
223
224 if (!pszPropName || !pvari)
225 {
226 ERR("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
227 return E_INVALIDARG;
228 }
229
230 ATL::CComVariant vari;
231 HRESULT hr = vari.Copy(pvari);
232 if (FAILED(hr))
233 {
234 ERR("%p: %s %p: 0x%08X\n", this, debugstr_w(pszPropName), pvari, hr);
235 return hr;
236 }
237
238 if (!m_PropMap.SetAt(pszPropName, vari))
239 {
240 ERR("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
241 return E_FAIL;
242 }
243
244 return hr;
245}
246
247/**************************************************************************
248 * SHCreatePropertyBagOnMemory (SHLWAPI.477)
249 *
250 * Creates a property bag object on memory.
251 *
252 * @param dwMode Specifies either STGM_READ, STGM_WRITE or STGM_READWRITE. Ignored on Vista+.
253 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
254 * Vista+ rejects IID_IPropertyBag2.
255 * @param ppvObj Receives an IPropertyBag pointer.
256 * @return An HRESULT value. S_OK on success, non-zero on failure.
257 * @see http://undoc.airesoft.co.uk/shlwapi.dll/SHCreatePropertyBagOnMemory.php
258 */
261{
262 TRACE("0x%08X, %s, %p\n", dwMode, debugstr_guid(&riid), ppvObj);
263
264 *ppvObj = NULL;
265
266 CComPtr<CMemPropertyBag> pMemBag(new(std::nothrow) CMemPropertyBag(dwMode));
267 if (!pMemBag)
268 return E_OUTOFMEMORY;
269
270 return pMemBag->QueryInterface(riid, ppvObj);
271}
272
274{
275protected:
277
278 HRESULT _ReadDword(LPCWSTR pszPropName, VARIANT *pvari);
279 HRESULT _ReadString(LPCWSTR pszPropName, VARIANTARG *pvarg, UINT len);
280 HRESULT _ReadBinary(LPCWSTR pszPropName, VARIANT *pvari, VARTYPE vt, DWORD uBytes);
282 HRESULT _CopyStreamIntoBuff(IStream *pStream, void *pv, ULONG cb);
283 HRESULT _GetStreamSize(IStream *pStream, LPDWORD pcbSize);
284 HRESULT _WriteStream(LPCWSTR pszPropName, IStream *pStream);
285
286public:
288 : CBasePropertyBag(dwMode)
289 , m_hKey(NULL)
290 {
291 }
292
294 {
295 if (m_hKey)
297 }
298
299 HRESULT Init(HKEY hKey, LPCWSTR lpSubKey);
300
301 STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari,
302 _Inout_opt_ IErrorLog *pErrorLog) override;
303 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
304};
305
307{
308 REGSAM nAccess = 0;
310 nAccess |= KEY_READ;
312 nAccess |= KEY_WRITE;
313
314 LONG error;
315 if (m_dwMode & STGM_CREATE)
316 error = ::RegCreateKeyExW(hKey, lpSubKey, 0, NULL, 0, nAccess, NULL, &m_hKey, NULL);
317 else
318 error = ::RegOpenKeyExW(hKey, lpSubKey, 0, nAccess, &m_hKey);
319
320 if (error != ERROR_SUCCESS)
321 {
322 ERR("%p %s 0x%08X\n", hKey, debugstr_w(lpSubKey), error);
324 }
325
326 return S_OK;
327}
328
330{
331 DWORD cbData = sizeof(DWORD);
332 LONG error = SHGetValueW(m_hKey, NULL, pszPropName, NULL, &V_UI4(pvari), &cbData);
333 if (error)
334 return E_FAIL;
335
336 V_VT(pvari) = VT_UI4;
337 return S_OK;
338}
339
341{
343 V_BSTR(pvarg) = bstr;
344 if (!bstr)
345 return E_OUTOFMEMORY;
346
347 V_VT(pvarg) = VT_BSTR;
348 LONG error = SHGetValueW(m_hKey, NULL, pszPropName, NULL, bstr, (LPDWORD)&len);
349 if (error)
350 {
351 ::VariantClear(pvarg);
352 return E_FAIL;
353 }
354
355 return S_OK;
356}
357
359{
361 V_UNKNOWN(pvari) = pStream;
362 if (!pStream)
363 return E_OUTOFMEMORY;
364 V_VT(pvari) = VT_UNKNOWN;
365 return S_OK;
366}
367
370 LPCWSTR pszPropName,
371 VARIANT *pvari,
372 VARTYPE vt,
373 DWORD uBytes)
374{
375 HRESULT hr = E_FAIL;
376 if (vt != VT_UNKNOWN || uBytes < sizeof(GUID))
377 return hr;
378
379 LPBYTE pbData = (LPBYTE)::LocalAlloc(LMEM_ZEROINIT, uBytes);
380 if (!pbData)
381 return hr;
382
383 if (!SHGetValueW(m_hKey, NULL, pszPropName, NULL, pbData, &uBytes) &&
384 memcmp(&GUID_NULL, pbData, sizeof(GUID)) == 0)
385 {
386 hr = _ReadStream(pvari, pbData + sizeof(GUID), uBytes - sizeof(GUID));
387 }
388
389 ::LocalFree(pbData);
390
391 return hr;
392}
393
395{
397 li.QuadPart = 0;
398 HRESULT hr = pStream->Seek(li, 0, NULL);
399 if (FAILED(hr))
400 return hr;
401 return pStream->Read(pv, cb, NULL);
402}
403
405{
406 *pcbSize = 0;
407
409 HRESULT hr = IStream_Size(pStream, &ui);
410 if (FAILED(hr))
411 return hr;
412
413 if (ui.DUMMYSTRUCTNAME.HighPart)
414 return E_FAIL; /* 64-bit value is not supported */
415
416 *pcbSize = ui.DUMMYSTRUCTNAME.LowPart;
417 return hr;
418}
419
422 _In_z_ LPCWSTR pszPropName,
423 _Inout_ VARIANT *pvari,
424 _Inout_opt_ IErrorLog *pErrorLog)
425{
426 UNREFERENCED_PARAMETER(pErrorLog);
427
428 TRACE("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
429
431 {
432 ERR("%p: 0x%X\n", this, m_dwMode);
433 ::VariantInit(pvari);
434 return E_ACCESSDENIED;
435 }
436
437 VARTYPE vt = V_VT(pvari);
438 VariantInit(pvari);
439
440 HRESULT hr;
441 DWORD dwType, cbValue;
442 LONG error = SHGetValueW(m_hKey, NULL, pszPropName, &dwType, NULL, &cbValue);
443 if (error != ERROR_SUCCESS)
444 hr = E_FAIL;
445 else if (dwType == REG_SZ)
446 hr = _ReadString(pszPropName, pvari, cbValue);
447 else if (dwType == REG_BINARY)
448 hr = _ReadBinary(pszPropName, pvari, vt, cbValue);
449 else if (dwType == REG_DWORD)
450 hr = _ReadDword(pszPropName, pvari);
451 else
452 hr = E_FAIL;
453
454 if (FAILED(hr))
455 {
456 ERR("%p: 0x%08X %ld: %s %p\n", this, hr, dwType, debugstr_w(pszPropName), pvari);
457 ::VariantInit(pvari);
458 return hr;
459 }
460
461 hr = ::VariantChangeTypeForRead(pvari, vt);
462 if (FAILED(hr))
463 {
464 ERR("%p: 0x%08X %ld: %s %p\n", this, hr, dwType, debugstr_w(pszPropName), pvari);
465 ::VariantInit(pvari);
466 }
467
468 return hr;
469}
470
473{
475 HRESULT hr = _GetStreamSize(pStream, &cbData);
476 if (FAILED(hr) || !cbData)
477 return hr;
478
479 DWORD cbBinary = cbData + sizeof(GUID);
480 LPBYTE pbBinary = (LPBYTE)::LocalAlloc(LMEM_ZEROINIT, cbBinary);
481 if (!pbBinary)
482 return E_OUTOFMEMORY;
483
484 hr = _CopyStreamIntoBuff(pStream, pbBinary + sizeof(GUID), cbData);
485 if (SUCCEEDED(hr))
486 {
487 if (SHSetValueW(m_hKey, NULL, pszPropName, REG_BINARY, pbBinary, cbBinary))
488 hr = E_FAIL;
489 }
490
491 ::LocalFree(pbBinary);
492 return hr;
493}
494
497{
498 TRACE("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
499
501 {
502 ERR("%p: 0x%X\n", this, m_dwMode);
503 return E_ACCESSDENIED;
504 }
505
506 HRESULT hr;
507 LONG error;
508 VARIANTARG vargTemp = { 0 };
509 switch (V_VT(pvari))
510 {
511 case VT_EMPTY:
512 SHDeleteValueW(m_hKey, NULL, pszPropName);
513 hr = S_OK;
514 break;
515
516 case VT_BOOL:
517 case VT_I1:
518 case VT_I2:
519 case VT_I4:
520 case VT_UI1:
521 case VT_UI2:
522 case VT_UI4:
523 case VT_INT:
524 case VT_UINT:
525 {
526 hr = ::VariantChangeType(&vargTemp, pvari, 0, VT_UI4);
527 if (FAILED(hr))
528 return hr;
529
530 error = SHSetValueW(m_hKey, NULL, pszPropName, REG_DWORD, &V_UI4(&vargTemp), sizeof(DWORD));
531 if (error)
532 hr = E_FAIL;
533
534 ::VariantClear(&vargTemp);
535 break;
536 }
537
538 case VT_UNKNOWN:
539 {
540 CComPtr<IStream> pStream;
541 hr = V_UNKNOWN(pvari)->QueryInterface(IID_IStream, (void **)&pStream);
542 if (FAILED(hr))
543 return hr;
544
545 hr = _WriteStream(pszPropName, pStream);
546 break;
547 }
548
549 default:
550 {
551 hr = ::VariantChangeType(&vargTemp, pvari, 0, VT_BSTR);
552 if (FAILED(hr))
553 return hr;
554
555 int cch = lstrlenW(V_BSTR(&vargTemp));
556 DWORD cb = (cch + 1) * sizeof(WCHAR);
557 error = SHSetValueW(m_hKey, NULL, pszPropName, REG_SZ, V_BSTR(&vargTemp), cb);
558 if (error)
559 hr = E_FAIL;
560
561 ::VariantClear(&vargTemp);
562 break;
563 }
564 }
565
566 return hr;
567}
568
569/**************************************************************************
570 * SHCreatePropertyBagOnRegKey (SHLWAPI.471)
571 *
572 * Creates a property bag object on registry key.
573 *
574 * @param hKey The registry key.
575 * @param pszSubKey The path of the sub-key.
576 * @param dwMode The combination of STGM_READ, STGM_WRITE, STGM_READWRITE, and STGM_CREATE.
577 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
578 * @param ppvObj Receives an IPropertyBag pointer.
579 * @return An HRESULT value. S_OK on success, non-zero on failure.
580 * @see https://source.winehq.org/WineAPI/SHCreatePropertyBagOnRegKey.html
581 */
584 _In_ HKEY hKey,
586 _In_ DWORD dwMode,
588 _Out_ void **ppvObj)
589{
590 TRACE("%p, %s, 0x%08X, %s, %p\n", hKey, debugstr_w(pszSubKey), dwMode,
591 debugstr_guid(&riid), ppvObj);
592
593 *ppvObj = NULL;
594
595 CComPtr<CRegPropertyBag> pRegBag(new(std::nothrow) CRegPropertyBag(dwMode));
596 if (!pRegBag)
597 return E_OUTOFMEMORY;
598
599 HRESULT hr = pRegBag->Init(hKey, pszSubKey);
600 if (FAILED(hr))
601 return hr;
602
603 return pRegBag->QueryInterface(riid, ppvObj);
604}
605
606/**************************************************************************
607 * SHGetIniStringW (SHLWAPI.294)
608 *
609 * @see https://source.winehq.org/WineAPI/SHGetIniStringW.html
610 */
614 _In_z_ LPCWSTR keyName,
615 _Out_writes_to_(outLen, return + 1) LPWSTR out,
616 _In_ DWORD outLen,
618{
619 TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName), debugstr_w(keyName),
620 out, outLen, debugstr_w(filename));
621
622 if (outLen == 0)
623 return 0;
624
625 // Try ".W"-appended section name. See also SHSetIniStringW
626 CStringW szSection(appName);
627 szSection += L".W";
628 CStringW pszWideBuff;
629 const INT cchWideMax = 4 * MAX_PATH; // UTF-7 needs 4 times length buffer.
630 GetPrivateProfileStringW(szSection, keyName, NULL,
631 pszWideBuff.GetBuffer(cchWideMax), cchWideMax, filename);
632 pszWideBuff.ReleaseBuffer();
633
634 if (pszWideBuff.IsEmpty()) // It's empty or not found
635 {
636 // Try the normal section name
637 return GetPrivateProfileStringW(appName, keyName, NULL, out, outLen, filename);
638 }
639
640 // Okay, now ".W" version is valid. Its value is a UTF-7 string in UTF-16
641 CW2A wide2utf7(pszWideBuff);
642 MultiByteToWideChar(CP_UTF7, 0, wide2utf7, -1, out, outLen);
643 out[outLen - 1] = UNICODE_NULL;
644
645 return lstrlenW(out);
646}
647
649{
650 if (!psz)
651 return TRUE;
652
653 while (*psz)
654 {
655 if (*psz > 0x7F)
656 return FALSE;
657 ++psz;
658 }
659 return TRUE;
660}
661
662/**************************************************************************
663 * SHSetIniStringW (SHLWAPI.295)
664 *
665 * @see https://source.winehq.org/WineAPI/SHSetIniStringW.html
666 */
670 _In_z_ LPCWSTR keyName,
673{
674 TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName), keyName, debugstr_w(str),
676
677 // Write a normal profile string. If str was NULL, then key will be deleted
679 return FALSE;
680
681 if (Is7BitClean(str))
682 {
683 // Delete ".A" version
684 CStringW szSection(appName);
685 szSection += L".A";
686 WritePrivateProfileStringW(szSection, keyName, NULL, filename);
687
688 // Delete ".W" version
689 szSection = appName;
690 szSection += L".W";
691 WritePrivateProfileStringW(szSection, keyName, NULL, filename);
692
693 return TRUE;
694 }
695
696 // Now str is not 7-bit clean. It needs UTF-7 encoding in UTF-16.
697 // We write ".A" and ".W"-appended sections
698 CW2A wide2utf7(str, CP_UTF7);
699 CA2W utf72wide(wide2utf7, CP_ACP);
700
701 BOOL ret = TRUE;
702
703 // Write ".A" version
704 CStringW szSection(appName);
705 szSection += L".A";
706 if (!WritePrivateProfileStringW(szSection, keyName, str, filename))
707 ret = FALSE;
708
709 // Write ".W" version
710 szSection = appName;
711 szSection += L".W";
712 if (!WritePrivateProfileStringW(szSection, keyName, utf72wide, filename))
713 ret = FALSE;
714
715 return ret;
716}
717
718/**************************************************************************
719 * SHGetIniStringUTF7W (SHLWAPI.473)
720 *
721 * Retrieves a string value from an INI file.
722 *
723 * @param lpAppName The section name.
724 * @param lpKeyName The key name.
725 * If this string begins from '@', the value will be interpreted as UTF-7.
726 * @param lpReturnedString Receives a wide string value.
727 * @param nSize The number of characters in lpReturnedString.
728 * @param lpFileName The INI file.
729 * @return The number of characters copied to the buffer if succeeded.
730 */
733 _In_opt_z_ LPCWSTR lpAppName,
734 _In_z_ LPCWSTR lpKeyName,
735 _Out_writes_to_(nSize, return + 1) _Post_z_ LPWSTR lpReturnedString,
738{
739 if (*lpKeyName == L'@') // UTF-7
740 return SHGetIniStringW(lpAppName, lpKeyName + 1, lpReturnedString, nSize, lpFileName);
741
742 return GetPrivateProfileStringW(lpAppName, lpKeyName, L"", lpReturnedString, nSize, lpFileName);
743}
744
745/**************************************************************************
746 * SHSetIniStringUTF7W (SHLWAPI.474)
747 *
748 * Sets a string value on an INI file.
749 *
750 * @param lpAppName The section name.
751 * @param lpKeyName The key name.
752 * If this begins from '@', the value will be stored as UTF-7.
753 * @param lpString The wide string value to be set.
754 * @param lpFileName The INI file.
755 * @return TRUE if successful. FALSE if failed.
756 */
759 _In_z_ LPCWSTR lpAppName,
760 _In_z_ LPCWSTR lpKeyName,
761 _In_opt_z_ LPCWSTR lpString,
763{
764 if (*lpKeyName == L'@') // UTF-7
765 return SHSetIniStringW(lpAppName, lpKeyName + 1, lpString, lpFileName);
766
767 return WritePrivateProfileStringW(lpAppName, lpKeyName, lpString, lpFileName);
768}
769
771{
772protected:
775 BOOL m_bAlternateStream; // ADS (Alternate Data Stream)
776
778 {
779 LPCWSTR pch = StrRChrW(pszStart, NULL, L'\\');
780 if (!pch)
781 pch = pszStart;
782 return StrChrW(pch, L':') != NULL;
783 }
784
785 HRESULT
787 LPCWSTR pszStart,
788 LPWSTR pszSection,
789 UINT cchSectionMax,
790 LPWSTR pszName,
791 UINT cchNameMax);
792
793public:
795 : CBasePropertyBag(dwMode)
799 {
800 }
801
803 {
806 }
807
808 HRESULT Init(LPCWSTR pszIniFile, LPCWSTR pszSection);
809
811 _In_z_ LPCWSTR pszPropName,
812 _Inout_ VARIANT *pvari,
813 _Inout_opt_ IErrorLog *pErrorLog) override;
814
815 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
816};
817
819{
820 m_pszFileName = StrDupW(pszIniFile);
821 if (!m_pszFileName)
822 return E_OUTOFMEMORY;
823
824 // Is it an ADS (Alternate Data Stream) pathname?
826
827 if (pszSection)
828 {
829 m_pszSection = StrDupW(pszSection);
830 if (!m_pszSection)
831 return E_OUTOFMEMORY;
832 }
833
834 return S_OK;
835}
836
839 LPCWSTR pszStart,
840 LPWSTR pszSection,
841 UINT cchSectionMax,
842 LPWSTR pszName,
843 UINT cchNameMax)
844{
845 LPCWSTR pchSep = StrChrW(pszStart, L'\\');
846 if (pchSep)
847 {
848 UINT cchSep = (UINT)(pchSep - pszStart + 1);
849 StrCpyNW(pszSection, pszStart, __min(cchSep, cchSectionMax));
850 StrCpyNW(pszName, pchSep + 1, cchNameMax);
851 return S_OK;
852 }
853
854 if (m_pszSection)
855 {
856 StrCpyNW(pszSection, m_pszSection, cchSectionMax);
857 StrCpyNW(pszName, pszStart, cchNameMax);
858 return S_OK;
859 }
860
861 ERR("%p: %s\n", this, debugstr_w(pszStart));
862 return E_INVALIDARG;
863}
864
867 _In_z_ LPCWSTR pszPropName,
868 _Inout_ VARIANT *pvari,
869 _Inout_opt_ IErrorLog *pErrorLog)
870{
871 UNREFERENCED_PARAMETER(pErrorLog);
872
873 TRACE("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
874
875 VARTYPE vt = V_VT(pvari);
876
877 ::VariantInit(pvari);
878
880 {
881 ERR("%p: 0x%X\n", this, m_dwMode);
882 return E_ACCESSDENIED;
883 }
884
885 WCHAR szSection[64], szName[64];
886 HRESULT hr =
887 _GetSectionAndName(pszPropName, szSection, _countof(szSection), szName, _countof(szName));
888 if (FAILED(hr))
889 return hr;
890
891 const INT cchBuffMax = 4 * MAX_PATH; // UTF-7 needs 4 times length buffer.
892 CComHeapPtr<WCHAR> pszBuff;
893 if (!pszBuff.Allocate(cchBuffMax * sizeof(WCHAR)))
894 return E_OUTOFMEMORY;
895
896 if (!SHGetIniStringUTF7W(szSection, szName, pszBuff, cchBuffMax, m_pszFileName))
897 return E_FAIL;
898
899 BSTR bstr = ::SysAllocString(pszBuff);
900 V_BSTR(pvari) = bstr;
901 if (!bstr)
902 return E_OUTOFMEMORY;
903
904 V_VT(pvari) = VT_BSTR;
905 return ::VariantChangeTypeForRead(pvari, vt);
906}
907
910{
911 TRACE("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
912
914 {
915 ERR("%p: 0x%X\n", this, m_dwMode);
916 return E_ACCESSDENIED;
917 }
918
919 HRESULT hr;
920 BSTR bstr;
921 VARIANTARG vargTemp = { 0 };
922 switch (V_VT(pvari))
923 {
924 case VT_EMPTY:
925 bstr = NULL;
926 break;
927
928 case VT_BSTR:
929 bstr = V_BSTR(pvari);
930 break;
931
932 default:
933 hr = ::VariantChangeType(&vargTemp, pvari, 0, VT_BSTR);
934 if (FAILED(hr))
935 goto Quit;
936
937 bstr = V_BSTR(&vargTemp);
938 break;
939 }
940
941 WCHAR szSection[64], szName[64];
942 hr = _GetSectionAndName(pszPropName, szSection, _countof(szSection), szName, _countof(szName));
943 if (SUCCEEDED(hr))
944 {
945 if (SHSetIniStringUTF7W(szSection, szName, bstr, m_pszFileName))
946 {
949 }
950 else
951 {
952 hr = E_FAIL;
953 }
954 }
955
956Quit:
957 ::VariantClear(&vargTemp);
958 return hr;
959}
960
961/**************************************************************************
962 * SHCreatePropertyBagOnProfileSection (SHLWAPI.472)
963 *
964 * Creates a property bag object on INI file.
965 *
966 * @param lpFileName The INI filename.
967 * @param pszSection The optional section name.
968 * @param dwMode The combination of STGM_READ, STGM_WRITE, STGM_READWRITE, and STGM_CREATE.
969 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
970 * @param ppvObj Receives an IPropertyBag pointer.
971 * @return An HRESULT value. S_OK on success, non-zero on failure.
972 * @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/propbag/createonprofilesection.htm
973 */
977 _In_opt_z_ LPCWSTR pszSection,
978 _In_ DWORD dwMode,
980 _Out_ void **ppvObj)
981{
983 PWCHAR pchFileTitle;
984 WCHAR szBuff[MAX_PATH];
985
986 if (dwMode & STGM_CREATE)
987 {
991 {
992 pchFileTitle = PathFindFileNameW(lpFileName);
993 if (lstrcmpiW(pchFileTitle, L"desktop.ini") == 0)
994 {
995 StrCpyNW(szBuff, lpFileName, _countof(szBuff));
996 if (PathRemoveFileSpecW(szBuff))
997 PathMakeSystemFolderW(szBuff);
998 }
1000 }
1001 }
1002
1003 *ppvObj = NULL;
1004
1007
1008 CComPtr<CIniPropertyBag> pIniPB(new(std::nothrow) CIniPropertyBag(dwMode));
1009 if (!pIniPB)
1010 return E_OUTOFMEMORY;
1011
1012 HRESULT hr = pIniPB->Init(lpFileName, pszSection);
1013 if (FAILED(hr))
1014 {
1015 ERR("0x%08X\n", hr);
1016 return hr;
1017 }
1018
1019 return pIniPB->QueryInterface(riid, ppvObj);
1020}
1021
1023{
1024protected:
1027 HRESULT _ReadFlags(VARIANT *pvari);
1030 IStream* _NewStreamFromOld(IStream *pOldStream);
1031
1032public:
1034
1036 _In_z_ LPCWSTR pszPropName,
1037 _Inout_ VARIANT *pvari,
1038 _Inout_opt_ IErrorLog *pErrorLog) override;
1039
1040 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
1041 {
1042 ERR("%p: %s: Read-only\n", this, debugstr_w(pszPropName));
1043 return E_NOTIMPL;
1044 }
1045};
1046
1048{
1049 DWORD dwValue = TRUE;
1050 SHSetValueW(hkey, NULL, L"Upgrade", REG_DWORD, &dwValue, sizeof(dwValue));
1051}
1052
1054{
1055 // Check the existence of the value written in _MarkAsUpgraded.
1056 DWORD dwValue, cbData = sizeof(dwValue);
1057 return SHGetValueW(hKey, NULL, L"Upgrade", NULL, &dwValue, &cbData) == ERROR_SUCCESS;
1058}
1059
1060typedef DWORDLONG DESKVIEW_FLAGS; // 64-bit data
1061
1063{
1065 DWORD cbValue = sizeof(Flags);
1067 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DeskView",
1068 L"Settings",
1069 NULL,
1070 &Flags,
1071 &cbValue) != ERROR_SUCCESS || cbValue < sizeof(Flags))
1072 {
1073 return E_FAIL;
1074 }
1075
1076 V_UINT(pvari) = ((UINT)(Flags >> 32)) | 0x220; // FIXME: Magic number
1077 V_VT(pvari) = VT_UINT;
1078 return S_OK;
1079}
1080
1082{
1087
1089{
1091 HRESULT hr = pOldStream->Read(&Header, sizeof(Header), NULL);
1092 if (FAILED(hr) || Header.wMagic != 28)
1093 return NULL;
1094
1095 // Move stream pointer
1097 li.QuadPart = Header.wSize - sizeof(Header);
1098 hr = pOldStream->Seek(li, STREAM_SEEK_CUR, NULL);
1099 if (FAILED(hr))
1100 return NULL;
1101
1102 // Get the size
1103 ULARGE_INTEGER uli;
1104 hr = IStream_Size(pOldStream, &uli);
1105 if (FAILED(hr))
1106 return NULL;
1107
1108 // Create new stream and attach
1109 CComPtr<IStream> pNewStream;
1110 pNewStream.Attach(SHCreateMemStream(NULL, 0));
1111 if (!pNewStream)
1112 return NULL;
1113
1114 // Subtract Header.wSize from the size
1115 uli.QuadPart -= Header.wSize;
1116
1117 // Copy to pNewStream
1118 hr = pOldStream->CopyTo(pNewStream, uli, NULL, NULL);
1119 if (FAILED(hr))
1120 return NULL;
1121
1122 li.QuadPart = 0;
1123 pNewStream->Seek(li, STREAM_SEEK_SET, NULL);
1124
1125 return pNewStream.Detach();
1126}
1127
1129{
1130 HKEY hKey = SHGetShellKey(SHKEY_Root_HKCU, L"Streams\\Desktop", FALSE);
1131 if (!hKey)
1132 return NULL;
1133
1134 CComPtr<IStream> pOldStream;
1135 if (!_AlreadyUpgraded(hKey))
1136 {
1137 pOldStream.Attach(SHOpenRegStream2W(hKey, NULL, L"ViewView2", 0));
1138 if (pOldStream)
1139 {
1140 ULARGE_INTEGER uli;
1141 HRESULT hr = IStream_Size(pOldStream, &uli);
1142 if (SUCCEEDED(hr) && !uli.QuadPart)
1143 pOldStream.Release();
1144 }
1145
1146 if (!pOldStream)
1147 pOldStream.Attach(SHOpenRegStream2W(hKey, NULL, L"ViewView", 0));
1148
1150 }
1151
1153 return pOldStream.Detach();
1154}
1155
1157{
1158 CComPtr<IStream> pOldStream;
1159 pOldStream.Attach(_GetOldDesktopViewStream());
1160 if (!pOldStream)
1161 return E_FAIL;
1162
1163 HRESULT hr = E_FAIL;
1164 IStream *pNewStream = _NewStreamFromOld(pOldStream);
1165 if (pNewStream)
1166 {
1167 V_UNKNOWN(pvari) = pNewStream;
1168 V_VT(pvari) = VT_UNKNOWN;
1169 hr = S_OK;
1170 }
1171
1172 return hr;
1173}
1174
1177 _In_z_ LPCWSTR pszPropName,
1178 _Inout_ VARIANT *pvari,
1179 _Inout_opt_ IErrorLog *pErrorLog)
1180{
1181 UNREFERENCED_PARAMETER(pErrorLog);
1182
1183 VARTYPE vt = V_VT(pvari);
1184
1185 HRESULT hr = E_FAIL;
1186 if (StrCmpW(L"FFlags", pszPropName) == 0)
1187 hr = _ReadFlags(pvari);
1188 else if (StrCmpNW(L"ItemPos", pszPropName, 7) == 0)
1189 hr = _ReadItemPositions(pvari);
1190
1191 if (FAILED(hr))
1192 {
1193 ::VariantInit(pvari);
1194 return hr;
1195 }
1196
1197 return ::VariantChangeType(pvari, pvari, 0, vt);
1198}
1199
1200/**************************************************************************
1201 * SHGetDesktopUpgradePropertyBag (Internal)
1202 *
1203 * Creates or gets a property bag object for desktop upgrade
1204 *
1205 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
1206 * @param ppvObj Receives an IPropertyBag pointer.
1207 * @return An HRESULT value. S_OK on success, non-zero on failure.
1208 */
1210{
1211 *ppvObj = NULL;
1213 if (!pPropBag)
1214 return E_OUTOFMEMORY;
1215 return pPropBag->QueryInterface(riid, ppvObj);
1216}
1217
1219{
1220protected:
1223 DWORD m_dwVspbFlags = 0; // SHGVSPB_... flags
1240
1241 BOOL _IsSamePidl(LPCITEMIDLIST pidlOther) const;
1242 BOOL _IsSystemFolder() const;
1243 BOOL _CanAccessPidlBag() const;
1247 BOOL _CanAccessInheritBag() const;
1248 BOOL _CanAccessUpgradeBag() const;
1249
1250 HKEY _GetHKey(DWORD dwVspbFlags);
1251
1253
1255 LPCITEMIDLIST pidl,
1256 DWORD dwMode,
1257 HKEY hKey,
1258 UINT *puSlots,
1259 UINT cSlots,
1260 UINT *pcSlots);
1261
1262 HRESULT _GetMRUSlot(LPCITEMIDLIST pidl, DWORD dwMode, HKEY hKey, UINT *pSlot);
1263
1265 LPCITEMIDLIST pidl,
1266 LPCWSTR pszBagName,
1267 DWORD dwFlags,
1268 DWORD dwMode,
1269 HKEY hKey,
1270 LPWSTR pszDest,
1271 INT cchDest);
1272
1274 LPITEMIDLIST pidl,
1275 LPCWSTR pszPath,
1276 DWORD dwVspbFlags,
1277 DWORD dwMode,
1278 REFIID riid,
1279 IPropertyBag **pppb);
1280
1282
1283 void _ResetTryAgainFlag();
1284
1293 HRESULT _ReadPidlBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1294 HRESULT _ReadInheritBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1295 HRESULT _ReadUpgradeBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1296 HRESULT _ReadUserDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1297 HRESULT _ReadFolderDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1298 HRESULT _ReadGlobalDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1299 void _PruneMRUTree();
1300
1301public:
1303
1305 {
1308 }
1309
1310 HRESULT Init(_In_opt_ LPCITEMIDLIST pidl, _In_opt_ LPCWSTR pszPath, _In_ DWORD dwVspbFlags);
1311 BOOL IsSameBag(LPCITEMIDLIST pidl, LPCWSTR pszPath, DWORD dwVspbFlags) const;
1312
1314 _In_z_ LPCWSTR pszPropName,
1315 _Inout_ VARIANT *pvari,
1316 _Inout_opt_ IErrorLog *pErrorLog) override;
1317
1318 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
1319};
1320
1321// CViewStatePropertyBag is cached
1323extern "C"
1324{
1326}
1327
1328HRESULT
1331 _In_opt_ LPCWSTR pszPath,
1332 _In_ DWORD dwVspbFlags)
1333{
1334 if (pidl)
1335 {
1336 m_pidl = ILClone(pidl);
1337 if (!m_pidl)
1338 return E_OUTOFMEMORY;
1339 }
1340
1341 if (pszPath)
1342 {
1343 m_pszPath = StrDupW(pszPath);
1344 if (!m_pszPath)
1345 return E_OUTOFMEMORY;
1346
1347 m_dwVspbFlags = dwVspbFlags;
1348 }
1349
1350 return S_OK;
1351}
1352
1354{
1355 if (!pidlOther && !m_pidl)
1356 return TRUE;
1357
1358 return (pidlOther && m_pidl && ILIsEqual(pidlOther, m_pidl));
1359}
1360
1362{
1363 return (dwVspbFlags == m_dwVspbFlags && StrCmpW(pszPath, m_pszPath) == 0 && _IsSamePidl(pidl));
1364}
1365
1367{
1368 LPCITEMIDLIST ppidlLast;
1370
1371 HRESULT hr = SHBindToParent(m_pidl, IID_IShellFolder, (void **)&psf, &ppidlLast);
1372 if (FAILED(hr))
1373 return FALSE;
1374
1375 WIN32_FIND_DATAW FindData;
1376 hr = SHGetDataFromIDListW(psf, ppidlLast, SHGDFIL_FINDDATA, &FindData, sizeof(FindData));
1377 if (FAILED(hr))
1378 return FALSE;
1379
1380 return PathIsSystemFolderW(NULL, FindData.dwFileAttributes);
1381}
1382
1384{
1386}
1387
1389{
1390 if (_CanAccessPidlBag())
1391 return TRUE;
1392
1394}
1395
1397{
1399 return TRUE;
1400
1402}
1403
1405{
1407 return TRUE;
1408
1410}
1411
1413{
1415}
1416
1418{
1419 return StrCmpW(m_pszPath, L"Desktop") == 0;
1420}
1421
1423{
1425 m_bReadBag = FALSE;
1427 m_bPidlBag = FALSE;
1428 else if (m_dwVspbFlags & SHGVSPB_INHERIT)
1436}
1437
1439{
1440 if (!(dwVspbFlags & (SHGVSPB_INHERIT | SHGVSPB_PERUSER)))
1442
1443 if ((m_dwVspbFlags & SHGVSPB_ROAM) && (dwVspbFlags & SHGVSPB_PERFOLDER))
1445
1447}
1448
1450{
1451 DWORD dwValue, cbValue = sizeof(dwValue);
1452
1453 if (SHGetValueW(hKey, NULL, L"BagMRU Size", NULL, &dwValue, &cbValue) != ERROR_SUCCESS)
1454 return 400; // The default size of the MRU (most recently used) list
1455
1456 return (UINT)dwValue;
1457}
1458
1459HRESULT
1461 LPCITEMIDLIST pidl,
1462 DWORD dwMode,
1463 HKEY hKey,
1464 UINT *puSlots,
1465 UINT cSlots,
1466 UINT *pcSlots)
1467{
1468 CComPtr<IMruPidlList> pMruList;
1469 HRESULT hr = ::CoCreateInstance(CLSID_MruPidlList, NULL, CLSCTX_INPROC_SERVER,
1470 IID_IMruPidlList, (void**)&pMruList);
1471 if (FAILED(hr))
1472 return hr;
1473
1474 UINT cMRUSize = _GetMRUSize(hKey);
1475 hr = pMruList->InitList(cMRUSize, hKey, L"BagMRU");
1476 if (FAILED(hr))
1477 return hr;
1478
1479 hr = pMruList->QueryPidl(pidl, cSlots, puSlots, pcSlots);
1480 if (hr == S_OK || MODE_CAN_WRITE(dwMode)) // FIXME: HACK! (Without this, a new pidl can never be saved)
1481 hr = pMruList->UsePidl(pidl, puSlots);
1482 else if (cSlots == 1)
1483 hr = E_FAIL;
1484
1485 return hr;
1486}
1487
1488HRESULT
1490{
1491 UINT cSlots;
1492 return _GetMRUSlots(pidl, dwMode, hKey, pSlot, 1, &cSlots);
1493}
1494
1495HRESULT
1497 LPCITEMIDLIST pidl,
1498 LPCWSTR pszBagName,
1499 DWORD dwFlags,
1500 DWORD dwMode,
1501 HKEY hKey,
1502 LPWSTR pszDest,
1503 INT cchDest)
1504{
1505 HRESULT hr = S_OK;
1506 UINT nSlot;
1507
1509 {
1510 hr = _GetMRUSlot(pidl, dwMode, hKey, &nSlot);
1511 if (SUCCEEDED(hr))
1512 {
1514 StringCchPrintfW(pszDest, cchDest, L"Bags\\%d\\%s\\Inherit", nSlot, pszBagName);
1515 else
1516 StringCchPrintfW(pszDest, cchDest, L"Bags\\%d\\%s", nSlot, pszBagName);
1517 }
1518 }
1519 else
1520 {
1521 StringCchPrintfW(pszDest, cchDest, L"Bags\\AllFolders\\%s", pszBagName);
1522 }
1523
1524 return hr;
1525}
1526
1528{
1529 HRESULT hr = ::CreateBindCtx(0, ppbc);
1530 if (FAILED(hr))
1531 return hr;
1532
1533 IBindCtx *pbc = *ppbc;
1534
1535 BIND_OPTS opts = { sizeof(opts) };
1536 opts.grfMode = dwMode;
1537 hr = pbc->SetBindOptions(&opts);
1538 if (FAILED(hr))
1539 {
1540 pbc->Release();
1541 *ppbc = NULL;
1542 }
1543
1544 return hr;
1545}
1546
1547HRESULT
1549 LPITEMIDLIST pidl,
1550 LPCWSTR pszPath,
1551 DWORD dwVspbFlags,
1552 DWORD dwMode,
1553 REFIID riid,
1554 IPropertyBag **pppb)
1555{
1556 HRESULT hr;
1557 HKEY hKey;
1560 WCHAR szBuff[64];
1561
1562 if (MODE_CAN_WRITE(dwMode))
1563 dwMode |= STGM_CREATE;
1564
1565 if ((dwVspbFlags & SHGVSPB_ALLUSERS) && (dwVspbFlags & SHGVSPB_PERFOLDER))
1566 {
1567 hr = BindCtx_CreateWithMode(dwMode, &pBC);
1568 if (SUCCEEDED(hr))
1569 {
1570 hr = SHGetDesktopFolder(&psf);
1571 if (SUCCEEDED(hr))
1572 {
1573 hr = psf->BindToObject(m_pidl, pBC, riid, (void **)pppb);
1574 if (SUCCEEDED(hr) && !*pppb)
1575 hr = E_FAIL;
1576 }
1577 }
1578 }
1579 else
1580 {
1581 hKey = _GetHKey(dwVspbFlags);
1582 if (!hKey)
1583 return E_FAIL;
1584
1585 hr = _GetRegKey(pidl, pszPath, dwVspbFlags, dwMode, hKey, szBuff, _countof(szBuff));
1586 if (SUCCEEDED(hr))
1587 hr = SHCreatePropertyBagOnRegKey(hKey, szBuff, dwMode, riid, (void**)pppb);
1588
1590 }
1591
1592 return hr;
1593}
1594
1595HRESULT
1597{
1598 *pppb = NULL;
1599
1601 if (!hKey)
1602 return E_FAIL;
1603
1604 UINT cSlots, anSlots[64];
1605 if (FAILED(_GetMRUSlots(m_pidl, 0, hKey, anSlots, _countof(anSlots), &cSlots)) || !cSlots)
1606 {
1608 return E_FAIL;
1609 }
1610
1611 HRESULT hr = E_FAIL;
1612 WCHAR szBuff[64];
1613 for (UINT iSlot = 0; iSlot < cSlots; ++iSlot)
1614 {
1615 StringCchPrintfW(szBuff, _countof(szBuff), L"Bags\\%d\\%s\\Inherit", anSlots[iSlot],
1616 m_pszPath);
1617 hr = SHCreatePropertyBagOnRegKey(hKey, szBuff, STGM_READ, riid, (void**)pppb);
1618 if (SUCCEEDED(hr))
1619 break;
1620 }
1621
1623 return hr;
1624}
1625
1627{
1628 if (!m_pReadBag && !m_bReadBag)
1629 {
1630 m_bReadBag = TRUE;
1632 }
1633 return (m_pReadBag != NULL);
1634}
1635
1637{
1639 {
1640 m_bPidlBag = TRUE;
1642 }
1643 return (m_pPidlBag != NULL);
1644}
1645
1647{
1649 {
1652 }
1653 return (m_pInheritBag != NULL);
1654}
1655
1657{
1659 {
1662 }
1663 return (m_pUpgradeBag != NULL);
1664}
1665
1667{
1669 {
1672 }
1673 return (m_pUserDefaultsBag != NULL);
1674}
1675
1677{
1679 {
1681 if (_IsSystemFolder())
1682 {
1684 dwMode, riid, &m_pFolderDefaultsBag);
1685 }
1686 }
1687 return (m_pFolderDefaultsBag != NULL);
1688}
1689
1691{
1693 {
1696 }
1697 return (m_pGlobalDefaultsBag != NULL);
1698}
1699
1700HRESULT
1702 LPCWSTR pszPropName,
1703 VARIANT *pvari,
1704 IErrorLog *pErrorLog)
1705{
1707 return E_FAIL;
1708
1709 return m_pPidlBag->Read(pszPropName, pvari, pErrorLog);
1710}
1711
1712HRESULT
1714 LPCWSTR pszPropName,
1715 VARIANT *pvari,
1716 IErrorLog *pErrorLog)
1717{
1719 return E_FAIL;
1720
1721 return m_pInheritBag->Read(pszPropName, pvari, pErrorLog);
1722}
1723
1724HRESULT
1726 LPCWSTR pszPropName,
1727 VARIANT *pvari,
1728 IErrorLog *pErrorLog)
1729{
1731 return E_FAIL;
1732
1733 return m_pUpgradeBag->Read(pszPropName, pvari, pErrorLog);
1734}
1735
1736HRESULT
1738 LPCWSTR pszPropName,
1739 VARIANT *pvari,
1740 IErrorLog *pErrorLog)
1741{
1743 return E_FAIL;
1744
1745 return m_pUserDefaultsBag->Read(pszPropName, pvari, pErrorLog);
1746}
1747
1748HRESULT
1750 LPCWSTR pszPropName,
1751 VARIANT *pvari,
1752 IErrorLog *pErrorLog)
1753{
1755 return E_FAIL;
1756
1757 return m_pFolderDefaultsBag->Read(pszPropName, pvari, pErrorLog);
1758}
1759
1760HRESULT
1762 LPCWSTR pszPropName,
1763 VARIANT *pvari,
1764 IErrorLog *pErrorLog)
1765{
1767 return E_FAIL;
1768
1769 return m_pGlobalDefaultsBag->Read(pszPropName, pvari, pErrorLog);
1770}
1771
1774 _In_z_ LPCWSTR pszPropName,
1775 _Inout_ VARIANT *pvari,
1776 _Inout_opt_ IErrorLog *pErrorLog)
1777{
1779 {
1781 return E_FAIL;
1782
1783 return m_pReadBag->Read(pszPropName, pvari, pErrorLog);
1784 }
1785
1786 HRESULT hr = _ReadPidlBag(pszPropName, pvari, pErrorLog);
1787 if (SUCCEEDED(hr))
1788 return hr;
1789
1790 hr = _ReadInheritBag(pszPropName, pvari, pErrorLog);
1791 if (SUCCEEDED(hr))
1792 return hr;
1793
1794 hr = _ReadUpgradeBag(pszPropName, pvari, pErrorLog);
1795 if (SUCCEEDED(hr))
1796 return hr;
1797
1798 hr = _ReadUserDefaultsBag(pszPropName, pvari, pErrorLog);
1799 if (SUCCEEDED(hr))
1800 return hr;
1801
1802 hr = _ReadFolderDefaultsBag(pszPropName, pvari, pErrorLog);
1803 if (SUCCEEDED(hr))
1804 return hr;
1805
1806 return _ReadGlobalDefaultsBag(pszPropName, pvari, pErrorLog);
1807}
1808
1810{
1812 if (!hKey)
1813 return;
1814
1815 CComPtr<IMruPidlList> pMruList;
1816 HRESULT hr = ::CoCreateInstance(CLSID_MruPidlList, NULL, CLSCTX_INPROC_SERVER,
1817 IID_IMruPidlList, (void**)&pMruList);
1818 if (SUCCEEDED(hr))
1819 {
1820 hr = pMruList->InitList(200, hKey, L"BagMRU");
1821 if (SUCCEEDED(hr))
1822 pMruList->PruneKids(m_pidl);
1823 }
1824
1826}
1827
1829{
1830 if (!m_pWriteBag && !m_bWriteBag)
1831 {
1832 m_bWriteBag = TRUE;
1834 if (m_pWriteBag)
1835 {
1838 _PruneMRUTree();
1839 }
1840 }
1841 return (m_pWriteBag != NULL);
1842}
1843
1845{
1847 return E_FAIL;
1848
1849 return m_pWriteBag->Write(pszPropName, pvari);
1850}
1851
1853{
1854 STRRET strret;
1856 WCHAR szBuff[MAX_PATH];
1857 LPCITEMIDLIST ppidlLast;
1858 INT iDrive, nType;
1859 HRESULT hr;
1860
1861 hr = SHBindToParent(pidl, IID_IShellFolder, (void **)&psf, &ppidlLast);
1862 if (FAILED(hr))
1863 return FALSE;
1864
1865 hr = psf->GetDisplayNameOf(ppidlLast, SHGDN_FORPARSING, &strret);
1866 if (FAILED(hr))
1867 return FALSE;
1868
1869 hr = StrRetToBufW(&strret, ppidlLast, szBuff, _countof(szBuff));
1870 if (FAILED(hr))
1871 return FALSE;
1872
1873 iDrive = PathGetDriveNumberW(szBuff);
1874 if (iDrive < 0)
1875 return FALSE;
1876
1877 nType = RealDriveType(iDrive, FALSE);
1878 return (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM);
1879}
1880
1881/**************************************************************************
1882 * SHGetViewStatePropertyBag (SHLWAPI.515)
1883 *
1884 * Retrieves a property bag in which the view state information of a folder
1885 * can be stored.
1886 *
1887 * @param pidl PIDL of the folder requested
1888 * @param bag_name Name of the property bag requested
1889 * @param flags Optional SHGVSPB_... flags
1890 * @param riid IID of requested property bag interface
1891 * @param ppv Address to receive pointer to the new interface
1892 * @return An HRESULT value. S_OK on success, non-zero on failure.
1893 * @see https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shgetviewstatepropertybag
1894 */
1898 _In_opt_ LPCWSTR bag_name,
1901 _Outptr_ void **ppv)
1902{
1903 HRESULT hr;
1904
1905 TRACE("%p %s 0x%X %p %p\n", pidl, debugstr_w(bag_name), flags, &riid, ppv);
1906
1907 *ppv = NULL;
1908
1910
1911 if (g_pCachedBag && g_pCachedBag->IsSameBag(pidl, bag_name, flags))
1912 {
1913 hr = g_pCachedBag->QueryInterface(riid, ppv);
1915 return hr;
1916 }
1917
1918 if (SHIsRemovableDrive(pidl))
1919 {
1920 TRACE("pidl %p is removable\n", pidl);
1922 return E_FAIL;
1923 }
1924
1925 CComPtr<CViewStatePropertyBag> pBag(new(std::nothrow) CViewStatePropertyBag());
1926 if (!pBag)
1927 {
1929 return E_OUTOFMEMORY;
1930 }
1931
1932 hr = pBag->Init(pidl, bag_name, flags);
1933 if (FAILED(hr))
1934 {
1935 ERR("0x%08X\n", hr);
1937 return hr;
1938 }
1939 g_pCachedBag = pBag;
1941 return pBag->QueryInterface(riid, ppv);
1942}
1943
1945{
1947 g_pCachedBag.Release();
1949}
1950
1951/**************************************************************************
1952 * SHGetPerScreenResName (SHLWAPI.533)
1953 *
1954 * @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/propbag/getperscreenresname.htm
1955 */
1958 _Out_writes_(cchBuffer) LPWSTR pszBuffer,
1961{
1962 if (dwReserved)
1963 return 0;
1964
1965 HDC hDC = ::GetDC(NULL);
1966 INT cxWidth = ::GetDeviceCaps(hDC, HORZRES);
1967 INT cyHeight = ::GetDeviceCaps(hDC, VERTRES);
1968 INT cMonitors = ::GetSystemMetrics(SM_CMONITORS);
1970
1971 StringCchPrintfW(pszBuffer, cchBuffer, L"%dx%d(%d)", cxWidth, cyHeight, cMonitors);
1972 return lstrlenW(pszBuffer);
1973}
1974
1975/**************************************************************************
1976 * IUnknown_QueryServicePropertyBag (SHLWAPI.536)
1977 *
1978 * @param punk An IUnknown interface.
1979 * @param flags The SHGVSPB_... flags of SHGetViewStatePropertyBag.
1980 * @param riid IID of requested property bag interface.
1981 * @param ppvObj Address to receive pointer to the new interface.
1982 * @return An HRESULT value. S_OK on success, non-zero on failure.
1983 * @see https://geoffchappell.com/studies/windows/shell/shlwapi/api/util/iunknown/queryservicepropertybag.htm
1984 */
1988 _In_ long flags,
1990 _Outptr_ void **ppvObj)
1991{
1992 TRACE("%p 0x%x %p %p\n", punk, flags, &riid, ppvObj);
1993
1995 HRESULT hr = IUnknown_QueryService(punk, SID_STopLevelBrowser, IID_IShellBrowserService,
1996 (void **)&pService);
1997 if (FAILED(hr))
1998 {
1999 ERR("0x%X\n", hr);
2000 return hr;
2001 }
2002
2003 return pService->GetPropertyBag(flags, riid, ppvObj);
2004}
static HDC hDC
Definition: 3dtext.c:33
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define ERR(fmt,...)
Definition: precomp.h:57
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
void Release()
Definition: atlcomcli.h:170
void Attach(T *lp)
Definition: atlcomcli.h:179
T * Detach()
Definition: atlcomcli.h:186
HRESULT Copy(_In_ const VARIANT *src)
Definition: atlcomcli.h:584
bool IsEmpty() const noexcept
Definition: atlsimpstr.h:394
void ReleaseBuffer(_In_ int nNewLength=-1)
Definition: atlsimpstr.h:387
int CompareNoCase(_In_z_ PCXSTR psz) const
Definition: cstringt.h:743
virtual ~CBasePropertyBag()
Definition: propbag.cpp:46
CBasePropertyBag(DWORD dwMode)
Definition: propbag.cpp:40
STDMETHODIMP_(ULONG) AddRef() override
Definition: propbag.cpp:74
STDMETHODIMP_(ULONG) Release() override
Definition: propbag.cpp:78
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
Definition: propbag.cpp:49
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:1040
HRESULT _ReadFlags(VARIANT *pvari)
Definition: propbag.cpp:1062
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:1176
IStream * _GetOldDesktopViewStream()
Definition: propbag.cpp:1128
VOID _MarkAsUpgraded(HKEY hkey)
Definition: propbag.cpp:1047
IStream * _NewStreamFromOld(IStream *pOldStream)
Definition: propbag.cpp:1088
HRESULT _ReadItemPositions(VARIANT *pvari)
Definition: propbag.cpp:1156
BOOL _AlreadyUpgraded(HKEY hKey)
Definition: propbag.cpp:1053
bool Allocate(_In_ size_t nElements=1)
Definition: atlalloc.h:143
LPWSTR m_pszFileName
Definition: propbag.cpp:773
static BOOL LooksLikeAnAlternateStream(LPCWSTR pszStart)
Definition: propbag.cpp:777
LPWSTR m_pszSection
Definition: propbag.cpp:774
BOOL m_bAlternateStream
Definition: propbag.cpp:775
HRESULT Init(LPCWSTR pszIniFile, LPCWSTR pszSection)
Definition: propbag.cpp:818
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:866
CIniPropertyBag(DWORD dwMode)
Definition: propbag.cpp:794
HRESULT _GetSectionAndName(LPCWSTR pszStart, LPWSTR pszSection, UINT cchSectionMax, LPWSTR pszName, UINT cchNameMax)
Definition: propbag.cpp:838
~CIniPropertyBag() override
Definition: propbag.cpp:802
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:909
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:156
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:209
ATL::CSimpleMap< ATL::CStringW, ATL::CComVariant, CPropMapEqual > m_PropMap
Definition: propbag.cpp:145
CMemPropertyBag(DWORD dwMode)
Definition: propbag.cpp:148
HRESULT _ReadDword(LPCWSTR pszPropName, VARIANT *pvari)
Definition: propbag.cpp:329
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:496
CRegPropertyBag(DWORD dwMode)
Definition: propbag.cpp:287
HRESULT _ReadBinary(LPCWSTR pszPropName, VARIANT *pvari, VARTYPE vt, DWORD uBytes)
Definition: propbag.cpp:369
HRESULT _ReadStream(VARIANT *pvari, BYTE *pInit, UINT cbInit)
Definition: propbag.cpp:358
HRESULT Init(HKEY hKey, LPCWSTR lpSubKey)
Definition: propbag.cpp:306
HRESULT _ReadString(LPCWSTR pszPropName, VARIANTARG *pvarg, UINT len)
Definition: propbag.cpp:340
HRESULT _CopyStreamIntoBuff(IStream *pStream, void *pv, ULONG cb)
Definition: propbag.cpp:394
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:421
HRESULT _GetStreamSize(IStream *pStream, LPDWORD pcbSize)
Definition: propbag.cpp:404
~CRegPropertyBag() override
Definition: propbag.cpp:293
HRESULT _WriteStream(LPCWSTR pszPropName, IStream *pStream)
Definition: propbag.cpp:472
HRESULT _ReadGlobalDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1761
BOOL _EnsureGlobalDefaultsBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1690
BOOL _CanAccessGlobalDefaultsBag() const
Definition: propbag.cpp:1404
HRESULT _GetMRUSlot(LPCITEMIDLIST pidl, DWORD dwMode, HKEY hKey, UINT *pSlot)
Definition: propbag.cpp:1489
BOOL _EnsureUserDefaultsBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1666
BOOL _CanAccessInheritBag() const
Definition: propbag.cpp:1412
HRESULT _ReadInheritBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1713
BOOL _EnsureInheritBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1646
BOOL _CanAccessFolderDefaultsBag() const
Definition: propbag.cpp:1396
BOOL _CanAccessUpgradeBag() const
Definition: propbag.cpp:1417
BOOL _EnsureReadBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1626
CComPtr< IPropertyBag > m_pWriteBag
Definition: propbag.cpp:1231
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:1844
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:1773
LPITEMIDLIST m_pidl
Definition: propbag.cpp:1221
BOOL _CanAccessUserDefaultsBag() const
Definition: propbag.cpp:1388
CComPtr< IPropertyBag > m_pUpgradeBag
Definition: propbag.cpp:1225
BOOL _CanAccessPidlBag() const
Definition: propbag.cpp:1383
HRESULT _FindNearestInheritBag(REFIID riid, IPropertyBag **pppb)
Definition: propbag.cpp:1596
HRESULT _ReadPidlBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1701
CComPtr< IPropertyBag > m_pInheritBag
Definition: propbag.cpp:1226
HRESULT _GetRegKey(LPCITEMIDLIST pidl, LPCWSTR pszBagName, DWORD dwFlags, DWORD dwMode, HKEY hKey, LPWSTR pszDest, INT cchDest)
Definition: propbag.cpp:1496
HRESULT _ReadFolderDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1749
CComPtr< IPropertyBag > m_pFolderDefaultsBag
Definition: propbag.cpp:1228
CComPtr< IPropertyBag > m_pReadBag
Definition: propbag.cpp:1230
~CViewStatePropertyBag() override
Definition: propbag.cpp:1304
HKEY _GetHKey(DWORD dwVspbFlags)
Definition: propbag.cpp:1438
HRESULT _GetMRUSlots(LPCITEMIDLIST pidl, DWORD dwMode, HKEY hKey, UINT *puSlots, UINT cSlots, UINT *pcSlots)
Definition: propbag.cpp:1460
BOOL _EnsurePidlBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1636
CComPtr< IPropertyBag > m_pPidlBag
Definition: propbag.cpp:1224
CComPtr< IPropertyBag > m_pGlobalDefaultsBag
Definition: propbag.cpp:1229
BOOL IsSameBag(LPCITEMIDLIST pidl, LPCWSTR pszPath, DWORD dwVspbFlags) const
Definition: propbag.cpp:1361
BOOL _EnsureFolderDefaultsBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1676
BOOL _EnsureWriteBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1828
BOOL _IsSamePidl(LPCITEMIDLIST pidlOther) const
Definition: propbag.cpp:1353
UINT _GetMRUSize(HKEY hKey)
Definition: propbag.cpp:1449
CComPtr< IPropertyBag > m_pUserDefaultsBag
Definition: propbag.cpp:1227
BOOL _IsSystemFolder() const
Definition: propbag.cpp:1366
BOOL _EnsureUpgradeBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1656
HRESULT _CreateBag(LPITEMIDLIST pidl, LPCWSTR pszPath, DWORD dwVspbFlags, DWORD dwMode, REFIID riid, IPropertyBag **pppb)
Definition: propbag.cpp:1548
HRESULT _ReadUpgradeBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1725
HRESULT Init(_In_opt_ LPCITEMIDLIST pidl, _In_opt_ LPCWSTR pszPath, _In_ DWORD dwVspbFlags)
Definition: propbag.cpp:1329
HRESULT _ReadUserDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1737
Definition: Header.h:9
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#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
LONG WINAPI RegCreateKeyExW(_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)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:552
INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:500
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
OLECHAR * BSTR
Definition: compat.h:2293
#define MAX_PATH
Definition: compat.h:34
unsigned short VARTYPE
Definition: compat.h:2254
#define CreateFileW
Definition: compat.h:741
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_BSTR
Definition: compat.h:2303
@ VT_INT
Definition: compat.h:2316
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_UI2
Definition: compat.h:2312
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_UINT
Definition: compat.h:2317
@ VT_EMPTY
Definition: compat.h:2295
@ VT_UI1
Definition: compat.h:2311
#define lstrlenW
Definition: compat.h:750
static DWORD cchBuffer
Definition: fusion.c:85
BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR string, LPCWSTR filename)
Definition: profile.c:1453
INT WINAPI GetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len, LPCWSTR filename)
Definition: profile.c:1142
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:1786
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1677
BOOL WINAPI PathRemoveFileSpecW(WCHAR *path)
Definition: path.c:1121
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2583
int WINAPI StrCmpW(const WCHAR *str, const WCHAR *comp)
Definition: string.c:458
WCHAR *WINAPI StrDupW(const WCHAR *str)
Definition: string.c:317
WCHAR *WINAPI StrCpyNW(WCHAR *dst, const WCHAR *src, int count)
Definition: string.c:470
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define __min(a, b)
Definition: stdlib.h:66
HRESULT WINAPI IUnknown_QueryService(IUnknown *obj, REFGUID sid, REFIID iid, void **out)
Definition: main.c:181
HRESULT WINAPI IStream_Size(IStream *stream, ULARGE_INTEGER *size)
Definition: main.c:120
DWORD WINAPI SHGetValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value, DWORD *type, void *data, DWORD *data_len)
Definition: main.c:2222
DWORD WINAPI SHSetValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value, DWORD type, const void *data, DWORD data_len)
Definition: main.c:2292
IStream *WINAPI SHCreateMemStream(const BYTE *data, UINT data_len)
Definition: main.c:873
DWORD WINAPI SHDeleteValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value)
Definition: main.c:1906
IStream *WINAPI SHOpenRegStream2W(HKEY hKey, const WCHAR *subkey, const WCHAR *value, DWORD mode)
Definition: main.c:1266
HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create)
Definition: ordinal.c:4049
BOOL WINAPI PathMakeSystemFolderW(LPCWSTR lpszPath)
Definition: path.c:1150
BOOL WINAPI PathIsSystemFolderW(LPCWSTR lpszPath, DWORD dwAttrib)
Definition: path.c:852
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:248
EXTERN_C ULONG WINAPI GetProcessOsVersion(void)
Definition: utils.cpp:1257
return ret
Definition: mutex.c:146
#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
PWDFDEVICE_INIT pInit
FxAutoRegKey hKey
LARGE_INTEGER li
Definition: fxtimerapi.cpp:235
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
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 SetBindOptions([in] BIND_OPTS *pbindopts)
HRESULT Write([in] LPCOLESTR pszPropName, [in] VARIANT *pVar)
HRESULT Read([out, size_is(cb), length_is(*pcbRead)] void *pv, [in] ULONG cb, [out] ULONG *pcbRead)
HRESULT CopyTo([in, unique] IStream *pstm, [in] ULARGE_INTEGER cb, [out] ULARGE_INTEGER *pcbRead, [out] ULARGE_INTEGER *pcbWritten)
HRESULT Seek([in] LARGE_INTEGER dlibMove, [in] DWORD dwOrigin, [out] ULARGE_INTEGER *plibNewPosition)
ULONG AddRef()
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
unsigned long long DWORDLONG
Definition: intsafe.h:93
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
#define REG_SZ
Definition: layer.c:22
const char * appName(const char *argv0)
Definition: loadlib.c:89
#define LMEM_ZEROINIT
Definition: minwinbase.h:85
#define error(str)
Definition: mkdosfs.c:1605
#define pch(ap)
Definition: match.c:418
#define CREATE_NEW
Definition: disk.h:69
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HDC
Definition: imagelist.c:88
@ SHKEY_Root_HKLM
Definition: ordinal.c:2806
@ SHKEY_Key_ShellNoRoam
Definition: ordinal.c:2809
@ SHKEY_Root_HKCU
Definition: ordinal.c:2805
@ SHKEY_Key_Shell
Definition: ordinal.c:2808
_In_ HANDLE hFile
Definition: mswsock.h:90
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
unsigned int UINT
Definition: ndis.h:50
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _Inout_
Definition: no_sal2.h:162
#define _In_z_
Definition: no_sal2.h:164
#define _In_opt_z_
Definition: no_sal2.h:218
#define _Outptr_
Definition: no_sal2.h:262
#define _Post_z_
Definition: no_sal2.h:508
#define _Inout_opt_
Definition: no_sal2.h:216
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Out_writes_to_(s, c)
Definition: no_sal2.h:188
#define REG_BINARY
Definition: nt_native.h:1499
#define KEY_READ
Definition: nt_native.h:1026
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define KEY_WRITE
Definition: nt_native.h:1034
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define STGM_CREATE
Definition: objbase.h:945
#define STGM_WRITE
Definition: objbase.h:937
#define STGM_READ
Definition: objbase.h:936
HRESULT WINAPI CreateBindCtx(DWORD reserved, IBindCtx **bind_context)
Definition: bindctx.c:491
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
Definition: oleaut.c:428
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
UINT ui
Definition: oleauto.h:49
#define V_UINT(A)
Definition: oleauto.h:264
#define V_UI4(A)
Definition: oleauto.h:270
const GUID IID_IPropertyBag
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:238
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1051
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1504
HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
Definition: pidl.c:1358
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:583
static const WCHAR szName[]
Definition: powrprof.c:45
EXTERN_C HRESULT WINAPI SHGetViewStatePropertyBag(_In_opt_ PCIDLIST_ABSOLUTE pidl, _In_opt_ LPCWSTR bag_name, _In_ DWORD flags, _In_ REFIID riid, _Outptr_ void **ppv)
Definition: propbag.cpp:1896
EXTERN_C BOOL WINAPI SHSetIniStringW(_In_z_ LPCWSTR appName, _In_z_ LPCWSTR keyName, _In_opt_z_ LPCWSTR str, _In_z_ LPCWSTR filename)
Definition: propbag.cpp:668
EXTERN_C BOOL WINAPI SHSetIniStringUTF7W(_In_z_ LPCWSTR lpAppName, _In_z_ LPCWSTR lpKeyName, _In_opt_z_ LPCWSTR lpString, _In_z_ LPCWSTR lpFileName)
Definition: propbag.cpp:758
EXTERN_C DWORD WINAPI SHGetIniStringW(_In_z_ LPCWSTR appName, _In_z_ LPCWSTR keyName, _Out_writes_to_(outLen, return+1) LPWSTR out, _In_ DWORD outLen, _In_z_ LPCWSTR filename)
Definition: propbag.cpp:612
DWORDLONG DESKVIEW_FLAGS
Definition: propbag.cpp:1060
EXTERN_C DWORD WINAPI SHGetIniStringUTF7W(_In_opt_z_ LPCWSTR lpAppName, _In_z_ LPCWSTR lpKeyName, _Out_writes_to_(nSize, return+1) _Post_z_ LPWSTR lpReturnedString, _In_ DWORD nSize, _In_z_ LPCWSTR lpFileName)
Definition: propbag.cpp:732
EXTERN_C HRESULT WINAPI SHCreatePropertyBagOnRegKey(_In_ HKEY hKey, _In_z_ LPCWSTR pszSubKey, _In_ DWORD dwMode, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: propbag.cpp:583
struct tagOLD_STREAM_HEADER * POLD_STREAM_HEADER
static BOOL Is7BitClean(LPCWSTR psz)
Definition: propbag.cpp:648
#define MODE_CAN_WRITE(dwMode)
Definition: propbag.cpp:26
HRESULT SHGetDesktopUpgradePropertyBag(REFIID riid, void **ppvObj)
Definition: propbag.cpp:1209
struct tagOLD_STREAM_HEADER OLD_STREAM_HEADER
static HRESULT BindCtx_CreateWithMode(DWORD dwMode, IBindCtx **ppbc)
Definition: propbag.cpp:1527
#define MODE_CAN_READ(dwMode)
Definition: propbag.cpp:24
EXTERN_C VOID FreeViewStatePropertyBagCache(VOID)
Definition: propbag.cpp:1944
static BOOL SHIsRemovableDrive(LPCITEMIDLIST pidl)
Definition: propbag.cpp:1852
EXTERN_C INT WINAPI SHGetPerScreenResName(_Out_writes_(cchBuffer) LPWSTR pszBuffer, _In_ INT cchBuffer, _In_ DWORD dwReserved)
Definition: propbag.cpp:1957
CRITICAL_SECTION g_csBagCacheLock
Definition: propbag.cpp:1325
EXTERN_C HRESULT WINAPI SHCreatePropertyBagOnProfileSection(_In_z_ LPCWSTR lpFileName, _In_opt_z_ LPCWSTR pszSection, _In_ DWORD dwMode, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: propbag.cpp:975
EXTERN_C HRESULT WINAPI IUnknown_QueryServicePropertyBag(_In_ IUnknown *punk, _In_ long flags, _In_ REFIID riid, _Outptr_ void **ppvObj)
Definition: propbag.cpp:1986
CComPtr< CViewStatePropertyBag > g_pCachedBag
Definition: propbag.cpp:1322
EXTERN_C HRESULT WINAPI SHCreatePropertyBagOnMemory(_In_ DWORD dwMode, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: propbag.cpp:260
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
_In_opt_ IUnknown * punk
Definition: shlwapi.h:158
#define SHGVSPB_ALLUSERS
Definition: shlwapi.h:168
#define SHGVSPB_GLOBALDEFAULTS
Definition: shlwapi.h:177
#define SHGVSPB_PERUSER
Definition: shlwapi.h:167
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
_In_ INT cchDest
Definition: shlwapi.h:1151
#define SHGVSPB_USERDEFAULTS
Definition: shlwapi.h:176
#define SHGVSPB_INHERIT
Definition: shlwapi.h:171
_In_ UINT cbInit
Definition: shlwapi.h:1025
#define SHGVSPB_FOLDER
Definition: shlwapi.h:174
#define SHGVSPB_NOAUTODEFAULTS
Definition: shlwapi.h:173
_In_opt_ LPCSTR pszSubKey
Definition: shlwapi.h:783
#define SHGVSPB_ROAM
Definition: shlwapi.h:172
#define SHGVSPB_PERFOLDER
Definition: shlwapi.h:169
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:615
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
EXTERN_C INT WINAPI RealDriveType(INT drive, BOOL bQueryNet)
Definition: shlfileop.cpp:2354
#define SHGDFIL_FINDDATA
Definition: shlobj.h:1459
#define SHCNE_UPDATEITEM
Definition: shlobj.h:1910
#define SHCNF_PATHW
Definition: shlobj.h:1933
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
_In_ BOOLEAN Read
Definition: strmini.h:479
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
static bool IsEqualKey(const ATL::CStringW &k1, const ATL::CStringW &k2)
Definition: propbag.cpp:131
static bool IsEqualValue(const ATL::CComVariant &v1, const ATL::CComVariant &v2)
Definition: propbag.cpp:136
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
DWORD dwFileAttributes
Definition: minwinbase.h:283
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
_In_ LPCSTR lpFileName
Definition: winbase.h:2800
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define DRIVE_CDROM
Definition: winbase.h:279
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:1811
#define DRIVE_REMOVABLE
Definition: winbase.h:276
#define WINAPI
Definition: msvc.h:6
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_ACCESSDENIED
Definition: winerror.h:4116
#define E_POINTER
Definition: winerror.h:3480
#define HORZRES
Definition: wingdi.h:716
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define VERTRES
Definition: wingdi.h:717
#define CP_UTF7
Definition: winnls.h:263
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:76
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HDC WINAPI GetDC(_In_opt_ HWND)
#define SM_CMONITORS
Definition: winuser.h:1051
int WINAPI GetSystemMetrics(_In_ int)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char BYTE
Definition: xxhash.c:193