ReactOS 0.4.16-dev-1983-g1a17364
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
622 IPropertyBag2 *pPropBag2;
624 IID_IPropertyBag2, (void **)&pPropBag2);
625 ok_long(hr, S_OK);
626
627 // Write UI4
628 PROPBAG2 propBag2 = {};
629 propBag2.dwType = PROPBAG2_TYPE_DATA;
630 propBag2.vt = VT_UI4;
631 propBag2.pstrName = const_cast<LPOLESTR>(L"Name1");
632 VariantInit(&vari);
633 V_VT(&vari) = VT_UI4;
634 V_UI4(&vari) = 0xDEADFACE;
635 hr = pPropBag2->Write(1, &propBag2, &vari);
637 VariantClear(&vari);
638
639 // Read UI4
640 VariantInit(&vari);
641 V_UI4(&vari) = 0xFEEDF00D;
642 HRESULT hrPropBag;
643 hr = pPropBag2->Read(1, &propBag2, NULL, &vari, &hrPropBag);
645 ok_int(V_VT(&vari), VT_EMPTY);
646 ok_long(V_UI4(&vari), 0xFEEDF00D);
647 VariantClear(&vari);
648
649 pPropBag2->Release();
650
651 // Clean up
652 RegDeleteKeyW(hKey, L"PropBagTest");
654}
655
657{
659 WCHAR szValue[MAX_PATH];
660 BOOL bRet;
661 DWORD dwRet;
662
663 ExpandEnvironmentStringsW(L"%TEMP%\\SHSetIniString.ini", szIniFile, _countof(szIniFile));
664
666
667 trace("%ls\n", szIniFile);
668
669 bRet = SHSetIniStringW(L"TestSection", L"Key", L"Value", szIniFile);
670 ok_int(bRet, TRUE);
671
673
674 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
675 ok_long(dwRet, 5);
676 ok_wstr(szValue, L"Value");
677
678 bRet = SHSetIniStringW(L"TestSection", L"Key", NULL, szIniFile);
679 ok_int(bRet, TRUE);
680
682
683 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
684 ok_long(dwRet, 0);
685 ok_wstr(szValue, L"");
686
687 bRet = SHSetIniStringW(L"TestSection", L"Key", L"ABC\x3042\x3044\x3046\x2665", szIniFile);
688 ok_int(bRet, TRUE);
689
691
692 dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, _countof(szValue), szIniFile);
693 ok_long(dwRet, 7);
694 ok_wstr(szValue, L"ABC\x3042\x3044\x3046\x2665");
695
696 szValue[0] = 0x3000;
697 szValue[1] = UNICODE_NULL;
698 dwRet = SHGetIniStringW(L"TestSection", L"NotExistentKey", szValue, _countof(szValue), szIniFile);
699 ok_long(dwRet, 0);
700 ok_wstr(szValue, L"");
701
703}
704
705static void SHPropertyBag_OnIniFile(void)
706{
707 WCHAR szIniFile[MAX_PATH], szValue[MAX_PATH];
708 HRESULT hr;
709 IPropertyBag *pPropBag;
710 VARIANT vari;
711 DWORD dwRet;
712
713 ExpandEnvironmentStringsW(L"%TEMP%\\SHPropertyBag.ini", szIniFile, _countof(szIniFile));
714
717
718 trace("%ls\n", szIniFile);
719
720 // read-write
722 szIniFile,
723 L"TestSection",
726 (void**)&pPropBag);
727 ok_long(hr, S_OK);
729
730 // Write UI4
731 VariantInit(&vari);
732 V_VT(&vari) = VT_UI4;
733 V_UI4(&vari) = 0xDEADFACE;
734 hr = pPropBag->Write(L"Name1", &vari);
735 ok_long(hr, S_OK);
736 VariantClear(&vari);
737
738 // Write BSTR
739 VariantInit(&vari);
740 V_VT(&vari) = VT_BSTR;
741 V_BSTR(&vari) = SysAllocString(L"StrValue");
742 hr = pPropBag->Write(L"Name2", &vari);
743 ok_long(hr, S_OK);
744 VariantClear(&vari);
745
746 // Write BSTR (dirty UTF-7)
747 VariantInit(&vari);
748 V_VT(&vari) = VT_BSTR;
749 V_BSTR(&vari) = SysAllocString(L"ABC\x3042\x3044\x3046\x2665");
750 hr = pPropBag->Write(L"@Name3", &vari);
751 ok_long(hr, S_OK);
752 VariantClear(&vari);
753
754 // Write BSTR (clean UTF-7)
755 VariantInit(&vari);
756 V_VT(&vari) = VT_BSTR;
757 V_BSTR(&vari) = SysAllocString(L"1234abc");
758 hr = pPropBag->Write(L"@Name4", &vari);
759 ok_long(hr, S_OK);
760 VariantClear(&vari);
761
762 pPropBag->Release();
763
764 // Flush
766
767 // Check INI file
768 dwRet = GetPrivateProfileStringW(L"TestSection", L"Name1", L"BAD", szValue, _countof(szValue), szIniFile);
769 ok_long(dwRet, 10);
770 ok_wstr(szValue, L"3735943886");
771
772 dwRet = GetPrivateProfileStringW(L"TestSection", L"Name2", L"BAD", szValue, _countof(szValue), szIniFile);
773 ok_long(dwRet, 8);
774 ok_wstr(szValue, L"StrValue");
775
776 GetPrivateProfileStringW(L"TestSection", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
777 ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
778
779 GetPrivateProfileStringW(L"TestSection.A", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
780 ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
781
782 GetPrivateProfileStringW(L"TestSection.W", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
783 ok_wstr(szValue, L"ABC+MEIwRDBGJmU-"); // UTF-7
784
785 GetPrivateProfileStringW(L"TestSection", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
786 ok_wstr(szValue, L"1234abc");
787
788 GetPrivateProfileStringW(L"TestSection.A", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
789 ok_wstr(szValue, L"NotFound");
790
791 GetPrivateProfileStringW(L"TestSection.W", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
792 ok_wstr(szValue, L"NotFound");
793
794 // read-only
796 szIniFile,
797 NULL,
798 STGM_READ,
800 (void**)&pPropBag);
801 ok_long(hr, S_OK);
802
803 // Read UI4
804 VariantInit(&vari);
805 V_VT(&vari) = VT_UI4;
806 hr = pPropBag->Read(L"TestSection\\Name1", &vari, NULL);
807 ok_long(hr, S_OK);
808 ok_long(V_UI4(&vari), 0xDEADFACE);
809 VariantClear(&vari);
810
811 // Read BSTR
812 VariantInit(&vari);
813 V_VT(&vari) = VT_BSTR;
814 hr = pPropBag->Read(L"TestSection\\Name2", &vari, NULL);
815 ok_long(hr, S_OK);
816 ok_wstr(V_BSTR(&vari), L"StrValue");
817 VariantClear(&vari);
818
819 // Read BSTR (dirty UTF-7)
820 VariantInit(&vari);
821 V_VT(&vari) = VT_BSTR;
822 hr = pPropBag->Read(L"TestSection\\@Name3", &vari, NULL);
823 ok_long(hr, S_OK);
824 ok_wstr(V_BSTR(&vari), L"ABC\x3042\x3044\x3046\x2665");
825 VariantClear(&vari);
826
827 // Read BSTR (clean UTF-7)
828 VariantInit(&vari);
829 V_VT(&vari) = VT_BSTR;
830 hr = pPropBag->Read(L"TestSection\\@Name4", &vari, NULL);
831 ok_long(hr, S_OK);
832 ok_wstr(V_BSTR(&vari), L"1234abc");
833 VariantClear(&vari);
834
835 pPropBag->Release();
836
838}
839
841{
842 HDC hDC = GetDC(NULL);
843 INT cxWidth = GetDeviceCaps(hDC, HORZRES);
844 INT cyHeight = GetDeviceCaps(hDC, VERTRES);
845 INT cMonitors = GetSystemMetrics(SM_CMONITORS);
847
848 WCHAR szBuff1[64], szBuff2[64];
849 StringCchPrintfW(szBuff1, _countof(szBuff1), L"%dx%d(%d)", cxWidth, cyHeight, cMonitors);
850
851 szBuff2[0] = UNICODE_NULL;
852 SHGetPerScreenResName(szBuff2, _countof(szBuff2), 0);
853 ok_wstr(szBuff1, szBuff2);
854}
855
856START_TEST(SHPropertyBag)
857{
865}
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:3549
DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out, DWORD outLen, LPCWSTR filename)
Definition: ordinal.c:3502
HRESULT WINAPI SHCreatePropertyBagOnRegKey(HKEY hKey, LPCWSTR subkey, DWORD grfMode, REFIID riid, void **ppv)
Definition: ordinal.c:5398
HRESULT WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LPLONG pValue)
Definition: ordinal.c:5806
#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 Read([in] ULONG cProperties, [in] PROPBAG2 *pPropBag, [in] IErrorLog *pErrLog, [out] VARIANT *pvarValue, [out] HRESULT *phrError)
HRESULT Write([in] ULONG cProperties, [in] PROPBAG2 *pPropBag, [in] VARIANT *pvarValue)
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 ZeroMemory
Definition: minwinbase.h:31
#define CopyMemory
Definition: minwinbase.h:29
CONST void * LPCVOID
Definition: minwindef.h:164
#define error(str)
Definition: mkdosfs.c:1605
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HDC
Definition: imagelist.c:88
static LPOLESTR
Definition: stg_prop.c:27
_In_ LPWSTR _In_ DWORD _In_ LPCVOID pvData
Definition: netsh.h:116
#define REG_BINARY
Definition: nt_native.h:1499
#define KEY_READ
Definition: nt_native.h:1026
#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:615
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()
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_ACCESSDENIED
Definition: winerror.h:4116
#define 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)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193