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"
31 /* Function ptrs for ordinal calls */
32 static HMODULE hShlwapi;
33 static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
34 static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
36 static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
37 static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
38 static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
39 static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
40 static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
41 static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*);
42 static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD);
43 static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
44 static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG);
46 static void test_GetAcceptLanguagesA(void)
48 DWORD buffersize, buffersize2, exactsize;
51 if (!pGetAcceptLanguagesA) {
52 win_skip("GetAcceptLanguagesA is not available\n");
56 buffersize = sizeof(buffer);
57 memset(buffer, 0, sizeof(buffer));
58 SetLastError(ERROR_SUCCESS);
59 retval = pGetAcceptLanguagesA( buffer, &buffersize);
60 if (!retval && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
61 win_skip("GetAcceptLanguagesA is not implemented\n");
64 trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
65 " last error %u\n", retval, buffersize, buffer, GetLastError());
67 trace("GetAcceptLanguagesA: skipping tests\n");
70 ok( (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()) ||
71 (ERROR_CLASS_DOES_NOT_EXIST == GetLastError()) ||
72 (ERROR_PROC_NOT_FOUND == GetLastError()) ||
73 (ERROR_SUCCESS == GetLastError()), "last error set to %u\n", GetLastError());
74 exactsize = strlen(buffer);
76 SetLastError(ERROR_SUCCESS);
77 retval = pGetAcceptLanguagesA( NULL, NULL);
78 ok(retval == E_FAIL ||
79 retval == E_INVALIDARG, /* w2k8 */
80 "function result wrong: got %08x; expected E_FAIL\n", retval);
81 ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
83 buffersize = sizeof(buffer);
84 SetLastError(ERROR_SUCCESS);
85 retval = pGetAcceptLanguagesA( NULL, &buffersize);
86 ok(retval == E_FAIL ||
87 retval == E_INVALIDARG, /* w2k8 */
88 "function result wrong: got %08x; expected E_FAIL\n", retval);
89 ok(buffersize == sizeof(buffer) ||
90 buffersize == 0, /* w2k8*/
91 "buffersize was changed and is not 0; size (%d))\n", buffersize);
92 ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
94 SetLastError(ERROR_SUCCESS);
95 retval = pGetAcceptLanguagesA( buffer, NULL);
96 ok(retval == E_FAIL ||
97 retval == E_INVALIDARG, /* w2k8 */
98 "function result wrong: got %08x; expected E_FAIL\n", retval);
99 ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
102 memset(buffer, 0, sizeof(buffer));
103 SetLastError(ERROR_SUCCESS);
104 retval = pGetAcceptLanguagesA( buffer, &buffersize);
105 ok(retval == E_FAIL ||
106 retval == E_INVALIDARG, /* w2k8 */
107 "function result wrong: got %08x; expected E_FAIL\n", retval);
109 "buffersize wrong(changed) got %08x; expected 0 (2nd parameter; not on Win2k)\n", buffersize);
110 ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
112 buffersize = buffersize2 = 1;
113 memset(buffer, 0, sizeof(buffer));
114 SetLastError(ERROR_SUCCESS);
115 retval = pGetAcceptLanguagesA( buffer, &buffersize);
118 if(buffersize == exactsize) {
119 ok( (ERROR_SUCCESS == GetLastError()) ||
120 (ERROR_PROC_NOT_FOUND == GetLastError()) || (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()),
121 "last error wrong: got %u; expected ERROR_SUCCESS(NT4)/"
122 "ERROR_PROC_NOT_FOUND(NT4)/ERROR_NO_IMPERSONATION_TOKEN(XP)\n", GetLastError());
123 ok(exactsize == strlen(buffer),
124 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), exactsize);
125 } else if((buffersize +1) == buffersize2) {
126 ok(ERROR_SUCCESS == GetLastError(),
127 "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
128 ok(buffersize == strlen(buffer),
129 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
131 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
132 retval, buffersize, buffer, GetLastError());
136 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
137 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
138 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
139 ok(buffersize2 == strlen(buffer),
140 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
142 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win7 */
144 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
145 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
146 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
149 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
150 retval, buffersize, buffer, GetLastError());
154 buffersize = buffersize2 = exactsize;
155 memset(buffer, 0, sizeof(buffer));
156 SetLastError(ERROR_SUCCESS);
157 retval = pGetAcceptLanguagesA( buffer, &buffersize);
160 ok(ERROR_SUCCESS == GetLastError(),
161 "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
162 if((buffersize == exactsize) /* XP */ ||
163 ((buffersize +1)== exactsize) /* 98 */)
164 ok(buffersize == strlen(buffer),
165 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
167 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
168 retval, buffersize, buffer, GetLastError());
172 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
173 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
174 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
175 ok(buffersize2 == strlen(buffer),
176 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
178 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win 7 */
180 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
181 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
182 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
185 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
186 retval, buffersize, buffer, GetLastError());
191 static void test_SHSearchMapInt(void)
193 int keys[8], values[8];
196 if (!pSHSearchMapInt)
199 memset(keys, 0, sizeof(keys));
200 memset(values, 0, sizeof(values));
201 keys[0] = 99; values[0] = 101;
203 /* NULL key/value lists crash native, so skip testing them */
206 i = pSHSearchMapInt(keys, values, 1, keys[0]);
207 ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
209 /* Key doesn't exist */
210 i = pSHSearchMapInt(keys, values, 1, 100);
211 ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);
213 /* Len = 0 => not found */
214 i = pSHSearchMapInt(keys, values, 0, keys[0]);
215 ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);
217 /* 2 elements, len = 1 */
218 keys[1] = 98; values[1] = 102;
219 i = pSHSearchMapInt(keys, values, 1, keys[1]);
220 ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);
222 /* 2 elements, len = 2 */
223 i = pSHSearchMapInt(keys, values, 2, keys[1]);
224 ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);
226 /* Searches forward */
227 keys[2] = 99; values[2] = 103;
228 i = pSHSearchMapInt(keys, values, 3, keys[0]);
229 ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
232 static void test_alloc_shared(void)
240 procid=GetCurrentProcessId();
241 hmem=pSHAllocShared(NULL,10,procid);
242 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
243 ret = pSHFreeShared(hmem, procid);
244 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
247 hmem=pSHAllocShared(&val,4,procid);
248 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
250 p=pSHLockShared(hmem,procid);
251 ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
253 ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
254 ret = pSHUnlockShared(p);
255 ok( ret, "SHUnlockShared failed: %u\n", GetLastError());
257 ret = pSHFreeShared(hmem, procid);
258 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
261 static void test_fdsa(void)
265 DWORD num_items; /* Number of elements inserted */
266 void *mem; /* Ptr to array */
267 DWORD blocks_alloced; /* Number of elements allocated */
268 BYTE inc; /* Number of elements to grow by when we need to expand */
269 BYTE block_size; /* Size in bytes of an element */
270 BYTE flags; /* Flags */
273 BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
275 BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
276 DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
277 BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);
280 int block_size = 10, init_blocks = 4, inc = 2;
284 pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
285 pFDSA_Destroy = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
286 pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
287 pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);
289 mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
290 memset(&info, 0, sizeof(info));
292 ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
293 ok(info.num_items == 0, "num_items = %d\n", info.num_items);
294 ok(info.mem == mem, "mem = %p\n", info.mem);
295 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
296 ok(info.inc == inc, "inc = %d\n", info.inc);
297 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
298 ok(info.flags == 0, "flags = %d\n", info.flags);
300 ret = pFDSA_InsertItem(&info, 1234, "1234567890");
301 ok(ret == 0, "ret = %d\n", ret);
302 ok(info.num_items == 1, "num_items = %d\n", info.num_items);
303 ok(info.mem == mem, "mem = %p\n", info.mem);
304 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
305 ok(info.inc == inc, "inc = %d\n", info.inc);
306 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
307 ok(info.flags == 0, "flags = %d\n", info.flags);
309 ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
310 ok(ret == 1, "ret = %d\n", ret);
312 ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
313 ok(ret == 1, "ret = %d\n", ret);
315 ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
316 ok(ret == 0, "ret = %d\n", ret);
317 ok(info.mem == mem, "mem = %p\n", info.mem);
318 ok(info.flags == 0, "flags = %d\n", info.flags);
320 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
321 ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
322 ok(ret == 0, "ret = %d\n", ret);
323 ok(info.mem != mem, "mem = %p\n", info.mem);
324 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
325 ok(info.flags == 0x1, "flags = %d\n", info.flags);
327 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
329 ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
330 ok(info.mem != mem, "mem = %p\n", info.mem);
331 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
332 ok(info.flags == 0x1, "flags = %d\n", info.flags);
334 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
336 ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
337 ok(info.mem != mem, "mem = %p\n", info.mem);
338 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
339 ok(info.flags == 0x1, "flags = %d\n", info.flags);
341 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
343 ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
345 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
346 ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
349 /* When Initialize is called with inc = 0, set it to 1 */
350 ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
351 ok(info.inc == 1, "inc = %d\n", info.inc);
353 /* This time, because shlwapi hasn't had to allocate memory
354 internally, Destroy rets non-zero */
355 ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");
358 HeapFree(GetProcessHeap(), 0, mem);
362 typedef struct SHELL_USER_SID {
363 SID_IDENTIFIER_AUTHORITY sidAuthority;
366 } SHELL_USER_SID, *PSHELL_USER_SID;
367 typedef struct SHELL_USER_PERMISSION {
368 SHELL_USER_SID susID;
373 DWORD dwInheritAccessMask;
374 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
375 static void test_GetShellSecurityDescriptor(void)
377 SHELL_USER_PERMISSION supCurrentUserFull = {
378 { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
379 ACCESS_ALLOWED_ACE_TYPE, FALSE,
381 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
382 SHELL_USER_PERMISSION supEveryoneDenied = {
383 { {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 },
384 ACCESS_DENIED_ACE_TYPE, TRUE,
385 GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ };
386 PSHELL_USER_PERMISSION rgsup[2] = {
387 &supCurrentUserFull, &supEveryoneDenied,
389 SECURITY_DESCRIPTOR* psd;
390 SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
392 pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);
394 if(!pGetShellSecurityDescriptor)
396 win_skip("GetShellSecurityDescriptor not available\n");
400 psd = pGetShellSecurityDescriptor(NULL, 2);
402 broken(psd==INVALID_HANDLE_VALUE), /* IE5 */
403 "GetShellSecurityDescriptor should fail\n");
404 psd = pGetShellSecurityDescriptor(rgsup, 0);
405 ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
407 SetLastError(0xdeadbeef);
408 psd = pGetShellSecurityDescriptor(rgsup, 2);
409 if (psd == NULL && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
411 /* The previous calls to GetShellSecurityDescriptor don't set the last error */
412 win_skip("GetShellSecurityDescriptor is not implemented\n");
415 if (psd==INVALID_HANDLE_VALUE)
417 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
420 ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
423 BOOL bHasDacl = FALSE, bDefaulted;
426 SECURITY_DESCRIPTOR_CONTROL control;
428 ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
430 ok(GetSecurityDescriptorControl(psd, &control, &dwRev),
431 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
432 ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");
434 ok(GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted),
435 "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
437 ok(bHasDacl, "SD has no DACL\n");
440 ok(!bDefaulted, "DACL should not be defaulted\n");
442 ok(pAcl != NULL, "NULL DACL!\n");
445 ACL_SIZE_INFORMATION asiSize;
447 ok(IsValidAcl(pAcl), "DACL is not valid\n");
449 ok(GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation),
450 "GetAclInformation failed with error %u\n", GetLastError());
452 ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
453 if (asiSize.AceCount == 3)
455 ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
457 ok(GetAce(pAcl, 0, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
458 ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
459 "Invalid ACE type %d\n", paaa->Header.AceType);
460 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
461 ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);
463 ok(GetAce(pAcl, 1, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
464 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
465 "Invalid ACE type %d\n", paaa->Header.AceType);
466 /* first one of two ACEs generated from inheritable entry - without inheritance */
467 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
468 ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);
470 ok(GetAce(pAcl, 2, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
471 ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
472 "Invalid ACE type %d\n", paaa->Header.AceType);
473 /* second ACE - with inheritance */
474 ok(paaa->Header.AceFlags == MY_INHERITANCE,
475 "Invalid ACE flags %x\n", paaa->Header.AceFlags);
476 ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
485 static void test_SHPackDispParams(void)
491 if(!pSHPackDispParams)
492 win_skip("SHPackSidpParams not available\n");
494 memset(¶ms, 0xc0, sizeof(params));
495 memset(vars, 0xc0, sizeof(vars));
496 hres = pSHPackDispParams(¶ms, vars, 1, VT_I4, 0xdeadbeef);
497 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
498 ok(params.cArgs == 1, "params.cArgs = %d\n", params.cArgs);
499 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
500 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
501 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
502 ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars));
503 ok(V_I4(vars) == 0xdeadbeef, "failed %x\n", V_I4(vars));
505 memset(¶ms, 0xc0, sizeof(params));
506 hres = pSHPackDispParams(¶ms, NULL, 0, 0);
507 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
508 ok(params.cArgs == 0, "params.cArgs = %d\n", params.cArgs);
509 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
510 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
511 ok(params.rgvarg == NULL, "params.rgvarg = %p\n", params.rgvarg);
513 memset(vars, 0xc0, sizeof(vars));
514 memset(¶ms, 0xc0, sizeof(params));
515 hres = pSHPackDispParams(¶ms, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10,
516 VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef);
517 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
518 ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs);
519 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
520 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
521 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
522 ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars));
523 ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars));
524 ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1));
525 ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1));
526 ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2));
527 ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2));
528 ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3));
529 ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
534 const IDispatchVtbl *vtbl;
538 typedef struct _contain
540 const IConnectionPointContainerVtbl *vtbl;
544 IConnectionPoint **pt;
547 typedef struct _cntptn
549 const IConnectionPointVtbl *vtbl;
560 const IEnumConnectionsVtbl *vtbl;
567 typedef struct _enumpt
569 const IEnumConnectionPointsVtbl *vtbl;
577 static HRESULT WINAPI Disp_QueryInterface(
584 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
591 IUnknown_AddRef(This);
595 trace("no interface\n");
596 return E_NOINTERFACE;
599 static ULONG WINAPI Disp_AddRef(IDispatch* This)
601 Disp *iface = (Disp*)This;
602 return InterlockedIncrement(&iface->refCount);
605 static ULONG WINAPI Disp_Release(IDispatch* This)
607 Disp *iface = (Disp*)This;
610 ret = InterlockedDecrement(&iface->refCount);
612 HeapFree(GetProcessHeap(),0,This);
616 static HRESULT WINAPI Disp_GetTypeInfoCount(
620 return ERROR_SUCCESS;
623 static HRESULT WINAPI Disp_GetTypeInfo(
629 return ERROR_SUCCESS;
632 static HRESULT WINAPI Disp_GetIDsOfNames(
640 return ERROR_SUCCESS;
643 static HRESULT WINAPI Disp_Invoke(
649 DISPPARAMS *pDispParams,
651 EXCEPINFO *pExcepInfo,
654 trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
656 ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
657 ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
658 ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
659 ok(lcid == 0,"Wrong lcid %x\n",lcid);
660 if (dispIdMember == 0xa0)
662 ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
663 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
664 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
665 ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
667 else if (dispIdMember == 0xa1)
669 ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
670 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
671 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
672 ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
673 ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
674 ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
675 ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
678 return ERROR_SUCCESS;
681 static const IDispatchVtbl disp_vtbl = {
686 Disp_GetTypeInfoCount,
692 static HRESULT WINAPI Enum_QueryInterface(
693 IEnumConnections* This,
699 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
706 IUnknown_AddRef(This);
710 trace("no interface\n");
711 return E_NOINTERFACE;
714 static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
716 EnumCon *iface = (EnumCon*)This;
717 return InterlockedIncrement(&iface->refCount);
720 static ULONG WINAPI Enum_Release(IEnumConnections* This)
722 EnumCon *iface = (EnumCon*)This;
725 ret = InterlockedDecrement(&iface->refCount);
727 HeapFree(GetProcessHeap(),0,This);
731 static HRESULT WINAPI Enum_Next(
732 IEnumConnections* This,
737 EnumCon *iface = (EnumCon*)This;
739 if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
741 rgcd->pUnk = iface->pt->sink[iface->idx];
742 IUnknown_AddRef(iface->pt->sink[iface->idx]);
753 static HRESULT WINAPI Enum_Skip(
754 IEnumConnections* This,
760 static HRESULT WINAPI Enum_Reset(
761 IEnumConnections* This)
766 static HRESULT WINAPI Enum_Clone(
767 IEnumConnections* This,
768 IEnumConnections **ppEnum)
773 static const IEnumConnectionsVtbl enum_vtbl = {
784 static HRESULT WINAPI ConPt_QueryInterface(
785 IConnectionPoint* This,
791 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
798 IUnknown_AddRef(This);
802 trace("no interface\n");
803 return E_NOINTERFACE;
806 static ULONG WINAPI ConPt_AddRef(
807 IConnectionPoint* This)
809 ConPt *iface = (ConPt*)This;
810 return InterlockedIncrement(&iface->refCount);
813 static ULONG WINAPI ConPt_Release(
814 IConnectionPoint* This)
816 ConPt *iface = (ConPt*)This;
819 ret = InterlockedDecrement(&iface->refCount);
822 if (iface->sinkCount > 0)
825 for (i = 0; i < iface->sinkCount; i++)
828 IUnknown_Release(iface->sink[i]);
830 HeapFree(GetProcessHeap(),0,iface->sink);
832 HeapFree(GetProcessHeap(),0,This);
837 static HRESULT WINAPI ConPt_GetConnectionInterface(
838 IConnectionPoint* This,
842 ConPt *iface = (ConPt*)This;
849 memcpy(pIID,&iface->id,sizeof(GUID));
853 static HRESULT WINAPI ConPt_GetConnectionPointContainer(
854 IConnectionPoint* This,
855 IConnectionPointContainer **ppCPC)
857 ConPt *iface = (ConPt*)This;
859 *ppCPC = (IConnectionPointContainer*)iface->container;
863 static HRESULT WINAPI ConPt_Advise(
864 IConnectionPoint* This,
868 ConPt *iface = (ConPt*)This;
870 if (iface->sinkCount == 0)
871 iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
873 iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
874 iface->sink[iface->sinkCount] = pUnkSink;
875 IUnknown_AddRef(pUnkSink);
877 *pdwCookie = iface->sinkCount;
881 static HRESULT WINAPI ConPt_Unadvise(
882 IConnectionPoint* This,
885 ConPt *iface = (ConPt*)This;
887 if (dwCookie > iface->sinkCount)
891 IUnknown_Release(iface->sink[dwCookie-1]);
892 iface->sink[dwCookie-1] = NULL;
897 static HRESULT WINAPI ConPt_EnumConnections(
898 IConnectionPoint* This,
899 IEnumConnections **ppEnum)
903 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
904 ec->vtbl = &enum_vtbl;
906 ec->pt = (ConPt*)This;
908 *ppEnum = (IEnumConnections*)ec;
913 static const IConnectionPointVtbl point_vtbl = {
914 ConPt_QueryInterface,
918 ConPt_GetConnectionInterface,
919 ConPt_GetConnectionPointContainer,
922 ConPt_EnumConnections
925 static HRESULT WINAPI EnumPt_QueryInterface(
926 IEnumConnectionPoints* This,
932 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
939 IUnknown_AddRef(This);
943 trace("no interface\n");
944 return E_NOINTERFACE;
947 static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
949 EnumPt *iface = (EnumPt*)This;
950 return InterlockedIncrement(&iface->refCount);
953 static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
955 EnumPt *iface = (EnumPt*)This;
958 ret = InterlockedDecrement(&iface->refCount);
960 HeapFree(GetProcessHeap(),0,This);
964 static HRESULT WINAPI EnumPt_Next(
965 IEnumConnectionPoints* This,
967 IConnectionPoint **rgcd,
970 EnumPt *iface = (EnumPt*)This;
972 if (cConnections > 0 && iface->idx < iface->container->ptCount)
974 *rgcd = iface->container->pt[iface->idx];
975 IUnknown_AddRef(iface->container->pt[iface->idx]);
985 static HRESULT WINAPI EnumPt_Skip(
986 IEnumConnectionPoints* This,
992 static HRESULT WINAPI EnumPt_Reset(
993 IEnumConnectionPoints* This)
998 static HRESULT WINAPI EnumPt_Clone(
999 IEnumConnectionPoints* This,
1000 IEnumConnectionPoints **ppEnumPt)
1005 static const IEnumConnectionPointsVtbl enumpt_vtbl = {
1007 EnumPt_QueryInterface,
1016 static HRESULT WINAPI Contain_QueryInterface(
1017 IConnectionPointContainer* This,
1023 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
1030 IUnknown_AddRef(This);
1034 trace("no interface\n");
1035 return E_NOINTERFACE;
1038 static ULONG WINAPI Contain_AddRef(
1039 IConnectionPointContainer* This)
1041 Contain *iface = (Contain*)This;
1042 return InterlockedIncrement(&iface->refCount);
1045 static ULONG WINAPI Contain_Release(
1046 IConnectionPointContainer* This)
1048 Contain *iface = (Contain*)This;
1051 ret = InterlockedDecrement(&iface->refCount);
1054 if (iface->ptCount > 0)
1057 for (i = 0; i < iface->ptCount; i++)
1058 IUnknown_Release(iface->pt[i]);
1059 HeapFree(GetProcessHeap(),0,iface->pt);
1061 HeapFree(GetProcessHeap(),0,This);
1066 static HRESULT WINAPI Contain_EnumConnectionPoints(
1067 IConnectionPointContainer* This,
1068 IEnumConnectionPoints **ppEnum)
1072 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
1073 ec->vtbl = &enumpt_vtbl;
1076 ec->container = (Contain*)This;
1077 *ppEnum = (IEnumConnectionPoints*)ec;
1082 static HRESULT WINAPI Contain_FindConnectionPoint(
1083 IConnectionPointContainer* This,
1085 IConnectionPoint **ppCP)
1087 Contain *iface = (Contain*)This;
1090 if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
1092 pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
1093 pt->vtbl = &point_vtbl;
1097 pt->container = iface;
1098 pt->id = IID_IDispatch;
1100 if (iface->ptCount == 0)
1101 iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1103 iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
1104 iface->pt[iface->ptCount] = (IConnectionPoint*)pt;
1107 *ppCP = (IConnectionPoint*)pt;
1111 *ppCP = iface->pt[0];
1112 IUnknown_AddRef((IUnknown*)*ppCP);
1118 static const IConnectionPointContainerVtbl contain_vtbl = {
1119 Contain_QueryInterface,
1123 Contain_EnumConnectionPoints,
1124 Contain_FindConnectionPoint
1127 static void test_IConnectionPoint(void)
1131 IConnectionPoint *point;
1134 DWORD cookie = 0xffffffff;
1138 if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
1140 win_skip("IConnectionPoint Apis not present\n");
1144 container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
1145 container->vtbl = &contain_vtbl;
1146 container->refCount = 1;
1147 container->ptCount = 0;
1148 container->pt = NULL;
1150 dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
1151 dispatch->vtbl = &disp_vtbl;
1152 dispatch->refCount = 1;
1154 rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
1155 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1156 ok(point != NULL, "returned ConnectionPoint is NULL\n");
1157 ok(cookie != 0xffffffff, "invalid cookie returned\n");
1159 rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
1160 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1162 if (pSHPackDispParams)
1164 memset(¶ms, 0xc0, sizeof(params));
1165 memset(vars, 0xc0, sizeof(vars));
1166 rc = pSHPackDispParams(¶ms, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
1167 ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
1169 rc = pIConnectionPoint_SimpleInvoke(point,0xa1,¶ms);
1170 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1173 win_skip("pSHPackDispParams not present\n");
1175 rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
1176 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1178 /* MSDN says this should be required but it crashs on XP
1179 IUnknown_Release(point);
1181 ref = IUnknown_Release((IUnknown*)container);
1182 ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
1183 ref = IUnknown_Release((IUnknown*)dispatch);
1184 ok(ref == 0, "leftover IDispatch reference %i\n",ref);
1187 typedef struct _propbag
1189 const IPropertyBagVtbl *vtbl;
1195 static HRESULT WINAPI Prop_QueryInterface(
1202 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPropertyBag))
1209 IUnknown_AddRef(This);
1213 trace("no interface\n");
1214 return E_NOINTERFACE;
1217 static ULONG WINAPI Prop_AddRef(
1220 PropBag *iface = (PropBag*)This;
1221 return InterlockedIncrement(&iface->refCount);
1224 static ULONG WINAPI Prop_Release(
1227 PropBag *iface = (PropBag*)This;
1230 ret = InterlockedDecrement(&iface->refCount);
1232 HeapFree(GetProcessHeap(),0,This);
1236 static HRESULT WINAPI Prop_Read(
1238 LPCOLESTR pszPropName,
1240 IErrorLog *pErrorLog)
1242 V_VT(pVar) = VT_BLOB|VT_BYREF;
1243 V_BYREF(pVar) = (LPVOID)0xdeadcafe;
1247 static HRESULT WINAPI Prop_Write(
1249 LPCOLESTR pszPropName,
1256 static const IPropertyBagVtbl prop_vtbl = {
1257 Prop_QueryInterface,
1265 static void test_SHPropertyBag_ReadLONG(void)
1270 static const WCHAR szName1[] = {'n','a','m','e','1',0};
1272 if (!pSHPropertyBag_ReadLONG)
1274 win_skip("SHPropertyBag_ReadLONG not present\n");
1278 pb = HeapAlloc(GetProcessHeap(),0,sizeof(PropBag));
1280 pb->vtbl = &prop_vtbl;
1283 rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out);
1284 ok(rc == E_INVALIDARG || broken(rc == 0), "incorrect return %x\n",rc);
1285 ok(out == 0xfeedface, "value should not have changed\n");
1286 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, NULL, &out);
1287 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1288 ok(out == 0xfeedface, "value should not have changed\n");
1289 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, NULL);
1290 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1291 ok(out == 0xfeedface, "value should not have changed\n");
1292 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, &out);
1293 ok(rc == DISP_E_BADVARTYPE || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1294 ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %x\n",out);
1295 IUnknown_Release((IUnknown*)pb);
1300 hShlwapi = GetModuleHandleA("shlwapi.dll");
1302 pGetAcceptLanguagesA = (void*)GetProcAddress(hShlwapi, (LPSTR)14);
1303 pSHSearchMapInt = (void*)GetProcAddress(hShlwapi, (LPSTR)198);
1304 pSHAllocShared=(void*)GetProcAddress(hShlwapi,(char*)7);
1305 pSHLockShared=(void*)GetProcAddress(hShlwapi,(char*)8);
1306 pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9);
1307 pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10);
1308 pSHPackDispParams=(void*)GetProcAddress(hShlwapi,(char*)282);
1309 pIConnectionPoint_SimpleInvoke=(void*)GetProcAddress(hShlwapi,(char*)284);
1310 pIConnectionPoint_InvokeWithCancel=(void*)GetProcAddress(hShlwapi,(char*)283);
1311 pConnectToConnectionPoint=(void*)GetProcAddress(hShlwapi,(char*)168);
1312 pSHPropertyBag_ReadLONG=(void*)GetProcAddress(hShlwapi,(char*)496);
1314 test_GetAcceptLanguagesA();
1315 test_SHSearchMapInt();
1316 test_alloc_shared();
1318 test_GetShellSecurityDescriptor();
1319 test_SHPackDispParams();
1320 test_IConnectionPoint();
1321 test_SHPropertyBag_ReadLONG();