kernel32: Log more information in case of a test failure, and don't run tests that...
[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));
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
855 static void test_basic_info(HANDLE handle)
856 {
857     ACTIVATION_CONTEXT_BASIC_INFORMATION basic;
858     SIZE_T size;
859     BOOL b;
860
861     b = pQueryActCtxW(0, handle, NULL,
862                           ActivationContextBasicInformation, &basic,
863                           sizeof(basic), &size);
864
865     ok (b,"ActivationContextBasicInformation failed\n");
866     ok (size == sizeof(ACTIVATION_CONTEXT_BASIC_INFORMATION),"size mismatch\n");
867     ok (basic.dwFlags == 0, "unexpected flags %x\n",basic.dwFlags);
868     ok (basic.hActCtx == handle, "unexpected handle\n");
869
870     b = pQueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, handle, NULL,
871                           ActivationContextBasicInformation, &basic,
872                           sizeof(basic), &size);
873     if (handle)
874     {
875         ok (!b,"ActivationContextBasicInformation succeeded\n");
876         ok (size == 0,"size mismatch\n");
877         ok (GetLastError() == ERROR_INVALID_PARAMETER, "Wrong last error\n");
878         ok (basic.dwFlags == 0, "unexpected flags %x\n",basic.dwFlags);
879         ok (basic.hActCtx == handle, "unexpected handle\n");
880     }
881     else
882     {
883         ok (b,"ActivationContextBasicInformation failed\n");
884         ok (size == sizeof(ACTIVATION_CONTEXT_BASIC_INFORMATION),"size mismatch\n");
885         ok (basic.dwFlags == 0, "unexpected flags %x\n",basic.dwFlags);
886         ok (basic.hActCtx == handle, "unexpected handle\n");
887     }
888 }
889
890 static void test_actctx(void)
891 {
892     ULONG_PTR cookie;
893     HANDLE handle;
894     BOOL b;
895
896     test_create_fail();
897
898     trace("default actctx\n");
899
900     b = pGetCurrentActCtx(&handle);
901     ok(handle == NULL, "handle = %p, expected NULL\n", handle);
902     ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
903     if(b) {
904         test_basic_info(handle);
905         test_detailed_info(handle, &detailed_info0);
906         pReleaseActCtx(handle);
907     }
908
909     if(!create_manifest_file("test1.manifest", manifest1, -1, NULL, NULL)) {
910         skip("Could not create manifest file\n");
911         return;
912     }
913
914     trace("manifest1\n");
915
916     handle = test_create("test1.manifest", manifest1);
917     DeleteFileA("test1.manifest");
918     if(handle != INVALID_HANDLE_VALUE) {
919         test_basic_info(handle);
920         test_detailed_info(handle, &detailed_info1);
921         test_info_in_assembly(handle, 1, &manifest1_info);
922
923         if (pIsDebuggerPresent && !pIsDebuggerPresent())
924         {
925             /* CloseHandle will generate an exception if a debugger is present */
926             b = CloseHandle(handle);
927             ok(!b, "CloseHandle succeeded\n");
928             ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() == %u\n", GetLastError());
929         }
930
931         pReleaseActCtx(handle);
932     }
933
934     if(!create_manifest_file("test2.manifest", manifest2, -1, "testdep.manifest", testdep_manifest1)) {
935         skip("Could not create manifest file\n");
936         return;
937     }
938
939     trace("manifest2 depmanifest1\n");
940
941     handle = test_create("test2.manifest", manifest2);
942     DeleteFileA("test2.manifest");
943     DeleteFileA("testdep.manifest");
944     if(handle != INVALID_HANDLE_VALUE) {
945         test_basic_info(handle);
946         test_detailed_info(handle, &detailed_info2);
947         test_info_in_assembly(handle, 1, &manifest2_info);
948         test_info_in_assembly(handle, 2, &depmanifest1_info);
949         pReleaseActCtx(handle);
950     }
951
952     if(!create_manifest_file("test3.manifest", manifest2, -1, "testdep.manifest", testdep_manifest2)) {
953         skip("Could not create manifest file\n");
954         return;
955     }
956
957     trace("manifest2 depmanifest2\n");
958
959     handle = test_create("test3.manifest", manifest2);
960     DeleteFileA("test3.manifest");
961     DeleteFileA("testdep.manifest");
962     if(handle != INVALID_HANDLE_VALUE) {
963         test_basic_info(handle);
964         test_detailed_info(handle, &detailed_info2);
965         test_info_in_assembly(handle, 1, &manifest2_info);
966         test_info_in_assembly(handle, 2, &depmanifest2_info);
967         test_file_info(handle, 1, 0, testlib_dll);
968         test_file_info(handle, 1, 1, testlib2_dll);
969
970         b = pActivateActCtx(handle, &cookie);
971         ok(b, "ActivateActCtx failed: %u\n", GetLastError());
972         test_find_dll_redirection(handle, testlib_dll, 2);
973         test_find_dll_redirection(handle, testlib2_dll, 2);
974         b = pDeactivateActCtx(0, cookie);
975         ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
976
977         pReleaseActCtx(handle);
978     }
979
980     trace("manifest2 depmanifest3\n");
981
982     if(!create_manifest_file("test2-3.manifest", manifest2, -1, "testdep.manifest", testdep_manifest3)) {
983         skip("Could not create manifest file\n");
984         return;
985     }
986
987     handle = test_create("test2-3.manifest", manifest2);
988     DeleteFileA("test2-3.manifest");
989     DeleteFileA("testdep.manifest");
990     if(handle != INVALID_HANDLE_VALUE) {
991         test_basic_info(handle);
992         test_detailed_info(handle, &detailed_info2);
993         test_info_in_assembly(handle, 1, &manifest2_info);
994         test_info_in_assembly(handle, 2, &depmanifest3_info);
995         test_file_info(handle, 1, 0, testlib_dll);
996         test_file_info(handle, 1, 1, testlib2_dll);
997
998         b = pActivateActCtx(handle, &cookie);
999         ok(b, "ActivateActCtx failed: %u\n", GetLastError());
1000         test_find_dll_redirection(handle, testlib_dll, 2);
1001         test_find_dll_redirection(handle, testlib2_dll, 2);
1002         test_find_window_class(handle, wndClassW, 2);
1003         test_find_window_class(handle, wndClass2W, 2);
1004         b = pDeactivateActCtx(0, cookie);
1005         ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
1006
1007         pReleaseActCtx(handle);
1008     }
1009
1010     trace("manifest3\n");
1011
1012     if(!create_manifest_file("test3.manifest", manifest3, -1, NULL, NULL)) {
1013         skip("Could not create manifest file\n");
1014         return;
1015     }
1016
1017     handle = test_create("test3.manifest", manifest3);
1018     DeleteFileA("test3.manifest");
1019     if(handle != INVALID_HANDLE_VALUE) {
1020         test_basic_info(handle);
1021         test_detailed_info(handle, &detailed_info1);
1022         test_info_in_assembly(handle, 1, &manifest3_info);
1023         test_file_info(handle, 0, 0, testlib_dll);
1024
1025         b = pActivateActCtx(handle, &cookie);
1026         ok(b, "ActivateActCtx failed: %u\n", GetLastError());
1027         test_find_dll_redirection(handle, testlib_dll, 1);
1028         test_find_dll_redirection(handle, testlib_dll, 1);
1029         test_find_string_fail();
1030         b = pDeactivateActCtx(0, cookie);
1031         ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
1032
1033         pReleaseActCtx(handle);
1034     }
1035
1036     trace("manifest4\n");
1037
1038     if(!create_manifest_file("test4.manifest", manifest4, -1, NULL, NULL)) {
1039         skip("Could not create manifest file\n");
1040         return;
1041     }
1042
1043     handle = test_create("test4.manifest", manifest4);
1044     DeleteFileA("test4.manifest");
1045     DeleteFileA("testdep.manifest");
1046     if(handle != INVALID_HANDLE_VALUE) {
1047         test_basic_info(handle);
1048         test_detailed_info(handle, &detailed_info2);
1049         test_info_in_assembly(handle, 1, &manifest4_info);
1050         test_info_in_assembly(handle, 2, &manifest_comctrl_info);
1051         pReleaseActCtx(handle);
1052     }
1053
1054     trace("manifest1 in subdir\n");
1055
1056     CreateDirectoryW(work_dir_subdir, NULL);
1057     if (SetCurrentDirectoryW(work_dir_subdir))
1058     {
1059         if(!create_manifest_file("..\\test1.manifest", manifest1, -1, NULL, NULL)) {
1060             skip("Could not create manifest file\n");
1061             return;
1062         }
1063         handle = test_create("..\\test1.manifest", manifest1);
1064         DeleteFileA("..\\test1.manifest");
1065         if(handle != INVALID_HANDLE_VALUE) {
1066             test_basic_info(handle);
1067             test_detailed_info(handle, &detailed_info1);
1068             test_info_in_assembly(handle, 1, &manifest1_info);
1069             pReleaseActCtx(handle);
1070         }
1071         SetCurrentDirectoryW(work_dir);
1072     }
1073     else
1074         skip("Couldn't change directory\n");
1075     RemoveDirectoryW(work_dir_subdir);
1076
1077     trace("UTF-16 manifest1, with BOM\n");
1078     if(!create_wide_manifest("test1.manifest", manifest1, TRUE, FALSE)) {
1079         skip("Could not create manifest file\n");
1080         return;
1081     }
1082
1083     handle = test_create("test1.manifest", manifest1);
1084     DeleteFileA("test1.manifest");
1085     if (handle != INVALID_HANDLE_VALUE) {
1086         test_basic_info(handle);
1087         test_detailed_info(handle, &detailed_info1);
1088         test_info_in_assembly(handle, 1, &manifest1_info);
1089         pReleaseActCtx(handle);
1090     }
1091
1092     trace("UTF-16 manifest1, reverse endian, with BOM\n");
1093     if(!create_wide_manifest("test1.manifest", manifest1, TRUE, TRUE)) {
1094         skip("Could not create manifest file\n");
1095         return;
1096     }
1097
1098     handle = test_create("test1.manifest", manifest1);
1099     DeleteFileA("test1.manifest");
1100     if (handle != INVALID_HANDLE_VALUE) {
1101         test_basic_info(handle);
1102         test_detailed_info(handle, &detailed_info1);
1103         test_info_in_assembly(handle, 1, &manifest1_info);
1104         pReleaseActCtx(handle);
1105     }
1106
1107 }
1108
1109 static void test_app_manifest(void)
1110 {
1111     HANDLE handle;
1112     BOOL b;
1113
1114     trace("child process manifest1\n");
1115
1116     b = pGetCurrentActCtx(&handle);
1117     ok(handle == NULL, "handle != NULL\n");
1118     ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
1119     if(b) {
1120         test_basic_info(handle);
1121         test_detailed_info(handle, &detailed_info1_child);
1122         test_info_in_assembly(handle, 1, &manifest1_child_info);
1123         pReleaseActCtx(handle);
1124     }
1125 }
1126
1127 static void run_child_process(void)
1128 {
1129     char cmdline[MAX_PATH];
1130     char path[MAX_PATH];
1131     char **argv;
1132     PROCESS_INFORMATION pi;
1133     STARTUPINFO si = { 0 };
1134
1135     GetModuleFileNameA(NULL, path, MAX_PATH);
1136     strcat(path, ".manifest");
1137     if(!create_manifest_file(path, manifest1, -1, NULL, NULL)) {
1138         skip("Could not create manifest file\n");
1139         return;
1140     }
1141
1142     si.cb = sizeof(si);
1143     winetest_get_mainargs( &argv );
1144     sprintf(cmdline, "\"%s\" %s manifest1", argv[0], argv[1]);
1145     ok(CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
1146                      &si, &pi) != 0, "Could not create process: %u\n", GetLastError());
1147     winetest_wait_child_process( pi.hProcess );
1148     CloseHandle(pi.hThread);
1149     CloseHandle(pi.hProcess);
1150     DeleteFileA(path);
1151 }
1152
1153 static void init_paths(void)
1154 {
1155     LPWSTR ptr;
1156     WCHAR last;
1157
1158     static const WCHAR dot_manifest[] = {'.','M','a','n','i','f','e','s','t',0};
1159     static const WCHAR backslash[] = {'\\',0};
1160     static const WCHAR subdir[] = {'T','e','s','t','S','u','b','d','i','r','\\',0};
1161
1162     GetModuleFileNameW(NULL, exe_path, sizeof(exe_path)/sizeof(WCHAR));
1163     lstrcpyW(app_dir, exe_path);
1164     for(ptr=app_dir+lstrlenW(app_dir); *ptr != '\\' && *ptr != '/'; ptr--);
1165     ptr[1] = 0;
1166
1167     GetCurrentDirectoryW(MAX_PATH, work_dir);
1168     last = work_dir[lstrlenW(work_dir) - 1];
1169     if (last != '\\' && last != '/')
1170         lstrcatW(work_dir, backslash);
1171     lstrcpyW(work_dir_subdir, work_dir);
1172     lstrcatW(work_dir_subdir, subdir);
1173
1174     GetModuleFileNameW(NULL, app_manifest_path, sizeof(app_manifest_path)/sizeof(WCHAR));
1175     lstrcpyW(app_manifest_path+lstrlenW(app_manifest_path), dot_manifest);
1176 }
1177
1178 static BOOL init_funcs(void)
1179 {
1180     HMODULE hKernel32 = GetModuleHandle("kernel32");
1181
1182 #define X(f) if (!(p##f = (void*)GetProcAddress(hKernel32, #f))) return FALSE;
1183     X(ActivateActCtx);
1184     X(CreateActCtxW);
1185     X(DeactivateActCtx);
1186     X(FindActCtxSectionStringW);
1187     X(GetCurrentActCtx);
1188     X(IsDebuggerPresent);
1189     X(QueryActCtxW);
1190     X(ReleaseActCtx);
1191 #undef X
1192
1193     return TRUE;
1194 }
1195
1196 START_TEST(actctx)
1197 {
1198     int argc;
1199     char **argv;
1200
1201     argc = winetest_get_mainargs(&argv);
1202
1203     if (!init_funcs())
1204     {
1205         skip("Needed functions are not available\n");
1206         return;
1207     }
1208     init_paths();
1209
1210     if(argc > 2 && !strcmp(argv[2], "manifest1")) {
1211         test_app_manifest();
1212         return;
1213     }
1214
1215     test_actctx();
1216     run_child_process();
1217 }