kernel32/tests: Fixed size to MultiByteToWideChar.
[wine] / dlls / kernel32 / tests / actctx.c
1 /*
2  * Copyright 2007 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <wine/test.h>
20 #include <winbase.h>
21 #include <windef.h>
22 #include <winnt.h>
23 #include <winternl.h>
24 #include <winnls.h>
25 #include <stdio.h>
26
27 static BOOL   (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
28 static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
29 static BOOL   (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
30 static BOOL   (WINAPI *pFindActCtxSectionStringW)(DWORD,const GUID *,ULONG,LPCWSTR,PACTCTX_SECTION_KEYED_DATA);
31 static BOOL   (WINAPI *pGetCurrentActCtx)(HANDLE *);
32 static BOOL   (WINAPI *pQueryActCtxW)(DWORD,HANDLE,PVOID,ULONG,PVOID,SIZE_T,SIZE_T*);
33 static VOID   (WINAPI *pReleaseActCtx)(HANDLE);
34
35 static const char* strw(LPCWSTR x)
36 {
37     static char buffer[1024];
38     char*       p = buffer;
39
40     if (!x) return "(nil)";
41     else while ((*p++ = *x++));
42     return buffer;
43 }
44
45 static const char manifest1[] =
46 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
47 "<assemblyIdentity version=\"1.0.0.0\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
48 "</assembly>";
49
50 static const char manifest2[] =
51 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
52 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\">"
53 "</assemblyIdentity>"
54 "<dependency>"
55 "<dependentAssembly>"
56 "<assemblyIdentity type=\"win32\" name=\"testdep\" version=\"6.5.4.3\" processorArchitecture=\"x86\">"
57 "</assemblyIdentity>"
58 "</dependentAssembly>"
59 "</dependency>"
60 "</assembly>";
61
62 static const char manifest3[] =
63 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
64 "<assemblyIdentity version=\"1.2.3.4\"  name=\"Wine.Test\" type=\"win32\""
65 " publicKeyToken=\"6595b6414666f1df\" />"
66 "<file name=\"testlib.dll\">"
67 "<windowClass>wndClass</windowClass>"
68 "</file>"
69 "</assembly>";
70
71 static const char manifest4[] =
72 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
73 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\">"
74 "</assemblyIdentity>"
75 "<dependency>"
76 "<dependentAssembly>"
77 "<assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.Common-Controls\" "
78     "version=\"6.0.0.0\" processorArchitecture=\"x86\" publicKeyToken=\"6595b64144ccf1df\">"
79 "</assemblyIdentity>"
80 "</dependentAssembly>"
81 "</dependency>"
82 "</assembly>";
83
84 static const char testdep_manifest1[] =
85 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
86 "<assemblyIdentity type=\"win32\" name=\"testdep\" version=\"6.5.4.3\" processorArchitecture=\"x86\"/>"
87 "</assembly>";
88
89 static const char testdep_manifest2[] =
90 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
91 "<assemblyIdentity type=\"win32\" name=\"testdep\" version=\"6.5.4.3\" processorArchitecture=\"x86\" />"
92 "<file name=\"testlib.dll\"></file>"
93 "<file name=\"testlib2.dll\" hash=\"63c978c2b53d6cf72b42fb7308f9af12ab19ec53\" hashalg=\"SHA1\" />"
94 "</assembly>";
95
96 static const char testdep_manifest3[] =
97 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"> "
98 "<assemblyIdentity type=\"win32\" name=\"testdep\" version=\"6.5.4.3\" processorArchitecture=\"x86\"/>"
99 "<file name=\"testlib.dll\"/>"
100 "<file name=\"testlib2.dll\" hash=\"63c978c2b53d6cf72b42fb7308f9af12ab19ec53\" hashalg=\"SHA1\">"
101 "<windowClass>wndClass</windowClass>"
102 "<windowClass>wndClass2</windowClass>"
103 "</file>"
104 "</assembly>";
105
106 static const char wrong_manifest1[] =
107 "<assembly manifestVersion=\"1.0\">"
108 "<assemblyIdentity version=\"1.0.0.0\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
109 "</assembly>";
110
111 static const char wrong_manifest2[] =
112 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\">"
113 "<assemblyIdentity version=\"1.0.0.0\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
114 "</assembly>";
115
116 static const char wrong_manifest3[] =
117 "<assembly test=\"test\" xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
118 "<assemblyIdentity version=\"1.0.0.0\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
119 "</assembly>";
120
121 static const char wrong_manifest4[] =
122 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
123 "<assemblyIdentity version=\"1.0.0.0\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
124 "<test></test>"
125 "</assembly>";
126
127 static const char wrong_manifest5[] =
128 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
129 "<assemblyIdentity version=\"1.0.0.0\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
130 "</assembly>"
131 "<test></test>";
132
133 static const char wrong_manifest6[] =
134 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v5\" manifestVersion=\"1.0\">"
135 "<assemblyIdentity version=\"1.0.0.0\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
136 "</assembly>";
137
138 static const char wrong_manifest7[] =
139 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
140 "<assemblyIdentity type=\"win32\" name=\"testdep\" version=\"6.5.4.3\" processorArchitecture=\"x86\" />"
141 "<file name=\"testlib.dll\" hash=\"63c978c2b53d6cf72b42fb7308f9af12ab19ec5\" hashalg=\"SHA1\" />"
142 "</assembly>";
143
144 static const char wrong_manifest8[] =
145 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
146 "<assemblyIdentity version=\"1.2.3.4\"  name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
147 "<file></file>"
148 "</assembly>";
149
150 static const char wrong_depmanifest1[] =
151 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
152 "<assemblyIdentity type=\"win32\" name=\"testdep\" version=\"6.5.4.4\" processorArchitecture=\"x86\" />"
153 "</assembly>";
154
155 static const WCHAR testlib_dll[] =
156     {'t','e','s','t','l','i','b','.','d','l','l',0};
157 static const WCHAR testlib2_dll[] =
158     {'t','e','s','t','l','i','b','2','.','d','l','l',0};
159 static const WCHAR wndClassW[] =
160     {'w','n','d','C','l','a','s','s',0};
161 static const WCHAR wndClass2W[] =
162     {'w','n','d','C','l','a','s','s','2',0};
163 static const WCHAR acr_manifest[] =
164     {'a','c','r','.','m','a','n','i','f','e','s','t',0};
165
166 static WCHAR app_dir[MAX_PATH], exe_path[MAX_PATH];
167 static WCHAR app_manifest_path[MAX_PATH], manifest_path[MAX_PATH], depmanifest_path[MAX_PATH];
168
169 static int strcmp_aw(LPCWSTR strw, const char *stra)
170 {
171     WCHAR buf[1024];
172
173     if (!stra) return 1;
174     MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
175     return lstrcmpW(strw, buf);
176 }
177
178 static DWORD strlen_aw(const char *str)
179 {
180     return MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0) - 1;
181 }
182
183 static BOOL create_manifest_file(const char *filename, const char *manifest,
184                                  const char *depfile, const char *depmanifest)
185 {
186     DWORD size;
187     HANDLE file;
188     WCHAR path[MAX_PATH];
189
190     MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
191     GetFullPathNameW(path, sizeof(manifest_path)/sizeof(WCHAR), manifest_path, NULL);
192
193     file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
194                        FILE_ATTRIBUTE_NORMAL, NULL);
195     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
196     if(file == INVALID_HANDLE_VALUE)
197         return FALSE;
198     WriteFile(file, manifest, strlen(manifest), &size, NULL);
199     CloseHandle(file);
200
201     if (depmanifest)
202     {
203         MultiByteToWideChar( CP_ACP, 0, depfile, -1, path, MAX_PATH );
204         GetFullPathNameW(path, sizeof(depmanifest_path)/sizeof(WCHAR), depmanifest_path, NULL);
205         file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
206                            FILE_ATTRIBUTE_NORMAL, NULL);
207         ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
208         if(file == INVALID_HANDLE_VALUE)
209             return FALSE;
210         WriteFile(file, depmanifest, strlen(depmanifest), &size, NULL);
211         CloseHandle(file);
212     }
213     return TRUE;
214 }
215
216 typedef struct {
217     ULONG format_version;
218     ULONG assembly_cnt;
219     ULONG root_manifest_type;
220     LPWSTR root_manifest_path;
221     ULONG root_config_type;
222     ULONG app_dir_type;
223     LPCWSTR app_dir;
224 } detailed_info_t;
225
226 static const detailed_info_t detailed_info0 = {
227     0, 0, 0, NULL, 0, 0, NULL
228 };
229
230 static const detailed_info_t detailed_info1 = {
231     1, 1, ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE, manifest_path,
232     ACTIVATION_CONTEXT_PATH_TYPE_NONE, ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE,
233     app_dir,
234 };
235
236 static const detailed_info_t detailed_info1_child = {
237     1, 1, ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE, app_manifest_path,
238     ACTIVATION_CONTEXT_PATH_TYPE_NONE, ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE,
239     app_dir,
240 };
241
242 static const detailed_info_t detailed_info2 = {
243     1, 2, ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE, manifest_path,
244     ACTIVATION_CONTEXT_PATH_TYPE_NONE, ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE,
245     app_dir,
246 };
247
248 static void test_detailed_info(HANDLE handle, const detailed_info_t *exinfo)
249 {
250     ACTIVATION_CONTEXT_DETAILED_INFORMATION detailed_info_tmp, *detailed_info;
251     SIZE_T size, exsize, retsize;
252     BOOL b;
253
254     exsize = sizeof(ACTIVATION_CONTEXT_DETAILED_INFORMATION)
255         + (exinfo->root_manifest_path ? (lstrlenW(exinfo->root_manifest_path)+1)*sizeof(WCHAR):0)
256         + (exinfo->app_dir ? (lstrlenW(app_dir)+1)*sizeof(WCHAR) : 0);
257
258     if(exsize != sizeof(ACTIVATION_CONTEXT_DETAILED_INFORMATION)) {
259         size = 0xdeadbeef;
260         b = pQueryActCtxW(0, handle, NULL,
261                           ActivationContextDetailedInformation, &detailed_info_tmp,
262                           sizeof(detailed_info_tmp), &size);
263         ok(!b, "QueryActCtx succeeded\n");
264         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() = %u\n", GetLastError());
265         ok(size == exsize, "size=%ld, expected %ld\n", size, exsize);
266     }else {
267         size = sizeof(ACTIVATION_CONTEXT_DETAILED_INFORMATION);
268     }
269
270     detailed_info = HeapAlloc(GetProcessHeap(), 0, size);
271     memset(detailed_info, 0xfe, size);
272     b = pQueryActCtxW(0, handle, NULL,
273                       ActivationContextDetailedInformation, detailed_info,
274                       size, &retsize);
275     ok(b, "QueryActCtx failed: %u\n", GetLastError());
276     ok(retsize == exsize, "size=%ld, expected %ld\n", retsize, exsize);
277
278     ok(detailed_info->dwFlags == 0, "detailed_info->dwFlags=%x\n", detailed_info->dwFlags);
279     ok(detailed_info->ulFormatVersion == exinfo->format_version,
280        "detailed_info->ulFormatVersion=%u, expected %u\n", detailed_info->ulFormatVersion,
281        exinfo->format_version);
282     ok(detailed_info->ulAssemblyCount == exinfo->assembly_cnt,
283        "detailed_info->ulAssemblyCount=%u, expected %u\n", detailed_info->ulAssemblyCount,
284        exinfo->assembly_cnt);
285     ok(detailed_info->ulRootManifestPathType == exinfo->root_manifest_type,
286        "detailed_info->ulRootManifestPathType=%u, expected %u\n",
287        detailed_info->ulRootManifestPathType, exinfo->root_manifest_type);
288     ok(detailed_info->ulRootManifestPathChars ==
289        (exinfo->root_manifest_path ? lstrlenW(exinfo->root_manifest_path) : 0),
290        "detailed_info->ulRootManifestPathChars=%u, expected %u\n",
291        detailed_info->ulRootManifestPathChars,
292        exinfo->root_manifest_path ?lstrlenW(exinfo->root_manifest_path) : 0);
293     ok(detailed_info->ulRootConfigurationPathType == exinfo->root_config_type,
294        "detailed_info->ulRootConfigurationPathType=%u, expected %u\n",
295        detailed_info->ulRootConfigurationPathType, exinfo->root_config_type);
296     ok(detailed_info->ulRootConfigurationPathChars == 0,
297        "detailed_info->ulRootConfigurationPathChars=%d\n", detailed_info->ulRootConfigurationPathChars);
298     ok(detailed_info->ulAppDirPathType == exinfo->app_dir_type,
299        "detailed_info->ulAppDirPathType=%u, expected %u\n", detailed_info->ulAppDirPathType,
300        exinfo->app_dir_type);
301     ok(detailed_info->ulAppDirPathChars == (exinfo->app_dir ? lstrlenW(app_dir) : 0),
302        "detailed_info->ulAppDirPathChars=%u, expected %u\n",
303        detailed_info->ulAppDirPathChars, exinfo->app_dir ? lstrlenW(app_dir) : 0);
304     if(exinfo->root_manifest_path) {
305         ok(detailed_info->lpRootManifestPath != NULL, "detailed_info->lpRootManifestPath == NULL\n");
306         if(detailed_info->lpRootManifestPath)
307             ok(!lstrcmpiW(detailed_info->lpRootManifestPath, exinfo->root_manifest_path),
308                "unexpected detailed_info->lpRootManifestPath\n");
309     }else {
310         ok(detailed_info->lpRootManifestPath == NULL, "detailed_info->lpRootManifestPath != NULL\n");
311     }
312     ok(detailed_info->lpRootConfigurationPath == NULL,
313        "detailed_info->lpRootConfigurationPath=%p\n", detailed_info->lpRootConfigurationPath);
314     if(exinfo->app_dir) {
315         ok(detailed_info->lpAppDirPath != NULL, "detailed_info->lpAppDirPath == NULL\n");
316         if(detailed_info->lpAppDirPath)
317             ok(!lstrcmpiW(app_dir, detailed_info->lpAppDirPath),
318                "unexpected detailed_info->lpAppDirPath %s\n",strw(detailed_info->lpAppDirPath));
319     }else {
320         ok(detailed_info->lpAppDirPath == NULL, "detailed_info->lpAppDirPath != NULL\n");
321     }
322
323     HeapFree(GetProcessHeap(), 0, detailed_info);
324 }
325
326 typedef struct {
327     ULONG flags;
328 /*    ULONG manifest_path_type; FIXME */
329     LPCWSTR manifest_path;
330     LPCSTR encoded_assembly_id;
331     BOOL has_assembly_dir;
332 } info_in_assembly;
333
334 static const info_in_assembly manifest1_info = {
335     1, manifest_path,
336     "Wine.Test,type=\"win32\",version=\"1.0.0.0\"",
337     FALSE
338 };
339
340 static const info_in_assembly manifest1_child_info = {
341     1, app_manifest_path,
342     "Wine.Test,type=\"win32\",version=\"1.0.0.0\"",
343     FALSE
344 };
345
346 static const info_in_assembly manifest2_info = {
347     1, manifest_path,
348     "Wine.Test,type=\"win32\",version=\"1.2.3.4\"",
349     FALSE
350 };
351
352 static const info_in_assembly manifest3_info = {
353     1, manifest_path,
354     "Wine.Test,publicKeyToken=\"6595b6414666f1df\",type=\"win32\",version=\"1.2.3.4\"",
355     FALSE
356 };
357
358 static const info_in_assembly manifest4_info = {
359     1, manifest_path,
360     "Wine.Test,type=\"win32\",version=\"1.2.3.4\"",
361     FALSE
362 };
363
364 static const info_in_assembly depmanifest1_info = {
365     0x10, depmanifest_path,
366     "testdep,processorArchitecture=\"x86\","
367     "type=\"win32\",version=\"6.5.4.3\"",
368     TRUE
369 };
370
371 static const info_in_assembly depmanifest2_info = {
372     0x10, depmanifest_path,
373     "testdep,processorArchitecture=\"x86\","
374     "type=\"win32\",version=\"6.5.4.3\"",
375     TRUE
376 };
377
378 static const info_in_assembly depmanifest3_info = {
379     0x10, depmanifest_path,
380     "testdep,processorArchitecture=\"x86\",type=\"win32\",version=\"6.5.4.3\"",
381     TRUE
382 };
383
384 static const info_in_assembly manifest_comctrl_info = {
385     0, NULL, NULL, TRUE /* These values may differ between Windows installations */
386 };
387
388 static void test_info_in_assembly(HANDLE handle, DWORD id, const info_in_assembly *exinfo)
389 {
390     ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info, info_tmp;
391     SIZE_T size, exsize;
392     ULONG len;
393     BOOL b;
394
395     exsize = sizeof(ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION);
396     if (exinfo->manifest_path) exsize += (lstrlenW(exinfo->manifest_path)+1) * sizeof(WCHAR);
397     if (exinfo->encoded_assembly_id) exsize += (strlen_aw(exinfo->encoded_assembly_id) + 1) * sizeof(WCHAR);
398
399     size = 0xdeadbeef;
400     b = pQueryActCtxW(0, handle, &id,
401                       AssemblyDetailedInformationInActivationContext, &info_tmp,
402                       sizeof(info_tmp), &size);
403     ok(!b, "QueryActCtx succeeded\n");
404     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() = %u\n", GetLastError());
405
406     ok(size >= exsize, "size=%lu, expected %lu\n", size, exsize);
407
408     if (size == 0xdeadbeef)
409     {
410         skip("bad size\n");
411         return;
412     }
413
414     info = HeapAlloc(GetProcessHeap(), 0, size);
415     memset(info, 0xfe, size);
416
417     size = 0xdeadbeef;
418     b = pQueryActCtxW(0, handle, &id,
419                       AssemblyDetailedInformationInActivationContext, info, size, &size);
420     ok(b, "QueryActCtx failed: %u\n", GetLastError());
421     if (!exinfo->manifest_path)
422         exsize += info->ulManifestPathLength + sizeof(WCHAR);
423     if (!exinfo->encoded_assembly_id)
424         exsize += info->ulEncodedAssemblyIdentityLength + sizeof(WCHAR);
425     if (exinfo->has_assembly_dir)
426         exsize += info->ulAssemblyDirectoryNameLength + sizeof(WCHAR);
427     ok(size == exsize, "size=%lu, expected %lu\n", size, exsize);
428
429     if (0)  /* FIXME: flags meaning unknown */
430     {
431         ok((info->ulFlags) == exinfo->flags, "info->ulFlags = %x, expected %x\n",
432            info->ulFlags, exinfo->flags);
433     }
434     if(exinfo->encoded_assembly_id) {
435         len = strlen_aw(exinfo->encoded_assembly_id)*sizeof(WCHAR);
436         ok(info->ulEncodedAssemblyIdentityLength == len,
437            "info->ulEncodedAssemblyIdentityLength = %u, expected %u\n",
438            info->ulEncodedAssemblyIdentityLength, len);
439     } else {
440         ok(info->ulEncodedAssemblyIdentityLength != 0,
441            "info->ulEncodedAssemblyIdentityLength == 0\n");
442     }
443     ok(info->ulManifestPathType == ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE,
444        "info->ulManifestPathType = %x\n", info->ulManifestPathType);
445     if(exinfo->manifest_path) {
446         len = lstrlenW(exinfo->manifest_path)*sizeof(WCHAR);
447         ok(info->ulManifestPathLength == len, "info->ulManifestPathLength = %u, expected %u\n",
448            info->ulManifestPathLength, len);
449     } else {
450         ok(info->ulManifestPathLength != 0, "info->ulManifestPathLength == 0\n");
451     }
452
453     ok(info->ulPolicyPathType == ACTIVATION_CONTEXT_PATH_TYPE_NONE,
454        "info->ulPolicyPathType = %x\n", info->ulPolicyPathType);
455     ok(info->ulPolicyPathLength == 0,
456        "info->ulPolicyPathLength = %u, expected 0\n", info->ulPolicyPathLength);
457     ok(info->ulMetadataSatelliteRosterIndex == 0, "info->ulMetadataSatelliteRosterIndex = %x\n",
458        info->ulMetadataSatelliteRosterIndex);
459     ok(info->ulManifestVersionMajor == 1,"info->ulManifestVersionMajor = %x\n",
460        info->ulManifestVersionMajor);
461     ok(info->ulManifestVersionMinor == 0, "info->ulManifestVersionMinor = %x\n",
462        info->ulManifestVersionMinor);
463     ok(info->ulPolicyVersionMajor == 0, "info->ulPolicyVersionMajor = %x\n",
464        info->ulPolicyVersionMajor);
465     ok(info->ulPolicyVersionMinor == 0, "info->ulPolicyVersionMinor = %x\n",
466        info->ulPolicyVersionMinor);
467     if(exinfo->has_assembly_dir)
468         ok(info->ulAssemblyDirectoryNameLength != 0,
469            "info->ulAssemblyDirectoryNameLength == 0\n");
470     else
471         ok(info->ulAssemblyDirectoryNameLength == 0,
472            "info->ulAssemblyDirectoryNameLength != 0\n");
473
474     ok(info->lpAssemblyEncodedAssemblyIdentity != NULL,
475        "info->lpAssemblyEncodedAssemblyIdentity == NULL\n");
476     if(info->lpAssemblyEncodedAssemblyIdentity && exinfo->encoded_assembly_id) {
477         ok(!strcmp_aw(info->lpAssemblyEncodedAssemblyIdentity, exinfo->encoded_assembly_id),
478            "unexpected info->lpAssemblyEncodedAssemblyIdentity %s / %s\n",
479            strw(info->lpAssemblyEncodedAssemblyIdentity), exinfo->encoded_assembly_id);
480     }
481     if(exinfo->manifest_path) {
482         ok(info->lpAssemblyManifestPath != NULL, "info->lpAssemblyManifestPath == NULL\n");
483         if(info->lpAssemblyManifestPath)
484             ok(!lstrcmpiW(info->lpAssemblyManifestPath, exinfo->manifest_path),
485                "unexpected info->lpAssemblyManifestPath\n");
486     }else {
487         ok(info->lpAssemblyManifestPath != NULL, "info->lpAssemblyManifestPath == NULL\n");
488     }
489
490     ok(info->lpAssemblyPolicyPath == NULL, "info->lpAssemblyPolicyPath != NULL\n");
491     if(info->lpAssemblyPolicyPath)
492         ok(*(WORD*)info->lpAssemblyPolicyPath == 0, "info->lpAssemblyPolicyPath is not empty\n");
493     if(exinfo->has_assembly_dir)
494         ok(info->lpAssemblyDirectoryName != NULL, "info->lpAssemblyDirectoryName == NULL\n");
495     else
496         ok(info->lpAssemblyDirectoryName == NULL, "info->lpAssemblyDirectoryName = %s\n",
497            strw(info->lpAssemblyDirectoryName));
498 }
499
500 static void test_file_info(HANDLE handle, ULONG assid, ULONG fileid, LPCWSTR filename)
501 {
502     ASSEMBLY_FILE_DETAILED_INFORMATION *info, info_tmp;
503     ACTIVATION_CONTEXT_QUERY_INDEX index = {assid, fileid};
504     SIZE_T size, exsize;
505     BOOL b;
506
507     exsize = sizeof(ASSEMBLY_FILE_DETAILED_INFORMATION)
508         +(lstrlenW(filename)+1)*sizeof(WCHAR);
509
510     size = 0xdeadbeef;
511     b = pQueryActCtxW(0, handle, &index,
512                       FileInformationInAssemblyOfAssemblyInActivationContext, &info_tmp,
513                       sizeof(info_tmp), &size);
514     ok(!b, "QueryActCtx succeeded\n");
515     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() = %u\n", GetLastError());
516     ok(size == exsize, "size=%lu, expected %lu\n", size, exsize);
517
518     if(size == 0xdeadbeef)
519     {
520         skip("bad size\n");
521         return;
522     }
523
524     info = HeapAlloc(GetProcessHeap(), 0, size);
525     memset(info, 0xfe, size);
526
527     b = pQueryActCtxW(0, handle, &index,
528                       FileInformationInAssemblyOfAssemblyInActivationContext, info, size, &size);
529     ok(b, "QueryActCtx failed: %u\n", GetLastError());
530     ok(!size, "size=%lu, expected 0\n", size);
531
532     ok(info->ulFlags == 2, "info->ulFlags=%x, expected 2\n", info->ulFlags);
533     ok(info->ulFilenameLength == lstrlenW(filename)*sizeof(WCHAR),
534        "info->ulFilenameLength=%u, expected %u\n",
535        info->ulFilenameLength, lstrlenW(filename)*sizeof(WCHAR));
536     ok(info->ulPathLength == 0, "info->ulPathLength=%u\n", info->ulPathLength);
537     ok(info->lpFileName != NULL, "info->lpFileName == NULL\n");
538     if(info->lpFileName)
539         ok(!lstrcmpiW(info->lpFileName, filename), "unexpected info->lpFileName\n");
540     ok(info->lpFilePath == NULL, "info->lpFilePath != NULL\n");
541 }
542
543 static HANDLE test_create(const char *file, const char *manifest)
544 {
545     ACTCTXW actctx;
546     HANDLE handle;
547     WCHAR path[MAX_PATH];
548
549     MultiByteToWideChar( CP_ACP, 0, file, -1, path, MAX_PATH );
550     memset(&actctx, 0, sizeof(ACTCTXW));
551     actctx.cbSize = sizeof(ACTCTXW);
552     actctx.lpSource = path;
553
554     handle = pCreateActCtxW(&actctx);
555     ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError());
556
557     ok(actctx.cbSize == sizeof(actctx), "actctx.cbSize=%d\n", actctx.cbSize);
558     ok(actctx.dwFlags == 0, "actctx.=%d\n", actctx.dwFlags);
559     ok(actctx.lpSource == path, "actctx.lpSource=%p\n", actctx.lpSource);
560     ok(actctx.wProcessorArchitecture == 0,
561        "actctx.wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
562     ok(actctx.wLangId == 0, "actctx.wLangId=%d\n", actctx.wLangId);
563     ok(actctx.lpAssemblyDirectory == NULL,
564        "actctx.lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
565     ok(actctx.lpResourceName == NULL, "actctx.lpResourceName=%p\n", actctx.lpResourceName);
566     ok(actctx.lpApplicationName == NULL, "actctx.lpApplocationName=%p\n",
567        actctx.lpApplicationName);
568     ok(actctx.hModule == NULL, "actctx.hModule=%p\n", actctx.hModule);
569
570     return handle;
571 }
572
573 static void test_create_and_fail(const char *manifest, const char *depmanifest, int todo)
574 {
575     ACTCTXW actctx;
576     HANDLE handle;
577     WCHAR path[MAX_PATH];
578
579     MultiByteToWideChar( CP_ACP, 0, "bad.manifest", -1, path, MAX_PATH );
580     memset(&actctx, 0, sizeof(ACTCTXW));
581     actctx.cbSize = sizeof(ACTCTXW);
582     actctx.lpSource = path;
583
584     create_manifest_file("bad.manifest", manifest, "testdep.manifest", depmanifest);
585     handle = pCreateActCtxW(&actctx);
586     if (todo) todo_wine
587     {
588         ok(handle == INVALID_HANDLE_VALUE, "handle != INVALID_HANDLE_VALUE\n");
589         ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX, "GetLastError == %u\n", GetLastError());
590     }
591     else
592     {
593         ok(handle == INVALID_HANDLE_VALUE, "handle != INVALID_HANDLE_VALUE\n");
594         ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX, "GetLastError == %u\n", GetLastError());
595     }
596     if (handle != INVALID_HANDLE_VALUE) pReleaseActCtx( handle );
597     DeleteFileA("bad.manifest");
598     DeleteFileA("testdep.manifest");
599 }
600
601 static void test_create_fail(void)
602 {
603     ACTCTXW actctx;
604     HANDLE handle;
605     WCHAR path[MAX_PATH];
606
607     MultiByteToWideChar( CP_ACP, 0, "nonexistent.manifest", -1, path, MAX_PATH );
608     memset(&actctx, 0, sizeof(ACTCTXW));
609     actctx.cbSize = sizeof(ACTCTXW);
610     actctx.lpSource = path;
611
612     handle = pCreateActCtxW(&actctx);
613     ok(handle == INVALID_HANDLE_VALUE, "handle != INVALID_HANDLE_VALUE\n");
614     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError == %u\n", GetLastError());
615
616     trace("wrong_manifest1\n");
617     test_create_and_fail(wrong_manifest1, NULL, 0 );
618     trace("wrong_manifest2\n");
619     test_create_and_fail(wrong_manifest2, NULL, 0 );
620     trace("wrong_manifest3\n");
621     test_create_and_fail(wrong_manifest3, NULL, 1 );
622     trace("wrong_manifest4\n");
623     test_create_and_fail(wrong_manifest4, NULL, 1 );
624     trace("wrong_manifest5\n");
625     test_create_and_fail(wrong_manifest5, NULL, 0 );
626     trace("wrong_manifest6\n");
627     test_create_and_fail(wrong_manifest6, NULL, 0 );
628     trace("wrong_manifest7\n");
629     test_create_and_fail(wrong_manifest7, NULL, 1 );
630     trace("wrong_manifest8\n");
631     test_create_and_fail(wrong_manifest8, NULL, 0 );
632     trace("manifest2\n");
633     test_create_and_fail(manifest2, NULL, 0 );
634     trace("manifest2+depmanifest1\n");
635     test_create_and_fail(manifest2, wrong_depmanifest1, 0 );
636 }
637
638 static void test_find_dll_redirection(HANDLE handle, LPCWSTR libname, ULONG exid)
639 {
640     ACTCTX_SECTION_KEYED_DATA data;
641     DWORD *p;
642     BOOL ret;
643
644     memset(&data, 0xfe, sizeof(data));
645     data.cbSize = sizeof(data);
646
647     ret = pFindActCtxSectionStringW(0, NULL,
648                                     ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
649                                     libname, &data);
650     ok(ret, "FindActCtxSectionStringW failed: %u\n", GetLastError());
651     if(!ret)
652     {
653         skip("couldn't find %s\n",strw(libname));
654         return;
655     }
656
657     ok(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize);
658     ok(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion);
659     ok(data.lpData != NULL, "data.lpData == NULL\n");
660     ok(data.ulLength == 20, "data.ulLength=%u\n", data.ulLength);
661
662     p = data.lpData;
663     if(ret && p) todo_wine {
664         ok(p[0] == 20 && p[1] == 2 && p[2] == 0 && p[3] == 0 && p[4] == 0,
665            "wrong data %u,%u,%u,%u,%u\n",p[0], p[1], p[2], p[3], p[4]);
666     }
667
668     ok(data.lpSectionGlobalData == NULL, "data.lpSectionGlobalData != NULL\n");
669     ok(data.ulSectionGlobalDataLength == 0, "data.ulSectionGlobalDataLength=%u\n",
670        data.ulSectionGlobalDataLength);
671     ok(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n");
672     /* ok(data.ulSectionTotalLength == ??, "data.ulSectionTotalLength=%u\n",
673        data.ulSectionTotalLength); */
674     ok(data.hActCtx == NULL, "data.hActCtx=%p\n", data.hActCtx);
675     ok(data.ulAssemblyRosterIndex == exid, "data.ulAssemblyRosterIndex=%u, expected %u\n",
676        data.ulAssemblyRosterIndex, exid);
677
678     memset(&data, 0xfe, sizeof(data));
679     data.cbSize = sizeof(data);
680
681     ret = pFindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
682                                     ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
683                                     libname, &data);
684     ok(ret, "FindActCtxSectionStringW failed: %u\n", GetLastError());
685     if(!ret)
686     {
687         skip("couldn't find\n");
688         return;
689     }
690
691     ok(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize);
692     ok(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion);
693     ok(data.lpData != NULL, "data.lpData == NULL\n");
694     ok(data.ulLength == 20, "data.ulLength=%u\n", data.ulLength);
695     ok(data.lpSectionGlobalData == NULL, "data.lpSectionGlobalData != NULL\n");
696     ok(data.ulSectionGlobalDataLength == 0, "data.ulSectionGlobalDataLength=%u\n",
697        data.ulSectionGlobalDataLength);
698     ok(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n");
699     /* ok(data.ulSectionTotalLength == ?? , "data.ulSectionTotalLength=%u\n",
700        data.ulSectionTotalLength); */
701     ok(data.hActCtx == handle, "data.hActCtx=%p\n", data.hActCtx);
702     ok(data.ulAssemblyRosterIndex == exid, "data.ulAssemblyRosterIndex=%u, expected %u\n",
703        data.ulAssemblyRosterIndex, exid);
704
705     pReleaseActCtx(handle);
706 }
707
708 static void test_find_window_class(HANDLE handle, LPCWSTR clsname, ULONG exid)
709 {
710     ACTCTX_SECTION_KEYED_DATA data;
711     BOOL ret;
712
713     memset(&data, 0xfe, sizeof(data));
714     data.cbSize = sizeof(data);
715
716     ret = pFindActCtxSectionStringW(0, NULL,
717                                     ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
718                                     clsname, &data);
719     ok(ret, "FindActCtxSectionStringW failed: %u\n", GetLastError());
720     if(!ret)
721     {
722         skip("couldn't find\n");
723         return;
724     }
725
726     ok(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize);
727     ok(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion);
728     ok(data.lpData != NULL, "data.lpData == NULL\n");
729     /* ok(data.ulLength == ??, "data.ulLength=%u\n", data.ulLength); */
730     ok(data.lpSectionGlobalData == NULL, "data.lpSectionGlobalData != NULL\n");
731     ok(data.ulSectionGlobalDataLength == 0, "data.ulSectionGlobalDataLength=%u\n",
732        data.ulSectionGlobalDataLength);
733     ok(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n");
734     /* ok(data.ulSectionTotalLength == 0, "data.ulSectionTotalLength=%u\n",
735        data.ulSectionTotalLength); FIXME */
736     ok(data.hActCtx == NULL, "data.hActCtx=%p\n", data.hActCtx);
737     ok(data.ulAssemblyRosterIndex == exid, "data.ulAssemblyRosterIndex=%u, expected %u\n",
738        data.ulAssemblyRosterIndex, exid);
739
740     memset(&data, 0xfe, sizeof(data));
741     data.cbSize = sizeof(data);
742
743     ret = pFindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
744                                     ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
745                                     clsname, &data);
746     ok(ret, "FindActCtxSectionStringW failed: %u\n", GetLastError());
747     if(!ret)
748     {
749         skip("couldn't find\n");
750         return;
751     }
752
753     ok(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize);
754     ok(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion);
755     ok(data.lpData != NULL, "data.lpData == NULL\n");
756     /* ok(data.ulLength == ??, "data.ulLength=%u\n", data.ulLength); FIXME */
757     ok(data.lpSectionGlobalData == NULL, "data.lpSectionGlobalData != NULL\n");
758     ok(data.ulSectionGlobalDataLength == 0, "data.ulSectionGlobalDataLength=%u\n",
759        data.ulSectionGlobalDataLength);
760     ok(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n");
761     /* ok(data.ulSectionTotalLength == 0, "data.ulSectionTotalLength=%u\n",
762        data.ulSectionTotalLength); FIXME */
763     ok(data.hActCtx == handle, "data.hActCtx=%p\n", data.hActCtx);
764     ok(data.ulAssemblyRosterIndex == exid, "data.ulAssemblyRosterIndex=%u, expected %u\n",
765        data.ulAssemblyRosterIndex, exid);
766
767     pReleaseActCtx(handle);
768 }
769
770 static void test_find_string_fail(void)
771 {
772     ACTCTX_SECTION_KEYED_DATA data = {sizeof(data)};
773     BOOL ret;
774
775     ret = pFindActCtxSectionStringW(0, NULL, 100, testlib_dll, &data);
776     ok(!ret, "FindActCtxSectionStringW succeeded\n");
777     ok(GetLastError() == ERROR_SXS_SECTION_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
778
779     ret = pFindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
780                                     testlib2_dll, &data);
781     ok(!ret, "FindActCtxSectionStringW succeeded\n");
782     ok(GetLastError() == ERROR_SXS_KEY_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
783
784     ret = pFindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
785                                     testlib_dll, NULL);
786     ok(!ret, "FindActCtxSectionStringW succeeded\n");
787     ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError()=%u\n", GetLastError());
788
789     ret = pFindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
790                                     NULL, &data);
791     ok(!ret, "FindActCtxSectionStringW succeeded\n");
792     ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError()=%u\n", GetLastError());
793
794     data.cbSize = 0;
795     ret = pFindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
796                                     testlib_dll, &data);
797     ok(!ret, "FindActCtxSectionStringW succeeded\n");
798     ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError()=%u\n", GetLastError());
799
800     data.cbSize = 35;
801     ret = pFindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
802                                     testlib_dll, &data);
803     ok(!ret, "FindActCtxSectionStringW succeeded\n");
804     ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError()=%u\n", GetLastError());
805 }
806
807 static void test_actctx(void)
808 {
809     ULONG_PTR cookie;
810     HANDLE handle;
811     BOOL b;
812
813     test_create_fail();
814
815     trace("default actctx\n");
816
817     b = pGetCurrentActCtx(&handle);
818     ok(handle == NULL, "handle = %p, expected NULL\n", handle);
819     ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
820     if(b) {
821         test_detailed_info(handle, &detailed_info0);
822         pReleaseActCtx(handle);
823     }
824
825     if(!create_manifest_file("test1.manifest", manifest1, NULL, NULL)) {
826         skip("Could not create manifest file\n");
827         return;
828     }
829
830     trace("manifest1\n");
831
832     handle = test_create("test1.manifest", manifest1);
833     DeleteFileA("test1.manifest");
834     if(handle != INVALID_HANDLE_VALUE) {
835         test_detailed_info(handle, &detailed_info1);
836         test_info_in_assembly(handle, 1, &manifest1_info);
837
838         b = CloseHandle(handle);
839         ok(!b, "CloseHandle succeeded\n");
840         ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() == %u\n", GetLastError());
841
842         pReleaseActCtx(handle);
843     }
844
845     if(!create_manifest_file("test2.manifest", manifest2, "testdep.manifest", testdep_manifest1)) {
846         skip("Could not create manifest file\n");
847         return;
848     }
849
850     trace("manifest2 depmanifest1\n");
851
852     handle = test_create("test2.manifest", manifest2);
853     DeleteFileA("test2.manifest");
854     DeleteFileA("testdep.manifest");
855     if(handle != INVALID_HANDLE_VALUE) {
856         test_detailed_info(handle, &detailed_info2);
857         test_info_in_assembly(handle, 1, &manifest2_info);
858         test_info_in_assembly(handle, 2, &depmanifest1_info);
859         pReleaseActCtx(handle);
860     }
861
862     if(!create_manifest_file("test3.manifest", manifest2, "testdep.manifest", testdep_manifest2)) {
863         skip("Could not create manifest file\n");
864         return;
865     }
866
867     trace("manifest2 depmanifest2\n");
868
869     handle = test_create("test3.manifest", manifest2);
870     DeleteFileA("test3.manifest");
871     DeleteFileA("testdep.manifest");
872     if(handle != INVALID_HANDLE_VALUE) {
873         test_detailed_info(handle, &detailed_info2);
874         test_info_in_assembly(handle, 1, &manifest2_info);
875         test_info_in_assembly(handle, 2, &depmanifest2_info);
876         test_file_info(handle, 1, 0, testlib_dll);
877         test_file_info(handle, 1, 1, testlib2_dll);
878
879         b = pActivateActCtx(handle, &cookie);
880         ok(b, "ActivateActCtx failed: %u\n", GetLastError());
881         test_find_dll_redirection(handle, testlib_dll, 2);
882         test_find_dll_redirection(handle, testlib2_dll, 2);
883         b = pDeactivateActCtx(0, cookie);
884         ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
885
886         pReleaseActCtx(handle);
887     }
888
889     trace("manifest2 depmanifest3\n");
890
891     if(!create_manifest_file("test2-3.manifest", manifest2, "testdep.manifest", testdep_manifest3)) {
892         skip("Could not create manifest file\n");
893         return;
894     }
895
896     handle = test_create("test2-3.manifest", manifest2);
897     DeleteFileA("test2-3.manifest");
898     DeleteFileA("testdep.manifest");
899     if(handle != INVALID_HANDLE_VALUE) {
900         test_detailed_info(handle, &detailed_info2);
901         test_info_in_assembly(handle, 1, &manifest2_info);
902         test_info_in_assembly(handle, 2, &depmanifest3_info);
903         test_file_info(handle, 1, 0, testlib_dll);
904         test_file_info(handle, 1, 1, testlib2_dll);
905
906         b = pActivateActCtx(handle, &cookie);
907         ok(b, "ActivateActCtx failed: %u\n", GetLastError());
908         test_find_dll_redirection(handle, testlib_dll, 2);
909         test_find_dll_redirection(handle, testlib2_dll, 2);
910         test_find_window_class(handle, wndClassW, 2);
911         test_find_window_class(handle, wndClass2W, 2);
912         b = pDeactivateActCtx(0, cookie);
913         ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
914
915         pReleaseActCtx(handle);
916     }
917
918     trace("manifest3\n");
919
920     if(!create_manifest_file("test3.manifest", manifest3, NULL, NULL)) {
921         skip("Could not create manifest file\n");
922         return;
923     }
924
925     handle = test_create("test3.manifest", manifest3);
926     DeleteFileA("test3.manifest");
927     if(handle != INVALID_HANDLE_VALUE) {
928         test_detailed_info(handle, &detailed_info1);
929         test_info_in_assembly(handle, 1, &manifest3_info);
930         test_file_info(handle, 0, 0, testlib_dll);
931
932         b = pActivateActCtx(handle, &cookie);
933         ok(b, "ActivateActCtx failed: %u\n", GetLastError());
934         test_find_dll_redirection(handle, testlib_dll, 1);
935         test_find_dll_redirection(handle, testlib_dll, 1);
936         test_find_string_fail();
937         b = pDeactivateActCtx(0, cookie);
938         ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
939
940         pReleaseActCtx(handle);
941     }
942
943     trace("manifest4\n");
944
945     if(!create_manifest_file("test4.manifest", manifest4, NULL, NULL)) {
946         skip("Could not create manifest file\n");
947         return;
948     }
949
950     handle = test_create("test4.manifest", manifest4);
951     DeleteFileA("test4.manifest");
952     DeleteFileA("testdep.manifest");
953     if(handle != INVALID_HANDLE_VALUE) {
954         test_detailed_info(handle, &detailed_info2);
955         test_info_in_assembly(handle, 1, &manifest4_info);
956         test_info_in_assembly(handle, 2, &manifest_comctrl_info);
957         pReleaseActCtx(handle);
958     }
959 }
960
961 static void test_app_manifest(void)
962 {
963     HANDLE handle;
964     BOOL b;
965
966     trace("child process manifest1\n");
967
968     b = pGetCurrentActCtx(&handle);
969     ok(handle == NULL, "handle != NULL\n");
970     ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
971     if(b) {
972         test_detailed_info(handle, &detailed_info1_child);
973         test_info_in_assembly(handle, 1, &manifest1_child_info);
974         pReleaseActCtx(handle);
975     }
976 }
977
978 static void run_child_process(void)
979 {
980     char cmdline[MAX_PATH];
981     char path[MAX_PATH];
982     char **argv;
983     PROCESS_INFORMATION pi;
984     STARTUPINFO si = { 0 };
985
986     GetModuleFileNameA(NULL, path, MAX_PATH);
987     strcat(path, ".manifest");
988     if(!create_manifest_file(path, manifest1, NULL, NULL)) {
989         skip("Could not create manifest file\n");
990         return;
991     }
992
993     si.cb = sizeof(si);
994     winetest_get_mainargs( &argv );
995     sprintf(cmdline, "%s %s manifest1", argv[0], argv[1]);
996     ok(CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
997                      &si, &pi) != 0, "Could not create process: %u\n", GetLastError());
998     CloseHandle(pi.hThread);
999
1000     WaitForSingleObject(pi.hProcess, INFINITE);
1001     CloseHandle(pi.hProcess);
1002     DeleteFileA(path);
1003 }
1004
1005 static void init_paths(void)
1006 {
1007     LPWSTR ptr;
1008
1009     static const WCHAR dot_manifest[] = {'.','M','a','n','i','f','e','s','t',0};
1010
1011     GetModuleFileNameW(NULL, exe_path, sizeof(exe_path)/sizeof(WCHAR));
1012     lstrcpyW(app_dir, exe_path);
1013     for(ptr=app_dir+lstrlenW(app_dir); *ptr != '\\'; ptr--);
1014     ptr[1] = 0;
1015
1016     GetModuleFileNameW(NULL, app_manifest_path, sizeof(app_manifest_path)/sizeof(WCHAR));
1017     lstrcpyW(app_manifest_path+lstrlenW(app_manifest_path), dot_manifest);
1018 }
1019
1020 static BOOL init_funcs(void)
1021 {
1022     HMODULE hKernel32 = GetModuleHandle("kernel32");
1023
1024 #define X(f) if (!(p##f = (void*)GetProcAddress(hKernel32, #f))) return FALSE;
1025     X(ActivateActCtx);
1026     X(CreateActCtxW);
1027     X(DeactivateActCtx);
1028     X(FindActCtxSectionStringW);
1029     X(GetCurrentActCtx);
1030     X(QueryActCtxW);
1031     X(ReleaseActCtx);
1032 #undef X
1033
1034     return TRUE;
1035 }
1036
1037 START_TEST(actctx)
1038 {
1039     int argc;
1040     char **argv;
1041
1042     argc = winetest_get_mainargs(&argv);
1043
1044     init_paths();
1045     if (!init_funcs())
1046     {
1047         skip("Couldn't load kernel32\n");
1048         return;
1049     }
1050
1051     if(argc > 2 && !strcmp(argv[2], "manifest1")) {
1052         test_app_manifest();
1053         return;
1054     }
1055
1056     test_actctx();
1057     run_child_process();
1058 }