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