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