shlwapi: Remove superfluous pointer casts.
[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 #include "wine/test.h"
23 #include "winbase.h"
24 #include "winerror.h"
25 #include "winuser.h"
26 #include "ole2.h"
27 #include "oaidl.h"
28
29 /* Function ptrs for ordinal calls */
30 static HMODULE hShlwapi;
31 static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
32 static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
33
34 static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
35 static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
36 static BOOL   (WINAPI *pSHUnlockShared)(LPVOID);
37 static BOOL   (WINAPI *pSHFreeShared)(HANDLE,DWORD);
38 static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
39
40 static void test_GetAcceptLanguagesA(void)
41 {   HRESULT retval;
42     DWORD buffersize, buffersize2, exactsize;
43     char buffer[100];
44
45     if (!pGetAcceptLanguagesA) {
46         win_skip("GetAcceptLanguagesA is not available\n");
47         return;
48     }
49
50     buffersize = sizeof(buffer);
51     memset(buffer, 0, sizeof(buffer));
52     SetLastError(ERROR_SUCCESS);
53     retval = pGetAcceptLanguagesA( buffer, &buffersize);
54     if (!retval && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
55         win_skip("GetAcceptLanguagesA is not implemented\n");
56         return;
57     }
58     trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
59         " last error %u\n", retval, buffersize, buffer, GetLastError());
60     if(retval != S_OK) {
61         trace("GetAcceptLanguagesA: skipping tests\n");
62         return;
63     }
64     ok( (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()) || 
65         (ERROR_CLASS_DOES_NOT_EXIST == GetLastError()) ||
66         (ERROR_PROC_NOT_FOUND == GetLastError()) ||
67         (ERROR_SUCCESS == GetLastError()), "last error set to %u\n", GetLastError());
68     exactsize = strlen(buffer);
69
70     SetLastError(ERROR_SUCCESS);
71     retval = pGetAcceptLanguagesA( NULL, NULL);
72     ok(retval == E_FAIL ||
73        retval == E_INVALIDARG, /* w2k8 */
74        "function result wrong: got %08x; expected E_FAIL\n", retval);
75     ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
76
77     buffersize = sizeof(buffer);
78     SetLastError(ERROR_SUCCESS);
79     retval = pGetAcceptLanguagesA( NULL, &buffersize);
80     ok(retval == E_FAIL ||
81        retval == E_INVALIDARG, /* w2k8 */
82        "function result wrong: got %08x; expected E_FAIL\n", retval);
83     ok(buffersize == sizeof(buffer) ||
84        buffersize == 0, /* w2k8*/
85        "buffersize was changed and is not 0; size (%d))\n", buffersize);
86     ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
87
88     SetLastError(ERROR_SUCCESS);
89     retval = pGetAcceptLanguagesA( buffer, NULL);
90     ok(retval == E_FAIL ||
91        retval == E_INVALIDARG, /* w2k8 */
92        "function result wrong: got %08x; expected E_FAIL\n", retval);
93     ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
94
95     buffersize = 0;
96     memset(buffer, 0, sizeof(buffer));
97     SetLastError(ERROR_SUCCESS);
98     retval = pGetAcceptLanguagesA( buffer, &buffersize);
99     ok(retval == E_FAIL ||
100        retval == E_INVALIDARG, /* w2k8 */
101        "function result wrong: got %08x; expected E_FAIL\n", retval);
102     ok(buffersize == 0,
103        "buffersize wrong(changed) got %08x; expected 0 (2nd parameter; not on Win2k)\n", buffersize);
104     ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
105
106     buffersize = buffersize2 = 1;
107     memset(buffer, 0, sizeof(buffer));
108     SetLastError(ERROR_SUCCESS);
109     retval = pGetAcceptLanguagesA( buffer, &buffersize);
110     switch(retval) {
111         case 0L:
112             if(buffersize == exactsize) {
113             ok( (ERROR_SUCCESS == GetLastError()) ||
114                 (ERROR_PROC_NOT_FOUND == GetLastError()) || (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()),
115                 "last error wrong: got %u; expected ERROR_SUCCESS(NT4)/"
116                 "ERROR_PROC_NOT_FOUND(NT4)/ERROR_NO_IMPERSONATION_TOKEN(XP)\n", GetLastError());
117             ok(exactsize == strlen(buffer),
118                  "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), exactsize);
119             } else if((buffersize +1) == buffersize2) {
120                 ok(ERROR_SUCCESS == GetLastError(),
121                     "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
122                 ok(buffersize == strlen(buffer),
123                     "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
124             } else
125                 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
126                     retval, buffersize, buffer, GetLastError());
127             break;
128         case E_INVALIDARG:
129             ok(buffersize == 0,
130                "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
131             ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
132                "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
133             ok(buffersize2 == strlen(buffer),
134                "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
135             break;
136         default:
137             ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
138                 retval, buffersize, buffer, GetLastError());
139             break;
140     }
141
142     buffersize = buffersize2 = exactsize;
143     memset(buffer, 0, sizeof(buffer));
144     SetLastError(ERROR_SUCCESS);
145     retval = pGetAcceptLanguagesA( buffer, &buffersize);
146     switch(retval) {
147         case 0L:
148             ok(ERROR_SUCCESS == GetLastError(),
149                  "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
150             if((buffersize == exactsize) /* XP */ ||
151                ((buffersize +1)== exactsize) /* 98 */)
152                 ok(buffersize == strlen(buffer),
153                     "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
154             else
155                 ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
156                     retval, buffersize, buffer, GetLastError());
157             break;
158         case E_INVALIDARG:
159             ok(buffersize == 0,
160                "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
161             ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
162                "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
163             ok(buffersize2 == strlen(buffer),
164                "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
165             break;
166         default:
167             ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
168                 retval, buffersize, buffer, GetLastError());
169             break;
170     }
171 }
172
173 static void test_SHSearchMapInt(void)
174 {
175   int keys[8], values[8];
176   int i = 0;
177
178   if (!pSHSearchMapInt)
179     return;
180
181   memset(keys, 0, sizeof(keys));
182   memset(values, 0, sizeof(values));
183   keys[0] = 99; values[0] = 101;
184
185   /* NULL key/value lists crash native, so skip testing them */
186
187   /* 1 element */
188   i = pSHSearchMapInt(keys, values, 1, keys[0]);
189   ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
190
191   /* Key doesn't exist */
192   i = pSHSearchMapInt(keys, values, 1, 100);
193   ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);
194
195   /* Len = 0 => not found */
196   i = pSHSearchMapInt(keys, values, 0, keys[0]);
197   ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);
198
199   /* 2 elements, len = 1 */
200   keys[1] = 98; values[1] = 102;
201   i = pSHSearchMapInt(keys, values, 1, keys[1]);
202   ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);
203
204   /* 2 elements, len = 2 */
205   i = pSHSearchMapInt(keys, values, 2, keys[1]);
206   ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);
207
208   /* Searches forward */
209   keys[2] = 99; values[2] = 103;
210   i = pSHSearchMapInt(keys, values, 3, keys[0]);
211   ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
212 }
213
214 static void test_alloc_shared(void)
215 {
216     DWORD procid;
217     HANDLE hmem;
218     int val;
219     int* p;
220     BOOL ret;
221
222     procid=GetCurrentProcessId();
223     hmem=pSHAllocShared(NULL,10,procid);
224     ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
225     ret = pSHFreeShared(hmem, procid);
226     ok( ret, "SHFreeShared failed: %u\n", GetLastError());
227
228     val=0x12345678;
229     hmem=pSHAllocShared(&val,4,procid);
230     ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
231
232     p=pSHLockShared(hmem,procid);
233     ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
234     if (p!=NULL)
235         ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
236     ret = pSHUnlockShared(p);
237     ok( ret, "SHUnlockShared failed: %u\n", GetLastError());
238
239     ret = pSHFreeShared(hmem, procid);
240     ok( ret, "SHFreeShared failed: %u\n", GetLastError());
241 }
242
243 static void test_fdsa(void)
244 {
245     typedef struct
246     {
247         DWORD num_items;       /* Number of elements inserted */
248         void *mem;             /* Ptr to array */
249         DWORD blocks_alloced;  /* Number of elements allocated */
250         BYTE inc;              /* Number of elements to grow by when we need to expand */
251         BYTE block_size;       /* Size in bytes of an element */
252         BYTE flags;            /* Flags */
253     } FDSA_info;
254
255     BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
256                                     DWORD init_blocks);
257     BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
258     DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
259     BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);
260
261     FDSA_info info;
262     int block_size = 10, init_blocks = 4, inc = 2;
263     DWORD ret;
264     char *mem;
265
266     pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
267     pFDSA_Destroy    = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
268     pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
269     pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);
270
271     mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
272     memset(&info, 0, sizeof(info));
273
274     ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
275     ok(info.num_items == 0, "num_items = %d\n", info.num_items);
276     ok(info.mem == mem, "mem = %p\n", info.mem);
277     ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
278     ok(info.inc == inc, "inc = %d\n", info.inc);
279     ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
280     ok(info.flags == 0, "flags = %d\n", info.flags);
281
282     ret = pFDSA_InsertItem(&info, 1234, "1234567890");
283     ok(ret == 0, "ret = %d\n", ret);
284     ok(info.num_items == 1, "num_items = %d\n", info.num_items);
285     ok(info.mem == mem, "mem = %p\n", info.mem);
286     ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
287     ok(info.inc == inc, "inc = %d\n", info.inc);
288     ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
289     ok(info.flags == 0, "flags = %d\n", info.flags);
290
291     ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
292     ok(ret == 1, "ret = %d\n", ret);
293
294     ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
295     ok(ret == 1, "ret = %d\n", ret);
296
297     ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
298     ok(ret == 0, "ret = %d\n", ret);
299     ok(info.mem == mem, "mem = %p\n", info.mem);
300     ok(info.flags == 0, "flags = %d\n", info.flags);
301
302     /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
303     ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
304     ok(ret == 0, "ret = %d\n", ret);
305     ok(info.mem != mem, "mem = %p\n", info.mem);
306     ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
307     ok(info.flags == 0x1, "flags = %d\n", info.flags);
308
309     ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
310
311     ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
312     ok(info.mem != mem, "mem = %p\n", info.mem);
313     ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
314     ok(info.flags == 0x1, "flags = %d\n", info.flags);
315
316     ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
317
318     ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
319     ok(info.mem != mem, "mem = %p\n", info.mem);
320     ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
321     ok(info.flags == 0x1, "flags = %d\n", info.flags);
322
323     ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
324
325     ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
326
327     /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
328     ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
329
330
331     /* When Initialize is called with inc = 0, set it to 1 */
332     ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
333     ok(info.inc == 1, "inc = %d\n", info.inc);
334
335     /* This time, because shlwapi hasn't had to allocate memory
336        internally, Destroy rets non-zero */
337     ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");
338
339
340     HeapFree(GetProcessHeap(), 0, mem);
341 }
342
343
344 typedef struct SHELL_USER_SID {
345     SID_IDENTIFIER_AUTHORITY sidAuthority;
346     DWORD                    dwUserGroupID;
347     DWORD                    dwUserID;
348 } SHELL_USER_SID, *PSHELL_USER_SID;
349 typedef struct SHELL_USER_PERMISSION {
350     SHELL_USER_SID susID;
351     DWORD          dwAccessType;
352     BOOL           fInherit;
353     DWORD          dwAccessMask;
354     DWORD          dwInheritMask;
355     DWORD          dwInheritAccessMask;
356 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
357 static void test_GetShellSecurityDescriptor(void)
358 {
359     SHELL_USER_PERMISSION supCurrentUserFull = {
360         { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
361         ACCESS_ALLOWED_ACE_TYPE, FALSE,
362         GENERIC_ALL, 0, 0 };
363 #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
364     SHELL_USER_PERMISSION supEveryoneDenied = {
365         { {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 },
366         ACCESS_DENIED_ACE_TYPE, TRUE,
367         GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ };
368     PSHELL_USER_PERMISSION rgsup[2] = {
369         &supCurrentUserFull, &supEveryoneDenied,
370     };
371     SECURITY_DESCRIPTOR* psd;
372     SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
373
374     pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);
375
376     if(!pGetShellSecurityDescriptor)
377     {
378         win_skip("GetShellSecurityDescriptor not available\n");
379         return;
380     }
381
382     psd = pGetShellSecurityDescriptor(NULL, 2);
383     ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
384     psd = pGetShellSecurityDescriptor(rgsup, 0);
385     ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
386
387     SetLastError(0xdeadbeef);
388     psd = pGetShellSecurityDescriptor(rgsup, 2);
389     if (psd == NULL && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
390     {
391         /* The previous calls to GetShellSecurityDescriptor don't set the last error */
392         win_skip("GetShellSecurityDescriptor is not implemented\n");
393         return;
394     }
395     ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
396     if (psd!=NULL)
397     {
398         BOOL bHasDacl = FALSE, bDefaulted;
399         PACL pAcl;
400         DWORD dwRev;
401         SECURITY_DESCRIPTOR_CONTROL control;
402
403         ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
404
405         ok(GetSecurityDescriptorControl(psd, &control, &dwRev),
406                 "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
407         ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");
408
409         ok(GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted), 
410             "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
411
412         ok(bHasDacl, "SD has no DACL\n");
413         if (bHasDacl)
414         {
415             ok(!bDefaulted, "DACL should not be defaulted\n");
416
417             ok(pAcl != NULL, "NULL DACL!\n");
418             if (pAcl != NULL)
419             {
420                 ACL_SIZE_INFORMATION asiSize;
421
422                 ok(IsValidAcl(pAcl), "DACL is not valid\n");
423
424                 ok(GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation),
425                         "GetAclInformation failed with error %u\n", GetLastError());
426
427                 ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
428                 if (asiSize.AceCount == 3)
429                 {
430                     ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
431
432                     ok(GetAce(pAcl, 0, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
433                     ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, 
434                             "Invalid ACE type %d\n", paaa->Header.AceType); 
435                     ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
436                     ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);
437
438                     ok(GetAce(pAcl, 1, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
439                     ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE, 
440                             "Invalid ACE type %d\n", paaa->Header.AceType); 
441                     /* first one of two ACEs generated from inheritable entry - without inheritance */
442                     ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
443                     ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);
444
445                     ok(GetAce(pAcl, 2, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
446                     ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE, 
447                             "Invalid ACE type %d\n", paaa->Header.AceType); 
448                     /* second ACE - with inheritance */
449                     ok(paaa->Header.AceFlags == MY_INHERITANCE,
450                             "Invalid ACE flags %x\n", paaa->Header.AceFlags);
451                     ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
452                 }
453             }
454         }
455
456         LocalFree(psd);
457     }
458 }
459
460 static void test_SHPackDispParams(void)
461 {
462     DISPPARAMS params;
463     VARIANT vars[10];
464     HRESULT hres;
465
466     if(!pSHPackDispParams)
467         skip("SHPackSidpParams not available\n");
468
469     memset(&params, 0xc0, sizeof(params));
470     memset(vars, 0xc0, sizeof(vars));
471     hres = pSHPackDispParams(&params, vars, 1, VT_I4, 0xdeadbeef);
472     ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
473     ok(params.cArgs == 1, "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 == vars, "params.rgvarg = %p\n", params.rgvarg);
477     ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars));
478     ok(V_DISPATCH(vars) == (void*)0xdeadbeef, "failed\n");
479
480     memset(&params, 0xc0, sizeof(params));
481     hres = pSHPackDispParams(&params, NULL, 0, 0);
482     ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
483     ok(params.cArgs == 0, "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 == NULL, "params.rgvarg = %p\n", params.rgvarg);
487
488     memset(vars, 0xc0, sizeof(vars));
489     memset(&params, 0xc0, sizeof(params));
490     hres = pSHPackDispParams(&params, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10,
491             VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef);
492     ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
493     ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs);
494     ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
495     ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
496     ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
497     ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars));
498     ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars));
499     ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1));
500     ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1));
501     ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2));
502     ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2));
503     ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3));
504     ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
505 }
506
507 START_TEST(ordinal)
508 {
509   hShlwapi = GetModuleHandleA("shlwapi.dll");
510
511   pGetAcceptLanguagesA = (void*)GetProcAddress(hShlwapi, (LPSTR)14);
512   pSHSearchMapInt = (void*)GetProcAddress(hShlwapi, (LPSTR)198);
513   pSHAllocShared=(void*)GetProcAddress(hShlwapi,(char*)7);
514   pSHLockShared=(void*)GetProcAddress(hShlwapi,(char*)8);
515   pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9);
516   pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10);
517   pSHPackDispParams=(void*)GetProcAddress(hShlwapi,(char*)282);
518
519   test_GetAcceptLanguagesA();
520   test_SHSearchMapInt();
521   test_alloc_shared();
522   test_fdsa();
523   test_GetShellSecurityDescriptor();
524   test_SHPackDispParams();
525 }