ReactOS 0.4.16-dev-311-g9382aa2
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
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"GUID1") == 0)
99 {
100 V_VT(pvari) = (VT_UI1 | VT_ARRAY);
101 V_ARRAY(pvari) = CreateByteArray(&IID_IShellLinkW, sizeof(IID));
102 return S_OK;
103 }
104
105 if (lstrcmpiW(pszPropName, L"GUID2") == 0)
106 {
107 WCHAR szText[50];
108 StringFromGUID2(IID_IUnknown, szText, _countof(szText));
109
110 V_VT(pvari) = VT_BSTR;
111 V_BSTR(pvari) = SysAllocString(szText);
112 return S_OK;
113 }
114
115 if (lstrcmpiW(pszPropName, L"GUID3") == 0)
116 {
117 V_VT(pvari) = VT_EMPTY;
118 V_UI4(pvari) = 0xDEADFACE;
119 return S_OK;
120 }
121
122 goto Skip1;
123 }
124 }
125 ok(FALSE, "Unexpected call\n");
126Skip1:
127 return S_OK;
128 }
129
130 STDMETHODIMP Write(LPCWSTR pszPropName, VARIANT *pvari) override
131 {
132 ++s_cWrite;
133 ok_int(s_vt, V_VT(pvari));
134 for (size_t i = 0; i < _countof(s_pszPropNames); ++i)
135 {
136 if (s_pszPropNames[i])
137 {
138 ok_wstr(pszPropName, s_pszPropNames[i]);
140 if (lstrcmpiW(pszPropName, L"RECTL2.bottom") == 0)
141 {
142 s_vt = VT_EMPTY;
144 s_pszPropNames[0] = L"RECTL2.right";
145 return E_FAIL;
146 }
147 goto Skip2;
148 }
149 }
150 ok(FALSE, "Unexpected call\n");
151Skip2:
152 return S_OK;
153 }
154};
155
156static void SHPropertyBag_ReadTest(void)
157{
158 HRESULT hr;
160 BOOL bValue = 0xDEADFACE;
161 SHORT sValue = 0xDEADu;
162 LONG lValue = 0xDEADDEAD;
163 DWORD dwValue = 0xFEEDF00D;
164 BSTR bstr = NULL;
165 POINTL ptl = { 0xEEEE, 0xDDDD };
166 POINTS pts = { 0x2222, 0x3333 };
167 RECTL rcl = { 123, 456, 789, 101112 };
168 GUID guid = { 0 };
169
170 ResetTest(VT_BOOL, L"BOOL1");
172 ok_long(hr, S_OK);
173 ok_int(s_cRead, 1);
174 ok_int(s_cWrite, 0);
175
176 ResetTest(VT_UI2, L"SHORT1");
178 ok_long(hr, S_OK);
179 ok_int(s_cRead, 1);
180 ok_int(s_cWrite, 0);
181
182 ResetTest(VT_I4, L"LONG1");
184 ok_long(hr, S_OK);
185 ok_int(s_cRead, 1);
186 ok_int(s_cWrite, 0);
187
188 ResetTest(VT_UI4, L"DWORD1");
190 ok_long(hr, S_OK);
191 ok_int(s_cRead, 1);
192 ok_int(s_cWrite, 0);
193
194 ResetTest(VT_BSTR, L"Str1");
196 ok_long(hr, S_OK);
197 ok_int(s_cRead, 1);
198 ok_int(s_cWrite, 0);
199 SysFreeString(bstr);
200
201 ResetTest(VT_I4, L"POINTL1.x", L"POINTL1.y");
202 hr = SHPropertyBag_ReadPOINTL(&dummy, L"POINTL1", &ptl);
203 ok_long(hr, S_OK);
204 ok_int(s_cRead, 2);
205 ok_int(s_cWrite, 0);
206
207 ResetTest(VT_I4, L"POINTS1.x", L"POINTS1.y");
208 hr = SHPropertyBag_ReadPOINTS(&dummy, L"POINTS1", &pts);
209 ok_long(hr, S_OK);
210 ok_int(s_cRead, 2);
211 ok_int(s_cWrite, 0);
212
213 ResetTest(VT_I4, L"RECTL1.left", L"RECTL1.top", L"RECTL1.right", L"RECTL1.bottom");
214 hr = SHPropertyBag_ReadRECTL(&dummy, L"RECTL1", &rcl);
215 ok_long(hr, S_OK);
216 ok_int(s_cRead, 4);
217 ok_int(s_cWrite, 0);
218
219 ResetTest(VT_I4, L"RECTL2.left", L"RECTL2.top", L"RECTL2.right", L"RECTL2.bottom");
220 hr = SHPropertyBag_ReadRECTL(&dummy, L"RECTL2", &rcl);
221 ok_long(hr, E_FAIL);
222 ok_int(s_cRead, 2);
223 ok_int(s_cWrite, 0);
224
225 ResetTest(VT_EMPTY, L"GUID1");
226 hr = SHPropertyBag_ReadGUID(&dummy, L"GUID1", &guid);
227 ok_long(hr, S_OK);
228 ok_int(s_cRead, 1);
229 ok_int(s_cWrite, 0);
230 ok_int(IsEqualGUID(guid, IID_IShellLinkW), TRUE);
231
232 ResetTest(VT_EMPTY, L"GUID2");
233 hr = SHPropertyBag_ReadGUID(&dummy, L"GUID2", &guid);
234 ok_long(hr, S_OK);
235 ok_int(s_cRead, 1);
236 ok_int(s_cWrite, 0);
238
239 ResetTest(VT_EMPTY, L"GUID3");
241 hr = SHPropertyBag_ReadGUID(&dummy, L"GUID3", &guid);
242
245 else
246 ok_long(hr, S_OK);
247
248 ok_int(s_cRead, 1);
249 ok_int(s_cWrite, 0);
251}
252
253static void SHPropertyBag_WriteTest(void)
254{
255 HRESULT hr;
257
258 ResetTest(VT_EMPTY, L"EMPTY1");
260 ok_long(hr, S_OK);
261 ok_int(s_cRead, 0);
262 ok_int(s_cWrite, 1);
263
264 ResetTest(VT_BOOL, L"BOOL1");
266 ok_long(hr, S_OK);
267 ok_int(s_cRead, 0);
268 ok_int(s_cWrite, 1);
269
270 ResetTest(VT_UI2, L"SHORT1");
272 ok_long(hr, S_OK);
273 ok_int(s_cRead, 0);
274 ok_int(s_cWrite, 1);
275
276 ResetTest(VT_I4, L"LONG1");
278 ok_long(hr, S_OK);
279 ok_int(s_cRead, 0);
280 ok_int(s_cWrite, 1);
281
282 ResetTest(VT_UI4, L"DWORD1");
284 ok_long(hr, S_OK);
285 ok_int(s_cRead, 0);
286 ok_int(s_cWrite, 1);
287
288 ResetTest(VT_BSTR, L"Str1");
290 ok_long(hr, S_OK);
291 ok_int(s_cRead, 0);
292 ok_int(s_cWrite, 1);
293
294 ResetTest(VT_I4, L"POINTL1.x", L"POINTL1.y");
295 POINTL ptl = { 0xEEEE, 0xDDDD };
296 hr = SHPropertyBag_WritePOINTL(&dummy, L"POINTL1", &ptl);
297 ok_long(hr, S_OK);
298 ok_int(s_cRead, 0);
299 ok_int(s_cWrite, 2);
300
301 ResetTest(VT_I4, L"POINTS1.x", L"POINTS1.y");
302 POINTS pts = { 0x2222, 0x3333 };
303 hr = SHPropertyBag_WritePOINTS(&dummy, L"POINTS1", &pts);
304 ok_long(hr, S_OK);
305 ok_int(s_cRead, 0);
306 ok_int(s_cWrite, 2);
307
308 ResetTest(VT_I4, L"RECTL1.left", L"RECTL1.top", L"RECTL1.right", L"RECTL1.bottom");
309 RECTL rcl = { 123, 456, 789, 101112 };
310 hr = SHPropertyBag_WriteRECTL(&dummy, L"RECTL1", &rcl);
311 ok_long(hr, S_OK);
312 ok_int(s_cRead, 0);
313 ok_int(s_cWrite, 4);
314
315 ResetTest(VT_I4, L"RECTL2.left", L"RECTL2.top", L"RECTL2.right", L"RECTL2.bottom");
316 hr = SHPropertyBag_WriteRECTL(&dummy, L"RECTL2", &rcl);
317 ok_long(hr, S_OK);
318 ok_int(s_cRead, 0);
319 ok_int(s_cWrite, 5);
320
321 GUID guid;
322 ZeroMemory(&guid, sizeof(guid));
323 ResetTest(VT_BSTR, L"GUID1");
324 hr = SHPropertyBag_WriteGUID(&dummy, L"GUID1", &guid);
325 ok_long(hr, S_OK);
326 ok_int(s_cRead, 0);
327 ok_int(s_cWrite, 1);
328}
329
330static void SHPropertyBag_OnMemory(void)
331{
332 HRESULT hr;
333 VARIANT vari;
334
335 IPropertyBag *pPropBag = NULL;
337 ok_long(hr, S_OK);
338 if (pPropBag == NULL)
339 {
340 skip("pPropBag was NULL\n");
341 return;
342 }
343
344 VariantInit(&vari);
345 hr = pPropBag->Read(L"InvalidName", &vari, NULL);
346 ok_long(hr, E_FAIL);
347 VariantClear(&vari);
348
349 VariantInit(&vari);
350 V_VT(&vari) = VT_UI4;
351 V_UI4(&vari) = 0xDEADFACE;
352 hr = pPropBag->Write(L"Name1", &vari);
353 ok_long(hr, S_OK);
354 VariantClear(&vari);
355
356 VariantInit(&vari);
357 hr = pPropBag->Read(L"Name1", &vari, NULL);
358 ok_long(hr, S_OK);
359 ok_long(V_VT(&vari), VT_UI4);
360 ok_long(V_UI4(&vari), 0xDEADFACE);
361 VariantClear(&vari);
362
363 pPropBag->Release();
364 pPropBag = NULL;
365
367 ok_long(hr, S_OK);
368
369 VariantInit(&vari);
370 V_VT(&vari) = VT_UI4;
371 V_UI4(&vari) = 0xDEADFACE;
372 hr = pPropBag->Write(L"Name1", &vari);
374 VariantClear(&vari);
375
376 VariantInit(&vari);
377 V_VT(&vari) = VT_UI4;
378 V_UI4(&vari) = 0xFEEDF00D;
379 hr = pPropBag->Read(L"Name1", &vari, NULL);
381 {
382 ok_long(hr, S_OK);
383 ok_int(V_VT(&vari), VT_UI4);
384 ok_long(V_UI4(&vari), 0xDEADFACE);
385 }
386 else
387 {
388 ok_long(hr, E_FAIL);
389 ok_int(V_VT(&vari), VT_EMPTY);
390 ok_long(V_UI4(&vari), 0xFEEDF00D);
391 }
392 VariantClear(&vari);
393
394 pPropBag->Release();
395 pPropBag = NULL;
396
398 ok_long(hr, S_OK);
399
400 VariantInit(&vari);
401 V_VT(&vari) = VT_UI4;
402 V_UI4(&vari) = 0xDEADFACE;
403 hr = pPropBag->Write(L"Name1", &vari);
404 ok_long(hr, S_OK);
405 VariantClear(&vari);
406
407 VariantInit(&vari);
408 V_VT(&vari) = VT_UI4;
409 V_UI4(&vari) = 0xFEEDF00D;
410 hr = pPropBag->Read(L"Name1", &vari, NULL);
412 {
413 ok_long(hr, S_OK);
414 ok_int(V_VT(&vari), VT_UI4);
415 ok_long(V_UI4(&vari), 0xDEADFACE);
416 }
417 else
418 {
420 ok_int(V_VT(&vari), VT_EMPTY);
421 ok_long(V_UI4(&vari), 0xFEEDF00D);
422 }
423 VariantClear(&vari);
424
425 pPropBag->Release();
426
427 hr = SHCreatePropertyBagOnMemory(STGM_READWRITE, IID_IPropertyBag2, (void**)&pPropBag);
429 {
431 }
432 else
433 {
434 ok_long(hr, S_OK);
435 pPropBag->Release();
436 }
437
438 hr = SHCreatePropertyBagOnMemory(STGM_READ, IID_IPropertyBag2, (void**)&pPropBag);
440 {
442 }
443 else
444 {
445 ok_long(hr, S_OK);
446 pPropBag->Release();
447 }
448
449 hr = SHCreatePropertyBagOnMemory(STGM_WRITE, IID_IPropertyBag2, (void**)&pPropBag);
451 {
453 }
454 else
455 {
456 ok_long(hr, S_OK);
457 pPropBag->Release();
458 }
459}
460
461static void SHPropertyBag_OnRegKey(void)
462{
463 HKEY hKey, hSubKey;
464 LONG error;
465 VARIANT vari;
466 WCHAR szText[MAX_PATH];
467 IStream *pStream;
468 GUID guid;
469 BYTE guid_and_extra[sizeof(GUID) + sizeof(GUID)];
470
471 // Create HKCU\Software\ReactOS registry key
472 error = RegCreateKeyW(HKEY_CURRENT_USER, L"Software\\ReactOS", &hKey);
473 if (error)
474 {
475 skip("FAILED to create HKCU\\Software\\ReactOS\n");
476 return;
477 }
478
479 IPropertyBag *pPropBag;
480 HRESULT hr;
481
482 // Try to create new registry key
483 RegDeleteKeyW(hKey, L"PropBagTest");
484 hr = SHCreatePropertyBagOnRegKey(hKey, L"PropBagTest", 0,
485 IID_IPropertyBag, (void **)&pPropBag);
487
488 // Try to create new registry key
489 RegDeleteKeyW(hKey, L"PropBagTest");
491 IID_IPropertyBag, (void **)&pPropBag);
493
494 // Create new registry key
495 RegDeleteKeyW(hKey, L"PropBagTest");
497 IID_IPropertyBag, (void **)&pPropBag);
498 if (FAILED(hr))
499 {
500 skip("SHCreatePropertyBagOnRegKey FAILED\n");
502 return;
503 }
504
505 // Write UI4
506 VariantInit(&vari);
507 V_VT(&vari) = VT_UI4;
508 V_UI4(&vari) = 0xDEADFACE;
509 hr = pPropBag->Write(L"Name1", &vari);
510 ok_long(hr, S_OK);
511 VariantClear(&vari);
512
513 // Read UI4
514 VariantInit(&vari);
515 hr = pPropBag->Read(L"Name1", &vari, NULL);
516 ok_long(hr, S_OK);
517 ok_long(V_VT(&vari), VT_UI4);
518 ok_long(V_UI4(&vari), 0xDEADFACE);
519 VariantClear(&vari);
520
521 // Write BSTR
522 VariantInit(&vari);
523 V_VT(&vari) = VT_BSTR;
524 V_BSTR(&vari) = SysAllocString(L"StrValue");
525 hr = pPropBag->Write(L"Name2", &vari);
526 ok_long(hr, S_OK);
527 VariantClear(&vari);
528
529 // Read BSTR
530 VariantInit(&vari);
531 V_VT(&vari) = VT_BSTR;
532 hr = pPropBag->Read(L"Name2", &vari, NULL);
533 ok_long(hr, S_OK);
534 ok_long(V_VT(&vari), VT_BSTR);
535 ok_wstr(V_BSTR(&vari), L"StrValue");
536 VariantClear(&vari);
537
538 // Write GUID
539 VariantInit(&vari);
540 V_VT(&vari) = VT_UNKNOWN;
541 V_UNKNOWN(&vari) = SHCreateMemStream((BYTE*)&IID_IShellLinkW, sizeof(IID_IShellLinkW));
542 hr = pPropBag->Write(L"Name4", &vari);
543 ok_long(hr, S_OK);
544 VariantClear(&vari);
545
546 // Read GUID
547 VariantInit(&vari);
548 V_VT(&vari) = VT_EMPTY;
549 hr = pPropBag->Read(L"Name4", &vari, NULL);
551 {
552 ok_long(hr, S_OK);
553 ok_long(V_VT(&vari), VT_UNKNOWN);
554 pStream = (IStream*)V_UNKNOWN(&vari);
555 FillMemory(&guid, sizeof(guid), 0xEE);
556 hr = pStream->Read(&guid, sizeof(guid), NULL);
557 ok_long(hr, S_OK);
558 ok_int(::IsEqualGUID(guid, IID_IShellLinkW), TRUE);
559 }
560 else // XP/2k3 Read is buggy
561 {
562 ok_long(hr, E_FAIL);
563 ok_long(V_VT(&vari), VT_EMPTY);
564 }
565 VariantClear(&vari);
566
567 pPropBag->Release();
568
569 // Check registry
570 error = RegOpenKeyExW(hKey, L"PropBagTest", 0, KEY_READ, &hSubKey);
572 DWORD dwType, dwValue, cbValue = sizeof(dwValue);
573 error = RegQueryValueExW(hSubKey, L"Name1", NULL, &dwType, (BYTE*)&dwValue, &cbValue);
575 ok_long(dwType, REG_DWORD);
576 ok_long(dwValue, 0xDEADFACE);
577 ok_long(cbValue, sizeof(DWORD));
578 cbValue = sizeof(szText);
579 error = RegQueryValueExW(hSubKey, L"Name2", NULL, &dwType, (BYTE*)szText, &cbValue);
581 ok_long(dwType, REG_SZ);
582 ok_wstr(szText, L"StrValue");
583 cbValue = sizeof(guid_and_extra);
584 error = RegQueryValueExW(hSubKey, L"Name4", NULL, &dwType, (BYTE*)&guid_and_extra, &cbValue);
586 ok_long(dwType, REG_BINARY);
587 ok_int(memcmp(&guid_and_extra, &GUID_NULL, sizeof(GUID)), 0);
588 ok_int(memcmp(&guid_and_extra[sizeof(GUID)], &IID_IShellLinkW, sizeof(GUID)), 0);
589 RegCloseKey(hSubKey);
590
591 // Create as read-only
593 IID_IPropertyBag, (void **)&pPropBag);
594 ok_long(hr, S_OK);
595
596 // Read UI4
597 VariantInit(&vari);
598 hr = pPropBag->Read(L"Name1", &vari, NULL);
599 ok_long(hr, S_OK);
600 ok_long(V_VT(&vari), VT_UI4);
601 ok_long(V_UI4(&vari), 0xDEADFACE);
602 VariantClear(&vari);
603
604 // Write UI4
605 VariantInit(&vari);
606 V_VT(&vari) = VT_UI4;
607 V_UI4(&vari) = 0xDEADFACE;
608 hr = pPropBag->Write(L"Name1", &vari);
610 VariantClear(&vari);
611
612 pPropBag->Release();
613
614 // Create as write-only IPropertyBag2
616 IID_IPropertyBag2, (void **)&pPropBag);
617 ok_long(hr, S_OK);
618
619 // Write UI4
620 VariantInit(&vari);
621 V_VT(&vari) = VT_UI4;
622 V_UI4(&vari) = 0xDEADFACE;
623 hr = pPropBag->Write(L"Name3", &vari);
625 VariantClear(&vari);
626
627 // Read UI4
628 VariantInit(&vari);
629 V_UI4(&vari) = 0xFEEDF00D;
630 hr = pPropBag->Read(L"Name3", &vari, NULL);
632 ok_int(V_VT(&vari), VT_EMPTY);
633 ok_long(V_UI4(&vari), 0xFEEDF00D);
634 VariantClear(&vari);
635
636 pPropBag->Release();
637
638 // Clean up
639 RegDeleteKeyW(hKey, L"PropBagTest");
641}
642
644{
646 WCHAR szValue[MAX_PATH];
647 BOOL bRet;
648 DWORD dwRet;
649
650 ExpandEnvironmentStringsW(L"%TEMP%\\SHSetIniString.ini", szIniFile, _countof(szIniFile));
651
653
654 trace("%ls\n", szIniFile);
655
656 bRet = SHSetIniStringW(L"TestSection", L"Key", L"Value", szIniFile);
657 ok_int(bRet, TRUE);
658
660
661 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
662 ok_long(dwRet, 5);
663 ok_wstr(szValue, L"Value");
664
665 bRet = SHSetIniStringW(L"TestSection", L"Key", NULL, szIniFile);
666 ok_int(bRet, TRUE);
667
669
670 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
671 ok_long(dwRet, 0);
672 ok_wstr(szValue, L"");
673
674 bRet = SHSetIniStringW(L"TestSection", L"Key", L"ABC\x3042\x3044\x3046\x2665", szIniFile);
675 ok_int(bRet, TRUE);
676
678
679 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
680 ok_long(dwRet, 7);
681 ok_wstr(szValue, L"ABC\x3042\x3044\x3046\x2665");
682
683 szValue[0] = 0x3000;
684 szValue[1] = UNICODE_NULL;
685 dwRet = SHGetIniStringW(L"TestSection", L"NotExistentKey", szValue, _countof(szValue), szIniFile);
686 ok_long(dwRet, 0);
687 ok_wstr(szValue, L"");
688
690}
691
692static void SHPropertyBag_OnIniFile(void)
693{
694 WCHAR szIniFile[MAX_PATH], szValue[MAX_PATH];
695 HRESULT hr;
696 IPropertyBag *pPropBag;
697 VARIANT vari;
698 DWORD dwRet;
699
700 ExpandEnvironmentStringsW(L"%TEMP%\\SHPropertyBag.ini", szIniFile, _countof(szIniFile));
701
704
705 trace("%ls\n", szIniFile);
706
707 // read-write
709 szIniFile,
710 L"TestSection",
713 (void**)&pPropBag);
714 ok_long(hr, S_OK);
716
717 // Write UI4
718 VariantInit(&vari);
719 V_VT(&vari) = VT_UI4;
720 V_UI4(&vari) = 0xDEADFACE;
721 hr = pPropBag->Write(L"Name1", &vari);
722 ok_long(hr, S_OK);
723 VariantClear(&vari);
724
725 // Write BSTR
726 VariantInit(&vari);
727 V_VT(&vari) = VT_BSTR;
728 V_BSTR(&vari) = SysAllocString(L"StrValue");
729 hr = pPropBag->Write(L"Name2", &vari);
730 ok_long(hr, S_OK);
731 VariantClear(&vari);
732
733 // Write BSTR (dirty UTF-7)
734 VariantInit(&vari);
735 V_VT(&vari) = VT_BSTR;
736 V_BSTR(&vari) = SysAllocString(L"ABC\x3042\x3044\x3046\x2665");
737 hr = pPropBag->Write(L"@Name3", &vari);
738 ok_long(hr, S_OK);
739 VariantClear(&vari);
740
741 // Write BSTR (clean UTF-7)
742 VariantInit(&vari);
743 V_VT(&vari) = VT_BSTR;
744 V_BSTR(&vari) = SysAllocString(L"1234abc");
745 hr = pPropBag->Write(L"@Name4", &vari);
746 ok_long(hr, S_OK);
747 VariantClear(&vari);
748
749 pPropBag->Release();
750
751 // Flush
753
754 // Check INI file
755 dwRet = GetPrivateProfileStringW(L"TestSection", L"Name1", L"BAD", szValue, _countof(szValue), szIniFile);
756 ok_long(dwRet, 10);
757 ok_wstr(szValue, L"3735943886");
758
759 dwRet = GetPrivateProfileStringW(L"TestSection", L"Name2", L"BAD", szValue, _countof(szValue), szIniFile);
760 ok_long(dwRet, 8);
761 ok_wstr(szValue, L"StrValue");
762
763 GetPrivateProfileStringW(L"TestSection", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
764 ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
765
766 GetPrivateProfileStringW(L"TestSection.A", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
767 ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
768
769 GetPrivateProfileStringW(L"TestSection.W", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
770 ok_wstr(szValue, L"ABC+MEIwRDBGJmU-"); // UTF-7
771
772 GetPrivateProfileStringW(L"TestSection", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
773 ok_wstr(szValue, L"1234abc");
774
775 GetPrivateProfileStringW(L"TestSection.A", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
776 ok_wstr(szValue, L"NotFound");
777
778 GetPrivateProfileStringW(L"TestSection.W", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
779 ok_wstr(szValue, L"NotFound");
780
781 // read-only
783 szIniFile,
784 NULL,
785 STGM_READ,
787 (void**)&pPropBag);
788 ok_long(hr, S_OK);
789
790 // Read UI4
791 VariantInit(&vari);
792 V_VT(&vari) = VT_UI4;
793 hr = pPropBag->Read(L"TestSection\\Name1", &vari, NULL);
794 ok_long(hr, S_OK);
795 ok_long(V_UI4(&vari), 0xDEADFACE);
796 VariantClear(&vari);
797
798 // Read BSTR
799 VariantInit(&vari);
800 V_VT(&vari) = VT_BSTR;
801 hr = pPropBag->Read(L"TestSection\\Name2", &vari, NULL);
802 ok_long(hr, S_OK);
803 ok_wstr(V_BSTR(&vari), L"StrValue");
804 VariantClear(&vari);
805
806 // Read BSTR (dirty UTF-7)
807 VariantInit(&vari);
808 V_VT(&vari) = VT_BSTR;
809 hr = pPropBag->Read(L"TestSection\\@Name3", &vari, NULL);
810 ok_long(hr, S_OK);
811 ok_wstr(V_BSTR(&vari), L"ABC\x3042\x3044\x3046\x2665");
812 VariantClear(&vari);
813
814 // Read BSTR (clean UTF-7)
815 VariantInit(&vari);
816 V_VT(&vari) = VT_BSTR;
817 hr = pPropBag->Read(L"TestSection\\@Name4", &vari, NULL);
818 ok_long(hr, S_OK);
819 ok_wstr(V_BSTR(&vari), L"1234abc");
820 VariantClear(&vari);
821
822 pPropBag->Release();
823
825}
826
828{
829 HDC hDC = GetDC(NULL);
830 INT cxWidth = GetDeviceCaps(hDC, HORZRES);
831 INT cyHeight = GetDeviceCaps(hDC, VERTRES);
832 INT cMonitors = GetSystemMetrics(SM_CMONITORS);
834
835 WCHAR szBuff1[64], szBuff2[64];
836 StringCchPrintfW(szBuff1, _countof(szBuff1), L"%dx%d(%d)", cxWidth, cyHeight, cMonitors);
837
838 szBuff2[0] = UNICODE_NULL;
839 SHGetPerScreenResName(szBuff2, _countof(szBuff2), 0);
840 ok_wstr(szBuff1, szBuff2);
841}
842
843START_TEST(SHPropertyBag)
844{
852}
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:4262
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:3426
DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out, DWORD outLen, LPCWSTR filename)
Definition: ordinal.c:3379
HRESULT WINAPI SHCreatePropertyBagOnRegKey(HKEY hKey, LPCWSTR subkey, DWORD grfMode, REFIID riid, void **ppv)
Definition: ordinal.c:5193
HRESULT WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LPLONG pValue)
Definition: ordinal.c:5601
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
#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
const GUID * guid
#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 L(x)
Definition: ntvdm.h:50
#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:1737
#define CopyMemory
Definition: winbase.h:1735
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
_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:1043
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