shlwapi/tests: Make test_IConnectionPoint() static.
[wine] / dlls / shlwapi / tests / ordinal.c
1 /* Unit test suite for SHLWAPI ordinal functions
2  *
3  * Copyright 2004 Jon Griffiths
4  *
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.
9  *
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.
14  *
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
18  */
19
20 #include <stdio.h>
21
22 #define COBJMACROS
23 #include "wine/test.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "oaidl.h"
29 #include "ocidl.h"
30
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);
35
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
45 static void test_GetAcceptLanguagesA(void)
46 {   HRESULT retval;
47     DWORD buffersize, buffersize2, exactsize;
48     char buffer[100];
49
50     if (!pGetAcceptLanguagesA) {
51         win_skip("GetAcceptLanguagesA is not available\n");
52         return;
53     }
54
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");
61         return;
62     }
63     trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
64         " last error %u\n", retval, buffersize, buffer, GetLastError());
65     if(retval != S_OK) {
66         trace("GetAcceptLanguagesA: skipping tests\n");
67         return;
68     }
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);
74
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());
81
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());
92
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());
99
100     buffersize = 0;
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);
107     ok(buffersize == 0,
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());
110
111     buffersize = buffersize2 = 1;
112     memset(buffer, 0, sizeof(buffer));
113     SetLastError(ERROR_SUCCESS);
114     retval = pGetAcceptLanguagesA( buffer, &buffersize);
115     switch(retval) {
116         case 0L:
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);
129             } else
130                 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
131                     retval, buffersize, buffer, GetLastError());
132             break;
133         case E_INVALIDARG:
134             ok(buffersize == 0,
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);
140             break;
141         case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win7 */
142             ok(buffersize == 0,
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());
146             break;
147         default:
148             ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
149                 retval, buffersize, buffer, GetLastError());
150             break;
151     }
152
153     buffersize = buffersize2 = exactsize;
154     memset(buffer, 0, sizeof(buffer));
155     SetLastError(ERROR_SUCCESS);
156     retval = pGetAcceptLanguagesA( buffer, &buffersize);
157     switch(retval) {
158         case 0L:
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);
165             else
166                 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
167                     retval, buffersize, buffer, GetLastError());
168             break;
169         case E_INVALIDARG:
170             ok(buffersize == 0,
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);
176             break;
177         case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win 7 */
178             ok(buffersize == 0,
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());
182             break;
183         default:
184             ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
185                 retval, buffersize, buffer, GetLastError());
186             break;
187     }
188 }
189
190 static void test_SHSearchMapInt(void)
191 {
192   int keys[8], values[8];
193   int i = 0;
194
195   if (!pSHSearchMapInt)
196     return;
197
198   memset(keys, 0, sizeof(keys));
199   memset(values, 0, sizeof(values));
200   keys[0] = 99; values[0] = 101;
201
202   /* NULL key/value lists crash native, so skip testing them */
203
204   /* 1 element */
205   i = pSHSearchMapInt(keys, values, 1, keys[0]);
206   ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
207
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);
211
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);
215
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);
220
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);
224
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);
229 }
230
231 static void test_alloc_shared(void)
232 {
233     DWORD procid;
234     HANDLE hmem;
235     int val;
236     int* p;
237     BOOL ret;
238
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());
244
245     val=0x12345678;
246     hmem=pSHAllocShared(&val,4,procid);
247     ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
248
249     p=pSHLockShared(hmem,procid);
250     ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
251     if (p!=NULL)
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());
255
256     ret = pSHFreeShared(hmem, procid);
257     ok( ret, "SHFreeShared failed: %u\n", GetLastError());
258 }
259
260 static void test_fdsa(void)
261 {
262     typedef struct
263     {
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 */
270     } FDSA_info;
271
272     BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
273                                     DWORD init_blocks);
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);
277
278     FDSA_info info;
279     int block_size = 10, init_blocks = 4, inc = 2;
280     DWORD ret;
281     char *mem;
282
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);
287
288     mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
289     memset(&info, 0, sizeof(info));
290
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);
298
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);
307
308     ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
309     ok(ret == 1, "ret = %d\n", ret);
310
311     ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
312     ok(ret == 1, "ret = %d\n", ret);
313
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);
318
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);
325
326     ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
327
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);
332
333     ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
334
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);
339
340     ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
341
342     ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
343
344     /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
345     ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
346
347
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);
351
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");
355
356
357     HeapFree(GetProcessHeap(), 0, mem);
358 }
359
360
361 typedef struct SHELL_USER_SID {
362     SID_IDENTIFIER_AUTHORITY sidAuthority;
363     DWORD                    dwUserGroupID;
364     DWORD                    dwUserID;
365 } SHELL_USER_SID, *PSHELL_USER_SID;
366 typedef struct SHELL_USER_PERMISSION {
367     SHELL_USER_SID susID;
368     DWORD          dwAccessType;
369     BOOL           fInherit;
370     DWORD          dwAccessMask;
371     DWORD          dwInheritMask;
372     DWORD          dwInheritAccessMask;
373 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
374 static void test_GetShellSecurityDescriptor(void)
375 {
376     SHELL_USER_PERMISSION supCurrentUserFull = {
377         { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
378         ACCESS_ALLOWED_ACE_TYPE, FALSE,
379         GENERIC_ALL, 0, 0 };
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,
387     };
388     SECURITY_DESCRIPTOR* psd;
389     SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
390
391     pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);
392
393     if(!pGetShellSecurityDescriptor)
394     {
395         win_skip("GetShellSecurityDescriptor not available\n");
396         return;
397     }
398
399     psd = pGetShellSecurityDescriptor(NULL, 2);
400     ok(psd==NULL ||
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");
405
406     SetLastError(0xdeadbeef);
407     psd = pGetShellSecurityDescriptor(rgsup, 2);
408     if (psd == NULL && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
409     {
410         /* The previous calls to GetShellSecurityDescriptor don't set the last error */
411         win_skip("GetShellSecurityDescriptor is not implemented\n");
412         return;
413     }
414     if (psd==INVALID_HANDLE_VALUE)
415     {
416         win_skip("GetShellSecurityDescriptor is broken on IE5\n");
417         return;
418     }
419     ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
420     if (psd!=NULL)
421     {
422         BOOL bHasDacl = FALSE, bDefaulted;
423         PACL pAcl;
424         DWORD dwRev;
425         SECURITY_DESCRIPTOR_CONTROL control;
426
427         ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
428
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");
432
433         ok(GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted), 
434             "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
435
436         ok(bHasDacl, "SD has no DACL\n");
437         if (bHasDacl)
438         {
439             ok(!bDefaulted, "DACL should not be defaulted\n");
440
441             ok(pAcl != NULL, "NULL DACL!\n");
442             if (pAcl != NULL)
443             {
444                 ACL_SIZE_INFORMATION asiSize;
445
446                 ok(IsValidAcl(pAcl), "DACL is not valid\n");
447
448                 ok(GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation),
449                         "GetAclInformation failed with error %u\n", GetLastError());
450
451                 ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
452                 if (asiSize.AceCount == 3)
453                 {
454                     ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
455
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);
461
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);
468
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);
476                 }
477             }
478         }
479
480         LocalFree(psd);
481     }
482 }
483
484 static void test_SHPackDispParams(void)
485 {
486     DISPPARAMS params;
487     VARIANT vars[10];
488     HRESULT hres;
489
490     if(!pSHPackDispParams)
491         win_skip("SHPackSidpParams not available\n");
492
493     memset(&params, 0xc0, sizeof(params));
494     memset(vars, 0xc0, sizeof(vars));
495     hres = pSHPackDispParams(&params, 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));
503
504     memset(&params, 0xc0, sizeof(params));
505     hres = pSHPackDispParams(&params, 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);
511
512     memset(vars, 0xc0, sizeof(vars));
513     memset(&params, 0xc0, sizeof(params));
514     hres = pSHPackDispParams(&params, 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));
529 }
530
531 typedef struct _disp
532 {
533     const IDispatchVtbl *vtbl;
534     LONG   refCount;
535 } Disp;
536
537 typedef struct _contain
538 {
539     const IConnectionPointContainerVtbl *vtbl;
540     LONG   refCount;
541
542     UINT  ptCount;
543     IConnectionPoint **pt;
544 } Contain;
545
546 typedef struct _cntptn
547 {
548     const IConnectionPointVtbl *vtbl;
549     LONG refCount;
550
551     Contain *container;
552     GUID  id;
553     UINT  sinkCount;
554     IUnknown **sink;
555 } ConPt;
556
557 typedef struct _enum
558 {
559     const IEnumConnectionsVtbl *vtbl;
560     LONG   refCount;
561
562     UINT idx;
563     ConPt *pt;
564 } EnumCon;
565
566 typedef struct _enumpt
567 {
568     const IEnumConnectionPointsVtbl *vtbl;
569     LONG   refCount;
570
571     int idx;
572     Contain *container;
573 } EnumPt;
574
575
576 static HRESULT WINAPI Disp_QueryInterface(
577         IDispatch* This,
578         REFIID riid,
579         void **ppvObject)
580 {
581     trace("\n");
582     *ppvObject = NULL;
583
584     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
585     {
586         *ppvObject = This;
587     }
588
589     if (*ppvObject)
590     {
591         IUnknown_AddRef(This);
592         return S_OK;
593     }
594
595     trace("no interface\n");
596     return E_NOINTERFACE;
597 }
598
599 static ULONG WINAPI Disp_AddRef(IDispatch* This)
600 {
601     Disp *iface = (Disp*)This;
602     return InterlockedIncrement(&iface->refCount);
603 }
604
605 static ULONG WINAPI Disp_Release(IDispatch* This)
606 {
607     Disp *iface = (Disp*)This;
608     ULONG ret;
609
610     ret = InterlockedDecrement(&iface->refCount);
611     if (ret == 0)
612         HeapFree(GetProcessHeap(),0,This);
613     return ret;
614 }
615
616 static HRESULT WINAPI Disp_GetTypeInfoCount(
617         IDispatch* This,
618         UINT *pctinfo)
619 {
620     trace("\n");
621     return ERROR_SUCCESS;
622 }
623
624 static HRESULT WINAPI Disp_GetTypeInfo(
625         IDispatch* This,
626         UINT iTInfo,
627         LCID lcid,
628         ITypeInfo **ppTInfo)
629 {
630     trace("\n");
631     return ERROR_SUCCESS;
632 }
633
634 static HRESULT WINAPI Disp_GetIDsOfNames(
635         IDispatch* This,
636         REFIID riid,
637         LPOLESTR *rgszNames,
638         UINT cNames,
639         LCID lcid,
640         DISPID *rgDispId)
641 {
642     trace("\n");
643     return ERROR_SUCCESS;
644 }
645
646 static HRESULT WINAPI Disp_Invoke(
647         IDispatch* This,
648         DISPID dispIdMember,
649         REFIID riid,
650         LCID lcid,
651         WORD wFlags,
652         DISPPARAMS *pDispParams,
653         VARIANT *pVarResult,
654         EXCEPINFO *pExcepInfo,
655         UINT *puArgErr)
656 {
657     trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
658
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)
664     {
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);
669     }
670     else if (dispIdMember == 0xa1)
671     {
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));
679     }
680
681     return ERROR_SUCCESS;
682 }
683
684 static const IDispatchVtbl disp_vtbl = {
685     Disp_QueryInterface,
686     Disp_AddRef,
687     Disp_Release,
688
689     Disp_GetTypeInfoCount,
690     Disp_GetTypeInfo,
691     Disp_GetIDsOfNames,
692     Disp_Invoke
693 };
694
695 static HRESULT WINAPI Enum_QueryInterface(
696         IEnumConnections* This,
697         REFIID riid,
698         void **ppvObject)
699 {
700     trace("\n");
701     *ppvObject = NULL;
702
703     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
704     {
705         *ppvObject = This;
706     }
707
708     if (*ppvObject)
709     {
710         IUnknown_AddRef(This);
711         return S_OK;
712     }
713
714     trace("no interface\n");
715     return E_NOINTERFACE;
716 }
717
718 static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
719 {
720     EnumCon *iface = (EnumCon*)This;
721     return InterlockedIncrement(&iface->refCount);
722 }
723
724 static ULONG WINAPI Enum_Release(IEnumConnections* This)
725 {
726     EnumCon *iface = (EnumCon*)This;
727     ULONG ret;
728
729     ret = InterlockedDecrement(&iface->refCount);
730     if (ret == 0)
731         HeapFree(GetProcessHeap(),0,This);
732     return ret;
733 }
734
735 static HRESULT WINAPI Enum_Next(
736         IEnumConnections* This,
737         ULONG cConnections,
738         LPCONNECTDATA rgcd,
739         ULONG *pcFetched)
740 {
741     EnumCon *iface = (EnumCon*)This;
742
743     trace("\n");
744     if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
745     {
746         rgcd->pUnk = iface->pt->sink[iface->idx];
747         IUnknown_AddRef(iface->pt->sink[iface->idx]);
748         rgcd->dwCookie=0xff;
749         if (pcFetched)
750             *pcFetched = 1;
751         iface->idx++;
752         return S_OK;
753     }
754
755     return E_FAIL;
756 }
757
758 static HRESULT WINAPI Enum_Skip(
759         IEnumConnections* This,
760         ULONG cConnections)
761 {
762     trace("\n");
763     return E_FAIL;
764 }
765
766 static HRESULT WINAPI Enum_Reset(
767         IEnumConnections* This)
768 {
769     trace("\n");
770     return E_FAIL;
771 }
772
773 static HRESULT WINAPI Enum_Clone(
774         IEnumConnections* This,
775         IEnumConnections **ppEnum)
776 {
777     trace("\n");
778     return E_FAIL;
779 }
780
781 static const IEnumConnectionsVtbl enum_vtbl = {
782
783     Enum_QueryInterface,
784     Enum_AddRef,
785     Enum_Release,
786     Enum_Next,
787     Enum_Skip,
788     Enum_Reset,
789     Enum_Clone
790 };
791
792 static HRESULT WINAPI ConPt_QueryInterface(
793         IConnectionPoint* This,
794         REFIID riid,
795         void **ppvObject)
796 {
797     trace("\n");
798     *ppvObject = NULL;
799
800     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
801     {
802         *ppvObject = This;
803     }
804
805     if (*ppvObject)
806     {
807         IUnknown_AddRef(This);
808         return S_OK;
809     }
810
811     trace("no interface\n");
812     return E_NOINTERFACE;
813 }
814
815 static ULONG WINAPI ConPt_AddRef(
816         IConnectionPoint* This)
817 {
818     ConPt *iface = (ConPt*)This;
819     return InterlockedIncrement(&iface->refCount);
820 }
821
822 static ULONG WINAPI ConPt_Release(
823         IConnectionPoint* This)
824 {
825     ConPt *iface = (ConPt*)This;
826     ULONG ret;
827
828     ret = InterlockedDecrement(&iface->refCount);
829     if (ret == 0)
830     {
831         if (iface->sinkCount > 0)
832         {
833             int i;
834             for (i = 0; i < iface->sinkCount; i++)
835             {
836                 if (iface->sink[i])
837                     IUnknown_Release(iface->sink[i]);
838             }
839             HeapFree(GetProcessHeap(),0,iface->sink);
840         }
841         HeapFree(GetProcessHeap(),0,This);
842     }
843     return ret;
844 }
845
846 static HRESULT WINAPI ConPt_GetConnectionInterface(
847         IConnectionPoint* This,
848         IID *pIID)
849 {
850     static int i = 0;
851     ConPt *iface = (ConPt*)This;
852     trace("\n");
853     if (i==0)
854     {
855         i++;
856         return E_FAIL;
857     }
858     else
859         memcpy(pIID,&iface->id,sizeof(GUID));
860     return S_OK;
861 }
862
863 static HRESULT WINAPI ConPt_GetConnectionPointContainer(
864         IConnectionPoint* This,
865         IConnectionPointContainer **ppCPC)
866 {
867     ConPt *iface = (ConPt*)This;
868     trace("\n");
869
870     *ppCPC = (IConnectionPointContainer*)iface->container;
871     return S_OK;
872 }
873
874 static HRESULT WINAPI ConPt_Advise(
875         IConnectionPoint* This,
876         IUnknown *pUnkSink,
877         DWORD *pdwCookie)
878 {
879     ConPt *iface = (ConPt*)This;
880     trace("\n");
881
882     if (iface->sinkCount == 0)
883         iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
884     else
885         iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
886     iface->sink[iface->sinkCount] = pUnkSink;
887     IUnknown_AddRef(pUnkSink);
888     iface->sinkCount++;
889     *pdwCookie = iface->sinkCount;
890     return S_OK;
891 }
892
893 static HRESULT WINAPI ConPt_Unadvise(
894         IConnectionPoint* This,
895         DWORD dwCookie)
896 {
897     ConPt *iface = (ConPt*)This;
898     trace("\n");
899
900     if (dwCookie > iface->sinkCount)
901         return E_FAIL;
902     else
903     {
904         IUnknown_Release(iface->sink[dwCookie-1]);
905         iface->sink[dwCookie-1] = NULL;
906     }
907     return S_OK;
908 }
909
910 static HRESULT WINAPI ConPt_EnumConnections(
911         IConnectionPoint* This,
912         IEnumConnections **ppEnum)
913 {
914     EnumCon *ec;
915
916     trace("\n");
917     ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
918     ec->vtbl = &enum_vtbl;
919     ec->refCount = 1;
920     ec->pt = (ConPt*)This;
921     ec->idx = 0;
922     *ppEnum = (IEnumConnections*)ec;
923
924     return S_OK;
925 }
926
927 static const IConnectionPointVtbl point_vtbl = {
928     ConPt_QueryInterface,
929     ConPt_AddRef,
930     ConPt_Release,
931
932     ConPt_GetConnectionInterface,
933     ConPt_GetConnectionPointContainer,
934     ConPt_Advise,
935     ConPt_Unadvise,
936     ConPt_EnumConnections
937 };
938
939 static HRESULT WINAPI EnumPt_QueryInterface(
940         IEnumConnectionPoints* This,
941         REFIID riid,
942         void **ppvObject)
943 {
944     trace("\n");
945     *ppvObject = NULL;
946
947     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
948     {
949         *ppvObject = This;
950     }
951
952     if (*ppvObject)
953     {
954         IUnknown_AddRef(This);
955         return S_OK;
956     }
957
958     trace("no interface\n");
959     return E_NOINTERFACE;
960 }
961
962 static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
963 {
964     EnumPt *iface = (EnumPt*)This;
965     return InterlockedIncrement(&iface->refCount);
966 }
967
968 static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
969 {
970     EnumPt *iface = (EnumPt*)This;
971     ULONG ret;
972
973     ret = InterlockedDecrement(&iface->refCount);
974     if (ret == 0)
975         HeapFree(GetProcessHeap(),0,This);
976     return ret;
977 }
978
979 static HRESULT WINAPI EnumPt_Next(
980         IEnumConnectionPoints* This,
981         ULONG cConnections,
982         IConnectionPoint **rgcd,
983         ULONG *pcFetched)
984 {
985     EnumPt *iface = (EnumPt*)This;
986
987     trace("\n");
988     if (cConnections > 0 && iface->idx < iface->container->ptCount)
989     {
990         *rgcd = iface->container->pt[iface->idx];
991         IUnknown_AddRef(iface->container->pt[iface->idx]);
992         if (pcFetched)
993             *pcFetched = 1;
994         iface->idx++;
995         return S_OK;
996     }
997
998     return E_FAIL;
999 }
1000
1001 static HRESULT WINAPI EnumPt_Skip(
1002         IEnumConnectionPoints* This,
1003         ULONG cConnections)
1004 {
1005     trace("\n");
1006     return E_FAIL;
1007 }
1008
1009 static HRESULT WINAPI EnumPt_Reset(
1010         IEnumConnectionPoints* This)
1011 {
1012     trace("\n");
1013     return E_FAIL;
1014 }
1015
1016 static HRESULT WINAPI EnumPt_Clone(
1017         IEnumConnectionPoints* This,
1018         IEnumConnectionPoints **ppEnumPt)
1019 {
1020     trace("\n");
1021     return E_FAIL;
1022 }
1023
1024 static const IEnumConnectionPointsVtbl enumpt_vtbl = {
1025
1026     EnumPt_QueryInterface,
1027     EnumPt_AddRef,
1028     EnumPt_Release,
1029     EnumPt_Next,
1030     EnumPt_Skip,
1031     EnumPt_Reset,
1032     EnumPt_Clone
1033 };
1034
1035 static HRESULT WINAPI Contain_QueryInterface(
1036         IConnectionPointContainer* This,
1037         REFIID riid,
1038         void **ppvObject)
1039 {
1040     trace("\n");
1041     *ppvObject = NULL;
1042
1043     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
1044     {
1045         *ppvObject = This;
1046     }
1047
1048     if (*ppvObject)
1049     {
1050         IUnknown_AddRef(This);
1051         return S_OK;
1052     }
1053
1054     trace("no interface\n");
1055     return E_NOINTERFACE;
1056 }
1057
1058 static ULONG WINAPI Contain_AddRef(
1059         IConnectionPointContainer* This)
1060 {
1061     Contain *iface = (Contain*)This;
1062     return InterlockedIncrement(&iface->refCount);
1063 }
1064
1065 static ULONG WINAPI Contain_Release(
1066         IConnectionPointContainer* This)
1067 {
1068     Contain *iface = (Contain*)This;
1069     ULONG ret;
1070
1071     ret = InterlockedDecrement(&iface->refCount);
1072     if (ret == 0)
1073     {
1074         if (iface->ptCount > 0)
1075         {
1076             int i;
1077             for (i = 0; i < iface->ptCount; i++)
1078                 IUnknown_Release(iface->pt[i]);
1079             HeapFree(GetProcessHeap(),0,iface->pt);
1080         }
1081         HeapFree(GetProcessHeap(),0,This);
1082     }
1083     return ret;
1084 }
1085
1086 static HRESULT WINAPI Contain_EnumConnectionPoints(
1087         IConnectionPointContainer* This,
1088         IEnumConnectionPoints **ppEnum)
1089 {
1090     EnumPt *ec;
1091
1092     trace("\n");
1093     ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
1094     ec->vtbl = &enumpt_vtbl;
1095     ec->refCount = 1;
1096     ec->idx= 0;
1097     ec->container = (Contain*)This;
1098     *ppEnum = (IEnumConnectionPoints*)ec;
1099
1100     return S_OK;
1101 }
1102
1103 static HRESULT WINAPI Contain_FindConnectionPoint(
1104         IConnectionPointContainer* This,
1105         REFIID riid,
1106         IConnectionPoint **ppCP)
1107 {
1108     Contain *iface = (Contain*)This;
1109     ConPt *pt;
1110     trace("\n");
1111
1112     if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
1113     {
1114         pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
1115         pt->vtbl = &point_vtbl;
1116         pt->refCount = 1;
1117         pt->sinkCount = 0;
1118         pt->sink = NULL;
1119         pt->container = iface;
1120
1121         if (iface->ptCount == 0)
1122             iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1123         else
1124             iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
1125         iface->pt[iface->ptCount] = (IConnectionPoint*)pt;
1126         iface->ptCount++;
1127
1128         *ppCP = (IConnectionPoint*)pt;
1129     }
1130     else
1131     {
1132         *ppCP = iface->pt[0];
1133         IUnknown_AddRef((IUnknown*)*ppCP);
1134     }
1135
1136     return S_OK;
1137 }
1138
1139 static const IConnectionPointContainerVtbl contain_vtbl = {
1140     Contain_QueryInterface,
1141     Contain_AddRef,
1142     Contain_Release,
1143
1144     Contain_EnumConnectionPoints,
1145     Contain_FindConnectionPoint
1146 };
1147
1148 static void test_IConnectionPoint(void)
1149 {
1150     HRESULT rc;
1151     ULONG ref;
1152     IConnectionPoint *point;
1153     Contain *container;
1154     Disp *dispatch;
1155     DWORD cookie = 0xffffffff;
1156     DISPPARAMS params;
1157     VARIANT vars[10];
1158
1159     if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
1160     {
1161         win_skip("IConnectionPoint Apis not present\n");
1162         return;
1163     }
1164
1165     container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
1166     container->vtbl = &contain_vtbl;
1167     container->refCount = 1;
1168     container->ptCount = 0;
1169     container->pt = NULL;
1170
1171     dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
1172     dispatch->vtbl = &disp_vtbl;
1173     dispatch->refCount = 1;
1174
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");
1179
1180     rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
1181     ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1182
1183     if (pSHPackDispParams)
1184     {
1185         memset(&params, 0xc0, sizeof(params));
1186         memset(vars, 0xc0, sizeof(vars));
1187         rc = pSHPackDispParams(&params, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
1188         ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
1189
1190         rc = pIConnectionPoint_SimpleInvoke(point,0xa1,&params);
1191         ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1192     }
1193     else
1194         win_skip("pSHPackDispParams not present\n");
1195
1196     rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
1197     ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1198
1199 /* MSDN says this should be required but it crashs on XP
1200     IUnknown_Release(point);
1201 */
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);
1206 }
1207
1208 START_TEST(ordinal)
1209 {
1210   hShlwapi = GetModuleHandleA("shlwapi.dll");
1211
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);
1222
1223   test_GetAcceptLanguagesA();
1224   test_SHSearchMapInt();
1225   test_alloc_shared();
1226   test_fdsa();
1227   test_GetShellSecurityDescriptor();
1228   test_SHPackDispParams();
1229   test_IConnectionPoint();
1230 }