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"
36 /* Function ptrs for ordinal calls */
37 static HMODULE hShlwapi;
38 static BOOL is_win2k_and_lower;
40 static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
41 static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
43 static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
44 static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
45 static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
46 static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
47 static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
48 static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*);
49 static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD);
50 static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
51 static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG);
52 static LONG (WINAPI *pSHSetWindowBits)(HWND, INT, UINT, UINT);
53 static INT (WINAPI *pSHFormatDateTimeA)(const FILETIME UNALIGNED*, DWORD*, LPSTR, UINT);
54 static INT (WINAPI *pSHFormatDateTimeW)(const FILETIME UNALIGNED*, DWORD*, LPWSTR, UINT);
55 static DWORD (WINAPI *pSHGetObjectCompatFlags)(IUnknown*, const CLSID*);
56 static BOOL (WINAPI *pGUIDFromStringA)(LPSTR, CLSID *);
57 static HRESULT (WINAPI *pIUnknown_QueryServiceExec)(IUnknown*, REFIID, const GUID*, DWORD, DWORD, VARIANT*, VARIANT*);
58 static HRESULT (WINAPI *pIUnknown_ProfferService)(IUnknown*, REFGUID, IServiceProvider*, DWORD*);
59 static HWND (WINAPI *pSHCreateWorkerWindowA)(LONG, HWND, DWORD, DWORD, HMENU, LONG_PTR);
60 static HRESULT (WINAPI *pSHIShellFolder_EnumObjects)(LPSHELLFOLDER, HWND, SHCONTF, IEnumIDList**);
62 static HMODULE hmlang;
63 static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
65 static const CHAR ie_international[] = {
66 'S','o','f','t','w','a','r','e','\\',
67 'M','i','c','r','o','s','o','f','t','\\',
68 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
69 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
70 static const CHAR acceptlanguage[] = {
71 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
84 static void init_call_trace(call_trace_t *ctrace)
88 ctrace->calls = HeapAlloc(GetProcessHeap(), 0, sizeof(call_entry_t) * ctrace->alloc);
91 static void free_call_trace(const call_trace_t *ctrace)
93 HeapFree(GetProcessHeap(), 0, ctrace->calls);
96 static void add_call(call_trace_t *ctrace, int id, const void *arg0,
97 const void *arg1, const void *arg2, const void *arg3, const void *arg4)
108 if (ctrace->count == ctrace->alloc)
111 ctrace->calls = HeapReAlloc(GetProcessHeap(),0, ctrace->calls, ctrace->alloc*sizeof(call_entry_t));
114 ctrace->calls[ctrace->count++] = call;
117 static void ok_trace_(call_trace_t *texpected, call_trace_t *tgot, int line)
119 if (texpected->count == tgot->count)
123 for (i = 0; i < texpected->count; i++)
125 call_entry_t *expected = &texpected->calls[i];
126 call_entry_t *got = &tgot->calls[i];
129 ok_(__FILE__, line)(expected->id == got->id, "got different ids %d: %d, %d\n", i+1, expected->id, got->id);
131 for (j = 0; j < 5; j++)
133 ok_(__FILE__, line)(expected->args[j] == got->args[j], "got different args[%d] for %d: %p, %p\n", j, i+1,
134 expected->args[j], got->args[j]);
139 ok_(__FILE__, line)(0, "traces length mismatch\n");
142 #define ok_trace(a, b) ok_trace_(a, b, __LINE__)
144 /* trace of actually made calls */
145 static call_trace_t trace_got;
147 static void test_GetAcceptLanguagesA(void)
149 static LPCSTR table[] = {"de,en-gb;q=0.7,en;q=0.3",
150 "de,en;q=0.3,en-gb;q=0.7", /* sorting is ignored */
151 "winetest", /* content is ignored */
161 LONG res_query = ERROR_SUCCESS;
164 DWORD maxlen = sizeof(buffer) - 2;
170 if (!pGetAcceptLanguagesA) {
171 win_skip("GetAcceptLanguagesA is not available\n");
175 lcid = GetUserDefaultLCID();
177 /* Get the original Value */
178 lres = RegOpenKeyA(HKEY_CURRENT_USER, ie_international, &hroot);
180 skip("RegOpenKey(%s) failed: %d\n", ie_international, lres);
183 len = sizeof(original);
185 res_query = RegQueryValueExA(hroot, acceptlanguage, 0, NULL, (PBYTE)original, &len);
187 RegDeleteValue(hroot, acceptlanguage);
189 /* Some windows versions use "lang-COUNTRY" as default */
190 memset(language, 0, sizeof(language));
191 len = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, language, sizeof(language));
194 lstrcat(language, "-");
195 memset(buffer, 0, sizeof(buffer));
196 len = GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, buffer, sizeof(buffer) - len - 1);
197 lstrcat(language, buffer);
201 /* LOCALE_SNAME has additional parts in some languages. Try only as last chance */
202 memset(language, 0, sizeof(language));
203 len = GetLocaleInfoA(lcid, LOCALE_SNAME, language, sizeof(language));
206 /* get the default value */
208 memset(buffer, '#', maxlen);
210 hr = pGetAcceptLanguagesA( buffer, &len);
213 win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr);
214 goto restore_original;
217 if (lstrcmpA(buffer, language)) {
218 /* some windows versions use "lang" or "lang-country" as default */
220 if (pLcidToRfc1766A) {
221 hr = pLcidToRfc1766A(lcid, language, sizeof(language));
222 ok(hr == S_OK, "LcidToRfc1766A returned 0x%x and %s\n", hr, language);
226 ok(!lstrcmpA(buffer, language),
227 "have '%s' (searching for '%s')\n", language, buffer);
229 if (lstrcmpA(buffer, language)) {
230 win_skip("no more ideas, how to build the default language '%s'\n", buffer);
231 goto restore_original;
234 trace("detected default: %s\n", language);
235 while ((entry = table[i])) {
237 exactsize = lstrlenA(entry);
239 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) entry, exactsize + 1);
240 ok(!lres, "got %d for RegSetValueExA: %s\n", lres, entry);
242 /* len includes space for the terminating 0 before vista/w2k8 */
244 memset(buffer, '#', maxlen);
246 hr = pGetAcceptLanguagesA( buffer, &len);
247 ok(((hr == E_INVALIDARG) && (len == 0)) ||
249 ((len == exactsize) || (len == exactsize+1)) &&
250 !lstrcmpA(buffer, entry)),
251 "+2_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
254 memset(buffer, '#', maxlen);
256 hr = pGetAcceptLanguagesA( buffer, &len);
257 ok(((hr == E_INVALIDARG) && (len == 0)) ||
259 ((len == exactsize) || (len == exactsize+1)) &&
260 !lstrcmpA(buffer, entry)),
261 "+1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
264 memset(buffer, '#', maxlen);
266 hr = pGetAcceptLanguagesA( buffer, &len);
268 /* There is no space for the string in the registry.
269 When the buffer is large enough, the default language is returned
271 When the buffer is too small for that fallback, win7_32 and w2k8_64
272 and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), but
273 recent os succeed and return a partial result while
274 older os succeed and overflow the buffer */
276 ok(((hr == E_INVALIDARG) && (len == 0)) ||
277 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
278 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
279 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
280 "==_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
284 memset(buffer, '#', maxlen);
286 hr = pGetAcceptLanguagesA( buffer, &len);
287 ok(((hr == E_INVALIDARG) && (len == 0)) ||
288 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
289 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
290 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
291 "-1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
295 memset(buffer, '#', maxlen);
297 hr = pGetAcceptLanguagesA( buffer, &len);
298 ok(((hr == E_INVALIDARG) && (len == 0)) ||
299 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
300 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
301 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
302 "=1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
305 hr = pGetAcceptLanguagesA( NULL, &len);
307 /* w2k3 and below: E_FAIL and untouched len,
308 since w2k8: S_OK and needed size (excluding 0) */
309 ok( ((hr == S_OK) && (len == exactsize)) ||
310 ((hr == E_FAIL) && (len == maxlen)),
311 "NULL,max #%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
316 /* without a value in the registry, a default language is returned */
317 RegDeleteValue(hroot, acceptlanguage);
320 memset(buffer, '#', maxlen);
322 hr = pGetAcceptLanguagesA( buffer, &len);
323 ok( ((hr == S_OK) && (len == lstrlenA(language))),
324 "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n",
325 hr, len, buffer, lstrlenA(language), language);
328 memset(buffer, '#', maxlen);
330 hr = pGetAcceptLanguagesA( buffer, &len);
331 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
332 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
333 "=2: got 0x%x with %d and %s\n", hr, len, buffer);
336 memset(buffer, '#', maxlen);
338 hr = pGetAcceptLanguagesA( buffer, &len);
339 /* When the buffer is too small, win7_32 and w2k8_64 and above fail with
340 HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), other versions suceed
341 and return a partial 0 terminated result while other versions
342 fail with E_INVALIDARG and return a partial unterminated result */
343 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
344 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
345 "=1: got 0x%x with %d and %s\n", hr, len, buffer);
348 memset(buffer, '#', maxlen);
350 hr = pGetAcceptLanguagesA( buffer, &len);
351 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
352 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
353 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
355 memset(buffer, '#', maxlen);
357 hr = pGetAcceptLanguagesA( buffer, NULL);
358 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
359 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
360 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
363 hr = pGetAcceptLanguagesA( NULL, NULL);
364 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
365 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
366 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
370 len = lstrlenA(original);
371 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) original, len ? len + 1: 0);
372 ok(!lres, "RegSetValueEx(%s) failed: %d\n", original, lres);
376 RegDeleteValue(hroot, acceptlanguage);
381 static void test_SHSearchMapInt(void)
383 int keys[8], values[8];
386 if (!pSHSearchMapInt)
389 memset(keys, 0, sizeof(keys));
390 memset(values, 0, sizeof(values));
391 keys[0] = 99; values[0] = 101;
393 /* NULL key/value lists crash native, so skip testing them */
396 i = pSHSearchMapInt(keys, values, 1, keys[0]);
397 ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
399 /* Key doesn't exist */
400 i = pSHSearchMapInt(keys, values, 1, 100);
401 ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);
403 /* Len = 0 => not found */
404 i = pSHSearchMapInt(keys, values, 0, keys[0]);
405 ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);
407 /* 2 elements, len = 1 */
408 keys[1] = 98; values[1] = 102;
409 i = pSHSearchMapInt(keys, values, 1, keys[1]);
410 ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);
412 /* 2 elements, len = 2 */
413 i = pSHSearchMapInt(keys, values, 2, keys[1]);
414 ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);
416 /* Searches forward */
417 keys[2] = 99; values[2] = 103;
418 i = pSHSearchMapInt(keys, values, 3, keys[0]);
419 ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
422 static void test_alloc_shared(void)
430 procid=GetCurrentProcessId();
431 hmem=pSHAllocShared(NULL,10,procid);
432 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
433 ret = pSHFreeShared(hmem, procid);
434 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
437 hmem=pSHAllocShared(&val,4,procid);
438 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
440 p=pSHLockShared(hmem,procid);
441 ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
443 ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
444 ret = pSHUnlockShared(p);
445 ok( ret, "SHUnlockShared failed: %u\n", GetLastError());
447 ret = pSHFreeShared(hmem, procid);
448 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
451 static void test_fdsa(void)
455 DWORD num_items; /* Number of elements inserted */
456 void *mem; /* Ptr to array */
457 DWORD blocks_alloced; /* Number of elements allocated */
458 BYTE inc; /* Number of elements to grow by when we need to expand */
459 BYTE block_size; /* Size in bytes of an element */
460 BYTE flags; /* Flags */
463 BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
465 BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
466 DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
467 BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);
470 int block_size = 10, init_blocks = 4, inc = 2;
474 pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
475 pFDSA_Destroy = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
476 pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
477 pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);
479 mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
480 memset(&info, 0, sizeof(info));
482 ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
483 ok(info.num_items == 0, "num_items = %d\n", info.num_items);
484 ok(info.mem == mem, "mem = %p\n", info.mem);
485 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
486 ok(info.inc == inc, "inc = %d\n", info.inc);
487 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
488 ok(info.flags == 0, "flags = %d\n", info.flags);
490 ret = pFDSA_InsertItem(&info, 1234, "1234567890");
491 ok(ret == 0, "ret = %d\n", ret);
492 ok(info.num_items == 1, "num_items = %d\n", info.num_items);
493 ok(info.mem == mem, "mem = %p\n", info.mem);
494 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
495 ok(info.inc == inc, "inc = %d\n", info.inc);
496 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
497 ok(info.flags == 0, "flags = %d\n", info.flags);
499 ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
500 ok(ret == 1, "ret = %d\n", ret);
502 ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
503 ok(ret == 1, "ret = %d\n", ret);
505 ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
506 ok(ret == 0, "ret = %d\n", ret);
507 ok(info.mem == mem, "mem = %p\n", info.mem);
508 ok(info.flags == 0, "flags = %d\n", info.flags);
510 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
511 ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
512 ok(ret == 0, "ret = %d\n", ret);
513 ok(info.mem != mem, "mem = %p\n", info.mem);
514 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
515 ok(info.flags == 0x1, "flags = %d\n", info.flags);
517 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
519 ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
520 ok(info.mem != mem, "mem = %p\n", info.mem);
521 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
522 ok(info.flags == 0x1, "flags = %d\n", info.flags);
524 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
526 ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
527 ok(info.mem != mem, "mem = %p\n", info.mem);
528 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
529 ok(info.flags == 0x1, "flags = %d\n", info.flags);
531 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
533 ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
535 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
536 ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
539 /* When Initialize is called with inc = 0, set it to 1 */
540 ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
541 ok(info.inc == 1, "inc = %d\n", info.inc);
543 /* This time, because shlwapi hasn't had to allocate memory
544 internally, Destroy rets non-zero */
545 ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");
548 HeapFree(GetProcessHeap(), 0, mem);
552 typedef struct SHELL_USER_SID {
553 SID_IDENTIFIER_AUTHORITY sidAuthority;
556 } SHELL_USER_SID, *PSHELL_USER_SID;
557 typedef struct SHELL_USER_PERMISSION {
558 SHELL_USER_SID susID;
563 DWORD dwInheritAccessMask;
564 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
565 static void test_GetShellSecurityDescriptor(void)
567 SHELL_USER_PERMISSION supCurrentUserFull = {
568 { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
569 ACCESS_ALLOWED_ACE_TYPE, FALSE,
571 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
572 SHELL_USER_PERMISSION supEveryoneDenied = {
573 { {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 },
574 ACCESS_DENIED_ACE_TYPE, TRUE,
575 GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ };
576 PSHELL_USER_PERMISSION rgsup[2] = {
577 &supCurrentUserFull, &supEveryoneDenied,
579 SECURITY_DESCRIPTOR* psd;
580 SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
582 pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);
584 if(!pGetShellSecurityDescriptor)
586 win_skip("GetShellSecurityDescriptor not available\n");
590 psd = pGetShellSecurityDescriptor(NULL, 2);
592 broken(psd==INVALID_HANDLE_VALUE), /* IE5 */
593 "GetShellSecurityDescriptor should fail\n");
594 psd = pGetShellSecurityDescriptor(rgsup, 0);
595 ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
597 SetLastError(0xdeadbeef);
598 psd = pGetShellSecurityDescriptor(rgsup, 2);
599 if (psd == NULL && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
601 /* The previous calls to GetShellSecurityDescriptor don't set the last error */
602 win_skip("GetShellSecurityDescriptor is not implemented\n");
605 if (psd==INVALID_HANDLE_VALUE)
607 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
610 ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
613 BOOL bHasDacl = FALSE, bDefaulted;
616 SECURITY_DESCRIPTOR_CONTROL control;
618 ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
620 ok(GetSecurityDescriptorControl(psd, &control, &dwRev),
621 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
622 ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");
624 ok(GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted),
625 "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
627 ok(bHasDacl, "SD has no DACL\n");
630 ok(!bDefaulted, "DACL should not be defaulted\n");
632 ok(pAcl != NULL, "NULL DACL!\n");
635 ACL_SIZE_INFORMATION asiSize;
637 ok(IsValidAcl(pAcl), "DACL is not valid\n");
639 ok(GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation),
640 "GetAclInformation failed with error %u\n", GetLastError());
642 ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
643 if (asiSize.AceCount == 3)
645 ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
647 ok(GetAce(pAcl, 0, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
648 ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
649 "Invalid ACE type %d\n", paaa->Header.AceType);
650 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
651 ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);
653 ok(GetAce(pAcl, 1, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
654 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
655 "Invalid ACE type %d\n", paaa->Header.AceType);
656 /* first one of two ACEs generated from inheritable entry - without inheritance */
657 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
658 ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);
660 ok(GetAce(pAcl, 2, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
661 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
662 "Invalid ACE type %d\n", paaa->Header.AceType);
663 /* second ACE - with inheritance */
664 ok(paaa->Header.AceFlags == MY_INHERITANCE,
665 "Invalid ACE flags %x\n", paaa->Header.AceFlags);
666 ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
675 static void test_SHPackDispParams(void)
681 if(!pSHPackDispParams)
682 win_skip("SHPackSidpParams not available\n");
684 memset(¶ms, 0xc0, sizeof(params));
685 memset(vars, 0xc0, sizeof(vars));
686 hres = pSHPackDispParams(¶ms, vars, 1, VT_I4, 0xdeadbeef);
687 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
688 ok(params.cArgs == 1, "params.cArgs = %d\n", params.cArgs);
689 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
690 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
691 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
692 ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars));
693 ok(V_I4(vars) == 0xdeadbeef, "failed %x\n", V_I4(vars));
695 memset(¶ms, 0xc0, sizeof(params));
696 hres = pSHPackDispParams(¶ms, NULL, 0, 0);
697 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
698 ok(params.cArgs == 0, "params.cArgs = %d\n", params.cArgs);
699 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
700 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
701 ok(params.rgvarg == NULL, "params.rgvarg = %p\n", params.rgvarg);
703 memset(vars, 0xc0, sizeof(vars));
704 memset(¶ms, 0xc0, sizeof(params));
705 hres = pSHPackDispParams(¶ms, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10,
706 VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef);
707 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
708 ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs);
709 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
710 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
711 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
712 ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars));
713 ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars));
714 ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1));
715 ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1));
716 ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2));
717 ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2));
718 ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3));
719 ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
724 const IDispatchVtbl *vtbl;
728 typedef struct _contain
730 const IConnectionPointContainerVtbl *vtbl;
734 IConnectionPoint **pt;
737 typedef struct _cntptn
739 const IConnectionPointVtbl *vtbl;
750 const IEnumConnectionsVtbl *vtbl;
757 typedef struct _enumpt
759 const IEnumConnectionPointsVtbl *vtbl;
767 static HRESULT WINAPI Disp_QueryInterface(
774 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
781 IUnknown_AddRef(This);
785 trace("no interface\n");
786 return E_NOINTERFACE;
789 static ULONG WINAPI Disp_AddRef(IDispatch* This)
791 Disp *iface = (Disp*)This;
792 return InterlockedIncrement(&iface->refCount);
795 static ULONG WINAPI Disp_Release(IDispatch* This)
797 Disp *iface = (Disp*)This;
800 ret = InterlockedDecrement(&iface->refCount);
802 HeapFree(GetProcessHeap(),0,This);
806 static HRESULT WINAPI Disp_GetTypeInfoCount(
810 return ERROR_SUCCESS;
813 static HRESULT WINAPI Disp_GetTypeInfo(
819 return ERROR_SUCCESS;
822 static HRESULT WINAPI Disp_GetIDsOfNames(
830 return ERROR_SUCCESS;
833 static HRESULT WINAPI Disp_Invoke(
839 DISPPARAMS *pDispParams,
841 EXCEPINFO *pExcepInfo,
844 trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
846 ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
847 ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
848 ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
849 ok(lcid == 0,"Wrong lcid %x\n",lcid);
850 if (dispIdMember == 0xa0)
852 ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
853 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
854 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
855 ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
857 else if (dispIdMember == 0xa1)
859 ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
860 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
861 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
862 ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
863 ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
864 ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
865 ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
868 return ERROR_SUCCESS;
871 static const IDispatchVtbl disp_vtbl = {
876 Disp_GetTypeInfoCount,
882 static HRESULT WINAPI Enum_QueryInterface(
883 IEnumConnections* This,
889 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
896 IUnknown_AddRef(This);
900 trace("no interface\n");
901 return E_NOINTERFACE;
904 static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
906 EnumCon *iface = (EnumCon*)This;
907 return InterlockedIncrement(&iface->refCount);
910 static ULONG WINAPI Enum_Release(IEnumConnections* This)
912 EnumCon *iface = (EnumCon*)This;
915 ret = InterlockedDecrement(&iface->refCount);
917 HeapFree(GetProcessHeap(),0,This);
921 static HRESULT WINAPI Enum_Next(
922 IEnumConnections* This,
927 EnumCon *iface = (EnumCon*)This;
929 if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
931 rgcd->pUnk = iface->pt->sink[iface->idx];
932 IUnknown_AddRef(iface->pt->sink[iface->idx]);
943 static HRESULT WINAPI Enum_Skip(
944 IEnumConnections* This,
950 static HRESULT WINAPI Enum_Reset(
951 IEnumConnections* This)
956 static HRESULT WINAPI Enum_Clone(
957 IEnumConnections* This,
958 IEnumConnections **ppEnum)
963 static const IEnumConnectionsVtbl enum_vtbl = {
974 static HRESULT WINAPI ConPt_QueryInterface(
975 IConnectionPoint* This,
981 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
988 IUnknown_AddRef(This);
992 trace("no interface\n");
993 return E_NOINTERFACE;
996 static ULONG WINAPI ConPt_AddRef(
997 IConnectionPoint* This)
999 ConPt *iface = (ConPt*)This;
1000 return InterlockedIncrement(&iface->refCount);
1003 static ULONG WINAPI ConPt_Release(
1004 IConnectionPoint* This)
1006 ConPt *iface = (ConPt*)This;
1009 ret = InterlockedDecrement(&iface->refCount);
1012 if (iface->sinkCount > 0)
1015 for (i = 0; i < iface->sinkCount; i++)
1018 IUnknown_Release(iface->sink[i]);
1020 HeapFree(GetProcessHeap(),0,iface->sink);
1022 HeapFree(GetProcessHeap(),0,This);
1027 static HRESULT WINAPI ConPt_GetConnectionInterface(
1028 IConnectionPoint* This,
1032 ConPt *iface = (ConPt*)This;
1039 memcpy(pIID,&iface->id,sizeof(GUID));
1043 static HRESULT WINAPI ConPt_GetConnectionPointContainer(
1044 IConnectionPoint* This,
1045 IConnectionPointContainer **ppCPC)
1047 ConPt *iface = (ConPt*)This;
1049 *ppCPC = (IConnectionPointContainer*)iface->container;
1053 static HRESULT WINAPI ConPt_Advise(
1054 IConnectionPoint* This,
1058 ConPt *iface = (ConPt*)This;
1060 if (iface->sinkCount == 0)
1061 iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1063 iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
1064 iface->sink[iface->sinkCount] = pUnkSink;
1065 IUnknown_AddRef(pUnkSink);
1067 *pdwCookie = iface->sinkCount;
1071 static HRESULT WINAPI ConPt_Unadvise(
1072 IConnectionPoint* This,
1075 ConPt *iface = (ConPt*)This;
1077 if (dwCookie > iface->sinkCount)
1081 IUnknown_Release(iface->sink[dwCookie-1]);
1082 iface->sink[dwCookie-1] = NULL;
1087 static HRESULT WINAPI ConPt_EnumConnections(
1088 IConnectionPoint* This,
1089 IEnumConnections **ppEnum)
1093 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
1094 ec->vtbl = &enum_vtbl;
1096 ec->pt = (ConPt*)This;
1098 *ppEnum = (IEnumConnections*)ec;
1103 static const IConnectionPointVtbl point_vtbl = {
1104 ConPt_QueryInterface,
1108 ConPt_GetConnectionInterface,
1109 ConPt_GetConnectionPointContainer,
1112 ConPt_EnumConnections
1115 static HRESULT WINAPI EnumPt_QueryInterface(
1116 IEnumConnectionPoints* This,
1122 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
1129 IUnknown_AddRef(This);
1133 trace("no interface\n");
1134 return E_NOINTERFACE;
1137 static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
1139 EnumPt *iface = (EnumPt*)This;
1140 return InterlockedIncrement(&iface->refCount);
1143 static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
1145 EnumPt *iface = (EnumPt*)This;
1148 ret = InterlockedDecrement(&iface->refCount);
1150 HeapFree(GetProcessHeap(),0,This);
1154 static HRESULT WINAPI EnumPt_Next(
1155 IEnumConnectionPoints* This,
1157 IConnectionPoint **rgcd,
1160 EnumPt *iface = (EnumPt*)This;
1162 if (cConnections > 0 && iface->idx < iface->container->ptCount)
1164 *rgcd = iface->container->pt[iface->idx];
1165 IUnknown_AddRef(iface->container->pt[iface->idx]);
1175 static HRESULT WINAPI EnumPt_Skip(
1176 IEnumConnectionPoints* This,
1182 static HRESULT WINAPI EnumPt_Reset(
1183 IEnumConnectionPoints* This)
1188 static HRESULT WINAPI EnumPt_Clone(
1189 IEnumConnectionPoints* This,
1190 IEnumConnectionPoints **ppEnumPt)
1195 static const IEnumConnectionPointsVtbl enumpt_vtbl = {
1197 EnumPt_QueryInterface,
1206 static HRESULT WINAPI Contain_QueryInterface(
1207 IConnectionPointContainer* This,
1213 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
1220 IUnknown_AddRef(This);
1224 trace("no interface\n");
1225 return E_NOINTERFACE;
1228 static ULONG WINAPI Contain_AddRef(
1229 IConnectionPointContainer* This)
1231 Contain *iface = (Contain*)This;
1232 return InterlockedIncrement(&iface->refCount);
1235 static ULONG WINAPI Contain_Release(
1236 IConnectionPointContainer* This)
1238 Contain *iface = (Contain*)This;
1241 ret = InterlockedDecrement(&iface->refCount);
1244 if (iface->ptCount > 0)
1247 for (i = 0; i < iface->ptCount; i++)
1248 IUnknown_Release(iface->pt[i]);
1249 HeapFree(GetProcessHeap(),0,iface->pt);
1251 HeapFree(GetProcessHeap(),0,This);
1256 static HRESULT WINAPI Contain_EnumConnectionPoints(
1257 IConnectionPointContainer* This,
1258 IEnumConnectionPoints **ppEnum)
1262 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
1263 ec->vtbl = &enumpt_vtbl;
1266 ec->container = (Contain*)This;
1267 *ppEnum = (IEnumConnectionPoints*)ec;
1272 static HRESULT WINAPI Contain_FindConnectionPoint(
1273 IConnectionPointContainer* This,
1275 IConnectionPoint **ppCP)
1277 Contain *iface = (Contain*)This;
1280 if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
1282 pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
1283 pt->vtbl = &point_vtbl;
1287 pt->container = iface;
1288 pt->id = IID_IDispatch;
1290 if (iface->ptCount == 0)
1291 iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1293 iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
1294 iface->pt[iface->ptCount] = (IConnectionPoint*)pt;
1297 *ppCP = (IConnectionPoint*)pt;
1301 *ppCP = iface->pt[0];
1302 IUnknown_AddRef((IUnknown*)*ppCP);
1308 static const IConnectionPointContainerVtbl contain_vtbl = {
1309 Contain_QueryInterface,
1313 Contain_EnumConnectionPoints,
1314 Contain_FindConnectionPoint
1317 static void test_IConnectionPoint(void)
1321 IConnectionPoint *point;
1324 DWORD cookie = 0xffffffff;
1328 if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
1330 win_skip("IConnectionPoint Apis not present\n");
1334 container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
1335 container->vtbl = &contain_vtbl;
1336 container->refCount = 1;
1337 container->ptCount = 0;
1338 container->pt = NULL;
1340 dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
1341 dispatch->vtbl = &disp_vtbl;
1342 dispatch->refCount = 1;
1344 rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
1345 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1346 ok(point != NULL, "returned ConnectionPoint is NULL\n");
1347 ok(cookie != 0xffffffff, "invalid cookie returned\n");
1349 rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
1350 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1352 if (pSHPackDispParams)
1354 memset(¶ms, 0xc0, sizeof(params));
1355 memset(vars, 0xc0, sizeof(vars));
1356 rc = pSHPackDispParams(¶ms, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
1357 ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
1359 rc = pIConnectionPoint_SimpleInvoke(point,0xa1,¶ms);
1360 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1363 win_skip("pSHPackDispParams not present\n");
1365 rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
1366 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1368 /* MSDN says this should be required but it crashs on XP
1369 IUnknown_Release(point);
1371 ref = IUnknown_Release((IUnknown*)container);
1372 ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
1373 ref = IUnknown_Release((IUnknown*)dispatch);
1374 ok(ref == 0, "leftover IDispatch reference %i\n",ref);
1377 typedef struct _propbag
1379 const IPropertyBagVtbl *vtbl;
1385 static HRESULT WINAPI Prop_QueryInterface(
1392 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPropertyBag))
1399 IUnknown_AddRef(This);
1403 trace("no interface\n");
1404 return E_NOINTERFACE;
1407 static ULONG WINAPI Prop_AddRef(
1410 PropBag *iface = (PropBag*)This;
1411 return InterlockedIncrement(&iface->refCount);
1414 static ULONG WINAPI Prop_Release(
1417 PropBag *iface = (PropBag*)This;
1420 ret = InterlockedDecrement(&iface->refCount);
1422 HeapFree(GetProcessHeap(),0,This);
1426 static HRESULT WINAPI Prop_Read(
1428 LPCOLESTR pszPropName,
1430 IErrorLog *pErrorLog)
1432 V_VT(pVar) = VT_BLOB|VT_BYREF;
1433 V_BYREF(pVar) = (LPVOID)0xdeadcafe;
1437 static HRESULT WINAPI Prop_Write(
1439 LPCOLESTR pszPropName,
1446 static const IPropertyBagVtbl prop_vtbl = {
1447 Prop_QueryInterface,
1455 static void test_SHPropertyBag_ReadLONG(void)
1460 static const WCHAR szName1[] = {'n','a','m','e','1',0};
1462 if (!pSHPropertyBag_ReadLONG)
1464 win_skip("SHPropertyBag_ReadLONG not present\n");
1468 pb = HeapAlloc(GetProcessHeap(),0,sizeof(PropBag));
1470 pb->vtbl = &prop_vtbl;
1473 rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out);
1474 ok(rc == E_INVALIDARG || broken(rc == 0), "incorrect return %x\n",rc);
1475 ok(out == 0xfeedface, "value should not have changed\n");
1476 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, NULL, &out);
1477 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1478 ok(out == 0xfeedface, "value should not have changed\n");
1479 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, NULL);
1480 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1481 ok(out == 0xfeedface, "value should not have changed\n");
1482 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, &out);
1483 ok(rc == DISP_E_BADVARTYPE || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1484 ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %x\n",out);
1485 IUnknown_Release((IUnknown*)pb);
1490 static void test_SHSetWindowBits(void)
1493 DWORD style, styleold;
1496 if(!pSHSetWindowBits)
1498 win_skip("SHSetWindowBits is not available\n");
1503 clsA.lpfnWndProc = DefWindowProcA;
1504 clsA.cbClsExtra = 0;
1505 clsA.cbWndExtra = 0;
1506 clsA.hInstance = GetModuleHandleA(NULL);
1508 clsA.hCursor = LoadCursorA(0, IDC_ARROW);
1509 clsA.hbrBackground = NULL;
1510 clsA.lpszMenuName = NULL;
1511 clsA.lpszClassName = "Shlwapi test class";
1512 RegisterClassA(&clsA);
1514 hwnd = CreateWindowA("Shlwapi test class", "Test", WS_VISIBLE, 0, 0, 100, 100,
1515 NULL, NULL, GetModuleHandle(NULL), 0);
1516 ok(IsWindow(hwnd), "failed to create window\n");
1519 SetLastError(0xdeadbeef);
1520 style = pSHSetWindowBits(NULL, GWL_STYLE, 0, 0);
1521 ok(style == 0, "expected 0 retval, got %d\n", style);
1522 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE ||
1523 broken(GetLastError() == 0xdeadbeef), /* Win9x/WinMe */
1524 "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
1526 /* zero mask, zero flags */
1527 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1528 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, 0);
1529 ok(styleold == style, "expected old style\n");
1530 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1533 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1534 ok(styleold & WS_VISIBLE, "expected WS_VISIBLE\n");
1535 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1537 ok(style == styleold, "expected previous style, got %x\n", style);
1538 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1540 /* test mask, unset style bit used */
1541 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1542 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1543 ok(style == styleold, "expected previous style, got %x\n", style);
1544 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1546 /* set back with flags */
1547 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1548 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, WS_VISIBLE);
1549 ok(style == styleold, "expected previous style, got %x\n", style);
1550 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "expected updated style\n");
1552 /* reset and try to set without a mask */
1553 pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1554 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1555 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1556 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, WS_VISIBLE);
1557 ok(style == styleold, "expected previous style, got %x\n", style);
1558 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1560 DestroyWindow(hwnd);
1562 UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL));
1565 static void test_SHFormatDateTimeA(void)
1567 FILETIME UNALIGNED filetime;
1568 CHAR buff[100], buff2[100], buff3[100];
1573 if(!pSHFormatDateTimeA)
1575 win_skip("pSHFormatDateTimeA isn't available\n");
1581 /* crashes on native */
1582 ret = pSHFormatDateTimeA(NULL, NULL, NULL, 0);
1586 SystemTimeToFileTime(&st, &filetime);
1587 /* SHFormatDateTime expects input as utc */
1588 LocalFileTimeToFileTime(&filetime, &filetime);
1590 /* no way to get required buffer length here */
1591 SetLastError(0xdeadbeef);
1592 ret = pSHFormatDateTimeA(&filetime, NULL, NULL, 0);
1593 ok(ret == 0, "got %d\n", ret);
1594 ok(GetLastError() == 0xdeadbeef || broken(GetLastError() == ERROR_SUCCESS /* Win7 */),
1595 "expected 0xdeadbeef, got %d\n", GetLastError());
1597 SetLastError(0xdeadbeef);
1598 buff[0] = 'a'; buff[1] = 0;
1599 ret = pSHFormatDateTimeA(&filetime, NULL, buff, 0);
1600 ok(ret == 0, "got %d\n", ret);
1601 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1602 ok(buff[0] == 'a', "expected same string, got %s\n", buff);
1604 /* flags needs to have FDTF_NOAUTOREADINGORDER for these tests to succeed on Vista+ */
1606 /* all combinations documented as invalid succeeded */
1607 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME | FDTF_LONGTIME;
1608 SetLastError(0xdeadbeef);
1609 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1610 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1611 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1613 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGDATE;
1614 SetLastError(0xdeadbeef);
1615 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1616 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1617 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1619 flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
1620 SetLastError(0xdeadbeef);
1621 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1622 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1623 ok(GetLastError() == 0xdeadbeef ||
1624 broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe */
1625 "expected 0xdeadbeef, got %d\n", GetLastError());
1627 /* now check returned strings */
1628 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME;
1629 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1630 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1631 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2));
1632 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1633 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1635 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME;
1636 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1637 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1638 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1639 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1640 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1642 /* both time flags */
1643 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME | FDTF_SHORTTIME;
1644 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1645 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1646 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1647 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1648 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1650 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE;
1651 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1652 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1653 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1654 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1655 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1657 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE;
1658 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1659 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1660 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1661 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1662 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1664 /* both date flags */
1665 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTDATE;
1666 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1667 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1668 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1669 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1670 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1672 /* various combinations of date/time flags */
1673 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTTIME;
1674 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1675 ok(ret == lstrlenA(buff)+1, "got %d, length %d\n", ret, lstrlenA(buff)+1);
1676 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1677 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1678 strcat(buff2, ", ");
1679 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1680 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1681 strcat(buff2, buff3);
1682 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1684 flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_LONGTIME;
1685 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1686 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1687 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1688 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1689 strcat(buff2, ", ");
1690 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1691 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1692 strcat(buff2, buff3);
1693 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1695 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_SHORTTIME;
1696 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1697 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1698 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1699 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1701 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1702 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1703 strcat(buff2, buff3);
1704 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1706 flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGTIME;
1707 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1708 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1709 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1710 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1712 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1713 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1714 strcat(buff2, buff3);
1715 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1718 static void test_SHFormatDateTimeW(void)
1720 FILETIME UNALIGNED filetime;
1721 WCHAR buff[100], buff2[100], buff3[100];
1725 static const WCHAR spaceW[] = {' ',0};
1726 static const WCHAR commaW[] = {',',' ',0};
1728 if(!pSHFormatDateTimeW)
1730 win_skip("pSHFormatDateTimeW isn't available\n");
1736 /* crashes on native */
1737 ret = pSHFormatDateTimeW(NULL, NULL, NULL, 0);
1741 SystemTimeToFileTime(&st, &filetime);
1742 /* SHFormatDateTime expects input as utc */
1743 LocalFileTimeToFileTime(&filetime, &filetime);
1745 /* no way to get required buffer length here */
1746 SetLastError(0xdeadbeef);
1747 ret = pSHFormatDateTimeW(&filetime, NULL, NULL, 0);
1748 ok(ret == 0, "got %d\n", ret);
1749 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1751 SetLastError(0xdeadbeef);
1752 buff[0] = 'a'; buff[1] = 0;
1753 ret = pSHFormatDateTimeW(&filetime, NULL, buff, 0);
1754 ok(ret == 0, "got %d\n", ret);
1755 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1756 ok(buff[0] == 'a', "expected same string\n");
1758 /* all combinations documented as invalid succeeded */
1759 flags = FDTF_SHORTTIME | FDTF_LONGTIME;
1760 SetLastError(0xdeadbeef);
1761 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1762 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1763 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1765 flags = FDTF_SHORTDATE | FDTF_LONGDATE;
1766 SetLastError(0xdeadbeef);
1767 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1768 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1769 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1771 flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
1772 SetLastError(0xdeadbeef);
1773 buff[0] = 0; /* NT4 doesn't clear the buffer on failure */
1774 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1775 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1776 ok(GetLastError() == 0xdeadbeef ||
1777 broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe/NT4 */
1778 "expected 0xdeadbeef, got %d\n", GetLastError());
1780 /* now check returned strings */
1781 flags = FDTF_SHORTTIME;
1782 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1783 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1784 SetLastError(0xdeadbeef);
1785 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1786 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1788 win_skip("Needed W-functions are not implemented\n");
1791 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1792 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1794 flags = FDTF_LONGTIME;
1795 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1796 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1797 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1798 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1799 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1801 /* both time flags */
1802 flags = FDTF_LONGTIME | FDTF_SHORTTIME;
1803 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1804 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1805 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1806 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1807 ok(lstrcmpW(buff, buff2) == 0, "expected equal string\n");
1809 flags = FDTF_SHORTDATE;
1810 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1811 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1812 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1813 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1814 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1816 flags = FDTF_LONGDATE;
1817 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1818 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1819 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1820 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1821 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1823 /* both date flags */
1824 flags = FDTF_LONGDATE | FDTF_SHORTDATE;
1825 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1826 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1827 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1828 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1829 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1831 /* various combinations of date/time flags */
1832 flags = FDTF_LONGDATE | FDTF_SHORTTIME;
1833 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1834 ok(ret == lstrlenW(buff)+1, "got %d, length %d\n", ret, lstrlenW(buff)+1);
1835 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1836 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1837 lstrcatW(buff2, commaW);
1838 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1839 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1840 lstrcatW(buff2, buff3);
1841 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1843 flags = FDTF_LONGDATE | FDTF_LONGTIME;
1844 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1845 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1846 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1847 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1848 lstrcatW(buff2, commaW);
1849 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1850 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1851 lstrcatW(buff2, buff3);
1852 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1854 flags = FDTF_SHORTDATE | FDTF_SHORTTIME;
1855 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1856 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1857 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1858 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1859 lstrcatW(buff2, spaceW);
1860 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1861 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1862 lstrcatW(buff2, buff3);
1863 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1865 flags = FDTF_SHORTDATE | FDTF_LONGTIME;
1866 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1867 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1868 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1869 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1870 lstrcatW(buff2, spaceW);
1871 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1872 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1873 lstrcatW(buff2, buff3);
1874 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1877 static void test_SHGetObjectCompatFlags(void)
1879 struct compat_value {
1884 struct compat_value values[] = {
1885 { "OTNEEDSSFCACHE", 0x1 },
1886 { "NO_WEBVIEW", 0x2 },
1887 { "UNBINDABLE", 0x4 },
1889 { "NEEDSFILESYSANCESTOR", 0x10 },
1890 { "NOTAFILESYSTEM", 0x20 },
1891 { "CTXMENU_NOVERBS", 0x40 },
1892 { "CTXMENU_LIMITEDQI", 0x80 },
1893 { "COCREATESHELLFOLDERONLY", 0x100 },
1894 { "NEEDSSTORAGEANCESTOR", 0x200 },
1895 { "NOLEGACYWEBVIEW", 0x400 },
1896 { "CTXMENU_XPQCMFLAGS", 0x1000 },
1897 { "NOIPROPERTYSTORE", 0x2000 }
1900 static const char compat_path[] = "Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Objects";
1901 CHAR keyA[39]; /* {CLSID} */
1906 if (!pSHGetObjectCompatFlags)
1908 win_skip("SHGetObjectCompatFlags isn't available\n");
1913 ret = pSHGetObjectCompatFlags(NULL, NULL);
1914 ok(ret == 0, "got %d\n", ret);
1916 ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, compat_path, &root);
1917 if (ret != ERROR_SUCCESS)
1919 skip("No compatibility class data found\n");
1923 for (i = 0; RegEnumKeyA(root, i, keyA, sizeof(keyA)) == ERROR_SUCCESS; i++)
1927 if (RegOpenKeyA(root, keyA, &clsid_key) == ERROR_SUCCESS)
1930 DWORD expected = 0, got, length = sizeof(valueA);
1934 for (v = 0; RegEnumValueA(clsid_key, v, valueA, &length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; v++)
1938 for (j = 0; j < sizeof(values)/sizeof(struct compat_value); j++)
1939 if (lstrcmpA(values[j].nameA, valueA) == 0)
1941 expected |= values[j].value;
1945 length = sizeof(valueA);
1948 pGUIDFromStringA(keyA, &clsid);
1949 got = pSHGetObjectCompatFlags(NULL, &clsid);
1950 ok(got == expected, "got 0x%08x, expected 0x%08x. Key %s\n", got, expected, keyA);
1952 RegCloseKey(clsid_key);
1960 const IOleCommandTargetVtbl *lpVtbl;
1962 } IOleCommandTargetImpl;
1964 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl;
1966 static IOleCommandTarget* IOleCommandTargetImpl_Construct(void)
1968 IOleCommandTargetImpl *obj;
1970 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
1971 obj->lpVtbl = &IOleCommandTargetImpl_Vtbl;
1974 return (IOleCommandTarget*)obj;
1977 static HRESULT WINAPI IOleCommandTargetImpl_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppvObj)
1979 IOleCommandTargetImpl *This = (IOleCommandTargetImpl *)iface;
1981 if (IsEqualIID(riid, &IID_IUnknown) ||
1982 IsEqualIID(riid, &IID_IOleCommandTarget))
1989 IUnknown_AddRef(iface);
1993 return E_NOINTERFACE;
1996 static ULONG WINAPI IOleCommandTargetImpl_AddRef(IOleCommandTarget *iface)
1998 IOleCommandTargetImpl *This = (IOleCommandTargetImpl *)iface;
1999 return InterlockedIncrement(&This->ref);
2002 static ULONG WINAPI IOleCommandTargetImpl_Release(IOleCommandTarget *iface)
2004 IOleCommandTargetImpl *This = (IOleCommandTargetImpl *)iface;
2005 ULONG ref = InterlockedDecrement(&This->ref);
2009 HeapFree(GetProcessHeap(), 0, This);
2015 static HRESULT WINAPI IOleCommandTargetImpl_QueryStatus(
2016 IOleCommandTarget *iface, const GUID *group, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
2021 static HRESULT WINAPI IOleCommandTargetImpl_Exec(
2022 IOleCommandTarget *iface,
2023 const GUID *CmdGroup,
2029 add_call(&trace_got, 3, CmdGroup, (void*)(DWORD_PTR)nCmdID, (void*)(DWORD_PTR)nCmdexecopt, pvaIn, pvaOut);
2033 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl =
2035 IOleCommandTargetImpl_QueryInterface,
2036 IOleCommandTargetImpl_AddRef,
2037 IOleCommandTargetImpl_Release,
2038 IOleCommandTargetImpl_QueryStatus,
2039 IOleCommandTargetImpl_Exec
2043 const IServiceProviderVtbl *lpVtbl;
2045 } IServiceProviderImpl;
2048 const IProfferServiceVtbl *lpVtbl;
2050 } IProfferServiceImpl;
2053 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl;
2054 static const IProfferServiceVtbl IProfferServiceImpl_Vtbl;
2056 static IServiceProvider* IServiceProviderImpl_Construct(void)
2058 IServiceProviderImpl *obj;
2060 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
2061 obj->lpVtbl = &IServiceProviderImpl_Vtbl;
2064 return (IServiceProvider*)obj;
2067 static IProfferService* IProfferServiceImpl_Construct(void)
2069 IProfferServiceImpl *obj;
2071 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
2072 obj->lpVtbl = &IProfferServiceImpl_Vtbl;
2075 return (IProfferService*)obj;
2078 static HRESULT WINAPI IServiceProviderImpl_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObj)
2080 IServiceProviderImpl *This = (IServiceProviderImpl *)iface;
2082 if (IsEqualIID(riid, &IID_IUnknown) ||
2083 IsEqualIID(riid, &IID_IServiceProvider))
2090 IUnknown_AddRef(iface);
2091 /* native uses redefined IID_IServiceProvider symbol, so we can't compare pointers */
2092 if (IsEqualIID(riid, &IID_IServiceProvider))
2093 add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0);
2097 return E_NOINTERFACE;
2100 static ULONG WINAPI IServiceProviderImpl_AddRef(IServiceProvider *iface)
2102 IServiceProviderImpl *This = (IServiceProviderImpl *)iface;
2103 return InterlockedIncrement(&This->ref);
2106 static ULONG WINAPI IServiceProviderImpl_Release(IServiceProvider *iface)
2108 IServiceProviderImpl *This = (IServiceProviderImpl *)iface;
2109 ULONG ref = InterlockedDecrement(&This->ref);
2113 HeapFree(GetProcessHeap(), 0, This);
2119 static HRESULT WINAPI IServiceProviderImpl_QueryService(
2120 IServiceProvider *iface, REFGUID service, REFIID riid, void **ppv)
2122 /* native uses redefined pointer for IID_IOleCommandTarget, not one from uuid.lib */
2123 if (IsEqualIID(riid, &IID_IOleCommandTarget))
2125 add_call(&trace_got, 2, iface, service, &IID_IOleCommandTarget, 0, 0);
2126 *ppv = IOleCommandTargetImpl_Construct();
2128 if (IsEqualIID(riid, &IID_IProfferService))
2130 if (IsEqualIID(service, &IID_IProfferService))
2131 add_call(&trace_got, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
2132 *ppv = IProfferServiceImpl_Construct();
2137 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl =
2139 IServiceProviderImpl_QueryInterface,
2140 IServiceProviderImpl_AddRef,
2141 IServiceProviderImpl_Release,
2142 IServiceProviderImpl_QueryService
2145 static void test_IUnknown_QueryServiceExec(void)
2147 IServiceProvider *provider = IServiceProviderImpl_Construct();
2148 static const GUID dummy_serviceid = { 0xdeadbeef };
2149 static const GUID dummy_groupid = { 0xbeefbeef };
2150 call_trace_t trace_expected;
2153 /* on <=W2K platforms same ordinal used for another export with different
2154 prototype, so skipping using this indirect condition */
2155 if (is_win2k_and_lower)
2157 win_skip("IUnknown_QueryServiceExec is not available\n");
2161 /* null source pointer */
2162 hr = pIUnknown_QueryServiceExec(NULL, &dummy_serviceid, &dummy_groupid, 0, 0, 0, 0);
2163 ok(hr == E_FAIL, "got 0x%08x\n", hr);
2166 IUnknown_QueryServiceExec( ptr1, serviceid, groupid, arg1, arg2, arg3, arg4);
2167 -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &prov );
2168 -> IServiceProvider_QueryService( prov, serviceid, &IID_IOleCommandTarget, &obj );
2169 -> IOleCommandTarget_Exec( obj, groupid, arg1, arg2, arg3, arg4 );
2171 init_call_trace(&trace_expected);
2173 add_call(&trace_expected, 1, provider, &IID_IServiceProvider, 0, 0, 0);
2174 add_call(&trace_expected, 2, provider, &dummy_serviceid, &IID_IOleCommandTarget, 0, 0);
2175 add_call(&trace_expected, 3, &dummy_groupid, (void*)0x1, (void*)0x2, (void*)0x3, (void*)0x4);
2177 init_call_trace(&trace_got);
2178 hr = pIUnknown_QueryServiceExec((IUnknown*)provider, &dummy_serviceid, &dummy_groupid, 0x1, 0x2, (void*)0x3, (void*)0x4);
2179 ok(hr == S_OK, "got 0x%08x\n", hr);
2181 ok_trace(&trace_expected, &trace_got);
2183 free_call_trace(&trace_expected);
2184 free_call_trace(&trace_got);
2186 IServiceProvider_Release(provider);
2190 static HRESULT WINAPI IProfferServiceImpl_QueryInterface(IProfferService *iface, REFIID riid, void **ppvObj)
2192 IProfferServiceImpl *This = (IProfferServiceImpl *)iface;
2194 if (IsEqualIID(riid, &IID_IUnknown) ||
2195 IsEqualIID(riid, &IID_IProfferService))
2199 else if (IsEqualIID(riid, &IID_IServiceProvider))
2201 *ppvObj = IServiceProviderImpl_Construct();
2202 add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0);
2208 IUnknown_AddRef(iface);
2212 return E_NOINTERFACE;
2215 static ULONG WINAPI IProfferServiceImpl_AddRef(IProfferService *iface)
2217 IProfferServiceImpl *This = (IProfferServiceImpl *)iface;
2218 return InterlockedIncrement(&This->ref);
2221 static ULONG WINAPI IProfferServiceImpl_Release(IProfferService *iface)
2223 IProfferServiceImpl *This = (IProfferServiceImpl *)iface;
2224 ULONG ref = InterlockedDecrement(&This->ref);
2228 HeapFree(GetProcessHeap(), 0, This);
2234 static HRESULT WINAPI IProfferServiceImpl_ProfferService(IProfferService *iface,
2235 REFGUID service, IServiceProvider *pService, DWORD *pCookie)
2237 add_call(&trace_got, 3, service, pService, pCookie, 0, 0);
2241 static HRESULT WINAPI IProfferServiceImpl_RevokeService(IProfferService *iface, DWORD cookie)
2243 add_call(&trace_got, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0);
2247 static const IProfferServiceVtbl IProfferServiceImpl_Vtbl =
2249 IProfferServiceImpl_QueryInterface,
2250 IProfferServiceImpl_AddRef,
2251 IProfferServiceImpl_Release,
2252 IProfferServiceImpl_ProfferService,
2253 IProfferServiceImpl_RevokeService
2256 static void test_IUnknown_ProfferService(void)
2258 IServiceProvider *provider = IServiceProviderImpl_Construct();
2259 IProfferService *proff = IProfferServiceImpl_Construct();
2260 static const GUID dummy_serviceid = { 0xdeadbeef };
2261 call_trace_t trace_expected;
2265 /* on <=W2K platforms same ordinal used for another export with different
2266 prototype, so skipping using this indirect condition */
2267 if (is_win2k_and_lower)
2269 win_skip("IUnknown_ProfferService is not available\n");
2273 /* null source pointer */
2274 hr = pIUnknown_ProfferService(NULL, &dummy_serviceid, 0, 0);
2275 ok(hr == E_FAIL, "got 0x%08x\n", hr);
2278 IUnknown_ProfferService( ptr1, serviceid, arg1, arg2);
2279 -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &provider );
2280 -> IServiceProvider_QueryService( provider, &IID_IProfferService, &IID_IProfferService, &proffer );
2282 if (service pointer not null):
2283 -> IProfferService_ProfferService( proffer, serviceid, arg1, arg2 );
2285 -> IProfferService_RevokeService( proffer, *arg2 );
2287 init_call_trace(&trace_expected);
2289 add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0);
2290 add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
2291 add_call(&trace_expected, 3, &dummy_serviceid, provider, &cookie, 0, 0);
2293 init_call_trace(&trace_got);
2294 hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, provider, &cookie);
2295 ok(hr == S_OK, "got 0x%08x\n", hr);
2297 ok_trace(&trace_expected, &trace_got);
2298 free_call_trace(&trace_got);
2299 free_call_trace(&trace_expected);
2301 /* same with ::Revoke path */
2302 init_call_trace(&trace_expected);
2304 add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0);
2305 add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
2306 add_call(&trace_expected, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0);
2308 init_call_trace(&trace_got);
2309 hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, 0, &cookie);
2310 ok(hr == S_OK, "got 0x%08x\n", hr);
2311 ok_trace(&trace_expected, &trace_got);
2312 free_call_trace(&trace_got);
2313 free_call_trace(&trace_expected);
2315 IServiceProvider_Release(provider);
2316 IProfferService_Release(proff);
2319 static void test_SHCreateWorkerWindowA(void)
2327 if (is_win2k_and_lower)
2329 win_skip("SHCreateWorkerWindowA not available\n");
2333 hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0);
2334 ok(hwnd != 0, "expected window\n");
2336 GetClassName(hwnd, classA, 20);
2337 ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA);
2339 ret = GetWindowLongPtrA(hwnd, 0);
2340 ok(ret == 0, "got %ld\n", ret);
2343 memset(&cliA, 0, sizeof(cliA));
2344 res = GetClassInfoA(GetModuleHandle("shlwapi.dll"), "WorkerA", &cliA);
2345 ok(res, "failed to get class info\n");
2346 ok(cliA.style == 0, "got 0x%08x\n", cliA.style);
2347 ok(cliA.cbClsExtra == 0, "got %d\n", cliA.cbClsExtra);
2348 ok(cliA.cbWndExtra == sizeof(LONG_PTR), "got %d\n", cliA.cbWndExtra);
2349 ok(cliA.lpszMenuName == 0, "got %s\n", cliA.lpszMenuName);
2351 DestroyWindow(hwnd);
2353 /* set extra bytes */
2354 hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0xdeadbeef);
2355 ok(hwnd != 0, "expected window\n");
2357 GetClassName(hwnd, classA, 20);
2358 ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA);
2360 ret = GetWindowLongPtrA(hwnd, 0);
2361 ok(ret == 0xdeadbeef, "got %ld\n", ret);
2364 ret = GetWindowLongA(hwnd, GWL_EXSTYLE);
2365 ok(ret == WS_EX_WINDOWEDGE, "0x%08lx\n", ret);
2367 DestroyWindow(hwnd);
2369 hwnd = pSHCreateWorkerWindowA(0, NULL, WS_EX_TOOLWINDOW, 0, 0, 0);
2370 ret = GetWindowLongA(hwnd, GWL_EXSTYLE);
2371 ok(ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW), "0x%08lx\n", ret);
2372 DestroyWindow(hwnd);
2375 static HRESULT WINAPI SF_QueryInterface(IShellFolder *iface,
2376 REFIID riid, void **ppv)
2378 /* SHIShellFolder_EnumObjects doesn't QI the object for IShellFolder */
2379 ok(!IsEqualGUID(&IID_IShellFolder, riid),
2380 "Unexpected QI for IShellFolder\n");
2381 return E_NOINTERFACE;
2384 static ULONG WINAPI SF_AddRef(IShellFolder *iface)
2389 static ULONG WINAPI SF_Release(IShellFolder *iface)
2394 static HRESULT WINAPI SF_ParseDisplayName(IShellFolder *iface,
2395 HWND owner, LPBC reserved, LPOLESTR displayName, ULONG *eaten,
2396 LPITEMIDLIST *idl, ULONG *attr)
2398 ok(0, "Didn't expect ParseDisplayName\n");
2402 static HRESULT WINAPI SF_EnumObjects(IShellFolder *iface,
2403 HWND owner, SHCONTF flags, IEnumIDList **enm)
2405 *enm = (IEnumIDList*)0xcafebabe;
2409 static HRESULT WINAPI SF_BindToObject(IShellFolder *iface,
2410 LPCITEMIDLIST idl, LPBC reserved, REFIID riid, void **obj)
2412 ok(0, "Didn't expect BindToObject\n");
2416 static HRESULT WINAPI SF_BindToStorage(IShellFolder *iface,
2417 LPCITEMIDLIST idl, LPBC reserved, REFIID riid, void **obj)
2419 ok(0, "Didn't expect BindToStorage\n");
2423 static HRESULT WINAPI SF_CompareIDs(IShellFolder *iface,
2424 LPARAM lparam, LPCITEMIDLIST idl1, LPCITEMIDLIST idl2)
2426 ok(0, "Didn't expect CompareIDs\n");
2430 static HRESULT WINAPI SF_CreateViewObject(IShellFolder *iface,
2431 HWND owner, REFIID riid, void **out)
2433 ok(0, "Didn't expect CreateViewObject\n");
2437 static HRESULT WINAPI SF_GetAttributesOf(IShellFolder *iface,
2438 UINT cidl, LPCITEMIDLIST *idl, SFGAOF *inOut)
2440 ok(0, "Didn't expect GetAttributesOf\n");
2444 static HRESULT WINAPI SF_GetUIObjectOf(IShellFolder *iface,
2445 HWND owner, UINT cidl, LPCITEMIDLIST *idls, REFIID riid, UINT *inOut,
2448 ok(0, "Didn't expect GetUIObjectOf\n");
2452 static HRESULT WINAPI SF_GetDisplayNameOf(IShellFolder *iface,
2453 LPCITEMIDLIST idl, SHGDNF flags, STRRET *name)
2455 ok(0, "Didn't expect GetDisplayNameOf\n");
2459 static HRESULT WINAPI SF_SetNameOf(IShellFolder *iface,
2460 HWND hwnd, LPCITEMIDLIST idl, LPCOLESTR name, SHGDNF flags,
2461 LPITEMIDLIST *idlOut)
2463 ok(0, "Didn't expect SetNameOf\n");
2467 static IShellFolderVtbl ShellFolderVtbl = {
2471 SF_ParseDisplayName,
2476 SF_CreateViewObject,
2479 SF_GetDisplayNameOf,
2483 static IShellFolder ShellFolder = { &ShellFolderVtbl };
2485 static void test_SHIShellFolder_EnumObjects(void)
2489 IShellFolder *folder;
2491 if(!pSHIShellFolder_EnumObjects || is_win2k_and_lower){
2492 win_skip("SHIShellFolder_EnumObjects not available\n");
2497 /* NULL object crashes on Windows */
2498 hres = pSHIShellFolder_EnumObjects(NULL, NULL, 0, NULL);
2501 /* SHIShellFolder_EnumObjects doesn't QI the object for IShellFolder */
2502 enm = (IEnumIDList*)0xdeadbeef;
2503 hres = pSHIShellFolder_EnumObjects(&ShellFolder, NULL, 0, &enm);
2504 ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres);
2505 ok(enm == (IEnumIDList*)0xcafebabe, "Didn't get expected enumerator location, instead: %p\n", enm);
2507 /* SHIShellFolder_EnumObjects isn't strict about the IShellFolder object */
2508 hres = SHGetDesktopFolder(&folder);
2509 ok(hres == S_OK, "SHGetDesktopFolder failed: 0x%08x\n", hres);
2512 hres = pSHIShellFolder_EnumObjects(folder, NULL, 0, &enm);
2513 ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres);
2514 ok(enm != NULL, "Didn't get an enumerator\n");
2516 IEnumIDList_Release(enm);
2518 IShellFolder_Release(folder);
2521 static void init_pointers(void)
2523 #define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord)))
2524 MAKEFUNC(SHAllocShared, 7);
2525 MAKEFUNC(SHLockShared, 8);
2526 MAKEFUNC(SHUnlockShared, 9);
2527 MAKEFUNC(SHFreeShared, 10);
2528 MAKEFUNC(GetAcceptLanguagesA, 14);
2529 MAKEFUNC(SHSetWindowBits, 165);
2530 MAKEFUNC(ConnectToConnectionPoint, 168);
2531 MAKEFUNC(SHSearchMapInt, 198);
2532 MAKEFUNC(SHCreateWorkerWindowA, 257);
2533 MAKEFUNC(GUIDFromStringA, 269);
2534 MAKEFUNC(SHPackDispParams, 282);
2535 MAKEFUNC(IConnectionPoint_InvokeWithCancel, 283);
2536 MAKEFUNC(IConnectionPoint_SimpleInvoke, 284);
2537 MAKEFUNC(SHFormatDateTimeA, 353);
2538 MAKEFUNC(SHFormatDateTimeW, 354);
2539 MAKEFUNC(SHIShellFolder_EnumObjects, 404);
2540 MAKEFUNC(SHGetObjectCompatFlags, 476);
2541 MAKEFUNC(IUnknown_QueryServiceExec, 484);
2542 MAKEFUNC(SHPropertyBag_ReadLONG, 496);
2543 MAKEFUNC(IUnknown_ProfferService, 514);
2549 hShlwapi = GetModuleHandleA("shlwapi.dll");
2550 is_win2k_and_lower = GetProcAddress(hShlwapi, "StrChrNW") == 0;
2554 hmlang = LoadLibraryA("mlang.dll");
2555 pLcidToRfc1766A = (void *)GetProcAddress(hmlang, "LcidToRfc1766A");
2557 test_GetAcceptLanguagesA();
2558 test_SHSearchMapInt();
2559 test_alloc_shared();
2561 test_GetShellSecurityDescriptor();
2562 test_SHPackDispParams();
2563 test_IConnectionPoint();
2564 test_SHPropertyBag_ReadLONG();
2565 test_SHSetWindowBits();
2566 test_SHFormatDateTimeA();
2567 test_SHFormatDateTimeW();
2568 test_SHGetObjectCompatFlags();
2569 test_IUnknown_QueryServiceExec();
2570 test_IUnknown_ProfferService();
2571 test_SHCreateWorkerWindowA();
2572 test_SHIShellFolder_EnumObjects();