shlwapi: Implement SHPropertyBag_ReadLONG.
[wine/multimedia.git] / dlls / shlwapi / tests / ordinal.c
blobac1a2239d4b8d34a316ffe6e540b1a9fb1ec115b
1 /* Unit test suite for SHLWAPI ordinal functions
3 * Copyright 2004 Jon Griffiths
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdio.h>
22 #define COBJMACROS
23 #include "wine/test.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "oaidl.h"
29 #include "ocidl.h"
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)
47 { HRESULT retval;
48 DWORD buffersize, buffersize2, exactsize;
49 char buffer[100];
51 if (!pGetAcceptLanguagesA) {
52 win_skip("GetAcceptLanguagesA is not available\n");
53 return;
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");
62 return;
64 trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
65 " last error %u\n", retval, buffersize, buffer, GetLastError());
66 if(retval != S_OK) {
67 trace("GetAcceptLanguagesA: skipping tests\n");
68 return;
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());
101 buffersize = 0;
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);
108 ok(buffersize == 0,
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);
116 switch(retval) {
117 case 0L:
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);
130 } else
131 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
132 retval, buffersize, buffer, GetLastError());
133 break;
134 case E_INVALIDARG:
135 ok(buffersize == 0,
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);
141 break;
142 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win7 */
143 ok(buffersize == 0,
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());
147 break;
148 default:
149 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
150 retval, buffersize, buffer, GetLastError());
151 break;
154 buffersize = buffersize2 = exactsize;
155 memset(buffer, 0, sizeof(buffer));
156 SetLastError(ERROR_SUCCESS);
157 retval = pGetAcceptLanguagesA( buffer, &buffersize);
158 switch(retval) {
159 case 0L:
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);
166 else
167 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
168 retval, buffersize, buffer, GetLastError());
169 break;
170 case E_INVALIDARG:
171 ok(buffersize == 0,
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);
177 break;
178 case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win 7 */
179 ok(buffersize == 0,
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());
183 break;
184 default:
185 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
186 retval, buffersize, buffer, GetLastError());
187 break;
191 static void test_SHSearchMapInt(void)
193 int keys[8], values[8];
194 int i = 0;
196 if (!pSHSearchMapInt)
197 return;
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 */
205 /* 1 element */
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)
234 DWORD procid;
235 HANDLE hmem;
236 int val;
237 int* p;
238 BOOL ret;
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());
246 val=0x12345678;
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());
252 if (p!=NULL)
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)
263 typedef struct
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 */
271 } FDSA_info;
273 BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
274 DWORD init_blocks);
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);
279 FDSA_info info;
280 int block_size = 10, init_blocks = 4, inc = 2;
281 DWORD ret;
282 char *mem;
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;
364 DWORD dwUserGroupID;
365 DWORD dwUserID;
366 } SHELL_USER_SID, *PSHELL_USER_SID;
367 typedef struct SHELL_USER_PERMISSION {
368 SHELL_USER_SID susID;
369 DWORD dwAccessType;
370 BOOL fInherit;
371 DWORD dwAccessMask;
372 DWORD dwInheritMask;
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,
380 GENERIC_ALL, 0, 0 };
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");
397 return;
400 psd = pGetShellSecurityDescriptor(NULL, 2);
401 ok(psd==NULL ||
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");
413 return;
415 if (psd==INVALID_HANDLE_VALUE)
417 win_skip("GetShellSecurityDescriptor is broken on IE5\n");
418 return;
420 ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
421 if (psd!=NULL)
423 BOOL bHasDacl = FALSE, bDefaulted;
424 PACL pAcl;
425 DWORD dwRev;
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");
438 if (bHasDacl)
440 ok(!bDefaulted, "DACL should not be defaulted\n");
442 ok(pAcl != NULL, "NULL DACL!\n");
443 if (pAcl != NULL)
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);
481 LocalFree(psd);
485 static void test_SHPackDispParams(void)
487 DISPPARAMS params;
488 VARIANT vars[10];
489 HRESULT hres;
491 if(!pSHPackDispParams)
492 win_skip("SHPackSidpParams not available\n");
494 memset(&params, 0xc0, sizeof(params));
495 memset(vars, 0xc0, sizeof(vars));
496 hres = pSHPackDispParams(&params, 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(&params, 0xc0, sizeof(params));
506 hres = pSHPackDispParams(&params, 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(&params, 0xc0, sizeof(params));
515 hres = pSHPackDispParams(&params, 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));
532 typedef struct _disp
534 const IDispatchVtbl *vtbl;
535 LONG refCount;
536 } Disp;
538 typedef struct _contain
540 const IConnectionPointContainerVtbl *vtbl;
541 LONG refCount;
543 UINT ptCount;
544 IConnectionPoint **pt;
545 } Contain;
547 typedef struct _cntptn
549 const IConnectionPointVtbl *vtbl;
550 LONG refCount;
552 Contain *container;
553 GUID id;
554 UINT sinkCount;
555 IUnknown **sink;
556 } ConPt;
558 typedef struct _enum
560 const IEnumConnectionsVtbl *vtbl;
561 LONG refCount;
563 UINT idx;
564 ConPt *pt;
565 } EnumCon;
567 typedef struct _enumpt
569 const IEnumConnectionPointsVtbl *vtbl;
570 LONG refCount;
572 int idx;
573 Contain *container;
574 } EnumPt;
577 static HRESULT WINAPI Disp_QueryInterface(
578 IDispatch* This,
579 REFIID riid,
580 void **ppvObject)
582 trace("\n");
583 *ppvObject = NULL;
585 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
587 *ppvObject = This;
590 if (*ppvObject)
592 IUnknown_AddRef(This);
593 return S_OK;
596 trace("no interface\n");
597 return E_NOINTERFACE;
600 static ULONG WINAPI Disp_AddRef(IDispatch* This)
602 Disp *iface = (Disp*)This;
603 return InterlockedIncrement(&iface->refCount);
606 static ULONG WINAPI Disp_Release(IDispatch* This)
608 Disp *iface = (Disp*)This;
609 ULONG ret;
611 ret = InterlockedDecrement(&iface->refCount);
612 if (ret == 0)
613 HeapFree(GetProcessHeap(),0,This);
614 return ret;
617 static HRESULT WINAPI Disp_GetTypeInfoCount(
618 IDispatch* This,
619 UINT *pctinfo)
621 trace("\n");
622 return ERROR_SUCCESS;
625 static HRESULT WINAPI Disp_GetTypeInfo(
626 IDispatch* This,
627 UINT iTInfo,
628 LCID lcid,
629 ITypeInfo **ppTInfo)
631 trace("\n");
632 return ERROR_SUCCESS;
635 static HRESULT WINAPI Disp_GetIDsOfNames(
636 IDispatch* This,
637 REFIID riid,
638 LPOLESTR *rgszNames,
639 UINT cNames,
640 LCID lcid,
641 DISPID *rgDispId)
643 trace("\n");
644 return ERROR_SUCCESS;
647 static HRESULT WINAPI Disp_Invoke(
648 IDispatch* This,
649 DISPID dispIdMember,
650 REFIID riid,
651 LCID lcid,
652 WORD wFlags,
653 DISPPARAMS *pDispParams,
654 VARIANT *pVarResult,
655 EXCEPINFO *pExcepInfo,
656 UINT *puArgErr)
658 trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
660 ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
661 ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
662 ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
663 ok(lcid == 0,"Wrong lcid %x\n",lcid);
664 if (dispIdMember == 0xa0)
666 ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
667 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
668 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
669 ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
671 else if (dispIdMember == 0xa1)
673 ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
674 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
675 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
676 ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
677 ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
678 ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
679 ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
682 return ERROR_SUCCESS;
685 static const IDispatchVtbl disp_vtbl = {
686 Disp_QueryInterface,
687 Disp_AddRef,
688 Disp_Release,
690 Disp_GetTypeInfoCount,
691 Disp_GetTypeInfo,
692 Disp_GetIDsOfNames,
693 Disp_Invoke
696 static HRESULT WINAPI Enum_QueryInterface(
697 IEnumConnections* This,
698 REFIID riid,
699 void **ppvObject)
701 trace("\n");
702 *ppvObject = NULL;
704 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
706 *ppvObject = This;
709 if (*ppvObject)
711 IUnknown_AddRef(This);
712 return S_OK;
715 trace("no interface\n");
716 return E_NOINTERFACE;
719 static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
721 EnumCon *iface = (EnumCon*)This;
722 return InterlockedIncrement(&iface->refCount);
725 static ULONG WINAPI Enum_Release(IEnumConnections* This)
727 EnumCon *iface = (EnumCon*)This;
728 ULONG ret;
730 ret = InterlockedDecrement(&iface->refCount);
731 if (ret == 0)
732 HeapFree(GetProcessHeap(),0,This);
733 return ret;
736 static HRESULT WINAPI Enum_Next(
737 IEnumConnections* This,
738 ULONG cConnections,
739 LPCONNECTDATA rgcd,
740 ULONG *pcFetched)
742 EnumCon *iface = (EnumCon*)This;
744 trace("\n");
745 if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
747 rgcd->pUnk = iface->pt->sink[iface->idx];
748 IUnknown_AddRef(iface->pt->sink[iface->idx]);
749 rgcd->dwCookie=0xff;
750 if (pcFetched)
751 *pcFetched = 1;
752 iface->idx++;
753 return S_OK;
756 return E_FAIL;
759 static HRESULT WINAPI Enum_Skip(
760 IEnumConnections* This,
761 ULONG cConnections)
763 trace("\n");
764 return E_FAIL;
767 static HRESULT WINAPI Enum_Reset(
768 IEnumConnections* This)
770 trace("\n");
771 return E_FAIL;
774 static HRESULT WINAPI Enum_Clone(
775 IEnumConnections* This,
776 IEnumConnections **ppEnum)
778 trace("\n");
779 return E_FAIL;
782 static const IEnumConnectionsVtbl enum_vtbl = {
784 Enum_QueryInterface,
785 Enum_AddRef,
786 Enum_Release,
787 Enum_Next,
788 Enum_Skip,
789 Enum_Reset,
790 Enum_Clone
793 static HRESULT WINAPI ConPt_QueryInterface(
794 IConnectionPoint* This,
795 REFIID riid,
796 void **ppvObject)
798 trace("\n");
799 *ppvObject = NULL;
801 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
803 *ppvObject = This;
806 if (*ppvObject)
808 IUnknown_AddRef(This);
809 return S_OK;
812 trace("no interface\n");
813 return E_NOINTERFACE;
816 static ULONG WINAPI ConPt_AddRef(
817 IConnectionPoint* This)
819 ConPt *iface = (ConPt*)This;
820 return InterlockedIncrement(&iface->refCount);
823 static ULONG WINAPI ConPt_Release(
824 IConnectionPoint* This)
826 ConPt *iface = (ConPt*)This;
827 ULONG ret;
829 ret = InterlockedDecrement(&iface->refCount);
830 if (ret == 0)
832 if (iface->sinkCount > 0)
834 int i;
835 for (i = 0; i < iface->sinkCount; i++)
837 if (iface->sink[i])
838 IUnknown_Release(iface->sink[i]);
840 HeapFree(GetProcessHeap(),0,iface->sink);
842 HeapFree(GetProcessHeap(),0,This);
844 return ret;
847 static HRESULT WINAPI ConPt_GetConnectionInterface(
848 IConnectionPoint* This,
849 IID *pIID)
851 static int i = 0;
852 ConPt *iface = (ConPt*)This;
853 trace("\n");
854 if (i==0)
856 i++;
857 return E_FAIL;
859 else
860 memcpy(pIID,&iface->id,sizeof(GUID));
861 return S_OK;
864 static HRESULT WINAPI ConPt_GetConnectionPointContainer(
865 IConnectionPoint* This,
866 IConnectionPointContainer **ppCPC)
868 ConPt *iface = (ConPt*)This;
869 trace("\n");
871 *ppCPC = (IConnectionPointContainer*)iface->container;
872 return S_OK;
875 static HRESULT WINAPI ConPt_Advise(
876 IConnectionPoint* This,
877 IUnknown *pUnkSink,
878 DWORD *pdwCookie)
880 ConPt *iface = (ConPt*)This;
881 trace("\n");
883 if (iface->sinkCount == 0)
884 iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
885 else
886 iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
887 iface->sink[iface->sinkCount] = pUnkSink;
888 IUnknown_AddRef(pUnkSink);
889 iface->sinkCount++;
890 *pdwCookie = iface->sinkCount;
891 return S_OK;
894 static HRESULT WINAPI ConPt_Unadvise(
895 IConnectionPoint* This,
896 DWORD dwCookie)
898 ConPt *iface = (ConPt*)This;
899 trace("\n");
901 if (dwCookie > iface->sinkCount)
902 return E_FAIL;
903 else
905 IUnknown_Release(iface->sink[dwCookie-1]);
906 iface->sink[dwCookie-1] = NULL;
908 return S_OK;
911 static HRESULT WINAPI ConPt_EnumConnections(
912 IConnectionPoint* This,
913 IEnumConnections **ppEnum)
915 EnumCon *ec;
917 trace("\n");
918 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
919 ec->vtbl = &enum_vtbl;
920 ec->refCount = 1;
921 ec->pt = (ConPt*)This;
922 ec->idx = 0;
923 *ppEnum = (IEnumConnections*)ec;
925 return S_OK;
928 static const IConnectionPointVtbl point_vtbl = {
929 ConPt_QueryInterface,
930 ConPt_AddRef,
931 ConPt_Release,
933 ConPt_GetConnectionInterface,
934 ConPt_GetConnectionPointContainer,
935 ConPt_Advise,
936 ConPt_Unadvise,
937 ConPt_EnumConnections
940 static HRESULT WINAPI EnumPt_QueryInterface(
941 IEnumConnectionPoints* This,
942 REFIID riid,
943 void **ppvObject)
945 trace("\n");
946 *ppvObject = NULL;
948 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
950 *ppvObject = This;
953 if (*ppvObject)
955 IUnknown_AddRef(This);
956 return S_OK;
959 trace("no interface\n");
960 return E_NOINTERFACE;
963 static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
965 EnumPt *iface = (EnumPt*)This;
966 return InterlockedIncrement(&iface->refCount);
969 static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
971 EnumPt *iface = (EnumPt*)This;
972 ULONG ret;
974 ret = InterlockedDecrement(&iface->refCount);
975 if (ret == 0)
976 HeapFree(GetProcessHeap(),0,This);
977 return ret;
980 static HRESULT WINAPI EnumPt_Next(
981 IEnumConnectionPoints* This,
982 ULONG cConnections,
983 IConnectionPoint **rgcd,
984 ULONG *pcFetched)
986 EnumPt *iface = (EnumPt*)This;
988 trace("\n");
989 if (cConnections > 0 && iface->idx < iface->container->ptCount)
991 *rgcd = iface->container->pt[iface->idx];
992 IUnknown_AddRef(iface->container->pt[iface->idx]);
993 if (pcFetched)
994 *pcFetched = 1;
995 iface->idx++;
996 return S_OK;
999 return E_FAIL;
1002 static HRESULT WINAPI EnumPt_Skip(
1003 IEnumConnectionPoints* This,
1004 ULONG cConnections)
1006 trace("\n");
1007 return E_FAIL;
1010 static HRESULT WINAPI EnumPt_Reset(
1011 IEnumConnectionPoints* This)
1013 trace("\n");
1014 return E_FAIL;
1017 static HRESULT WINAPI EnumPt_Clone(
1018 IEnumConnectionPoints* This,
1019 IEnumConnectionPoints **ppEnumPt)
1021 trace("\n");
1022 return E_FAIL;
1025 static const IEnumConnectionPointsVtbl enumpt_vtbl = {
1027 EnumPt_QueryInterface,
1028 EnumPt_AddRef,
1029 EnumPt_Release,
1030 EnumPt_Next,
1031 EnumPt_Skip,
1032 EnumPt_Reset,
1033 EnumPt_Clone
1036 static HRESULT WINAPI Contain_QueryInterface(
1037 IConnectionPointContainer* This,
1038 REFIID riid,
1039 void **ppvObject)
1041 trace("\n");
1042 *ppvObject = NULL;
1044 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
1046 *ppvObject = This;
1049 if (*ppvObject)
1051 IUnknown_AddRef(This);
1052 return S_OK;
1055 trace("no interface\n");
1056 return E_NOINTERFACE;
1059 static ULONG WINAPI Contain_AddRef(
1060 IConnectionPointContainer* This)
1062 Contain *iface = (Contain*)This;
1063 return InterlockedIncrement(&iface->refCount);
1066 static ULONG WINAPI Contain_Release(
1067 IConnectionPointContainer* This)
1069 Contain *iface = (Contain*)This;
1070 ULONG ret;
1072 ret = InterlockedDecrement(&iface->refCount);
1073 if (ret == 0)
1075 if (iface->ptCount > 0)
1077 int i;
1078 for (i = 0; i < iface->ptCount; i++)
1079 IUnknown_Release(iface->pt[i]);
1080 HeapFree(GetProcessHeap(),0,iface->pt);
1082 HeapFree(GetProcessHeap(),0,This);
1084 return ret;
1087 static HRESULT WINAPI Contain_EnumConnectionPoints(
1088 IConnectionPointContainer* This,
1089 IEnumConnectionPoints **ppEnum)
1091 EnumPt *ec;
1093 trace("\n");
1094 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
1095 ec->vtbl = &enumpt_vtbl;
1096 ec->refCount = 1;
1097 ec->idx= 0;
1098 ec->container = (Contain*)This;
1099 *ppEnum = (IEnumConnectionPoints*)ec;
1101 return S_OK;
1104 static HRESULT WINAPI Contain_FindConnectionPoint(
1105 IConnectionPointContainer* This,
1106 REFIID riid,
1107 IConnectionPoint **ppCP)
1109 Contain *iface = (Contain*)This;
1110 ConPt *pt;
1111 trace("\n");
1113 if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
1115 pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
1116 pt->vtbl = &point_vtbl;
1117 pt->refCount = 1;
1118 pt->sinkCount = 0;
1119 pt->sink = NULL;
1120 pt->container = iface;
1122 if (iface->ptCount == 0)
1123 iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1124 else
1125 iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
1126 iface->pt[iface->ptCount] = (IConnectionPoint*)pt;
1127 iface->ptCount++;
1129 *ppCP = (IConnectionPoint*)pt;
1131 else
1133 *ppCP = iface->pt[0];
1134 IUnknown_AddRef((IUnknown*)*ppCP);
1137 return S_OK;
1140 static const IConnectionPointContainerVtbl contain_vtbl = {
1141 Contain_QueryInterface,
1142 Contain_AddRef,
1143 Contain_Release,
1145 Contain_EnumConnectionPoints,
1146 Contain_FindConnectionPoint
1149 static void test_IConnectionPoint(void)
1151 HRESULT rc;
1152 ULONG ref;
1153 IConnectionPoint *point;
1154 Contain *container;
1155 Disp *dispatch;
1156 DWORD cookie = 0xffffffff;
1157 DISPPARAMS params;
1158 VARIANT vars[10];
1160 if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
1162 win_skip("IConnectionPoint Apis not present\n");
1163 return;
1166 container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
1167 container->vtbl = &contain_vtbl;
1168 container->refCount = 1;
1169 container->ptCount = 0;
1170 container->pt = NULL;
1172 dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
1173 dispatch->vtbl = &disp_vtbl;
1174 dispatch->refCount = 1;
1176 rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
1177 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1178 ok(point != NULL, "returned ConnectionPoint is NULL\n");
1179 ok(cookie != 0xffffffff, "invalid cookie returned\n");
1181 rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
1182 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1184 if (pSHPackDispParams)
1186 memset(&params, 0xc0, sizeof(params));
1187 memset(vars, 0xc0, sizeof(vars));
1188 rc = pSHPackDispParams(&params, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
1189 ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
1191 rc = pIConnectionPoint_SimpleInvoke(point,0xa1,&params);
1192 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1194 else
1195 win_skip("pSHPackDispParams not present\n");
1197 rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
1198 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1200 /* MSDN says this should be required but it crashs on XP
1201 IUnknown_Release(point);
1203 ref = IUnknown_Release((IUnknown*)container);
1204 ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
1205 ref = IUnknown_Release((IUnknown*)dispatch);
1206 ok(ref == 0, "leftover IDispatch reference %i\n",ref);
1209 typedef struct _propbag
1211 const IPropertyBagVtbl *vtbl;
1212 LONG refCount;
1214 } PropBag;
1217 static HRESULT WINAPI Prop_QueryInterface(
1218 IPropertyBag* This,
1219 REFIID riid,
1220 void **ppvObject)
1222 trace("\n");
1223 *ppvObject = NULL;
1225 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPropertyBag))
1227 *ppvObject = This;
1230 if (*ppvObject)
1232 IUnknown_AddRef(This);
1233 return S_OK;
1236 trace("no interface\n");
1237 return E_NOINTERFACE;
1240 static ULONG WINAPI Prop_AddRef(
1241 IPropertyBag* This)
1243 PropBag *iface = (PropBag*)This;
1244 return InterlockedIncrement(&iface->refCount);
1247 static ULONG WINAPI Prop_Release(
1248 IPropertyBag* This)
1250 PropBag *iface = (PropBag*)This;
1251 ULONG ret;
1253 ret = InterlockedDecrement(&iface->refCount);
1254 if (ret == 0)
1255 HeapFree(GetProcessHeap(),0,This);
1256 return ret;
1259 static HRESULT WINAPI Prop_Read(
1260 IPropertyBag* This,
1261 LPCOLESTR pszPropName,
1262 VARIANT *pVar,
1263 IErrorLog *pErrorLog)
1265 V_VT(pVar) = VT_BLOB|VT_BYREF;
1266 V_BYREF(pVar) = (LPVOID)0xdeadcafe;
1267 return S_OK;
1270 static HRESULT WINAPI Prop_Write(
1271 IPropertyBag* This,
1272 LPCOLESTR pszPropName,
1273 VARIANT *pVar)
1275 return S_OK;
1279 static const IPropertyBagVtbl prop_vtbl = {
1280 Prop_QueryInterface,
1281 Prop_AddRef,
1282 Prop_Release,
1284 Prop_Read,
1285 Prop_Write
1288 static void test_SHPropertyBag_ReadLONG(void)
1290 PropBag *pb;
1291 HRESULT rc;
1292 LONG out;
1293 static const WCHAR szName1[] = {'n','a','m','e','1',0};
1295 if (!pSHPropertyBag_ReadLONG)
1297 win_skip("SHPropertyBag_ReadLONG not present\n");
1298 return;
1301 pb = HeapAlloc(GetProcessHeap(),0,sizeof(PropBag));
1302 pb->refCount = 1;
1303 pb->vtbl = &prop_vtbl;
1305 out = 0xfeedface;
1306 rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out);
1307 ok(rc == E_INVALIDARG || broken(rc == 0), "incorrect return %x\n",rc);
1308 ok(out == 0xfeedface, "value should not have changed\n");
1309 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, NULL, &out);
1310 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1311 ok(out == 0xfeedface, "value should not have changed\n");
1312 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, NULL);
1313 ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1314 ok(out == 0xfeedface, "value should not have changed\n");
1315 rc = pSHPropertyBag_ReadLONG((IPropertyBag*)pb, szName1, &out);
1316 ok(rc == DISP_E_BADVARTYPE || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
1317 ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %x\n",out);
1318 IUnknown_Release((IUnknown*)pb);
1321 START_TEST(ordinal)
1323 hShlwapi = GetModuleHandleA("shlwapi.dll");
1325 pGetAcceptLanguagesA = (void*)GetProcAddress(hShlwapi, (LPSTR)14);
1326 pSHSearchMapInt = (void*)GetProcAddress(hShlwapi, (LPSTR)198);
1327 pSHAllocShared=(void*)GetProcAddress(hShlwapi,(char*)7);
1328 pSHLockShared=(void*)GetProcAddress(hShlwapi,(char*)8);
1329 pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9);
1330 pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10);
1331 pSHPackDispParams=(void*)GetProcAddress(hShlwapi,(char*)282);
1332 pIConnectionPoint_SimpleInvoke=(void*)GetProcAddress(hShlwapi,(char*)284);
1333 pIConnectionPoint_InvokeWithCancel=(void*)GetProcAddress(hShlwapi,(char*)283);
1334 pConnectToConnectionPoint=(void*)GetProcAddress(hShlwapi,(char*)168);
1335 pSHPropertyBag_ReadLONG=(void*)GetProcAddress(hShlwapi,(char*)496);
1337 test_GetAcceptLanguagesA();
1338 test_SHSearchMapInt();
1339 test_alloc_shared();
1340 test_fdsa();
1341 test_GetShellSecurityDescriptor();
1342 test_SHPackDispParams();
1343 test_IConnectionPoint();
1344 test_SHPropertyBag_ReadLONG();