push 6e61d6ca5bcaf95ac09a664b4ba4f88238c927be
[wine/hacks.git] / dlls / shlwapi / tests / ordinal.c
blob83aec78cd1f147f9cd06148b09cfd21bb81525b9
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
20 #include <stdio.h>
22 #define COBJMACROS
23 #include "wine/test.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "oaidl.h"
29 #include "ocidl.h"
30 #include "mlang.h"
31 #include "shlwapi.h"
33 /* Function ptrs for ordinal calls */
34 static HMODULE hShlwapi;
35 static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
36 static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
38 static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
39 static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
40 static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
41 static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
42 static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
43 static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*);
44 static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD);
45 static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
46 static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG);
47 static LONG (WINAPI *pSHSetWindowBits)(HWND, INT, UINT, UINT);
48 static INT (WINAPI *pSHFormatDateTimeA)(const FILETIME UNALIGNED*, DWORD*, LPSTR, UINT);
49 static INT (WINAPI *pSHFormatDateTimeW)(const FILETIME UNALIGNED*, DWORD*, LPWSTR, UINT);
51 static HMODULE hmlang;
52 static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
54 static const CHAR ie_international[] = {
55 'S','o','f','t','w','a','r','e','\\',
56 'M','i','c','r','o','s','o','f','t','\\',
57 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
58 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
59 static const CHAR acceptlanguage[] = {
60 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
63 static void test_GetAcceptLanguagesA(void)
65 static LPCSTR table[] = {"de,en-gb;q=0.7,en;q=0.3",
66 "de,en;q=0.3,en-gb;q=0.7", /* sorting is ignored */
67 "winetest", /* content is ignored */
68 "de-de,de;q=0.5",
69 "de",
70 NULL};
72 DWORD exactsize;
73 char original[512];
74 char language[32];
75 char buffer[64];
76 HKEY hroot = NULL;
77 LONG res_query = ERROR_SUCCESS;
78 LONG lres;
79 HRESULT hr;
80 DWORD maxlen = sizeof(buffer) - 2;
81 DWORD len;
82 LCID lcid;
83 LPCSTR entry;
84 INT i = 0;
86 if (!pGetAcceptLanguagesA) {
87 win_skip("GetAcceptLanguagesA is not available\n");
88 return;
91 lcid = GetUserDefaultLCID();
93 /* Get the original Value */
94 lres = RegOpenKeyA(HKEY_CURRENT_USER, ie_international, &hroot);
95 if (lres) {
96 skip("RegOpenKey(%s) failed: %d\n", ie_international, lres);
97 return;
99 len = sizeof(original);
100 original[0] = 0;
101 res_query = RegQueryValueExA(hroot, acceptlanguage, 0, NULL, (PBYTE)original, &len);
103 RegDeleteValue(hroot, acceptlanguage);
105 /* Some windows versions use "lang-COUNTRY" as default */
106 memset(language, 0, sizeof(language));
107 len = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, language, sizeof(language));
109 if (len) {
110 lstrcat(language, "-");
111 memset(buffer, 0, sizeof(buffer));
112 len = GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, buffer, sizeof(buffer) - len - 1);
113 lstrcat(language, buffer);
115 else
117 /* LOCALE_SNAME has additional parts in some languages. Try only as last chance */
118 memset(language, 0, sizeof(language));
119 len = GetLocaleInfoA(lcid, LOCALE_SNAME, language, sizeof(language));
122 /* get the default value */
123 len = maxlen;
124 memset(buffer, '#', maxlen);
125 buffer[maxlen] = 0;
126 hr = pGetAcceptLanguagesA( buffer, &len);
128 if (hr != S_OK) {
129 win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr);
130 goto restore_original;
133 if (lstrcmpA(buffer, language)) {
134 /* some windows versions use "lang" or "lang-country" as default */
135 language[0] = 0;
136 if (pLcidToRfc1766A) {
137 hr = pLcidToRfc1766A(lcid, language, sizeof(language));
138 ok(hr == S_OK, "LcidToRfc1766A returned 0x%x and %s\n", hr, language);
142 ok(!lstrcmpA(buffer, language),
143 "have '%s' (searching for '%s')\n", language, buffer);
145 if (lstrcmpA(buffer, language)) {
146 win_skip("no more ideas, how to build the default language '%s'\n", buffer);
147 goto restore_original;
150 trace("detected default: %s\n", language);
151 while ((entry = table[i])) {
153 exactsize = lstrlenA(entry);
155 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) entry, exactsize + 1);
156 ok(!lres, "got %d for RegSetValueExA: %s\n", lres, entry);
158 /* len includes space for the terminating 0 before vista/w2k8 */
159 len = exactsize + 2;
160 memset(buffer, '#', maxlen);
161 buffer[maxlen] = 0;
162 hr = pGetAcceptLanguagesA( buffer, &len);
163 ok(((hr == E_INVALIDARG) && (len == 0)) ||
164 (SUCCEEDED(hr) &&
165 ((len == exactsize) || (len == exactsize+1)) &&
166 !lstrcmpA(buffer, entry)),
167 "+2_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
169 len = exactsize + 1;
170 memset(buffer, '#', maxlen);
171 buffer[maxlen] = 0;
172 hr = pGetAcceptLanguagesA( buffer, &len);
173 ok(((hr == E_INVALIDARG) && (len == 0)) ||
174 (SUCCEEDED(hr) &&
175 ((len == exactsize) || (len == exactsize+1)) &&
176 !lstrcmpA(buffer, entry)),
177 "+1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
179 len = exactsize;
180 memset(buffer, '#', maxlen);
181 buffer[maxlen] = 0;
182 hr = pGetAcceptLanguagesA( buffer, &len);
184 /* There is no space for the string in the registry.
185 When the buffer is large enough, the default language is returned
187 When the buffer is to small for that fallback, win7_32 and w2k8_64
188 and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), but
189 recent os succeed and return a partial result while
190 older os succeed and overflow the buffer */
192 ok(((hr == E_INVALIDARG) && (len == 0)) ||
193 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
194 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
195 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
196 "==_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
198 if (exactsize > 1) {
199 len = exactsize - 1;
200 memset(buffer, '#', maxlen);
201 buffer[maxlen] = 0;
202 hr = pGetAcceptLanguagesA( buffer, &len);
203 ok(((hr == E_INVALIDARG) && (len == 0)) ||
204 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
205 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
206 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
207 "-1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
210 len = 1;
211 memset(buffer, '#', maxlen);
212 buffer[maxlen] = 0;
213 hr = pGetAcceptLanguagesA( buffer, &len);
214 ok(((hr == E_INVALIDARG) && (len == 0)) ||
215 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
216 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
217 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
218 "=1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
220 len = maxlen;
221 hr = pGetAcceptLanguagesA( NULL, &len);
223 /* w2k3 and below: E_FAIL and untouched len,
224 since w2k8: S_OK and needed size (excluding 0) */
225 ok( ((hr == S_OK) && (len == exactsize)) ||
226 ((hr == E_FAIL) && (len == maxlen)),
227 "NULL,max #%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
229 i++;
232 /* without a value in the registry, a default language is returned */
233 RegDeleteValue(hroot, acceptlanguage);
235 len = maxlen;
236 memset(buffer, '#', maxlen);
237 buffer[maxlen] = 0;
238 hr = pGetAcceptLanguagesA( buffer, &len);
239 ok( ((hr == S_OK) && (len == lstrlenA(language))),
240 "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n",
241 hr, len, buffer, lstrlenA(language), language);
243 len = 2;
244 memset(buffer, '#', maxlen);
245 buffer[maxlen] = 0;
246 hr = pGetAcceptLanguagesA( buffer, &len);
247 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
248 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
249 "=2: got 0x%x with %d and %s\n", hr, len, buffer);
251 len = 1;
252 memset(buffer, '#', maxlen);
253 buffer[maxlen] = 0;
254 hr = pGetAcceptLanguagesA( buffer, &len);
255 /* When the buffer is to small, win7_32 and w2k8_64 and above fail with
256 HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), other versions suceed
257 and return a partial 0 terminated result while other versions
258 fail with E_INVALIDARG and return a partial unterminated result */
259 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
260 ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
261 "=1: got 0x%x with %d and %s\n", hr, len, buffer);
263 len = 0;
264 memset(buffer, '#', maxlen);
265 buffer[maxlen] = 0;
266 hr = pGetAcceptLanguagesA( buffer, &len);
267 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
268 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
269 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
271 memset(buffer, '#', maxlen);
272 buffer[maxlen] = 0;
273 hr = pGetAcceptLanguagesA( buffer, NULL);
274 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
275 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
276 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
279 hr = pGetAcceptLanguagesA( NULL, NULL);
280 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
281 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
282 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
284 restore_original:
285 if (!res_query) {
286 len = lstrlenA(original);
287 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) original, len ? len + 1: 0);
288 ok(!lres, "RegSetValueEx(%s) failed: %d\n", original, lres);
290 else
292 RegDeleteValue(hroot, acceptlanguage);
294 RegCloseKey(hroot);
297 static void test_SHSearchMapInt(void)
299 int keys[8], values[8];
300 int i = 0;
302 if (!pSHSearchMapInt)
303 return;
305 memset(keys, 0, sizeof(keys));
306 memset(values, 0, sizeof(values));
307 keys[0] = 99; values[0] = 101;
309 /* NULL key/value lists crash native, so skip testing them */
311 /* 1 element */
312 i = pSHSearchMapInt(keys, values, 1, keys[0]);
313 ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
315 /* Key doesn't exist */
316 i = pSHSearchMapInt(keys, values, 1, 100);
317 ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);
319 /* Len = 0 => not found */
320 i = pSHSearchMapInt(keys, values, 0, keys[0]);
321 ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);
323 /* 2 elements, len = 1 */
324 keys[1] = 98; values[1] = 102;
325 i = pSHSearchMapInt(keys, values, 1, keys[1]);
326 ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);
328 /* 2 elements, len = 2 */
329 i = pSHSearchMapInt(keys, values, 2, keys[1]);
330 ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);
332 /* Searches forward */
333 keys[2] = 99; values[2] = 103;
334 i = pSHSearchMapInt(keys, values, 3, keys[0]);
335 ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
338 static void test_alloc_shared(void)
340 DWORD procid;
341 HANDLE hmem;
342 int val;
343 int* p;
344 BOOL ret;
346 procid=GetCurrentProcessId();
347 hmem=pSHAllocShared(NULL,10,procid);
348 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
349 ret = pSHFreeShared(hmem, procid);
350 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
352 val=0x12345678;
353 hmem=pSHAllocShared(&val,4,procid);
354 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
356 p=pSHLockShared(hmem,procid);
357 ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
358 if (p!=NULL)
359 ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
360 ret = pSHUnlockShared(p);
361 ok( ret, "SHUnlockShared failed: %u\n", GetLastError());
363 ret = pSHFreeShared(hmem, procid);
364 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
367 static void test_fdsa(void)
369 typedef struct
371 DWORD num_items; /* Number of elements inserted */
372 void *mem; /* Ptr to array */
373 DWORD blocks_alloced; /* Number of elements allocated */
374 BYTE inc; /* Number of elements to grow by when we need to expand */
375 BYTE block_size; /* Size in bytes of an element */
376 BYTE flags; /* Flags */
377 } FDSA_info;
379 BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
380 DWORD init_blocks);
381 BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
382 DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
383 BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);
385 FDSA_info info;
386 int block_size = 10, init_blocks = 4, inc = 2;
387 DWORD ret;
388 char *mem;
390 pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
391 pFDSA_Destroy = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
392 pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
393 pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);
395 mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
396 memset(&info, 0, sizeof(info));
398 ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
399 ok(info.num_items == 0, "num_items = %d\n", info.num_items);
400 ok(info.mem == mem, "mem = %p\n", info.mem);
401 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
402 ok(info.inc == inc, "inc = %d\n", info.inc);
403 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
404 ok(info.flags == 0, "flags = %d\n", info.flags);
406 ret = pFDSA_InsertItem(&info, 1234, "1234567890");
407 ok(ret == 0, "ret = %d\n", ret);
408 ok(info.num_items == 1, "num_items = %d\n", info.num_items);
409 ok(info.mem == mem, "mem = %p\n", info.mem);
410 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
411 ok(info.inc == inc, "inc = %d\n", info.inc);
412 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
413 ok(info.flags == 0, "flags = %d\n", info.flags);
415 ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
416 ok(ret == 1, "ret = %d\n", ret);
418 ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
419 ok(ret == 1, "ret = %d\n", ret);
421 ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
422 ok(ret == 0, "ret = %d\n", ret);
423 ok(info.mem == mem, "mem = %p\n", info.mem);
424 ok(info.flags == 0, "flags = %d\n", info.flags);
426 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
427 ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
428 ok(ret == 0, "ret = %d\n", ret);
429 ok(info.mem != mem, "mem = %p\n", info.mem);
430 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
431 ok(info.flags == 0x1, "flags = %d\n", info.flags);
433 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
435 ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
436 ok(info.mem != mem, "mem = %p\n", info.mem);
437 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
438 ok(info.flags == 0x1, "flags = %d\n", info.flags);
440 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
442 ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
443 ok(info.mem != mem, "mem = %p\n", info.mem);
444 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
445 ok(info.flags == 0x1, "flags = %d\n", info.flags);
447 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
449 ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
451 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
452 ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
455 /* When Initialize is called with inc = 0, set it to 1 */
456 ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
457 ok(info.inc == 1, "inc = %d\n", info.inc);
459 /* This time, because shlwapi hasn't had to allocate memory
460 internally, Destroy rets non-zero */
461 ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");
464 HeapFree(GetProcessHeap(), 0, mem);
468 typedef struct SHELL_USER_SID {
469 SID_IDENTIFIER_AUTHORITY sidAuthority;
470 DWORD dwUserGroupID;
471 DWORD dwUserID;
472 } SHELL_USER_SID, *PSHELL_USER_SID;
473 typedef struct SHELL_USER_PERMISSION {
474 SHELL_USER_SID susID;
475 DWORD dwAccessType;
476 BOOL fInherit;
477 DWORD dwAccessMask;
478 DWORD dwInheritMask;
479 DWORD dwInheritAccessMask;
480 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
481 static void test_GetShellSecurityDescriptor(void)
483 SHELL_USER_PERMISSION supCurrentUserFull = {
484 { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
485 ACCESS_ALLOWED_ACE_TYPE, FALSE,
486 GENERIC_ALL, 0, 0 };
487 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
488 SHELL_USER_PERMISSION supEveryoneDenied = {
489 { {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 },
490 ACCESS_DENIED_ACE_TYPE, TRUE,
491 GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ };
492 PSHELL_USER_PERMISSION rgsup[2] = {
493 &supCurrentUserFull, &supEveryoneDenied,
495 SECURITY_DESCRIPTOR* psd;
496 SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
498 pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);
500 if(!pGetShellSecurityDescriptor)
502 win_skip("GetShellSecurityDescriptor not available\n");
503 return;
506 psd = pGetShellSecurityDescriptor(NULL, 2);
507 ok(psd==NULL ||
508 broken(psd==INVALID_HANDLE_VALUE), /* IE5 */
509 "GetShellSecurityDescriptor should fail\n");
510 psd = pGetShellSecurityDescriptor(rgsup, 0);
511 ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
513 SetLastError(0xdeadbeef);
514 psd = pGetShellSecurityDescriptor(rgsup, 2);
515 if (psd == NULL && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
517 /* The previous calls to GetShellSecurityDescriptor don't set the last error */
518 win_skip("GetShellSecurityDescriptor is not implemented\n");
519 return;
521 if (psd==INVALID_HANDLE_VALUE)
523 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
524 return;
526 ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
527 if (psd!=NULL)
529 BOOL bHasDacl = FALSE, bDefaulted;
530 PACL pAcl;
531 DWORD dwRev;
532 SECURITY_DESCRIPTOR_CONTROL control;
534 ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
536 ok(GetSecurityDescriptorControl(psd, &control, &dwRev),
537 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
538 ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");
540 ok(GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted),
541 "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
543 ok(bHasDacl, "SD has no DACL\n");
544 if (bHasDacl)
546 ok(!bDefaulted, "DACL should not be defaulted\n");
548 ok(pAcl != NULL, "NULL DACL!\n");
549 if (pAcl != NULL)
551 ACL_SIZE_INFORMATION asiSize;
553 ok(IsValidAcl(pAcl), "DACL is not valid\n");
555 ok(GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation),
556 "GetAclInformation failed with error %u\n", GetLastError());
558 ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
559 if (asiSize.AceCount == 3)
561 ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
563 ok(GetAce(pAcl, 0, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
564 ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
565 "Invalid ACE type %d\n", paaa->Header.AceType);
566 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
567 ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);
569 ok(GetAce(pAcl, 1, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
570 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
571 "Invalid ACE type %d\n", paaa->Header.AceType);
572 /* first one of two ACEs generated from inheritable entry - without inheritance */
573 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
574 ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);
576 ok(GetAce(pAcl, 2, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
577 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
578 "Invalid ACE type %d\n", paaa->Header.AceType);
579 /* second ACE - with inheritance */
580 ok(paaa->Header.AceFlags == MY_INHERITANCE,
581 "Invalid ACE flags %x\n", paaa->Header.AceFlags);
582 ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
587 LocalFree(psd);
591 static void test_SHPackDispParams(void)
593 DISPPARAMS params;
594 VARIANT vars[10];
595 HRESULT hres;
597 if(!pSHPackDispParams)
598 win_skip("SHPackSidpParams not available\n");
600 memset(&params, 0xc0, sizeof(params));
601 memset(vars, 0xc0, sizeof(vars));
602 hres = pSHPackDispParams(&params, vars, 1, VT_I4, 0xdeadbeef);
603 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
604 ok(params.cArgs == 1, "params.cArgs = %d\n", params.cArgs);
605 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
606 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
607 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
608 ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars));
609 ok(V_I4(vars) == 0xdeadbeef, "failed %x\n", V_I4(vars));
611 memset(&params, 0xc0, sizeof(params));
612 hres = pSHPackDispParams(&params, NULL, 0, 0);
613 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
614 ok(params.cArgs == 0, "params.cArgs = %d\n", params.cArgs);
615 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
616 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
617 ok(params.rgvarg == NULL, "params.rgvarg = %p\n", params.rgvarg);
619 memset(vars, 0xc0, sizeof(vars));
620 memset(&params, 0xc0, sizeof(params));
621 hres = pSHPackDispParams(&params, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10,
622 VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef);
623 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
624 ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs);
625 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
626 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
627 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
628 ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars));
629 ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars));
630 ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1));
631 ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1));
632 ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2));
633 ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2));
634 ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3));
635 ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
638 typedef struct _disp
640 const IDispatchVtbl *vtbl;
641 LONG refCount;
642 } Disp;
644 typedef struct _contain
646 const IConnectionPointContainerVtbl *vtbl;
647 LONG refCount;
649 UINT ptCount;
650 IConnectionPoint **pt;
651 } Contain;
653 typedef struct _cntptn
655 const IConnectionPointVtbl *vtbl;
656 LONG refCount;
658 Contain *container;
659 GUID id;
660 UINT sinkCount;
661 IUnknown **sink;
662 } ConPt;
664 typedef struct _enum
666 const IEnumConnectionsVtbl *vtbl;
667 LONG refCount;
669 UINT idx;
670 ConPt *pt;
671 } EnumCon;
673 typedef struct _enumpt
675 const IEnumConnectionPointsVtbl *vtbl;
676 LONG refCount;
678 int idx;
679 Contain *container;
680 } EnumPt;
683 static HRESULT WINAPI Disp_QueryInterface(
684 IDispatch* This,
685 REFIID riid,
686 void **ppvObject)
688 *ppvObject = NULL;
690 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
692 *ppvObject = This;
695 if (*ppvObject)
697 IUnknown_AddRef(This);
698 return S_OK;
701 trace("no interface\n");
702 return E_NOINTERFACE;
705 static ULONG WINAPI Disp_AddRef(IDispatch* This)
707 Disp *iface = (Disp*)This;
708 return InterlockedIncrement(&iface->refCount);
711 static ULONG WINAPI Disp_Release(IDispatch* This)
713 Disp *iface = (Disp*)This;
714 ULONG ret;
716 ret = InterlockedDecrement(&iface->refCount);
717 if (ret == 0)
718 HeapFree(GetProcessHeap(),0,This);
719 return ret;
722 static HRESULT WINAPI Disp_GetTypeInfoCount(
723 IDispatch* This,
724 UINT *pctinfo)
726 return ERROR_SUCCESS;
729 static HRESULT WINAPI Disp_GetTypeInfo(
730 IDispatch* This,
731 UINT iTInfo,
732 LCID lcid,
733 ITypeInfo **ppTInfo)
735 return ERROR_SUCCESS;
738 static HRESULT WINAPI Disp_GetIDsOfNames(
739 IDispatch* This,
740 REFIID riid,
741 LPOLESTR *rgszNames,
742 UINT cNames,
743 LCID lcid,
744 DISPID *rgDispId)
746 return ERROR_SUCCESS;
749 static HRESULT WINAPI Disp_Invoke(
750 IDispatch* This,
751 DISPID dispIdMember,
752 REFIID riid,
753 LCID lcid,
754 WORD wFlags,
755 DISPPARAMS *pDispParams,
756 VARIANT *pVarResult,
757 EXCEPINFO *pExcepInfo,
758 UINT *puArgErr)
760 trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
762 ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
763 ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
764 ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
765 ok(lcid == 0,"Wrong lcid %x\n",lcid);
766 if (dispIdMember == 0xa0)
768 ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
769 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
770 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
771 ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
773 else if (dispIdMember == 0xa1)
775 ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
776 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
777 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
778 ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
779 ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
780 ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
781 ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
784 return ERROR_SUCCESS;
787 static const IDispatchVtbl disp_vtbl = {
788 Disp_QueryInterface,
789 Disp_AddRef,
790 Disp_Release,
792 Disp_GetTypeInfoCount,
793 Disp_GetTypeInfo,
794 Disp_GetIDsOfNames,
795 Disp_Invoke
798 static HRESULT WINAPI Enum_QueryInterface(
799 IEnumConnections* This,
800 REFIID riid,
801 void **ppvObject)
803 *ppvObject = NULL;
805 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
807 *ppvObject = This;
810 if (*ppvObject)
812 IUnknown_AddRef(This);
813 return S_OK;
816 trace("no interface\n");
817 return E_NOINTERFACE;
820 static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
822 EnumCon *iface = (EnumCon*)This;
823 return InterlockedIncrement(&iface->refCount);
826 static ULONG WINAPI Enum_Release(IEnumConnections* This)
828 EnumCon *iface = (EnumCon*)This;
829 ULONG ret;
831 ret = InterlockedDecrement(&iface->refCount);
832 if (ret == 0)
833 HeapFree(GetProcessHeap(),0,This);
834 return ret;
837 static HRESULT WINAPI Enum_Next(
838 IEnumConnections* This,
839 ULONG cConnections,
840 LPCONNECTDATA rgcd,
841 ULONG *pcFetched)
843 EnumCon *iface = (EnumCon*)This;
845 if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
847 rgcd->pUnk = iface->pt->sink[iface->idx];
848 IUnknown_AddRef(iface->pt->sink[iface->idx]);
849 rgcd->dwCookie=0xff;
850 if (pcFetched)
851 *pcFetched = 1;
852 iface->idx++;
853 return S_OK;
856 return E_FAIL;
859 static HRESULT WINAPI Enum_Skip(
860 IEnumConnections* This,
861 ULONG cConnections)
863 return E_FAIL;
866 static HRESULT WINAPI Enum_Reset(
867 IEnumConnections* This)
869 return E_FAIL;
872 static HRESULT WINAPI Enum_Clone(
873 IEnumConnections* This,
874 IEnumConnections **ppEnum)
876 return E_FAIL;
879 static const IEnumConnectionsVtbl enum_vtbl = {
881 Enum_QueryInterface,
882 Enum_AddRef,
883 Enum_Release,
884 Enum_Next,
885 Enum_Skip,
886 Enum_Reset,
887 Enum_Clone
890 static HRESULT WINAPI ConPt_QueryInterface(
891 IConnectionPoint* This,
892 REFIID riid,
893 void **ppvObject)
895 *ppvObject = NULL;
897 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
899 *ppvObject = This;
902 if (*ppvObject)
904 IUnknown_AddRef(This);
905 return S_OK;
908 trace("no interface\n");
909 return E_NOINTERFACE;
912 static ULONG WINAPI ConPt_AddRef(
913 IConnectionPoint* This)
915 ConPt *iface = (ConPt*)This;
916 return InterlockedIncrement(&iface->refCount);
919 static ULONG WINAPI ConPt_Release(
920 IConnectionPoint* This)
922 ConPt *iface = (ConPt*)This;
923 ULONG ret;
925 ret = InterlockedDecrement(&iface->refCount);
926 if (ret == 0)
928 if (iface->sinkCount > 0)
930 int i;
931 for (i = 0; i < iface->sinkCount; i++)
933 if (iface->sink[i])
934 IUnknown_Release(iface->sink[i]);
936 HeapFree(GetProcessHeap(),0,iface->sink);
938 HeapFree(GetProcessHeap(),0,This);
940 return ret;
943 static HRESULT WINAPI ConPt_GetConnectionInterface(
944 IConnectionPoint* This,
945 IID *pIID)
947 static int i = 0;
948 ConPt *iface = (ConPt*)This;
949 if (i==0)
951 i++;
952 return E_FAIL;
954 else
955 memcpy(pIID,&iface->id,sizeof(GUID));
956 return S_OK;
959 static HRESULT WINAPI ConPt_GetConnectionPointContainer(
960 IConnectionPoint* This,
961 IConnectionPointContainer **ppCPC)
963 ConPt *iface = (ConPt*)This;
965 *ppCPC = (IConnectionPointContainer*)iface->container;
966 return S_OK;
969 static HRESULT WINAPI ConPt_Advise(
970 IConnectionPoint* This,
971 IUnknown *pUnkSink,
972 DWORD *pdwCookie)
974 ConPt *iface = (ConPt*)This;
976 if (iface->sinkCount == 0)
977 iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
978 else
979 iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
980 iface->sink[iface->sinkCount] = pUnkSink;
981 IUnknown_AddRef(pUnkSink);
982 iface->sinkCount++;
983 *pdwCookie = iface->sinkCount;
984 return S_OK;
987 static HRESULT WINAPI ConPt_Unadvise(
988 IConnectionPoint* This,
989 DWORD dwCookie)
991 ConPt *iface = (ConPt*)This;
993 if (dwCookie > iface->sinkCount)
994 return E_FAIL;
995 else
997 IUnknown_Release(iface->sink[dwCookie-1]);
998 iface->sink[dwCookie-1] = NULL;
1000 return S_OK;
1003 static HRESULT WINAPI ConPt_EnumConnections(
1004 IConnectionPoint* This,
1005 IEnumConnections **ppEnum)
1007 EnumCon *ec;
1009 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
1010 ec->vtbl = &enum_vtbl;
1011 ec->refCount = 1;
1012 ec->pt = (ConPt*)This;
1013 ec->idx = 0;
1014 *ppEnum = (IEnumConnections*)ec;
1016 return S_OK;
1019 static const IConnectionPointVtbl point_vtbl = {
1020 ConPt_QueryInterface,
1021 ConPt_AddRef,
1022 ConPt_Release,
1024 ConPt_GetConnectionInterface,
1025 ConPt_GetConnectionPointContainer,
1026 ConPt_Advise,
1027 ConPt_Unadvise,
1028 ConPt_EnumConnections
1031 static HRESULT WINAPI EnumPt_QueryInterface(
1032 IEnumConnectionPoints* This,
1033 REFIID riid,
1034 void **ppvObject)
1036 *ppvObject = NULL;
1038 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
1040 *ppvObject = This;
1043 if (*ppvObject)
1045 IUnknown_AddRef(This);
1046 return S_OK;
1049 trace("no interface\n");
1050 return E_NOINTERFACE;
1053 static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
1055 EnumPt *iface = (EnumPt*)This;
1056 return InterlockedIncrement(&iface->refCount);
1059 static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
1061 EnumPt *iface = (EnumPt*)This;
1062 ULONG ret;
1064 ret = InterlockedDecrement(&iface->refCount);
1065 if (ret == 0)
1066 HeapFree(GetProcessHeap(),0,This);
1067 return ret;
1070 static HRESULT WINAPI EnumPt_Next(
1071 IEnumConnectionPoints* This,
1072 ULONG cConnections,
1073 IConnectionPoint **rgcd,
1074 ULONG *pcFetched)
1076 EnumPt *iface = (EnumPt*)This;
1078 if (cConnections > 0 && iface->idx < iface->container->ptCount)
1080 *rgcd = iface->container->pt[iface->idx];
1081 IUnknown_AddRef(iface->container->pt[iface->idx]);
1082 if (pcFetched)
1083 *pcFetched = 1;
1084 iface->idx++;
1085 return S_OK;
1088 return E_FAIL;
1091 static HRESULT WINAPI EnumPt_Skip(
1092 IEnumConnectionPoints* This,
1093 ULONG cConnections)
1095 return E_FAIL;
1098 static HRESULT WINAPI EnumPt_Reset(
1099 IEnumConnectionPoints* This)
1101 return E_FAIL;
1104 static HRESULT WINAPI EnumPt_Clone(
1105 IEnumConnectionPoints* This,
1106 IEnumConnectionPoints **ppEnumPt)
1108 return E_FAIL;
1111 static const IEnumConnectionPointsVtbl enumpt_vtbl = {
1113 EnumPt_QueryInterface,
1114 EnumPt_AddRef,
1115 EnumPt_Release,
1116 EnumPt_Next,
1117 EnumPt_Skip,
1118 EnumPt_Reset,
1119 EnumPt_Clone
1122 static HRESULT WINAPI Contain_QueryInterface(
1123 IConnectionPointContainer* This,
1124 REFIID riid,
1125 void **ppvObject)
1127 *ppvObject = NULL;
1129 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
1131 *ppvObject = This;
1134 if (*ppvObject)
1136 IUnknown_AddRef(This);
1137 return S_OK;
1140 trace("no interface\n");
1141 return E_NOINTERFACE;
1144 static ULONG WINAPI Contain_AddRef(
1145 IConnectionPointContainer* This)
1147 Contain *iface = (Contain*)This;
1148 return InterlockedIncrement(&iface->refCount);
1151 static ULONG WINAPI Contain_Release(
1152 IConnectionPointContainer* This)
1154 Contain *iface = (Contain*)This;
1155 ULONG ret;
1157 ret = InterlockedDecrement(&iface->refCount);
1158 if (ret == 0)
1160 if (iface->ptCount > 0)
1162 int i;
1163 for (i = 0; i < iface->ptCount; i++)
1164 IUnknown_Release(iface->pt[i]);
1165 HeapFree(GetProcessHeap(),0,iface->pt);
1167 HeapFree(GetProcessHeap(),0,This);
1169 return ret;
1172 static HRESULT WINAPI Contain_EnumConnectionPoints(
1173 IConnectionPointContainer* This,
1174 IEnumConnectionPoints **ppEnum)
1176 EnumPt *ec;
1178 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
1179 ec->vtbl = &enumpt_vtbl;
1180 ec->refCount = 1;
1181 ec->idx= 0;
1182 ec->container = (Contain*)This;
1183 *ppEnum = (IEnumConnectionPoints*)ec;
1185 return S_OK;
1188 static HRESULT WINAPI Contain_FindConnectionPoint(
1189 IConnectionPointContainer* This,
1190 REFIID riid,
1191 IConnectionPoint **ppCP)
1193 Contain *iface = (Contain*)This;
1194 ConPt *pt;
1196 if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
1198 pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
1199 pt->vtbl = &point_vtbl;
1200 pt->refCount = 1;
1201 pt->sinkCount = 0;
1202 pt->sink = NULL;
1203 pt->container = iface;
1204 pt->id = IID_IDispatch;
1206 if (iface->ptCount == 0)
1207 iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1208 else
1209 iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
1210 iface->pt[iface->ptCount] = (IConnectionPoint*)pt;
1211 iface->ptCount++;
1213 *ppCP = (IConnectionPoint*)pt;
1215 else
1217 *ppCP = iface->pt[0];
1218 IUnknown_AddRef((IUnknown*)*ppCP);
1221 return S_OK;
1224 static const IConnectionPointContainerVtbl contain_vtbl = {
1225 Contain_QueryInterface,
1226 Contain_AddRef,
1227 Contain_Release,
1229 Contain_EnumConnectionPoints,
1230 Contain_FindConnectionPoint
1233 static void test_IConnectionPoint(void)
1235 HRESULT rc;
1236 ULONG ref;
1237 IConnectionPoint *point;
1238 Contain *container;
1239 Disp *dispatch;
1240 DWORD cookie = 0xffffffff;
1241 DISPPARAMS params;
1242 VARIANT vars[10];
1244 if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
1246 win_skip("IConnectionPoint Apis not present\n");
1247 return;
1250 container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
1251 container->vtbl = &contain_vtbl;
1252 container->refCount = 1;
1253 container->ptCount = 0;
1254 container->pt = NULL;
1256 dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
1257 dispatch->vtbl = &disp_vtbl;
1258 dispatch->refCount = 1;
1260 rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
1261 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1262 ok(point != NULL, "returned ConnectionPoint is NULL\n");
1263 ok(cookie != 0xffffffff, "invalid cookie returned\n");
1265 rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
1266 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1268 if (pSHPackDispParams)
1270 memset(&params, 0xc0, sizeof(params));
1271 memset(vars, 0xc0, sizeof(vars));
1272 rc = pSHPackDispParams(&params, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
1273 ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
1275 rc = pIConnectionPoint_SimpleInvoke(point,0xa1,&params);
1276 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1278 else
1279 win_skip("pSHPackDispParams not present\n");
1281 rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
1282 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1284 /* MSDN says this should be required but it crashs on XP
1285 IUnknown_Release(point);
1287 ref = IUnknown_Release((IUnknown*)container);
1288 ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
1289 ref = IUnknown_Release((IUnknown*)dispatch);
1290 ok(ref == 0, "leftover IDispatch reference %i\n",ref);
1293 typedef struct _propbag
1295 const IPropertyBagVtbl *vtbl;
1296 LONG refCount;
1298 } PropBag;
1301 static HRESULT WINAPI Prop_QueryInterface(
1302 IPropertyBag* This,
1303 REFIID riid,
1304 void **ppvObject)
1306 *ppvObject = NULL;
1308 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPropertyBag))
1310 *ppvObject = This;
1313 if (*ppvObject)
1315 IUnknown_AddRef(This);
1316 return S_OK;
1319 trace("no interface\n");
1320 return E_NOINTERFACE;
1323 static ULONG WINAPI Prop_AddRef(
1324 IPropertyBag* This)
1326 PropBag *iface = (PropBag*)This;
1327 return InterlockedIncrement(&iface->refCount);
1330 static ULONG WINAPI Prop_Release(
1331 IPropertyBag* This)
1333 PropBag *iface = (PropBag*)This;
1334 ULONG ret;
1336 ret = InterlockedDecrement(&iface->refCount);
1337 if (ret == 0)
1338 HeapFree(GetProcessHeap(),0,This);
1339 return ret;
1342 static HRESULT WINAPI Prop_Read(
1343 IPropertyBag* This,
1344 LPCOLESTR pszPropName,
1345 VARIANT *pVar,
1346 IErrorLog *pErrorLog)
1348 V_VT(pVar) = VT_BLOB|VT_BYREF;
1349 V_BYREF(pVar) = (LPVOID)0xdeadcafe;
1350 return S_OK;
1353 static HRESULT WINAPI Prop_Write(
1354 IPropertyBag* This,
1355 LPCOLESTR pszPropName,
1356 VARIANT *pVar)
1358 return S_OK;
1362 static const IPropertyBagVtbl prop_vtbl = {
1363 Prop_QueryInterface,
1364 Prop_AddRef,
1365 Prop_Release,
1367 Prop_Read,
1368 Prop_Write
1371 static void test_SHPropertyBag_ReadLONG(void)
1373 PropBag *pb;
1374 HRESULT rc;
1375 LONG out;
1376 static const WCHAR szName1[] = {'n','a','m','e','1',0};
1378 if (!pSHPropertyBag_ReadLONG)
1380 win_skip("SHPropertyBag_ReadLONG not present\n");
1381 return;
1384 pb = HeapAlloc(GetProcessHeap(),0,sizeof(PropBag));
1385 pb->refCount = 1;
1386 pb->vtbl = &prop_vtbl;
1388 out = 0xfeedface;
1389 rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out);
1390 ok(rc == E_INVALIDARG || broken(rc == 0), "incorrect return %x\n",rc);
1391 ok(out == 0xfeedface, "value should not have changed\n");
1392 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, NULL, &out);
1393 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1394 ok(out == 0xfeedface, "value should not have changed\n");
1395 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, NULL);
1396 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1397 ok(out == 0xfeedface, "value should not have changed\n");
1398 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, &out);
1399 ok(rc == DISP_E_BADVARTYPE || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1400 ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %x\n",out);
1401 IUnknown_Release((IUnknown*)pb);
1406 static void test_SHSetWindowBits(void)
1408 HWND hwnd;
1409 DWORD style, styleold;
1410 WNDCLASSA clsA;
1412 if(!pSHSetWindowBits)
1414 win_skip("SHSetWindowBits is not available\n");
1415 return;
1418 clsA.style = 0;
1419 clsA.lpfnWndProc = DefWindowProcA;
1420 clsA.cbClsExtra = 0;
1421 clsA.cbWndExtra = 0;
1422 clsA.hInstance = GetModuleHandleA(NULL);
1423 clsA.hIcon = 0;
1424 clsA.hCursor = LoadCursorA(0, IDC_ARROW);
1425 clsA.hbrBackground = NULL;
1426 clsA.lpszMenuName = NULL;
1427 clsA.lpszClassName = "Shlwapi test class";
1428 RegisterClassA(&clsA);
1430 hwnd = CreateWindowA("Shlwapi test class", "Test", WS_VISIBLE, 0, 0, 100, 100,
1431 NULL, NULL, GetModuleHandle(NULL), 0);
1432 ok(IsWindow(hwnd), "failed to create window\n");
1434 /* null window */
1435 SetLastError(0xdeadbeef);
1436 style = pSHSetWindowBits(NULL, GWL_STYLE, 0, 0);
1437 ok(style == 0, "expected 0 retval, got %d\n", style);
1438 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE ||
1439 broken(GetLastError() == 0xdeadbeef), /* Win9x/WinMe */
1440 "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
1442 /* zero mask, zero flags */
1443 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1444 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, 0);
1445 ok(styleold == style, "expected old style\n");
1446 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1448 /* test mask */
1449 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1450 ok(styleold & WS_VISIBLE, "expected WS_VISIBLE\n");
1451 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1453 ok(style == styleold, "expected previous style, got %x\n", style);
1454 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1456 /* test mask, unset style bit used */
1457 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1458 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1459 ok(style == styleold, "expected previous style, got %x\n", style);
1460 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1462 /* set back with flags */
1463 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1464 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, WS_VISIBLE);
1465 ok(style == styleold, "expected previous style, got %x\n", style);
1466 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "expected updated style\n");
1468 /* reset and try to set without a mask */
1469 pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1470 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1471 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1472 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, WS_VISIBLE);
1473 ok(style == styleold, "expected previous style, got %x\n", style);
1474 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1476 DestroyWindow(hwnd);
1478 UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL));
1481 static void test_SHFormatDateTimeA(void)
1483 FILETIME UNALIGNED filetime;
1484 CHAR buff[100], buff2[100], buff3[100];
1485 SYSTEMTIME st;
1486 DWORD flags;
1487 INT ret;
1489 if(!pSHFormatDateTimeA)
1491 win_skip("pSHFormatDateTimeA isn't available\n");
1492 return;
1495 if (0)
1497 /* crashes on native */
1498 ret = pSHFormatDateTimeA(NULL, NULL, NULL, 0);
1501 GetLocalTime(&st);
1502 SystemTimeToFileTime(&st, &filetime);
1503 /* SHFormatDateTime expects input as utc */
1504 LocalFileTimeToFileTime(&filetime, &filetime);
1506 /* no way to get required buffer length here */
1507 SetLastError(0xdeadbeef);
1508 ret = pSHFormatDateTimeA(&filetime, NULL, NULL, 0);
1509 ok(ret == 0, "got %d\n", ret);
1510 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1512 SetLastError(0xdeadbeef);
1513 buff[0] = 'a'; buff[1] = 0;
1514 ret = pSHFormatDateTimeA(&filetime, NULL, buff, 0);
1515 ok(ret == 0, "got %d\n", ret);
1516 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1517 ok(buff[0] == 'a', "expected same string, got %s\n", buff);
1519 /* all combinations documented as invalid succeeded */
1520 flags = FDTF_SHORTTIME | FDTF_LONGTIME;
1521 SetLastError(0xdeadbeef);
1522 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1523 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1524 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1526 flags = FDTF_SHORTDATE | FDTF_LONGDATE;
1527 SetLastError(0xdeadbeef);
1528 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1529 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1530 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1532 flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
1533 SetLastError(0xdeadbeef);
1534 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1535 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1536 ok(GetLastError() == 0xdeadbeef ||
1537 broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe */
1538 "expected 0xdeadbeef, got %d\n", GetLastError());
1540 /* now check returned strings */
1541 flags = FDTF_SHORTTIME;
1542 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1543 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1544 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2));
1545 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1546 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1548 flags = FDTF_LONGTIME;
1549 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1550 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1551 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1552 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1553 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1555 /* both time flags */
1556 flags = FDTF_LONGTIME | FDTF_SHORTTIME;
1557 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1558 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1559 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1560 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1561 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1563 flags = FDTF_SHORTDATE;
1564 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1565 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1566 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1567 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1568 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1570 flags = FDTF_LONGDATE;
1571 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1572 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1573 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1574 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1575 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1577 /* both date flags */
1578 flags = FDTF_LONGDATE | FDTF_SHORTDATE;
1579 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1580 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1581 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1582 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1583 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1585 /* various combinations of date/time flags */
1586 flags = FDTF_LONGDATE | FDTF_SHORTTIME;
1587 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1588 ok(ret == lstrlenA(buff)+1, "got %d, length %d\n", ret, lstrlenA(buff)+1);
1589 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1590 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1591 strcat(buff2, ", ");
1592 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1593 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1594 strcat(buff2, buff3);
1595 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1597 flags = FDTF_LONGDATE | FDTF_LONGTIME;
1598 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1599 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1600 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1601 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1602 strcat(buff2, ", ");
1603 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1604 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1605 strcat(buff2, buff3);
1606 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1608 flags = FDTF_SHORTDATE | FDTF_SHORTTIME;
1609 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1610 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1611 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1612 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1613 strcat(buff2, " ");
1614 ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1615 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1616 strcat(buff2, buff3);
1617 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1619 flags = FDTF_SHORTDATE | FDTF_LONGTIME;
1620 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1621 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1622 ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1623 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1624 strcat(buff2, " ");
1625 ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1626 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1627 strcat(buff2, buff3);
1628 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1631 static void test_SHFormatDateTimeW(void)
1633 FILETIME UNALIGNED filetime;
1634 WCHAR buff[100], buff2[100], buff3[100];
1635 SYSTEMTIME st;
1636 DWORD flags;
1637 INT ret;
1638 static const WCHAR spaceW[] = {' ',0};
1639 static const WCHAR commaW[] = {',',' ',0};
1641 if(!pSHFormatDateTimeW)
1643 win_skip("pSHFormatDateTimeW isn't available\n");
1644 return;
1647 if (0)
1649 /* crashes on native */
1650 ret = pSHFormatDateTimeW(NULL, NULL, NULL, 0);
1653 GetLocalTime(&st);
1654 SystemTimeToFileTime(&st, &filetime);
1655 /* SHFormatDateTime expects input as utc */
1656 LocalFileTimeToFileTime(&filetime, &filetime);
1658 /* no way to get required buffer length here */
1659 SetLastError(0xdeadbeef);
1660 ret = pSHFormatDateTimeW(&filetime, NULL, NULL, 0);
1661 ok(ret == 0, "got %d\n", ret);
1662 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1664 SetLastError(0xdeadbeef);
1665 buff[0] = 'a'; buff[1] = 0;
1666 ret = pSHFormatDateTimeW(&filetime, NULL, buff, 0);
1667 ok(ret == 0, "got %d\n", ret);
1668 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1669 ok(buff[0] == 'a', "expected same string\n");
1671 /* all combinations documented as invalid succeeded */
1672 flags = FDTF_SHORTTIME | FDTF_LONGTIME;
1673 SetLastError(0xdeadbeef);
1674 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1675 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1676 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1678 flags = FDTF_SHORTDATE | FDTF_LONGDATE;
1679 SetLastError(0xdeadbeef);
1680 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1681 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1682 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1684 flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
1685 SetLastError(0xdeadbeef);
1686 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1687 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1688 ok(GetLastError() == 0xdeadbeef ||
1689 broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe */
1690 "expected 0xdeadbeef, got %d\n", GetLastError());
1692 /* now check returned strings */
1693 flags = FDTF_SHORTTIME;
1694 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1695 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1696 SetLastError(0xdeadbeef);
1697 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1698 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1700 win_skip("Needed W-functions are not implemented\n");
1701 return;
1703 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1704 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1706 flags = FDTF_LONGTIME;
1707 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1708 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1709 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1710 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1711 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1713 /* both time flags */
1714 flags = FDTF_LONGTIME | FDTF_SHORTTIME;
1715 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1716 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1717 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1718 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1719 ok(lstrcmpW(buff, buff2) == 0, "expected equal string\n");
1721 flags = FDTF_SHORTDATE;
1722 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1723 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1724 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1725 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1726 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1728 flags = FDTF_LONGDATE;
1729 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1730 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1731 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1732 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1733 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1735 /* both date flags */
1736 flags = FDTF_LONGDATE | FDTF_SHORTDATE;
1737 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1738 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1739 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1740 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1741 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1743 /* various combinations of date/time flags */
1744 flags = FDTF_LONGDATE | FDTF_SHORTTIME;
1745 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1746 ok(ret == lstrlenW(buff)+1, "got %d, length %d\n", ret, lstrlenW(buff)+1);
1747 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1748 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1749 lstrcatW(buff2, commaW);
1750 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1751 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1752 lstrcatW(buff2, buff3);
1753 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1755 flags = FDTF_LONGDATE | FDTF_LONGTIME;
1756 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1757 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1758 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1759 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1760 lstrcatW(buff2, commaW);
1761 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1762 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1763 lstrcatW(buff2, buff3);
1764 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1766 flags = FDTF_SHORTDATE | FDTF_SHORTTIME;
1767 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1768 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1769 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1770 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1771 lstrcatW(buff2, spaceW);
1772 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1773 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1774 lstrcatW(buff2, buff3);
1775 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1777 flags = FDTF_SHORTDATE | FDTF_LONGTIME;
1778 ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
1779 ok(ret == lstrlenW(buff)+1, "got %d\n", ret);
1780 ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
1781 ok(ret == lstrlenW(buff2)+1, "got %d\n", ret);
1782 lstrcatW(buff2, spaceW);
1783 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
1784 ok(ret == lstrlenW(buff3)+1, "got %d\n", ret);
1785 lstrcatW(buff2, buff3);
1786 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1789 static void init_pointers(void)
1791 #define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord)))
1792 MAKEFUNC(SHAllocShared, 7);
1793 MAKEFUNC(SHLockShared, 8);
1794 MAKEFUNC(SHUnlockShared, 9);
1795 MAKEFUNC(SHFreeShared, 10);
1796 MAKEFUNC(GetAcceptLanguagesA, 14);
1797 MAKEFUNC(SHSetWindowBits, 165);
1798 MAKEFUNC(ConnectToConnectionPoint, 168);
1799 MAKEFUNC(SHSearchMapInt, 198);
1800 MAKEFUNC(SHPackDispParams, 282);
1801 MAKEFUNC(IConnectionPoint_InvokeWithCancel, 283);
1802 MAKEFUNC(IConnectionPoint_SimpleInvoke, 284);
1803 MAKEFUNC(SHFormatDateTimeA, 353);
1804 MAKEFUNC(SHFormatDateTimeW, 354);
1805 MAKEFUNC(SHPropertyBag_ReadLONG, 496);
1806 #undef MAKEFUNC
1809 START_TEST(ordinal)
1811 hShlwapi = GetModuleHandleA("shlwapi.dll");
1813 init_pointers();
1815 hmlang = LoadLibraryA("mlang.dll");
1816 pLcidToRfc1766A = (void *)GetProcAddress(hmlang, "LcidToRfc1766A");
1818 test_GetAcceptLanguagesA();
1819 test_SHSearchMapInt();
1820 test_alloc_shared();
1821 test_fdsa();
1822 test_GetShellSecurityDescriptor();
1823 test_SHPackDispParams();
1824 test_IConnectionPoint();
1825 test_SHPropertyBag_ReadLONG();
1826 test_SHSetWindowBits();
1827 test_SHFormatDateTimeA();
1828 test_SHFormatDateTimeW();