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