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 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
59 trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
60 " last error %u\n", retval
, buffersize
, buffer
, GetLastError());
62 trace("GetAcceptLanguagesA: skipping tests\n");
65 exactsize
= strlen(buffer
);
67 retval
= pGetAcceptLanguagesA( NULL
, NULL
);
68 ok(retval
== E_FAIL
||
69 retval
== E_INVALIDARG
, /* w2k8 */
70 "function result wrong: got %08x; expected E_FAIL\n", retval
);
72 buffersize
= sizeof(buffer
);
73 retval
= pGetAcceptLanguagesA( NULL
, &buffersize
);
74 ok(retval
== E_FAIL
||
75 retval
== E_INVALIDARG
, /* w2k8 */
76 "function result wrong: got %08x; expected E_FAIL\n", retval
);
77 ok(buffersize
== sizeof(buffer
) ||
78 buffersize
== 0, /* w2k8*/
79 "buffersize was changed and is not 0; size (%d))\n", buffersize
);
81 retval
= pGetAcceptLanguagesA( buffer
, NULL
);
82 ok(retval
== E_FAIL
||
83 retval
== E_INVALIDARG
, /* w2k8 */
84 "function result wrong: got %08x; expected E_FAIL\n", retval
);
87 memset(buffer
, 0, sizeof(buffer
));
88 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
89 ok(retval
== E_FAIL
||
90 retval
== E_INVALIDARG
, /* w2k8 */
91 "function result wrong: got %08x; expected E_FAIL\n", retval
);
93 "buffersize wrong(changed) got %08x; expected 0 (2nd parameter; not on Win2k)\n", buffersize
);
95 buffersize
= buffersize2
= 1;
96 memset(buffer
, 0, sizeof(buffer
));
97 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
100 if(buffersize
== exactsize
) {
101 ok(exactsize
== strlen(buffer
),
102 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), exactsize
);
103 } else if((buffersize
+1) == buffersize2
) {
104 ok(buffersize
== strlen(buffer
),
105 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize
);
107 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
108 retval
, buffersize
, buffer
, GetLastError());
112 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
113 ok(buffersize2
== strlen(buffer
),
114 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize2
);
116 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
): /* Win7 */
118 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
121 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
122 retval
, buffersize
, buffer
, GetLastError());
126 buffersize
= buffersize2
= exactsize
;
127 memset(buffer
, 0, sizeof(buffer
));
128 retval
= pGetAcceptLanguagesA( buffer
, &buffersize
);
131 if((buffersize
== exactsize
) /* XP */ ||
132 ((buffersize
+1)== exactsize
) /* 98 */)
133 ok(buffersize
== strlen(buffer
),
134 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize
);
136 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
137 retval
, buffersize
, buffer
, GetLastError());
141 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
142 ok(buffersize2
== strlen(buffer
),
143 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer
), buffersize2
);
145 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
): /* Win 7 */
147 "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize
);
150 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
151 retval
, buffersize
, buffer
, GetLastError());
156 static void test_SHSearchMapInt(void)
158 int keys
[8], values
[8];
161 if (!pSHSearchMapInt
)
164 memset(keys
, 0, sizeof(keys
));
165 memset(values
, 0, sizeof(values
));
166 keys
[0] = 99; values
[0] = 101;
168 /* NULL key/value lists crash native, so skip testing them */
171 i
= pSHSearchMapInt(keys
, values
, 1, keys
[0]);
172 ok(i
== values
[0], "Len 1, expected %d, got %d\n", values
[0], i
);
174 /* Key doesn't exist */
175 i
= pSHSearchMapInt(keys
, values
, 1, 100);
176 ok(i
== -1, "Len 1 - bad key, expected -1, got %d\n", i
);
178 /* Len = 0 => not found */
179 i
= pSHSearchMapInt(keys
, values
, 0, keys
[0]);
180 ok(i
== -1, "Len 1 - passed len 0, expected -1, got %d\n", i
);
182 /* 2 elements, len = 1 */
183 keys
[1] = 98; values
[1] = 102;
184 i
= pSHSearchMapInt(keys
, values
, 1, keys
[1]);
185 ok(i
== -1, "Len 1 - array len 2, expected -1, got %d\n", i
);
187 /* 2 elements, len = 2 */
188 i
= pSHSearchMapInt(keys
, values
, 2, keys
[1]);
189 ok(i
== values
[1], "Len 2, expected %d, got %d\n", values
[1], i
);
191 /* Searches forward */
192 keys
[2] = 99; values
[2] = 103;
193 i
= pSHSearchMapInt(keys
, values
, 3, keys
[0]);
194 ok(i
== values
[0], "Len 3, expected %d, got %d\n", values
[0], i
);
197 static void test_alloc_shared(void)
205 procid
=GetCurrentProcessId();
206 hmem
=pSHAllocShared(NULL
,10,procid
);
207 ok(hmem
!=NULL
,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
208 ret
= pSHFreeShared(hmem
, procid
);
209 ok( ret
, "SHFreeShared failed: %u\n", GetLastError());
212 hmem
=pSHAllocShared(&val
,4,procid
);
213 ok(hmem
!=NULL
,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
215 p
=pSHLockShared(hmem
,procid
);
216 ok(p
!=NULL
,"SHLockShared failed: %u\n", GetLastError());
218 ok(*p
==val
,"Wrong value in shared memory: %d instead of %d\n",*p
,val
);
219 ret
= pSHUnlockShared(p
);
220 ok( ret
, "SHUnlockShared failed: %u\n", GetLastError());
222 ret
= pSHFreeShared(hmem
, procid
);
223 ok( ret
, "SHFreeShared failed: %u\n", GetLastError());
226 static void test_fdsa(void)
230 DWORD num_items
; /* Number of elements inserted */
231 void *mem
; /* Ptr to array */
232 DWORD blocks_alloced
; /* Number of elements allocated */
233 BYTE inc
; /* Number of elements to grow by when we need to expand */
234 BYTE block_size
; /* Size in bytes of an element */
235 BYTE flags
; /* Flags */
238 BOOL (WINAPI
*pFDSA_Initialize
)(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
240 BOOL (WINAPI
*pFDSA_Destroy
)(FDSA_info
*info
);
241 DWORD (WINAPI
*pFDSA_InsertItem
)(FDSA_info
*info
, DWORD where
, const void *block
);
242 BOOL (WINAPI
*pFDSA_DeleteItem
)(FDSA_info
*info
, DWORD where
);
245 int block_size
= 10, init_blocks
= 4, inc
= 2;
249 pFDSA_Initialize
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)208);
250 pFDSA_Destroy
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)209);
251 pFDSA_InsertItem
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)210);
252 pFDSA_DeleteItem
= (void *)GetProcAddress(hShlwapi
, (LPSTR
)211);
254 mem
= HeapAlloc(GetProcessHeap(), 0, block_size
* init_blocks
);
255 memset(&info
, 0, sizeof(info
));
257 ok(pFDSA_Initialize(block_size
, inc
, &info
, mem
, init_blocks
), "FDSA_Initialize rets FALSE\n");
258 ok(info
.num_items
== 0, "num_items = %d\n", info
.num_items
);
259 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
260 ok(info
.blocks_alloced
== init_blocks
, "blocks_alloced = %d\n", info
.blocks_alloced
);
261 ok(info
.inc
== inc
, "inc = %d\n", info
.inc
);
262 ok(info
.block_size
== block_size
, "block_size = %d\n", info
.block_size
);
263 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
265 ret
= pFDSA_InsertItem(&info
, 1234, "1234567890");
266 ok(ret
== 0, "ret = %d\n", ret
);
267 ok(info
.num_items
== 1, "num_items = %d\n", info
.num_items
);
268 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
269 ok(info
.blocks_alloced
== init_blocks
, "blocks_alloced = %d\n", info
.blocks_alloced
);
270 ok(info
.inc
== inc
, "inc = %d\n", info
.inc
);
271 ok(info
.block_size
== block_size
, "block_size = %d\n", info
.block_size
);
272 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
274 ret
= pFDSA_InsertItem(&info
, 1234, "abcdefghij");
275 ok(ret
== 1, "ret = %d\n", ret
);
277 ret
= pFDSA_InsertItem(&info
, 1, "klmnopqrst");
278 ok(ret
== 1, "ret = %d\n", ret
);
280 ret
= pFDSA_InsertItem(&info
, 0, "uvwxyzABCD");
281 ok(ret
== 0, "ret = %d\n", ret
);
282 ok(info
.mem
== mem
, "mem = %p\n", info
.mem
);
283 ok(info
.flags
== 0, "flags = %d\n", info
.flags
);
285 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
286 ret
= pFDSA_InsertItem(&info
, 0, "EFGHIJKLMN");
287 ok(ret
== 0, "ret = %d\n", ret
);
288 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
289 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
290 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
292 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info
.mem
);
294 ok(pFDSA_DeleteItem(&info
, 2), "rets FALSE\n");
295 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
296 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
297 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
299 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info
.mem
);
301 ok(pFDSA_DeleteItem(&info
, 3), "rets FALSE\n");
302 ok(info
.mem
!= mem
, "mem = %p\n", info
.mem
);
303 ok(info
.blocks_alloced
== init_blocks
+ inc
, "blocks_alloced = %d\n", info
.blocks_alloced
);
304 ok(info
.flags
== 0x1, "flags = %d\n", info
.flags
);
306 ok(!memcmp(info
.mem
, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info
.mem
);
308 ok(!pFDSA_DeleteItem(&info
, 4), "does not ret FALSE\n");
310 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
311 ok(!pFDSA_Destroy(&info
), "FDSA_Destroy does not ret FALSE\n");
314 /* When Initialize is called with inc = 0, set it to 1 */
315 ok(pFDSA_Initialize(block_size
, 0, &info
, mem
, init_blocks
), "FDSA_Initialize rets FALSE\n");
316 ok(info
.inc
== 1, "inc = %d\n", info
.inc
);
318 /* This time, because shlwapi hasn't had to allocate memory
319 internally, Destroy rets non-zero */
320 ok(pFDSA_Destroy(&info
), "FDSA_Destroy rets FALSE\n");
323 HeapFree(GetProcessHeap(), 0, mem
);
327 typedef struct SHELL_USER_SID
{
328 SID_IDENTIFIER_AUTHORITY sidAuthority
;
331 } SHELL_USER_SID
, *PSHELL_USER_SID
;
332 typedef struct SHELL_USER_PERMISSION
{
333 SHELL_USER_SID susID
;
338 DWORD dwInheritAccessMask
;
339 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
340 static void test_GetShellSecurityDescriptor(void)
342 SHELL_USER_PERMISSION supCurrentUserFull
= {
343 { {SECURITY_NULL_SID_AUTHORITY
}, 0, 0 },
344 ACCESS_ALLOWED_ACE_TYPE
, FALSE
,
346 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
347 SHELL_USER_PERMISSION supEveryoneDenied
= {
348 { {SECURITY_WORLD_SID_AUTHORITY
}, SECURITY_WORLD_RID
, 0 },
349 ACCESS_DENIED_ACE_TYPE
, TRUE
,
350 GENERIC_WRITE
, MY_INHERITANCE
| 0xDEADBA00, GENERIC_READ
};
351 PSHELL_USER_PERMISSION rgsup
[2] = {
352 &supCurrentUserFull
, &supEveryoneDenied
,
354 SECURITY_DESCRIPTOR
* psd
;
355 SECURITY_DESCRIPTOR
* (WINAPI
*pGetShellSecurityDescriptor
)(PSHELL_USER_PERMISSION
*,int);
357 pGetShellSecurityDescriptor
=(void*)GetProcAddress(hShlwapi
,(char*)475);
359 if(!pGetShellSecurityDescriptor
)
361 win_skip("GetShellSecurityDescriptor not available\n");
365 psd
= pGetShellSecurityDescriptor(NULL
, 2);
367 broken(psd
==INVALID_HANDLE_VALUE
), /* IE5 */
368 "GetShellSecurityDescriptor should fail\n");
369 psd
= pGetShellSecurityDescriptor(rgsup
, 0);
370 ok(psd
==NULL
, "GetShellSecurityDescriptor should fail\n");
372 SetLastError(0xdeadbeef);
373 psd
= pGetShellSecurityDescriptor(rgsup
, 2);
374 if (psd
== NULL
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
376 /* The previous calls to GetShellSecurityDescriptor don't set the last error */
377 win_skip("GetShellSecurityDescriptor is not implemented\n");
380 if (psd
==INVALID_HANDLE_VALUE
)
382 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
385 ok(psd
!=NULL
, "GetShellSecurityDescriptor failed\n");
388 BOOL bHasDacl
= FALSE
, bDefaulted
;
391 SECURITY_DESCRIPTOR_CONTROL control
;
393 ok(IsValidSecurityDescriptor(psd
), "returned value is not valid SD\n");
395 ok(GetSecurityDescriptorControl(psd
, &control
, &dwRev
),
396 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
397 ok(0 == (control
& SE_SELF_RELATIVE
), "SD should be absolute\n");
399 ok(GetSecurityDescriptorDacl(psd
, &bHasDacl
, &pAcl
, &bDefaulted
),
400 "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
402 ok(bHasDacl
, "SD has no DACL\n");
405 ok(!bDefaulted
, "DACL should not be defaulted\n");
407 ok(pAcl
!= NULL
, "NULL DACL!\n");
410 ACL_SIZE_INFORMATION asiSize
;
412 ok(IsValidAcl(pAcl
), "DACL is not valid\n");
414 ok(GetAclInformation(pAcl
, &asiSize
, sizeof(asiSize
), AclSizeInformation
),
415 "GetAclInformation failed with error %u\n", GetLastError());
417 ok(asiSize
.AceCount
== 3, "Incorrect number of ACEs: %d entries\n", asiSize
.AceCount
);
418 if (asiSize
.AceCount
== 3)
420 ACCESS_ALLOWED_ACE
*paaa
; /* will use for DENIED too */
422 ok(GetAce(pAcl
, 0, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
423 ok(paaa
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
,
424 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
425 ok(paaa
->Header
.AceFlags
== 0, "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
426 ok(paaa
->Mask
== GENERIC_ALL
, "Invalid ACE mask %x\n", paaa
->Mask
);
428 ok(GetAce(pAcl
, 1, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
429 ok(paaa
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
,
430 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
431 /* first one of two ACEs generated from inheritable entry - without inheritance */
432 ok(paaa
->Header
.AceFlags
== 0, "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
433 ok(paaa
->Mask
== GENERIC_WRITE
, "Invalid ACE mask %x\n", paaa
->Mask
);
435 ok(GetAce(pAcl
, 2, (LPVOID
*)&paaa
), "GetAce failed with error %u\n", GetLastError());
436 ok(paaa
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
,
437 "Invalid ACE type %d\n", paaa
->Header
.AceType
);
438 /* second ACE - with inheritance */
439 ok(paaa
->Header
.AceFlags
== MY_INHERITANCE
,
440 "Invalid ACE flags %x\n", paaa
->Header
.AceFlags
);
441 ok(paaa
->Mask
== GENERIC_READ
, "Invalid ACE mask %x\n", paaa
->Mask
);
450 static void test_SHPackDispParams(void)
456 if(!pSHPackDispParams
)
457 win_skip("SHPackSidpParams not available\n");
459 memset(¶ms
, 0xc0, sizeof(params
));
460 memset(vars
, 0xc0, sizeof(vars
));
461 hres
= pSHPackDispParams(¶ms
, vars
, 1, VT_I4
, 0xdeadbeef);
462 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
463 ok(params
.cArgs
== 1, "params.cArgs = %d\n", params
.cArgs
);
464 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
465 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
466 ok(params
.rgvarg
== vars
, "params.rgvarg = %p\n", params
.rgvarg
);
467 ok(V_VT(vars
) == VT_I4
, "V_VT(var) = %d\n", V_VT(vars
));
468 ok(V_I4(vars
) == 0xdeadbeef, "failed %x\n", V_I4(vars
));
470 memset(¶ms
, 0xc0, sizeof(params
));
471 hres
= pSHPackDispParams(¶ms
, NULL
, 0, 0);
472 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
473 ok(params
.cArgs
== 0, "params.cArgs = %d\n", params
.cArgs
);
474 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
475 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
476 ok(params
.rgvarg
== NULL
, "params.rgvarg = %p\n", params
.rgvarg
);
478 memset(vars
, 0xc0, sizeof(vars
));
479 memset(¶ms
, 0xc0, sizeof(params
));
480 hres
= pSHPackDispParams(¶ms
, vars
, 4, VT_BSTR
, (void*)0xdeadbeef, VT_EMPTY
, 10,
481 VT_I4
, 100, VT_DISPATCH
, (void*)0xdeadbeef);
482 ok(hres
== S_OK
, "SHPackDispParams failed: %08x\n", hres
);
483 ok(params
.cArgs
== 4, "params.cArgs = %d\n", params
.cArgs
);
484 ok(params
.cNamedArgs
== 0, "params.cNamedArgs = %d\n", params
.cArgs
);
485 ok(params
.rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", params
.rgdispidNamedArgs
);
486 ok(params
.rgvarg
== vars
, "params.rgvarg = %p\n", params
.rgvarg
);
487 ok(V_VT(vars
) == VT_DISPATCH
, "V_VT(vars[0]) = %x\n", V_VT(vars
));
488 ok(V_I4(vars
) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars
));
489 ok(V_VT(vars
+1) == VT_I4
, "V_VT(vars[1]) = %d\n", V_VT(vars
+1));
490 ok(V_I4(vars
+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars
+1));
491 ok(V_VT(vars
+2) == VT_I4
, "V_VT(vars[2]) = %d\n", V_VT(vars
+2));
492 ok(V_I4(vars
+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars
+2));
493 ok(V_VT(vars
+3) == VT_BSTR
, "V_VT(vars[3]) = %d\n", V_VT(vars
+3));
494 ok(V_BSTR(vars
+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars
+3));
499 const IDispatchVtbl
*vtbl
;
503 typedef struct _contain
505 const IConnectionPointContainerVtbl
*vtbl
;
509 IConnectionPoint
**pt
;
512 typedef struct _cntptn
514 const IConnectionPointVtbl
*vtbl
;
525 const IEnumConnectionsVtbl
*vtbl
;
532 typedef struct _enumpt
534 const IEnumConnectionPointsVtbl
*vtbl
;
542 static HRESULT WINAPI
Disp_QueryInterface(
549 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
))
556 IUnknown_AddRef(This
);
560 trace("no interface\n");
561 return E_NOINTERFACE
;
564 static ULONG WINAPI
Disp_AddRef(IDispatch
* This
)
566 Disp
*iface
= (Disp
*)This
;
567 return InterlockedIncrement(&iface
->refCount
);
570 static ULONG WINAPI
Disp_Release(IDispatch
* This
)
572 Disp
*iface
= (Disp
*)This
;
575 ret
= InterlockedDecrement(&iface
->refCount
);
577 HeapFree(GetProcessHeap(),0,This
);
581 static HRESULT WINAPI
Disp_GetTypeInfoCount(
585 return ERROR_SUCCESS
;
588 static HRESULT WINAPI
Disp_GetTypeInfo(
594 return ERROR_SUCCESS
;
597 static HRESULT WINAPI
Disp_GetIDsOfNames(
605 return ERROR_SUCCESS
;
608 static HRESULT WINAPI
Disp_Invoke(
614 DISPPARAMS
*pDispParams
,
616 EXCEPINFO
*pExcepInfo
,
619 trace("%p %x %p %x %x %p %p %p %p\n",This
,dispIdMember
,riid
,lcid
,wFlags
,pDispParams
,pVarResult
,pExcepInfo
,puArgErr
);
621 ok(dispIdMember
== 0xa0 || dispIdMember
== 0xa1, "Unknown dispIdMember\n");
622 ok(pDispParams
!= NULL
, "Invoked with NULL pDispParams\n");
623 ok(wFlags
== DISPATCH_METHOD
, "Wrong flags %x\n",wFlags
);
624 ok(lcid
== 0,"Wrong lcid %x\n",lcid
);
625 if (dispIdMember
== 0xa0)
627 ok(pDispParams
->cArgs
== 0, "params.cArgs = %d\n", pDispParams
->cArgs
);
628 ok(pDispParams
->cNamedArgs
== 0, "params.cNamedArgs = %d\n", pDispParams
->cArgs
);
629 ok(pDispParams
->rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", pDispParams
->rgdispidNamedArgs
);
630 ok(pDispParams
->rgvarg
== NULL
, "params.rgvarg = %p\n", pDispParams
->rgvarg
);
632 else if (dispIdMember
== 0xa1)
634 ok(pDispParams
->cArgs
== 2, "params.cArgs = %d\n", pDispParams
->cArgs
);
635 ok(pDispParams
->cNamedArgs
== 0, "params.cNamedArgs = %d\n", pDispParams
->cArgs
);
636 ok(pDispParams
->rgdispidNamedArgs
== NULL
, "params.rgdispidNamedArgs = %p\n", pDispParams
->rgdispidNamedArgs
);
637 ok(V_VT(pDispParams
->rgvarg
) == VT_BSTR
, "V_VT(var) = %d\n", V_VT(pDispParams
->rgvarg
));
638 ok(V_I4(pDispParams
->rgvarg
) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams
->rgvarg
));
639 ok(V_VT(pDispParams
->rgvarg
+1) == VT_I4
, "V_VT(var) = %d\n", V_VT(pDispParams
->rgvarg
+1));
640 ok(V_I4(pDispParams
->rgvarg
+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams
->rgvarg
+1));
643 return ERROR_SUCCESS
;
646 static const IDispatchVtbl disp_vtbl
= {
651 Disp_GetTypeInfoCount
,
657 static HRESULT WINAPI
Enum_QueryInterface(
658 IEnumConnections
* This
,
664 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IEnumConnections
))
671 IUnknown_AddRef(This
);
675 trace("no interface\n");
676 return E_NOINTERFACE
;
679 static ULONG WINAPI
Enum_AddRef(IEnumConnections
* This
)
681 EnumCon
*iface
= (EnumCon
*)This
;
682 return InterlockedIncrement(&iface
->refCount
);
685 static ULONG WINAPI
Enum_Release(IEnumConnections
* This
)
687 EnumCon
*iface
= (EnumCon
*)This
;
690 ret
= InterlockedDecrement(&iface
->refCount
);
692 HeapFree(GetProcessHeap(),0,This
);
696 static HRESULT WINAPI
Enum_Next(
697 IEnumConnections
* This
,
702 EnumCon
*iface
= (EnumCon
*)This
;
704 if (cConnections
> 0 && iface
->idx
< iface
->pt
->sinkCount
)
706 rgcd
->pUnk
= iface
->pt
->sink
[iface
->idx
];
707 IUnknown_AddRef(iface
->pt
->sink
[iface
->idx
]);
718 static HRESULT WINAPI
Enum_Skip(
719 IEnumConnections
* This
,
725 static HRESULT WINAPI
Enum_Reset(
726 IEnumConnections
* This
)
731 static HRESULT WINAPI
Enum_Clone(
732 IEnumConnections
* This
,
733 IEnumConnections
**ppEnum
)
738 static const IEnumConnectionsVtbl enum_vtbl
= {
749 static HRESULT WINAPI
ConPt_QueryInterface(
750 IConnectionPoint
* This
,
756 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IConnectionPoint
))
763 IUnknown_AddRef(This
);
767 trace("no interface\n");
768 return E_NOINTERFACE
;
771 static ULONG WINAPI
ConPt_AddRef(
772 IConnectionPoint
* This
)
774 ConPt
*iface
= (ConPt
*)This
;
775 return InterlockedIncrement(&iface
->refCount
);
778 static ULONG WINAPI
ConPt_Release(
779 IConnectionPoint
* This
)
781 ConPt
*iface
= (ConPt
*)This
;
784 ret
= InterlockedDecrement(&iface
->refCount
);
787 if (iface
->sinkCount
> 0)
790 for (i
= 0; i
< iface
->sinkCount
; i
++)
793 IUnknown_Release(iface
->sink
[i
]);
795 HeapFree(GetProcessHeap(),0,iface
->sink
);
797 HeapFree(GetProcessHeap(),0,This
);
802 static HRESULT WINAPI
ConPt_GetConnectionInterface(
803 IConnectionPoint
* This
,
807 ConPt
*iface
= (ConPt
*)This
;
814 memcpy(pIID
,&iface
->id
,sizeof(GUID
));
818 static HRESULT WINAPI
ConPt_GetConnectionPointContainer(
819 IConnectionPoint
* This
,
820 IConnectionPointContainer
**ppCPC
)
822 ConPt
*iface
= (ConPt
*)This
;
824 *ppCPC
= (IConnectionPointContainer
*)iface
->container
;
828 static HRESULT WINAPI
ConPt_Advise(
829 IConnectionPoint
* This
,
833 ConPt
*iface
= (ConPt
*)This
;
835 if (iface
->sinkCount
== 0)
836 iface
->sink
= HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown
*));
838 iface
->sink
= HeapReAlloc(GetProcessHeap(),0,iface
->sink
,sizeof(IUnknown
*)*(iface
->sinkCount
+1));
839 iface
->sink
[iface
->sinkCount
] = pUnkSink
;
840 IUnknown_AddRef(pUnkSink
);
842 *pdwCookie
= iface
->sinkCount
;
846 static HRESULT WINAPI
ConPt_Unadvise(
847 IConnectionPoint
* This
,
850 ConPt
*iface
= (ConPt
*)This
;
852 if (dwCookie
> iface
->sinkCount
)
856 IUnknown_Release(iface
->sink
[dwCookie
-1]);
857 iface
->sink
[dwCookie
-1] = NULL
;
862 static HRESULT WINAPI
ConPt_EnumConnections(
863 IConnectionPoint
* This
,
864 IEnumConnections
**ppEnum
)
868 ec
= HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon
));
869 ec
->vtbl
= &enum_vtbl
;
871 ec
->pt
= (ConPt
*)This
;
873 *ppEnum
= (IEnumConnections
*)ec
;
878 static const IConnectionPointVtbl point_vtbl
= {
879 ConPt_QueryInterface
,
883 ConPt_GetConnectionInterface
,
884 ConPt_GetConnectionPointContainer
,
887 ConPt_EnumConnections
890 static HRESULT WINAPI
EnumPt_QueryInterface(
891 IEnumConnectionPoints
* This
,
897 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IEnumConnectionPoints
))
904 IUnknown_AddRef(This
);
908 trace("no interface\n");
909 return E_NOINTERFACE
;
912 static ULONG WINAPI
EnumPt_AddRef(IEnumConnectionPoints
* This
)
914 EnumPt
*iface
= (EnumPt
*)This
;
915 return InterlockedIncrement(&iface
->refCount
);
918 static ULONG WINAPI
EnumPt_Release(IEnumConnectionPoints
* This
)
920 EnumPt
*iface
= (EnumPt
*)This
;
923 ret
= InterlockedDecrement(&iface
->refCount
);
925 HeapFree(GetProcessHeap(),0,This
);
929 static HRESULT WINAPI
EnumPt_Next(
930 IEnumConnectionPoints
* This
,
932 IConnectionPoint
**rgcd
,
935 EnumPt
*iface
= (EnumPt
*)This
;
937 if (cConnections
> 0 && iface
->idx
< iface
->container
->ptCount
)
939 *rgcd
= iface
->container
->pt
[iface
->idx
];
940 IUnknown_AddRef(iface
->container
->pt
[iface
->idx
]);
950 static HRESULT WINAPI
EnumPt_Skip(
951 IEnumConnectionPoints
* This
,
957 static HRESULT WINAPI
EnumPt_Reset(
958 IEnumConnectionPoints
* This
)
963 static HRESULT WINAPI
EnumPt_Clone(
964 IEnumConnectionPoints
* This
,
965 IEnumConnectionPoints
**ppEnumPt
)
970 static const IEnumConnectionPointsVtbl enumpt_vtbl
= {
972 EnumPt_QueryInterface
,
981 static HRESULT WINAPI
Contain_QueryInterface(
982 IConnectionPointContainer
* This
,
988 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IConnectionPointContainer
))
995 IUnknown_AddRef(This
);
999 trace("no interface\n");
1000 return E_NOINTERFACE
;
1003 static ULONG WINAPI
Contain_AddRef(
1004 IConnectionPointContainer
* This
)
1006 Contain
*iface
= (Contain
*)This
;
1007 return InterlockedIncrement(&iface
->refCount
);
1010 static ULONG WINAPI
Contain_Release(
1011 IConnectionPointContainer
* This
)
1013 Contain
*iface
= (Contain
*)This
;
1016 ret
= InterlockedDecrement(&iface
->refCount
);
1019 if (iface
->ptCount
> 0)
1022 for (i
= 0; i
< iface
->ptCount
; i
++)
1023 IUnknown_Release(iface
->pt
[i
]);
1024 HeapFree(GetProcessHeap(),0,iface
->pt
);
1026 HeapFree(GetProcessHeap(),0,This
);
1031 static HRESULT WINAPI
Contain_EnumConnectionPoints(
1032 IConnectionPointContainer
* This
,
1033 IEnumConnectionPoints
**ppEnum
)
1037 ec
= HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt
));
1038 ec
->vtbl
= &enumpt_vtbl
;
1041 ec
->container
= (Contain
*)This
;
1042 *ppEnum
= (IEnumConnectionPoints
*)ec
;
1047 static HRESULT WINAPI
Contain_FindConnectionPoint(
1048 IConnectionPointContainer
* This
,
1050 IConnectionPoint
**ppCP
)
1052 Contain
*iface
= (Contain
*)This
;
1055 if (!IsEqualIID(riid
, &IID_NULL
) || iface
->ptCount
==0)
1057 pt
= HeapAlloc(GetProcessHeap(),0,sizeof(ConPt
));
1058 pt
->vtbl
= &point_vtbl
;
1062 pt
->container
= iface
;
1063 pt
->id
= IID_IDispatch
;
1065 if (iface
->ptCount
== 0)
1066 iface
->pt
=HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown
*));
1068 iface
->pt
= HeapReAlloc(GetProcessHeap(),0,iface
->pt
,sizeof(IUnknown
*)*(iface
->ptCount
+1));
1069 iface
->pt
[iface
->ptCount
] = (IConnectionPoint
*)pt
;
1072 *ppCP
= (IConnectionPoint
*)pt
;
1076 *ppCP
= iface
->pt
[0];
1077 IUnknown_AddRef((IUnknown
*)*ppCP
);
1083 static const IConnectionPointContainerVtbl contain_vtbl
= {
1084 Contain_QueryInterface
,
1088 Contain_EnumConnectionPoints
,
1089 Contain_FindConnectionPoint
1092 static void test_IConnectionPoint(void)
1096 IConnectionPoint
*point
;
1099 DWORD cookie
= 0xffffffff;
1103 if (!pIConnectionPoint_SimpleInvoke
|| !pConnectToConnectionPoint
)
1105 win_skip("IConnectionPoint Apis not present\n");
1109 container
= HeapAlloc(GetProcessHeap(),0,sizeof(Contain
));
1110 container
->vtbl
= &contain_vtbl
;
1111 container
->refCount
= 1;
1112 container
->ptCount
= 0;
1113 container
->pt
= NULL
;
1115 dispatch
= HeapAlloc(GetProcessHeap(),0,sizeof(Disp
));
1116 dispatch
->vtbl
= &disp_vtbl
;
1117 dispatch
->refCount
= 1;
1119 rc
= pConnectToConnectionPoint((IUnknown
*)dispatch
, &IID_NULL
, TRUE
, (IUnknown
*)container
, &cookie
, &point
);
1120 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1121 ok(point
!= NULL
, "returned ConnectionPoint is NULL\n");
1122 ok(cookie
!= 0xffffffff, "invalid cookie returned\n");
1124 rc
= pIConnectionPoint_SimpleInvoke(point
,0xa0,NULL
);
1125 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1127 if (pSHPackDispParams
)
1129 memset(¶ms
, 0xc0, sizeof(params
));
1130 memset(vars
, 0xc0, sizeof(vars
));
1131 rc
= pSHPackDispParams(¶ms
, vars
, 2, VT_I4
, 0xdeadbeef, VT_BSTR
, 0xdeadcafe);
1132 ok(rc
== S_OK
, "SHPackDispParams failed: %08x\n", rc
);
1134 rc
= pIConnectionPoint_SimpleInvoke(point
,0xa1,¶ms
);
1135 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1138 win_skip("pSHPackDispParams not present\n");
1140 rc
= pConnectToConnectionPoint(NULL
, &IID_NULL
, FALSE
, (IUnknown
*)container
, &cookie
, NULL
);
1141 ok(rc
== S_OK
, "pConnectToConnectionPoint failed with %x\n",rc
);
1143 /* MSDN says this should be required but it crashs on XP
1144 IUnknown_Release(point);
1146 ref
= IUnknown_Release((IUnknown
*)container
);
1147 ok(ref
== 0, "leftover IConnectionPointContainer reference %i\n",ref
);
1148 ref
= IUnknown_Release((IUnknown
*)dispatch
);
1149 ok(ref
== 0, "leftover IDispatch reference %i\n",ref
);
1152 typedef struct _propbag
1154 const IPropertyBagVtbl
*vtbl
;
1160 static HRESULT WINAPI
Prop_QueryInterface(
1167 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IPropertyBag
))
1174 IUnknown_AddRef(This
);
1178 trace("no interface\n");
1179 return E_NOINTERFACE
;
1182 static ULONG WINAPI
Prop_AddRef(
1185 PropBag
*iface
= (PropBag
*)This
;
1186 return InterlockedIncrement(&iface
->refCount
);
1189 static ULONG WINAPI
Prop_Release(
1192 PropBag
*iface
= (PropBag
*)This
;
1195 ret
= InterlockedDecrement(&iface
->refCount
);
1197 HeapFree(GetProcessHeap(),0,This
);
1201 static HRESULT WINAPI
Prop_Read(
1203 LPCOLESTR pszPropName
,
1205 IErrorLog
*pErrorLog
)
1207 V_VT(pVar
) = VT_BLOB
|VT_BYREF
;
1208 V_BYREF(pVar
) = (LPVOID
)0xdeadcafe;
1212 static HRESULT WINAPI
Prop_Write(
1214 LPCOLESTR pszPropName
,
1221 static const IPropertyBagVtbl prop_vtbl
= {
1222 Prop_QueryInterface
,
1230 static void test_SHPropertyBag_ReadLONG(void)
1235 static const WCHAR szName1
[] = {'n','a','m','e','1',0};
1237 if (!pSHPropertyBag_ReadLONG
)
1239 win_skip("SHPropertyBag_ReadLONG not present\n");
1243 pb
= HeapAlloc(GetProcessHeap(),0,sizeof(PropBag
));
1245 pb
->vtbl
= &prop_vtbl
;
1248 rc
= pSHPropertyBag_ReadLONG(NULL
, szName1
, &out
);
1249 ok(rc
== E_INVALIDARG
|| broken(rc
== 0), "incorrect return %x\n",rc
);
1250 ok(out
== 0xfeedface, "value should not have changed\n");
1251 rc
= pSHPropertyBag_ReadLONG((IPropertyBag
*)pb
, NULL
, &out
);
1252 ok(rc
== E_INVALIDARG
|| broken(rc
== 0) || broken(rc
== 1), "incorrect return %x\n",rc
);
1253 ok(out
== 0xfeedface, "value should not have changed\n");
1254 rc
= pSHPropertyBag_ReadLONG((IPropertyBag
*)pb
, szName1
, NULL
);
1255 ok(rc
== E_INVALIDARG
|| broken(rc
== 0) || broken(rc
== 1), "incorrect return %x\n",rc
);
1256 ok(out
== 0xfeedface, "value should not have changed\n");
1257 rc
= pSHPropertyBag_ReadLONG((IPropertyBag
*)pb
, szName1
, &out
);
1258 ok(rc
== DISP_E_BADVARTYPE
|| broken(rc
== 0) || broken(rc
== 1), "incorrect return %x\n",rc
);
1259 ok(out
== 0xfeedface || broken(out
== 0xfeedfa00), "value should not have changed %x\n",out
);
1260 IUnknown_Release((IUnknown
*)pb
);
1265 hShlwapi
= GetModuleHandleA("shlwapi.dll");
1267 pGetAcceptLanguagesA
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)14);
1268 pSHSearchMapInt
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)198);
1269 pSHAllocShared
=(void*)GetProcAddress(hShlwapi
,(char*)7);
1270 pSHLockShared
=(void*)GetProcAddress(hShlwapi
,(char*)8);
1271 pSHUnlockShared
=(void*)GetProcAddress(hShlwapi
,(char*)9);
1272 pSHFreeShared
=(void*)GetProcAddress(hShlwapi
,(char*)10);
1273 pSHPackDispParams
=(void*)GetProcAddress(hShlwapi
,(char*)282);
1274 pIConnectionPoint_SimpleInvoke
=(void*)GetProcAddress(hShlwapi
,(char*)284);
1275 pIConnectionPoint_InvokeWithCancel
=(void*)GetProcAddress(hShlwapi
,(char*)283);
1276 pConnectToConnectionPoint
=(void*)GetProcAddress(hShlwapi
,(char*)168);
1277 pSHPropertyBag_ReadLONG
=(void*)GetProcAddress(hShlwapi
,(char*)496);
1279 test_GetAcceptLanguagesA();
1280 test_SHSearchMapInt();
1281 test_alloc_shared();
1283 test_GetShellSecurityDescriptor();
1284 test_SHPackDispParams();
1285 test_IConnectionPoint();
1286 test_SHPropertyBag_ReadLONG();