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 WIN32_NO_STATUS
20 #define _INC_WINDOWS
21 #define COM_NO_WINDOWS_H
22 
23 #define COBJMACROS
24 
25 //#include <stdio.h>
26 #include <stdarg.h>
27 
28 //#include <windows.h>
29 #include <windef.h>
30 #include <winbase.h>
31 #include <winnls.h>
32 #include <objbase.h>
33 //#include <mscoree.h>
34 #include <fusion.h>
35 #include <corerror.h>
36 #include <strsafe.h>
37 
38 #include <wine/test.h>
39 
40 /* ok-like statement which takes two unicode strings or one unicode and one ANSI string as arguments */
41 static CHAR string1[MAX_PATH];
42 
43 #define ok_aw(aString, wString) \
44     WideCharToMultiByte(CP_ACP, 0, wString, -1, string1, MAX_PATH, NULL, NULL); \
45     if (lstrcmpA(string1, aString) != 0) \
46         ok(0, "Expected \"%s\", got \"%s\"\n", aString, string1);
47 
48 static HRESULT (WINAPI *pCreateAssemblyNameObject)(IAssemblyName **ppAssemblyNameObj,
49                                                    LPCWSTR szAssemblyName, DWORD dwFlags,
50                                                    LPVOID pvReserved);
51 static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion,
52                                           LPVOID pvReserved, HMODULE *phModDll);
53 
54 static BOOL init_functionpointers(void)
55 {
56     HRESULT hr;
57     HMODULE hfusion;
58     HMODULE hmscoree;
59 
60     static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
61 
62     hmscoree = LoadLibraryA("mscoree.dll");
63     if (!hmscoree)
64         return FALSE;
65 
66     pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
67     if (!pLoadLibraryShim)
68     {
69         FreeLibrary(hmscoree);
70         return FALSE;
71     }
72 
73     hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion);
74     if (FAILED(hr))
75         return FALSE;
76 
77     pCreateAssemblyNameObject = (void *)GetProcAddress(hfusion, "CreateAssemblyNameObject");
78     if (!pCreateAssemblyNameObject)
79         return FALSE;
80 
81     return TRUE;
82 }
83 
84 typedef struct _tagASMPROP_RES
85 {
86     HRESULT hr;
87     CHAR val[MAX_PATH];
88     DWORD size;
89 } ASMPROP_RES;
90 
91 static const ASMPROP_RES defaults[ASM_NAME_MAX_PARAMS] =
92 {
93     {S_OK, "", 0},
94     {S_OK, "", 0},
95     {S_OK, "", 0},
96     {S_OK, "", 0},
97     {S_OK, "", 0},
98     {S_OK, "", 0},
99     {S_OK, "", 0},
100     {S_OK, "", 0},
101     {S_OK, "", 0},
102     {S_OK, "", 0},
103     {S_OK, "", 0},
104     {S_OK, "", 0},
105     {S_OK, "", 0},
106     {S_OK, "", 0},
107     {S_OK, "", 0},
108     {S_FALSE, "", MAX_PATH},
109     {S_FALSE, "", MAX_PATH},
110     {S_OK, "", 0},
111     {S_OK, "", MAX_PATH},
112     {S_OK, "", 0},
113     {S_OK, "", 0},
114     {S_OK, "", 0},
115     {S_OK, "", 0},
116     {S_OK, "", 0},
117     {S_OK, "", 0},
118     {S_OK, "", 0},
119     {S_OK, "", 0},
120     {S_OK, "", 0}
121 };
122 
123 static const ASMPROP_RES emptyname[ASM_NAME_MAX_PARAMS] =
124 {
125     {S_OK, "", 0},
126     {S_OK, "", 0},
127     {S_OK, "", 0},
128     {S_OK, "", 2},
129     {S_OK, "", 0},
130     {S_OK, "", 0},
131     {S_OK, "", 0},
132     {S_OK, "", 0},
133     {S_OK, "", 0},
134     {S_OK, "", 0},
135     {S_OK, "", 0},
136     {S_OK, "", 0},
137     {S_OK, "", 0},
138     {S_OK, "", 0},
139     {S_OK, "", 0},
140     {S_FALSE, "", MAX_PATH},
141     {S_FALSE, "", MAX_PATH},
142     {S_OK, "", 0},
143     {S_OK, "", MAX_PATH},
144     {S_OK, "", 0},
145     {S_OK, "", 0},
146     {S_OK, "", 0},
147     {S_OK, "", 0},
148     {S_OK, "", 0},
149     {S_OK, "", 0},
150     {S_OK, "", 0},
151     {S_OK, "", 0},
152     {S_OK, "", 0}
153 };
154 
155 static const ASMPROP_RES winename[ASM_NAME_MAX_PARAMS] =
156 {
157     {S_OK, "", 0},
158     {S_OK, "", 0},
159     {S_OK, "", 0},
160     {S_OK, "wine", 10},
161     {S_OK, "", 0},
162     {S_OK, "", 0},
163     {S_OK, "", 0},
164     {S_OK, "", 0},
165     {S_OK, "", 0},
166     {S_OK, "", 0},
167     {S_OK, "", 0},
168     {S_OK, "", 0},
169     {S_OK, "", 0},
170     {S_OK, "", 0},
171     {S_OK, "", 0},
172     {S_FALSE, "", MAX_PATH},
173     {S_FALSE, "", MAX_PATH},
174     {S_OK, "", 0},
175     {S_OK, "", MAX_PATH},
176     {S_OK, "", 0},
177     {S_OK, "", 0},
178     {S_OK, "", 0},
179     {S_OK, "", 0},
180     {S_OK, "", 0},
181     {S_OK, "", 0},
182     {S_OK, "", 0},
183     {S_OK, "", 0},
184     {S_OK, "", 0}
185 };
186 
187 static const ASMPROP_RES vername[ASM_NAME_MAX_PARAMS] =
188 {
189     {S_OK, "", 0},
190     {S_OK, "", 0},
191     {S_OK, "", 0},
192     {S_OK, "wine", 10},
193     {S_OK, "\x01", 2},
194     {S_OK, "\x02", 2},
195     {S_OK, "\x03", 2},
196     {S_OK, "\x04", 2},
197     {S_OK, "", 0},
198     {S_OK, "", 0},
199     {S_OK, "", 0},
200     {S_OK, "", 0},
201     {S_OK, "", 0},
202     {S_OK, "", 0},
203     {S_OK, "", 0},
204     {S_FALSE, "", MAX_PATH},
205     {S_FALSE, "", MAX_PATH},
206     {S_OK, "", 0},
207     {S_OK, "", MAX_PATH},
208     {S_OK, "", 0},
209     {S_OK, "", 0},
210     {S_OK, "", 0},
211     {S_OK, "", 0},
212     {S_OK, "", 0},
213     {S_OK, "", 0},
214     {S_OK, "", 0},
215     {S_OK, "", 0},
216     {S_OK, "", 0}
217 };
218 
219 static const ASMPROP_RES badvername[ASM_NAME_MAX_PARAMS] =
220 {
221     {S_OK, "", 0},
222     {S_OK, "", 0},
223     {S_OK, "", 0},
224     {S_OK, "wine", 10},
225     {S_OK, "\x01", 2},
226     {S_OK, "\x05", 2},
227     {S_OK, "", 0},
228     {S_OK, "", 0},
229     {S_OK, "", 0},
230     {S_OK, "", 0},
231     {S_OK, "", 0},
232     {S_OK, "", 0},
233     {S_OK, "", 0},
234     {S_OK, "", 0},
235     {S_OK, "", 0},
236     {S_FALSE, "", MAX_PATH},
237     {S_FALSE, "", MAX_PATH},
238     {S_OK, "", 0},
239     {S_OK, "", MAX_PATH},
240     {S_OK, "", 0},
241     {S_OK, "", 0},
242     {S_OK, "", 0},
243     {S_OK, "", 0},
244     {S_OK, "", 0},
245     {S_OK, "", 0},
246     {S_OK, "", 0},
247     {S_OK, "", 0},
248     {S_OK, "", 0}
249 };
250 
251 static const ASMPROP_RES neutralname[ASM_NAME_MAX_PARAMS] =
252 {
253     {S_OK, "", 0},
254     {S_OK, "", 0},
255     {S_OK, "", 0},
256     {S_OK, "wine", 10},
257     {S_OK, "", 0},
258     {S_OK, "", 0},
259     {S_OK, "", 0},
260     {S_OK, "", 0},
261     {S_OK, "", 2},
262     {S_OK, "", 0},
263     {S_OK, "", 0},
264     {S_OK, "", 0},
265     {S_OK, "", 0},
266     {S_OK, "", 0},
267     {S_OK, "", 0},
268     {S_FALSE, "", MAX_PATH},
269     {S_FALSE, "", MAX_PATH},
270     {S_OK, "", 0},
271     {S_OK, "", MAX_PATH},
272     {S_OK, "", 0},
273     {S_OK, "", 0},
274     {S_OK, "", 0},
275     {S_OK, "", 0},
276     {S_OK, "", 0},
277     {S_OK, "", 0},
278     {S_OK, "", 0},
279     {S_OK, "", 0},
280     {S_OK, "", 0}
281 };
282 
283 static const ASMPROP_RES enname[ASM_NAME_MAX_PARAMS] =
284 {
285     {S_OK, "", 0},
286     {S_OK, "", 0},
287     {S_OK, "", 0},
288     {S_OK, "wine", 10},
289     {S_OK, "", 0},
290     {S_OK, "", 0},
291     {S_OK, "", 0},
292     {S_OK, "", 0},
293     {S_OK, "en", 6},
294     {S_OK, "", 0},
295     {S_OK, "", 0},
296     {S_OK, "", 0},
297     {S_OK, "", 0},
298     {S_OK, "", 0},
299     {S_OK, "", 0},
300     {S_FALSE, "", MAX_PATH},
301     {S_FALSE, "", MAX_PATH},
302     {S_OK, "", 0},
303     {S_OK, "", MAX_PATH},
304     {S_OK, "", 0},
305     {S_OK, "", 0},
306     {S_OK, "", 0},
307     {S_OK, "", 0},
308     {S_OK, "", 0},
309     {S_OK, "", 0},
310     {S_OK, "", 0},
311     {S_OK, "", 0},
312     {S_OK, "", 0}
313 };
314 
315 static const ASMPROP_RES pubkeyname[ASM_NAME_MAX_PARAMS] =
316 {
317     {S_OK, "", 0},
318     {S_OK, "\x01\x23\x45\x67\x89\x0a\xbc\xde", 8},
319     {S_OK, "", 0},
320     {S_OK, "wine", 10},
321     {S_OK, "", 0},
322     {S_OK, "", 0},
323     {S_OK, "", 0},
324     {S_OK, "", 0},
325     {S_OK, "", 0},
326     {S_OK, "", 0},
327     {S_OK, "", 0},
328     {S_OK, "", 0},
329     {S_OK, "", 0},
330     {S_OK, "", 0},
331     {S_OK, "", 0},
332     {S_OK, "", MAX_PATH},
333     {S_OK, "", MAX_PATH},
334     {S_OK, "", 0},
335     {S_OK, "", MAX_PATH},
336     {S_OK, "", 0},
337     {S_OK, "", 0},
338     {S_OK, "", 0},
339     {S_OK, "", 0},
340     {S_OK, "", 0},
341     {S_OK, "", 0},
342     {S_OK, "", 0},
343     {S_OK, "", 0},
344     {S_OK, "", 0}
345 };
346 
347 static inline void to_widechar(LPWSTR dest, LPCSTR src)
348 {
349     MultiByteToWideChar(CP_ACP, 0, src, -1, dest, MAX_PATH);
350 }
351 
352 static void test_assembly_name_props_line(IAssemblyName *name,
353                                           const ASMPROP_RES *vals, int line)
354 {
355     HRESULT hr;
356     DWORD i, size;
357     WCHAR expect[MAX_PATH];
358     WCHAR str[MAX_PATH];
359 
360     for (i = 0; i < ASM_NAME_MAX_PARAMS; i++)
361     {
362         to_widechar(expect, vals[i].val);
363 
364         size = MAX_PATH;
365         memset( str, 0xcc, sizeof(str) );
366         hr = IAssemblyName_GetProperty(name, i, str, &size);
367 
368         ok(hr == vals[i].hr ||
369            broken(i >= ASM_NAME_CONFIG_MASK && hr == E_INVALIDARG) || /* .NET 1.1 */
370            broken(i >= ASM_NAME_FILE_MAJOR_VERSION && hr == E_INVALIDARG), /* .NET 1.0 */
371            "%d: prop %d: Expected %08x, got %08x\n", line, i, vals[i].hr, hr);
372         if (hr != E_INVALIDARG)
373         {
374             ok(size == vals[i].size, "%d: prop %d: Expected %d, got %d\n", line, i, vals[i].size, size);
375             if (!size)
376             {
377                 ok(str[0] == 0xcccc, "%d: prop %d: str[0] = %x\n", line, i, str[0]);
378             }
379             else if (size != MAX_PATH)
380             {
381                 if (i != ASM_NAME_NAME && i != ASM_NAME_CULTURE)
382                     ok( !memcmp( vals[i].val, str, size ), "%d: prop %d: wrong value\n", line, i );
383                 else
384                     ok( !lstrcmpW( expect, str ), "%d: prop %d: Expected %s, got %s\n",
385                         line, i, wine_dbgstr_w(expect), wine_dbgstr_w(str) );
386             }
387 
388             if (size != 0 && size != MAX_PATH)
389             {
390                 size--;
391                 hr = IAssemblyName_GetProperty(name, i, str, &size);
392                 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER,
393                         "%d: prop %d: Expected STRSAFE_E_INSUFFICIENT_BUFFER, got %08x\n", line, i, hr);
394                 ok(size == vals[i].size, "%d: prop %d: Expected %d, got %d\n", line, i, vals[i].size, size);
395             }
396         }
397     }
398 }
399 
400 #define test_assembly_name_props(name, vals) \
401     test_assembly_name_props_line(name, vals, __LINE__);
402 
403 static void test_CreateAssemblyNameObject(void)
404 {
405     IAssemblyName *name;
406     WCHAR str[MAX_PATH];
407     WCHAR namestr[MAX_PATH];
408     DWORD size, hi, lo;
409     PEKIND arch;
410     HRESULT hr;
411 
412     static const WCHAR empty[] = {0};
413 
414     /* NULL ppAssemblyNameObj */
415     to_widechar(namestr, "wine.dll");
416     hr = pCreateAssemblyNameObject(NULL, namestr, 0, NULL);
417     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
418 
419     /* NULL szAssemblyName, CANOF_PARSE_DISPLAY_NAME */
420     name = (IAssemblyName *)0xdeadbeef;
421     hr = pCreateAssemblyNameObject(&name, NULL, CANOF_PARSE_DISPLAY_NAME, NULL);
422     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
423     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
424 
425     /* empty szAssemblyName, CANOF_PARSE_DISPLAY_NAME */
426     name = (IAssemblyName *)0xdeadbeef;
427     hr = pCreateAssemblyNameObject(&name, empty, CANOF_PARSE_DISPLAY_NAME, NULL);
428     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
429     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
430 
431     /* check the contents of the AssemblyName for default values */
432 
433     /* NULL szAssemblyName */
434     name = NULL;
435     hr = pCreateAssemblyNameObject(&name, NULL, CANOF_SET_DEFAULT_VALUES, NULL);
436     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
437     ok(name != NULL, "Expected non-NULL name\n");
438 
439     size = MAX_PATH;
440     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
441     ok(hr == FUSION_E_INVALID_NAME ||
442        broken(hr == E_INVALIDARG), /* .NET 1.x */
443        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
444 
445     str[0] = 'a';
446     size = MAX_PATH;
447     hr = IAssemblyName_GetName(name, &size, str);
448     ok(hr == S_OK, "got %08x\n", hr);
449     ok(str[0] == 'a', "got %c\n", str[0]);
450     ok(!size, "got %u\n", size);
451 
452     hi = 0xbeefcace;
453     lo = 0xcafebabe;
454     hr = IAssemblyName_GetVersion(name, &hi, &lo);
455     ok(hr == FUSION_E_INVALID_NAME ||
456        broken(hr == S_OK), /* .NET 1.x */
457        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
458     ok(hi == 0, "Expected 0, got %08x\n", hi);
459     ok(lo == 0, "Expected 0, got %08x\n", lo);
460 
461     if (hr == S_OK)
462         win_skip(".NET 1.x doesn't handle ASM_NAME_PROCESSOR_ID_ARRAY"
463                  " and ASM_NAME_OSINFO_ARRAY correctly\n");
464     else
465         test_assembly_name_props(name, defaults);
466 
467     IAssemblyName_Release(name);
468 
469     /* empty szAssemblyName */
470     name = NULL;
471     hr = pCreateAssemblyNameObject(&name, empty, CANOF_SET_DEFAULT_VALUES, NULL);
472     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
473     ok(name != NULL, "Expected non-NULL name\n");
474 
475     size = MAX_PATH;
476     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
477     ok(hr == FUSION_E_INVALID_NAME ||
478        broken(hr == S_OK), /* .NET 1.x */
479        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
480 
481     size = 0;
482     hr = IAssemblyName_GetName(name, &size, NULL);
483     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr);
484     ok(size == 1, "got %u\n", size);
485 
486     if (0) /* crash */
487     {
488     str[0] = '\0';
489     hr = IAssemblyName_GetName(name, NULL, str);
490     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr);
491     ok(!str[0], "got %c\n", str[0]);
492     }
493 
494     size = 0;
495     str[0] = '\0';
496     hr = IAssemblyName_GetName(name, &size, str);
497     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr);
498     ok(!str[0], "got %c\n", str[0]);
499     ok(size == 1, "got %u\n", size);
500 
501     size = MAX_PATH;
502     str[0] = '\0';
503     hr = IAssemblyName_GetName(name, &size, str);
504     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
505     ok(!str[0], "Expected empty name\n");
506     ok(size == 1, "Expected 1, got %d\n", size);
507 
508     hi = 0xbeefcace;
509     lo = 0xcafebabe;
510     hr = IAssemblyName_GetVersion(name, &hi, &lo);
511     ok(hr == FUSION_E_INVALID_NAME ||
512        broken(hr == S_OK), /* .NET 1.x */
513        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
514     ok(hi == 0, "Expected 0, got %08x\n", hi);
515     ok(lo == 0, "Expected 0, got %08x\n", lo);
516 
517     if (hr == S_OK)
518         win_skip(".NET 1.x doesn't handle ASM_NAME_PROCESSOR_ID_ARRAY"
519                  " and ASM_NAME_OSINFO_ARRAY correctly\n");
520     else
521         test_assembly_name_props(name, emptyname);
522 
523     IAssemblyName_Release(name);
524 
525     /* 'wine' */
526     to_widechar(namestr, "wine");
527     name = NULL;
528     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_SET_DEFAULT_VALUES, NULL);
529     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
530     ok(name != NULL, "Expected non-NULL name\n");
531 
532     size = 0;
533     hr = IAssemblyName_GetDisplayName(name, NULL, &size, 0);
534     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr);
535     ok(size == 5, "got %u\n", size);
536 
537     size = 3;
538     hr = IAssemblyName_GetDisplayName(name, NULL, &size, 0);
539     ok(hr == E_NOT_SUFFICIENT_BUFFER || broken(hr == E_INVALIDARG), "got %08x\n", hr);
540     ok(size == 5 || broken(size == 3), "got %u\n", size);
541 
542     size = 3;
543     str[0] = 'a';
544     hr = IAssemblyName_GetDisplayName(name, str, &size, 0);
545     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr);
546     ok(str[0] == 'a', "got %c\n", str[0]);
547     ok(size == 5, "got %u\n", size);
548 
549     size = 0;
550     str[0] = 'a';
551     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
552     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr);
553     ok(str[0] == 'a', "got %c\n", str[0]);
554     ok(size == 5, "Wrong size %u\n", size);
555 
556     size = MAX_PATH;
557     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
558     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
559     ok_aw("wine", str);
560     ok(size == 5, "Expected 5, got %d\n", size);
561 
562     size = 0;
563     str[0] = 0;
564     hr = IAssemblyName_GetName(name, &size, str);
565     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got %08x\n", hr);
566     ok(!str[0], "got %c\n", str[0]);
567     ok(size == 5, "got %u\n", size);
568 
569     size = MAX_PATH;
570     str[0] = '\0';
571     hr = IAssemblyName_GetName(name, &size, str);
572     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
573     ok_aw("wine", str);
574     ok(size == 5, "Expected 5, got %d\n", size);
575 
576     hi = 0xbeefcace;
577     lo = 0xcafebabe;
578     hr = IAssemblyName_GetVersion(name, &hi, &lo);
579     ok(hr == FUSION_E_INVALID_NAME ||
580        broken(hr == S_OK), /* .NET 1.x */
581        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
582     ok(hi == 0, "Expected 0, got %08x\n", hi);
583     ok(lo == 0, "Expected 0, got %08x\n", lo);
584 
585     if (hr == S_OK)
586         win_skip(".NET 1.x doesn't handle ASM_NAME_PROCESSOR_ID_ARRAY"
587                  " and ASM_NAME_OSINFO_ARRAY correctly\n");
588     else
589         test_assembly_name_props(name, winename);
590 
591     IAssemblyName_Release(name);
592 
593     /* check the contents of the AssemblyName with parsing */
594 
595     /* 'wine' */
596     to_widechar(namestr, "wine");
597     name = NULL;
598     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
599     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
600     ok(name != NULL, "Expected non-NULL name\n");
601 
602     size = MAX_PATH;
603     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
604     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
605     ok_aw("wine", str);
606     ok(size == 5, "Expected 5, got %d\n", size);
607 
608     size = MAX_PATH;
609     str[0] = '\0';
610     hr = IAssemblyName_GetName(name, &size, str);
611     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
612     ok_aw("wine", str);
613     ok(size == 5, "Expected 5, got %d\n", size);
614 
615     hi = 0xbeefcace;
616     lo = 0xcafebabe;
617     hr = IAssemblyName_GetVersion(name, &hi, &lo);
618     ok(hr == FUSION_E_INVALID_NAME ||
619        broken(hr == S_OK), /* .NET 1.x */
620        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
621     ok(hi == 0, "Expected 0, got %08x\n", hi);
622     ok(lo == 0, "Expected 0, got %08x\n", lo);
623 
624     test_assembly_name_props(name, winename);
625 
626     IAssemblyName_Release(name);
627 
628     /* 'wine, Version=1.2.3.4' */
629     to_widechar(namestr, "wine, Version=1.2.3.4");
630     name = NULL;
631     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
632     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
633     ok(name != NULL, "Expected non-NULL name\n");
634 
635     size = MAX_PATH;
636     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
637     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
638     ok_aw("wine, Version=1.2.3.4", str);
639     ok(size == 22, "Expected 22, got %d\n", size);
640 
641     size = MAX_PATH;
642     str[0] = '\0';
643     hr = IAssemblyName_GetName(name, &size, str);
644     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
645     ok_aw("wine", str);
646     ok(size == 5, "Expected 5, got %d\n", size);
647 
648     hi = 0xbeefcace;
649     lo = 0xcafebabe;
650     hr = IAssemblyName_GetVersion(name, &hi, &lo);
651     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
652     ok(hi == 0x00010002, "Expected 0x00010002, got %08x\n", hi);
653     ok(lo == 0x00030004, "Expected 0x00030004, got %08x\n", lo);
654 
655     test_assembly_name_props(name, vername);
656 
657     IAssemblyName_Release(name);
658 
659     /* Version isn't of the form 1.x.x.x */
660     to_widechar(namestr, "wine, Version=1.5");
661     name = NULL;
662     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
663     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
664     ok(name != NULL, "Expected non-NULL name\n");
665 
666     size = MAX_PATH;
667     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
668     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
669     ok_aw("wine, Version=1.5", str);
670     ok(size == 18, "Expected 18, got %d\n", size);
671 
672     size = MAX_PATH;
673     str[0] = '\0';
674     hr = IAssemblyName_GetName(name, &size, str);
675     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
676     ok_aw("wine", str);
677     ok(size == 5, "Expected 5, got %d\n", size);
678 
679     hi = 0xbeefcace;
680     lo = 0xcafebabe;
681     hr = IAssemblyName_GetVersion(name, &hi, &lo);
682     ok(hr == FUSION_E_INVALID_NAME ||
683        broken(hr == S_OK), /* .NET 1.x */
684        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
685     ok(hi == 0 ||
686        broken(hi == 0x10005), /* .NET 1.x */
687        "Expected 0, got %08x\n", hi);
688     ok(lo == 0, "Expected 0, got %08x\n", lo);
689 
690     test_assembly_name_props(name, badvername);
691 
692     IAssemblyName_Release(name);
693 
694     /* 'wine, Culture=neutral' */
695     to_widechar(namestr, "wine, Culture=neutral");
696     name = NULL;
697     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
698     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
699     ok(name != NULL, "Expected non-NULL name\n");
700 
701     size = MAX_PATH;
702     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
703     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
704     ok_aw("wine, Culture=neutral", str);
705     ok(size == 22, "Expected 22, got %d\n", size);
706 
707     size = MAX_PATH;
708     str[0] = '\0';
709     hr = IAssemblyName_GetName(name, &size, str);
710     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
711     ok_aw("wine", str);
712     ok(size == 5, "Expected 5, got %d\n", size);
713 
714     hi = 0xbeefcace;
715     lo = 0xcafebabe;
716     hr = IAssemblyName_GetVersion(name, &hi, &lo);
717     ok(hr == FUSION_E_INVALID_NAME ||
718        broken(hr == S_OK), /* .NET 1.x */
719        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
720     ok(hi == 0, "Expected 0, got %08x\n", hi);
721     ok(lo == 0, "Expected 0, got %08x\n", lo);
722 
723     test_assembly_name_props(name, neutralname);
724 
725     IAssemblyName_Release(name);
726 
727     /* 'wine, Culture=en' */
728     to_widechar(namestr, "wine, Culture=en");
729     name = NULL;
730     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
731     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
732     ok(name != NULL, "Expected non-NULL name\n");
733 
734     size = MAX_PATH;
735     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
736     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
737     ok_aw("wine, Culture=en", str);
738     ok(size == 17, "Expected 17, got %d\n", size);
739 
740     size = MAX_PATH;
741     str[0] = '\0';
742     hr = IAssemblyName_GetName(name, &size, str);
743     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
744     ok_aw("wine", str);
745     ok(size == 5, "Expected 5, got %d\n", size);
746 
747     hi = 0xbeefcace;
748     lo = 0xcafebabe;
749     hr = IAssemblyName_GetVersion(name, &hi, &lo);
750     ok(hr == FUSION_E_INVALID_NAME ||
751        broken(hr == S_OK), /* .NET 1.x */
752        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
753     ok(hi == 0, "Expected 0, got %08x\n", hi);
754     ok(lo == 0, "Expected 0, got %08x\n", lo);
755 
756     test_assembly_name_props(name, enname);
757 
758     IAssemblyName_Release(name);
759 
760     /* 'wine, PublicKeyToken=01234567890abcde' */
761     to_widechar(namestr, "wine, PublicKeyToken=01234567890abcde");
762     name = NULL;
763     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
764     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
765     ok(name != NULL, "Expected non-NULL name\n");
766 
767     size = MAX_PATH;
768     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
769     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
770     ok_aw("wine, PublicKeyToken=01234567890abcde", str);
771     ok(size == 38, "Expected 38, got %d\n", size);
772 
773     size = MAX_PATH;
774     str[0] = '\0';
775     hr = IAssemblyName_GetName(name, &size, str);
776     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
777     ok_aw("wine", str);
778     ok(size == 5, "Expected 5, got %d\n", size);
779 
780     hi = 0xbeefcace;
781     lo = 0xcafebabe;
782     hr = IAssemblyName_GetVersion(name, &hi, &lo);
783     ok(hr == FUSION_E_INVALID_NAME ||
784        broken(hr == S_OK), /* .NET 1.x */
785        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
786     ok(hi == 0, "Expected 0, got %08x\n", hi);
787     ok(lo == 0, "Expected 0, got %08x\n", lo);
788 
789     test_assembly_name_props(name, pubkeyname);
790 
791     IAssemblyName_Release(name);
792 
793     /* Processor architecture tests */
794     to_widechar(namestr, "wine, processorArchitecture=x86");
795     name = NULL;
796     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
797     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
798 
799     ok(name != NULL, "Expected non-NULL name\n");
800 
801     size = MAX_PATH;
802     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
803     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
804 
805     WideCharToMultiByte(CP_ACP, 0, str, -1, string1, MAX_PATH, NULL, NULL);
806 
807     if (lstrcmpA(string1, "wine") == 0)
808         win_skip("processorArchitecture not supported on .NET 1.x\n");
809     else
810     {
811         ok_aw("wine, processorArchitecture=x86", str);
812         ok(size == 32, "Expected 32, got %d\n", size);
813 
814         size = sizeof(arch);
815         hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size);
816         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
817         ok(arch == peI386, "Expected peI386, got %d\n", arch);
818         ok(size == sizeof(arch), "Wrong size %d\n", size);
819 
820         IAssemblyName_Release(name);
821 
822         /* amd64 */
823         to_widechar(namestr, "wine, processorArchitecture=AMD64");
824         name = NULL;
825         hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
826         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
827 
828         size = MAX_PATH;
829         hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
830         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
831         ok_aw("wine, processorArchitecture=AMD64", str);
832         ok(size == 34, "Expected 34, got %d\n", size);
833 
834         size = sizeof(arch);
835         hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size);
836         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
837         ok(arch == peAMD64, "Expected peAMD64, got %d\n", arch);
838         ok(size == sizeof(arch), "Wrong size %d\n", size);
839 
840         IAssemblyName_Release(name);
841 
842         /* ia64 */
843         to_widechar(namestr, "wine, processorArchitecture=IA64");
844         name = NULL;
845         hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
846         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
847 
848         size = MAX_PATH;
849         hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
850         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
851         ok_aw("wine, processorArchitecture=IA64", str);
852         ok(size == 33, "Expected 33, got %d\n", size);
853 
854         size = sizeof(arch);
855         hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size);
856         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
857         ok(arch == peIA64, "Expected peIA64, got %d\n", arch);
858         ok(size == sizeof(arch), "Wrong size %d\n", size);
859 
860         IAssemblyName_Release(name);
861 
862         /* msil */
863         to_widechar(namestr, "wine, processorArchitecture=MSIL");
864         name = NULL;
865         hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
866         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
867 
868         size = MAX_PATH;
869         hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
870         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
871         ok_aw("wine, processorArchitecture=MSIL", str);
872         ok(size == 33, "Expected 33, got %d\n", size);
873 
874         size = sizeof(arch);
875         hr = IAssemblyName_GetProperty(name, ASM_NAME_ARCHITECTURE, &arch, &size);
876         ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
877         ok(arch == peMSIL, "Expected peMSIL, got %d\n", arch);
878         ok(size == sizeof(arch), "Wrong size %d\n", size);
879 
880         IAssemblyName_Release(name);
881     }
882 
883     /* Pulling out various different values */
884     to_widechar(namestr, "wine, Version=1.2.3.4, Culture=en, PublicKeyToken=1234567890abcdef");
885     name = NULL;
886     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
887     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
888     ok(name != NULL, "Expected non-NULL name\n");
889 
890     size = MAX_PATH;
891     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE);
892     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
893     ok_aw("wine, Version=1.2.3.4, Culture=en", str);
894     ok(size == 34, "Expected 34, got %d\n", size);
895 
896     size = MAX_PATH;
897     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_CULTURE | ASM_DISPLAYF_PUBLIC_KEY_TOKEN);
898     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
899     ok_aw("wine, Culture=en, PublicKeyToken=1234567890abcdef", str);
900     ok(size == 50, "Expected 50, got %d\n", size);
901 
902     size = MAX_PATH;
903     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
904     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
905     ok_aw("wine, Version=1.2.3.4, Culture=en, PublicKeyToken=1234567890abcdef", str);
906     ok(size == 67, "Expected 67, got %d\n", size);
907 
908     IAssemblyName_Release(name);
909 
910     /* invalid property */
911     to_widechar(namestr, "wine, BadProp=42");
912     name = NULL;
913     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
914     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
915     ok(name != NULL, "Expected non-NULL name\n");
916 
917     size = MAX_PATH;
918     str[0] = '\0';
919     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
920     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
921     ok_aw("wine", str);
922     ok(size == 5, "Expected 5, got %d\n", size);
923 
924     size = MAX_PATH;
925     str[0] = '\0';
926     hr = IAssemblyName_GetName(name, &size, str);
927     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
928     ok_aw("wine", str);
929     ok(size == 5, "Expected 5, got %d\n", size);
930 
931     hi = 0xbeefcace;
932     lo = 0xcafebabe;
933     hr = IAssemblyName_GetVersion(name, &hi, &lo);
934     ok(hr == FUSION_E_INVALID_NAME ||
935        broken(hr == S_OK), /* .NET 1.x */
936        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
937     ok(hi == 0, "Expected 0, got %08x\n", hi);
938     ok(lo == 0, "Expected 0, got %08x\n", lo);
939 
940     test_assembly_name_props(name, winename);
941 
942     IAssemblyName_Release(name);
943 
944     /* PublicKeyToken is not 16 chars long */
945     to_widechar(namestr, "wine, PublicKeyToken=567890abcdef");
946     name = (IAssemblyName *)0xdeadbeef;
947     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
948     if (hr == S_OK && name != (IAssemblyName *)0xdeadbeef)
949     {
950         win_skip(".NET 1.x doesn't check PublicKeyToken correctly\n");
951         IAssemblyName_Release(name);
952         return;
953     }
954     ok(hr == FUSION_E_INVALID_NAME,
955        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
956     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
957 
958     /* PublicKeyToken contains invalid chars */
959     to_widechar(namestr, "wine, PublicKeyToken=1234567890ghijkl");
960     name = (IAssemblyName *)0xdeadbeef;
961     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
962     ok(hr == FUSION_E_INVALID_NAME,
963        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
964     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
965 
966     /* no comma separator */
967     to_widechar(namestr, "wine PublicKeyToken=1234567890abcdef");
968     name = (IAssemblyName *)0xdeadbeef;
969     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
970     ok(hr == FUSION_E_INVALID_NAME,
971        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
972     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
973     if(SUCCEEDED(hr)) IAssemblyName_Release(name);
974 
975     /* no '=' */
976     to_widechar(namestr, "wine, PublicKeyToken");
977     name = (IAssemblyName *)0xdeadbeef;
978     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
979     ok(hr == FUSION_E_INVALID_NAME,
980        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
981     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
982 
983     /* no value */
984     to_widechar(namestr, "wine, PublicKeyToken=");
985     name = (IAssemblyName *)0xdeadbeef;
986     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
987     ok(hr == FUSION_E_INVALID_NAME,
988        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
989     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
990 
991     /* no spaces */
992     to_widechar(namestr, "wine,version=1.0.0.0");
993     name = (IAssemblyName *)0xdeadbeef;
994     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
995     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
996     ok(name != NULL, "Expected non-NULL name\n");
997     hi = lo = 0xdeadbeef;
998     hr = IAssemblyName_GetVersion(name, &hi, &lo);
999     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1000     ok(hi == 65536, "Expected 536, got %u\n", hi);
1001     ok(lo == 0, "Expected 0, got %u\n", lo);
1002     IAssemblyName_Release(name);
1003 
1004     /* quoted values */
1005     to_widechar(namestr, "wine, version=\"1.0.0.0\",culture=\"en\"");
1006     name = (IAssemblyName *)0xdeadbeef;
1007     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
1008     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1009     ok(name != NULL, "Expected non-NULL name\n");
1010     hi = lo = 0xdeadbeef;
1011     hr = IAssemblyName_GetVersion(name, &hi, &lo);
1012     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1013     ok(hi == 65536, "Expected 65536, got %u\n", hi);
1014     ok(lo == 0, "Expected 0, got %u\n", lo);
1015     IAssemblyName_Release(name);
1016 }
1017 
1018 static void test_IAssemblyName_IsEqual(void)
1019 {
1020     static const WCHAR wine1[] =
1021         {'w','i','n','e',0};
1022     static const WCHAR wine2[] =
1023         {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',0};
1024     static const WCHAR wine3[] =
1025         {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',',',
1026          'c','u','l','t','u','r','e','=','n','e','u','t','r','a','l',0};
1027     static const WCHAR wine4[] =
1028         {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',',',
1029          'c','u','l','t','u','r','e','=','e','n',0};
1030     static const WCHAR wine5[] =
1031         {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',',',
1032          'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=','1','2','3','4','5','6',
1033          '7','8','9','0','a','b','c','d','e','f',0};
1034     HRESULT hr;
1035     IAssemblyName *name1, *name2;
1036 
1037     hr = pCreateAssemblyNameObject( &name1, wine1, CANOF_PARSE_DISPLAY_NAME, NULL );
1038     ok( hr == S_OK, "got %08x\n", hr );
1039 
1040     hr = pCreateAssemblyNameObject( &name2, wine1, CANOF_PARSE_DISPLAY_NAME, NULL );
1041     ok( hr == S_OK, "got %08x\n", hr );
1042 
1043     if (0) { /* crashes on some old version */
1044     hr = IAssemblyName_IsEqual( name1, NULL, 0 );
1045     ok( hr == S_FALSE, "got %08x\n", hr );
1046 
1047     hr = IAssemblyName_IsEqual( name1, NULL, ASM_CMPF_IL_ALL );
1048     ok( hr == S_FALSE, "got %08x\n", hr );
1049     }
1050 
1051     hr = IAssemblyName_IsEqual( name1, name1, ASM_CMPF_IL_ALL );
1052     ok( hr == S_OK, "got %08x\n", hr );
1053 
1054     hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL );
1055     ok( hr == S_OK, "got %08x\n", hr );
1056 
1057     IAssemblyName_Release( name2 );
1058     hr = pCreateAssemblyNameObject( &name2, wine2, CANOF_PARSE_DISPLAY_NAME, NULL );
1059     ok( hr == S_OK, "got %08x\n", hr );
1060 
1061     hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL );
1062     ok( hr == S_OK, "got %08x\n", hr );
1063 
1064     IAssemblyName_Release( name2 );
1065     hr = pCreateAssemblyNameObject( &name2, wine3, CANOF_PARSE_DISPLAY_NAME, NULL );
1066     ok( hr == S_OK, "got %08x\n", hr );
1067 
1068     hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL );
1069     ok( hr == S_OK, "got %08x\n", hr );
1070 
1071     IAssemblyName_Release( name1 );
1072     hr = pCreateAssemblyNameObject( &name1, wine4, CANOF_PARSE_DISPLAY_NAME, NULL );
1073     ok( hr == S_OK, "got %08x\n", hr );
1074 
1075     hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL );
1076     ok( hr == S_FALSE, "got %08x\n", hr );
1077 
1078     IAssemblyName_Release( name1 );
1079     hr = pCreateAssemblyNameObject( &name1, wine1, CANOF_PARSE_DISPLAY_NAME, NULL );
1080     ok( hr == S_OK, "got %08x\n", hr );
1081 
1082     IAssemblyName_Release( name2 );
1083     hr = pCreateAssemblyNameObject( &name2, wine5, CANOF_PARSE_DISPLAY_NAME, NULL );
1084     ok( hr == S_OK, "got %08x\n", hr );
1085 
1086     hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL );
1087     ok( hr == S_OK, "got %08x\n", hr );
1088 
1089     IAssemblyName_Release( name1 );
1090     IAssemblyName_Release( name2 );
1091 }
1092 
1093 START_TEST(asmname)
1094 {
1095     if (!init_functionpointers())
1096     {
1097         win_skip("fusion.dll not available\n");
1098         return;
1099     }
1100 
1101     test_CreateAssemblyNameObject();
1102     test_IAssemblyName_IsEqual();
1103 }
1104