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
**);
45 static void test_GetAcceptLanguagesA(void)
47 DWORD buffersize
, buffersize2
, exactsize
;
50 if (!pGetAcceptLanguagesA
) {
51 win_skip("GetAcceptLanguagesA is not available\n");
55 buffersize
= sizeof(buffer
);
56 memset(buffer
, 0, sizeof(buffer
));
57 SetLastError(ERROR_SUCCESS
);
58 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
59 if (!retval
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
60 win_skip("GetAcceptLanguagesA is not implemented\n");
63 trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
64 " last error %u\n", retval
, buffersize
, buffer
, GetLastError());
66 trace("GetAcceptLanguagesA: skipping tests\n");
69 ok( (ERROR_NO_IMPERSONATION_TOKEN
== GetLastError()) ||
70 (ERROR_CLASS_DOES_NOT_EXIST
== GetLastError()) ||
71 (ERROR_PROC_NOT_FOUND
== GetLastError()) ||
72 (ERROR_SUCCESS
== GetLastError()), "last error set to %u\n", GetLastError());
73 exactsize
= strlen(buffer
);
75 SetLastError(ERROR_SUCCESS
);
76 retval
= pGetAcceptLanguagesA( NULL
, NULL
);
77 ok(retval
== E_FAIL
||
78 retval
== E_INVALIDARG
, /* w2k8 */
79 "function result wrong: got %08x; expected E_FAIL\n", retval
);
80 ok(ERROR_SUCCESS
== GetLastError(), "last error set to %u\n", GetLastError());
82 buffersize
= sizeof(buffer
);
83 SetLastError(ERROR_SUCCESS
);
84 retval
= pGetAcceptLanguagesA( NULL
, &buffersize
);
85 ok(retval
== E_FAIL
||
86 retval
== E_INVALIDARG
, /* w2k8 */
87 "function result wrong: got %08x; expected E_FAIL\n", retval
);
88 ok(buffersize
== sizeof(buffer
) ||
89 buffersize
== 0, /* w2k8*/
90 "buffersize was changed and is not 0; size (%d))\n", buffersize
);
91 ok(ERROR_SUCCESS
== GetLastError(), "last error set to %u\n", GetLastError());
93 SetLastError(ERROR_SUCCESS
);
94 retval
= pGetAcceptLanguagesA( buffer
, NULL
);
95 ok(retval
== E_FAIL
||
96 retval
== E_INVALIDARG
, /* w2k8 */
97 "function result wrong: got %08x; expected E_FAIL\n", retval
);
98 ok(ERROR_SUCCESS
== GetLastError(), "last error set to %u\n", GetLastError());
101 memset(buffer
, 0, sizeof(buffer
));
102 SetLastError(ERROR_SUCCESS
);
103 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
104 ok(retval
== E_FAIL
||
105 retval
== E_INVALIDARG
, /* w2k8 */
106 "function result wrong: got %08x; expected E_FAIL\n", retval
);
108 "buffersize wrong(changed) got %08x; expected 0 (2nd parameter; not on Win2k)\n", buffersize
);
109 ok(ERROR_SUCCESS
== GetLastError(), "last error set to %u\n", GetLastError());
111 buffersize
= buffersize2
= 1;
112 memset(buffer
, 0, sizeof(buffer
));
113 SetLastError(ERROR_SUCCESS
);
114 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
117 if(buffersize
== exactsize
) {
118 ok( (ERROR_SUCCESS
== GetLastError()) ||
119 (ERROR_PROC_NOT_FOUND
== GetLastError()) || (ERROR_NO_IMPERSONATION_TOKEN
== GetLastError()),
120 "last error wrong: got %u; expected ERROR_SUCCESS(NT4)/"
121 "ERROR_PROC_NOT_FOUND(NT4)/ERROR_NO_IMPERSONATION_TOKEN(XP)\n", GetLastError());
122 ok(exactsize
== strlen(buffer
),
123 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), exactsize
);
124 } else if((buffersize
+1) == buffersize2
) {
125 ok(ERROR_SUCCESS
== GetLastError(),
126 "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
127 ok(buffersize
== strlen(buffer
),
128 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize
);
130 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
131 retval
, buffersize
, buffer
, GetLastError());
135 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
136 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
137 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
138 ok(buffersize2
== strlen(buffer
),
139 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize2
);
141 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
): /* Win7 */
143 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
144 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
145 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
148 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
149 retval
, buffersize
, buffer
, GetLastError());
153 buffersize
= buffersize2
= exactsize
;
154 memset(buffer
, 0, sizeof(buffer
));
155 SetLastError(ERROR_SUCCESS
);
156 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
159 ok(ERROR_SUCCESS
== GetLastError(),
160 "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
161 if((buffersize
== exactsize
) /* XP */ ||
162 ((buffersize
+1)== exactsize
) /* 98 */)
163 ok(buffersize
== strlen(buffer
),
164 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize
);
166 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
167 retval
, buffersize
, buffer
, GetLastError());
171 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
172 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
173 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
174 ok(buffersize2
== strlen(buffer
),
175 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize2
);
177 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
): /* Win 7 */
179 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
180 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
181 "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
184 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
185 retval
, buffersize
, buffer
, GetLastError());
190 static void test_SHSearchMapInt(void)
192 int keys
[8], values
[8];
195 if (!pSHSearchMapInt
)
198 memset(keys
, 0, sizeof(keys
));
199 memset(values
, 0, sizeof(values
));
200 keys
[0] = 99; values
[0] = 101;
202 /* NULL key/value lists crash native, so skip testing them */
205 i
= pSHSearchMapInt(keys
, values
, 1, keys
[0]);
206 ok(i
== values
[0], "Len 1, expected %d, got %d\n", values
[0], i
);
208 /* Key doesn't exist */
209 i
= pSHSearchMapInt(keys
, values
, 1, 100);
210 ok(i
== -1, "Len 1 - bad key, expected -1, got %d\n", i
);
212 /* Len = 0 => not found */
213 i
= pSHSearchMapInt(keys
, values
, 0, keys
[0]);
214 ok(i
== -1, "Len 1 - passed len 0, expected -1, got %d\n", i
);
216 /* 2 elements, len = 1 */
217 keys
[1] = 98; values
[1] = 102;
218 i
= pSHSearchMapInt(keys
, values
, 1, keys
[1]);
219 ok(i
== -1, "Len 1 - array len 2, expected -1, got %d\n", i
);
221 /* 2 elements, len = 2 */
222 i
= pSHSearchMapInt(keys
, values
, 2, keys
[1]);
223 ok(i
== values
[1], "Len 2, expected %d, got %d\n", values
[1], i
);
225 /* Searches forward */
226 keys
[2] = 99; values
[2] = 103;
227 i
= pSHSearchMapInt(keys
, values
, 3, keys
[0]);
228 ok(i
== values
[0], "Len 3, expected %d, got %d\n", values
[0], i
);
231 static void test_alloc_shared(void)
239 procid
=GetCurrentProcessId();
240 hmem
=pSHAllocShared(NULL
,10,procid
);
241 ok(hmem
!=NULL
,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
242 ret
= pSHFreeShared(hmem
, procid
);
243 ok( ret
, "SHFreeShared failed: %u\n", GetLastError());
246 hmem
=pSHAllocShared(&val
,4,procid
);
247 ok(hmem
!=NULL
,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
249 p
=pSHLockShared(hmem
,procid
);
250 ok(p
!=NULL
,"SHLockShared failed: %u\n", GetLastError());
252 ok(*p
==val
,"Wrong value in shared memory: %d instead of %d\n",*p
,val
);
253 ret
= pSHUnlockShared(p
);
254 ok( ret
, "SHUnlockShared failed: %u\n", GetLastError());
256 ret
= pSHFreeShared(hmem
, procid
);
257 ok( ret
, "SHFreeShared failed: %u\n", GetLastError());
260 static void test_fdsa(void)
264 DWORD num_items
; /* Number of elements inserted */
265 void *mem
; /* Ptr to array */
266 DWORD blocks_alloced
; /* Number of elements allocated */
267 BYTE inc
; /* Number of elements to grow by when we need to expand */
268 BYTE block_size
; /* Size in bytes of an element */
269 BYTE flags
; /* Flags */
272 BOOL (WINAPI
*pFDSA_Initialize
)(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
274 BOOL (WINAPI
*pFDSA_Destroy
)(FDSA_info
*info
);
275 DWORD (WINAPI
*pFDSA_InsertItem
)(FDSA_info
*info
, DWORD where
, const void *block
);
276 BOOL (WINAPI
*pFDSA_DeleteItem
)(FDSA_info
*info
, DWORD where
);
279 int block_size
= 10, init_blocks
= 4, inc
= 2;
283 pFDSA_Initialize
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)208);
284 pFDSA_Destroy
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)209);
285 pFDSA_InsertItem
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)210);
286 pFDSA_DeleteItem
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)211);
288 mem
= HeapAlloc(GetProcessHeap(), 0, block_size
* init_blocks
);
289 memset(&info
, 0, sizeof(info
));
291 ok(pFDSA_Initialize(block_size
, inc
, &info
, mem
, init_blocks
), "FDSA_Initialize rets FALSE\n");
292 ok(info
.num_items
== 0, "num_items = %d\n", info
.num_items
);
293 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
294 ok(info
.blocks_alloced
== init_blocks
, "blocks_alloced = %d\n", info
.blocks_alloced
);
295 ok(info
.inc
== inc
, "inc = %d\n", info
.inc
);
296 ok(info
.block_size
== block_size
, "block_size = %d\n", info
.block_size
);
297 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
299 ret
= pFDSA_InsertItem(&info
, 1234, "1234567890");
300 ok(ret
== 0, "ret = %d\n", ret
);
301 ok(info
.num_items
== 1, "num_items = %d\n", info
.num_items
);
302 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
303 ok(info
.blocks_alloced
== init_blocks
, "blocks_alloced = %d\n", info
.blocks_alloced
);
304 ok(info
.inc
== inc
, "inc = %d\n", info
.inc
);
305 ok(info
.block_size
== block_size
, "block_size = %d\n", info
.block_size
);
306 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
308 ret
= pFDSA_InsertItem(&info
, 1234, "abcdefghij");
309 ok(ret
== 1, "ret = %d\n", ret
);
311 ret
= pFDSA_InsertItem(&info
, 1, "klmnopqrst");
312 ok(ret
== 1, "ret = %d\n", ret
);
314 ret
= pFDSA_InsertItem(&info
, 0, "uvwxyzABCD");
315 ok(ret
== 0, "ret = %d\n", ret
);
316 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
317 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
319 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
320 ret
= pFDSA_InsertItem(&info
, 0, "EFGHIJKLMN");
321 ok(ret
== 0, "ret = %d\n", ret
);
322 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
323 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
324 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
326 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info
.mem
);
328 ok(pFDSA_DeleteItem(&info
, 2), "rets FALSE\n");
329 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
330 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
331 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
333 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info
.mem
);
335 ok(pFDSA_DeleteItem(&info
, 3), "rets FALSE\n");
336 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
337 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
338 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
340 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info
.mem
);
342 ok(!pFDSA_DeleteItem(&info
, 4), "does not ret FALSE\n");
344 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
345 ok(!pFDSA_Destroy(&info
), "FDSA_Destroy does not ret FALSE\n");
348 /* When Initialize is called with inc = 0, set it to 1 */
349 ok(pFDSA_Initialize(block_size
, 0, &info
, mem
, init_blocks
), "FDSA_Initialize rets FALSE\n");
350 ok(info
.inc
== 1, "inc = %d\n", info
.inc
);
352 /* This time, because shlwapi hasn't had to allocate memory
353 internally, Destroy rets non-zero */
354 ok(pFDSA_Destroy(&info
), "FDSA_Destroy rets FALSE\n");
357 HeapFree(GetProcessHeap(), 0, mem
);
361 typedef struct SHELL_USER_SID
{
362 SID_IDENTIFIER_AUTHORITY sidAuthority
;
365 } SHELL_USER_SID
, *PSHELL_USER_SID
;
366 typedef struct SHELL_USER_PERMISSION
{
367 SHELL_USER_SID susID
;
372 DWORD dwInheritAccessMask
;
373 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
374 static void test_GetShellSecurityDescriptor(void)
376 SHELL_USER_PERMISSION supCurrentUserFull
= {
377 { {SECURITY_NULL_SID_AUTHORITY
}, 0, 0 },
378 ACCESS_ALLOWED_ACE_TYPE
, FALSE
,
380 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
381 SHELL_USER_PERMISSION supEveryoneDenied
= {
382 { {SECURITY_WORLD_SID_AUTHORITY
}, SECURITY_WORLD_RID
, 0 },
383 ACCESS_DENIED_ACE_TYPE
, TRUE
,
384 GENERIC_WRITE
, MY_INHERITANCE
| 0xDEADBA00, GENERIC_READ
};
385 PSHELL_USER_PERMISSION rgsup
[2] = {
386 &supCurrentUserFull
, &supEveryoneDenied
,
388 SECURITY_DESCRIPTOR
* psd
;
389 SECURITY_DESCRIPTOR
* (WINAPI
*pGetShellSecurityDescriptor
)(PSHELL_USER_PERMISSION
*,int);
391 pGetShellSecurityDescriptor
=(void*)GetProcAddress(hShlwapi
,(char*)475);
393 if(!pGetShellSecurityDescriptor
)
395 win_skip("GetShellSecurityDescriptor not available\n");
399 psd
= pGetShellSecurityDescriptor(NULL
, 2);
401 broken(psd
==INVALID_HANDLE_VALUE
), /* IE5 */
402 "GetShellSecurityDescriptor should fail\n");
403 psd
= pGetShellSecurityDescriptor(rgsup
, 0);
404 ok(psd
==NULL
, "GetShellSecurityDescriptor should fail\n");
406 SetLastError(0xdeadbeef);
407 psd
= pGetShellSecurityDescriptor(rgsup
, 2);
408 if (psd
== NULL
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
410 /* The previous calls to GetShellSecurityDescriptor don't set the last error */
411 win_skip("GetShellSecurityDescriptor is not implemented\n");
414 if (psd
==INVALID_HANDLE_VALUE
)
416 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
419 ok(psd
!=NULL
, "GetShellSecurityDescriptor failed\n");
422 BOOL bHasDacl
= FALSE
, bDefaulted
;
425 SECURITY_DESCRIPTOR_CONTROL control
;
427 ok(IsValidSecurityDescriptor(psd
), "returned value is not valid SD\n");
429 ok(GetSecurityDescriptorControl(psd
, &control
, &dwRev
),
430 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
431 ok(0 == (control
& SE_SELF_RELATIVE
), "SD should be absolute\n");
433 ok(GetSecurityDescriptorDacl(psd
, &bHasDacl
, &pAcl
, &bDefaulted
),
434 "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
436 ok(bHasDacl
, "SD has no DACL\n");
439 ok(!bDefaulted
, "DACL should not be defaulted\n");
441 ok(pAcl
!= NULL
, "NULL DACL!\n");
444 ACL_SIZE_INFORMATION asiSize
;
446 ok(IsValidAcl(pAcl
), "DACL is not valid\n");
448 ok(GetAclInformation(pAcl
, &asiSize
, sizeof(asiSize
), AclSizeInformation
),
449 "GetAclInformation failed with error %u\n", GetLastError());
451 ok(asiSize
.AceCount
== 3, "Incorrect number of ACEs: %d entries\n", asiSize
.AceCount
);
452 if (asiSize
.AceCount
== 3)
454 ACCESS_ALLOWED_ACE
*paaa
; /* will use for DENIED too */
456 ok(GetAce(pAcl
, 0, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
457 ok(paaa
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
,
458 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
459 ok(paaa
->Header
.AceFlags
== 0, "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
460 ok(paaa
->Mask
== GENERIC_ALL
, "Invalid ACE mask %x\n", paaa
->Mask
);
462 ok(GetAce(pAcl
, 1, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
463 ok(paaa
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
,
464 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
465 /* first one of two ACEs generated from inheritable entry - without inheritance */
466 ok(paaa
->Header
.AceFlags
== 0, "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
467 ok(paaa
->Mask
== GENERIC_WRITE
, "Invalid ACE mask %x\n", paaa
->Mask
);
469 ok(GetAce(pAcl
, 2, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
470 ok(paaa
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
,
471 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
472 /* second ACE - with inheritance */
473 ok(paaa
->Header
.AceFlags
== MY_INHERITANCE
,
474 "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
475 ok(paaa
->Mask
== GENERIC_READ
, "Invalid ACE mask %x\n", paaa
->Mask
);
484 static void test_SHPackDispParams(void)
490 if(!pSHPackDispParams
)
491 win_skip("SHPackSidpParams not available\n");
493 memset(¶ms
, 0xc0, sizeof(params
));
494 memset(vars
, 0xc0, sizeof(vars
));
495 hres
= pSHPackDispParams(¶ms
, vars
, 1, VT_I4
, 0xdeadbeef);
496 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
497 ok(params
.cArgs
== 1, "params.cArgs = %d\n", params
.cArgs
);
498 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
499 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
500 ok(params
.rgvarg
== vars
, "params.rgvarg = %p\n", params
.rgvarg
);
501 ok(V_VT(vars
) == VT_I4
, "V_VT(var) = %d\n", V_VT(vars
));
502 ok(V_I4(vars
) == 0xdeadbeef, "failed %x\n", V_I4(vars
));
504 memset(¶ms
, 0xc0, sizeof(params
));
505 hres
= pSHPackDispParams(¶ms
, NULL
, 0, 0);
506 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
507 ok(params
.cArgs
== 0, "params.cArgs = %d\n", params
.cArgs
);
508 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
509 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
510 ok(params
.rgvarg
== NULL
, "params.rgvarg = %p\n", params
.rgvarg
);
512 memset(vars
, 0xc0, sizeof(vars
));
513 memset(¶ms
, 0xc0, sizeof(params
));
514 hres
= pSHPackDispParams(¶ms
, vars
, 4, VT_BSTR
, (void*)0xdeadbeef, VT_EMPTY
, 10,
515 VT_I4
, 100, VT_DISPATCH
, (void*)0xdeadbeef);
516 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
517 ok(params
.cArgs
== 4, "params.cArgs = %d\n", params
.cArgs
);
518 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
519 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
520 ok(params
.rgvarg
== vars
, "params.rgvarg = %p\n", params
.rgvarg
);
521 ok(V_VT(vars
) == VT_DISPATCH
, "V_VT(vars[0]) = %x\n", V_VT(vars
));
522 ok(V_I4(vars
) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars
));
523 ok(V_VT(vars
+1) == VT_I4
, "V_VT(vars[1]) = %d\n", V_VT(vars
+1));
524 ok(V_I4(vars
+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars
+1));
525 ok(V_VT(vars
+2) == VT_I4
, "V_VT(vars[2]) = %d\n", V_VT(vars
+2));
526 ok(V_I4(vars
+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars
+2));
527 ok(V_VT(vars
+3) == VT_BSTR
, "V_VT(vars[3]) = %d\n", V_VT(vars
+3));
528 ok(V_BSTR(vars
+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars
+3));
533 const IDispatchVtbl
*vtbl
;
537 typedef struct _contain
539 const IConnectionPointContainerVtbl
*vtbl
;
543 IConnectionPoint
**pt
;
546 typedef struct _cntptn
548 const IConnectionPointVtbl
*vtbl
;
559 const IEnumConnectionsVtbl
*vtbl
;
566 typedef struct _enumpt
568 const IEnumConnectionPointsVtbl
*vtbl
;
576 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(
621 return ERROR_SUCCESS
;
624 static HRESULT WINAPI
Disp_GetTypeInfo(
631 return ERROR_SUCCESS
;
634 static HRESULT WINAPI
Disp_GetIDsOfNames(
643 return ERROR_SUCCESS
;
646 static HRESULT WINAPI
Disp_Invoke(
652 DISPPARAMS
*pDispParams
,
654 EXCEPINFO
*pExcepInfo
,
657 trace("%p %x %p %x %x %p %p %p %p\n",This
,dispIdMember
,riid
,lcid
,wFlags
,pDispParams
,pVarResult
,pExcepInfo
,puArgErr
);
659 ok(dispIdMember
== 0xa0 || dispIdMember
== 0xa1, "Unknown dispIdMember\n");
660 ok(pDispParams
!= NULL
, "Invoked with NULL pDispParams\n");
661 ok(wFlags
== DISPATCH_METHOD
, "Wrong flags %x\n",wFlags
);
662 ok(lcid
== 0,"Wrong lcid %x\n",lcid
);
663 if (dispIdMember
== 0xa0)
665 ok(pDispParams
->cArgs
== 0, "params.cArgs = %d\n", pDispParams
->cArgs
);
666 ok(pDispParams
->cNamedArgs
== 0, "params.cNamedArgs = %d\n", pDispParams
->cArgs
);
667 ok(pDispParams
->rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", pDispParams
->rgdispidNamedArgs
);
668 ok(pDispParams
->rgvarg
== NULL
, "params.rgvarg = %p\n", pDispParams
->rgvarg
);
670 else if (dispIdMember
== 0xa1)
672 ok(pDispParams
->cArgs
== 2, "params.cArgs = %d\n", pDispParams
->cArgs
);
673 ok(pDispParams
->cNamedArgs
== 0, "params.cNamedArgs = %d\n", pDispParams
->cArgs
);
674 ok(pDispParams
->rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", pDispParams
->rgdispidNamedArgs
);
675 ok(V_VT(pDispParams
->rgvarg
) == VT_BSTR
, "V_VT(var) = %d\n", V_VT(pDispParams
->rgvarg
));
676 ok(V_I4(pDispParams
->rgvarg
) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams
->rgvarg
));
677 ok(V_VT(pDispParams
->rgvarg
+1) == VT_I4
, "V_VT(var) = %d\n", V_VT(pDispParams
->rgvarg
+1));
678 ok(V_I4(pDispParams
->rgvarg
+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams
->rgvarg
+1));
681 return ERROR_SUCCESS
;
684 static const IDispatchVtbl disp_vtbl
= {
689 Disp_GetTypeInfoCount
,
695 static HRESULT WINAPI
Enum_QueryInterface(
696 IEnumConnections
* This
,
703 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IEnumConnections
))
710 IUnknown_AddRef(This
);
714 trace("no interface\n");
715 return E_NOINTERFACE
;
718 static ULONG WINAPI
Enum_AddRef(IEnumConnections
* This
)
720 EnumCon
*iface
= (EnumCon
*)This
;
721 return InterlockedIncrement(&iface
->refCount
);
724 static ULONG WINAPI
Enum_Release(IEnumConnections
* This
)
726 EnumCon
*iface
= (EnumCon
*)This
;
729 ret
= InterlockedDecrement(&iface
->refCount
);
731 HeapFree(GetProcessHeap(),0,This
);
735 static HRESULT WINAPI
Enum_Next(
736 IEnumConnections
* This
,
741 EnumCon
*iface
= (EnumCon
*)This
;
744 if (cConnections
> 0 && iface
->idx
< iface
->pt
->sinkCount
)
746 rgcd
->pUnk
= iface
->pt
->sink
[iface
->idx
];
747 IUnknown_AddRef(iface
->pt
->sink
[iface
->idx
]);
758 static HRESULT WINAPI
Enum_Skip(
759 IEnumConnections
* This
,
766 static HRESULT WINAPI
Enum_Reset(
767 IEnumConnections
* This
)
773 static HRESULT WINAPI
Enum_Clone(
774 IEnumConnections
* This
,
775 IEnumConnections
**ppEnum
)
781 static const IEnumConnectionsVtbl enum_vtbl
= {
792 static HRESULT WINAPI
ConPt_QueryInterface(
793 IConnectionPoint
* This
,
800 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IConnectionPoint
))
807 IUnknown_AddRef(This
);
811 trace("no interface\n");
812 return E_NOINTERFACE
;
815 static ULONG WINAPI
ConPt_AddRef(
816 IConnectionPoint
* This
)
818 ConPt
*iface
= (ConPt
*)This
;
819 return InterlockedIncrement(&iface
->refCount
);
822 static ULONG WINAPI
ConPt_Release(
823 IConnectionPoint
* This
)
825 ConPt
*iface
= (ConPt
*)This
;
828 ret
= InterlockedDecrement(&iface
->refCount
);
831 if (iface
->sinkCount
> 0)
834 for (i
= 0; i
< iface
->sinkCount
; i
++)
837 IUnknown_Release(iface
->sink
[i
]);
839 HeapFree(GetProcessHeap(),0,iface
->sink
);
841 HeapFree(GetProcessHeap(),0,This
);
846 static HRESULT WINAPI
ConPt_GetConnectionInterface(
847 IConnectionPoint
* This
,
851 ConPt
*iface
= (ConPt
*)This
;
859 memcpy(pIID
,&iface
->id
,sizeof(GUID
));
863 static HRESULT WINAPI
ConPt_GetConnectionPointContainer(
864 IConnectionPoint
* This
,
865 IConnectionPointContainer
**ppCPC
)
867 ConPt
*iface
= (ConPt
*)This
;
870 *ppCPC
= (IConnectionPointContainer
*)iface
->container
;
874 static HRESULT WINAPI
ConPt_Advise(
875 IConnectionPoint
* This
,
879 ConPt
*iface
= (ConPt
*)This
;
882 if (iface
->sinkCount
== 0)
883 iface
->sink
= HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown
*));
885 iface
->sink
= HeapReAlloc(GetProcessHeap(),0,iface
->sink
,sizeof(IUnknown
*)*(iface
->sinkCount
+1));
886 iface
->sink
[iface
->sinkCount
] = pUnkSink
;
887 IUnknown_AddRef(pUnkSink
);
889 *pdwCookie
= iface
->sinkCount
;
893 static HRESULT WINAPI
ConPt_Unadvise(
894 IConnectionPoint
* This
,
897 ConPt
*iface
= (ConPt
*)This
;
900 if (dwCookie
> iface
->sinkCount
)
904 IUnknown_Release(iface
->sink
[dwCookie
-1]);
905 iface
->sink
[dwCookie
-1] = NULL
;
910 static HRESULT WINAPI
ConPt_EnumConnections(
911 IConnectionPoint
* This
,
912 IEnumConnections
**ppEnum
)
917 ec
= HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon
));
918 ec
->vtbl
= &enum_vtbl
;
920 ec
->pt
= (ConPt
*)This
;
922 *ppEnum
= (IEnumConnections
*)ec
;
927 static const IConnectionPointVtbl point_vtbl
= {
928 ConPt_QueryInterface
,
932 ConPt_GetConnectionInterface
,
933 ConPt_GetConnectionPointContainer
,
936 ConPt_EnumConnections
939 static HRESULT WINAPI
EnumPt_QueryInterface(
940 IEnumConnectionPoints
* This
,
947 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IEnumConnectionPoints
))
954 IUnknown_AddRef(This
);
958 trace("no interface\n");
959 return E_NOINTERFACE
;
962 static ULONG WINAPI
EnumPt_AddRef(IEnumConnectionPoints
* This
)
964 EnumPt
*iface
= (EnumPt
*)This
;
965 return InterlockedIncrement(&iface
->refCount
);
968 static ULONG WINAPI
EnumPt_Release(IEnumConnectionPoints
* This
)
970 EnumPt
*iface
= (EnumPt
*)This
;
973 ret
= InterlockedDecrement(&iface
->refCount
);
975 HeapFree(GetProcessHeap(),0,This
);
979 static HRESULT WINAPI
EnumPt_Next(
980 IEnumConnectionPoints
* This
,
982 IConnectionPoint
**rgcd
,
985 EnumPt
*iface
= (EnumPt
*)This
;
988 if (cConnections
> 0 && iface
->idx
< iface
->container
->ptCount
)
990 *rgcd
= iface
->container
->pt
[iface
->idx
];
991 IUnknown_AddRef(iface
->container
->pt
[iface
->idx
]);
1001 static HRESULT WINAPI
EnumPt_Skip(
1002 IEnumConnectionPoints
* This
,
1009 static HRESULT WINAPI
EnumPt_Reset(
1010 IEnumConnectionPoints
* This
)
1016 static HRESULT WINAPI
EnumPt_Clone(
1017 IEnumConnectionPoints
* This
,
1018 IEnumConnectionPoints
**ppEnumPt
)
1024 static const IEnumConnectionPointsVtbl enumpt_vtbl
= {
1026 EnumPt_QueryInterface
,
1035 static HRESULT WINAPI
Contain_QueryInterface(
1036 IConnectionPointContainer
* This
,
1043 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IConnectionPointContainer
))
1050 IUnknown_AddRef(This
);
1054 trace("no interface\n");
1055 return E_NOINTERFACE
;
1058 static ULONG WINAPI
Contain_AddRef(
1059 IConnectionPointContainer
* This
)
1061 Contain
*iface
= (Contain
*)This
;
1062 return InterlockedIncrement(&iface
->refCount
);
1065 static ULONG WINAPI
Contain_Release(
1066 IConnectionPointContainer
* This
)
1068 Contain
*iface
= (Contain
*)This
;
1071 ret
= InterlockedDecrement(&iface
->refCount
);
1074 if (iface
->ptCount
> 0)
1077 for (i
= 0; i
< iface
->ptCount
; i
++)
1078 IUnknown_Release(iface
->pt
[i
]);
1079 HeapFree(GetProcessHeap(),0,iface
->pt
);
1081 HeapFree(GetProcessHeap(),0,This
);
1086 static HRESULT WINAPI
Contain_EnumConnectionPoints(
1087 IConnectionPointContainer
* This
,
1088 IEnumConnectionPoints
**ppEnum
)
1093 ec
= HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt
));
1094 ec
->vtbl
= &enumpt_vtbl
;
1097 ec
->container
= (Contain
*)This
;
1098 *ppEnum
= (IEnumConnectionPoints
*)ec
;
1103 static HRESULT WINAPI
Contain_FindConnectionPoint(
1104 IConnectionPointContainer
* This
,
1106 IConnectionPoint
**ppCP
)
1108 Contain
*iface
= (Contain
*)This
;
1112 if (!IsEqualIID(riid
, &IID_NULL
) || iface
->ptCount
==0)
1114 pt
= HeapAlloc(GetProcessHeap(),0,sizeof(ConPt
));
1115 pt
->vtbl
= &point_vtbl
;
1119 pt
->container
= iface
;
1121 if (iface
->ptCount
== 0)
1122 iface
->pt
=HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown
*));
1124 iface
->pt
= HeapReAlloc(GetProcessHeap(),0,iface
->pt
,sizeof(IUnknown
*)*(iface
->ptCount
+1));
1125 iface
->pt
[iface
->ptCount
] = (IConnectionPoint
*)pt
;
1128 *ppCP
= (IConnectionPoint
*)pt
;
1132 *ppCP
= iface
->pt
[0];
1133 IUnknown_AddRef((IUnknown
*)*ppCP
);
1139 static const IConnectionPointContainerVtbl contain_vtbl
= {
1140 Contain_QueryInterface
,
1144 Contain_EnumConnectionPoints
,
1145 Contain_FindConnectionPoint
1148 void test_IConnectionPoint(void)
1152 IConnectionPoint
*point
;
1155 DWORD cookie
= 0xffffffff;
1159 if (!pIConnectionPoint_SimpleInvoke
|| !pConnectToConnectionPoint
)
1161 win_skip("IConnectionPoint Apis not present\n");
1165 container
= HeapAlloc(GetProcessHeap(),0,sizeof(Contain
));
1166 container
->vtbl
= &contain_vtbl
;
1167 container
->refCount
= 1;
1168 container
->ptCount
= 0;
1169 container
->pt
= NULL
;
1171 dispatch
= HeapAlloc(GetProcessHeap(),0,sizeof(Disp
));
1172 dispatch
->vtbl
= &disp_vtbl
;
1173 dispatch
->refCount
= 1;
1175 rc
= pConnectToConnectionPoint((IUnknown
*)dispatch
, &IID_NULL
, TRUE
, (IUnknown
*)container
, &cookie
, &point
);
1176 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1177 ok(point
!= NULL
, "returned ConnectionPoint is NULL\n");
1178 ok(cookie
!= 0xffffffff, "invalid cookie returned\n");
1180 rc
= pIConnectionPoint_SimpleInvoke(point
,0xa0,NULL
);
1181 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1183 if (pSHPackDispParams
)
1185 memset(¶ms
, 0xc0, sizeof(params
));
1186 memset(vars
, 0xc0, sizeof(vars
));
1187 rc
= pSHPackDispParams(¶ms
, vars
, 2, VT_I4
, 0xdeadbeef, VT_BSTR
, 0xdeadcafe);
1188 ok(rc
== S_OK
, "SHPackDispParams failed: %08x\n", rc
);
1190 rc
= pIConnectionPoint_SimpleInvoke(point
,0xa1,¶ms
);
1191 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1194 win_skip("pSHPackDispParams not present\n");
1196 rc
= pConnectToConnectionPoint(NULL
, &IID_NULL
, FALSE
, (IUnknown
*)container
, &cookie
, NULL
);
1197 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1199 /* MSDN says this should be required but it crashs on XP
1200 IUnknown_Release(point);
1202 ref
= IUnknown_Release((IUnknown
*)container
);
1203 ok(ref
== 0, "leftover IConnectionPointContainer reference %i\n",ref
);
1204 ref
= IUnknown_Release((IUnknown
*)dispatch
);
1205 ok(ref
== 0, "leftover IDispatch reference %i\n",ref
);
1210 hShlwapi
= GetModuleHandleA("shlwapi.dll");
1212 pGetAcceptLanguagesA
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)14);
1213 pSHSearchMapInt
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)198);
1214 pSHAllocShared
=(void*)GetProcAddress(hShlwapi
,(char*)7);
1215 pSHLockShared
=(void*)GetProcAddress(hShlwapi
,(char*)8);
1216 pSHUnlockShared
=(void*)GetProcAddress(hShlwapi
,(char*)9);
1217 pSHFreeShared
=(void*)GetProcAddress(hShlwapi
,(char*)10);
1218 pSHPackDispParams
=(void*)GetProcAddress(hShlwapi
,(char*)282);
1219 pIConnectionPoint_SimpleInvoke
=(void*)GetProcAddress(hShlwapi
,(char*)284);
1220 pIConnectionPoint_InvokeWithCancel
=(void*)GetProcAddress(hShlwapi
,(char*)283);
1221 pConnectToConnectionPoint
=(void*)GetProcAddress(hShlwapi
,(char*)168);
1223 test_GetAcceptLanguagesA();
1224 test_SHSearchMapInt();
1225 test_alloc_shared();
1227 test_GetShellSecurityDescriptor();
1228 test_SHPackDispParams();
1229 test_IConnectionPoint();