Release 1.5.29.
[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_HDR32_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         win_skip("mscoree.dll not available\n");
763         return FALSE;
764     }
765
766     pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
767     if (!pLoadLibraryShim)
768     {
769         win_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         win_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         win_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 BOOL check_dotnet20(void)
839 {
840     IAssemblyCache *cache;
841     HRESULT hr;
842     BOOL ret = FALSE;
843     ULONG disp;
844
845     static const WCHAR winedll[] = {'w','i','n','e','.','d','l','l',0};
846
847     create_assembly("wine.dll");
848
849     hr = pCreateAssemblyCache(&cache, 0);
850     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
851
852     hr = IAssemblyCache_InstallAssembly(cache, 0, winedll, NULL);
853     if (hr == S_OK)
854         ret = TRUE;
855     else if (hr == CLDB_E_FILE_OLDVER)
856         win_skip("Tests can't be run on older .NET version (.NET 1.1)\n");
857     else if (hr == E_ACCESSDENIED)
858         skip("Not enough rights to install an assembly\n");
859     else
860         ok(0, "Expected S_OK, got %08x\n", hr);
861
862     DeleteFileA("wine.dll");
863     IAssemblyCache_UninstallAssembly(cache, 0, winedll, NULL, &disp);
864     IAssemblyCache_Release(cache);
865     return ret;
866 }
867
868 static void test_CreateAssemblyCache(void)
869 {
870     IAssemblyCache *cache;
871     HRESULT hr;
872
873     /* NULL ppAsmCache */
874     hr = pCreateAssemblyCache(NULL, 0);
875     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
876
877     /* dwReserved is non-zero */
878     hr = pCreateAssemblyCache(&cache, 42);
879     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
880
881     IAssemblyCache_Release(cache);
882 }
883
884 static void test_InstallAssembly(void)
885 {
886     IAssemblyCache *cache;
887     HRESULT hr;
888     ULONG disp;
889     DWORD attr;
890     char dllpath[MAX_PATH];
891
892     static const WCHAR empty[] = {0};
893     static const WCHAR noext[] = {'f','i','l','e',0};
894     static const WCHAR badext[] = {'f','i','l','e','.','b','a','d',0};
895     static const WCHAR dllext[] = {'f','i','l','e','.','d','l','l',0};
896     static const WCHAR exeext[] = {'f','i','l','e','.','e','x','e',0};
897     static const WCHAR testdll[] = {'t','e','s','t','.','d','l','l',0};
898     static const WCHAR winedll[] = {'w','i','n','e','.','d','l','l',0};
899     static const WCHAR wine[] = {'w','i','n','e',0};
900
901     create_file("test.dll", 100);
902     create_assembly("wine.dll");
903
904     hr = pCreateAssemblyCache(&cache, 0);
905     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
906
907     /* NULL pszManifestFilePath */
908     hr = IAssemblyCache_InstallAssembly(cache, 0, NULL, NULL);
909     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
910
911     /* empty pszManifestFilePath */
912     hr = IAssemblyCache_InstallAssembly(cache, 0, empty, NULL);
913     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
914
915     /* pszManifestFilePath has no extension */
916     hr = IAssemblyCache_InstallAssembly(cache, 0, noext, NULL);
917     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME),
918        "Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x\n", hr);
919
920     /* pszManifestFilePath has bad extension */
921     hr = IAssemblyCache_InstallAssembly(cache, 0, badext, NULL);
922     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME),
923        "Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x\n", hr);
924
925     /* pszManifestFilePath has dll extension */
926     hr = IAssemblyCache_InstallAssembly(cache, 0, dllext, NULL);
927     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
928        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
929
930     /* pszManifestFilePath has exe extension */
931     hr = IAssemblyCache_InstallAssembly(cache, 0, exeext, NULL);
932     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
933        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
934
935     /* empty file */
936     hr = IAssemblyCache_InstallAssembly(cache, 0, testdll, NULL);
937     ok(hr == COR_E_ASSEMBLYEXPECTED,
938        "Expected COR_E_ASSEMBLYEXPECTED, got %08x\n", hr);
939
940     /* wine assembly */
941     hr = IAssemblyCache_InstallAssembly(cache, 0, winedll, NULL);
942     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
943
944     GetWindowsDirectoryA(dllpath, MAX_PATH);
945     strcat(dllpath, "\\assembly\\GAC_MSIL\\wine\\\\1.0.0.0__2d03617b1c31e2f5\\wine.dll");
946
947     attr = GetFileAttributes(dllpath);
948     ok(attr != INVALID_FILE_ATTRIBUTES, "Expected assembly to exist\n");
949
950     /* uninstall the assembly from the GAC */
951     disp = 0xf00dbad;
952     hr = IAssemblyCache_UninstallAssembly(cache, 0, wine, NULL, &disp);
953     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
954     ok(disp == IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED,
955        "Expected IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED, got %d\n", disp);
956
957     attr = GetFileAttributes(dllpath);
958     ok(attr == INVALID_FILE_ATTRIBUTES, "Expected assembly not to exist\n");
959
960     disp = 0xf00dbad;
961     hr = IAssemblyCache_UninstallAssembly(cache, 0, wine, NULL, &disp);
962     ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
963     ok(disp == IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED,
964        "Expected IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED, got %d\n", disp);
965
966     DeleteFileA("test.dll");
967     DeleteFileA("wine.dll");
968     IAssemblyCache_Release(cache);
969 }
970
971 #define INIT_ASM_INFO() \
972     ZeroMemory(&info, sizeof(ASSEMBLY_INFO)); \
973     info.cbAssemblyInfo = sizeof(ASSEMBLY_INFO); \
974     info.pszCurrentAssemblyPathBuf = path; \
975     info.cchBuf = MAX_PATH; \
976     path[0] = '\0';
977
978 static void test_QueryAssemblyInfo(void)
979 {
980     IAssemblyCache *cache;
981     ASSEMBLY_INFO info;
982     WCHAR path[MAX_PATH];
983     WCHAR asmpath[MAX_PATH];
984     WCHAR name[MAX_PATH];
985     HRESULT hr;
986     DWORD size;
987     ULONG disp;
988
989     static const WCHAR empty[] = {0};
990     static const WCHAR commasep[] = {',',' ',0};
991     static const WCHAR winedll[] = {'w','i','n','e','.','d','l','l',0};
992     static const WCHAR wine[] = {'w','i','n','e',0};
993     static const WCHAR ver[] = {
994         'V','e','r','s','i','o','n','=','1','.','0','.','0','.','0',0};
995     static const WCHAR otherver[] = {
996         'V','e','r','s','i','o','n','=','1','.','0','.','0','.','0','0','0','0','0',0};
997     static const WCHAR badver[] = {
998         'V','e','r','s','i','o','n','=','1','.','0','.','0','.','1',0};
999     static const WCHAR culture[] = {
1000         'C','u','l','t','u','r','e','=','n','e','u','t','r','a','l',0};
1001     static const WCHAR badculture[] = {
1002         'C','u','l','t','u','r','e','=','e','n',0};
1003     static const WCHAR pubkey[] = {
1004         'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',
1005         '2','d','0','3','6','1','7','b','1','c','3','1','e','2','f','5',0};
1006     static const WCHAR badpubkey[] = {
1007         'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',
1008         'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0};
1009     static const WCHAR badprop[] = {'B','a','d','P','r','o','p','=','b','u','h',0};
1010     static const WCHAR msil[] = {
1011         '_','M','S','I','L','\\','w','i','n','e','\\',
1012         '1','.','0','.','0','.','0','_','_','2','d','0','3','6','1','7','b',
1013         '1','c','3','1','e','2','f','5','\\',0};
1014     static const WCHAR wine2[] = {
1015         'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','1',',',
1016         'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=',
1017         '2','d','0','3','6','1','7','b','1','c','3','1','e','2','f','5',',',
1018         'c','u','l','t','u','r','e','=','n','e','u','t','r','a','l',0};
1019     static const WCHAR nullpublickey[] = {
1020         'm','s','c','o','r','l','i','b','.','d','l','l',',','v','e','r','s','i','o','n','=','0','.','0','.',
1021         '0','.','0',',','c','u','l','t','u','r','e','=','n','e','u','t','r','a','l',',',
1022         'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=','n','u','l','l',0};
1023     static const WCHAR nullpublickey1[] = {
1024         'm','s','c','o','r','l','i','b','.','d','l','l',',',
1025         'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=','n','u','L','l',0};
1026
1027     size = MAX_PATH;
1028     hr = pGetCachePath(ASM_CACHE_GAC, asmpath, &size);
1029     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1030
1031     lstrcatW(asmpath, msil);
1032     lstrcatW(asmpath, winedll);
1033
1034     create_assembly("wine.dll");
1035
1036     hr = pCreateAssemblyCache(&cache, 0);
1037     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1038
1039     /* assembly not installed yet */
1040     INIT_ASM_INFO();
1041     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, wine, &info);
1042     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1043        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
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     hr = IAssemblyCache_InstallAssembly(cache, 0, winedll, NULL);
1056     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1057
1058     /* NULL pszAssemblyName */
1059     INIT_ASM_INFO();
1060     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1061                                           NULL, &info);
1062     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1063     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1064        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1065     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1066     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1067        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1068     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1069        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1070     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1071        "Assembly path was changed\n");
1072     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1073
1074     /* empty pszAssemblyName */
1075     INIT_ASM_INFO();
1076     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1077                                           empty, &info);
1078     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1079     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1080        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1081     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1082     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1083        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1084     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1085        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1086     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1087        "Assembly path was changed\n");
1088     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1089
1090     /* no dwFlags */
1091     INIT_ASM_INFO();
1092     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, wine, &info);
1093     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1094     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1095        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1096     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1097        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1098     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1099        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1100     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1101        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1102     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1103        "Wrong assembly path returned\n");
1104     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1105        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1106
1107     /* pwzCachePath is full filename */
1108     INIT_ASM_INFO();
1109     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, winedll, &info);
1110     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1111        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1112     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1113        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1114     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
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     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1120        "Assembly path was changed\n");
1121     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1122
1123     /* NULL pAsmInfo, QUERYASMINFO_FLAG_VALIDATE */
1124     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1125                                           wine, NULL);
1126     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1127
1128     /* NULL pAsmInfo, QUERYASMINFO_FLAG_GETSIZE */
1129     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1130                                           wine, NULL);
1131     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1132
1133     /* info.cbAssemblyInfo is 0 */
1134     INIT_ASM_INFO();
1135     info.cbAssemblyInfo = 0;
1136     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1137                                           wine, &info);
1138     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1139     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1140        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1141     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1142        "Expected ASSEMBLYINFO_FLAG_INSTALLED, 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, asmpath),
1148        "Wrong assembly path returned\n");
1149     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1150        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1151
1152     /* info.cbAssemblyInfo is 1 */
1153     INIT_ASM_INFO();
1154     info.cbAssemblyInfo = 1;
1155     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1156                                           wine, &info);
1157     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1158     ok(info.cbAssemblyInfo == 1, "Expected 1, got %d\n", info.cbAssemblyInfo);
1159     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1160     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1161        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1162     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1163        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1164     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1165        "Assembly path was changed\n");
1166     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1167
1168     /* info.cbAssemblyInfo is > sizeof(ASSEMBLY_INFO) */
1169     INIT_ASM_INFO();
1170     info.cbAssemblyInfo = sizeof(ASSEMBLY_INFO) * 2;
1171     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1172                                           wine, &info);
1173     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1174     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO) * 2,
1175        "Expected sizeof(ASSEMBLY_INFO) * 2, got %d\n", info.cbAssemblyInfo);
1176     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1177     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1178        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1179     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1180        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1181     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1182        "Assembly path was changed\n");
1183     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1184
1185     /* QUERYASMINFO_FLAG_GETSIZE */
1186     INIT_ASM_INFO();
1187     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1188                                           wine, &info);
1189     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1190     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1191        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1192     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1193        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1194     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1195        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1196     todo_wine
1197     {
1198         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1199            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1200     }
1201     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1202        "Wrong assembly path returned\n");
1203     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1204        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1205
1206     /* QUERYASMINFO_FLAG_GETSIZE and QUERYASMINFO_FLAG_VALIDATE */
1207     INIT_ASM_INFO();
1208     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE |
1209                                           QUERYASMINFO_FLAG_VALIDATE,wine, &info);
1210     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1211     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1212        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1213     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1214        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1215     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1216        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1217     todo_wine
1218     {
1219         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1220            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1221     }
1222     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1223        "Wrong assembly path returned\n");
1224     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1225        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1226
1227     /* info.pszCurrentAssemblyPathBuf is NULL */
1228     INIT_ASM_INFO();
1229     info.pszCurrentAssemblyPathBuf = NULL;
1230     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1231                                           wine, &info);
1232     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1233        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1234     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1235        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1236     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1237        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1238     ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
1239        "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got %08x\n", hr);
1240     todo_wine
1241     {
1242         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1243            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1244     }
1245     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1246        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1247
1248     /* info.cchBuf is exactly size of asmpath */
1249     INIT_ASM_INFO();
1250     info.cchBuf = lstrlenW(asmpath);
1251     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1252                                           wine, &info);
1253     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1254        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1255     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1256        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1257     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1258        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1259     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1260        "Assembly path was changed\n");
1261     ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
1262        "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got %08x\n", hr);
1263     todo_wine
1264     {
1265         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1266            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1267     }
1268     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1269        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1270
1271     /* info.cchBuf has room for NULL-terminator */
1272     INIT_ASM_INFO();
1273     info.cchBuf = lstrlenW(asmpath) + 1;
1274     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1275                                           wine, &info);
1276     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1277     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1278        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1279     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1280        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1281     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1282        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1283     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1284        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1285     todo_wine
1286     {
1287         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1288            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1289     }
1290     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1291        "Wrong assembly path returned\n");
1292
1293     /* display name is "wine, Version=1.0.0.0" */
1294     INIT_ASM_INFO();
1295     lstrcpyW(name, wine);
1296     lstrcatW(name, commasep);
1297     lstrcatW(name, ver);
1298     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1299                                           name, &info);
1300     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1301     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1302        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1303     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1304        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1305     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1306        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1307     todo_wine
1308     {
1309         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1310            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1311     }
1312     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1313        "Wrong assembly path returned\n");
1314     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1315        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1316
1317     /* short buffer, QUERYASMINFO_FLAG_VALIDATE */
1318     memset(&info, 0, sizeof(info));
1319     lstrcpyW(name, wine);
1320     lstrcatW(name, commasep);
1321     lstrcatW(name, otherver);
1322     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
1323                                           name, &info);
1324     ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %08x\n", hr);
1325     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED, "got %08x\n", info.dwAssemblyFlags);
1326
1327     /* short buffer, QUERYASMINFO_FLAG_GETSIZE */
1328     memset(&info, 0, sizeof(info));
1329     lstrcpyW(name, wine);
1330     lstrcatW(name, commasep);
1331     lstrcatW(name, otherver);
1332     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1333                                           name, &info);
1334     ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %08x\n", hr);
1335     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED, "got %08x\n", info.dwAssemblyFlags);
1336
1337     /* display name is "wine, Version=1.0.0.00000" */
1338     INIT_ASM_INFO();
1339     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1340                                           name, &info);
1341     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1342     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1343        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1344     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1345        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1346     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1347        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1348     todo_wine
1349     {
1350         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1351            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1352     }
1353     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1354        "Wrong assembly path returned\n");
1355     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1356        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1357
1358     /* display name is "wine, Version=1.0.0.1", versions don't match */
1359     INIT_ASM_INFO();
1360     lstrcpyW(name, wine);
1361     lstrcatW(name, commasep);
1362     lstrcatW(name, badver);
1363     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1364                                           name, &info);
1365     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1366        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1367     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1368        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1369     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1370     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1371        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1372     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1373        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1374     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1375        "Assembly path was changed\n");
1376     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1377
1378     /* display name is "wine,version=1.0.0.1,publicKeyToken=2d03617b1c31e2f5,culture=neutral" */
1379     INIT_ASM_INFO();
1380     lstrcpyW(name, wine2);
1381     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1382                                           name, &info);
1383     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1384        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1385     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1386        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1387     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1388     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1389        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1390     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1391        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1392     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1393        "Assembly path was changed\n");
1394     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1395
1396     /* display name is "mscorlib.dll,version=0.0.0.0,culture=neutral,publicKeyToken=null" */
1397     INIT_ASM_INFO();
1398     lstrcpyW(name, nullpublickey);
1399     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, name, &info);
1400     ok(hr == FUSION_E_PRIVATE_ASM_DISALLOWED, "got %08x\n", hr);
1401
1402     /* display name is "mscorlib.dll,publicKeyToken=nuLl" */
1403     INIT_ASM_INFO();
1404     lstrcpyW(name, nullpublickey1);
1405     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, name, &info);
1406     ok(hr == FUSION_E_PRIVATE_ASM_DISALLOWED, "got %08x\n", hr);
1407
1408     /* display name is "wine, Culture=neutral" */
1409     INIT_ASM_INFO();
1410     lstrcpyW(name, wine);
1411     lstrcatW(name, commasep);
1412     lstrcatW(name, culture);
1413     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1414                                           name, &info);
1415     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1416     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1417        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1418     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1419        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1420     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1421        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1422     todo_wine
1423     {
1424         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1425            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1426     }
1427     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1428        "Wrong assembly path returned\n");
1429     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1430        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1431
1432     /* display name is "wine, Culture=en", cultures don't match */
1433     INIT_ASM_INFO();
1434     lstrcpyW(name, wine);
1435     lstrcatW(name, commasep);
1436     lstrcatW(name, badculture);
1437     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1438                                           name, &info);
1439     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1440        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1441     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1442     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1443        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1444     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1445        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1446     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1447        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1448     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1449        "Assembly path was changed\n");
1450     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1451
1452     /* display name is "wine, PublicKeyTokens=2d03617b1c31e2f5" */
1453     INIT_ASM_INFO();
1454     lstrcpyW(name, wine);
1455     lstrcatW(name, commasep);
1456     lstrcatW(name, pubkey);
1457     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1458                                           name, &info);
1459     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1460     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1461        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1462     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1463        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1464     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1465        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1466     todo_wine
1467     {
1468         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1469            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1470     }
1471     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1472        "Wrong assembly path returned\n");
1473     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1474        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1475
1476     /* display name is "wine, PublicKeyToken=aaaaaaaaaaaaaaaa", pubkeys don't match */
1477     INIT_ASM_INFO();
1478     lstrcpyW(name, wine);
1479     lstrcatW(name, commasep);
1480     lstrcatW(name, badpubkey);
1481     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1482                                           name, &info);
1483     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
1484        "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr);
1485     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1486        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1487     ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags);
1488     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1489        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1490     ok(info.uliAssemblySizeInKB.u.LowPart == 0,
1491        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1492     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty),
1493        "Assembly path was changed\n");
1494     ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf);
1495
1496     /* display name is "wine, BadProp=buh", bad property */
1497     INIT_ASM_INFO();
1498     lstrcpyW(name, wine);
1499     lstrcatW(name, commasep);
1500     lstrcatW(name, badprop);
1501     hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE,
1502                                           name, &info);
1503     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1504     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1505        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1506     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1507        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1508     ok(info.uliAssemblySizeInKB.u.HighPart == 0,
1509        "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart);
1510     todo_wine
1511     {
1512         ok((info.uliAssemblySizeInKB.u.LowPart == 4),
1513            "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart);
1514     }
1515     ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath),
1516        "Wrong assembly path returned\n");
1517     ok(info.cchBuf == lstrlenW(asmpath) + 1,
1518        "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf);
1519
1520     /* no flags, display name is "wine, Version=1.0.0.0" */
1521     INIT_ASM_INFO();
1522     info.pszCurrentAssemblyPathBuf = NULL;
1523     info.cchBuf = 0;
1524     lstrcpyW(name, wine);
1525     lstrcatW(name, commasep);
1526     lstrcatW(name, ver);
1527     hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, name, &info);
1528     ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
1529        "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got %08x\n", hr);
1530     ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO),
1531        "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo);
1532     ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED,
1533        "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", info.dwAssemblyFlags);
1534
1535     /* uninstall the assembly from the GAC */
1536     disp = 0xf00dbad;
1537     hr = IAssemblyCache_UninstallAssembly(cache, 0, wine, NULL, &disp);
1538     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1539     ok(disp == IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED,
1540        "Expected IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED, got %d\n", disp);
1541
1542     DeleteFileA("test.dll");
1543     DeleteFileA("wine.dll");
1544     IAssemblyCache_Release(cache);
1545 }
1546
1547 START_TEST(asmcache)
1548 {
1549     if (!init_functionpointers())
1550         return;
1551
1552     if (!check_dotnet20())
1553         return;
1554
1555     test_CreateAssemblyCache();
1556     test_InstallAssembly();
1557     test_QueryAssemblyInfo();
1558 }