ReactOS 0.4.16-dev-1493-ge7358c5
SHPropertyBag.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Tests for SHPropertyBag Read/Write
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include <apitest.h>
9#include <shlwapi.h>
10#include <shlobj.h>
11#include <stdio.h>
12#include <shlwapi_undoc.h>
13#include <versionhelpers.h>
14#include <strsafe.h>
15
16#include <pseh/pseh2.h>
17
20static INT s_cRead = 0;
21static INT s_cWrite = 0;
22
23static void ResetTest(VARTYPE vt,
24 LPCWSTR pszName0 = NULL, LPCWSTR pszName1 = NULL,
25 LPCWSTR pszName2 = NULL, LPCWSTR pszName3 = NULL)
26{
27 s_vt = vt;
28 s_cRead = s_cWrite = 0;
29 s_pszPropNames[0] = pszName0;
30 s_pszPropNames[1] = pszName1;
31 s_pszPropNames[2] = pszName2;
32 s_pszPropNames[3] = pszName3;
33}
34
35static SAFEARRAY* CreateByteArray(LPCVOID pvSrc, DWORD cbSize)
36{
37 SAFEARRAYBOUND Bound;
38 Bound.lLbound = 0;
39 Bound.cElements = cbSize;
40
41 SAFEARRAY* pArray = SafeArrayCreate(VT_UI1, 1, &Bound);
42 if (!pArray)
43 return NULL;
44
45 void HUGEP *pvData;
47 if (FAILED(hr))
48 {
49 SafeArrayDestroy(pArray);
50 return NULL;
51 }
52
53 CopyMemory(pvData, pvSrc, cbSize);
55
56 return pArray;
57}
58
60{
61public:
63 {
64 }
65
66 // IUnknown
67 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
68 {
69 ok(FALSE, "Unexpected call\n");
70 return S_OK;
71 }
73 {
74 ok(FALSE, "Unexpected call\n");
75 return S_OK;
76 }
78 {
79 ok(FALSE, "Unexpected call\n");
80 return S_OK;
81 }
82
83 // IPropertyBag
84 STDMETHODIMP Read(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog) override
85 {
86 ++s_cRead;
87 ok_int(s_vt, V_VT(pvari));
88 for (size_t i = 0; i < _countof(s_pszPropNames); ++i)
89 {
90 if (s_pszPropNames[i])
91 {
92 ok_wstr(pszPropName, s_pszPropNames[i]);
94
95 if (lstrcmpiW(pszPropName, L"RECTL2.top") == 0)
96 return E_FAIL;
97
98 if (lstrcmpiW(pszPropName, L"Str1") == 0)
99 {
100 V_VT(pvari) = VT_BSTR;
101 V_BSTR(pvari) = SysAllocString(L"TestString");
102 return S_OK;
103 }
104
105 if (lstrcmpiW(pszPropName, L"GUID1") == 0)
106 {
107 V_VT(pvari) = (VT_UI1 | VT_ARRAY);
108 V_ARRAY(pvari) = CreateByteArray(&IID_IShellLinkW, sizeof(IID));
109 return S_OK;
110 }
111
112 if (lstrcmpiW(pszPropName, L"GUID2") == 0)
113 {
114 WCHAR szText[50];
115 StringFromGUID2(IID_IUnknown, szText, _countof(szText));
116
117 V_VT(pvari) = VT_BSTR;
118 V_BSTR(pvari) = SysAllocString(szText);
119 return S_OK;
120 }
121
122 if (lstrcmpiW(pszPropName, L"GUID3") == 0)
123 {
124 V_VT(pvari) = VT_EMPTY;
125 V_UI4(pvari) = 0xDEADFACE;
126 return S_OK;
127 }
128
129 goto Skip1;
130 }
131 }
132 ok(FALSE, "Unexpected call\n");
133Skip1:
134 return S_OK;
135 }
136
137 STDMETHODIMP Write(LPCWSTR pszPropName, VARIANT *pvari) override
138 {
139 ++s_cWrite;
140 ok_int(s_vt, V_VT(pvari));
141 for (size_t i = 0; i < _countof(s_pszPropNames); ++i)
142 {
143 if (s_pszPropNames[i])
144 {
145 ok_wstr(pszPropName, s_pszPropNames[i]);
147 if (lstrcmpiW(pszPropName, L"RECTL2.bottom") == 0)
148 {
149 s_vt = VT_EMPTY;
151 s_pszPropNames[0] = L"RECTL2.right";
152 return E_FAIL;
153 }
154 goto Skip2;
155 }
156 }
157 ok(FALSE, "Unexpected call\n");
158Skip2:
159 return S_OK;
160 }
161};
162
163static void SHPropertyBag_ReadTest(void)
164{
165 HRESULT hr;
167 BOOL bValue = 0xDEADFACE;
168 SHORT sValue = 0xDEADu;
169 LONG lValue = 0xDEADDEAD;
170 DWORD dwValue = 0xFEEDF00D;
171 BSTR bstr = NULL;
172 POINTL ptl = { 0xEEEE, 0xDDDD };
173 POINTS pts = { 0x2222, 0x3333 };
174 RECTL rcl = { 123, 456, 789, 101112 };
175 GUID guid = { 0 };
176
177 ResetTest(VT_BOOL, L"BOOL1");
179 ok_long(hr, S_OK);
180 ok_int(s_cRead, 1);
181 ok_int(s_cWrite, 0);
182
183 ResetTest(VT_UI2, L"SHORT1");
185 ok_long(hr, S_OK);
186 ok_int(s_cRead, 1);
187 ok_int(s_cWrite, 0);
188
189 ResetTest(VT_I4, L"LONG1");
191 ok_long(hr, S_OK);
192 ok_int(s_cRead, 1);
193 ok_int(s_cWrite, 0);
194
195 ResetTest(VT_UI4, L"DWORD1");
197 ok_long(hr, S_OK);
198 ok_int(s_cRead, 1);
199 ok_int(s_cWrite, 0);
200
201 ResetTest(VT_BSTR, L"Str1");
203 ok_long(hr, S_OK);
204 ok_int(s_cRead, 1);
205 ok_int(s_cWrite, 0);
206 SysFreeString(bstr);
207
208 ResetTest(VT_I4, L"POINTL1.x", L"POINTL1.y");
209 hr = SHPropertyBag_ReadPOINTL(&dummy, L"POINTL1", &ptl);
210 ok_long(hr, S_OK);
211 ok_int(s_cRead, 2);
212 ok_int(s_cWrite, 0);
213
214 ResetTest(VT_I4, L"POINTS1.x", L"POINTS1.y");
215 hr = SHPropertyBag_ReadPOINTS(&dummy, L"POINTS1", &pts);
216 ok_long(hr, S_OK);
217 ok_int(s_cRead, 2);
218 ok_int(s_cWrite, 0);
219
220 ResetTest(VT_I4, L"RECTL1.left", L"RECTL1.top", L"RECTL1.right", L"RECTL1.bottom");
221 hr = SHPropertyBag_ReadRECTL(&dummy, L"RECTL1", &rcl);
222 ok_long(hr, S_OK);
223 ok_int(s_cRead, 4);
224 ok_int(s_cWrite, 0);
225
226 ResetTest(VT_I4, L"RECTL2.left", L"RECTL2.top", L"RECTL2.right", L"RECTL2.bottom");
227 hr = SHPropertyBag_ReadRECTL(&dummy, L"RECTL2", &rcl);
228 ok_long(hr, E_FAIL);
229 ok_int(s_cRead, 2);
230 ok_int(s_cWrite, 0);
231
232 ResetTest(VT_EMPTY, L"GUID1");
233 hr = SHPropertyBag_ReadGUID(&dummy, L"GUID1", &guid);
234 ok_long(hr, S_OK);
235 ok_int(s_cRead, 1);
236 ok_int(s_cWrite, 0);
237 ok_int(IsEqualGUID(guid, IID_IShellLinkW), TRUE);
238
239 ResetTest(VT_EMPTY, L"GUID2");
240 hr = SHPropertyBag_ReadGUID(&dummy, L"GUID2", &guid);
241 ok_long(hr, S_OK);
242 ok_int(s_cRead, 1);
243 ok_int(s_cWrite, 0);
245
246 ResetTest(VT_EMPTY, L"GUID3");
248 hr = SHPropertyBag_ReadGUID(&dummy, L"GUID3", &guid);
249
252 else
253 ok_long(hr, S_OK);
254
255 ok_int(s_cRead, 1);
256 ok_int(s_cWrite, 0);
258}
259
260static void SHPropertyBag_WriteTest(void)
261{
262 HRESULT hr;
264
265 ResetTest(VT_EMPTY, L"EMPTY1");
267 ok_long(hr, S_OK);
268 ok_int(s_cRead, 0);
269 ok_int(s_cWrite, 1);
270
271 ResetTest(VT_BOOL, L"BOOL1");
273 ok_long(hr, S_OK);
274 ok_int(s_cRead, 0);
275 ok_int(s_cWrite, 1);
276
277 ResetTest(VT_UI2, L"SHORT1");
279 ok_long(hr, S_OK);
280 ok_int(s_cRead, 0);
281 ok_int(s_cWrite, 1);
282
283 ResetTest(VT_I4, L"LONG1");
285 ok_long(hr, S_OK);
286 ok_int(s_cRead, 0);
287 ok_int(s_cWrite, 1);
288
289 ResetTest(VT_UI4, L"DWORD1");
291 ok_long(hr, S_OK);
292 ok_int(s_cRead, 0);
293 ok_int(s_cWrite, 1);
294
295 ResetTest(VT_BSTR, L"Str1");
297 ok_long(hr, S_OK);
298 ok_int(s_cRead, 0);
299 ok_int(s_cWrite, 1);
300
301 ResetTest(VT_I4, L"POINTL1.x", L"POINTL1.y");
302 POINTL ptl = { 0xEEEE, 0xDDDD };
303 hr = SHPropertyBag_WritePOINTL(&dummy, L"POINTL1", &ptl);
304 ok_long(hr, S_OK);
305 ok_int(s_cRead, 0);
306 ok_int(s_cWrite, 2);
307
308 ResetTest(VT_I4, L"POINTS1.x", L"POINTS1.y");
309 POINTS pts = { 0x2222, 0x3333 };
310 hr = SHPropertyBag_WritePOINTS(&dummy, L"POINTS1", &pts);
311 ok_long(hr, S_OK);
312 ok_int(s_cRead, 0);
313 ok_int(s_cWrite, 2);
314
315 ResetTest(VT_I4, L"RECTL1.left", L"RECTL1.top", L"RECTL1.right", L"RECTL1.bottom");
316 RECTL rcl = { 123, 456, 789, 101112 };
317 hr = SHPropertyBag_WriteRECTL(&dummy, L"RECTL1", &rcl);
318 ok_long(hr, S_OK);
319 ok_int(s_cRead, 0);
320 ok_int(s_cWrite, 4);
321
322 ResetTest(VT_I4, L"RECTL2.left", L"RECTL2.top", L"RECTL2.right", L"RECTL2.bottom");
323 hr = SHPropertyBag_WriteRECTL(&dummy, L"RECTL2", &rcl);
324 ok_long(hr, S_OK);
325 ok_int(s_cRead, 0);
326 ok_int(s_cWrite, 5);
327
328 GUID guid;
329 ZeroMemory(&guid, sizeof(guid));
330 ResetTest(VT_BSTR, L"GUID1");
331 hr = SHPropertyBag_WriteGUID(&dummy, L"GUID1", &guid);
332 ok_long(hr, S_OK);
333 ok_int(s_cRead, 0);
334 ok_int(s_cWrite, 1);
335}
336
337static void SHPropertyBag_OnMemory(void)
338{
339 HRESULT hr;
340 VARIANT vari;
341
342 IPropertyBag *pPropBag = NULL;
344 ok_long(hr, S_OK);
345 if (pPropBag == NULL)
346 {
347 skip("pPropBag was NULL\n");
348 return;
349 }
350
351 VariantInit(&vari);
352 hr = pPropBag->Read(L"InvalidName", &vari, NULL);
353 ok_long(hr, E_FAIL);
354 VariantClear(&vari);
355
356 VariantInit(&vari);
357 V_VT(&vari) = VT_UI4;
358 V_UI4(&vari) = 0xDEADFACE;
359 hr = pPropBag->Write(L"Name1", &vari);
360 ok_long(hr, S_OK);
361 VariantClear(&vari);
362
363 VariantInit(&vari);
364 hr = pPropBag->Read(L"Name1", &vari, NULL);
365 ok_long(hr, S_OK);
366 ok_long(V_VT(&vari), VT_UI4);
367 ok_long(V_UI4(&vari), 0xDEADFACE);
368 VariantClear(&vari);
369
370 pPropBag->Release();
371 pPropBag = NULL;
372
374 ok_long(hr, S_OK);
375
376 VariantInit(&vari);
377 V_VT(&vari) = VT_UI4;
378 V_UI4(&vari) = 0xDEADFACE;
379 hr = pPropBag->Write(L"Name1", &vari);
381 VariantClear(&vari);
382
383 VariantInit(&vari);
384 V_VT(&vari) = VT_UI4;
385 V_UI4(&vari) = 0xFEEDF00D;
386 hr = pPropBag->Read(L"Name1", &vari, NULL);
388 {
389 ok_long(hr, S_OK);
390 ok_int(V_VT(&vari), VT_UI4);
391 ok_long(V_UI4(&vari), 0xDEADFACE);
392 }
393 else
394 {
395 ok_long(hr, E_FAIL);
396 ok_int(V_VT(&vari), VT_EMPTY);
397 ok_long(V_UI4(&vari), 0xFEEDF00D);
398 }
399 VariantClear(&vari);
400
401 pPropBag->Release();
402 pPropBag = NULL;
403
405 ok_long(hr, S_OK);
406
407 VariantInit(&vari);
408 V_VT(&vari) = VT_UI4;
409 V_UI4(&vari) = 0xDEADFACE;
410 hr = pPropBag->Write(L"Name1", &vari);
411 ok_long(hr, S_OK);
412 VariantClear(&vari);
413
414 VariantInit(&vari);
415 V_VT(&vari) = VT_UI4;
416 V_UI4(&vari) = 0xFEEDF00D;
417 hr = pPropBag->Read(L"Name1", &vari, NULL);
419 {
420 ok_long(hr, S_OK);
421 ok_int(V_VT(&vari), VT_UI4);
422 ok_long(V_UI4(&vari), 0xDEADFACE);
423 }
424 else
425 {
427 ok_int(V_VT(&vari), VT_EMPTY);
428 ok_long(V_UI4(&vari), 0xFEEDF00D);
429 }
430 VariantClear(&vari);
431
432 pPropBag->Release();
433
434 hr = SHCreatePropertyBagOnMemory(STGM_READWRITE, IID_IPropertyBag2, (void**)&pPropBag);
436 {
438 }
439 else
440 {
441 ok_long(hr, S_OK);
442 pPropBag->Release();
443 }
444
445 hr = SHCreatePropertyBagOnMemory(STGM_READ, IID_IPropertyBag2, (void**)&pPropBag);
447 {
449 }
450 else
451 {
452 ok_long(hr, S_OK);
453 pPropBag->Release();
454 }
455
456 hr = SHCreatePropertyBagOnMemory(STGM_WRITE, IID_IPropertyBag2, (void**)&pPropBag);
458 {
460 }
461 else
462 {
463 ok_long(hr, S_OK);
464 pPropBag->Release();
465 }
466}
467
468static void SHPropertyBag_OnRegKey(void)
469{
470 HKEY hKey, hSubKey;
471 LONG error;
472 VARIANT vari;
473 WCHAR szText[MAX_PATH];
474 IStream *pStream;
475 GUID guid;
476 BYTE guid_and_extra[sizeof(GUID) + sizeof(GUID)];
477
478 // Create HKCU\Software\ReactOS registry key
479 error = RegCreateKeyW(HKEY_CURRENT_USER, L"Software\\ReactOS", &hKey);
480 if (error)
481 {
482 skip("FAILED to create HKCU\\Software\\ReactOS\n");
483 return;
484 }
485
486 IPropertyBag *pPropBag;
487 HRESULT hr;
488
489 // Try to create new registry key
490 RegDeleteKeyW(hKey, L"PropBagTest");
491 hr = SHCreatePropertyBagOnRegKey(hKey, L"PropBagTest", 0,
492 IID_IPropertyBag, (void **)&pPropBag);
494
495 // Try to create new registry key
496 RegDeleteKeyW(hKey, L"PropBagTest");
498 IID_IPropertyBag, (void **)&pPropBag);
500
501 // Create new registry key
502 RegDeleteKeyW(hKey, L"PropBagTest");
504 IID_IPropertyBag, (void **)&pPropBag);
505 if (FAILED(hr))
506 {
507 skip("SHCreatePropertyBagOnRegKey FAILED\n");
509 return;
510 }
511
512 // Write UI4
513 VariantInit(&vari);
514 V_VT(&vari) = VT_UI4;
515 V_UI4(&vari) = 0xDEADFACE;
516 hr = pPropBag->Write(L"Name1", &vari);
517 ok_long(hr, S_OK);
518 VariantClear(&vari);
519
520 // Read UI4
521 VariantInit(&vari);
522 hr = pPropBag->Read(L"Name1", &vari, NULL);
523 ok_long(hr, S_OK);
524 ok_long(V_VT(&vari), VT_UI4);
525 ok_long(V_UI4(&vari), 0xDEADFACE);
526 VariantClear(&vari);
527
528 // Write BSTR
529 VariantInit(&vari);
530 V_VT(&vari) = VT_BSTR;
531 V_BSTR(&vari) = SysAllocString(L"StrValue");
532 hr = pPropBag->Write(L"Name2", &vari);
533 ok_long(hr, S_OK);
534 VariantClear(&vari);
535
536 // Read BSTR
537 VariantInit(&vari);
538 V_VT(&vari) = VT_BSTR;
539 hr = pPropBag->Read(L"Name2", &vari, NULL);
540 ok_long(hr, S_OK);
541 ok_long(V_VT(&vari), VT_BSTR);
542 ok_wstr(V_BSTR(&vari), L"StrValue");
543 VariantClear(&vari);
544
545 // Write GUID
546 VariantInit(&vari);
547 V_VT(&vari) = VT_UNKNOWN;
548 V_UNKNOWN(&vari) = SHCreateMemStream((BYTE*)&IID_IShellLinkW, sizeof(IID_IShellLinkW));
549 hr = pPropBag->Write(L"Name4", &vari);
550 ok_long(hr, S_OK);
551 VariantClear(&vari);
552
553 // Read GUID
554 VariantInit(&vari);
555 V_VT(&vari) = VT_EMPTY;
556 hr = pPropBag->Read(L"Name4", &vari, NULL);
558 {
559 ok_long(hr, S_OK);
560 ok_long(V_VT(&vari), VT_UNKNOWN);
561 pStream = (IStream*)V_UNKNOWN(&vari);
562 FillMemory(&guid, sizeof(guid), 0xEE);
563 hr = pStream->Read(&guid, sizeof(guid), NULL);
564 ok_long(hr, S_OK);
565 ok_int(::IsEqualGUID(guid, IID_IShellLinkW), TRUE);
566 }
567 else // XP/2k3 Read is buggy
568 {
569 ok_long(hr, E_FAIL);
570 ok_long(V_VT(&vari), VT_EMPTY);
571 }
572 VariantClear(&vari);
573
574 pPropBag->Release();
575
576 // Check registry
577 error = RegOpenKeyExW(hKey, L"PropBagTest", 0, KEY_READ, &hSubKey);
579 DWORD dwType, dwValue, cbValue = sizeof(dwValue);
580 error = RegQueryValueExW(hSubKey, L"Name1", NULL, &dwType, (BYTE*)&dwValue, &cbValue);
582 ok_long(dwType, REG_DWORD);
583 ok_long(dwValue, 0xDEADFACE);
584 ok_long(cbValue, sizeof(DWORD));
585 cbValue = sizeof(szText);
586 error = RegQueryValueExW(hSubKey, L"Name2", NULL, &dwType, (BYTE*)szText, &cbValue);
588 ok_long(dwType, REG_SZ);
589 ok_wstr(szText, L"StrValue");
590 cbValue = sizeof(guid_and_extra);
591 error = RegQueryValueExW(hSubKey, L"Name4", NULL, &dwType, (BYTE*)&guid_and_extra, &cbValue);
593 ok_long(dwType, REG_BINARY);
594 ok_int(memcmp(&guid_and_extra, &GUID_NULL, sizeof(GUID)), 0);
595 ok_int(memcmp(&guid_and_extra[sizeof(GUID)], &IID_IShellLinkW, sizeof(GUID)), 0);
596 RegCloseKey(hSubKey);
597
598 // Create as read-only
600 IID_IPropertyBag, (void **)&pPropBag);
601 ok_long(hr, S_OK);
602
603 // Read UI4
604 VariantInit(&vari);
605 hr = pPropBag->Read(L"Name1", &vari, NULL);
606 ok_long(hr, S_OK);
607 ok_long(V_VT(&vari), VT_UI4);
608 ok_long(V_UI4(&vari), 0xDEADFACE);
609 VariantClear(&vari);
610
611 // Write UI4
612 VariantInit(&vari);
613 V_VT(&vari) = VT_UI4;
614 V_UI4(&vari) = 0xDEADFACE;
615 hr = pPropBag->Write(L"Name1", &vari);
617 VariantClear(&vari);
618
619 pPropBag->Release();
620
621 // Create as write-only IPropertyBag2
623 IID_IPropertyBag2, (void **)&pPropBag);
624 ok_long(hr, S_OK);
625
626 // Write UI4
627 VariantInit(&vari);
628 V_VT(&vari) = VT_UI4;
629 V_UI4(&vari) = 0xDEADFACE;
630 hr = pPropBag->Write(L"Name3", &vari);
632 VariantClear(&vari);
633
634 // Read UI4
635 VariantInit(&vari);
636 V_UI4(&vari) = 0xFEEDF00D;
637 hr = pPropBag->Read(L"Name3", &vari, NULL);
639 ok_int(V_VT(&vari), VT_EMPTY);
640 ok_long(V_UI4(&vari), 0xFEEDF00D);
641 VariantClear(&vari);
642
643 pPropBag->Release();
644
645 // Clean up
646 RegDeleteKeyW(hKey, L"PropBagTest");
648}
649
651{
653 WCHAR szValue[MAX_PATH];
654 BOOL bRet;
655 DWORD dwRet;
656
657 ExpandEnvironmentStringsW(L"%TEMP%\\SHSetIniString.ini", szIniFile, _countof(szIniFile));
658
660
661 trace("%ls\n", szIniFile);
662
663 bRet = SHSetIniStringW(L"TestSection", L"Key", L"Value", szIniFile);
664 ok_int(bRet, TRUE);
665
667
668 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
669 ok_long(dwRet, 5);
670 ok_wstr(szValue, L"Value");
671
672 bRet = SHSetIniStringW(L"TestSection", L"Key", NULL, szIniFile);
673 ok_int(bRet, TRUE);
674
676
677 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
678 ok_long(dwRet, 0);
679 ok_wstr(szValue, L"");
680
681 bRet = SHSetIniStringW(L"TestSection", L"Key", L"ABC\x3042\x3044\x3046\x2665", szIniFile);
682 ok_int(bRet, TRUE);
683
685
686 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
687 ok_long(dwRet, 7);
688 ok_wstr(szValue, L"ABC\x3042\x3044\x3046\x2665");
689
690 szValue[0] = 0x3000;
691 szValue[1] = UNICODE_NULL;
692 dwRet = SHGetIniStringW(L"TestSection", L"NotExistentKey", szValue, _countof(szValue), szIniFile);
693 ok_long(dwRet, 0);
694 ok_wstr(szValue, L"");
695
697}
698
699static void SHPropertyBag_OnIniFile(void)
700{
701 WCHAR szIniFile[MAX_PATH], szValue[MAX_PATH];
702 HRESULT hr;
703 IPropertyBag *pPropBag;
704 VARIANT vari;
705 DWORD dwRet;
706
707 ExpandEnvironmentStringsW(L"%TEMP%\\SHPropertyBag.ini", szIniFile, _countof(szIniFile));
708
711
712 trace("%ls\n", szIniFile);
713
714 // read-write
716 szIniFile,
717 L"TestSection",
720 (void**)&pPropBag);
721 ok_long(hr, S_OK);
723
724 // Write UI4
725 VariantInit(&vari);
726 V_VT(&vari) = VT_UI4;
727 V_UI4(&vari) = 0xDEADFACE;
728 hr = pPropBag->Write(L"Name1", &vari);
729 ok_long(hr, S_OK);
730 VariantClear(&vari);
731
732 // Write BSTR
733 VariantInit(&vari);
734 V_VT(&vari) = VT_BSTR;
735 V_BSTR(&vari) = SysAllocString(L"StrValue");
736 hr = pPropBag->Write(L"Name2", &vari);
737 ok_long(hr, S_OK);
738 VariantClear(&vari);
739
740 // Write BSTR (dirty UTF-7)
741 VariantInit(&vari);
742 V_VT(&vari) = VT_BSTR;
743 V_BSTR(&vari) = SysAllocString(L"ABC\x3042\x3044\x3046\x2665");
744 hr = pPropBag->Write(L"@Name3", &vari);
745 ok_long(hr, S_OK);
746 VariantClear(&vari);
747
748 // Write BSTR (clean UTF-7)
749 VariantInit(&vari);
750 V_VT(&vari) = VT_BSTR;
751 V_BSTR(&vari) = SysAllocString(L"1234abc");
752 hr = pPropBag->Write(L"@Name4", &vari);
753 ok_long(hr, S_OK);
754 VariantClear(&vari);
755
756 pPropBag->Release();
757
758 // Flush
760
761 // Check INI file
762 dwRet = GetPrivateProfileStringW(L"TestSection", L"Name1", L"BAD", szValue, _countof(szValue), szIniFile);
763 ok_long(dwRet, 10);
764 ok_wstr(szValue, L"3735943886");
765
766 dwRet = GetPrivateProfileStringW(L"TestSection", L"Name2", L"BAD", szValue, _countof(szValue), szIniFile);
767 ok_long(dwRet, 8);
768 ok_wstr(szValue, L"StrValue");
769
770 GetPrivateProfileStringW(L"TestSection", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
771 ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
772
773 GetPrivateProfileStringW(L"TestSection.A", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
774 ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
775
776 GetPrivateProfileStringW(L"TestSection.W", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
777 ok_wstr(szValue, L"ABC+MEIwRDBGJmU-"); // UTF-7
778
779 GetPrivateProfileStringW(L"TestSection", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
780 ok_wstr(szValue, L"1234abc");
781
782 GetPrivateProfileStringW(L"TestSection.A", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
783 ok_wstr(szValue, L"NotFound");
784
785 GetPrivateProfileStringW(L"TestSection.W", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
786 ok_wstr(szValue, L"NotFound");
787
788 // read-only
790 szIniFile,
791 NULL,
792 STGM_READ,
794 (void**)&pPropBag);
795 ok_long(hr, S_OK);
796
797 // Read UI4
798 VariantInit(&vari);
799 V_VT(&vari) = VT_UI4;
800 hr = pPropBag->Read(L"TestSection\\Name1", &vari, NULL);
801 ok_long(hr, S_OK);
802 ok_long(V_UI4(&vari), 0xDEADFACE);
803 VariantClear(&vari);
804
805 // Read BSTR
806 VariantInit(&vari);
807 V_VT(&vari) = VT_BSTR;
808 hr = pPropBag->Read(L"TestSection\\Name2", &vari, NULL);
809 ok_long(hr, S_OK);
810 ok_wstr(V_BSTR(&vari), L"StrValue");
811 VariantClear(&vari);
812
813 // Read BSTR (dirty UTF-7)
814 VariantInit(&vari);
815 V_VT(&vari) = VT_BSTR;
816 hr = pPropBag->Read(L"TestSection\\@Name3", &vari, NULL);
817 ok_long(hr, S_OK);
818 ok_wstr(V_BSTR(&vari), L"ABC\x3042\x3044\x3046\x2665");
819 VariantClear(&vari);
820
821 // Read BSTR (clean UTF-7)
822 VariantInit(&vari);
823 V_VT(&vari) = VT_BSTR;
824 hr = pPropBag->Read(L"TestSection\\@Name4", &vari, NULL);
825 ok_long(hr, S_OK);
826 ok_wstr(V_BSTR(&vari), L"1234abc");
827 VariantClear(&vari);
828
829 pPropBag->Release();
830
832}
833
835{
836 HDC hDC = GetDC(NULL);
837 INT cxWidth = GetDeviceCaps(hDC, HORZRES);
838 INT cyHeight = GetDeviceCaps(hDC, VERTRES);
839 INT cMonitors = GetSystemMetrics(SM_CMONITORS);
841
842 WCHAR szBuff1[64], szBuff2[64];
843 StringCchPrintfW(szBuff1, _countof(szBuff1), L"%dx%d(%d)", cxWidth, cyHeight, cMonitors);
844
845 szBuff2[0] = UNICODE_NULL;
846 SHGetPerScreenResName(szBuff2, _countof(szBuff2), 0);
847 ok_wstr(szBuff1, szBuff2);
848}
849
850START_TEST(SHPropertyBag)
851{
859}
static HDC hDC
Definition: 3dtext.c:33
static void SHPropertyBag_SHSetIniStringW(void)
static INT s_cRead
static void SHPropertyBag_OnIniFile(void)
static VARTYPE s_vt
static void SHPropertyBag_WriteTest(void)
static void SHPropertyBag_PerScreenRes(void)
static void SHPropertyBag_ReadTest(void)
static LPCWSTR s_pszPropNames[4]
static void SHPropertyBag_OnMemory(void)
static void SHPropertyBag_OnRegKey(void)
static INT s_cWrite
static SAFEARRAY * CreateByteArray(LPCVOID pvSrc, DWORD cbSize)
static void ResetTest(VARTYPE vt, LPCWSTR pszName0=NULL, LPCWSTR pszName1=NULL, LPCWSTR pszName2=NULL, LPCWSTR pszName3=NULL)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ok_long(expression, result)
Definition: atltest.h:133
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define ok_wstr(x, y)
Definition: atltest.h:130
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
STDMETHODIMP Write(LPCWSTR pszPropName, VARIANT *pvari) override
STDMETHODIMP_(ULONG) Release() override
STDMETHODIMP Read(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog) override
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
#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 RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
OLECHAR * BSTR
Definition: compat.h:2293
#define MAX_PATH
Definition: compat.h:34
unsigned short VARTYPE
Definition: compat.h:2254
@ VT_BSTR
Definition: compat.h:2303
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_UI2
Definition: compat.h:2312
@ VT_ARRAY
Definition: compat.h:2341
@ VT_I4
Definition: compat.h:2298
@ VT_BOOL
Definition: compat.h:2306
@ VT_UI4
Definition: compat.h:2313
@ VT_EMPTY
Definition: compat.h:2295
@ VT_UI1
Definition: compat.h:2311
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
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:4265
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2607
GUID guid
Definition: version.c:147
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
BOOL WINAPI SHSetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPCWSTR str, LPCWSTR filename)
Definition: ordinal.c:3545
DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out, DWORD outLen, LPCWSTR filename)
Definition: ordinal.c:3498
HRESULT WINAPI SHCreatePropertyBagOnRegKey(HKEY hKey, LPCWSTR subkey, DWORD grfMode, REFIID riid, void **ppv)
Definition: ordinal.c:5381
HRESULT WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LPLONG pValue)
Definition: ordinal.c:5789
#define L(x)
Definition: resources.c:13
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
REFIID riid
Definition: atlbase.h:39
HRESULT Write([in] LPCOLESTR pszPropName, [in] VARIANT *pVar)
HRESULT Read([in] LPCOLESTR pszPropName, [in, out] VARIANT *pVar, [in] IErrorLog *pErrorLog)
HRESULT Read([out, size_is(cb), length_is(*pcbRead)] void *pv, [in] ULONG cb, [out] ULONG *pcbRead)
ULONG AddRef()
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define GUID_NULL
Definition: ks.h:106
#define REG_SZ
Definition: layer.c:22
#define error(str)
Definition: mkdosfs.c:1605
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HDC
Definition: imagelist.c:88
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
#define UNICODE_NULL
#define STGM_CREATE
Definition: objbase.h:926
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
#define HUGEP
Definition: objbase.h:1052
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_UI4(A)
Definition: oleauto.h:270
const GUID IID_IPropertyBag
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
EXTERN_C INT WINAPI SHGetPerScreenResName(_Out_writes_(cchBuffer) LPWSTR pszBuffer, _In_ INT cchBuffer, _In_ DWORD dwReserved)
Definition: propbag.cpp:1938
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 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 SHCreateMemStream(const BYTE *lpbData, UINT dwDataLen)
Definition: regstream.c:652
TCHAR szIniFile[]
Definition: scrnsave.c:29
#define REG_DWORD
Definition: sdbapi.c:596
HRESULT hr
Definition: shlfolder.c:183
#define IID_IExtractIcon
Definition: shlguid.h:132
HRESULT WINAPI SHPropertyBag_WriteRECTL(IPropertyBag *ppb, LPCWSTR pszPropName, const RECTL *prcl)
HRESULT WINAPI SHPropertyBag_ReadDWORD(IPropertyBag *ppb, LPCWSTR pszPropName, DWORD *pdwValue)
HRESULT WINAPI SHPropertyBag_ReadSHORT(IPropertyBag *ppb, LPCWSTR pszPropName, SHORT *psValue)
HRESULT WINAPI SHPropertyBag_ReadGUID(IPropertyBag *ppb, LPCWSTR pszPropName, GUID *pguid)
HRESULT WINAPI SHPropertyBag_ReadPOINTS(IPropertyBag *ppb, LPCWSTR pszPropName, POINTS *ppts)
HRESULT WINAPI SHPropertyBag_WriteBOOL(IPropertyBag *ppb, LPCWSTR pszPropName, BOOL bValue)
HRESULT WINAPI SHPropertyBag_ReadPOINTL(IPropertyBag *ppb, LPCWSTR pszPropName, POINTL *pptl)
HRESULT WINAPI SHPropertyBag_WriteGUID(IPropertyBag *ppb, LPCWSTR pszPropName, const GUID *pguid)
HRESULT WINAPI SHPropertyBag_WriteSHORT(IPropertyBag *ppb, LPCWSTR pszPropName, SHORT sValue)
HRESULT WINAPI SHPropertyBag_ReadBSTR(IPropertyBag *ppb, LPCWSTR pszPropName, BSTR *pbstr)
HRESULT WINAPI SHPropertyBag_ReadRECTL(IPropertyBag *ppb, LPCWSTR pszPropName, RECTL *prcl)
HRESULT WINAPI SHPropertyBag_Delete(IPropertyBag *ppb, LPCWSTR pszPropName)
HRESULT WINAPI SHPropertyBag_ReadBOOL(IPropertyBag *ppb, LPCWSTR pszPropName, BOOL *pbValue)
HRESULT WINAPI SHPropertyBag_WriteStr(IPropertyBag *ppb, LPCWSTR pszPropName, LPCWSTR pszValue)
HRESULT WINAPI SHPropertyBag_WritePOINTL(IPropertyBag *ppb, LPCWSTR pszPropName, const POINTL *pptl)
HRESULT WINAPI SHPropertyBag_WritePOINTS(IPropertyBag *ppb, LPCWSTR pszPropName, const POINTS *ppts)
HRESULT WINAPI SHPropertyBag_WriteLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LONG lValue)
HRESULT WINAPI SHPropertyBag_WriteDWORD(IPropertyBag *ppb, LPCWSTR pszPropName, DWORD dwValue)
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
VERSIONHELPERAPI IsWindowsVistaOrGreater()
#define ZeroMemory
Definition: winbase.h:1753
#define CopyMemory
Definition: winbase.h:1751
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3749
CONST void * LPCVOID
Definition: windef.h:191
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define HORZRES
Definition: wingdi.h:716
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define VERTRES
Definition: wingdi.h:717
#define HKEY_CURRENT_USER
Definition: winreg.h:11
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)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193