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"
35 /* Function ptrs for ordinal calls */
36 static HMODULE hShlwapi
;
37 static BOOL is_win2k_and_lower
;
39 static int (WINAPI
*pSHSearchMapInt
)(const int*,const int*,int,int);
40 static HRESULT (WINAPI
*pGetAcceptLanguagesA
)(LPSTR
,LPDWORD
);
42 static HANDLE (WINAPI
*pSHAllocShared
)(LPCVOID
,DWORD
,DWORD
);
43 static LPVOID (WINAPI
*pSHLockShared
)(HANDLE
,DWORD
);
44 static BOOL (WINAPI
*pSHUnlockShared
)(LPVOID
);
45 static BOOL (WINAPI
*pSHFreeShared
)(HANDLE
,DWORD
);
46 static HRESULT(WINAPIV
*pSHPackDispParams
)(DISPPARAMS
*,VARIANTARG
*,UINT
,...);
47 static HRESULT(WINAPI
*pIConnectionPoint_SimpleInvoke
)(IConnectionPoint
*,DISPID
,DISPPARAMS
*);
48 static HRESULT(WINAPI
*pIConnectionPoint_InvokeWithCancel
)(IConnectionPoint
*,DISPID
,DISPPARAMS
*,DWORD
,DWORD
);
49 static HRESULT(WINAPI
*pConnectToConnectionPoint
)(IUnknown
*,REFIID
,BOOL
,IUnknown
*, LPDWORD
,IConnectionPoint
**);
50 static HRESULT(WINAPI
*pSHPropertyBag_ReadLONG
)(IPropertyBag
*,LPCWSTR
,LPLONG
);
51 static LONG (WINAPI
*pSHSetWindowBits
)(HWND
, INT
, UINT
, UINT
);
52 static INT (WINAPI
*pSHFormatDateTimeA
)(const FILETIME UNALIGNED
*, DWORD
*, LPSTR
, UINT
);
53 static INT (WINAPI
*pSHFormatDateTimeW
)(const FILETIME UNALIGNED
*, DWORD
*, LPWSTR
, UINT
);
54 static DWORD (WINAPI
*pSHGetObjectCompatFlags
)(IUnknown
*, const CLSID
*);
55 static BOOL (WINAPI
*pGUIDFromStringA
)(LPSTR
, CLSID
*);
56 static HRESULT (WINAPI
*pIUnknown_QueryServiceExec
)(IUnknown
*, REFIID
, const GUID
*, DWORD
, DWORD
, VARIANT
*, VARIANT
*);
57 static HRESULT (WINAPI
*pIUnknown_ProfferService
)(IUnknown
*, REFGUID
, IServiceProvider
*, DWORD
*);
58 static HWND (WINAPI
*pSHCreateWorkerWindowA
)(LONG
, HWND
, DWORD
, DWORD
, HMENU
, LONG_PTR
);
60 static HMODULE hmlang
;
61 static HRESULT (WINAPI
*pLcidToRfc1766A
)(LCID
, LPSTR
, INT
);
63 static const CHAR ie_international
[] = {
64 'S','o','f','t','w','a','r','e','\\',
65 'M','i','c','r','o','s','o','f','t','\\',
66 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
67 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
68 static const CHAR acceptlanguage
[] = {
69 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
82 static void init_call_trace(call_trace_t
*ctrace
)
86 ctrace
->calls
= HeapAlloc(GetProcessHeap(), 0, sizeof(call_entry_t
) * ctrace
->alloc
);
89 static void free_call_trace(const call_trace_t
*ctrace
)
91 HeapFree(GetProcessHeap(), 0, ctrace
->calls
);
94 static void add_call(call_trace_t
*ctrace
, int id
, const void *arg0
,
95 const void *arg1
, const void *arg2
, const void *arg3
, const void *arg4
)
106 if (ctrace
->count
== ctrace
->alloc
)
109 ctrace
->calls
= HeapReAlloc(GetProcessHeap(),0, ctrace
->calls
, ctrace
->alloc
*sizeof(call_entry_t
));
112 ctrace
->calls
[ctrace
->count
++] = call
;
115 static void ok_trace_(call_trace_t
*texpected
, call_trace_t
*tgot
, int line
)
117 if (texpected
->count
== tgot
->count
)
121 for (i
= 0; i
< texpected
->count
; i
++)
123 call_entry_t
*expected
= &texpected
->calls
[i
];
124 call_entry_t
*got
= &tgot
->calls
[i
];
127 ok_(__FILE__
, line
)(expected
->id
== got
->id
, "got different ids %d: %d, %d\n", i
+1, expected
->id
, got
->id
);
129 for (j
= 0; j
< 5; j
++)
131 ok_(__FILE__
, line
)(expected
->args
[j
] == got
->args
[j
], "got different args[%d] for %d: %p, %p\n", j
, i
+1,
132 expected
->args
[j
], got
->args
[j
]);
137 ok_(__FILE__
, line
)(0, "traces length mismatch\n");
140 #define ok_trace(a, b) ok_trace_(a, b, __LINE__)
142 /* trace of actually made calls */
143 static call_trace_t trace_got
;
145 static void test_GetAcceptLanguagesA(void)
147 static LPCSTR table
[] = {"de,en-gb;q=0.7,en;q=0.3",
148 "de,en;q=0.3,en-gb;q=0.7", /* sorting is ignored */
149 "winetest", /* content is ignored */
159 LONG res_query
= ERROR_SUCCESS
;
162 DWORD maxlen
= sizeof(buffer
) - 2;
168 if (!pGetAcceptLanguagesA
) {
169 win_skip("GetAcceptLanguagesA is not available\n");
173 lcid
= GetUserDefaultLCID();
175 /* Get the original Value */
176 lres
= RegOpenKeyA(HKEY_CURRENT_USER
, ie_international
, &hroot
);
178 skip("RegOpenKey(%s) failed: %d\n", ie_international
, lres
);
181 len
= sizeof(original
);
183 res_query
= RegQueryValueExA(hroot
, acceptlanguage
, 0, NULL
, (PBYTE
)original
, &len
);
185 RegDeleteValue(hroot
, acceptlanguage
);
187 /* Some windows versions use "lang-COUNTRY" as default */
188 memset(language
, 0, sizeof(language
));
189 len
= GetLocaleInfoA(lcid
, LOCALE_SISO639LANGNAME
, language
, sizeof(language
));
192 lstrcat(language
, "-");
193 memset(buffer
, 0, sizeof(buffer
));
194 len
= GetLocaleInfoA(lcid
, LOCALE_SISO3166CTRYNAME
, buffer
, sizeof(buffer
) - len
- 1);
195 lstrcat(language
, buffer
);
199 /* LOCALE_SNAME has additional parts in some languages. Try only as last chance */
200 memset(language
, 0, sizeof(language
));
201 len
= GetLocaleInfoA(lcid
, LOCALE_SNAME
, language
, sizeof(language
));
204 /* get the default value */
206 memset(buffer
, '#', maxlen
);
208 hr
= pGetAcceptLanguagesA( buffer
, &len
);
211 win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr
);
212 goto restore_original
;
215 if (lstrcmpA(buffer
, language
)) {
216 /* some windows versions use "lang" or "lang-country" as default */
218 if (pLcidToRfc1766A
) {
219 hr
= pLcidToRfc1766A(lcid
, language
, sizeof(language
));
220 ok(hr
== S_OK
, "LcidToRfc1766A returned 0x%x and %s\n", hr
, language
);
224 ok(!lstrcmpA(buffer
, language
),
225 "have '%s' (searching for '%s')\n", language
, buffer
);
227 if (lstrcmpA(buffer
, language
)) {
228 win_skip("no more ideas, how to build the default language '%s'\n", buffer
);
229 goto restore_original
;
232 trace("detected default: %s\n", language
);
233 while ((entry
= table
[i
])) {
235 exactsize
= lstrlenA(entry
);
237 lres
= RegSetValueExA(hroot
, acceptlanguage
, 0, REG_SZ
, (const BYTE
*) entry
, exactsize
+ 1);
238 ok(!lres
, "got %d for RegSetValueExA: %s\n", lres
, entry
);
240 /* len includes space for the terminating 0 before vista/w2k8 */
242 memset(buffer
, '#', maxlen
);
244 hr
= pGetAcceptLanguagesA( buffer
, &len
);
245 ok(((hr
== E_INVALIDARG
) && (len
== 0)) ||
247 ((len
== exactsize
) || (len
== exactsize
+1)) &&
248 !lstrcmpA(buffer
, entry
)),
249 "+2_#%d: got 0x%x with %d and %s\n", i
, hr
, len
, buffer
);
252 memset(buffer
, '#', maxlen
);
254 hr
= pGetAcceptLanguagesA( buffer
, &len
);
255 ok(((hr
== E_INVALIDARG
) && (len
== 0)) ||
257 ((len
== exactsize
) || (len
== exactsize
+1)) &&
258 !lstrcmpA(buffer
, entry
)),
259 "+1_#%d: got 0x%x with %d and %s\n", i
, hr
, len
, buffer
);
262 memset(buffer
, '#', maxlen
);
264 hr
= pGetAcceptLanguagesA( buffer
, &len
);
266 /* There is no space for the string in the registry.
267 When the buffer is large enough, the default language is returned
269 When the buffer is too small for that fallback, win7_32 and w2k8_64
270 and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), but
271 recent os succeed and return a partial result while
272 older os succeed and overflow the buffer */
274 ok(((hr
== E_INVALIDARG
) && (len
== 0)) ||
275 (((hr
== S_OK
) && !lstrcmpA(buffer
, language
) && (len
== lstrlenA(language
))) ||
276 ((hr
== S_OK
) && !memcmp(buffer
, language
, len
)) ||
277 ((hr
== __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
)) && !len
)),
278 "==_#%d: got 0x%x with %d and %s\n", i
, hr
, len
, buffer
);
282 memset(buffer
, '#', maxlen
);
284 hr
= pGetAcceptLanguagesA( buffer
, &len
);
285 ok(((hr
== E_INVALIDARG
) && (len
== 0)) ||
286 (((hr
== S_OK
) && !lstrcmpA(buffer
, language
) && (len
== lstrlenA(language
))) ||
287 ((hr
== S_OK
) && !memcmp(buffer
, language
, len
)) ||
288 ((hr
== __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
)) && !len
)),
289 "-1_#%d: got 0x%x with %d and %s\n", i
, hr
, len
, buffer
);
293 memset(buffer
, '#', maxlen
);
295 hr
= pGetAcceptLanguagesA( buffer
, &len
);
296 ok(((hr
== E_INVALIDARG
) && (len
== 0)) ||
297 (((hr
== S_OK
) && !lstrcmpA(buffer
, language
) && (len
== lstrlenA(language
))) ||
298 ((hr
== S_OK
) && !memcmp(buffer
, language
, len
)) ||
299 ((hr
== __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
)) && !len
)),
300 "=1_#%d: got 0x%x with %d and %s\n", i
, hr
, len
, buffer
);
303 hr
= pGetAcceptLanguagesA( NULL
, &len
);
305 /* w2k3 and below: E_FAIL and untouched len,
306 since w2k8: S_OK and needed size (excluding 0) */
307 ok( ((hr
== S_OK
) && (len
== exactsize
)) ||
308 ((hr
== E_FAIL
) && (len
== maxlen
)),
309 "NULL,max #%d: got 0x%x with %d and %s\n", i
, hr
, len
, buffer
);
314 /* without a value in the registry, a default language is returned */
315 RegDeleteValue(hroot
, acceptlanguage
);
318 memset(buffer
, '#', maxlen
);
320 hr
= pGetAcceptLanguagesA( buffer
, &len
);
321 ok( ((hr
== S_OK
) && (len
== lstrlenA(language
))),
322 "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n",
323 hr
, len
, buffer
, lstrlenA(language
), language
);
326 memset(buffer
, '#', maxlen
);
328 hr
= pGetAcceptLanguagesA( buffer
, &len
);
329 ok( (((hr
== S_OK
) || (hr
== E_INVALIDARG
)) && !memcmp(buffer
, language
, len
)) ||
330 ((hr
== __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
)) && !len
),
331 "=2: got 0x%x with %d and %s\n", hr
, len
, buffer
);
334 memset(buffer
, '#', maxlen
);
336 hr
= pGetAcceptLanguagesA( buffer
, &len
);
337 /* When the buffer is too small, win7_32 and w2k8_64 and above fail with
338 HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), other versions suceed
339 and return a partial 0 terminated result while other versions
340 fail with E_INVALIDARG and return a partial unterminated result */
341 ok( (((hr
== S_OK
) || (hr
== E_INVALIDARG
)) && !memcmp(buffer
, language
, len
)) ||
342 ((hr
== __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
)) && !len
),
343 "=1: got 0x%x with %d and %s\n", hr
, len
, buffer
);
346 memset(buffer
, '#', maxlen
);
348 hr
= pGetAcceptLanguagesA( buffer
, &len
);
349 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
350 ok((hr
== E_FAIL
) || (hr
== E_INVALIDARG
),
351 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr
);
353 memset(buffer
, '#', maxlen
);
355 hr
= pGetAcceptLanguagesA( buffer
, NULL
);
356 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
357 ok((hr
== E_FAIL
) || (hr
== E_INVALIDARG
),
358 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr
);
361 hr
= pGetAcceptLanguagesA( NULL
, NULL
);
362 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
363 ok((hr
== E_FAIL
) || (hr
== E_INVALIDARG
),
364 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr
);
368 len
= lstrlenA(original
);
369 lres
= RegSetValueExA(hroot
, acceptlanguage
, 0, REG_SZ
, (const BYTE
*) original
, len
? len
+ 1: 0);
370 ok(!lres
, "RegSetValueEx(%s) failed: %d\n", original
, lres
);
374 RegDeleteValue(hroot
, acceptlanguage
);
379 static void test_SHSearchMapInt(void)
381 int keys
[8], values
[8];
384 if (!pSHSearchMapInt
)
387 memset(keys
, 0, sizeof(keys
));
388 memset(values
, 0, sizeof(values
));
389 keys
[0] = 99; values
[0] = 101;
391 /* NULL key/value lists crash native, so skip testing them */
394 i
= pSHSearchMapInt(keys
, values
, 1, keys
[0]);
395 ok(i
== values
[0], "Len 1, expected %d, got %d\n", values
[0], i
);
397 /* Key doesn't exist */
398 i
= pSHSearchMapInt(keys
, values
, 1, 100);
399 ok(i
== -1, "Len 1 - bad key, expected -1, got %d\n", i
);
401 /* Len = 0 => not found */
402 i
= pSHSearchMapInt(keys
, values
, 0, keys
[0]);
403 ok(i
== -1, "Len 1 - passed len 0, expected -1, got %d\n", i
);
405 /* 2 elements, len = 1 */
406 keys
[1] = 98; values
[1] = 102;
407 i
= pSHSearchMapInt(keys
, values
, 1, keys
[1]);
408 ok(i
== -1, "Len 1 - array len 2, expected -1, got %d\n", i
);
410 /* 2 elements, len = 2 */
411 i
= pSHSearchMapInt(keys
, values
, 2, keys
[1]);
412 ok(i
== values
[1], "Len 2, expected %d, got %d\n", values
[1], i
);
414 /* Searches forward */
415 keys
[2] = 99; values
[2] = 103;
416 i
= pSHSearchMapInt(keys
, values
, 3, keys
[0]);
417 ok(i
== values
[0], "Len 3, expected %d, got %d\n", values
[0], i
);
420 static void test_alloc_shared(void)
428 procid
=GetCurrentProcessId();
429 hmem
=pSHAllocShared(NULL
,10,procid
);
430 ok(hmem
!=NULL
,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
431 ret
= pSHFreeShared(hmem
, procid
);
432 ok( ret
, "SHFreeShared failed: %u\n", GetLastError());
435 hmem
=pSHAllocShared(&val
,4,procid
);
436 ok(hmem
!=NULL
,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
438 p
=pSHLockShared(hmem
,procid
);
439 ok(p
!=NULL
,"SHLockShared failed: %u\n", GetLastError());
441 ok(*p
==val
,"Wrong value in shared memory: %d instead of %d\n",*p
,val
);
442 ret
= pSHUnlockShared(p
);
443 ok( ret
, "SHUnlockShared failed: %u\n", GetLastError());
445 ret
= pSHFreeShared(hmem
, procid
);
446 ok( ret
, "SHFreeShared failed: %u\n", GetLastError());
449 static void test_fdsa(void)
453 DWORD num_items
; /* Number of elements inserted */
454 void *mem
; /* Ptr to array */
455 DWORD blocks_alloced
; /* Number of elements allocated */
456 BYTE inc
; /* Number of elements to grow by when we need to expand */
457 BYTE block_size
; /* Size in bytes of an element */
458 BYTE flags
; /* Flags */
461 BOOL (WINAPI
*pFDSA_Initialize
)(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
463 BOOL (WINAPI
*pFDSA_Destroy
)(FDSA_info
*info
);
464 DWORD (WINAPI
*pFDSA_InsertItem
)(FDSA_info
*info
, DWORD where
, const void *block
);
465 BOOL (WINAPI
*pFDSA_DeleteItem
)(FDSA_info
*info
, DWORD where
);
468 int block_size
= 10, init_blocks
= 4, inc
= 2;
472 pFDSA_Initialize
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)208);
473 pFDSA_Destroy
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)209);
474 pFDSA_InsertItem
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)210);
475 pFDSA_DeleteItem
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)211);
477 mem
= HeapAlloc(GetProcessHeap(), 0, block_size
* init_blocks
);
478 memset(&info
, 0, sizeof(info
));
480 ok(pFDSA_Initialize(block_size
, inc
, &info
, mem
, init_blocks
), "FDSA_Initialize rets FALSE\n");
481 ok(info
.num_items
== 0, "num_items = %d\n", info
.num_items
);
482 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
483 ok(info
.blocks_alloced
== init_blocks
, "blocks_alloced = %d\n", info
.blocks_alloced
);
484 ok(info
.inc
== inc
, "inc = %d\n", info
.inc
);
485 ok(info
.block_size
== block_size
, "block_size = %d\n", info
.block_size
);
486 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
488 ret
= pFDSA_InsertItem(&info
, 1234, "1234567890");
489 ok(ret
== 0, "ret = %d\n", ret
);
490 ok(info
.num_items
== 1, "num_items = %d\n", info
.num_items
);
491 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
492 ok(info
.blocks_alloced
== init_blocks
, "blocks_alloced = %d\n", info
.blocks_alloced
);
493 ok(info
.inc
== inc
, "inc = %d\n", info
.inc
);
494 ok(info
.block_size
== block_size
, "block_size = %d\n", info
.block_size
);
495 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
497 ret
= pFDSA_InsertItem(&info
, 1234, "abcdefghij");
498 ok(ret
== 1, "ret = %d\n", ret
);
500 ret
= pFDSA_InsertItem(&info
, 1, "klmnopqrst");
501 ok(ret
== 1, "ret = %d\n", ret
);
503 ret
= pFDSA_InsertItem(&info
, 0, "uvwxyzABCD");
504 ok(ret
== 0, "ret = %d\n", ret
);
505 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
506 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
508 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
509 ret
= pFDSA_InsertItem(&info
, 0, "EFGHIJKLMN");
510 ok(ret
== 0, "ret = %d\n", ret
);
511 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
512 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
513 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
515 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info
.mem
);
517 ok(pFDSA_DeleteItem(&info
, 2), "rets FALSE\n");
518 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
519 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
520 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
522 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info
.mem
);
524 ok(pFDSA_DeleteItem(&info
, 3), "rets FALSE\n");
525 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
526 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
527 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
529 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info
.mem
);
531 ok(!pFDSA_DeleteItem(&info
, 4), "does not ret FALSE\n");
533 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
534 ok(!pFDSA_Destroy(&info
), "FDSA_Destroy does not ret FALSE\n");
537 /* When Initialize is called with inc = 0, set it to 1 */
538 ok(pFDSA_Initialize(block_size
, 0, &info
, mem
, init_blocks
), "FDSA_Initialize rets FALSE\n");
539 ok(info
.inc
== 1, "inc = %d\n", info
.inc
);
541 /* This time, because shlwapi hasn't had to allocate memory
542 internally, Destroy rets non-zero */
543 ok(pFDSA_Destroy(&info
), "FDSA_Destroy rets FALSE\n");
546 HeapFree(GetProcessHeap(), 0, mem
);
550 typedef struct SHELL_USER_SID
{
551 SID_IDENTIFIER_AUTHORITY sidAuthority
;
554 } SHELL_USER_SID
, *PSHELL_USER_SID
;
555 typedef struct SHELL_USER_PERMISSION
{
556 SHELL_USER_SID susID
;
561 DWORD dwInheritAccessMask
;
562 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
563 static void test_GetShellSecurityDescriptor(void)
565 SHELL_USER_PERMISSION supCurrentUserFull
= {
566 { {SECURITY_NULL_SID_AUTHORITY
}, 0, 0 },
567 ACCESS_ALLOWED_ACE_TYPE
, FALSE
,
569 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
570 SHELL_USER_PERMISSION supEveryoneDenied
= {
571 { {SECURITY_WORLD_SID_AUTHORITY
}, SECURITY_WORLD_RID
, 0 },
572 ACCESS_DENIED_ACE_TYPE
, TRUE
,
573 GENERIC_WRITE
, MY_INHERITANCE
| 0xDEADBA00, GENERIC_READ
};
574 PSHELL_USER_PERMISSION rgsup
[2] = {
575 &supCurrentUserFull
, &supEveryoneDenied
,
577 SECURITY_DESCRIPTOR
* psd
;
578 SECURITY_DESCRIPTOR
* (WINAPI
*pGetShellSecurityDescriptor
)(PSHELL_USER_PERMISSION
*,int);
580 pGetShellSecurityDescriptor
=(void*)GetProcAddress(hShlwapi
,(char*)475);
582 if(!pGetShellSecurityDescriptor
)
584 win_skip("GetShellSecurityDescriptor not available\n");
588 psd
= pGetShellSecurityDescriptor(NULL
, 2);
590 broken(psd
==INVALID_HANDLE_VALUE
), /* IE5 */
591 "GetShellSecurityDescriptor should fail\n");
592 psd
= pGetShellSecurityDescriptor(rgsup
, 0);
593 ok(psd
==NULL
, "GetShellSecurityDescriptor should fail\n");
595 SetLastError(0xdeadbeef);
596 psd
= pGetShellSecurityDescriptor(rgsup
, 2);
597 if (psd
== NULL
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
599 /* The previous calls to GetShellSecurityDescriptor don't set the last error */
600 win_skip("GetShellSecurityDescriptor is not implemented\n");
603 if (psd
==INVALID_HANDLE_VALUE
)
605 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
608 ok(psd
!=NULL
, "GetShellSecurityDescriptor failed\n");
611 BOOL bHasDacl
= FALSE
, bDefaulted
;
614 SECURITY_DESCRIPTOR_CONTROL control
;
616 ok(IsValidSecurityDescriptor(psd
), "returned value is not valid SD\n");
618 ok(GetSecurityDescriptorControl(psd
, &control
, &dwRev
),
619 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
620 ok(0 == (control
& SE_SELF_RELATIVE
), "SD should be absolute\n");
622 ok(GetSecurityDescriptorDacl(psd
, &bHasDacl
, &pAcl
, &bDefaulted
),
623 "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
625 ok(bHasDacl
, "SD has no DACL\n");
628 ok(!bDefaulted
, "DACL should not be defaulted\n");
630 ok(pAcl
!= NULL
, "NULL DACL!\n");
633 ACL_SIZE_INFORMATION asiSize
;
635 ok(IsValidAcl(pAcl
), "DACL is not valid\n");
637 ok(GetAclInformation(pAcl
, &asiSize
, sizeof(asiSize
), AclSizeInformation
),
638 "GetAclInformation failed with error %u\n", GetLastError());
640 ok(asiSize
.AceCount
== 3, "Incorrect number of ACEs: %d entries\n", asiSize
.AceCount
);
641 if (asiSize
.AceCount
== 3)
643 ACCESS_ALLOWED_ACE
*paaa
; /* will use for DENIED too */
645 ok(GetAce(pAcl
, 0, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
646 ok(paaa
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
,
647 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
648 ok(paaa
->Header
.AceFlags
== 0, "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
649 ok(paaa
->Mask
== GENERIC_ALL
, "Invalid ACE mask %x\n", paaa
->Mask
);
651 ok(GetAce(pAcl
, 1, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
652 ok(paaa
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
,
653 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
654 /* first one of two ACEs generated from inheritable entry - without inheritance */
655 ok(paaa
->Header
.AceFlags
== 0, "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
656 ok(paaa
->Mask
== GENERIC_WRITE
, "Invalid ACE mask %x\n", paaa
->Mask
);
658 ok(GetAce(pAcl
, 2, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
659 ok(paaa
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
,
660 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
661 /* second ACE - with inheritance */
662 ok(paaa
->Header
.AceFlags
== MY_INHERITANCE
,
663 "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
664 ok(paaa
->Mask
== GENERIC_READ
, "Invalid ACE mask %x\n", paaa
->Mask
);
673 static void test_SHPackDispParams(void)
679 if(!pSHPackDispParams
)
680 win_skip("SHPackSidpParams not available\n");
682 memset(¶ms
, 0xc0, sizeof(params
));
683 memset(vars
, 0xc0, sizeof(vars
));
684 hres
= pSHPackDispParams(¶ms
, vars
, 1, VT_I4
, 0xdeadbeef);
685 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
686 ok(params
.cArgs
== 1, "params.cArgs = %d\n", params
.cArgs
);
687 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
688 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
689 ok(params
.rgvarg
== vars
, "params.rgvarg = %p\n", params
.rgvarg
);
690 ok(V_VT(vars
) == VT_I4
, "V_VT(var) = %d\n", V_VT(vars
));
691 ok(V_I4(vars
) == 0xdeadbeef, "failed %x\n", V_I4(vars
));
693 memset(¶ms
, 0xc0, sizeof(params
));
694 hres
= pSHPackDispParams(¶ms
, NULL
, 0, 0);
695 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
696 ok(params
.cArgs
== 0, "params.cArgs = %d\n", params
.cArgs
);
697 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
698 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
699 ok(params
.rgvarg
== NULL
, "params.rgvarg = %p\n", params
.rgvarg
);
701 memset(vars
, 0xc0, sizeof(vars
));
702 memset(¶ms
, 0xc0, sizeof(params
));
703 hres
= pSHPackDispParams(¶ms
, vars
, 4, VT_BSTR
, (void*)0xdeadbeef, VT_EMPTY
, 10,
704 VT_I4
, 100, VT_DISPATCH
, (void*)0xdeadbeef);
705 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
706 ok(params
.cArgs
== 4, "params.cArgs = %d\n", params
.cArgs
);
707 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
708 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
709 ok(params
.rgvarg
== vars
, "params.rgvarg = %p\n", params
.rgvarg
);
710 ok(V_VT(vars
) == VT_DISPATCH
, "V_VT(vars[0]) = %x\n", V_VT(vars
));
711 ok(V_I4(vars
) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars
));
712 ok(V_VT(vars
+1) == VT_I4
, "V_VT(vars[1]) = %d\n", V_VT(vars
+1));
713 ok(V_I4(vars
+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars
+1));
714 ok(V_VT(vars
+2) == VT_I4
, "V_VT(vars[2]) = %d\n", V_VT(vars
+2));
715 ok(V_I4(vars
+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars
+2));
716 ok(V_VT(vars
+3) == VT_BSTR
, "V_VT(vars[3]) = %d\n", V_VT(vars
+3));
717 ok(V_BSTR(vars
+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars
+3));
722 const IDispatchVtbl
*vtbl
;
726 typedef struct _contain
728 const IConnectionPointContainerVtbl
*vtbl
;
732 IConnectionPoint
**pt
;
735 typedef struct _cntptn
737 const IConnectionPointVtbl
*vtbl
;
748 const IEnumConnectionsVtbl
*vtbl
;
755 typedef struct _enumpt
757 const IEnumConnectionPointsVtbl
*vtbl
;
765 static HRESULT WINAPI
Disp_QueryInterface(
772 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
))
779 IUnknown_AddRef(This
);
783 trace("no interface\n");
784 return E_NOINTERFACE
;
787 static ULONG WINAPI
Disp_AddRef(IDispatch
* This
)
789 Disp
*iface
= (Disp
*)This
;
790 return InterlockedIncrement(&iface
->refCount
);
793 static ULONG WINAPI
Disp_Release(IDispatch
* This
)
795 Disp
*iface
= (Disp
*)This
;
798 ret
= InterlockedDecrement(&iface
->refCount
);
800 HeapFree(GetProcessHeap(),0,This
);
804 static HRESULT WINAPI
Disp_GetTypeInfoCount(
808 return ERROR_SUCCESS
;
811 static HRESULT WINAPI
Disp_GetTypeInfo(
817 return ERROR_SUCCESS
;
820 static HRESULT WINAPI
Disp_GetIDsOfNames(
828 return ERROR_SUCCESS
;
831 static HRESULT WINAPI
Disp_Invoke(
837 DISPPARAMS
*pDispParams
,
839 EXCEPINFO
*pExcepInfo
,
842 trace("%p %x %p %x %x %p %p %p %p\n",This
,dispIdMember
,riid
,lcid
,wFlags
,pDispParams
,pVarResult
,pExcepInfo
,puArgErr
);
844 ok(dispIdMember
== 0xa0 || dispIdMember
== 0xa1, "Unknown dispIdMember\n");
845 ok(pDispParams
!= NULL
, "Invoked with NULL pDispParams\n");
846 ok(wFlags
== DISPATCH_METHOD
, "Wrong flags %x\n",wFlags
);
847 ok(lcid
== 0,"Wrong lcid %x\n",lcid
);
848 if (dispIdMember
== 0xa0)
850 ok(pDispParams
->cArgs
== 0, "params.cArgs = %d\n", pDispParams
->cArgs
);
851 ok(pDispParams
->cNamedArgs
== 0, "params.cNamedArgs = %d\n", pDispParams
->cArgs
);
852 ok(pDispParams
->rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", pDispParams
->rgdispidNamedArgs
);
853 ok(pDispParams
->rgvarg
== NULL
, "params.rgvarg = %p\n", pDispParams
->rgvarg
);
855 else if (dispIdMember
== 0xa1)
857 ok(pDispParams
->cArgs
== 2, "params.cArgs = %d\n", pDispParams
->cArgs
);
858 ok(pDispParams
->cNamedArgs
== 0, "params.cNamedArgs = %d\n", pDispParams
->cArgs
);
859 ok(pDispParams
->rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", pDispParams
->rgdispidNamedArgs
);
860 ok(V_VT(pDispParams
->rgvarg
) == VT_BSTR
, "V_VT(var) = %d\n", V_VT(pDispParams
->rgvarg
));
861 ok(V_I4(pDispParams
->rgvarg
) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams
->rgvarg
));
862 ok(V_VT(pDispParams
->rgvarg
+1) == VT_I4
, "V_VT(var) = %d\n", V_VT(pDispParams
->rgvarg
+1));
863 ok(V_I4(pDispParams
->rgvarg
+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams
->rgvarg
+1));
866 return ERROR_SUCCESS
;
869 static const IDispatchVtbl disp_vtbl
= {
874 Disp_GetTypeInfoCount
,
880 static HRESULT WINAPI
Enum_QueryInterface(
881 IEnumConnections
* This
,
887 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IEnumConnections
))
894 IUnknown_AddRef(This
);
898 trace("no interface\n");
899 return E_NOINTERFACE
;
902 static ULONG WINAPI
Enum_AddRef(IEnumConnections
* This
)
904 EnumCon
*iface
= (EnumCon
*)This
;
905 return InterlockedIncrement(&iface
->refCount
);
908 static ULONG WINAPI
Enum_Release(IEnumConnections
* This
)
910 EnumCon
*iface
= (EnumCon
*)This
;
913 ret
= InterlockedDecrement(&iface
->refCount
);
915 HeapFree(GetProcessHeap(),0,This
);
919 static HRESULT WINAPI
Enum_Next(
920 IEnumConnections
* This
,
925 EnumCon
*iface
= (EnumCon
*)This
;
927 if (cConnections
> 0 && iface
->idx
< iface
->pt
->sinkCount
)
929 rgcd
->pUnk
= iface
->pt
->sink
[iface
->idx
];
930 IUnknown_AddRef(iface
->pt
->sink
[iface
->idx
]);
941 static HRESULT WINAPI
Enum_Skip(
942 IEnumConnections
* This
,
948 static HRESULT WINAPI
Enum_Reset(
949 IEnumConnections
* This
)
954 static HRESULT WINAPI
Enum_Clone(
955 IEnumConnections
* This
,
956 IEnumConnections
**ppEnum
)
961 static const IEnumConnectionsVtbl enum_vtbl
= {
972 static HRESULT WINAPI
ConPt_QueryInterface(
973 IConnectionPoint
* This
,
979 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IConnectionPoint
))
986 IUnknown_AddRef(This
);
990 trace("no interface\n");
991 return E_NOINTERFACE
;
994 static ULONG WINAPI
ConPt_AddRef(
995 IConnectionPoint
* This
)
997 ConPt
*iface
= (ConPt
*)This
;
998 return InterlockedIncrement(&iface
->refCount
);
1001 static ULONG WINAPI
ConPt_Release(
1002 IConnectionPoint
* This
)
1004 ConPt
*iface
= (ConPt
*)This
;
1007 ret
= InterlockedDecrement(&iface
->refCount
);
1010 if (iface
->sinkCount
> 0)
1013 for (i
= 0; i
< iface
->sinkCount
; i
++)
1016 IUnknown_Release(iface
->sink
[i
]);
1018 HeapFree(GetProcessHeap(),0,iface
->sink
);
1020 HeapFree(GetProcessHeap(),0,This
);
1025 static HRESULT WINAPI
ConPt_GetConnectionInterface(
1026 IConnectionPoint
* This
,
1030 ConPt
*iface
= (ConPt
*)This
;
1037 memcpy(pIID
,&iface
->id
,sizeof(GUID
));
1041 static HRESULT WINAPI
ConPt_GetConnectionPointContainer(
1042 IConnectionPoint
* This
,
1043 IConnectionPointContainer
**ppCPC
)
1045 ConPt
*iface
= (ConPt
*)This
;
1047 *ppCPC
= (IConnectionPointContainer
*)iface
->container
;
1051 static HRESULT WINAPI
ConPt_Advise(
1052 IConnectionPoint
* This
,
1056 ConPt
*iface
= (ConPt
*)This
;
1058 if (iface
->sinkCount
== 0)
1059 iface
->sink
= HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown
*));
1061 iface
->sink
= HeapReAlloc(GetProcessHeap(),0,iface
->sink
,sizeof(IUnknown
*)*(iface
->sinkCount
+1));
1062 iface
->sink
[iface
->sinkCount
] = pUnkSink
;
1063 IUnknown_AddRef(pUnkSink
);
1065 *pdwCookie
= iface
->sinkCount
;
1069 static HRESULT WINAPI
ConPt_Unadvise(
1070 IConnectionPoint
* This
,
1073 ConPt
*iface
= (ConPt
*)This
;
1075 if (dwCookie
> iface
->sinkCount
)
1079 IUnknown_Release(iface
->sink
[dwCookie
-1]);
1080 iface
->sink
[dwCookie
-1] = NULL
;
1085 static HRESULT WINAPI
ConPt_EnumConnections(
1086 IConnectionPoint
* This
,
1087 IEnumConnections
**ppEnum
)
1091 ec
= HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon
));
1092 ec
->vtbl
= &enum_vtbl
;
1094 ec
->pt
= (ConPt
*)This
;
1096 *ppEnum
= (IEnumConnections
*)ec
;
1101 static const IConnectionPointVtbl point_vtbl
= {
1102 ConPt_QueryInterface
,
1106 ConPt_GetConnectionInterface
,
1107 ConPt_GetConnectionPointContainer
,
1110 ConPt_EnumConnections
1113 static HRESULT WINAPI
EnumPt_QueryInterface(
1114 IEnumConnectionPoints
* This
,
1120 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IEnumConnectionPoints
))
1127 IUnknown_AddRef(This
);
1131 trace("no interface\n");
1132 return E_NOINTERFACE
;
1135 static ULONG WINAPI
EnumPt_AddRef(IEnumConnectionPoints
* This
)
1137 EnumPt
*iface
= (EnumPt
*)This
;
1138 return InterlockedIncrement(&iface
->refCount
);
1141 static ULONG WINAPI
EnumPt_Release(IEnumConnectionPoints
* This
)
1143 EnumPt
*iface
= (EnumPt
*)This
;
1146 ret
= InterlockedDecrement(&iface
->refCount
);
1148 HeapFree(GetProcessHeap(),0,This
);
1152 static HRESULT WINAPI
EnumPt_Next(
1153 IEnumConnectionPoints
* This
,
1155 IConnectionPoint
**rgcd
,
1158 EnumPt
*iface
= (EnumPt
*)This
;
1160 if (cConnections
> 0 && iface
->idx
< iface
->container
->ptCount
)
1162 *rgcd
= iface
->container
->pt
[iface
->idx
];
1163 IUnknown_AddRef(iface
->container
->pt
[iface
->idx
]);
1173 static HRESULT WINAPI
EnumPt_Skip(
1174 IEnumConnectionPoints
* This
,
1180 static HRESULT WINAPI
EnumPt_Reset(
1181 IEnumConnectionPoints
* This
)
1186 static HRESULT WINAPI
EnumPt_Clone(
1187 IEnumConnectionPoints
* This
,
1188 IEnumConnectionPoints
**ppEnumPt
)
1193 static const IEnumConnectionPointsVtbl enumpt_vtbl
= {
1195 EnumPt_QueryInterface
,
1204 static HRESULT WINAPI
Contain_QueryInterface(
1205 IConnectionPointContainer
* This
,
1211 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IConnectionPointContainer
))
1218 IUnknown_AddRef(This
);
1222 trace("no interface\n");
1223 return E_NOINTERFACE
;
1226 static ULONG WINAPI
Contain_AddRef(
1227 IConnectionPointContainer
* This
)
1229 Contain
*iface
= (Contain
*)This
;
1230 return InterlockedIncrement(&iface
->refCount
);
1233 static ULONG WINAPI
Contain_Release(
1234 IConnectionPointContainer
* This
)
1236 Contain
*iface
= (Contain
*)This
;
1239 ret
= InterlockedDecrement(&iface
->refCount
);
1242 if (iface
->ptCount
> 0)
1245 for (i
= 0; i
< iface
->ptCount
; i
++)
1246 IUnknown_Release(iface
->pt
[i
]);
1247 HeapFree(GetProcessHeap(),0,iface
->pt
);
1249 HeapFree(GetProcessHeap(),0,This
);
1254 static HRESULT WINAPI
Contain_EnumConnectionPoints(
1255 IConnectionPointContainer
* This
,
1256 IEnumConnectionPoints
**ppEnum
)
1260 ec
= HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt
));
1261 ec
->vtbl
= &enumpt_vtbl
;
1264 ec
->container
= (Contain
*)This
;
1265 *ppEnum
= (IEnumConnectionPoints
*)ec
;
1270 static HRESULT WINAPI
Contain_FindConnectionPoint(
1271 IConnectionPointContainer
* This
,
1273 IConnectionPoint
**ppCP
)
1275 Contain
*iface
= (Contain
*)This
;
1278 if (!IsEqualIID(riid
, &IID_NULL
) || iface
->ptCount
==0)
1280 pt
= HeapAlloc(GetProcessHeap(),0,sizeof(ConPt
));
1281 pt
->vtbl
= &point_vtbl
;
1285 pt
->container
= iface
;
1286 pt
->id
= IID_IDispatch
;
1288 if (iface
->ptCount
== 0)
1289 iface
->pt
=HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown
*));
1291 iface
->pt
= HeapReAlloc(GetProcessHeap(),0,iface
->pt
,sizeof(IUnknown
*)*(iface
->ptCount
+1));
1292 iface
->pt
[iface
->ptCount
] = (IConnectionPoint
*)pt
;
1295 *ppCP
= (IConnectionPoint
*)pt
;
1299 *ppCP
= iface
->pt
[0];
1300 IUnknown_AddRef((IUnknown
*)*ppCP
);
1306 static const IConnectionPointContainerVtbl contain_vtbl
= {
1307 Contain_QueryInterface
,
1311 Contain_EnumConnectionPoints
,
1312 Contain_FindConnectionPoint
1315 static void test_IConnectionPoint(void)
1319 IConnectionPoint
*point
;
1322 DWORD cookie
= 0xffffffff;
1326 if (!pIConnectionPoint_SimpleInvoke
|| !pConnectToConnectionPoint
)
1328 win_skip("IConnectionPoint Apis not present\n");
1332 container
= HeapAlloc(GetProcessHeap(),0,sizeof(Contain
));
1333 container
->vtbl
= &contain_vtbl
;
1334 container
->refCount
= 1;
1335 container
->ptCount
= 0;
1336 container
->pt
= NULL
;
1338 dispatch
= HeapAlloc(GetProcessHeap(),0,sizeof(Disp
));
1339 dispatch
->vtbl
= &disp_vtbl
;
1340 dispatch
->refCount
= 1;
1342 rc
= pConnectToConnectionPoint((IUnknown
*)dispatch
, &IID_NULL
, TRUE
, (IUnknown
*)container
, &cookie
, &point
);
1343 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1344 ok(point
!= NULL
, "returned ConnectionPoint is NULL\n");
1345 ok(cookie
!= 0xffffffff, "invalid cookie returned\n");
1347 rc
= pIConnectionPoint_SimpleInvoke(point
,0xa0,NULL
);
1348 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1350 if (pSHPackDispParams
)
1352 memset(¶ms
, 0xc0, sizeof(params
));
1353 memset(vars
, 0xc0, sizeof(vars
));
1354 rc
= pSHPackDispParams(¶ms
, vars
, 2, VT_I4
, 0xdeadbeef, VT_BSTR
, 0xdeadcafe);
1355 ok(rc
== S_OK
, "SHPackDispParams failed: %08x\n", rc
);
1357 rc
= pIConnectionPoint_SimpleInvoke(point
,0xa1,¶ms
);
1358 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1361 win_skip("pSHPackDispParams not present\n");
1363 rc
= pConnectToConnectionPoint(NULL
, &IID_NULL
, FALSE
, (IUnknown
*)container
, &cookie
, NULL
);
1364 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1366 /* MSDN says this should be required but it crashs on XP
1367 IUnknown_Release(point);
1369 ref
= IUnknown_Release((IUnknown
*)container
);
1370 ok(ref
== 0, "leftover IConnectionPointContainer reference %i\n",ref
);
1371 ref
= IUnknown_Release((IUnknown
*)dispatch
);
1372 ok(ref
== 0, "leftover IDispatch reference %i\n",ref
);
1375 typedef struct _propbag
1377 const IPropertyBagVtbl
*vtbl
;
1383 static HRESULT WINAPI
Prop_QueryInterface(
1390 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IPropertyBag
))
1397 IUnknown_AddRef(This
);
1401 trace("no interface\n");
1402 return E_NOINTERFACE
;
1405 static ULONG WINAPI
Prop_AddRef(
1408 PropBag
*iface
= (PropBag
*)This
;
1409 return InterlockedIncrement(&iface
->refCount
);
1412 static ULONG WINAPI
Prop_Release(
1415 PropBag
*iface
= (PropBag
*)This
;
1418 ret
= InterlockedDecrement(&iface
->refCount
);
1420 HeapFree(GetProcessHeap(),0,This
);
1424 static HRESULT WINAPI
Prop_Read(
1426 LPCOLESTR pszPropName
,
1428 IErrorLog
*pErrorLog
)
1430 V_VT(pVar
) = VT_BLOB
|VT_BYREF
;
1431 V_BYREF(pVar
) = (LPVOID
)0xdeadcafe;
1435 static HRESULT WINAPI
Prop_Write(
1437 LPCOLESTR pszPropName
,
1444 static const IPropertyBagVtbl prop_vtbl
= {
1445 Prop_QueryInterface
,
1453 static void test_SHPropertyBag_ReadLONG(void)
1458 static const WCHAR szName1
[] = {'n','a','m','e','1',0};
1460 if (!pSHPropertyBag_ReadLONG
)
1462 win_skip("SHPropertyBag_ReadLONG not present\n");
1466 pb
= HeapAlloc(GetProcessHeap(),0,sizeof(PropBag
));
1468 pb
->vtbl
= &prop_vtbl
;
1471 rc
= pSHPropertyBag_ReadLONG(NULL
, szName1
, &out
);
1472 ok(rc
== E_INVALIDARG
|| broken(rc
== 0), "incorrect return %x\n",rc
);
1473 ok(out
== 0xfeedface, "value should not have changed\n");
1474 rc
= pSHPropertyBag_ReadLONG((IPropertyBag
*)pb
, NULL
, &out
);
1475 ok(rc
== E_INVALIDARG
|| broken(rc
== 0) || broken(rc
== 1), "incorrect return %x\n",rc
);
1476 ok(out
== 0xfeedface, "value should not have changed\n");
1477 rc
= pSHPropertyBag_ReadLONG((IPropertyBag
*)pb
, szName1
, NULL
);
1478 ok(rc
== E_INVALIDARG
|| broken(rc
== 0) || broken(rc
== 1), "incorrect return %x\n",rc
);
1479 ok(out
== 0xfeedface, "value should not have changed\n");
1480 rc
= pSHPropertyBag_ReadLONG((IPropertyBag
*)pb
, szName1
, &out
);
1481 ok(rc
== DISP_E_BADVARTYPE
|| broken(rc
== 0) || broken(rc
== 1), "incorrect return %x\n",rc
);
1482 ok(out
== 0xfeedface || broken(out
== 0xfeedfa00), "value should not have changed %x\n",out
);
1483 IUnknown_Release((IUnknown
*)pb
);
1488 static void test_SHSetWindowBits(void)
1491 DWORD style
, styleold
;
1494 if(!pSHSetWindowBits
)
1496 win_skip("SHSetWindowBits is not available\n");
1501 clsA
.lpfnWndProc
= DefWindowProcA
;
1502 clsA
.cbClsExtra
= 0;
1503 clsA
.cbWndExtra
= 0;
1504 clsA
.hInstance
= GetModuleHandleA(NULL
);
1506 clsA
.hCursor
= LoadCursorA(0, IDC_ARROW
);
1507 clsA
.hbrBackground
= NULL
;
1508 clsA
.lpszMenuName
= NULL
;
1509 clsA
.lpszClassName
= "Shlwapi test class";
1510 RegisterClassA(&clsA
);
1512 hwnd
= CreateWindowA("Shlwapi test class", "Test", WS_VISIBLE
, 0, 0, 100, 100,
1513 NULL
, NULL
, GetModuleHandle(NULL
), 0);
1514 ok(IsWindow(hwnd
), "failed to create window\n");
1517 SetLastError(0xdeadbeef);
1518 style
= pSHSetWindowBits(NULL
, GWL_STYLE
, 0, 0);
1519 ok(style
== 0, "expected 0 retval, got %d\n", style
);
1520 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
||
1521 broken(GetLastError() == 0xdeadbeef), /* Win9x/WinMe */
1522 "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
1524 /* zero mask, zero flags */
1525 styleold
= GetWindowLongA(hwnd
, GWL_STYLE
);
1526 style
= pSHSetWindowBits(hwnd
, GWL_STYLE
, 0, 0);
1527 ok(styleold
== style
, "expected old style\n");
1528 ok(styleold
== GetWindowLongA(hwnd
, GWL_STYLE
), "expected to keep old style\n");
1531 styleold
= GetWindowLongA(hwnd
, GWL_STYLE
);
1532 ok(styleold
& WS_VISIBLE
, "expected WS_VISIBLE\n");
1533 style
= pSHSetWindowBits(hwnd
, GWL_STYLE
, WS_VISIBLE
, 0);
1535 ok(style
== styleold
, "expected previous style, got %x\n", style
);
1536 ok((GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
) == 0, "expected updated style\n");
1538 /* test mask, unset style bit used */
1539 styleold
= GetWindowLongA(hwnd
, GWL_STYLE
);
1540 style
= pSHSetWindowBits(hwnd
, GWL_STYLE
, WS_VISIBLE
, 0);
1541 ok(style
== styleold
, "expected previous style, got %x\n", style
);
1542 ok(styleold
== GetWindowLongA(hwnd
, GWL_STYLE
), "expected to keep old style\n");
1544 /* set back with flags */
1545 styleold
= GetWindowLongA(hwnd
, GWL_STYLE
);
1546 style
= pSHSetWindowBits(hwnd
, GWL_STYLE
, WS_VISIBLE
, WS_VISIBLE
);
1547 ok(style
== styleold
, "expected previous style, got %x\n", style
);
1548 ok(GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
, "expected updated style\n");
1550 /* reset and try to set without a mask */
1551 pSHSetWindowBits(hwnd
, GWL_STYLE
, WS_VISIBLE
, 0);
1552 ok((GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
) == 0, "expected updated style\n");
1553 styleold
= GetWindowLongA(hwnd
, GWL_STYLE
);
1554 style
= pSHSetWindowBits(hwnd
, GWL_STYLE
, 0, WS_VISIBLE
);
1555 ok(style
== styleold
, "expected previous style, got %x\n", style
);
1556 ok((GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
) == 0, "expected updated style\n");
1558 DestroyWindow(hwnd
);
1560 UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL
));
1563 static void test_SHFormatDateTimeA(void)
1565 FILETIME UNALIGNED filetime
;
1566 CHAR buff
[100], buff2
[100], buff3
[100];
1571 if(!pSHFormatDateTimeA
)
1573 win_skip("pSHFormatDateTimeA isn't available\n");
1579 /* crashes on native */
1580 ret
= pSHFormatDateTimeA(NULL
, NULL
, NULL
, 0);
1584 SystemTimeToFileTime(&st
, &filetime
);
1585 /* SHFormatDateTime expects input as utc */
1586 LocalFileTimeToFileTime(&filetime
, &filetime
);
1588 /* no way to get required buffer length here */
1589 SetLastError(0xdeadbeef);
1590 ret
= pSHFormatDateTimeA(&filetime
, NULL
, NULL
, 0);
1591 ok(ret
== 0, "got %d\n", ret
);
1592 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1594 SetLastError(0xdeadbeef);
1595 buff
[0] = 'a'; buff
[1] = 0;
1596 ret
= pSHFormatDateTimeA(&filetime
, NULL
, buff
, 0);
1597 ok(ret
== 0, "got %d\n", ret
);
1598 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1599 ok(buff
[0] == 'a', "expected same string, got %s\n", buff
);
1601 /* flags needs to have FDTF_NOAUTOREADINGORDER for these tests to succeed on Vista+ */
1603 /* all combinations documented as invalid succeeded */
1604 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_SHORTTIME
| FDTF_LONGTIME
;
1605 SetLastError(0xdeadbeef);
1606 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1607 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1608 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1610 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_SHORTDATE
| FDTF_LONGDATE
;
1611 SetLastError(0xdeadbeef);
1612 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1613 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1614 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1616 flags
= FDTF_SHORTDATE
| FDTF_LTRDATE
| FDTF_RTLDATE
;
1617 SetLastError(0xdeadbeef);
1618 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1619 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1620 ok(GetLastError() == 0xdeadbeef ||
1621 broken(GetLastError() == ERROR_INVALID_FLAGS
), /* Win9x/WinMe */
1622 "expected 0xdeadbeef, got %d\n", GetLastError());
1624 /* now check returned strings */
1625 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_SHORTTIME
;
1626 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1627 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1628 ret
= GetTimeFormat(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &st
, NULL
, buff2
, sizeof(buff2
));
1629 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1630 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1632 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_LONGTIME
;
1633 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1634 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1635 ret
= GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff2
, sizeof(buff2
));
1636 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1637 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1639 /* both time flags */
1640 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_LONGTIME
| FDTF_SHORTTIME
;
1641 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1642 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1643 ret
= GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff2
, sizeof(buff2
));
1644 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1645 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1647 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_SHORTDATE
;
1648 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1649 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1650 ret
= GetDateFormat(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, NULL
, buff2
, sizeof(buff2
));
1651 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1652 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1654 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_LONGDATE
;
1655 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1656 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1657 ret
= GetDateFormat(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
));
1658 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1659 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1661 /* both date flags */
1662 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_LONGDATE
| FDTF_SHORTDATE
;
1663 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1664 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1665 ret
= GetDateFormat(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
));
1666 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1667 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1669 /* various combinations of date/time flags */
1670 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_LONGDATE
| FDTF_SHORTTIME
;
1671 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1672 ok(ret
== lstrlenA(buff
)+1, "got %d, length %d\n", ret
, lstrlenA(buff
)+1);
1673 ret
= GetDateFormat(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
));
1674 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1675 strcat(buff2
, ", ");
1676 ret
= GetTimeFormat(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &st
, NULL
, buff3
, sizeof(buff3
));
1677 ok(ret
== lstrlenA(buff3
)+1, "got %d\n", ret
);
1678 strcat(buff2
, buff3
);
1679 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1681 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_LONGDATE
| FDTF_LONGTIME
;
1682 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1683 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1684 ret
= GetDateFormat(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
));
1685 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1686 strcat(buff2
, ", ");
1687 ret
= GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff3
, sizeof(buff3
));
1688 ok(ret
== lstrlenA(buff3
)+1, "got %d\n", ret
);
1689 strcat(buff2
, buff3
);
1690 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1692 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_SHORTDATE
| FDTF_SHORTTIME
;
1693 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1694 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1695 ret
= GetDateFormat(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, NULL
, buff2
, sizeof(buff2
));
1696 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1698 ret
= GetTimeFormat(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &st
, NULL
, buff3
, sizeof(buff3
));
1699 ok(ret
== lstrlenA(buff3
)+1, "got %d\n", ret
);
1700 strcat(buff2
, buff3
);
1701 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1703 flags
= FDTF_NOAUTOREADINGORDER
| FDTF_SHORTDATE
| FDTF_LONGTIME
;
1704 ret
= pSHFormatDateTimeA(&filetime
, &flags
, buff
, sizeof(buff
));
1705 ok(ret
== lstrlenA(buff
)+1, "got %d\n", ret
);
1706 ret
= GetDateFormat(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, NULL
, buff2
, sizeof(buff2
));
1707 ok(ret
== lstrlenA(buff2
)+1, "got %d\n", ret
);
1709 ret
= GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff3
, sizeof(buff3
));
1710 ok(ret
== lstrlenA(buff3
)+1, "got %d\n", ret
);
1711 strcat(buff2
, buff3
);
1712 ok(lstrcmpA(buff
, buff2
) == 0, "expected (%s), got (%s)\n", buff2
, buff
);
1715 static void test_SHFormatDateTimeW(void)
1717 FILETIME UNALIGNED filetime
;
1718 WCHAR buff
[100], buff2
[100], buff3
[100];
1722 static const WCHAR spaceW
[] = {' ',0};
1723 static const WCHAR commaW
[] = {',',' ',0};
1725 if(!pSHFormatDateTimeW
)
1727 win_skip("pSHFormatDateTimeW isn't available\n");
1733 /* crashes on native */
1734 ret
= pSHFormatDateTimeW(NULL
, NULL
, NULL
, 0);
1738 SystemTimeToFileTime(&st
, &filetime
);
1739 /* SHFormatDateTime expects input as utc */
1740 LocalFileTimeToFileTime(&filetime
, &filetime
);
1742 /* no way to get required buffer length here */
1743 SetLastError(0xdeadbeef);
1744 ret
= pSHFormatDateTimeW(&filetime
, NULL
, NULL
, 0);
1745 ok(ret
== 0, "got %d\n", ret
);
1746 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1748 SetLastError(0xdeadbeef);
1749 buff
[0] = 'a'; buff
[1] = 0;
1750 ret
= pSHFormatDateTimeW(&filetime
, NULL
, buff
, 0);
1751 ok(ret
== 0, "got %d\n", ret
);
1752 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1753 ok(buff
[0] == 'a', "expected same string\n");
1755 /* all combinations documented as invalid succeeded */
1756 flags
= FDTF_SHORTTIME
| FDTF_LONGTIME
;
1757 SetLastError(0xdeadbeef);
1758 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1759 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1760 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1762 flags
= FDTF_SHORTDATE
| FDTF_LONGDATE
;
1763 SetLastError(0xdeadbeef);
1764 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1765 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1766 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1768 flags
= FDTF_SHORTDATE
| FDTF_LTRDATE
| FDTF_RTLDATE
;
1769 SetLastError(0xdeadbeef);
1770 buff
[0] = 0; /* NT4 doesn't clear the buffer on failure */
1771 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1772 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1773 ok(GetLastError() == 0xdeadbeef ||
1774 broken(GetLastError() == ERROR_INVALID_FLAGS
), /* Win9x/WinMe/NT4 */
1775 "expected 0xdeadbeef, got %d\n", GetLastError());
1777 /* now check returned strings */
1778 flags
= FDTF_SHORTTIME
;
1779 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1780 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1781 SetLastError(0xdeadbeef);
1782 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1783 if (ret
== 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1785 win_skip("Needed W-functions are not implemented\n");
1788 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1789 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1791 flags
= FDTF_LONGTIME
;
1792 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1793 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1794 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1795 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1796 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1798 /* both time flags */
1799 flags
= FDTF_LONGTIME
| FDTF_SHORTTIME
;
1800 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1801 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1802 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1803 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1804 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal string\n");
1806 flags
= FDTF_SHORTDATE
;
1807 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1808 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1809 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1810 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1811 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1813 flags
= FDTF_LONGDATE
;
1814 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1815 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1816 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1817 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1818 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1820 /* both date flags */
1821 flags
= FDTF_LONGDATE
| FDTF_SHORTDATE
;
1822 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1823 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1824 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1825 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1826 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1828 /* various combinations of date/time flags */
1829 flags
= FDTF_LONGDATE
| FDTF_SHORTTIME
;
1830 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1831 ok(ret
== lstrlenW(buff
)+1, "got %d, length %d\n", ret
, lstrlenW(buff
)+1);
1832 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1833 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1834 lstrcatW(buff2
, commaW
);
1835 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &st
, NULL
, buff3
, sizeof(buff3
)/sizeof(WCHAR
));
1836 ok(ret
== lstrlenW(buff3
)+1, "got %d\n", ret
);
1837 lstrcatW(buff2
, buff3
);
1838 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1840 flags
= FDTF_LONGDATE
| FDTF_LONGTIME
;
1841 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1842 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1843 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1844 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1845 lstrcatW(buff2
, commaW
);
1846 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff3
, sizeof(buff3
)/sizeof(WCHAR
));
1847 ok(ret
== lstrlenW(buff3
)+1, "got %d\n", ret
);
1848 lstrcatW(buff2
, buff3
);
1849 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1851 flags
= FDTF_SHORTDATE
| FDTF_SHORTTIME
;
1852 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1853 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1854 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1855 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1856 lstrcatW(buff2
, spaceW
);
1857 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &st
, NULL
, buff3
, sizeof(buff3
)/sizeof(WCHAR
));
1858 ok(ret
== lstrlenW(buff3
)+1, "got %d\n", ret
);
1859 lstrcatW(buff2
, buff3
);
1860 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1862 flags
= FDTF_SHORTDATE
| FDTF_LONGTIME
;
1863 ret
= pSHFormatDateTimeW(&filetime
, &flags
, buff
, sizeof(buff
)/sizeof(WCHAR
));
1864 ok(ret
== lstrlenW(buff
)+1, "got %d\n", ret
);
1865 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, NULL
, buff2
, sizeof(buff2
)/sizeof(WCHAR
));
1866 ok(ret
== lstrlenW(buff2
)+1, "got %d\n", ret
);
1867 lstrcatW(buff2
, spaceW
);
1868 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buff3
, sizeof(buff3
)/sizeof(WCHAR
));
1869 ok(ret
== lstrlenW(buff3
)+1, "got %d\n", ret
);
1870 lstrcatW(buff2
, buff3
);
1871 ok(lstrcmpW(buff
, buff2
) == 0, "expected equal strings\n");
1874 static void test_SHGetObjectCompatFlags(void)
1876 struct compat_value
{
1881 struct compat_value values
[] = {
1882 { "OTNEEDSSFCACHE", 0x1 },
1883 { "NO_WEBVIEW", 0x2 },
1884 { "UNBINDABLE", 0x4 },
1886 { "NEEDSFILESYSANCESTOR", 0x10 },
1887 { "NOTAFILESYSTEM", 0x20 },
1888 { "CTXMENU_NOVERBS", 0x40 },
1889 { "CTXMENU_LIMITEDQI", 0x80 },
1890 { "COCREATESHELLFOLDERONLY", 0x100 },
1891 { "NEEDSSTORAGEANCESTOR", 0x200 },
1892 { "NOLEGACYWEBVIEW", 0x400 },
1893 { "CTXMENU_XPQCMFLAGS", 0x1000 },
1894 { "NOIPROPERTYSTORE", 0x2000 }
1897 static const char compat_path
[] = "Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Objects";
1898 CHAR keyA
[39]; /* {CLSID} */
1903 if (!pSHGetObjectCompatFlags
)
1905 win_skip("SHGetObjectCompatFlags isn't available\n");
1910 ret
= pSHGetObjectCompatFlags(NULL
, NULL
);
1911 ok(ret
== 0, "got %d\n", ret
);
1913 ret
= RegOpenKeyA(HKEY_LOCAL_MACHINE
, compat_path
, &root
);
1914 if (ret
!= ERROR_SUCCESS
)
1916 skip("No compatibility class data found\n");
1920 for (i
= 0; RegEnumKeyA(root
, i
, keyA
, sizeof(keyA
)) == ERROR_SUCCESS
; i
++)
1924 if (RegOpenKeyA(root
, keyA
, &clsid_key
) == ERROR_SUCCESS
)
1927 DWORD expected
= 0, got
, length
= sizeof(valueA
);
1931 for (v
= 0; RegEnumValueA(clsid_key
, v
, valueA
, &length
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; v
++)
1935 for (j
= 0; j
< sizeof(values
)/sizeof(struct compat_value
); j
++)
1936 if (lstrcmpA(values
[j
].nameA
, valueA
) == 0)
1938 expected
|= values
[j
].value
;
1942 length
= sizeof(valueA
);
1945 pGUIDFromStringA(keyA
, &clsid
);
1946 got
= pSHGetObjectCompatFlags(NULL
, &clsid
);
1947 ok(got
== expected
, "got 0x%08x, expected 0x%08x. Key %s\n", got
, expected
, keyA
);
1949 RegCloseKey(clsid_key
);
1957 const IOleCommandTargetVtbl
*lpVtbl
;
1959 } IOleCommandTargetImpl
;
1961 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl
;
1963 static IOleCommandTarget
* IOleCommandTargetImpl_Construct(void)
1965 IOleCommandTargetImpl
*obj
;
1967 obj
= HeapAlloc(GetProcessHeap(), 0, sizeof(*obj
));
1968 obj
->lpVtbl
= &IOleCommandTargetImpl_Vtbl
;
1971 return (IOleCommandTarget
*)obj
;
1974 static HRESULT WINAPI
IOleCommandTargetImpl_QueryInterface(IOleCommandTarget
*iface
, REFIID riid
, void **ppvObj
)
1976 IOleCommandTargetImpl
*This
= (IOleCommandTargetImpl
*)iface
;
1978 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1979 IsEqualIID(riid
, &IID_IOleCommandTarget
))
1986 IUnknown_AddRef(iface
);
1990 return E_NOINTERFACE
;
1993 static ULONG WINAPI
IOleCommandTargetImpl_AddRef(IOleCommandTarget
*iface
)
1995 IOleCommandTargetImpl
*This
= (IOleCommandTargetImpl
*)iface
;
1996 return InterlockedIncrement(&This
->ref
);
1999 static ULONG WINAPI
IOleCommandTargetImpl_Release(IOleCommandTarget
*iface
)
2001 IOleCommandTargetImpl
*This
= (IOleCommandTargetImpl
*)iface
;
2002 ULONG ref
= InterlockedDecrement(&This
->ref
);
2006 HeapFree(GetProcessHeap(), 0, This
);
2012 static HRESULT WINAPI
IOleCommandTargetImpl_QueryStatus(
2013 IOleCommandTarget
*iface
, const GUID
*group
, ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
2018 static HRESULT WINAPI
IOleCommandTargetImpl_Exec(
2019 IOleCommandTarget
*iface
,
2020 const GUID
*CmdGroup
,
2026 add_call(&trace_got
, 3, CmdGroup
, (void*)(DWORD_PTR
)nCmdID
, (void*)(DWORD_PTR
)nCmdexecopt
, pvaIn
, pvaOut
);
2030 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl
=
2032 IOleCommandTargetImpl_QueryInterface
,
2033 IOleCommandTargetImpl_AddRef
,
2034 IOleCommandTargetImpl_Release
,
2035 IOleCommandTargetImpl_QueryStatus
,
2036 IOleCommandTargetImpl_Exec
2040 const IServiceProviderVtbl
*lpVtbl
;
2042 } IServiceProviderImpl
;
2045 const IProfferServiceVtbl
*lpVtbl
;
2047 } IProfferServiceImpl
;
2050 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl
;
2051 static const IProfferServiceVtbl IProfferServiceImpl_Vtbl
;
2053 static IServiceProvider
* IServiceProviderImpl_Construct(void)
2055 IServiceProviderImpl
*obj
;
2057 obj
= HeapAlloc(GetProcessHeap(), 0, sizeof(*obj
));
2058 obj
->lpVtbl
= &IServiceProviderImpl_Vtbl
;
2061 return (IServiceProvider
*)obj
;
2064 static IProfferService
* IProfferServiceImpl_Construct(void)
2066 IProfferServiceImpl
*obj
;
2068 obj
= HeapAlloc(GetProcessHeap(), 0, sizeof(*obj
));
2069 obj
->lpVtbl
= &IProfferServiceImpl_Vtbl
;
2072 return (IProfferService
*)obj
;
2075 static HRESULT WINAPI
IServiceProviderImpl_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppvObj
)
2077 IServiceProviderImpl
*This
= (IServiceProviderImpl
*)iface
;
2079 if (IsEqualIID(riid
, &IID_IUnknown
) ||
2080 IsEqualIID(riid
, &IID_IServiceProvider
))
2087 IUnknown_AddRef(iface
);
2088 /* native uses redefined IID_IServiceProvider symbol, so we can't compare pointers */
2089 if (IsEqualIID(riid
, &IID_IServiceProvider
))
2090 add_call(&trace_got
, 1, iface
, &IID_IServiceProvider
, 0, 0, 0);
2094 return E_NOINTERFACE
;
2097 static ULONG WINAPI
IServiceProviderImpl_AddRef(IServiceProvider
*iface
)
2099 IServiceProviderImpl
*This
= (IServiceProviderImpl
*)iface
;
2100 return InterlockedIncrement(&This
->ref
);
2103 static ULONG WINAPI
IServiceProviderImpl_Release(IServiceProvider
*iface
)
2105 IServiceProviderImpl
*This
= (IServiceProviderImpl
*)iface
;
2106 ULONG ref
= InterlockedDecrement(&This
->ref
);
2110 HeapFree(GetProcessHeap(), 0, This
);
2116 static HRESULT WINAPI
IServiceProviderImpl_QueryService(
2117 IServiceProvider
*iface
, REFGUID service
, REFIID riid
, void **ppv
)
2119 /* native uses redefined pointer for IID_IOleCommandTarget, not one from uuid.lib */
2120 if (IsEqualIID(riid
, &IID_IOleCommandTarget
))
2122 add_call(&trace_got
, 2, iface
, service
, &IID_IOleCommandTarget
, 0, 0);
2123 *ppv
= IOleCommandTargetImpl_Construct();
2125 if (IsEqualIID(riid
, &IID_IProfferService
))
2127 if (IsEqualIID(service
, &IID_IProfferService
))
2128 add_call(&trace_got
, 2, &IID_IProfferService
, &IID_IProfferService
, 0, 0, 0);
2129 *ppv
= IProfferServiceImpl_Construct();
2134 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl
=
2136 IServiceProviderImpl_QueryInterface
,
2137 IServiceProviderImpl_AddRef
,
2138 IServiceProviderImpl_Release
,
2139 IServiceProviderImpl_QueryService
2142 static void test_IUnknown_QueryServiceExec(void)
2144 IServiceProvider
*provider
= IServiceProviderImpl_Construct();
2145 static const GUID dummy_serviceid
= { 0xdeadbeef };
2146 static const GUID dummy_groupid
= { 0xbeefbeef };
2147 call_trace_t trace_expected
;
2150 /* on <=W2K platforms same ordinal used for another export with different
2151 prototype, so skipping using this indirect condition */
2152 if (is_win2k_and_lower
)
2154 win_skip("IUnknown_QueryServiceExec is not available\n");
2158 /* null source pointer */
2159 hr
= pIUnknown_QueryServiceExec(NULL
, &dummy_serviceid
, &dummy_groupid
, 0, 0, 0, 0);
2160 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2163 IUnknown_QueryServiceExec( ptr1, serviceid, groupid, arg1, arg2, arg3, arg4);
2164 -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &prov );
2165 -> IServiceProvider_QueryService( prov, serviceid, &IID_IOleCommandTarget, &obj );
2166 -> IOleCommandTarget_Exec( obj, groupid, arg1, arg2, arg3, arg4 );
2168 init_call_trace(&trace_expected
);
2170 add_call(&trace_expected
, 1, provider
, &IID_IServiceProvider
, 0, 0, 0);
2171 add_call(&trace_expected
, 2, provider
, &dummy_serviceid
, &IID_IOleCommandTarget
, 0, 0);
2172 add_call(&trace_expected
, 3, &dummy_groupid
, (void*)0x1, (void*)0x2, (void*)0x3, (void*)0x4);
2174 init_call_trace(&trace_got
);
2175 hr
= pIUnknown_QueryServiceExec((IUnknown
*)provider
, &dummy_serviceid
, &dummy_groupid
, 0x1, 0x2, (void*)0x3, (void*)0x4);
2176 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2178 ok_trace(&trace_expected
, &trace_got
);
2180 free_call_trace(&trace_expected
);
2181 free_call_trace(&trace_got
);
2183 IServiceProvider_Release(provider
);
2187 static HRESULT WINAPI
IProfferServiceImpl_QueryInterface(IProfferService
*iface
, REFIID riid
, void **ppvObj
)
2189 IProfferServiceImpl
*This
= (IProfferServiceImpl
*)iface
;
2191 if (IsEqualIID(riid
, &IID_IUnknown
) ||
2192 IsEqualIID(riid
, &IID_IProfferService
))
2196 else if (IsEqualIID(riid
, &IID_IServiceProvider
))
2198 *ppvObj
= IServiceProviderImpl_Construct();
2199 add_call(&trace_got
, 1, iface
, &IID_IServiceProvider
, 0, 0, 0);
2205 IUnknown_AddRef(iface
);
2209 return E_NOINTERFACE
;
2212 static ULONG WINAPI
IProfferServiceImpl_AddRef(IProfferService
*iface
)
2214 IProfferServiceImpl
*This
= (IProfferServiceImpl
*)iface
;
2215 return InterlockedIncrement(&This
->ref
);
2218 static ULONG WINAPI
IProfferServiceImpl_Release(IProfferService
*iface
)
2220 IProfferServiceImpl
*This
= (IProfferServiceImpl
*)iface
;
2221 ULONG ref
= InterlockedDecrement(&This
->ref
);
2225 HeapFree(GetProcessHeap(), 0, This
);
2231 static HRESULT WINAPI
IProfferServiceImpl_ProfferService(IProfferService
*iface
,
2232 REFGUID service
, IServiceProvider
*pService
, DWORD
*pCookie
)
2234 add_call(&trace_got
, 3, service
, pService
, pCookie
, 0, 0);
2238 static HRESULT WINAPI
IProfferServiceImpl_RevokeService(IProfferService
*iface
, DWORD cookie
)
2240 add_call(&trace_got
, 4, (void*)(DWORD_PTR
)cookie
, 0, 0, 0, 0);
2244 static const IProfferServiceVtbl IProfferServiceImpl_Vtbl
=
2246 IProfferServiceImpl_QueryInterface
,
2247 IProfferServiceImpl_AddRef
,
2248 IProfferServiceImpl_Release
,
2249 IProfferServiceImpl_ProfferService
,
2250 IProfferServiceImpl_RevokeService
2253 static void test_IUnknown_ProfferService(void)
2255 IServiceProvider
*provider
= IServiceProviderImpl_Construct();
2256 IProfferService
*proff
= IProfferServiceImpl_Construct();
2257 static const GUID dummy_serviceid
= { 0xdeadbeef };
2258 call_trace_t trace_expected
;
2262 /* on <=W2K platforms same ordinal used for another export with different
2263 prototype, so skipping using this indirect condition */
2264 if (is_win2k_and_lower
)
2266 win_skip("IUnknown_ProfferService is not available\n");
2270 /* null source pointer */
2271 hr
= pIUnknown_ProfferService(NULL
, &dummy_serviceid
, 0, 0);
2272 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2275 IUnknown_ProfferService( ptr1, serviceid, arg1, arg2);
2276 -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &provider );
2277 -> IServiceProvider_QueryService( provider, &IID_IProfferService, &IID_IProfferService, &proffer );
2279 if (service pointer not null):
2280 -> IProfferService_ProfferService( proffer, serviceid, arg1, arg2 );
2282 -> IProfferService_RevokeService( proffer, *arg2 );
2284 init_call_trace(&trace_expected
);
2286 add_call(&trace_expected
, 1, proff
, &IID_IServiceProvider
, 0, 0, 0);
2287 add_call(&trace_expected
, 2, &IID_IProfferService
, &IID_IProfferService
, 0, 0, 0);
2288 add_call(&trace_expected
, 3, &dummy_serviceid
, provider
, &cookie
, 0, 0);
2290 init_call_trace(&trace_got
);
2291 hr
= pIUnknown_ProfferService((IUnknown
*)proff
, &dummy_serviceid
, provider
, &cookie
);
2292 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2294 ok_trace(&trace_expected
, &trace_got
);
2295 free_call_trace(&trace_got
);
2296 free_call_trace(&trace_expected
);
2298 /* same with ::Revoke path */
2299 init_call_trace(&trace_expected
);
2301 add_call(&trace_expected
, 1, proff
, &IID_IServiceProvider
, 0, 0, 0);
2302 add_call(&trace_expected
, 2, &IID_IProfferService
, &IID_IProfferService
, 0, 0, 0);
2303 add_call(&trace_expected
, 4, (void*)(DWORD_PTR
)cookie
, 0, 0, 0, 0);
2305 init_call_trace(&trace_got
);
2306 hr
= pIUnknown_ProfferService((IUnknown
*)proff
, &dummy_serviceid
, 0, &cookie
);
2307 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2308 ok_trace(&trace_expected
, &trace_got
);
2309 free_call_trace(&trace_got
);
2310 free_call_trace(&trace_expected
);
2312 IServiceProvider_Release(provider
);
2313 IProfferService_Release(proff
);
2316 static void test_SHCreateWorkerWindowA(void)
2324 if (is_win2k_and_lower
)
2326 win_skip("SHCreateWorkerWindowA not available\n");
2330 hwnd
= pSHCreateWorkerWindowA(0, NULL
, 0, 0, 0, 0);
2331 ok(hwnd
!= 0, "expected window\n");
2333 GetClassName(hwnd
, classA
, 20);
2334 ok(lstrcmpA(classA
, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA
);
2336 ret
= GetWindowLongPtrA(hwnd
, 0);
2337 ok(ret
== 0, "got %ld\n", ret
);
2340 memset(&cliA
, 0, sizeof(cliA
));
2341 res
= GetClassInfoA(GetModuleHandle("shlwapi.dll"), "WorkerA", &cliA
);
2342 ok(res
, "failed to get class info\n");
2343 ok(cliA
.style
== 0, "got 0x%08x\n", cliA
.style
);
2344 ok(cliA
.cbClsExtra
== 0, "got %d\n", cliA
.cbClsExtra
);
2345 ok(cliA
.cbWndExtra
== sizeof(LONG_PTR
), "got %d\n", cliA
.cbWndExtra
);
2346 ok(cliA
.lpszMenuName
== 0, "got %s\n", cliA
.lpszMenuName
);
2348 DestroyWindow(hwnd
);
2350 /* set extra bytes */
2351 hwnd
= pSHCreateWorkerWindowA(0, NULL
, 0, 0, 0, 0xdeadbeef);
2352 ok(hwnd
!= 0, "expected window\n");
2354 GetClassName(hwnd
, classA
, 20);
2355 ok(lstrcmpA(classA
, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA
);
2357 ret
= GetWindowLongPtrA(hwnd
, 0);
2358 ok(ret
== 0xdeadbeef, "got %ld\n", ret
);
2361 ret
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
2362 ok(ret
== WS_EX_WINDOWEDGE
, "0x%08lx\n", ret
);
2364 DestroyWindow(hwnd
);
2366 hwnd
= pSHCreateWorkerWindowA(0, NULL
, WS_EX_TOOLWINDOW
, 0, 0, 0);
2367 ret
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
2368 ok(ret
== (WS_EX_WINDOWEDGE
|WS_EX_TOOLWINDOW
), "0x%08lx\n", ret
);
2369 DestroyWindow(hwnd
);
2372 static void init_pointers(void)
2374 #define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord)))
2375 MAKEFUNC(SHAllocShared
, 7);
2376 MAKEFUNC(SHLockShared
, 8);
2377 MAKEFUNC(SHUnlockShared
, 9);
2378 MAKEFUNC(SHFreeShared
, 10);
2379 MAKEFUNC(GetAcceptLanguagesA
, 14);
2380 MAKEFUNC(SHSetWindowBits
, 165);
2381 MAKEFUNC(ConnectToConnectionPoint
, 168);
2382 MAKEFUNC(SHSearchMapInt
, 198);
2383 MAKEFUNC(SHCreateWorkerWindowA
, 257);
2384 MAKEFUNC(GUIDFromStringA
, 269);
2385 MAKEFUNC(SHPackDispParams
, 282);
2386 MAKEFUNC(IConnectionPoint_InvokeWithCancel
, 283);
2387 MAKEFUNC(IConnectionPoint_SimpleInvoke
, 284);
2388 MAKEFUNC(SHFormatDateTimeA
, 353);
2389 MAKEFUNC(SHFormatDateTimeW
, 354);
2390 MAKEFUNC(SHGetObjectCompatFlags
, 476);
2391 MAKEFUNC(IUnknown_QueryServiceExec
, 484);
2392 MAKEFUNC(SHPropertyBag_ReadLONG
, 496);
2393 MAKEFUNC(IUnknown_ProfferService
, 514);
2399 hShlwapi
= GetModuleHandleA("shlwapi.dll");
2400 is_win2k_and_lower
= GetProcAddress(hShlwapi
, "StrChrNW") == 0;
2404 hmlang
= LoadLibraryA("mlang.dll");
2405 pLcidToRfc1766A
= (void *)GetProcAddress(hmlang
, "LcidToRfc1766A");
2407 test_GetAcceptLanguagesA();
2408 test_SHSearchMapInt();
2409 test_alloc_shared();
2411 test_GetShellSecurityDescriptor();
2412 test_SHPackDispParams();
2413 test_IConnectionPoint();
2414 test_SHPropertyBag_ReadLONG();
2415 test_SHSetWindowBits();
2416 test_SHFormatDateTimeA();
2417 test_SHFormatDateTimeW();
2418 test_SHGetObjectCompatFlags();
2419 test_IUnknown_QueryServiceExec();
2420 test_IUnknown_ProfferService();
2421 test_SHCreateWorkerWindowA();