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