1 /* Unit test suite for SHLWAPI ordinal functions
3 * Copyright 2004 Jon Griffiths
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
33 /* Function ptrs for ordinal calls */
34 static HMODULE hShlwapi;
35 static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
36 static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
38 static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
39 static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
40 static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
41 static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
42 static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
43 static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*);
44 static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD);
45 static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
46 static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG);
47 static LONG (WINAPI *pSHSetWindowBits)(HWND, INT, UINT, UINT);
48 static INT (WINAPI *pSHFormatDateTimeA)(const FILETIME UNALIGNED*, DWORD*, LPSTR, UINT);
49 static INT (WINAPI *pSHFormatDateTimeW)(const FILETIME UNALIGNED*, DWORD*, LPWSTR, UINT);
50 static DWORD (WINAPI *pSHGetObjectCompatFlags)(IUnknown*, const CLSID*);
51 static BOOL (WINAPI *pGUIDFromStringA)(LPSTR, CLSID *);
53 static HMODULE hmlang;
54 static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
56 static const CHAR ie_international[] = {
57 'S','o','f','t','w','a','r','e','\\',
58 'M','i','c','r','o','s','o','f','t','\\',
59 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
60 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
61 static const CHAR acceptlanguage[] = {
62 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
65 static void test_GetAcceptLanguagesA(void)
67 static LPCSTR table[] = {"de,en-gb;q=0.7,en;q=0.3",
68 "de,en;q=0.3,en-gb;q=0.7", /* sorting is ignored */
69 "winetest", /* content is ignored */
79 LONG res_query = ERROR_SUCCESS;
82 DWORD maxlen = sizeof(buffer) - 2;
88 if (!pGetAcceptLanguagesA) {
89 win_skip("GetAcceptLanguagesA is not available\n");
93 lcid = GetUserDefaultLCID();
95 /* Get the original Value */
96 lres = RegOpenKeyA(HKEY_CURRENT_USER, ie_international, &hroot);
98 skip("RegOpenKey(%s) failed: %d\n", ie_international, lres);
101 len = sizeof(original);
103 res_query = RegQueryValueExA(hroot, acceptlanguage, 0, NULL, (PBYTE)original, &len);
105 RegDeleteValue(hroot, acceptlanguage);
107 /* Some windows versions use "lang-COUNTRY" as default */
108 memset(language, 0, sizeof(language));
109 len = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, language, sizeof(language));
112 lstrcat(language, "-");
113 memset(buffer, 0, sizeof(buffer));
114 len = GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, buffer, sizeof(buffer) - len - 1);
115 lstrcat(language, buffer);
119 /* LOCALE_SNAME has additional parts in some languages. Try only as last chance */
120 memset(language, 0, sizeof(language));
121 len = GetLocaleInfoA(lcid, LOCALE_SNAME, language, sizeof(language));
124 /* get the default value */
126 memset(buffer, '#', maxlen);
128 hr = pGetAcceptLanguagesA( buffer, &len);
131 win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr);
132 goto restore_original;
135 if (lstrcmpA(buffer, language)) {
136 /* some windows versions use "lang" or "lang-country" as default */
138 if (pLcidToRfc1766A) {
139 hr = pLcidToRfc1766A(lcid, language, sizeof(language));
140 ok(hr == S_OK, "LcidToRfc1766A returned 0x%x and %s\n", hr, language);
144 ok(!lstrcmpA(buffer, language),
145 "have '%s' (searching for '%s')\n", language, buffer);
147 if (lstrcmpA(buffer, language)) {
148 win_skip("no more ideas, how to build the default language '%s'\n", buffer);
149 goto restore_original;
152 trace("detected default: %s\n", language);
153 while ((entry = table[i])) {
155 exactsize = lstrlenA(entry);
157 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) entry, exactsize + 1);
158 ok(!lres, "got %d for RegSetValueExA: %s\n", lres, entry);
160 /* len includes space for the terminating 0 before vista/w2k8 */
162 memset(buffer, '#', maxlen);
164 hr = pGetAcceptLanguagesA( buffer, &len);
165 ok(((hr == E_INVALIDARG) && (len == 0)) ||
167 ((len == exactsize) || (len == exactsize+1)) &&
168 !lstrcmpA(buffer, entry)),
169 "+2_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
172 memset(buffer, '#', maxlen);
174 hr = pGetAcceptLanguagesA( buffer, &len);
175 ok(((hr == E_INVALIDARG) && (len == 0)) ||
177 ((len == exactsize) || (len == exactsize+1)) &&
178 !lstrcmpA(buffer, entry)),
179 "+1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
182 memset(buffer, '#', maxlen);
184 hr = pGetAcceptLanguagesA( buffer, &len);
186 /* There is no space for the string in the registry.
187 When the buffer is large enough, the default language is returned
189 When the buffer is to small for that fallback, win7_32 and w2k8_64
190 and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), but
191 recent os succeed and return a partial result while
192 older os succeed and overflow the buffer */
194 ok(((hr == E_INVALIDARG) && (len == 0)) ||
195 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
196 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
197 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
198 "==_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
202 memset(buffer, '#', maxlen);
204 hr = pGetAcceptLanguagesA( buffer, &len);
205 ok(((hr == E_INVALIDARG) && (len == 0)) ||
206 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
207 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
208 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
209 "-1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
213 memset(buffer, '#', maxlen);
215 hr = pGetAcceptLanguagesA( buffer, &len);
216 ok(((hr == E_INVALIDARG) && (len == 0)) ||
217 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
218 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
219 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
220 "=1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
223 hr = pGetAcceptLanguagesA( NULL, &len);
225 /* w2k3 and below: E_FAIL and untouched len,
226 since w2k8: S_OK and needed size (excluding 0) */
227 ok( ((hr == S_OK) && (len == exactsize)) ||
228 ((hr == E_FAIL) && (len == maxlen)),
229 "NULL,max #%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
234 /* without a value in the registry, a default language is returned */
235 RegDeleteValue(hroot, acceptlanguage);
238 memset(buffer, '#', maxlen);
240 hr = pGetAcceptLanguagesA( buffer, &len);
241 ok( ((hr == S_OK) && (len == lstrlenA(language))),
242 "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n",
243 hr, len, buffer, lstrlenA(language), language);
246 memset(buffer, '#', maxlen);
248 hr = pGetAcceptLanguagesA( buffer, &len);
249 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
250 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
251 "=2: got 0x%x with %d and %s\n", hr, len, buffer);
254 memset(buffer, '#', maxlen);
256 hr = pGetAcceptLanguagesA( buffer, &len);
257 /* When the buffer is to small, win7_32 and w2k8_64 and above fail with
258 HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), other versions suceed
259 and return a partial 0 terminated result while other versions
260 fail with E_INVALIDARG and return a partial unterminated result */
261 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
262 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
263 "=1: got 0x%x with %d and %s\n", hr, len, buffer);
266 memset(buffer, '#', maxlen);
268 hr = pGetAcceptLanguagesA( buffer, &len);
269 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
270 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
271 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
273 memset(buffer, '#', maxlen);
275 hr = pGetAcceptLanguagesA( buffer, NULL);
276 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
277 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
278 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
281 hr = pGetAcceptLanguagesA( NULL, NULL);
282 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
283 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
284 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
288 len = lstrlenA(original);
289 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) original, len ? len + 1: 0);
290 ok(!lres, "RegSetValueEx(%s) failed: %d\n", original, lres);
294 RegDeleteValue(hroot, acceptlanguage);
299 static void test_SHSearchMapInt(void)
301 int keys[8], values[8];
304 if (!pSHSearchMapInt)
307 memset(keys, 0, sizeof(keys));
308 memset(values, 0, sizeof(values));
309 keys[0] = 99; values[0] = 101;
311 /* NULL key/value lists crash native, so skip testing them */
314 i = pSHSearchMapInt(keys, values, 1, keys[0]);
315 ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
317 /* Key doesn't exist */
318 i = pSHSearchMapInt(keys, values, 1, 100);
319 ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);
321 /* Len = 0 => not found */
322 i = pSHSearchMapInt(keys, values, 0, keys[0]);
323 ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);
325 /* 2 elements, len = 1 */
326 keys[1] = 98; values[1] = 102;
327 i = pSHSearchMapInt(keys, values, 1, keys[1]);
328 ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);
330 /* 2 elements, len = 2 */
331 i = pSHSearchMapInt(keys, values, 2, keys[1]);
332 ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);
334 /* Searches forward */
335 keys[2] = 99; values[2] = 103;
336 i = pSHSearchMapInt(keys, values, 3, keys[0]);
337 ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
340 static void test_alloc_shared(void)
348 procid=GetCurrentProcessId();
349 hmem=pSHAllocShared(NULL,10,procid);
350 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
351 ret = pSHFreeShared(hmem, procid);
352 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
355 hmem=pSHAllocShared(&val,4,procid);
356 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
358 p=pSHLockShared(hmem,procid);
359 ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
361 ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
362 ret = pSHUnlockShared(p);
363 ok( ret, "SHUnlockShared failed: %u\n", GetLastError());
365 ret = pSHFreeShared(hmem, procid);
366 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
369 static void test_fdsa(void)
373 DWORD num_items; /* Number of elements inserted */
374 void *mem; /* Ptr to array */
375 DWORD blocks_alloced; /* Number of elements allocated */
376 BYTE inc; /* Number of elements to grow by when we need to expand */
377 BYTE block_size; /* Size in bytes of an element */
378 BYTE flags; /* Flags */
381 BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
383 BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
384 DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
385 BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);
388 int block_size = 10, init_blocks = 4, inc = 2;
392 pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
393 pFDSA_Destroy = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
394 pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
395 pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);
397 mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
398 memset(&info, 0, sizeof(info));
400 ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
401 ok(info.num_items == 0, "num_items = %d\n", info.num_items);
402 ok(info.mem == mem, "mem = %p\n", info.mem);
403 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
404 ok(info.inc == inc, "inc = %d\n", info.inc);
405 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
406 ok(info.flags == 0, "flags = %d\n", info.flags);
408 ret = pFDSA_InsertItem(&info, 1234, "1234567890");
409 ok(ret == 0, "ret = %d\n", ret);
410 ok(info.num_items == 1, "num_items = %d\n", info.num_items);
411 ok(info.mem == mem, "mem = %p\n", info.mem);
412 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
413 ok(info.inc == inc, "inc = %d\n", info.inc);
414 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
415 ok(info.flags == 0, "flags = %d\n", info.flags);
417 ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
418 ok(ret == 1, "ret = %d\n", ret);
420 ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
421 ok(ret == 1, "ret = %d\n", ret);
423 ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
424 ok(ret == 0, "ret = %d\n", ret);
425 ok(info.mem == mem, "mem = %p\n", info.mem);
426 ok(info.flags == 0, "flags = %d\n", info.flags);
428 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
429 ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
430 ok(ret == 0, "ret = %d\n", ret);
431 ok(info.mem != mem, "mem = %p\n", info.mem);
432 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
433 ok(info.flags == 0x1, "flags = %d\n", info.flags);
435 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
437 ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
438 ok(info.mem != mem, "mem = %p\n", info.mem);
439 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
440 ok(info.flags == 0x1, "flags = %d\n", info.flags);
442 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
444 ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
445 ok(info.mem != mem, "mem = %p\n", info.mem);
446 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
447 ok(info.flags == 0x1, "flags = %d\n", info.flags);
449 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
451 ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
453 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
454 ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
457 /* When Initialize is called with inc = 0, set it to 1 */
458 ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
459 ok(info.inc == 1, "inc = %d\n", info.inc);
461 /* This time, because shlwapi hasn't had to allocate memory
462 internally, Destroy rets non-zero */
463 ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");
466 HeapFree(GetProcessHeap(), 0, mem);
470 typedef struct SHELL_USER_SID {
471 SID_IDENTIFIER_AUTHORITY sidAuthority;
474 } SHELL_USER_SID, *PSHELL_USER_SID;
475 typedef struct SHELL_USER_PERMISSION {
476 SHELL_USER_SID susID;
481 DWORD dwInheritAccessMask;
482 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
483 static void test_GetShellSecurityDescriptor(void)
485 SHELL_USER_PERMISSION supCurrentUserFull = {
486 { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
487 ACCESS_ALLOWED_ACE_TYPE, FALSE,
489 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
490 SHELL_USER_PERMISSION supEveryoneDenied = {
491 { {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 },
492 ACCESS_DENIED_ACE_TYPE, TRUE,
493 GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ };
494 PSHELL_USER_PERMISSION rgsup[2] = {
495 &supCurrentUserFull, &supEveryoneDenied,
497 SECURITY_DESCRIPTOR* psd;
498 SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
500 pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);
502 if(!pGetShellSecurityDescriptor)
504 win_skip("GetShellSecurityDescriptor not available\n");
508 psd = pGetShellSecurityDescriptor(NULL, 2);
510 broken(psd==INVALID_HANDLE_VALUE), /* IE5 */
511 "GetShellSecurityDescriptor should fail\n");
512 psd = pGetShellSecurityDescriptor(rgsup, 0);
513 ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
515 SetLastError(0xdeadbeef);
516 psd = pGetShellSecurityDescriptor(rgsup, 2);
517 if (psd == NULL && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
519 /* The previous calls to GetShellSecurityDescriptor don't set the last error */
520 win_skip("GetShellSecurityDescriptor is not implemented\n");
523 if (psd==INVALID_HANDLE_VALUE)
525 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
528 ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
531 BOOL bHasDacl = FALSE, bDefaulted;
534 SECURITY_DESCRIPTOR_CONTROL control;
536 ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
538 ok(GetSecurityDescriptorControl(psd, &control, &dwRev),
539 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
540 ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");
542 ok(GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted),
543 "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
545 ok(bHasDacl, "SD has no DACL\n");
548 ok(!bDefaulted, "DACL should not be defaulted\n");
550 ok(pAcl != NULL, "NULL DACL!\n");
553 ACL_SIZE_INFORMATION asiSize;
555 ok(IsValidAcl(pAcl), "DACL is not valid\n");
557 ok(GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation),
558 "GetAclInformation failed with error %u\n", GetLastError());
560 ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
561 if (asiSize.AceCount == 3)
563 ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
565 ok(GetAce(pAcl, 0, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
566 ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
567 "Invalid ACE type %d\n", paaa->Header.AceType);
568 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
569 ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);
571 ok(GetAce(pAcl, 1, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
572 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
573 "Invalid ACE type %d\n", paaa->Header.AceType);
574 /* first one of two ACEs generated from inheritable entry - without inheritance */
575 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
576 ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);
578 ok(GetAce(pAcl, 2, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
579 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
580 "Invalid ACE type %d\n", paaa->Header.AceType);
581 /* second ACE - with inheritance */
582 ok(paaa->Header.AceFlags == MY_INHERITANCE,
583 "Invalid ACE flags %x\n", paaa->Header.AceFlags);
584 ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
593 static void test_SHPackDispParams(void)
599 if(!pSHPackDispParams)
600 win_skip("SHPackSidpParams not available\n");
602 memset(¶ms, 0xc0, sizeof(params));
603 memset(vars, 0xc0, sizeof(vars));
604 hres = pSHPackDispParams(¶ms, vars, 1, VT_I4, 0xdeadbeef);
605 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
606 ok(params.cArgs == 1, "params.cArgs = %d\n", params.cArgs);
607 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
608 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
609 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
610 ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars));
611 ok(V_I4(vars) == 0xdeadbeef, "failed %x\n", V_I4(vars));
613 memset(¶ms, 0xc0, sizeof(params));
614 hres = pSHPackDispParams(¶ms, NULL, 0, 0);
615 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
616 ok(params.cArgs == 0, "params.cArgs = %d\n", params.cArgs);
617 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
618 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
619 ok(params.rgvarg == NULL, "params.rgvarg = %p\n", params.rgvarg);
621 memset(vars, 0xc0, sizeof(vars));
622 memset(¶ms, 0xc0, sizeof(params));
623 hres = pSHPackDispParams(¶ms, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10,
624 VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef);
625 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
626 ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs);
627 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
628 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
629 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
630 ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars));
631 ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars));
632 ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1));
633 ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1));
634 ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2));
635 ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2));
636 ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3));
637 ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
642 const IDispatchVtbl *vtbl;
646 typedef struct _contain
648 const IConnectionPointContainerVtbl *vtbl;
652 IConnectionPoint **pt;
655 typedef struct _cntptn
657 const IConnectionPointVtbl *vtbl;
668 const IEnumConnectionsVtbl *vtbl;
675 typedef struct _enumpt
677 const IEnumConnectionPointsVtbl *vtbl;
685 static HRESULT WINAPI Disp_QueryInterface(
692 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
699 IUnknown_AddRef(This);
703 trace("no interface\n");
704 return E_NOINTERFACE;
707 static ULONG WINAPI Disp_AddRef(IDispatch* This)
709 Disp *iface = (Disp*)This;
710 return InterlockedIncrement(&iface->refCount);
713 static ULONG WINAPI Disp_Release(IDispatch* This)
715 Disp *iface = (Disp*)This;
718 ret = InterlockedDecrement(&iface->refCount);
720 HeapFree(GetProcessHeap(),0,This);
724 static HRESULT WINAPI Disp_GetTypeInfoCount(
728 return ERROR_SUCCESS;
731 static HRESULT WINAPI Disp_GetTypeInfo(
737 return ERROR_SUCCESS;
740 static HRESULT WINAPI Disp_GetIDsOfNames(
748 return ERROR_SUCCESS;
751 static HRESULT WINAPI Disp_Invoke(
757 DISPPARAMS *pDispParams,
759 EXCEPINFO *pExcepInfo,
762 trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
764 ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
765 ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
766 ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
767 ok(lcid == 0,"Wrong lcid %x\n",lcid);
768 if (dispIdMember == 0xa0)
770 ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
771 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
772 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
773 ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
775 else if (dispIdMember == 0xa1)
777 ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
778 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
779 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
780 ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
781 ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
782 ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
783 ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
786 return ERROR_SUCCESS;
789 static const IDispatchVtbl disp_vtbl = {
794 Disp_GetTypeInfoCount,
800 static HRESULT WINAPI Enum_QueryInterface(
801 IEnumConnections* This,
807 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
814 IUnknown_AddRef(This);
818 trace("no interface\n");
819 return E_NOINTERFACE;
822 static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
824 EnumCon *iface = (EnumCon*)This;
825 return InterlockedIncrement(&iface->refCount);
828 static ULONG WINAPI Enum_Release(IEnumConnections* This)
830 EnumCon *iface = (EnumCon*)This;
833 ret = InterlockedDecrement(&iface->refCount);
835 HeapFree(GetProcessHeap(),0,This);
839 static HRESULT WINAPI Enum_Next(
840 IEnumConnections* This,
845 EnumCon *iface = (EnumCon*)This;
847 if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
849 rgcd->pUnk = iface->pt->sink[iface->idx];
850 IUnknown_AddRef(iface->pt->sink[iface->idx]);
861 static HRESULT WINAPI Enum_Skip(
862 IEnumConnections* This,
868 static HRESULT WINAPI Enum_Reset(
869 IEnumConnections* This)
874 static HRESULT WINAPI Enum_Clone(
875 IEnumConnections* This,
876 IEnumConnections **ppEnum)
881 static const IEnumConnectionsVtbl enum_vtbl = {
892 static HRESULT WINAPI ConPt_QueryInterface(
893 IConnectionPoint* This,
899 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
906 IUnknown_AddRef(This);
910 trace("no interface\n");
911 return E_NOINTERFACE;
914 static ULONG WINAPI ConPt_AddRef(
915 IConnectionPoint* This)
917 ConPt *iface = (ConPt*)This;
918 return InterlockedIncrement(&iface->refCount);
921 static ULONG WINAPI ConPt_Release(
922 IConnectionPoint* This)
924 ConPt *iface = (ConPt*)This;
927 ret = InterlockedDecrement(&iface->refCount);
930 if (iface->sinkCount > 0)
933 for (i = 0; i < iface->sinkCount; i++)
936 IUnknown_Release(iface->sink[i]);
938 HeapFree(GetProcessHeap(),0,iface->sink);
940 HeapFree(GetProcessHeap(),0,This);
945 static HRESULT WINAPI ConPt_GetConnectionInterface(
946 IConnectionPoint* This,
950 ConPt *iface = (ConPt*)This;
957 memcpy(pIID,&iface->id,sizeof(GUID));
961 static HRESULT WINAPI ConPt_GetConnectionPointContainer(
962 IConnectionPoint* This,
963 IConnectionPointContainer **ppCPC)
965 ConPt *iface = (ConPt*)This;
967 *ppCPC = (IConnectionPointContainer*)iface->container;
971 static HRESULT WINAPI ConPt_Advise(
972 IConnectionPoint* This,
976 ConPt *iface = (ConPt*)This;
978 if (iface->sinkCount == 0)
979 iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
981 iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
982 iface->sink[iface->sinkCount] = pUnkSink;
983 IUnknown_AddRef(pUnkSink);
985 *pdwCookie = iface->sinkCount;
989 static HRESULT WINAPI ConPt_Unadvise(
990 IConnectionPoint* This,
993 ConPt *iface = (ConPt*)This;
995 if (dwCookie > iface->sinkCount)
999 IUnknown_Release(iface->sink[dwCookie-1]);
1000 iface->sink[dwCookie-1] = NULL;
1005 static HRESULT WINAPI ConPt_EnumConnections(
1006 IConnectionPoint* This,
1007 IEnumConnections **ppEnum)
1011 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
1012 ec->vtbl = &enum_vtbl;
1014 ec->pt = (ConPt*)This;
1016 *ppEnum = (IEnumConnections*)ec;
1021 static const IConnectionPointVtbl point_vtbl = {
1022 ConPt_QueryInterface,
1026 ConPt_GetConnectionInterface,
1027 ConPt_GetConnectionPointContainer,
1030 ConPt_EnumConnections
1033 static HRESULT WINAPI EnumPt_QueryInterface(
1034 IEnumConnectionPoints* This,
1040 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
1047 IUnknown_AddRef(This);
1051 trace("no interface\n");
1052 return E_NOINTERFACE;
1055 static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
1057 EnumPt *iface = (EnumPt*)This;
1058 return InterlockedIncrement(&iface->refCount);
1061 static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
1063 EnumPt *iface = (EnumPt*)This;
1066 ret = InterlockedDecrement(&iface->refCount);
1068 HeapFree(GetProcessHeap(),0,This);
1072 static HRESULT WINAPI EnumPt_Next(
1073 IEnumConnectionPoints* This,
1075 IConnectionPoint **rgcd,
1078 EnumPt *iface = (EnumPt*)This;
1080 if (cConnections > 0 && iface->idx < iface->container->ptCount)
1082 *rgcd = iface->container->pt[iface->idx];
1083 IUnknown_AddRef(iface->container->pt[iface->idx]);
1093 static HRESULT WINAPI EnumPt_Skip(
1094 IEnumConnectionPoints* This,
1100 static HRESULT WINAPI EnumPt_Reset(
1101 IEnumConnectionPoints* This)
1106 static HRESULT WINAPI EnumPt_Clone(
1107 IEnumConnectionPoints* This,
1108 IEnumConnectionPoints **ppEnumPt)
1113 static const IEnumConnectionPointsVtbl enumpt_vtbl = {
1115 EnumPt_QueryInterface,
1124 static HRESULT WINAPI Contain_QueryInterface(
1125 IConnectionPointContainer* This,
1131 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
1138 IUnknown_AddRef(This);
1142 trace("no interface\n");
1143 return E_NOINTERFACE;
1146 static ULONG WINAPI Contain_AddRef(
1147 IConnectionPointContainer* This)
1149 Contain *iface = (Contain*)This;
1150 return InterlockedIncrement(&iface->refCount);
1153 static ULONG WINAPI Contain_Release(
1154 IConnectionPointContainer* This)
1156 Contain *iface = (Contain*)This;
1159 ret = InterlockedDecrement(&iface->refCount);
1162 if (iface->ptCount > 0)
1165 for (i = 0; i < iface->ptCount; i++)
1166 IUnknown_Release(iface->pt[i]);
1167 HeapFree(GetProcessHeap(),0,iface->pt);
1169 HeapFree(GetProcessHeap(),0,This);
1174 static HRESULT WINAPI Contain_EnumConnectionPoints(
1175 IConnectionPointContainer* This,
1176 IEnumConnectionPoints **ppEnum)
1180 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
1181 ec->vtbl = &enumpt_vtbl;
1184 ec->container = (Contain*)This;
1185 *ppEnum = (IEnumConnectionPoints*)ec;
1190 static HRESULT WINAPI Contain_FindConnectionPoint(
1191 IConnectionPointContainer* This,
1193 IConnectionPoint **ppCP)
1195 Contain *iface = (Contain*)This;
1198 if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
1200 pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
1201 pt->vtbl = &point_vtbl;
1205 pt->container = iface;
1206 pt->id = IID_IDispatch;
1208 if (iface->ptCount == 0)
1209 iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1211 iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
1212 iface->pt[iface->ptCount] = (IConnectionPoint*)pt;
1215 *ppCP = (IConnectionPoint*)pt;
1219 *ppCP = iface->pt[0];
1220 IUnknown_AddRef((IUnknown*)*ppCP);
1226 static const IConnectionPointContainerVtbl contain_vtbl = {
1227 Contain_QueryInterface,
1231 Contain_EnumConnectionPoints,
1232 Contain_FindConnectionPoint
1235 static void test_IConnectionPoint(void)
1239 IConnectionPoint *point;
1242 DWORD cookie = 0xffffffff;
1246 if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
1248 win_skip("IConnectionPoint Apis not present\n");
1252 container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
1253 container->vtbl = &contain_vtbl;
1254 container->refCount = 1;
1255 container->ptCount = 0;
1256 container->pt = NULL;
1258 dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
1259 dispatch->vtbl = &disp_vtbl;
1260 dispatch->refCount = 1;
1262 rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
1263 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1264 ok(point != NULL, "returned ConnectionPoint is NULL\n");
1265 ok(cookie != 0xffffffff, "invalid cookie returned\n");
1267 rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
1268 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1270 if (pSHPackDispParams)
1272 memset(¶ms, 0xc0, sizeof(params));
1273 memset(vars, 0xc0, sizeof(vars));
1274 rc = pSHPackDispParams(¶ms, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
1275 ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
1277 rc = pIConnectionPoint_SimpleInvoke(point,0xa1,¶ms);
1278 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1281 win_skip("pSHPackDispParams not present\n");
1283 rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
1284 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1286 /* MSDN says this should be required but it crashs on XP
1287 IUnknown_Release(point);
1289 ref = IUnknown_Release((IUnknown*)container);
1290 ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
1291 ref = IUnknown_Release((IUnknown*)dispatch);
1292 ok(ref == 0, "leftover IDispatch reference %i\n",ref);
1295 typedef struct _propbag
1297 const IPropertyBagVtbl *vtbl;
1303 static HRESULT WINAPI Prop_QueryInterface(
1310 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPropertyBag))
1317 IUnknown_AddRef(This);
1321 trace("no interface\n");
1322 return E_NOINTERFACE;
1325 static ULONG WINAPI Prop_AddRef(
1328 PropBag *iface = (PropBag*)This;
1329 return InterlockedIncrement(&iface->refCount);
1332 static ULONG WINAPI Prop_Release(
1335 PropBag *iface = (PropBag*)This;
1338 ret = InterlockedDecrement(&iface->refCount);
1340 HeapFree(GetProcessHeap(),0,This);
1344 static HRESULT WINAPI Prop_Read(
1346 LPCOLESTR pszPropName,
1348 IErrorLog *pErrorLog)
1350 V_VT(pVar) = VT_BLOB|VT_BYREF;
1351 V_BYREF(pVar) = (LPVOID)0xdeadcafe;
1355 static HRESULT WINAPI Prop_Write(
1357 LPCOLESTR pszPropName,
1364 static const IPropertyBagVtbl prop_vtbl = {
1365 Prop_QueryInterface,
1373 static void test_SHPropertyBag_ReadLONG(void)
1378 static const WCHAR szName1[] = {'n','a','m','e','1',0};
1380 if (!pSHPropertyBag_ReadLONG)
1382 win_skip("SHPropertyBag_ReadLONG not present\n");
1386 pb = HeapAlloc(GetProcessHeap(),0,sizeof(PropBag));
1388 pb->vtbl = &prop_vtbl;
1391 rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out);
1392 ok(rc == E_INVALIDARG || broken(rc == 0), "incorrect return %x\n",rc);
1393 ok(out == 0xfeedface, "value should not have changed\n");
1394 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, NULL, &out);
1395 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1396 ok(out == 0xfeedface, "value should not have changed\n");
1397 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, NULL);
1398 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1399 ok(out == 0xfeedface, "value should not have changed\n");
1400 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, &out);
1401 ok(rc == DISP_E_BADVARTYPE || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1402 ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %x\n",out);
1403 IUnknown_Release((IUnknown*)pb);
1408 static void test_SHSetWindowBits(void)
1411 DWORD style, styleold;
1414 if(!pSHSetWindowBits)
1416 win_skip("SHSetWindowBits is not available\n");
1421 clsA.lpfnWndProc = DefWindowProcA;
1422 clsA.cbClsExtra = 0;
1423 clsA.cbWndExtra = 0;
1424 clsA.hInstance = GetModuleHandleA(NULL);
1426 clsA.hCursor = LoadCursorA(0, IDC_ARROW);
1427 clsA.hbrBackground = NULL;
1428 clsA.lpszMenuName = NULL;
1429 clsA.lpszClassName = "Shlwapi test class";
1430 RegisterClassA(&clsA);
1432 hwnd = CreateWindowA("Shlwapi test class", "Test", WS_VISIBLE, 0, 0, 100, 100,
1433 NULL, NULL, GetModuleHandle(NULL), 0);
1434 ok(IsWindow(hwnd), "failed to create window\n");
1437 SetLastError(0xdeadbeef);
1438 style = pSHSetWindowBits(NULL, GWL_STYLE, 0, 0);
1439 ok(style == 0, "expected 0 retval, got %d\n", style);
1440 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE ||
1441 broken(GetLastError() == 0xdeadbeef), /* Win9x/WinMe */
1442 "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
1444 /* zero mask, zero flags */
1445 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1446 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, 0);
1447 ok(styleold == style, "expected old style\n");
1448 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1451 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1452 ok(styleold & WS_VISIBLE, "expected WS_VISIBLE\n");
1453 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1455 ok(style == styleold, "expected previous style, got %x\n", style);
1456 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1458 /* test mask, unset style bit used */
1459 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1460 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1461 ok(style == styleold, "expected previous style, got %x\n", style);
1462 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1464 /* set back with flags */
1465 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1466 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, WS_VISIBLE);
1467 ok(style == styleold, "expected previous style, got %x\n", style);
1468 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "expected updated style\n");
1470 /* reset and try to set without a mask */
1471 pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1472 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1473 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1474 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, WS_VISIBLE);
1475 ok(style == styleold, "expected previous style, got %x\n", style);
1476 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1478 DestroyWindow(hwnd);
1480 UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL));
1483 static void test_SHFormatDateTimeA(void)
1485 FILETIME UNALIGNED filetime;
1486 CHAR buff[100], buff2[100], buff3[100];
1491 if(!pSHFormatDateTimeA)
1493 win_skip("pSHFormatDateTimeA isn't available\n");
1499 /* crashes on native */
1500 ret = pSHFormatDateTimeA(NULL, NULL, NULL, 0);
1504 SystemTimeToFileTime(&st, &filetime);
1505 /* SHFormatDateTime expects input as utc */
1506 LocalFileTimeToFileTime(&filetime, &filetime);
1508 /* no way to get required buffer length here */
1509 SetLastError(0xdeadbeef);
1510 ret = pSHFormatDateTimeA(&filetime, NULL, NULL, 0);
1511 ok(ret == 0, "got %d\n", ret);
1512 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1514 SetLastError(0xdeadbeef);
1515 buff[0] = 'a'; buff[1] = 0;
1516 ret = pSHFormatDateTimeA(&filetime, NULL, buff, 0);
1517 ok(ret == 0, "got %d\n", ret);
1518 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1519 ok(buff[0] == 'a', "expected same string, got %s\n", buff);
1521 /* flags needs to have FDTF_NOAUTOREADINGORDER for these tests to succeed on Vista+ */
1523 /* all combinations documented as invalid succeeded */
1524 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME | FDTF_LONGTIME;
1525 SetLastError(0xdeadbeef);
1526 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1527 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1528 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1530 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGDATE;
1531 SetLastError(0xdeadbeef);
1532 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1533 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1534 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1536 flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
1537 SetLastError(0xdeadbeef);
1538 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1539 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1540 ok(GetLastError() == 0xdeadbeef ||
1541 broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe */
1542 "expected 0xdeadbeef, got %d\n", GetLastError());
1544 /* now check returned strings */
1545 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME;
1546 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1547 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1548 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2));
1549 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1550 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1552 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME;
1553 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1554 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1555 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1556 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1557 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1559 /* both time flags */
1560 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME | FDTF_SHORTTIME;
1561 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1562 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1563 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1564 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1565 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1567 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE;
1568 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1569 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1570 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1571 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1572 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1574 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE;
1575 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1576 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1577 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1578 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1579 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1581 /* both date flags */
1582 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTDATE;
1583 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1584 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1585 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1586 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1587 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1589 /* various combinations of date/time flags */
1590 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTTIME;
1591 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1592 ok(ret == lstrlenA(buff)+1, "got %d, length %d\n", ret, lstrlenA(buff)+1);
1593 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1594 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1595 strcat(buff2, ", ");
1596 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1597 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1598 strcat(buff2, buff3);
1599 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1601 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_LONGTIME;
1602 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1603 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1604 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1605 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1606 strcat(buff2, ", ");
1607 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1608 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1609 strcat(buff2, buff3);
1610 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1612 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_SHORTTIME;
1613 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1614 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1615 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1616 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1618 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1619 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1620 strcat(buff2, buff3);
1621 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1623 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGTIME;
1624 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1625 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1626 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1627 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1629 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1630 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1631 strcat(buff2, buff3);
1632 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1635 static void test_SHFormatDateTimeW(void)
1637 FILETIME UNALIGNED filetime;
1638 WCHAR buff[100], buff2[100], buff3[100];
1642 static const WCHAR spaceW[] = {' ',0};
1643 static const WCHAR commaW[] = {',',' ',0};
1645 if(!pSHFormatDateTimeW)
1647 win_skip("pSHFormatDateTimeW isn't available\n");
1653 /* crashes on native */
1654 ret = pSHFormatDateTimeW(NULL, NULL, NULL, 0);
1658 SystemTimeToFileTime(&st, &filetime);
1659 /* SHFormatDateTime expects input as utc */
1660 LocalFileTimeToFileTime(&filetime, &filetime);
1662 /* no way to get required buffer length here */
1663 SetLastError(0xdeadbeef);
1664 ret = pSHFormatDateTimeW(&filetime, NULL, NULL, 0);
1665 ok(ret == 0, "got %d\n", ret);
1666 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1668 SetLastError(0xdeadbeef);
1669 buff[0] = 'a'; buff[1] = 0;
1670 ret = pSHFormatDateTimeW(&filetime, NULL, buff, 0);
1671 ok(ret == 0, "got %d\n", ret);
1672 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1673 ok(buff[0] == 'a', "expected same string\n");
1675 /* all combinations documented as invalid succeeded */
1676 flags = FDTF_SHORTTIME | FDTF_LONGTIME;
1677 SetLastError(0xdeadbeef);
1678 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1679 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1680 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1682 flags = FDTF_SHORTDATE | FDTF_LONGDATE;
1683 SetLastError(0xdeadbeef);
1684 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1685 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1686 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1688 flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
1689 SetLastError(0xdeadbeef);
1690 buff[0] = 0; /* NT4 doesn't clear the buffer on failure */
1691 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1692 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1693 ok(GetLastError() == 0xdeadbeef ||
1694 broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe/NT4 */
1695 "expected 0xdeadbeef, got %d\n", GetLastError());
1697 /* now check returned strings */
1698 flags = FDTF_SHORTTIME;
1699 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1700 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1701 SetLastError(0xdeadbeef);
1702 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1703 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1705 win_skip("Needed W-functions are not implemented\n");
1708 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1709 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1711 flags = FDTF_LONGTIME;
1712 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1713 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1714 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1715 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1716 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1718 /* both time flags */
1719 flags = FDTF_LONGTIME | FDTF_SHORTTIME;
1720 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1721 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1722 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1723 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1724 ok(lstrcmpW(buff, buff2) == 0, "expected equal string\n");
1726 flags = FDTF_SHORTDATE;
1727 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1728 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1729 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1730 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1731 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1733 flags = FDTF_LONGDATE;
1734 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1735 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1736 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1737 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1738 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1740 /* both date flags */
1741 flags = FDTF_LONGDATE | FDTF_SHORTDATE;
1742 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1743 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1744 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1745 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1746 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1748 /* various combinations of date/time flags */
1749 flags = FDTF_LONGDATE | FDTF_SHORTTIME;
1750 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1751 ok(ret == lstrlenW(buff)+1, "got %d, length %d\n", ret, lstrlenW(buff)+1);
1752 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1753 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1754 lstrcatW(buff2, commaW);
1755 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1756 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1757 lstrcatW(buff2, buff3);
1758 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1760 flags = FDTF_LONGDATE | FDTF_LONGTIME;
1761 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1762 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1763 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1764 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1765 lstrcatW(buff2, commaW);
1766 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1767 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1768 lstrcatW(buff2, buff3);
1769 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1771 flags = FDTF_SHORTDATE | FDTF_SHORTTIME;
1772 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1773 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1774 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1775 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1776 lstrcatW(buff2, spaceW);
1777 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1778 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1779 lstrcatW(buff2, buff3);
1780 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1782 flags = FDTF_SHORTDATE | FDTF_LONGTIME;
1783 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1784 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1785 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1786 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1787 lstrcatW(buff2, spaceW);
1788 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1789 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1790 lstrcatW(buff2, buff3);
1791 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1794 static void test_SHGetObjectCompatFlags(void)
1796 struct compat_value {
1801 struct compat_value values[] = {
1802 { "OTNEEDSSFCACHE", 0x1 },
1803 { "NO_WEBVIEW", 0x2 },
1804 { "UNBINDABLE", 0x4 },
1806 { "NEEDSFILESYSANCESTOR", 0x10 },
1807 { "NOTAFILESYSTEM", 0x20 },
1808 { "CTXMENU_NOVERBS", 0x40 },
1809 { "CTXMENU_LIMITEDQI", 0x80 },
1810 { "COCREATESHELLFOLDERONLY", 0x100 },
1811 { "NEEDSSTORAGEANCESTOR", 0x200 },
1812 { "NOLEGACYWEBVIEW", 0x400 },
1813 { "CTXMENU_XPQCMFLAGS", 0x1000 },
1814 { "NOIPROPERTYSTORE", 0x2000 }
1817 static const char compat_path[] = "Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Objects";
1818 CHAR keyA[39]; /* {CLSID} */
1823 if (!pSHGetObjectCompatFlags)
1825 win_skip("SHGetObjectCompatFlags isn't available\n");
1830 ret = pSHGetObjectCompatFlags(NULL, NULL);
1831 ok(ret == 0, "got %d\n", ret);
1833 ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, compat_path, &root);
1834 if (ret != ERROR_SUCCESS)
1836 skip("No compatibility class data found\n");
1840 for (i = 0; RegEnumKeyA(root, i, keyA, sizeof(keyA)) == ERROR_SUCCESS; i++)
1844 if (RegOpenKeyA(root, keyA, &clsid_key) == ERROR_SUCCESS)
1847 DWORD expected = 0, got, length = sizeof(valueA);
1851 for (v = 0; RegEnumValueA(clsid_key, v, valueA, &length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; v++)
1855 for (j = 0; j < sizeof(values)/sizeof(struct compat_value); j++)
1856 if (lstrcmpA(values[j].nameA, valueA) == 0)
1858 expected |= values[j].value;
1862 length = sizeof(valueA);
1865 pGUIDFromStringA(keyA, &clsid);
1866 got = pSHGetObjectCompatFlags(NULL, &clsid);
1867 ok(got == expected, "got 0x%08x, expected 0x%08x. Key %s\n", got, expected, keyA);
1869 RegCloseKey(clsid_key);
1876 static void init_pointers(void)
1878 #define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord)))
1879 MAKEFUNC(SHAllocShared, 7);
1880 MAKEFUNC(SHLockShared, 8);
1881 MAKEFUNC(SHUnlockShared, 9);
1882 MAKEFUNC(SHFreeShared, 10);
1883 MAKEFUNC(GetAcceptLanguagesA, 14);
1884 MAKEFUNC(SHSetWindowBits, 165);
1885 MAKEFUNC(ConnectToConnectionPoint, 168);
1886 MAKEFUNC(SHSearchMapInt, 198);
1887 MAKEFUNC(GUIDFromStringA, 269);
1888 MAKEFUNC(SHPackDispParams, 282);
1889 MAKEFUNC(IConnectionPoint_InvokeWithCancel, 283);
1890 MAKEFUNC(IConnectionPoint_SimpleInvoke, 284);
1891 MAKEFUNC(SHFormatDateTimeA, 353);
1892 MAKEFUNC(SHFormatDateTimeW, 354);
1893 MAKEFUNC(SHGetObjectCompatFlags, 476);
1894 MAKEFUNC(SHPropertyBag_ReadLONG, 496);
1900 hShlwapi = GetModuleHandleA("shlwapi.dll");
1904 hmlang = LoadLibraryA("mlang.dll");
1905 pLcidToRfc1766A = (void *)GetProcAddress(hmlang, "LcidToRfc1766A");
1907 test_GetAcceptLanguagesA();
1908 test_SHSearchMapInt();
1909 test_alloc_shared();
1911 test_GetShellSecurityDescriptor();
1912 test_SHPackDispParams();
1913 test_IConnectionPoint();
1914 test_SHPropertyBag_ReadLONG();
1915 test_SHSetWindowBits();
1916 test_SHFormatDateTimeA();
1917 test_SHFormatDateTimeW();
1918 test_SHGetObjectCompatFlags();