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