gdiplus: Implement GdipGetEmHeight.
[wine] / dlls / fusion / tests / asmcache.c
1 /*
2  * Copyright 2008 James Hawkins
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 #define COBJMACROS
20 #define INITGUID
21
22 #include <stdio.h>
23
24 #include <windows.h>
25 #include <mscoree.h>
26 #include <fusion.h>
27 #include <corerror.h>
28
29 #include "wine/test.h"
30
31 typedef struct _tagASSEMBLY ASSEMBLY;
32
33 typedef struct
34 {
35     ULONG Signature;
36     USHORT MajorVersion;
37     USHORT MinorVersion;
38     ULONG Reserved;
39     ULONG VersionLength;
40     BYTE Version[12];
41     BYTE Flags;
42     WORD Streams;
43 } METADATAHDR;
44
45 #include <pshpack1.h>
46
47 typedef struct
48 {
49     DWORD Offset;
50     DWORD Size;
51 } METADATASTREAMHDR;
52
53 typedef struct
54 {
55     DWORD Reserved1;
56     BYTE MajorVersion;
57     BYTE MinorVersion;
58     BYTE HeapOffsetSizes;
59     BYTE Reserved2;
60     LARGE_INTEGER MaskValid;
61     LARGE_INTEGER MaskSorted;
62 } METADATATABLESHDR;
63
64 typedef struct
65 {
66     WORD Generation;
67     WORD Name;
68     WORD Mvid;
69     WORD EncId;
70     WORD EncBaseId;
71 } MODULETABLE;
72
73 typedef struct
74 {
75     DWORD Flags;
76     WORD Name;
77     WORD Namespace;
78     WORD Extends;
79     WORD FieldList;
80     WORD MethodList;
81 } TYPEDEFTABLE;
82
83 typedef struct
84 {
85     DWORD HashAlgId;
86     WORD MajorVersion;
87     WORD MinorVersion;
88     WORD BuildNumber;
89     WORD RevisionNumber;
90     DWORD Flags;
91     WORD PublicKey;
92     WORD Name;
93     WORD Culture;
94 } ASSEMBLYTABLE;
95
96 typedef struct
97 {
98     DWORD Offset;
99     DWORD Flags;
100     WORD Name;
101     WORD Implementation;
102 } MANIFESTRESTABLE;
103
104 typedef struct
105 {
106     DWORD ImportLookupTable;
107     DWORD DateTimeStamp;
108     DWORD ForwarderChain;
109     DWORD Name;
110     DWORD ImportAddressTable;
111     BYTE pad[20];
112 } IMPORTTABLE;
113
114 typedef struct
115 {
116     DWORD HintNameTableRVA;
117     BYTE pad[8];
118 } IMPORTLOOKUPTABLE;
119
120 typedef struct
121 {
122     WORD Hint;
123     BYTE Name[12];
124     BYTE Module[12];
125     DWORD Reserved;
126     WORD EntryPoint;
127     DWORD RVA;
128 } HINTNAMETABLE;
129
130 typedef struct
131 {
132     DWORD PageRVA;
133     DWORD Size;
134     DWORD Relocation;
135 } RELOCATION;
136
137 typedef struct
138 {
139     WORD wLength;
140     WORD wValueLength;
141     WORD wType;
142     WCHAR szKey[17];
143     VS_FIXEDFILEINFO Value;
144 } VS_VERSIONINFO;
145
146 typedef struct
147 {
148     WORD wLength;
149     WORD wValueLength;
150     WORD wType;
151     WCHAR szKey[13];
152 } VARFILEINFO;
153
154 typedef struct
155 {
156     WORD wLength;
157     WORD wValueLength;
158     WORD wType;
159     WCHAR szKey[13];
160     DWORD Value;
161 } VAR;
162
163 typedef struct
164 {
165     WORD wLength;
166     WORD wValueLength;
167     WORD wType;
168     WCHAR szKey[15];
169 } STRINGFILEINFO;
170
171 typedef struct
172 {
173     WORD wLength;
174     WORD wValueLength;
175     WORD wType;
176     WCHAR szKey[9];
177 } STRINGTABLE;
178
179 typedef struct
180 {
181     WORD wLength;
182     WORD wValueLength;
183     WORD wType;
184 } STRINGHDR;
185
186 typedef struct
187 {
188     DWORD Size;
189     DWORD Signature;
190     DWORD HeaderVersion;
191     DWORD SkipBytes;
192     BYTE Data[168];
193 } RESOURCE;
194
195 #include <poppack.h>
196
197 static struct _tagASSEMBLY
198 {
199     IMAGE_DOS_HEADER doshdr;
200     WORD unknown[32];
201     IMAGE_NT_HEADERS32 nthdrs;
202     IMAGE_SECTION_HEADER text;
203     IMAGE_SECTION_HEADER rsrc;
204     IMAGE_SECTION_HEADER reloc;
205     BYTE pad[16];
206     IMAGE_IMPORT_BY_NAME iat;
207     BYTE pad2[3];
208     IMAGE_COR20_HEADER clrhdr;
209     WORD strongname[64];
210     RESOURCE resource;
211     METADATAHDR metadatahdr;
212     METADATASTREAMHDR roothdr;
213     BYTE rootname[4];
214     METADATASTREAMHDR stringshdr;
215     BYTE stringsname[12];
216     METADATASTREAMHDR ushdr;
217     BYTE usname[4];
218     METADATASTREAMHDR guidhdr;
219     BYTE guidname[8];
220     METADATASTREAMHDR blobhdr;
221     BYTE blobname[8];
222     METADATATABLESHDR tableshdr;
223     DWORD numrows[4];
224     MODULETABLE modtable;
225     TYPEDEFTABLE tdtable;
226     ASSEMBLYTABLE asmtable;
227     MANIFESTRESTABLE manifestrestable;
228     WORD pad3;
229     BYTE stringheap[40];
230     WORD usheap[4];
231     WORD guidheap[8];
232     WORD blobheap[82];
233     IMAGE_IMPORT_DESCRIPTOR importdesc;
234     BYTE pad4[20];
235     IMPORTLOOKUPTABLE importlookup;
236     HINTNAMETABLE hintnametable;
237     BYTE pad5[108];
238     IMAGE_RESOURCE_DIRECTORY topresdir;
239     IMAGE_RESOURCE_DIRECTORY_ENTRY labelres;
240     IMAGE_RESOURCE_DIRECTORY res11dir;
241     IMAGE_RESOURCE_DIRECTORY_ENTRY label11res;
242     IMAGE_RESOURCE_DIRECTORY res10dir;
243     IMAGE_RESOURCE_DIRECTORY_ENTRY label10res;
244     IMAGE_RESOURCE_DATA_ENTRY resdata;
245     VS_VERSIONINFO verinfo;
246     VARFILEINFO varfileinfo;
247     VAR translation;
248     STRINGFILEINFO strfileinfo;
249     STRINGTABLE strtable;
250     STRINGHDR filedeschdr;
251     WCHAR filedesckey[17];
252     WCHAR filedescval[2];
253     STRINGHDR fileverhdr;
254     WCHAR fileverkey[13];
255     WCHAR fileverval[8];
256     STRINGHDR intnamehdr;
257     WCHAR intnamekey[13];
258     WCHAR intnameval[10];
259     STRINGHDR copyrighthdr;
260     WCHAR copyrightkey[15];
261     WCHAR copyrightval[2];
262     STRINGHDR orignamehdr;
263     WCHAR orignamekey[17];
264     WCHAR orignameval[10];
265     STRINGHDR prodverhdr;
266     WCHAR prodverkey[15];
267     WCHAR prodverval[8];
268     STRINGHDR asmverhdr;
269     WCHAR asmverkey[17];
270     WCHAR asmverval[8];
271     WORD pad6[182];
272     RELOCATION relocation;
273     WORD pad7[250];
274 } assembly =
275 {
276     /* IMAGE_DOS_HEADER */
277     {
278         IMAGE_DOS_SIGNATURE, 144, 3, 0, 4, 0, 0xFFFF, 0, 0xB8, 0, 0, 0, 0x40,
279         0, { 0  }, 0, 0, { 0 }, 0x80
280     },
281     /* binary to print "This program cannot be run in DOS mode." */
282     {
283         0x1F0E, 0x0EBA, 0xB400, 0xCD09, 0xB821, 0x4C01, 0x21CD, 0x6854, 0x7369,
284         0x7020, 0x6F72, 0x7267, 0x6D61, 0x6320, 0x6E61, 0x6F6E, 0x2074, 0x6562,
285         0x7220, 0x6E75, 0x6920, 0x206E, 0x4F44, 0x2053, 0x6F6D, 0x6564, 0x0D2E,
286         0x0A0D, 0x0024, 0x0000, 0x0000, 0x0000
287     },
288     /* IMAGE_NT_HEADERS32 */
289     {
290         IMAGE_NT_SIGNATURE, /* Signature */
291         /* IMAGE_FILE_HEADER */
292         {
293             IMAGE_FILE_MACHINE_I386, /* Machine */
294             3, /* NumberOfSections */
295             0x47EFDF09, /* TimeDateStamp */
296             0, /* PointerToSymbolTable */
297             0, /* NumberOfSymbols */
298             0xE0, /* SizeOfOptionalHeader */
299             IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED |
300             IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
301             IMAGE_FILE_DLL, /* Characteristics */
302         },
303         /* IMAGE_OPTIONAL_HEADER32 */
304         {
305             IMAGE_NT_OPTIONAL_HDR_MAGIC, /* Magic */
306             8, /* MajorLinkerVersion */
307             0, /* MinorLinkerVersion */
308             0x400, /* SizeOfCode */
309             0x600, /* SizeOfInitializedData */
310             0, /* SizeOfUninitializedData */
311             0x238E, /* AddressOfEntryPoint */
312             0x2000, /* BaseOfCode */
313             0x4000, /* BaseOfData */
314             0x400000, /* ImageBase */
315             0x2000, /* SectionAlignment */
316             0x200, /* FileAlignment */
317             4, /* MajorOperatingSystemVersion */
318             0, /* MinorOperatingSystemVersion */
319             0, /* MajorImageVersion */
320             0, /* MinorImageVersion */
321             4, /* MajorSubsystemVersion */
322             0, /* MinorSubsystemVersion */
323             0, /* Win32VersionValue */
324             0x8000, /* SizeOfImage */
325             0x200, /* SizeOfHeaders */
326             0xB576, /* CheckSum */
327             IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */
328             IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |
329             IMAGE_DLLCHARACTERISTICS_NO_SEH |
330             IMAGE_DLLCHARACTERISTICS_NX_COMPAT, /* DllCharacteristics */
331             0x100000, /* SizeOfStackReserve */
332             0x1000, /* SizeOfStackCommit */
333             0x100000, /* SizeOfHeapReserve */
334             0x1000, /* SizeOfHeapCommit */
335             0, /* LoaderFlags */
336             0x10, /* NumberOfRvaAndSizes */
337             /* IMAGE_DATA_DIRECTORY */
338             {
339                 { 0 }, /* Export Table */
340                 { 0x233C, 0x4F }, /* Import Table */
341                 { 0x4000, 0x298 }, /* Resource Table */
342                 { 0 }, /* Exception Table */
343                 { 0 }, /* Certificate Table */
344                 { 0x6000, 0xC }, /* Base Relocation Table */
345                 { 0 }, /* Debug */
346                 { 0 }, /* Copyright */
347                 { 0 }, /* Global Ptr */
348                 { 0 }, /* TLS Table */
349                 { 0 }, /* Load Config Table */
350                 { 0 }, /* Bound Import */
351                 { 0x2000, 8 }, /* IAT */
352                 { 0 }, /* Delay Import Descriptor */
353                 { 0x2008, 0x48 }, /* CLI Header */
354                 { 0 } /* Reserved */
355             }
356         }
357     },
358     /* IMAGE_SECTION_HEADER */
359     {
360         ".text", /* Name */
361         { 0x394 }, /* Misc.VirtualSize */
362         0x2000, /* VirtualAddress */
363         0x400, /* SizeOfRawData */
364         0x200, /* PointerToRawData */
365         0, /* PointerToRelocations */
366         0, /* PointerToLinenumbers */
367         0, /* NumberOfRelocations */
368         0, /* NumberOfLinenumbers */
369         IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE |
370         IMAGE_SCN_CNT_CODE, /* Characteristics */
371     },
372     /* IMAGE_SECTION_HEADER */
373     {
374         ".rsrc", /* Name */
375         { 0x298 }, /* Misc.VirtualSize */
376         0x4000, /* VirtualAddress */
377         0x400, /* SizeOfRawData */
378         0x600, /* PointerToRawData */
379         0, /* PointerToRelocations */
380         0, /* PointerToLinenumbers */
381         0, /* NumberOfRelocations */
382         0, /* NumberOfLinenumbers */
383         IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ, /* Characteristics */
384     },
385     /* IMAGE_SECTION_HEADER */
386     {
387         ".reloc", /* Name */
388         { 0xC }, /* Misc.VirtualSize */
389         0x6000, /* VirtualAddress */
390         0x200, /* SizeOfRawData */
391         0xA00, /* PointerToRawData */
392         0, /* PointerToRelocations */
393         0, /* PointerToLinenumbers */
394         0, /* NumberOfRelocations */
395         0, /* NumberOfLinenumbers */
396         IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
397         IMAGE_SCN_MEM_DISCARDABLE, /* Characteristics */
398     },
399     /* fill */
400     { 0 },
401     /* IMAGE_IMPORT_BY_NAME */
402     {
403         0x2370, /* Hint */
404         { 0 } /* Name */
405     },
406     /* fill */
407     { 0 },
408     /* IMAGE_COR20_HEADER */
409     {
410         0x48, /* Cb */
411         2, /* MajorRuntimeVersion */
412         5, /* MinorRuntimeVersion */
413         { 0x2188, 0x1B4 }, /* MetaData */
414         COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_STRONGNAMESIGNED, /* Flags */
415         0, /* EntryPointToken */
416         { 0x20D0, 0xB8 }, /* Resources */
417         { 0x2050, 0x80 }, /* StrongNameSignature */
418         { 0 }, /* CodeManagerTable */
419         { 0 }, /* VTableFixups */
420         { 0 }, /* ExportAddressTableJumps */
421         { 0 } /* ManagedNativeHeader */
422     },
423     { 0xE496, 0x9A6E, 0xD95E, 0xA2A1, 0x5D72, 0x9CEF, 0x41E3, 0xD483,
424       0xCB5C, 0x329A, 0x887C, 0xE18E, 0xE664, 0x2E1C, 0x0E61, 0xB361,
425       0x8B88, 0xC8D0, 0x47A5, 0x9260, 0x6CC5, 0xE60F, 0x1F61, 0x1E3E,
426       0xAFEE, 0x925A, 0xA084, 0x6B44, 0x2DC6, 0x8126, 0xEBC9, 0xD812,
427       0xF3E9, 0xA3F3, 0xD0D5, 0x2C7F, 0x4592, 0xA0AF, 0x8B15, 0xD91E,
428       0x693E, 0x7A4F, 0x5567, 0xC466, 0xC410, 0x3D29, 0xB25F, 0xCD6C,
429       0x53EF, 0x0D29, 0x085A, 0xEC39, 0xE3BD, 0x58E0, 0x78F5, 0x0587,
430       0xF8D8, 0x14E4, 0x77CE, 0xCCC9, 0x4DCF, 0x8A18, 0x90E8, 0x1A52
431     },
432     /* RESOURCE */
433     {
434         0xB4, /* Size */
435         0xBEEFCACE, /* Signature */
436         1, /* HeaderVersion */
437         0x91, /* SkipBytes */
438         { 'l','S','y','s','t','e','m','.','R','e','s','o','u','r','c','e','s','.',
439           'R','e','s','o','u','r','c','e','R','e','a','d','e','r',',',' ',
440           'm','s','c','o','r','l','i','b',',',' ','V','e','r','s','i','o','n','=',
441           '2','.','0','.','0','.','0',',',' ','C','u','l','t','u','r','e','=',
442           'n','e','u','t','r','a','l',',',' ','P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',
443           'b','7','7','a','5','c','5','6','1','9','3','4','e','0','8','9',
444           '#','S','y','s','t','e','m','.','R','e','s','o','u','r','c','e','s','.',
445           'R','u','n','t','i','m','e','R','e','s','o','u','r','c','e','S','e','t',
446           2,0,0,0,0,0,0,0,0,0,0,0,'P','A','D','P','A','D','P',180,0,0,0
447         }
448     },
449     /* METADATAHDR */
450     {
451         0x424A5342, /* Signature */
452         1, /* MajorVersion */
453         1, /* MinorVersion */
454         0, /* Reserved */
455         0xC, /* VersionLength */
456         "v2.0.50727", /* Version */
457         0, /* Flags */
458         5 /* Streams */
459     },
460     /* METADATASTREAMHDR */
461     {
462         0x6C, /* Offset */
463         0x64, /* Size */
464     },
465     "#~\0\0",
466     /* METADATASTREAMHDR */
467     {
468         0xD0, /* Offset */
469         0x28, /* Size */
470     },
471     "#Strings\0\0\0\0",
472     /* METADATASTREAMHDR */
473     {
474         0xF8, /* Offset */
475         0x8, /* Size */
476     },
477     "#US\0",
478     /* METADATASTREAMHDR */
479     {
480         0x100, /* Offset */
481         0x10, /* Size */
482     },
483     "#GUID\0\0\0",
484     /* METADATASTREAMHDR */
485     {
486         0x110, /* Offset */
487         0xA4, /* Size */
488     },
489     "#Blob\0\0\0",
490     /* METADATATABLESHDR */
491     {
492         0, /* Reserved1 */
493         2, /* MajorVersion */
494         0, /* MinorVersion */
495         0, /* HeapOffsetSizes */
496         1, /* Reserved2 */
497         { { 0 } }, /* MaskValid */
498         { { 0 } } /* MaskSorted */
499     },
500     /* numrows */
501     { 1, 1, 1, 1 },
502     /* MODULETABLE */
503     {
504         0, /* Generation */
505         0xA, /* Name */
506         1, /* Mvid */
507         0, /* EncId */
508         0 /* EncBaseId */
509     },
510     /* TYPEDEFTABLE */
511     {
512         0, /* Flags */
513         0x1, /* Name */
514         0, /* Namespace */
515         0, /* Extends */
516         1, /* FieldList */
517         1 /* MethodList */
518     },
519     /* ASSEMBLYTABLE */
520     {
521         0x8004, /* HashAlgId */
522         1, /* MajorVersion */
523         0, /* MinorVersion */
524         0, /* BuildNumber */
525         0, /* RevisionNumber */
526         1, /* Flags */
527         1, /* PublicKey */
528         0x13, /* Name */
529         0 /* Culture */
530     },
531     /* MANIFESTRESTABLE */
532     {
533         0, /* Offset */
534         0x2, /* Flags */
535         0x18, /* Name */
536         0 /* Implementation */
537     },
538     /* pad */
539     0,
540     /* String heap */
541     "\0<Module>\0wine.dll\0wine\0wine.resources\0\0",
542     /* US heap */
543     { 0x0300, 0x0020 },
544     /* GUID heap */
545     { 0x86EF, 0x5B5A, 0x2C5E, 0x4F6D, 0xC2AB, 0x0A94, 0xD658, 0x31DA },
546     /* BLOB heap */
547     { 0x8000, 0x00A0, 0x0024, 0x0400, 0x0080, 0x9400, 0x0000, 0x0600,
548       0x0002, 0x0000, 0x0024, 0x5200, 0x4153, 0x0031, 0x0004, 0x0100,
549       0x0100, 0x2F00, 0x60E0, 0x4D76, 0x5E5C, 0x430A, 0x6FF3, 0x77D6,
550       0x04CA, 0xF6AD, 0xF54D, 0x0AD2, 0x9FB6, 0x39C2, 0x2E66, 0xD30F,
551       0x916F, 0x1826, 0xFB52, 0x78A0, 0x8262, 0x6902, 0xBD47, 0xAF30,
552       0xBAB1, 0x29DA, 0xAA6D, 0xF189, 0x296A, 0x0F13, 0x4982, 0x531D,
553       0x8283, 0x1343, 0x5A33, 0x5D36, 0xEB3F, 0x0863, 0xA771, 0x0679,
554       0x4DFF, 0xD30A, 0xBEAD, 0x2A9F, 0x12A8, 0x4319, 0x5706, 0x333D,
555       0x0CAC, 0xE80A, 0xFD99, 0xC82D, 0x3D3B, 0xBFFE, 0xF256, 0x25E3,
556       0x1A12, 0xC116, 0x8936, 0xF237, 0x5F26, 0xC68A, 0x1E42, 0xCE41,
557       0xC17C, 0x00C4
558     },
559     /* IMAGE_IMPORT_DESCRIPTOR */
560     {
561         { 0x2364 }, /* OriginalFirstThunk */
562         0, /* TimeDateStamp */
563         0, /* ForwarderChain */
564         0x237E, /* Name */
565         0x2000, /* FirstThunk */
566     },
567     /* pad */
568     { 0 },
569     /* IMPORTLOOKUPTABLE */
570     {
571         0x2370, /* HintNameTableRVA */
572         { 0 }, /* pad */
573     },
574     /* HINTNAMETABLE */
575     {
576         0, /* Hint */
577         "_CorDllMain", /* Name */
578         "mscoree.dll", /* Module */
579         0, /* Reserved */
580         0x25FF, /* EntryPoint */
581         0x402000 /* RVA */
582     },
583     /* pad to 0x600 */
584     { 0 },
585     /* IMAGE_RESOURCE_DIRECTORY */
586     {
587         0, /* Characteristics */
588         0, /* TimeDateStamp */
589         0, /* MajorVersion */
590         0, /* MinorVersion */
591         0, /* NumberOfNamedEntries */
592         1, /* NumberOfIdEntries */
593     },
594     /* IMAGE_RESOURCE_DIRECTORY_ENTRY */
595     { { { 0 } }, { 0 } }, /* nameless unions initialized later */
596     /* IMAGE_RESOURCE_DIRECTORY */
597     {
598         0, /* Characteristics */
599         0, /* TimeDateStamp */
600         0, /* MajorVersion */
601         0, /* MinorVersion */
602         0, /* NumberOfNamedEntries */
603         1, /* NumberOfIdEntries */
604     },
605     /* IMAGE_RESOURCE_DIRECTORY_ENTRY */
606     { { { 0 } }, { 0 } }, /* nameless unions initialized later */
607     /* IMAGE_RESOURCE_DIRECTORY */
608     {
609         0, /* Characteristics */
610         0, /* TimeDateStamp */
611         0, /* MajorVersion */
612         0, /* MinorVersion */
613         0, /* NumberOfNamedEntries */
614         1, /* NumberOfIdEntries */
615     },
616     /* IMAGE_RESOURCE_DIRECTORY_ENTRY */
617     { { { 0 } }, { 0 } }, /* nameless unions initialized later */
618     /* IMAGE_RESOURCE_DATA_ENTRY */
619     {
620         0x4058, /* OffsetToData */
621         0x23C, /* Size */
622         0, /* CodePage */
623         0, /* Reserved */
624     },
625     /* VS_VERSIONINFO */
626     {
627         0x23C, /* wLength */
628         0x34, /* wValueLength */
629         0, /* wType */
630         { 'V','S','_','V','E','R','S','I','O','N','_','I','N','F','O',0,0 }, /* szKey */
631         /* VS_FIXEDFILEINFO */
632         {
633             VS_FFI_SIGNATURE, /* dwSignature */
634             VS_FFI_STRUCVERSION, /* dwStrucVersion */
635             0x10000, /* dwFileVersionMS */
636             0x00000, /* dwFileVersionLS */
637             0x10000, /* dwProductVersionMS */
638             0x00000, /* dwProductVersionLS */
639             VS_FFI_FILEFLAGSMASK, /* dwFileFlagsMask */
640             0x0, /* dwFileFlags */
641             VOS__WINDOWS32, /* dwFileOS */
642             VFT_DLL, /* dwFileType */
643             VFT2_UNKNOWN, /* dwFileSubtype */
644             0, /* dwFileDateMS */
645             0, /* dwFileDateLS */
646         },
647     },
648     /* VARFILEINFO */
649     {
650         0x44, /* wLength */
651         0, /* wValueLength */
652         1, /* wType */
653         { 'V','a','r','F','i','l','e','I','n','f','o',0,0 } /* szKey */
654     },
655     /* VAR */
656     {
657         0x24, /* wLength */
658         0x4, /* wValueLength */
659         0, /* wType */
660         { 'T','r','a','n','s','l','a','t','i','o','n',0,0 }, /* szKey */
661         0x4B00000, /* Value */
662     },
663     /* STRINGFILEINFO */
664     {
665         0x19C, /* wLength */
666         0, /* wValueLength */
667         1, /* wType */
668         { 'S','t','r','i','n','g','F','i','l','e','I','n','f','o',0 }, /* szKey */
669     },
670     /* STRINGTABLE */
671     {
672         0x178, /* wLength */
673         0, /* wValueLength */
674         1, /* wType */
675         { '0','0','0','0','0','4','b','0',0 }, /* szKey */
676     },
677     /* STRINGHDR */
678     {
679         0x2C, /* wLength */
680         2, /* wValueLength */
681         1, /* wType */
682     },
683     { 'F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0,0 }, /* szKey */
684     { ' ',0 }, /* szValue */
685     /* STRINGHDR */
686     {
687         0x30, /* wLength */
688         8, /* wValueLength */
689         1, /* wType */
690     },
691     { 'F','i','l','e','V','e','r','s','i','o','n',0,0 }, /* szKey */
692     { '1','.','0','.','0','.','0',0 }, /* szValue */
693     /* STRINGHDR */
694     {
695         0x34, /* wLength */
696         9, /* wValueLength */
697         1, /* wType */
698     },
699     { 'I','n','t','e','r','n','a','l','N','a','m','e',0 }, /* szKey */
700     { 'w','i','n','e','.','d','l','l',0 }, /* szValue */
701     /* STRINGHDR */
702     {
703         0x28, /* wLength */
704         2, /* wValueLength */
705         1, /* wType */
706     },
707     { 'L','e','g','a','l','C','o','p','y','r','i','g','h','t',0 }, /* szKey */
708     { ' ',0 }, /* szValue */
709     /* STRINGHDR */
710     {
711         0x3C, /* wLength */
712         9, /* wValueLength */
713         1, /* wType */
714     },
715     { 'O','r','i','g','i','n','a','l','F','i','l','e','n','a','m','e',0 }, /* szKey */
716     { 'w','i','n','e','.','d','l','l',0,0 }, /* szValue */
717     /* STRINGHDR */
718     {
719         0x34, /* wLength */
720         8, /* wValueLength */
721         1, /* wType */
722     },
723     { 'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0 }, /* szKey */
724     { '1','.','0','.','0','.','0',0 }, /* szValue */
725     /* STRINGHDR */
726     {
727         0x38, /* wLength */
728         8, /* wValueLength */
729         1, /* wType */
730     },
731     { 'A','s','s','e','m','b','l','y',' ','V','e','r','s','i','o','n',0 }, /* szKey */
732     { '1','.','0','.','0','.','0',0 }, /* szValue */
733     { 0 }, /* pad */
734     /* RELOCATION */
735     {
736         0x2000, /* PageRVA */
737         0xC, /* Size */
738         0x3390, /* Relocation */
739     },
740     { 0 }
741 };
742
743
744 static HRESULT (WINAPI *pCreateAssemblyCache)(IAssemblyCache **ppAsmCache,
745                                               DWORD dwReserved);
746 static HRESULT (WINAPI *pGetCachePath)(ASM_CACHE_FLAGS dwCacheFlags,
747                                        LPWSTR pwzCachePath, PDWORD pcchPath);
748 static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion,
749                                           LPVOID pvReserved, HMODULE *phModDll);
750
751 static BOOL init_functionpointers(void)
752 {
753     HRESULT hr;
754     HMODULE hfusion;
755     HMODULE hmscoree;
756
757     static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
758
759     hmscoree = LoadLibraryA("mscoree.dll");
760     if (!hmscoree)
761     {
762         skip("mscoree.dll not available\n");
763         return FALSE;
764     }
765
766     pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
767     if (!pLoadLibraryShim)
768     {
769         skip("LoadLibraryShim not available\n");
770         FreeLibrary(hmscoree);
771         return FALSE;
772     }
773
774     hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion);
775     if (FAILED(hr))
776     {
777         skip("fusion.dll not available\n");
778         FreeLibrary(hmscoree);
779         return FALSE;
780     }
781
782     pCreateAssemblyCache = (void *)GetProcAddress(hfusion, "CreateAssemblyCache");
783     pGetCachePath = (void *)GetProcAddress(hfusion, "GetCachePath");
784
785     if (!pCreateAssemblyCache || !pGetCachePath)
786     {
787         skip("fusion.dll not implemented\n");
788         return FALSE;
789     }
790
791     FreeLibrary(hmscoree);
792     return TRUE;
793 }
794
795 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
796 {
797     HANDLE file;
798     DWORD written;
799
800     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
801     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
802     WriteFile(file, data, strlen(data), &written, NULL);
803
804     if (size)
805     {
806         SetFilePointer(file, size, NULL, FILE_BEGIN);
807         SetEndOfFile(file);
808     }
809
810     CloseHandle(file);
811 }
812
813 #define create_file(name, size) create_file_data(name, name, size)
814
815 static void create_assembly(LPCSTR file)
816 {
817     HANDLE hfile;
818     DWORD written;
819
820     /* nameless unions initialized here */
821     assembly.tableshdr.MaskValid.u.HighPart = 0x101;
822     assembly.tableshdr.MaskValid.u.LowPart = 0x00000005;
823     assembly.tableshdr.MaskSorted.u.HighPart = 0x1600;
824     assembly.tableshdr.MaskSorted.u.LowPart = 0x3301FA00;
825     U1(assembly.labelres).Name = 0x10;
826     U2(assembly.labelres).OffsetToData = 0x80000018;
827     U1(assembly.label11res).Name = 0x1;
828     U2(assembly.label11res).OffsetToData = 0x80000030;
829     U1(assembly.label10res).Name = 0x0;
830     U2(assembly.label10res).OffsetToData = 0x48;
831
832     hfile = CreateFileA(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
833
834     WriteFile(hfile, &assembly, sizeof(ASSEMBLY), &written, NULL);
835     CloseHandle(hfile);
836 }
837
838 static void test_CreateAssemblyCache(void)
839 {
840     IAssemblyCache *cache;
841     HRESULT hr;
842
843     /* NULL ppAsmCache */
844     hr = pCreateAssemblyCache(NULL, 0);
845     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
846
847     /* dwReserved is non-zero */
848     hr = pCreateAssemblyCache(&cache, 42);
849     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
850
851     IAssemblyCache_Release(cache);
852 }
853
854 static void test_InstallAssembly(void)
855 {
856     IAssemblyCache *cache;
857     HRESULT hr;
858     ULONG disp;
859     DWORD attr;
860
861     static const WCHAR empty[] = {0};
862     static const WCHAR noext[] = {'f','i','l','e',0};
863     static const WCHAR badext[] = {'f','i','l','e','.','b','a','d',0};
864     static const WCHAR dllext[] = {'f','i','l','e','.','d','l','l',0};
865     static const WCHAR exeext[] = {'f','i','l','e','.','e','x','e',0};
866     static const WCHAR testdll[] = {'t','e','s','t','.','d','l','l',0};
867     static const WCHAR winedll[] = {'w','i','n','e','.','d','l','l',0};
868     static const WCHAR wine[] = {'w','i','n','e',0};
869
870     create_file("test.dll", 100);
871     create_assembly("wine.dll");
872
873     hr = pCreateAssemblyCache(&cache, 0);
874     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
875
876     /* NULL pszManifestFilePath */
877     hr = IAssemblyCache_InstallAssembly(cache, 0, NULL, NULL);
878     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
879
880     /* empty pszManifestFilePath */
881     hr = IAssemblyCache_InstallAssembly(cache, 0, empty, NULL);
882     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
883
884     /* pszManifestFilePath has no extension */
885     hr = IAssemblyCache_InstallAssembly(cache, 0, noext, NULL);
886     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME),
887        "Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x\n", hr);
888
889     /* pszManifestFilePath has bad extension */
890     hr = IAssemblyCache_InstallAssembly(cache, 0, badext, NULL);
891     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME),
892        "Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x\n", hr);
893
894     /* pszManifestFilePath has dll extension */
895     hr = IAssemblyCache_InstallAssembly(cache, 0, dllext, NULL);
896     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
897        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
898
899     /* pszManifestFilePath has exe extension */
900     hr = IAssemblyCache_InstallAssembly(cache, 0, exeext, NULL);
901     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
902        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
903
904     /* empty file */
905     hr = IAssemblyCache_InstallAssembly(cache, 0, testdll, NULL);
906     ok(hr == COR_E_ASSEMBLYEXPECTED,
907        "Expected COR_E_ASSEMBLYEXPECTED, got %08x\n", hr);
908
909     /* wine assembly */
910     hr = IAssemblyCache_InstallAssembly(cache, 0, winedll, NULL);
911     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
912
913     attr = GetFileAttributes("C:\\windows\\assembly\\GAC_MSIL\\wine\\"
914                              "1.0.0.0__2d03617b1c31e2f5/wine.dll");
915     ok(attr != INVALID_FILE_ATTRIBUTES, "Expected assembly to exist\n");
916
917     /* uninstall the assembly from the GAC */
918     disp = 0xf00dbad;
919     hr = IAssemblyCache_UninstallAssembly(cache, 0, wine, NULL, &disp);
920     todo_wine
921     {
922         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
923         ok(disp == IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED,
924            "Expected IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED, got %d\n", disp);
925     }
926
927     /* FIXME: remove once UninstallAssembly is implemented */
928     DeleteFileA("C:\\windows\\assembly\\GAC_MSIL\\wine\\"
929                 "1.0.0.0__2d03617b1c31e2f5\\wine.dll");
930     RemoveDirectoryA("C:\\windows\\assembly\\GAC_MSIL\\wine\\1.0.0.0__2d03617b1c31e2f5");
931     RemoveDirectoryA("C:\\windows\\assembly\\GAC_MSIL\\wine");
932
933     DeleteFileA("test.dll");
934     DeleteFileA("wine.dll");
935     IAssemblyCache_Release(cache);
936 }
937
938 #define INIT_ASM_INFO() \
939     ZeroMemory(&info, sizeof(ASSEMBLY_INFO)); \
940     info.cbAssemblyInfo = sizeof(ASSEMBLY_INFO); \
941     info.pszCurrentAssemblyPathBuf = path; \
942     info.cchBuf = MAX_PATH; \
943     path[0] = '\0';
944
945 static void test_QueryAssemblyInfo(void)
946 {
947     IAssemblyCache *cache;
948     ASSEMBLY_INFO info;
949     WCHAR path[MAX_PATH];
950     WCHAR asmpath[MAX_PATH];
951     WCHAR name[MAX_PATH];
952     HRESULT hr;
953     DWORD size;
954     ULONG disp;
955
956     static const WCHAR empty[] = {0};
957     static const WCHAR commasep[] = {',',' ',0};
958     static const WCHAR winedll[] = {'w','i','n','e','.','d','l','l',0};
959     static const WCHAR wine[] = {'w','i','n','e',0};
960     static const WCHAR ver[] = {
961         'V','e','r','s','i','o','n','=','1','.','0','.','0','.','0',0};
962     static const WCHAR badver[] = {
963         'V','e','r','s','i','o','n','=','1','.','0','.','0','.','1',0};
964     static const WCHAR culture[] = {
965         'C','u','l','t','u','r','e','=','n','e','u','t','r','a','l',0};
966     static const WCHAR badculture[] = {
967         'C','u','l','t','u','r','e','=','e','n',0};
968     static const WCHAR pubkey[] = {
969         'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',
970         '2','d','0','3','6','1','7','b','1','c','3','1','e','2','f','5',0};
971     static const WCHAR badpubkey[] = {
972         'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',
973         'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0};
974     static const WCHAR badprop[] = {'B','a','d','P','r','o','p','=','b','u','h',0};
975     static const WCHAR msil[] = {
976         '_','M','S','I','L','\\','w','i','n','e','\\',
977         '1','.','0','.','0','.','0','_','_','2','d','0','3','6','1','7','b',
978         '1','c','3','1','e','2','f','5','\\',0};
979
980     size = MAX_PATH;
981     hr = pGetCachePath(ASM_CACHE_GAC, asmpath, &size);
982     todo_wine
983     {
984         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
985     }
986
987     lstrcatW(asmpath, msil);
988     lstrcatW(asmpath, winedll);
989
990     create_assembly("wine.dll");
991
992     hr = pCreateAssemblyCache(&cache, 0);
993     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
994
995     /* assembly not installed yet */
996     INIT_ASM_INFO();
997     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, wine, &info);
998     todo_wine
999     {
1000         ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1001            "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1002     }
1003     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1004        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1005     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1006     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1007        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1008     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1009        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1010     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1011        "Assembly path was changed\n");
1012     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1013
1014     hr = IAssemblyCache_InstallAssembly(cache, 0, winedll, NULL);
1015     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1016
1017     /* NULL pszAssemblyName */
1018     INIT_ASM_INFO();
1019     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1020                                           NULL, &info);
1021     todo_wine
1022     {
1023         ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1024     }
1025     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1026        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1027     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1028     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1029        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1030     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1031        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1032     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1033        "Assembly path was changed\n");
1034     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1035
1036     /* empty pszAssemblyName */
1037     INIT_ASM_INFO();
1038     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1039                                           empty, &info);
1040     todo_wine
1041     {
1042         ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1043     }
1044     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1045        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1046     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1047     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1048        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1049     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1050        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1051     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1052        "Assembly path was changed\n");
1053     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1054
1055     /* no dwFlags */
1056     INIT_ASM_INFO();
1057     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, wine, &info);
1058     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1059        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1060     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1061        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1062     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1063        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1064     todo_wine
1065     {
1066         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1067         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1068            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1069         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1070            "Wrong assembly path returned\n");
1071         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1072            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1073     }
1074
1075     /* pwzCachePath is full filename */
1076     INIT_ASM_INFO();
1077     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, winedll, &info);
1078     todo_wine
1079     {
1080         ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1081            "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1082     }
1083     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1084        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1085     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1086     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1087        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1088     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1089        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1090     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1091        "Assembly path was changed\n");
1092     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1093
1094     /* NULL pAsmInfo, QUERYASMINFO_FLAG_VALIDATE */
1095     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1096                                           wine, NULL);
1097     todo_wine
1098     {
1099         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1100     }
1101
1102     /* NULL pAsmInfo, QUERYASMINFO_FLAG_GETSIZE */
1103     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1104                                           wine, NULL);
1105     todo_wine
1106     {
1107         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1108     }
1109
1110     /* info.cbAssemblyInfo is 0 */
1111     INIT_ASM_INFO();
1112     info.cbAssemblyInfo = 0;
1113     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1114                                           wine, &info);
1115     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1116        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1117     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1118        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1119     todo_wine
1120     {
1121         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1122         ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1123            "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1124         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1125            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1126         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1127            "Wrong assembly path returned\n");
1128         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1129            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1130     }
1131
1132     /* info.cbAssemblyInfo is 1 */
1133     INIT_ASM_INFO();
1134     info.cbAssemblyInfo = 1;
1135     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1136                                           wine, &info);
1137     todo_wine
1138     {
1139         ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1140     }
1141     ok(info.cbAssemblyInfo == 1, "Expected 1, got %d\n", info.cbAssemblyInfo);
1142     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1143     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1144        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1145     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1146        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1147     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1148        "Assembly path was changed\n");
1149     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1150
1151     /* info.cbAssemblyInfo is > sizeof(ASSEMBLY_INFO) */
1152     INIT_ASM_INFO();
1153     info.cbAssemblyInfo = sizeof(ASSEMBLY_INFO) * 2;
1154     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1155                                           wine, &info);
1156     todo_wine
1157     {
1158         ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1159     }
1160     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO) * 2,
1161        "Expected sizeof(ASSEMBLY_INFO) * 2, got %d\n", info.cbAssemblyInfo);
1162     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1163     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1164        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1165     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1166        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1167     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1168        "Assembly path was changed\n");
1169     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1170
1171     /* QUERYASMINFO_FLAG_GETSIZE */
1172     INIT_ASM_INFO();
1173     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1174                                           wine, &info);
1175     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1176        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1177     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1178        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1179     todo_wine
1180     {
1181         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1182         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1183            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1184         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1185            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1186         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1187            "Wrong assembly path returned\n");
1188         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1189            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1190     }
1191
1192     /* QUERYASMINFO_FLAG_GETSIZE and QUERYASMINFO_FLAG_VALIDATE */
1193     INIT_ASM_INFO();
1194     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE |
1195                                           QUERYASMINFO_FLAG_VALIDATE,wine, &info);
1196     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1197        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1198     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1199        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1200     todo_wine
1201     {
1202         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1203         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1204            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1205         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1206            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1207         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1208            "Wrong assembly path returned\n");
1209         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1210            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1211     }
1212
1213     /* info.pszCurrentAssemblyPathBuf is NULL */
1214     INIT_ASM_INFO();
1215     info.pszCurrentAssemblyPathBuf = NULL;
1216     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1217                                           wine, &info);
1218     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1219        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1220     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1221        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1222     todo_wine
1223     {
1224         ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
1225            "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got %08x\n", hr);
1226         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1227            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1228         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1229            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1230         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1231            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1232     }
1233
1234     /* info.cchBuf is exactly size of asmpath */
1235     INIT_ASM_INFO();
1236     info.cchBuf = lstrlenW(asmpath);
1237     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1238                                           wine, &info);
1239     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1240        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1241     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1242        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1243     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1244        "Assembly path was changed\n");
1245     todo_wine
1246     {
1247         ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
1248            "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got %08x\n", hr);
1249         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1250            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1251         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1252            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1253         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1254            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1255     }
1256
1257     /* info.cchBuf has room for NULL-terminator */
1258     INIT_ASM_INFO();
1259     info.cchBuf = lstrlenW(asmpath) + 1;
1260     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1261                                           wine, &info);
1262     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1263        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1264     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1265        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1266     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1267        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1268     todo_wine
1269     {
1270         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1271         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1272            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1273         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1274            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1275         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1276            "Wrong assembly path returned\n");
1277     }
1278
1279     /* display name is "wine, Version=1.0.0.0" */
1280     INIT_ASM_INFO();
1281     lstrcpyW(name, wine);
1282     lstrcatW(name, commasep);
1283     lstrcatW(name, ver);
1284     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1285                                           name, &info);
1286     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1287        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1288     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1289        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1290     todo_wine
1291     {
1292         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1293         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1294            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1295         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1296            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1297         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1298            "Wrong assembly path returned\n");
1299         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1300            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1301     }
1302
1303     /* display name is "wine, Version=1.0.0.1", versions don't match */
1304     INIT_ASM_INFO();
1305     lstrcpyW(name, wine);
1306     lstrcatW(name, commasep);
1307     lstrcatW(name, badver);
1308     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1309                                           name, &info);
1310     todo_wine
1311     {
1312         ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1313            "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1314     }
1315     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1316        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1317     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1318     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1319        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1320     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1321        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1322     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1323        "Assembly path was changed\n");
1324     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1325
1326     /* display name is "wine, Culture=neutral" */
1327     INIT_ASM_INFO();
1328     lstrcpyW(name, wine);
1329     lstrcatW(name, commasep);
1330     lstrcatW(name, culture);
1331     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1332                                           name, &info);
1333     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1334        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1335     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1336        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1337     todo_wine
1338     {
1339         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1340         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1341            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1342         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1343            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1344         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1345            "Wrong assembly path returned\n");
1346         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1347            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1348     }
1349
1350     /* display name is "wine, Culture=en", cultures don't match */
1351     INIT_ASM_INFO();
1352     lstrcpyW(name, wine);
1353     lstrcatW(name, commasep);
1354     lstrcatW(name, badculture);
1355     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1356                                           name, &info);
1357     todo_wine
1358     {
1359         ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1360            "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1361     }
1362     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1363        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1364     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1365     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1366        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1367     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1368        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1369     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1370        "Assembly path was changed\n");
1371     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1372
1373     /* display name is "wine, PublicKeyTokens=2d03617b1c31e2f5" */
1374     INIT_ASM_INFO();
1375     lstrcpyW(name, wine);
1376     lstrcatW(name, commasep);
1377     lstrcatW(name, pubkey);
1378     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1379                                           name, &info);
1380     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1381        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1382     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1383        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1384     todo_wine
1385     {
1386         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1387         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1388            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1389         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1390            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1391         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1392            "Wrong assembly path returned\n");
1393         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1394            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1395     }
1396
1397     /* display name is "wine, PublicKeyToken=aaaaaaaaaaaaaaaa", pubkeys don't match */
1398     INIT_ASM_INFO();
1399     lstrcpyW(name, wine);
1400     lstrcatW(name, commasep);
1401     lstrcatW(name, badpubkey);
1402     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1403                                           name, &info);
1404     todo_wine
1405     {
1406         ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1407            "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1408     }
1409     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1410        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1411     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1412     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1413        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1414     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1415        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1416     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1417        "Assembly path was changed\n");
1418     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1419
1420     /* display name is "wine, BadProp=buh", bad property */
1421     INIT_ASM_INFO();
1422     lstrcpyW(name, wine);
1423     lstrcatW(name, commasep);
1424     lstrcatW(name, badprop);
1425     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1426                                           name, &info);
1427     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1428        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1429     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1430        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1431     todo_wine
1432     {
1433         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1434         ok(info.uliAssemblySizeInKB.u.LowPart == 4,
1435            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1436         ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1437            "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1438         ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1439            "Wrong assembly path returned\n");
1440         ok(info.cchBuf == lstrlenW(asmpath) + 1,
1441            "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1442     }
1443
1444     /* uninstall the assembly from the GAC */
1445     disp = 0xf00dbad;
1446     hr = IAssemblyCache_UninstallAssembly(cache, 0, wine, NULL, &disp);
1447     todo_wine
1448     {
1449         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1450         ok(disp == IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED,
1451            "Expected IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED, got %d\n", disp);
1452     }
1453
1454     /* FIXME: remove once UninstallAssembly is implemented */
1455     DeleteFileA("C:\\windows\\assembly\\GAC_MSIL\\wine\\"
1456                 "1.0.0.0__2d03617b1c31e2f5\\wine.dll");
1457     RemoveDirectoryA("C:\\windows\\assembly\\GAC_MSIL\\wine\\1.0.0.0__2d03617b1c31e2f5");
1458     RemoveDirectoryA("C:\\windows\\assembly\\GAC_MSIL\\wine");
1459
1460     DeleteFileA("test.dll");
1461     DeleteFileA("wine.dll");
1462     IAssemblyCache_Release(cache);
1463 }
1464
1465 START_TEST(asmcache)
1466 {
1467     if (!init_functionpointers())
1468         return;
1469
1470     test_CreateAssemblyCache();
1471     test_InstallAssembly();
1472     test_QueryAssemblyInfo();
1473 }