ReactOS 0.4.15-dev-7961-gdcf9eb0
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
21
22#define MODE_CAN_READ(dwMode) \
23 (((dwMode) & (STGM_READ | STGM_WRITE | STGM_READWRITE)) != STGM_WRITE)
24#define MODE_CAN_WRITE(dwMode) \
25 (((dwMode) & (STGM_READ | STGM_WRITE | STGM_READWRITE)) != STGM_READ)
26
28 : public IPropertyBag
29#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
30 , public IPropertyBag2
31#endif
32{
33protected:
34 LONG m_cRefs; // reference count
35 DWORD m_dwMode; // STGM_* flags
36
37public:
39 : m_cRefs(0)
40 , m_dwMode(dwMode)
41 {
42 }
43
44 virtual ~CBasePropertyBag() { }
45
46 // IUnknown interface
48 {
49 if (!ppvObject)
50 return E_POINTER;
51
52#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
53 if (::IsEqualGUID(riid, IID_IPropertyBag2))
54 {
55 AddRef();
56 *ppvObject = static_cast<IPropertyBag2*>(this);
57 return S_OK;
58 }
59#endif
61 {
62 AddRef();
63 *ppvObject = static_cast<IPropertyBag*>(this);
64 return S_OK;
65 }
66
67 ERR("%p: %s: E_NOINTERFACE\n", this, debugstr_guid(&riid));
68 return E_NOINTERFACE;
69 }
71 {
72 return ::InterlockedIncrement(&m_cRefs);
73 }
75 {
77 {
78 delete this;
79 return 0;
80 }
81 return m_cRefs;
82 }
83
84#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
85 // IPropertyBag2 interface (stubs)
87 _In_ ULONG cProperties,
88 _In_ PROPBAG2 *pPropBag,
89 _In_opt_ IErrorLog *pErrorLog,
90 _Out_ VARIANT *pvarValue,
91 _Out_ HRESULT *phrError) override
92 {
93 return E_NOTIMPL;
94 }
96 _In_ ULONG cProperties,
97 _In_ PROPBAG2 *pPropBag,
98 _In_ VARIANT *pvarValue)
99 {
100 return E_NOTIMPL;
101 }
102 STDMETHODIMP CountProperties(_Out_ ULONG *pcProperties) override
103 {
104 return E_NOTIMPL;
105 }
106 STDMETHODIMP GetPropertyInfo(
107 _In_ ULONG iProperty,
108 _In_ ULONG cProperties,
109 _Out_ PROPBAG2 *pPropBag,
110 _Out_ ULONG *pcProperties) override
111 {
112 return E_NOTIMPL;
113 }
114 STDMETHODIMP LoadObject(
115 _In_z_ LPCWSTR pstrName,
116 _In_ DWORD dwHint,
117 _In_ IUnknown *pUnkObject,
118 _In_opt_ IErrorLog *pErrorLog) override
119 {
120 return E_NOTIMPL;
121 }
122#endif
123};
124
126{
127 static bool IsEqualKey(const ATL::CStringW& k1, const ATL::CStringW& k2)
128 {
129 return k1.CompareNoCase(k2) == 0;
130 }
131
133 {
134 return false;
135 }
136};
137
139{
140protected:
142
143public:
145
146 STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari,
147 _Inout_opt_ IErrorLog *pErrorLog) override;
148 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
149};
150
153 _In_z_ LPCWSTR pszPropName,
154 _Inout_ VARIANT *pvari,
155 _Inout_opt_ IErrorLog *pErrorLog)
156{
157 UNREFERENCED_PARAMETER(pErrorLog);
158
159 TRACE("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
160
161 VARTYPE vt = V_VT(pvari);
162
163 ::VariantInit(pvari);
164
165#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
167 {
168 ERR("%p: 0x%X\n", this, m_dwMode);
169 return E_ACCESSDENIED;
170 }
171#endif
172
173 if (!pszPropName || !pvari)
174 {
175 ERR("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
176 return E_INVALIDARG;
177 }
178
179 INT iItem = m_PropMap.FindKey(pszPropName);
180 if (iItem == -1)
181 {
182 ERR("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
183 return E_FAIL;
184 }
185
186 HRESULT hr = ::VariantCopy(pvari, &m_PropMap.GetValueAt(iItem));
187 if (FAILED(hr))
188 {
189 ERR("%p: 0x%08X %p\n", this, hr, pvari);
190 return hr;
191 }
192
193 hr = ::VariantChangeTypeForRead(pvari, vt);
194 if (FAILED(hr))
195 {
196 ERR("%p: 0x%08X %p\n", this, hr, pvari);
197 return hr;
198 }
199
200 return hr;
201}
202
205 _In_z_ LPCWSTR pszPropName,
206 _In_ VARIANT *pvari)
207{
208 TRACE("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
209
210#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
212 {
213 ERR("%p: 0x%X\n", this, m_dwMode);
214 return E_ACCESSDENIED;
215 }
216#endif
217
218 if (!pszPropName || !pvari)
219 {
220 ERR("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
221 return E_INVALIDARG;
222 }
223
224 ATL::CComVariant vari;
225 HRESULT hr = vari.Copy(pvari);
226 if (FAILED(hr))
227 {
228 ERR("%p: %s %p: 0x%08X\n", this, debugstr_w(pszPropName), pvari, hr);
229 return hr;
230 }
231
232 if (!m_PropMap.SetAt(pszPropName, vari))
233 {
234 ERR("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
235 return E_FAIL;
236 }
237
238 return hr;
239}
240
241/**************************************************************************
242 * SHCreatePropertyBagOnMemory (SHLWAPI.477)
243 *
244 * Creates a property bag object on memory.
245 *
246 * @param dwMode Specifies either STGM_READ, STGM_WRITE or STGM_READWRITE. Ignored on Vista+.
247 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
248 * Vista+ rejects IID_IPropertyBag2.
249 * @param ppvObj Receives an IPropertyBag pointer.
250 * @return An HRESULT value. S_OK on success, non-zero on failure.
251 * @see http://undoc.airesoft.co.uk/shlwapi.dll/SHCreatePropertyBagOnMemory.php
252 */
255{
256 TRACE("0x%08X, %s, %p\n", dwMode, debugstr_guid(&riid), ppvObj);
257
258 *ppvObj = NULL;
259
260 CComPtr<CMemPropertyBag> pMemBag(new CMemPropertyBag(dwMode));
261
262 return pMemBag->QueryInterface(riid, ppvObj);
263}
264
266{
267protected:
269
270 HRESULT _ReadDword(LPCWSTR pszPropName, VARIANT *pvari);
271 HRESULT _ReadString(LPCWSTR pszPropName, VARIANTARG *pvarg, UINT len);
272 HRESULT _ReadBinary(LPCWSTR pszPropName, VARIANT *pvari, VARTYPE vt, DWORD uBytes);
273 HRESULT _ReadStream(VARIANT *pvari, BYTE *pInit, UINT cbInit);
274 HRESULT _CopyStreamIntoBuff(IStream *pStream, void *pv, ULONG cb);
275 HRESULT _GetStreamSize(IStream *pStream, LPDWORD pcbSize);
276 HRESULT _WriteStream(LPCWSTR pszPropName, IStream *pStream);
277
278public:
280 : CBasePropertyBag(dwMode)
281 , m_hKey(NULL)
282 {
283 }
284
286 {
287 if (m_hKey)
289 }
290
291 HRESULT Init(HKEY hKey, LPCWSTR lpSubKey);
292
293 STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari,
294 _Inout_opt_ IErrorLog *pErrorLog) override;
295 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
296};
297
299{
300 REGSAM nAccess = 0;
302 nAccess |= KEY_READ;
304 nAccess |= KEY_WRITE;
305
306 LONG error;
307 if (m_dwMode & STGM_CREATE)
308 error = ::RegCreateKeyExW(hKey, lpSubKey, 0, NULL, 0, nAccess, NULL, &m_hKey, NULL);
309 else
310 error = ::RegOpenKeyExW(hKey, lpSubKey, 0, nAccess, &m_hKey);
311
312 if (error != ERROR_SUCCESS)
313 {
314 ERR("%p %s 0x%08X\n", hKey, debugstr_w(lpSubKey), error);
316 }
317
318 return S_OK;
319}
320
322{
323 DWORD cbData = sizeof(DWORD);
324 LONG error = SHGetValueW(m_hKey, NULL, pszPropName, NULL, &V_UI4(pvari), &cbData);
325 if (error)
326 return E_FAIL;
327
328 V_VT(pvari) = VT_UI4;
329 return S_OK;
330}
331
333{
335 V_BSTR(pvarg) = bstr;
336 if (!bstr)
337 return E_OUTOFMEMORY;
338
339 V_VT(pvarg) = VT_BSTR;
340 LONG error = SHGetValueW(m_hKey, NULL, pszPropName, NULL, bstr, (LPDWORD)&len);
341 if (error)
342 {
343 ::VariantClear(pvarg);
344 return E_FAIL;
345 }
346
347 return S_OK;
348}
349
351{
352 IStream *pStream = SHCreateMemStream(pInit, cbInit);
353 V_UNKNOWN(pvari) = pStream;
354 if (!pStream)
355 return E_OUTOFMEMORY;
356 V_VT(pvari) = VT_UNKNOWN;
357 return S_OK;
358}
359
362 LPCWSTR pszPropName,
363 VARIANT *pvari,
364 VARTYPE vt,
365 DWORD uBytes)
366{
367 HRESULT hr = E_FAIL;
368 if (vt != VT_UNKNOWN || uBytes < sizeof(GUID))
369 return hr;
370
372 if (!pbData)
373 return hr;
374
375 if (!SHGetValueW(m_hKey, NULL, pszPropName, NULL, pbData, &uBytes) &&
376 memcmp(&GUID_NULL, pbData, sizeof(GUID)) == 0)
377 {
378 hr = _ReadStream(pvari, pbData + sizeof(GUID), uBytes - sizeof(GUID));
379 }
380
382
383 return hr;
384}
385
387{
389 li.QuadPart = 0;
390 HRESULT hr = pStream->Seek(li, 0, NULL);
391 if (FAILED(hr))
392 return hr;
393 return pStream->Read(pv, cb, NULL);
394}
395
397{
398 *pcbSize = 0;
399
401 HRESULT hr = IStream_Size(pStream, &ui);
402 if (FAILED(hr))
403 return hr;
404
405 if (ui.DUMMYSTRUCTNAME.HighPart)
406 return E_FAIL; /* 64-bit value is not supported */
407
408 *pcbSize = ui.DUMMYSTRUCTNAME.LowPart;
409 return hr;
410}
411
414 _In_z_ LPCWSTR pszPropName,
415 _Inout_ VARIANT *pvari,
416 _Inout_opt_ IErrorLog *pErrorLog)
417{
418 UNREFERENCED_PARAMETER(pErrorLog);
419
420 TRACE("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
421
423 {
424 ERR("%p: 0x%X\n", this, m_dwMode);
425 ::VariantInit(pvari);
426 return E_ACCESSDENIED;
427 }
428
429 VARTYPE vt = V_VT(pvari);
430 VariantInit(pvari);
431
432 HRESULT hr;
433 DWORD dwType, cbValue;
434 LONG error = SHGetValueW(m_hKey, NULL, pszPropName, &dwType, NULL, &cbValue);
435 if (error != ERROR_SUCCESS)
436 hr = E_FAIL;
437 else if (dwType == REG_SZ)
438 hr = _ReadString(pszPropName, pvari, cbValue);
439 else if (dwType == REG_BINARY)
440 hr = _ReadBinary(pszPropName, pvari, vt, cbValue);
441 else if (dwType == REG_DWORD)
442 hr = _ReadDword(pszPropName, pvari);
443 else
444 hr = E_FAIL;
445
446 if (FAILED(hr))
447 {
448 ERR("%p: 0x%08X %ld: %s %p\n", this, hr, dwType, debugstr_w(pszPropName), pvari);
449 ::VariantInit(pvari);
450 return hr;
451 }
452
453 hr = ::VariantChangeTypeForRead(pvari, vt);
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 }
459
460 return hr;
461}
462
465{
466 DWORD cbData;
467 HRESULT hr = _GetStreamSize(pStream, &cbData);
468 if (FAILED(hr) || !cbData)
469 return hr;
470
471 DWORD cbBinary = cbData + sizeof(GUID);
473 if (!pbBinary)
474 return E_OUTOFMEMORY;
475
476 hr = _CopyStreamIntoBuff(pStream, pbBinary + sizeof(GUID), cbData);
477 if (SUCCEEDED(hr))
478 {
479 if (SHSetValueW(m_hKey, NULL, pszPropName, REG_BINARY, pbBinary, cbBinary))
480 hr = E_FAIL;
481 }
482
483 ::LocalFree(pbBinary);
484 return hr;
485}
486
489{
490 TRACE("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
491
493 {
494 ERR("%p: 0x%X\n", this, m_dwMode);
495 return E_ACCESSDENIED;
496 }
497
498 HRESULT hr;
499 LONG error;
500 VARIANTARG vargTemp = { 0 };
501 switch (V_VT(pvari))
502 {
503 case VT_EMPTY:
504 SHDeleteValueW(m_hKey, NULL, pszPropName);
505 hr = S_OK;
506 break;
507
508 case VT_BOOL:
509 case VT_I1:
510 case VT_I2:
511 case VT_I4:
512 case VT_UI1:
513 case VT_UI2:
514 case VT_UI4:
515 case VT_INT:
516 case VT_UINT:
517 {
518 hr = ::VariantChangeType(&vargTemp, pvari, 0, VT_UI4);
519 if (FAILED(hr))
520 return hr;
521
522 error = SHSetValueW(m_hKey, NULL, pszPropName, REG_DWORD, &V_UI4(&vargTemp), sizeof(DWORD));
523 if (error)
524 hr = E_FAIL;
525
526 ::VariantClear(&vargTemp);
527 break;
528 }
529
530 case VT_UNKNOWN:
531 {
532 CComPtr<IStream> pStream;
533 hr = V_UNKNOWN(pvari)->QueryInterface(IID_IStream, (void **)&pStream);
534 if (FAILED(hr))
535 return hr;
536
537 hr = _WriteStream(pszPropName, pStream);
538 break;
539 }
540
541 default:
542 {
543 hr = ::VariantChangeType(&vargTemp, pvari, 0, VT_BSTR);
544 if (FAILED(hr))
545 return hr;
546
547 int cch = lstrlenW(V_BSTR(&vargTemp));
548 DWORD cb = (cch + 1) * sizeof(WCHAR);
549 error = SHSetValueW(m_hKey, NULL, pszPropName, REG_SZ, V_BSTR(&vargTemp), cb);
550 if (error)
551 hr = E_FAIL;
552
553 ::VariantClear(&vargTemp);
554 break;
555 }
556 }
557
558 return hr;
559}
560
561/**************************************************************************
562 * SHCreatePropertyBagOnRegKey (SHLWAPI.471)
563 *
564 * Creates a property bag object on registry key.
565 *
566 * @param hKey The registry key.
567 * @param pszSubKey The path of the sub-key.
568 * @param dwMode The combination of STGM_READ, STGM_WRITE, STGM_READWRITE, and STGM_CREATE.
569 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
570 * @param ppvObj Receives an IPropertyBag pointer.
571 * @return An HRESULT value. S_OK on success, non-zero on failure.
572 * @see https://source.winehq.org/WineAPI/SHCreatePropertyBagOnRegKey.html
573 */
576 _In_ HKEY hKey,
577 _In_z_ LPCWSTR pszSubKey,
578 _In_ DWORD dwMode,
580 _Out_ void **ppvObj)
581{
582 TRACE("%p, %s, 0x%08X, %s, %p\n", hKey, debugstr_w(pszSubKey), dwMode,
583 debugstr_guid(&riid), ppvObj);
584
585 *ppvObj = NULL;
586
587 CComPtr<CRegPropertyBag> pRegBag(new CRegPropertyBag(dwMode));
588
589 HRESULT hr = pRegBag->Init(hKey, pszSubKey);
590 if (FAILED(hr))
591 return hr;
592
593 return pRegBag->QueryInterface(riid, ppvObj);
594}
595
596/**************************************************************************
597 * SHGetIniStringW (SHLWAPI.294)
598 *
599 * @see https://source.winehq.org/WineAPI/SHGetIniStringW.html
600 */
604 _In_z_ LPCWSTR keyName,
605 _Out_writes_to_(outLen, return + 1) LPWSTR out,
606 _In_ DWORD outLen,
608{
609 TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName), debugstr_w(keyName),
610 out, outLen, debugstr_w(filename));
611
612 if (outLen == 0)
613 return 0;
614
615 // Try ".W"-appended section name. See also SHSetIniStringW
616 CStringW szSection(appName);
617 szSection += L".W";
618 CStringW pszWideBuff;
619 const INT cchWideMax = 4 * MAX_PATH; // UTF-7 needs 4 times length buffer.
620 GetPrivateProfileStringW(szSection, keyName, NULL,
621 pszWideBuff.GetBuffer(cchWideMax), cchWideMax, filename);
622 pszWideBuff.ReleaseBuffer();
623
624 if (pszWideBuff.IsEmpty()) // It's empty or not found
625 {
626 // Try the normal section name
627 return GetPrivateProfileStringW(appName, keyName, NULL, out, outLen, filename);
628 }
629
630 // Okay, now ".W" version is valid. Its value is a UTF-7 string in UTF-16
631 CW2A wide2utf7(pszWideBuff);
632 MultiByteToWideChar(CP_UTF7, 0, wide2utf7, -1, out, outLen);
633 out[outLen - 1] = UNICODE_NULL;
634
635 return lstrlenW(out);
636}
637
639{
640 if (!psz)
641 return TRUE;
642
643 while (*psz)
644 {
645 if (*psz > 0x7F)
646 return FALSE;
647 ++psz;
648 }
649 return TRUE;
650}
651
652/**************************************************************************
653 * SHSetIniStringW (SHLWAPI.295)
654 *
655 * @see https://source.winehq.org/WineAPI/SHSetIniStringW.html
656 */
660 _In_z_ LPCWSTR keyName,
663{
664 TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName), keyName, debugstr_w(str),
666
667 // Write a normal profile string. If str was NULL, then key will be deleted
669 return FALSE;
670
671 if (Is7BitClean(str))
672 {
673 // Delete ".A" version
674 CStringW szSection(appName);
675 szSection += L".A";
676 WritePrivateProfileStringW(szSection, keyName, NULL, filename);
677
678 // Delete ".W" version
679 szSection = appName;
680 szSection += L".W";
681 WritePrivateProfileStringW(szSection, keyName, NULL, filename);
682
683 return TRUE;
684 }
685
686 // Now str is not 7-bit clean. It needs UTF-7 encoding in UTF-16.
687 // We write ".A" and ".W"-appended sections
688 CW2A wide2utf7(str, CP_UTF7);
689 CA2W utf72wide(wide2utf7, CP_ACP);
690
691 BOOL ret = TRUE;
692
693 // Write ".A" version
694 CStringW szSection(appName);
695 szSection += L".A";
696 if (!WritePrivateProfileStringW(szSection, keyName, str, filename))
697 ret = FALSE;
698
699 // Write ".W" version
700 szSection = appName;
701 szSection += L".W";
702 if (!WritePrivateProfileStringW(szSection, keyName, utf72wide, filename))
703 ret = FALSE;
704
705 return ret;
706}
707
708/**************************************************************************
709 * SHGetIniStringUTF7W (SHLWAPI.473)
710 *
711 * Retrieves a string value from an INI file.
712 *
713 * @param lpAppName The section name.
714 * @param lpKeyName The key name.
715 * If this string begins from '@', the value will be interpreted as UTF-7.
716 * @param lpReturnedString Receives a wide string value.
717 * @param nSize The number of characters in lpReturnedString.
718 * @param lpFileName The INI file.
719 * @return The number of characters copied to the buffer if succeeded.
720 */
723 _In_opt_z_ LPCWSTR lpAppName,
724 _In_z_ LPCWSTR lpKeyName,
725 _Out_writes_to_(nSize, return + 1) _Post_z_ LPWSTR lpReturnedString,
728{
729 if (*lpKeyName == L'@') // UTF-7
730 return SHGetIniStringW(lpAppName, lpKeyName + 1, lpReturnedString, nSize, lpFileName);
731
732 return GetPrivateProfileStringW(lpAppName, lpKeyName, L"", lpReturnedString, nSize, lpFileName);
733}
734
735/**************************************************************************
736 * SHSetIniStringUTF7W (SHLWAPI.474)
737 *
738 * Sets a string value on an INI file.
739 *
740 * @param lpAppName The section name.
741 * @param lpKeyName The key name.
742 * If this begins from '@', the value will be stored as UTF-7.
743 * @param lpString The wide string value to be set.
744 * @param lpFileName The INI file.
745 * @return TRUE if successful. FALSE if failed.
746 */
749 _In_z_ LPCWSTR lpAppName,
750 _In_z_ LPCWSTR lpKeyName,
751 _In_opt_z_ LPCWSTR lpString,
753{
754 if (*lpKeyName == L'@') // UTF-7
755 return SHSetIniStringW(lpAppName, lpKeyName + 1, lpString, lpFileName);
756
757 return WritePrivateProfileStringW(lpAppName, lpKeyName, lpString, lpFileName);
758}
759
761{
762protected:
765 BOOL m_bAlternateStream; // ADS (Alternate Data Stream)
766
768 {
769 LPCWSTR pch = StrRChrW(pszStart, NULL, L'\\');
770 if (!pch)
771 pch = pszStart;
772 return StrChrW(pch, L':') != NULL;
773 }
774
775 HRESULT
777 LPCWSTR pszStart,
778 LPWSTR pszSection,
779 UINT cchSectionMax,
780 LPWSTR pszName,
781 UINT cchNameMax);
782
783public:
785 : CBasePropertyBag(dwMode)
789 {
790 }
791
793 {
796 }
797
798 HRESULT Init(LPCWSTR pszIniFile, LPCWSTR pszSection);
799
801 _In_z_ LPCWSTR pszPropName,
802 _Inout_ VARIANT *pvari,
803 _Inout_opt_ IErrorLog *pErrorLog) override;
804
805 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
806};
807
809{
810 m_pszFileName = StrDupW(pszIniFile);
811 if (!m_pszFileName)
812 return E_OUTOFMEMORY;
813
814 // Is it an ADS (Alternate Data Stream) pathname?
816
817 if (pszSection)
818 {
819 m_pszSection = StrDupW(pszSection);
820 if (!m_pszSection)
821 return E_OUTOFMEMORY;
822 }
823
824 return S_OK;
825}
826
829 LPCWSTR pszStart,
830 LPWSTR pszSection,
831 UINT cchSectionMax,
832 LPWSTR pszName,
833 UINT cchNameMax)
834{
835 LPCWSTR pchSep = StrChrW(pszStart, L'\\');
836 if (pchSep)
837 {
838 UINT cchSep = (UINT)(pchSep - pszStart + 1);
839 StrCpyNW(pszSection, pszStart, min(cchSep, cchSectionMax));
840 StrCpyNW(pszName, pchSep + 1, cchNameMax);
841 return S_OK;
842 }
843
844 if (m_pszSection)
845 {
846 StrCpyNW(pszSection, m_pszSection, cchSectionMax);
847 StrCpyNW(pszName, pszStart, cchNameMax);
848 return S_OK;
849 }
850
851 ERR("%p: %s\n", this, debugstr_w(pszStart));
852 return E_INVALIDARG;
853}
854
857 _In_z_ LPCWSTR pszPropName,
858 _Inout_ VARIANT *pvari,
859 _Inout_opt_ IErrorLog *pErrorLog)
860{
861 UNREFERENCED_PARAMETER(pErrorLog);
862
863 TRACE("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
864
865 VARTYPE vt = V_VT(pvari);
866
867 ::VariantInit(pvari);
868
870 {
871 ERR("%p: 0x%X\n", this, m_dwMode);
872 return E_ACCESSDENIED;
873 }
874
875 WCHAR szSection[64], szName[64];
876 HRESULT hr =
877 _GetSectionAndName(pszPropName, szSection, _countof(szSection), szName, _countof(szName));
878 if (FAILED(hr))
879 return hr;
880
881 const INT cchBuffMax = 4 * MAX_PATH; // UTF-7 needs 4 times length buffer.
882 CComHeapPtr<WCHAR> pszBuff;
883 if (!pszBuff.Allocate(cchBuffMax * sizeof(WCHAR)))
884 return E_OUTOFMEMORY;
885
886 if (!SHGetIniStringUTF7W(szSection, szName, pszBuff, cchBuffMax, m_pszFileName))
887 return E_FAIL;
888
889 BSTR bstr = ::SysAllocString(pszBuff);
890 V_BSTR(pvari) = bstr;
891 if (!bstr)
892 return E_OUTOFMEMORY;
893
894 V_VT(pvari) = VT_BSTR;
895 return ::VariantChangeTypeForRead(pvari, vt);
896}
897
900{
901 TRACE("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
902
904 {
905 ERR("%p: 0x%X\n", this, m_dwMode);
906 return E_ACCESSDENIED;
907 }
908
909 HRESULT hr;
910 BSTR bstr;
911 VARIANTARG vargTemp = { 0 };
912 switch (V_VT(pvari))
913 {
914 case VT_EMPTY:
915 bstr = NULL;
916 break;
917
918 case VT_BSTR:
919 bstr = V_BSTR(pvari);
920 break;
921
922 default:
923 hr = ::VariantChangeType(&vargTemp, pvari, 0, VT_BSTR);
924 if (FAILED(hr))
925 goto Quit;
926
927 bstr = V_BSTR(&vargTemp);
928 break;
929 }
930
931 WCHAR szSection[64], szName[64];
932 hr = _GetSectionAndName(pszPropName, szSection, _countof(szSection), szName, _countof(szName));
933 if (SUCCEEDED(hr))
934 {
935 if (SHSetIniStringUTF7W(szSection, szName, bstr, m_pszFileName))
936 {
939 }
940 else
941 {
942 hr = E_FAIL;
943 }
944 }
945
946Quit:
947 ::VariantClear(&vargTemp);
948 return hr;
949}
950
951/**************************************************************************
952 * SHCreatePropertyBagOnProfileSection (SHLWAPI.472)
953 *
954 * Creates a property bag object on INI file.
955 *
956 * @param lpFileName The INI filename.
957 * @param pszSection The optional section name.
958 * @param dwMode The combination of STGM_READ, STGM_WRITE, STGM_READWRITE, and STGM_CREATE.
959 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
960 * @param ppvObj Receives an IPropertyBag pointer.
961 * @return An HRESULT value. S_OK on success, non-zero on failure.
962 * @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/propbag/createonprofilesection.htm
963 */
967 _In_opt_z_ LPCWSTR pszSection,
968 _In_ DWORD dwMode,
970 _Out_ void **ppvObj)
971{
973 PWCHAR pchFileTitle;
974 WCHAR szBuff[MAX_PATH];
975
976 if (dwMode & STGM_CREATE)
977 {
981 {
982 pchFileTitle = PathFindFileNameW(lpFileName);
983 if (lstrcmpiW(pchFileTitle, L"desktop.ini") == 0)
984 {
985 StrCpyNW(szBuff, lpFileName, _countof(szBuff));
986 if (PathRemoveFileSpecW(szBuff))
987 PathMakeSystemFolderW(szBuff);
988 }
990 }
991 }
992
993 *ppvObj = NULL;
994
997
998 CComPtr<CIniPropertyBag> pIniPB(new CIniPropertyBag(dwMode));
999
1000 HRESULT hr = pIniPB->Init(lpFileName, pszSection);
1001 if (FAILED(hr))
1002 {
1003 ERR("0x%08X\n", hr);
1004 return hr;
1005 }
1006
1007 return pIniPB->QueryInterface(riid, ppvObj);
1008}
1009
1011{
1012protected:
1015 HRESULT _ReadFlags(VARIANT *pvari);
1018 IStream* _NewStreamFromOld(IStream *pOldStream);
1019
1020public:
1022
1024 _In_z_ LPCWSTR pszPropName,
1025 _Inout_ VARIANT *pvari,
1026 _Inout_opt_ IErrorLog *pErrorLog) override;
1027
1028 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
1029 {
1030 ERR("%p: %s: Read-only\n", this, debugstr_w(pszPropName));
1031 return E_NOTIMPL;
1032 }
1033};
1034
1036{
1037 DWORD dwValue = TRUE;
1038 SHSetValueW(hkey, NULL, L"Upgrade", REG_DWORD, &dwValue, sizeof(dwValue));
1039}
1040
1042{
1043 // Check the existence of the value written in _MarkAsUpgraded.
1044 DWORD dwValue, cbData = sizeof(dwValue);
1045 return SHGetValueW(hKey, NULL, L"Upgrade", NULL, &dwValue, &cbData) == ERROR_SUCCESS;
1046}
1047
1048typedef DWORDLONG DESKVIEW_FLAGS; // 64-bit data
1049
1051{
1053 DWORD cbValue = sizeof(Flags);
1055 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DeskView",
1056 L"Settings",
1057 NULL,
1058 &Flags,
1059 &cbValue) != ERROR_SUCCESS || cbValue < sizeof(Flags))
1060 {
1061 return E_FAIL;
1062 }
1063
1064 V_UINT(pvari) = ((UINT)(Flags >> 32)) | 0x220; // FIXME: Magic number
1065 V_VT(pvari) = VT_UINT;
1066 return S_OK;
1067}
1068
1070{
1075
1077{
1079 HRESULT hr = pOldStream->Read(&Header, sizeof(Header), NULL);
1080 if (FAILED(hr) || Header.wMagic != 28)
1081 return NULL;
1082
1083 // Move stream pointer
1085 li.QuadPart = Header.wSize - sizeof(Header);
1086 hr = pOldStream->Seek(li, STREAM_SEEK_CUR, NULL);
1087 if (FAILED(hr))
1088 return NULL;
1089
1090 // Get the size
1091 ULARGE_INTEGER uli;
1092 hr = IStream_Size(pOldStream, &uli);
1093 if (FAILED(hr))
1094 return NULL;
1095
1096 // Create new stream and attach
1097 CComPtr<IStream> pNewStream;
1098 pNewStream.Attach(SHCreateMemStream(NULL, 0));
1099 if (!pNewStream)
1100 return NULL;
1101
1102 // Subtract Header.wSize from the size
1103 uli.QuadPart -= Header.wSize;
1104
1105 // Copy to pNewStream
1106 hr = pOldStream->CopyTo(pNewStream, uli, NULL, NULL);
1107 if (FAILED(hr))
1108 return NULL;
1109
1110 li.QuadPart = 0;
1111 pNewStream->Seek(li, STREAM_SEEK_SET, NULL);
1112
1113 return pNewStream.Detach();
1114}
1115
1117{
1118 HKEY hKey = SHGetShellKey(SHKEY_Root_HKCU, L"Streams\\Desktop", FALSE);
1119 if (!hKey)
1120 return NULL;
1121
1122 CComPtr<IStream> pOldStream;
1123 if (!_AlreadyUpgraded(hKey))
1124 {
1125 pOldStream.Attach(SHOpenRegStream2W(hKey, NULL, L"ViewView2", 0));
1126 if (pOldStream)
1127 {
1128 ULARGE_INTEGER uli;
1129 HRESULT hr = IStream_Size(pOldStream, &uli);
1130 if (SUCCEEDED(hr) && !uli.QuadPart)
1131 pOldStream.Release();
1132 }
1133
1134 if (!pOldStream)
1135 pOldStream.Attach(SHOpenRegStream2W(hKey, NULL, L"ViewView", 0));
1136
1138 }
1139
1141 return pOldStream.Detach();
1142}
1143
1145{
1146 CComPtr<IStream> pOldStream;
1147 pOldStream.Attach(_GetOldDesktopViewStream());
1148 if (!pOldStream)
1149 return E_FAIL;
1150
1151 HRESULT hr = E_FAIL;
1152 IStream *pNewStream = _NewStreamFromOld(pOldStream);
1153 if (pNewStream)
1154 {
1155 V_UNKNOWN(pvari) = pNewStream;
1156 V_VT(pvari) = VT_UNKNOWN;
1157 hr = S_OK;
1158 }
1159
1160 return hr;
1161}
1162
1165 _In_z_ LPCWSTR pszPropName,
1166 _Inout_ VARIANT *pvari,
1167 _Inout_opt_ IErrorLog *pErrorLog)
1168{
1169 UNREFERENCED_PARAMETER(pErrorLog);
1170
1171 VARTYPE vt = V_VT(pvari);
1172
1173 HRESULT hr = E_FAIL;
1174 if (StrCmpW(L"FFlags", pszPropName) == 0)
1175 hr = _ReadFlags(pvari);
1176 else if (StrCmpNW(L"ItemPos", pszPropName, 7) == 0)
1177 hr = _ReadItemPositions(pvari);
1178
1179 if (FAILED(hr))
1180 {
1181 ::VariantInit(pvari);
1182 return hr;
1183 }
1184
1185 return ::VariantChangeType(pvari, pvari, 0, vt);
1186}
1187
1188/**************************************************************************
1189 * SHGetDesktopUpgradePropertyBag (Internal)
1190 *
1191 * Creates or gets a property bag object for desktop upgrade
1192 *
1193 * @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
1194 * @param ppvObj Receives an IPropertyBag pointer.
1195 * @return An HRESULT value. S_OK on success, non-zero on failure.
1196 */
1198{
1199 *ppvObj = NULL;
1201 return pPropBag->QueryInterface(riid, ppvObj);
1202}
1203
1205{
1206protected:
1209 DWORD m_dwVspbFlags = 0; // SHGVSPB_... flags
1226
1227 BOOL _IsSamePidl(LPCITEMIDLIST pidlOther) const;
1228 BOOL _IsSystemFolder() const;
1229 BOOL _CanAccessPidlBag() const;
1233 BOOL _CanAccessInheritBag() const;
1234 BOOL _CanAccessUpgradeBag() const;
1235
1236 HKEY _GetHKey(DWORD dwVspbFlags);
1237
1239
1241 LPCITEMIDLIST pidl,
1242 DWORD dwMode,
1243 HKEY hKey,
1244 UINT *puSlots,
1245 UINT cSlots,
1246 UINT *pcSlots);
1247
1248 HRESULT _GetMRUSlot(LPCITEMIDLIST pidl, DWORD dwMode, HKEY hKey, UINT *pSlot);
1249
1251 LPCITEMIDLIST pidl,
1252 LPCWSTR pszBagName,
1253 DWORD dwFlags,
1254 DWORD dwMode,
1255 HKEY hKey,
1256 LPWSTR pszDest,
1257 INT cchDest);
1258
1260 LPITEMIDLIST pidl,
1261 LPCWSTR pszPath,
1262 DWORD dwVspbFlags,
1263 DWORD dwMode,
1264 REFIID riid,
1265 IPropertyBag **pppb);
1266
1268
1269 void _ResetTryAgainFlag();
1270
1279 HRESULT _ReadPidlBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1280 HRESULT _ReadInheritBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1281 HRESULT _ReadUpgradeBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1282 HRESULT _ReadUserDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1283 HRESULT _ReadFolderDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1284 HRESULT _ReadGlobalDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog);
1285 void _PruneMRUTree();
1286
1287public:
1289
1291 {
1294 }
1295
1296 HRESULT Init(_In_opt_ LPCITEMIDLIST pidl, _In_opt_ LPCWSTR pszPath, _In_ DWORD dwVspbFlags);
1297 BOOL IsSameBag(LPCITEMIDLIST pidl, LPCWSTR pszPath, DWORD dwVspbFlags) const;
1298
1300 _In_z_ LPCWSTR pszPropName,
1301 _Inout_ VARIANT *pvari,
1302 _Inout_opt_ IErrorLog *pErrorLog) override;
1303
1304 STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
1305};
1306
1307// CViewStatePropertyBag is cached
1309extern "C"
1310{
1312}
1313
1314HRESULT
1317 _In_opt_ LPCWSTR pszPath,
1318 _In_ DWORD dwVspbFlags)
1319{
1320 if (pidl)
1321 {
1322 m_pidl = ILClone(pidl);
1323 if (!m_pidl)
1324 return E_OUTOFMEMORY;
1325 }
1326
1327 if (pszPath)
1328 {
1329 m_pszPath = StrDupW(pszPath);
1330 if (!m_pszPath)
1331 return E_OUTOFMEMORY;
1332
1333 m_dwVspbFlags = dwVspbFlags;
1334 }
1335
1336 return S_OK;
1337}
1338
1340{
1341 if (!pidlOther && !m_pidl)
1342 return TRUE;
1343
1344 return (pidlOther && m_pidl && ILIsEqual(pidlOther, m_pidl));
1345}
1346
1348{
1349 return (dwVspbFlags == m_dwVspbFlags && StrCmpW(pszPath, m_pszPath) == 0 && _IsSamePidl(pidl));
1350}
1351
1353{
1354 LPCITEMIDLIST ppidlLast;
1356
1357 HRESULT hr = SHBindToParent(m_pidl, IID_IShellFolder, (void **)&psf, &ppidlLast);
1358 if (FAILED(hr))
1359 return FALSE;
1360
1361 WIN32_FIND_DATAW FindData;
1362 hr = SHGetDataFromIDListW(psf, ppidlLast, SHGDFIL_FINDDATA, &FindData, sizeof(FindData));
1363 if (FAILED(hr))
1364 return FALSE;
1365
1366 return PathIsSystemFolderW(NULL, FindData.dwFileAttributes);
1367}
1368
1370{
1371 return ((m_dwVspbFlags & SHGVSPB_FOLDER) == SHGVSPB_FOLDER);
1372}
1373
1375{
1376 if (_CanAccessPidlBag())
1377 return TRUE;
1378
1379 return ((m_dwVspbFlags & SHGVSPB_USERDEFAULTS) == SHGVSPB_USERDEFAULTS);
1380}
1381
1383{
1385 return TRUE;
1386
1387 return ((m_dwVspbFlags & SHGVSPB_ALLUSERS) && (m_dwVspbFlags & SHGVSPB_PERFOLDER));
1388}
1389
1391{
1393 return TRUE;
1394
1395 return ((m_dwVspbFlags & SHGVSPB_GLOBALDEAFAULTS) == SHGVSPB_GLOBALDEAFAULTS);
1396}
1397
1399{
1400 return (_CanAccessPidlBag() || (m_dwVspbFlags & SHGVSPB_INHERIT));
1401}
1402
1404{
1405 return StrCmpW(m_pszPath, L"Desktop") == 0;
1406}
1407
1409{
1410 if (m_dwVspbFlags & SHGVSPB_NOAUTODEFAULTS)
1411 m_bReadBag = FALSE;
1412 else if ((m_dwVspbFlags & SHGVSPB_FOLDER) == SHGVSPB_FOLDER)
1413 m_bPidlBag = FALSE;
1414 else if (m_dwVspbFlags & SHGVSPB_INHERIT)
1416 else if ((m_dwVspbFlags & SHGVSPB_USERDEFAULTS) == SHGVSPB_USERDEFAULTS)
1418 else if ((m_dwVspbFlags & SHGVSPB_ALLUSERS) && (m_dwVspbFlags & SHGVSPB_PERFOLDER))
1420 else if ((m_dwVspbFlags & SHGVSPB_GLOBALDEAFAULTS) == SHGVSPB_GLOBALDEAFAULTS)
1422}
1423
1425{
1426 if (!(dwVspbFlags & (SHGVSPB_INHERIT | SHGVSPB_PERUSER)))
1428
1429 if ((m_dwVspbFlags & SHGVSPB_ROAM) && (dwVspbFlags & SHGVSPB_PERFOLDER))
1431
1433}
1434
1436{
1437 DWORD dwValue, cbValue = sizeof(dwValue);
1438
1439 if (SHGetValueW(hKey, NULL, L"BagMRU Size", NULL, &dwValue, &cbValue) != ERROR_SUCCESS)
1440 return 400; // The default size of the MRU (most recently used) list
1441
1442 return (UINT)dwValue;
1443}
1444
1445HRESULT
1447 LPCITEMIDLIST pidl,
1448 DWORD dwMode,
1449 HKEY hKey,
1450 UINT *puSlots,
1451 UINT cSlots,
1452 UINT *pcSlots)
1453{
1454 CComPtr<IMruPidlList> pMruList;
1455 HRESULT hr = ::CoCreateInstance(CLSID_MruPidlList, NULL, CLSCTX_INPROC_SERVER,
1456 IID_IMruPidlList, (void**)&pMruList);
1457 if (FAILED(hr))
1458 return hr;
1459
1460 UINT cMRUSize = _GetMRUSize(hKey);
1461 hr = pMruList->InitList(cMRUSize, hKey, L"BagMRU");
1462 if (FAILED(hr))
1463 return hr;
1464
1465 hr = pMruList->QueryPidl(pidl, cSlots, puSlots, pcSlots);
1466 if (hr == S_OK && MODE_CAN_WRITE(dwMode))
1467 hr = pMruList->UsePidl(pidl, puSlots);
1468 else if (cSlots == 1)
1469 hr = E_FAIL;
1470
1471 return hr;
1472}
1473
1474HRESULT
1476{
1477 UINT cSlots;
1478 return _GetMRUSlots(pidl, dwMode, hKey, pSlot, 1, &cSlots);
1479}
1480
1481HRESULT
1483 LPCITEMIDLIST pidl,
1484 LPCWSTR pszBagName,
1485 DWORD dwFlags,
1486 DWORD dwMode,
1487 HKEY hKey,
1488 LPWSTR pszDest,
1489 INT cchDest)
1490{
1491 HRESULT hr = S_OK;
1492 UINT nSlot;
1493
1494 if (dwFlags & (SHGVSPB_INHERIT | SHGVSPB_PERFOLDER))
1495 {
1496 hr = _GetMRUSlot(pidl, dwMode, hKey, &nSlot);
1497 if (SUCCEEDED(hr))
1498 {
1499 if (dwFlags & SHGVSPB_INHERIT)
1500 StringCchPrintfW(pszDest, cchDest, L"Bags\\%d\\%s\\Inherit", nSlot, pszBagName);
1501 else
1502 StringCchPrintfW(pszDest, cchDest, L"Bags\\%d\\%s", nSlot, pszBagName);
1503 }
1504 }
1505 else
1506 {
1507 StringCchPrintfW(pszDest, cchDest, L"Bags\\AllFolders\\%s", pszBagName);
1508 }
1509
1510 return hr;
1511}
1512
1514{
1515 HRESULT hr = ::CreateBindCtx(0, ppbc);
1516 if (FAILED(hr))
1517 return hr;
1518
1519 IBindCtx *pbc = *ppbc;
1520
1521 BIND_OPTS opts = { sizeof(opts) };
1522 opts.grfMode = dwMode;
1523 hr = pbc->SetBindOptions(&opts);
1524 if (FAILED(hr))
1525 {
1526 pbc->Release();
1527 *ppbc = NULL;
1528 }
1529
1530 return hr;
1531}
1532
1533HRESULT
1535 LPITEMIDLIST pidl,
1536 LPCWSTR pszPath,
1537 DWORD dwVspbFlags,
1538 DWORD dwMode,
1539 REFIID riid,
1540 IPropertyBag **pppb)
1541{
1542 HRESULT hr;
1543 HKEY hKey;
1546 WCHAR szBuff[64];
1547
1548 if (MODE_CAN_WRITE(dwMode))
1549 dwMode |= STGM_CREATE;
1550
1551 if ((dwVspbFlags & SHGVSPB_ALLUSERS) && (dwVspbFlags & SHGVSPB_PERFOLDER))
1552 {
1553 hr = BindCtx_CreateWithMode(dwMode, &pBC);
1554 if (SUCCEEDED(hr))
1555 {
1556 hr = SHGetDesktopFolder(&psf);
1557 if (SUCCEEDED(hr))
1558 {
1559 hr = psf->BindToObject(m_pidl, pBC, riid, (void **)pppb);
1560 if (SUCCEEDED(hr) && !*pppb)
1561 hr = E_FAIL;
1562 }
1563 }
1564 }
1565 else
1566 {
1567 hKey = _GetHKey(dwVspbFlags);
1568 if (!hKey)
1569 return E_FAIL;
1570
1571 hr = _GetRegKey(pidl, pszPath, dwVspbFlags, dwMode, hKey, szBuff, _countof(szBuff));
1572 if (SUCCEEDED(hr))
1573 hr = SHCreatePropertyBagOnRegKey(hKey, szBuff, dwMode, riid, (void**)pppb);
1574
1576 }
1577
1578 return hr;
1579}
1580
1581HRESULT
1583{
1584 *pppb = NULL;
1585
1586 HKEY hKey = _GetHKey(SHGVSPB_INHERIT);
1587 if (!hKey)
1588 return E_FAIL;
1589
1590 UINT cSlots, anSlots[64];
1591 if (FAILED(_GetMRUSlots(m_pidl, 0, hKey, anSlots, _countof(anSlots), &cSlots)) || !cSlots)
1592 {
1594 return E_FAIL;
1595 }
1596
1597 HRESULT hr = E_FAIL;
1598 WCHAR szBuff[64];
1599 for (UINT iSlot = 0; iSlot < cSlots; ++iSlot)
1600 {
1601 StringCchPrintfW(szBuff, _countof(szBuff), L"Bags\\%d\\%s\\Inherit", anSlots[iSlot],
1602 m_pszPath);
1603 hr = SHCreatePropertyBagOnRegKey(hKey, szBuff, STGM_READ, riid, (void**)pppb);
1604 if (SUCCEEDED(hr))
1605 break;
1606 }
1607
1609 return hr;
1610}
1611
1613{
1614 if (!m_pReadBag && !m_bReadBag)
1615 {
1616 m_bReadBag = TRUE;
1618 }
1619 return (m_pReadBag != NULL);
1620}
1621
1623{
1625 {
1626 m_bPidlBag = TRUE;
1627 _CreateBag(m_pidl, m_pszPath, SHGVSPB_FOLDER, dwMode, riid, &m_pPidlBag);
1628 }
1629 return (m_pPidlBag != NULL);
1630}
1631
1633{
1635 {
1638 }
1639 return (m_pInheritBag != NULL);
1640}
1641
1643{
1645 {
1648 }
1649 return (m_pUpgradeBag != NULL);
1650}
1651
1653{
1655 {
1657 _CreateBag(NULL, m_pszPath, SHGVSPB_USERDEFAULTS, dwMode, riid, &m_pUserDefaultsBag);
1658 }
1659 return (m_pUserDefaultsBag != NULL);
1660}
1661
1663{
1665 {
1667 if (_IsSystemFolder())
1668 {
1669 _CreateBag(m_pidl, m_pszPath, SHGVSPB_PERFOLDER | SHGVSPB_ALLUSERS,
1670 dwMode, riid, &m_pFolderDefaultsBag);
1671 }
1672 }
1673 return (m_pFolderDefaultsBag != NULL);
1674}
1675
1677{
1679 {
1681 _CreateBag(NULL, m_pszPath, SHGVSPB_GLOBALDEAFAULTS, dwMode, riid, &m_pGlobalDefaultsBag);
1682 }
1683 return (m_pGlobalDefaultsBag != NULL);
1684}
1685
1686HRESULT
1688 LPCWSTR pszPropName,
1689 VARIANT *pvari,
1690 IErrorLog *pErrorLog)
1691{
1693 return E_FAIL;
1694
1695 return m_pPidlBag->Read(pszPropName, pvari, pErrorLog);
1696}
1697
1698HRESULT
1700 LPCWSTR pszPropName,
1701 VARIANT *pvari,
1702 IErrorLog *pErrorLog)
1703{
1705 return E_FAIL;
1706
1707 return m_pInheritBag->Read(pszPropName, pvari, pErrorLog);
1708}
1709
1710HRESULT
1712 LPCWSTR pszPropName,
1713 VARIANT *pvari,
1714 IErrorLog *pErrorLog)
1715{
1717 return E_FAIL;
1718
1719 return m_pUpgradeBag->Read(pszPropName, pvari, pErrorLog);
1720}
1721
1722HRESULT
1724 LPCWSTR pszPropName,
1725 VARIANT *pvari,
1726 IErrorLog *pErrorLog)
1727{
1729 return E_FAIL;
1730
1731 return m_pUserDefaultsBag->Read(pszPropName, pvari, pErrorLog);
1732}
1733
1734HRESULT
1736 LPCWSTR pszPropName,
1737 VARIANT *pvari,
1738 IErrorLog *pErrorLog)
1739{
1741 return E_FAIL;
1742
1743 return m_pFolderDefaultsBag->Read(pszPropName, pvari, pErrorLog);
1744}
1745
1746HRESULT
1748 LPCWSTR pszPropName,
1749 VARIANT *pvari,
1750 IErrorLog *pErrorLog)
1751{
1753 return E_FAIL;
1754
1755 return m_pGlobalDefaultsBag->Read(pszPropName, pvari, pErrorLog);
1756}
1757
1760 _In_z_ LPCWSTR pszPropName,
1761 _Inout_ VARIANT *pvari,
1762 _Inout_opt_ IErrorLog *pErrorLog)
1763{
1764 if ((m_dwVspbFlags & SHGVSPB_NOAUTODEFAULTS) || (m_dwVspbFlags & SHGVSPB_INHERIT))
1765 {
1767 return E_FAIL;
1768
1769 return m_pReadBag->Read(pszPropName, pvari, pErrorLog);
1770 }
1771
1772 HRESULT hr = _ReadPidlBag(pszPropName, pvari, pErrorLog);
1773 if (SUCCEEDED(hr))
1774 return hr;
1775
1776 hr = _ReadInheritBag(pszPropName, pvari, pErrorLog);
1777 if (SUCCEEDED(hr))
1778 return hr;
1779
1780 hr = _ReadUpgradeBag(pszPropName, pvari, pErrorLog);
1781 if (SUCCEEDED(hr))
1782 return hr;
1783
1784 hr = _ReadUserDefaultsBag(pszPropName, pvari, pErrorLog);
1785 if (SUCCEEDED(hr))
1786 return hr;
1787
1788 hr = _ReadFolderDefaultsBag(pszPropName, pvari, pErrorLog);
1789 if (SUCCEEDED(hr))
1790 return hr;
1791
1792 return _ReadGlobalDefaultsBag(pszPropName, pvari, pErrorLog);
1793}
1794
1796{
1797 HKEY hKey = _GetHKey(SHGVSPB_INHERIT);
1798 if (!hKey)
1799 return;
1800
1801 CComPtr<IMruPidlList> pMruList;
1802 HRESULT hr = ::CoCreateInstance(CLSID_MruPidlList, NULL, CLSCTX_INPROC_SERVER,
1803 IID_IMruPidlList, (void**)&pMruList);
1804 if (SUCCEEDED(hr))
1805 {
1806 hr = pMruList->InitList(200, hKey, L"BagMRU");
1807 if (SUCCEEDED(hr))
1808 pMruList->PruneKids(m_pidl);
1809 }
1810
1812}
1813
1815{
1816 if (!m_pWriteBag && !m_bWriteBag)
1817 {
1818 m_bWriteBag = TRUE;
1820 if (m_pWriteBag)
1821 {
1823 if (m_dwVspbFlags & SHGVSPB_INHERIT)
1824 _PruneMRUTree();
1825 }
1826 }
1827 return (m_pWriteBag != NULL);
1828}
1829
1831{
1833 return E_FAIL;
1834
1835 return m_pWriteBag->Write(pszPropName, pvari);
1836}
1837
1839{
1840 STRRET strret;
1842 WCHAR szBuff[MAX_PATH];
1843 LPCITEMIDLIST ppidlLast;
1844 INT iDrive, nType;
1845 HRESULT hr;
1846
1847 hr = SHBindToParent(pidl, IID_IShellFolder, (void **)&psf, &ppidlLast);
1848 if (FAILED(hr))
1849 return FALSE;
1850
1851 hr = psf->GetDisplayNameOf(ppidlLast, SHGDN_FORPARSING, &strret);
1852 if (FAILED(hr))
1853 return FALSE;
1854
1855 hr = StrRetToBufW(&strret, ppidlLast, szBuff, _countof(szBuff));
1856 if (FAILED(hr))
1857 return FALSE;
1858
1859 iDrive = PathGetDriveNumberW(szBuff);
1860 if (iDrive < 0)
1861 return FALSE;
1862
1863 nType = RealDriveType(iDrive, FALSE);
1864 return (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM);
1865}
1866
1867/**************************************************************************
1868 * SHGetViewStatePropertyBag (SHLWAPI.515)
1869 *
1870 * Retrieves a property bag in which the view state information of a folder
1871 * can be stored.
1872 *
1873 * @param pidl PIDL of the folder requested
1874 * @param bag_name Name of the property bag requested
1875 * @param flags Optional SHGVSPB_... flags
1876 * @param riid IID of requested property bag interface
1877 * @param ppv Address to receive pointer to the new interface
1878 * @return An HRESULT value. S_OK on success, non-zero on failure.
1879 * @see https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shgetviewstatepropertybag
1880 */
1884 _In_opt_ LPCWSTR bag_name,
1887 _Outptr_ void **ppv)
1888{
1889 HRESULT hr;
1890
1891 TRACE("%p %s 0x%X %p %p\n", pidl, debugstr_w(bag_name), flags, &riid, ppv);
1892
1893 *ppv = NULL;
1894
1896
1897 if (g_pCachedBag && g_pCachedBag->IsSameBag(pidl, bag_name, flags))
1898 {
1899 hr = g_pCachedBag->QueryInterface(riid, ppv);
1901 return hr;
1902 }
1903
1904 if (SHIsRemovableDrive(pidl))
1905 {
1906 TRACE("pidl %p is removable\n", pidl);
1908 return E_FAIL;
1909 }
1910
1912
1913 hr = pBag->Init(pidl, bag_name, flags);
1914 if (FAILED(hr))
1915 {
1916 ERR("0x%08X\n", hr);
1918 return hr;
1919 }
1920
1921 g_pCachedBag.Attach(pBag);
1922
1923 hr = g_pCachedBag->QueryInterface(riid, ppv);
1924
1926 return hr;
1927}
1928
1930{
1932 g_pCachedBag.Release();
1934}
1935
1936/**************************************************************************
1937 * SHGetPerScreenResName (SHLWAPI.533)
1938 *
1939 * @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/propbag/getperscreenresname.htm
1940 */
1943 _Out_writes_(cchBuffer) LPWSTR pszBuffer,
1946{
1947 if (dwReserved)
1948 return 0;
1949
1950 HDC hDC = ::GetDC(NULL);
1951 INT cxWidth = ::GetDeviceCaps(hDC, HORZRES);
1952 INT cyHeight = ::GetDeviceCaps(hDC, VERTRES);
1953 INT cMonitors = ::GetSystemMetrics(SM_CMONITORS);
1955
1956 StringCchPrintfW(pszBuffer, cchBuffer, L"%dx%d(%d)", cxWidth, cyHeight, cMonitors);
1957 return lstrlenW(pszBuffer);
1958}
1959
1960/**************************************************************************
1961 * IUnknown_QueryServicePropertyBag (SHLWAPI.536)
1962 *
1963 * @param punk An IUnknown interface.
1964 * @param flags The SHGVSPB_... flags of SHGetViewStatePropertyBag.
1965 * @param riid IID of requested property bag interface.
1966 * @param ppvObj Address to receive pointer to the new interface.
1967 * @return An HRESULT value. S_OK on success, non-zero on failure.
1968 * @see https://geoffchappell.com/studies/windows/shell/shlwapi/api/util/iunknown/queryservicepropertybag.htm
1969 */
1972 _In_ IUnknown *punk,
1973 _In_ long flags,
1975 _Outptr_ void **ppvObj)
1976{
1977 TRACE("%p 0x%x %p %p\n", punk, flags, &riid, ppvObj);
1978
1980 HRESULT hr = IUnknown_QueryService(punk, SID_STopLevelBrowser, IID_IShellBrowserService,
1981 (void **)&pService);
1982 if (FAILED(hr))
1983 {
1984 ERR("0x%X\n", hr);
1985 return hr;
1986 }
1987
1988 return pService->GetPropertyBag(flags, riid, ppvObj);
1989}
static HDC hDC
Definition: 3dtext.c:33
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
#define ERR(fmt,...)
Definition: debug.h:110
#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:44
CBasePropertyBag(DWORD dwMode)
Definition: propbag.cpp:38
STDMETHODIMP_(ULONG) AddRef() override
Definition: propbag.cpp:70
STDMETHODIMP_(ULONG) Release() override
Definition: propbag.cpp:74
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
Definition: propbag.cpp:47
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:1028
HRESULT _ReadFlags(VARIANT *pvari)
Definition: propbag.cpp:1050
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:1164
IStream * _GetOldDesktopViewStream()
Definition: propbag.cpp:1116
VOID _MarkAsUpgraded(HKEY hkey)
Definition: propbag.cpp:1035
IStream * _NewStreamFromOld(IStream *pOldStream)
Definition: propbag.cpp:1076
HRESULT _ReadItemPositions(VARIANT *pvari)
Definition: propbag.cpp:1144
BOOL _AlreadyUpgraded(HKEY hKey)
Definition: propbag.cpp:1041
bool Allocate(_In_ size_t nElements=1)
Definition: atlalloc.h:143
LPWSTR m_pszFileName
Definition: propbag.cpp:763
static BOOL LooksLikeAnAlternateStream(LPCWSTR pszStart)
Definition: propbag.cpp:767
LPWSTR m_pszSection
Definition: propbag.cpp:764
BOOL m_bAlternateStream
Definition: propbag.cpp:765
HRESULT Init(LPCWSTR pszIniFile, LPCWSTR pszSection)
Definition: propbag.cpp:808
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:856
CIniPropertyBag(DWORD dwMode)
Definition: propbag.cpp:784
HRESULT _GetSectionAndName(LPCWSTR pszStart, LPWSTR pszSection, UINT cchSectionMax, LPWSTR pszName, UINT cchNameMax)
Definition: propbag.cpp:828
~CIniPropertyBag() override
Definition: propbag.cpp:792
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:899
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:152
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:204
ATL::CSimpleMap< ATL::CStringW, ATL::CComVariant, CPropMapEqual > m_PropMap
Definition: propbag.cpp:141
CMemPropertyBag(DWORD dwMode)
Definition: propbag.cpp:144
HRESULT _ReadDword(LPCWSTR pszPropName, VARIANT *pvari)
Definition: propbag.cpp:321
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:488
CRegPropertyBag(DWORD dwMode)
Definition: propbag.cpp:279
HRESULT _ReadBinary(LPCWSTR pszPropName, VARIANT *pvari, VARTYPE vt, DWORD uBytes)
Definition: propbag.cpp:361
HRESULT _ReadStream(VARIANT *pvari, BYTE *pInit, UINT cbInit)
Definition: propbag.cpp:350
HRESULT Init(HKEY hKey, LPCWSTR lpSubKey)
Definition: propbag.cpp:298
HRESULT _ReadString(LPCWSTR pszPropName, VARIANTARG *pvarg, UINT len)
Definition: propbag.cpp:332
HRESULT _CopyStreamIntoBuff(IStream *pStream, void *pv, ULONG cb)
Definition: propbag.cpp:386
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:413
HRESULT _GetStreamSize(IStream *pStream, LPDWORD pcbSize)
Definition: propbag.cpp:396
~CRegPropertyBag() override
Definition: propbag.cpp:285
HRESULT _WriteStream(LPCWSTR pszPropName, IStream *pStream)
Definition: propbag.cpp:464
HRESULT _ReadGlobalDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1747
BOOL _EnsureGlobalDefaultsBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1676
BOOL _CanAccessGlobalDefaultsBag() const
Definition: propbag.cpp:1390
HRESULT _GetMRUSlot(LPCITEMIDLIST pidl, DWORD dwMode, HKEY hKey, UINT *pSlot)
Definition: propbag.cpp:1475
BOOL _EnsureUserDefaultsBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1652
BOOL _CanAccessInheritBag() const
Definition: propbag.cpp:1398
HRESULT _ReadInheritBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1699
BOOL _EnsureInheritBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1632
BOOL _CanAccessFolderDefaultsBag() const
Definition: propbag.cpp:1382
BOOL _CanAccessUpgradeBag() const
Definition: propbag.cpp:1403
BOOL _EnsureReadBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1612
CComPtr< IPropertyBag > m_pWriteBag
Definition: propbag.cpp:1217
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override
Definition: propbag.cpp:1830
STDMETHODIMP Read(_In_z_ LPCWSTR pszPropName, _Inout_ VARIANT *pvari, _Inout_opt_ IErrorLog *pErrorLog) override
Definition: propbag.cpp:1759
LPITEMIDLIST m_pidl
Definition: propbag.cpp:1207
BOOL _CanAccessUserDefaultsBag() const
Definition: propbag.cpp:1374
CComPtr< IPropertyBag > m_pUpgradeBag
Definition: propbag.cpp:1211
BOOL _CanAccessPidlBag() const
Definition: propbag.cpp:1369
HRESULT _FindNearestInheritBag(REFIID riid, IPropertyBag **pppb)
Definition: propbag.cpp:1582
HRESULT _ReadPidlBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1687
CComPtr< IPropertyBag > m_pInheritBag
Definition: propbag.cpp:1212
HRESULT _GetRegKey(LPCITEMIDLIST pidl, LPCWSTR pszBagName, DWORD dwFlags, DWORD dwMode, HKEY hKey, LPWSTR pszDest, INT cchDest)
Definition: propbag.cpp:1482
HRESULT _ReadFolderDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1735
CComPtr< IPropertyBag > m_pFolderDefaultsBag
Definition: propbag.cpp:1214
CComPtr< IPropertyBag > m_pReadBag
Definition: propbag.cpp:1216
~CViewStatePropertyBag() override
Definition: propbag.cpp:1290
HKEY _GetHKey(DWORD dwVspbFlags)
Definition: propbag.cpp:1424
HRESULT _GetMRUSlots(LPCITEMIDLIST pidl, DWORD dwMode, HKEY hKey, UINT *puSlots, UINT cSlots, UINT *pcSlots)
Definition: propbag.cpp:1446
BOOL _EnsurePidlBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1622
CComPtr< IPropertyBag > m_pPidlBag
Definition: propbag.cpp:1210
CComPtr< IPropertyBag > m_pGlobalDefaultsBag
Definition: propbag.cpp:1215
BOOL IsSameBag(LPCITEMIDLIST pidl, LPCWSTR pszPath, DWORD dwVspbFlags) const
Definition: propbag.cpp:1347
BOOL _EnsureFolderDefaultsBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1662
BOOL _EnsureWriteBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1814
BOOL _IsSamePidl(LPCITEMIDLIST pidlOther) const
Definition: propbag.cpp:1339
UINT _GetMRUSize(HKEY hKey)
Definition: propbag.cpp:1435
CComPtr< IPropertyBag > m_pUserDefaultsBag
Definition: propbag.cpp:1213
BOOL _IsSystemFolder() const
Definition: propbag.cpp:1352
BOOL _EnsureUpgradeBag(DWORD dwMode, REFIID riid)
Definition: propbag.cpp:1642
HRESULT _CreateBag(LPITEMIDLIST pidl, LPCWSTR pszPath, DWORD dwVspbFlags, DWORD dwMode, REFIID riid, IPropertyBag **pppb)
Definition: propbag.cpp:1534
HRESULT _ReadUpgradeBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1711
HRESULT Init(_In_opt_ LPCITEMIDLIST pidl, _In_opt_ LPCWSTR pszPath, _In_ DWORD dwVspbFlags)
Definition: propbag.cpp:1315
HRESULT _ReadUserDefaultsBag(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog)
Definition: propbag.cpp:1723
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
#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
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:468
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:556
INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:504
#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
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:86
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI IStream_Size(IStream *lpStream, ULARGE_INTEGER *lpulSize)
Definition: istream.c:661
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1497
HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create)
Definition: ordinal.c:4585
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:553
BOOL WINAPI PathMakeSystemFolderW(LPCWSTR lpszPath)
Definition: path.c:3120
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
BOOL WINAPI PathIsSystemFolderW(LPCWSTR lpszPath, DWORD dwAttrib)
Definition: path.c:2218
DWORD WINAPI SHDeleteValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue)
Definition: reg.c:1762
DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1236
DWORD WINAPI SHSetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, DWORD dwType, LPCVOID pvData, DWORD cbData)
Definition: reg.c:1306
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1530
LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count)
Definition: string.c:536
int WINAPI StrCmpW(LPCWSTR lpszStr, LPCWSTR lpszComp)
Definition: string.c:434
LPWSTR WINAPI StrDupW(LPCWSTR lpszStr)
Definition: string.c:1093
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
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
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define DRIVE_CDROM
Definition: machpc98.h:119
#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:92
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
@ SHKEY_Root_HKLM
Definition: ordinal.c:2805
@ SHKEY_Key_ShellNoRoam
Definition: ordinal.c:2808
@ SHKEY_Root_HKCU
Definition: ordinal.c:2804
@ SHKEY_Key_Shell
Definition: ordinal.c:2807
#define min(a, b)
Definition: monoChain.cc:55
#define _Post_z_
Definition: ms_sal.h:691
#define _Inout_
Definition: ms_sal.h:378
#define _In_z_
Definition: ms_sal.h:313
#define _In_opt_z_
Definition: ms_sal.h:314
#define _Outptr_
Definition: ms_sal.h:427
#define _Out_writes_(size)
Definition: ms_sal.h:348
#define _Inout_opt_
Definition: ms_sal.h:379
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define _Out_writes_to_(size, count)
Definition: ms_sal.h:355
_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
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
#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:1031
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define L(x)
Definition: ntvdm.h:50
#define STGM_CREATE
Definition: objbase.h:926
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
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
long LONG
Definition: pedump.c:60
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:938
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1361
HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
Definition: pidl.c:1221
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:548
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:1882
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:658
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:748
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:602
DWORDLONG DESKVIEW_FLAGS
Definition: propbag.cpp:1048
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:722
EXTERN_C HRESULT WINAPI SHCreatePropertyBagOnRegKey(_In_ HKEY hKey, _In_z_ LPCWSTR pszSubKey, _In_ DWORD dwMode, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: propbag.cpp:575
struct tagOLD_STREAM_HEADER * POLD_STREAM_HEADER
static BOOL Is7BitClean(LPCWSTR psz)
Definition: propbag.cpp:638
#define MODE_CAN_WRITE(dwMode)
Definition: propbag.cpp:24
HRESULT SHGetDesktopUpgradePropertyBag(REFIID riid, void **ppvObj)
Definition: propbag.cpp:1197
struct tagOLD_STREAM_HEADER OLD_STREAM_HEADER
static HRESULT BindCtx_CreateWithMode(DWORD dwMode, IBindCtx **ppbc)
Definition: propbag.cpp:1513
#define MODE_CAN_READ(dwMode)
Definition: propbag.cpp:22
EXTERN_C VOID FreeViewStatePropertyBagCache(VOID)
Definition: propbag.cpp:1929
static BOOL SHIsRemovableDrive(LPCITEMIDLIST pidl)
Definition: propbag.cpp:1838
EXTERN_C INT WINAPI SHGetPerScreenResName(_Out_writes_(cchBuffer) LPWSTR pszBuffer, _In_ INT cchBuffer, _In_ DWORD dwReserved)
Definition: propbag.cpp:1942
CRITICAL_SECTION g_csBagCacheLock
Definition: propbag.cpp:1311
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:965
EXTERN_C HRESULT WINAPI IUnknown_QueryServicePropertyBag(_In_ IUnknown *punk, _In_ long flags, _In_ REFIID riid, _Outptr_ void **ppvObj)
Definition: propbag.cpp:1971
CComPtr< CViewStatePropertyBag > g_pCachedBag
Definition: propbag.cpp:1308
EXTERN_C HRESULT WINAPI SHCreatePropertyBagOnMemory(_In_ DWORD dwMode, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: propbag.cpp:254
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
IStream *WINAPI SHOpenRegStream2W(HKEY hKey, LPCWSTR pszSubkey, LPCWSTR pszValue, DWORD dwMode)
Definition: regstream.c:537
IStream *WINAPI SHCreateMemStream(const BYTE *lpbData, UINT dwDataLen)
Definition: regstream.c:652
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
EXTERN_C INT WINAPI RealDriveType(INT drive, BOOL bQueryNet)
Definition: shlfileop.cpp:2222
HRESULT hr
Definition: shlfolder.c:183
#define SHGDFIL_FINDDATA
Definition: shlobj.h:1443
#define SHCNE_UPDATEITEM
Definition: shlobj.h:1888
#define SHCNF_PATHW
Definition: shlobj.h:1910
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:68
#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:127
static bool IsEqualValue(const ATL::CComVariant &v1, const ATL::CComVariant &v2)
Definition: propbag.cpp:132
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
unsigned char * LPBYTE
Definition: typedefs.h:53
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
int ret
#define LMEM_ZEROINIT
Definition: winbase.h:375
_In_ LPCSTR lpFileName
Definition: winbase.h:3071
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2084
#define DRIVE_REMOVABLE
Definition: winbase.h:251
_In_ DWORD cbBinary
Definition: wincrypt.h:4503
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_updates_bytes_to_ pdwDataLen BYTE * pbData
Definition: wincrypt.h:4201
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#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:235
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:69
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HDC WINAPI GetDC(_In_opt_ HWND)
#define SM_CMONITORS
Definition: winuser.h:1040
int WINAPI GetSystemMetrics(_In_ int)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__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