wininet: Don't unnecessarily convert hostname to ANSI to check it.
[wine] / dlls / fusion / tests / asmname.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
21 #include <stdio.h>
22
23 #include <windows.h>
24 #include <mscoree.h>
25 #include <fusion.h>
26 #include <corerror.h>
27
28 #include "wine/test.h"
29
30 /* ok-like statement which takes two unicode strings or one unicode and one ANSI string as arguments */
31 static CHAR string1[MAX_PATH];
32
33 #define ok_aw(aString, wString) \
34     WideCharToMultiByte(CP_ACP, 0, wString, -1, string1, MAX_PATH, NULL, NULL); \
35     if (lstrcmpA(string1, aString) != 0) \
36         ok(0, "Expected \"%s\", got \"%s\"\n", aString, string1);
37
38 static HRESULT (WINAPI *pCreateAssemblyNameObject)(LPASSEMBLYNAME *ppAssemblyNameObj,
39                                                    LPCWSTR szAssemblyName, DWORD dwFlags,
40                                                    LPVOID pvReserved);
41 static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion,
42                                           LPVOID pvReserved, HMODULE *phModDll);
43
44 static BOOL init_functionpointers(void)
45 {
46     HRESULT hr;
47     HMODULE hfusion;
48     HMODULE hmscoree;
49
50     static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
51
52     hmscoree = LoadLibraryA("mscoree.dll");
53     if (!hmscoree)
54         return FALSE;
55
56     pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
57     if (!pLoadLibraryShim)
58     {
59         FreeLibrary(hmscoree);
60         return FALSE;
61     }
62
63     hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion);
64     if (FAILED(hr))
65         return FALSE;
66
67     pCreateAssemblyNameObject = (void *)GetProcAddress(hfusion, "CreateAssemblyNameObject");
68     if (!pCreateAssemblyNameObject)
69         return FALSE;
70
71     return TRUE;
72 }
73
74 typedef struct _tagASMPROP_RES
75 {
76     HRESULT hr;
77     CHAR val[MAX_PATH];
78     DWORD size;
79 } ASMPROP_RES;
80
81 static const ASMPROP_RES defaults[ASM_NAME_MAX_PARAMS] =
82 {
83     {S_OK, "", 0},
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_FALSE, "", MAX_PATH},
99     {S_FALSE, "", MAX_PATH},
100     {S_OK, "", 0},
101     {S_OK, "", MAX_PATH},
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_OK, "", 0},
109     {S_OK, "", 0},
110     {S_OK, "", 0}
111 };
112
113 static const ASMPROP_RES emptyname[ASM_NAME_MAX_PARAMS] =
114 {
115     {S_OK, "", 0},
116     {S_OK, "", 0},
117     {S_OK, "", 0},
118     {S_OK, "", 2},
119     {S_OK, "", 0},
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_FALSE, "", MAX_PATH},
131     {S_FALSE, "", MAX_PATH},
132     {S_OK, "", 0},
133     {S_OK, "", MAX_PATH},
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_OK, "", 0},
141     {S_OK, "", 0},
142     {S_OK, "", 0}
143 };
144
145 static const ASMPROP_RES winename[ASM_NAME_MAX_PARAMS] =
146 {
147     {S_OK, "", 0},
148     {S_OK, "", 0},
149     {S_OK, "", 0},
150     {S_OK, "wine", 10},
151     {S_OK, "", 0},
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_FALSE, "", MAX_PATH},
163     {S_FALSE, "", MAX_PATH},
164     {S_OK, "", 0},
165     {S_OK, "", MAX_PATH},
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_OK, "", 0},
173     {S_OK, "", 0},
174     {S_OK, "", 0}
175 };
176
177 static const ASMPROP_RES vername[ASM_NAME_MAX_PARAMS] =
178 {
179     {S_OK, "", 0},
180     {S_OK, "", 0},
181     {S_OK, "", 0},
182     {S_OK, "wine", 10},
183     {S_OK, "\x01", 2},
184     {S_OK, "\x02", 2},
185     {S_OK, "\x03", 2},
186     {S_OK, "\x04", 2},
187     {S_OK, "", 0},
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_FALSE, "", MAX_PATH},
195     {S_FALSE, "", MAX_PATH},
196     {S_OK, "", 0},
197     {S_OK, "", MAX_PATH},
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_OK, "", 0},
205     {S_OK, "", 0},
206     {S_OK, "", 0}
207 };
208
209 static const ASMPROP_RES badvername[ASM_NAME_MAX_PARAMS] =
210 {
211     {S_OK, "", 0},
212     {S_OK, "", 0},
213     {S_OK, "", 0},
214     {S_OK, "wine", 10},
215     {S_OK, "\x01", 2},
216     {S_OK, "\x05", 2},
217     {S_OK, "", 0},
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_FALSE, "", MAX_PATH},
227     {S_FALSE, "", MAX_PATH},
228     {S_OK, "", 0},
229     {S_OK, "", MAX_PATH},
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_OK, "", 0},
237     {S_OK, "", 0},
238     {S_OK, "", 0}
239 };
240
241 static const ASMPROP_RES neutralname[ASM_NAME_MAX_PARAMS] =
242 {
243     {S_OK, "", 0},
244     {S_OK, "", 0},
245     {S_OK, "", 0},
246     {S_OK, "wine", 10},
247     {S_OK, "", 0},
248     {S_OK, "", 0},
249     {S_OK, "", 0},
250     {S_OK, "", 0},
251     {S_OK, "", 2},
252     {S_OK, "", 0},
253     {S_OK, "", 0},
254     {S_OK, "", 0},
255     {S_OK, "", 0},
256     {S_OK, "", 0},
257     {S_OK, "", 0},
258     {S_FALSE, "", MAX_PATH},
259     {S_FALSE, "", MAX_PATH},
260     {S_OK, "", 0},
261     {S_OK, "", MAX_PATH},
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_OK, "", 0},
269     {S_OK, "", 0},
270     {S_OK, "", 0}
271 };
272
273 static const ASMPROP_RES enname[ASM_NAME_MAX_PARAMS] =
274 {
275     {S_OK, "", 0},
276     {S_OK, "", 0},
277     {S_OK, "", 0},
278     {S_OK, "wine", 10},
279     {S_OK, "", 0},
280     {S_OK, "", 0},
281     {S_OK, "", 0},
282     {S_OK, "", 0},
283     {S_OK, "en", 6},
284     {S_OK, "", 0},
285     {S_OK, "", 0},
286     {S_OK, "", 0},
287     {S_OK, "", 0},
288     {S_OK, "", 0},
289     {S_OK, "", 0},
290     {S_FALSE, "", MAX_PATH},
291     {S_FALSE, "", MAX_PATH},
292     {S_OK, "", 0},
293     {S_OK, "", MAX_PATH},
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_OK, "", 0},
301     {S_OK, "", 0},
302     {S_OK, "", 0}
303 };
304
305 static const ASMPROP_RES pubkeyname[ASM_NAME_MAX_PARAMS] =
306 {
307     {S_OK, "", 0},
308     {S_OK, "\x12\x34\x56\x78\x90\xab\xcd\xef", 8},
309     {S_OK, "", 0},
310     {S_OK, "wine", 10},
311     {S_OK, "", 0},
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, "", MAX_PATH},
323     {S_OK, "", MAX_PATH},
324     {S_OK, "", 0},
325     {S_OK, "", MAX_PATH},
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, "", 0},
333     {S_OK, "", 0},
334     {S_OK, "", 0}
335 };
336
337 static inline void to_widechar(LPWSTR dest, LPCSTR src)
338 {
339     MultiByteToWideChar(CP_ACP, 0, src, -1, dest, MAX_PATH);
340 }
341
342 static inline void to_multibyte(LPSTR dest, LPWSTR src)
343 {
344     WideCharToMultiByte(CP_ACP, 0, src, -1, dest, MAX_PATH, NULL, NULL);
345 }
346
347 static void test_assembly_name_props_line(IAssemblyName *name,
348                                           const ASMPROP_RES *vals, int line)
349 {
350     HRESULT hr;
351     DWORD i, size;
352     WCHAR expect[MAX_PATH];
353     WCHAR str[MAX_PATH];
354     CHAR val[MAX_PATH];
355
356     for (i = 0; i < ASM_NAME_MAX_PARAMS; i++)
357     {
358         to_widechar(expect, vals[i].val);
359
360         size = MAX_PATH;
361         ZeroMemory(str, MAX_PATH);
362         hr = IAssemblyName_GetProperty(name, i, str, &size);
363         to_multibyte(val, str);
364
365         ok(hr == vals[i].hr ||
366            broken(i >= ASM_NAME_CONFIG_MASK && hr == E_INVALIDARG) || /* .NET 1.1 */
367            broken(i >= ASM_NAME_FILE_MAJOR_VERSION && hr == E_INVALIDARG), /* .NET 1.0 */
368            "%d: prop %d: Expected %08x, got %08x\n", line, i, vals[i].hr, hr);
369         if (hr != E_INVALIDARG)
370         {
371             if (i == ASM_NAME_PUBLIC_KEY_TOKEN)
372                 ok(!memcmp(vals[i].val, str, size), "Expected a correct ASM_NAME_PUBLIC_KEY_TOKEN\n");
373             else
374                 ok(!lstrcmpA(vals[i].val, val), "%d: prop %d: Expected \"%s\", got \"%s\"\n", line, i, vals[i].val, val);
375             ok(size == vals[i].size, "%d: prop %d: Expected %d, got %d\n", line, i, vals[i].size, size);
376         }
377     }
378 }
379
380 #define test_assembly_name_props(name, vals) \
381     test_assembly_name_props_line(name, vals, __LINE__);
382
383 static void test_CreateAssemblyNameObject(void)
384 {
385     IAssemblyName *name;
386     WCHAR str[MAX_PATH];
387     WCHAR namestr[MAX_PATH];
388     DWORD size, hi, lo;
389     HRESULT hr;
390
391     static const WCHAR empty[] = {0};
392
393     /* NULL ppAssemblyNameObj */
394     to_widechar(namestr, "wine.dll");
395     hr = pCreateAssemblyNameObject(NULL, namestr, 0, NULL);
396     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
397
398     /* NULL szAssemblyName, CANOF_PARSE_DISPLAY_NAME */
399     name = (IAssemblyName *)0xdeadbeef;
400     hr = pCreateAssemblyNameObject(&name, NULL, CANOF_PARSE_DISPLAY_NAME, NULL);
401     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
402     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
403
404     /* empty szAssemblyName, CANOF_PARSE_DISPLAY_NAME */
405     name = (IAssemblyName *)0xdeadbeef;
406     hr = pCreateAssemblyNameObject(&name, empty, CANOF_PARSE_DISPLAY_NAME, NULL);
407     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
408     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
409
410     /* check the contents of the AssemblyName for default values */
411
412     /* NULL szAssemblyName */
413     name = NULL;
414     hr = pCreateAssemblyNameObject(&name, NULL, CANOF_SET_DEFAULT_VALUES, NULL);
415     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
416     ok(name != NULL, "Expected non-NULL name\n");
417
418     size = MAX_PATH;
419     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
420     ok(hr == FUSION_E_INVALID_NAME ||
421        broken(hr == E_INVALIDARG), /* .NET 1.x */
422        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
423
424     size = MAX_PATH;
425     str[0] = '\0';
426     hr = IAssemblyName_GetName(name, &size, str);
427     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
428     ok(lstrlenW(str) == 0, "Expected empty name\n");
429     ok(size == 0, "Expected 0, got %d\n", size);
430
431     hi = 0xbeefcace;
432     lo = 0xcafebabe;
433     hr = IAssemblyName_GetVersion(name, &hi, &lo);
434     ok(hr == FUSION_E_INVALID_NAME ||
435        broken(hr == S_OK), /* .NET 1.x */
436        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
437     ok(hi == 0, "Expected 0, got %08x\n", hi);
438     ok(lo == 0, "Expected 0, got %08x\n", lo);
439
440     if (hr == S_OK)
441         win_skip(".NET 1.x doesn't handle ASM_NAME_PROCESSOR_ID_ARRAY"
442                  " and ASM_NAME_OSINFO_ARRAY correctly\n");
443     else
444         test_assembly_name_props(name, defaults);
445
446     IAssemblyName_Release(name);
447
448     /* empty szAssemblyName */
449     name = NULL;
450     hr = pCreateAssemblyNameObject(&name, empty, CANOF_SET_DEFAULT_VALUES, NULL);
451     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
452     ok(name != NULL, "Expected non-NULL name\n");
453
454     size = MAX_PATH;
455     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
456     ok(hr == FUSION_E_INVALID_NAME ||
457        broken(hr == S_OK), /* .NET 1.x */
458        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
459
460     size = MAX_PATH;
461     str[0] = '\0';
462     hr = IAssemblyName_GetName(name, &size, str);
463     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
464     ok(lstrlenW(str) == 0, "Expected empty name\n");
465     ok(size == 1, "Expected 1, got %d\n", size);
466
467     hi = 0xbeefcace;
468     lo = 0xcafebabe;
469     hr = IAssemblyName_GetVersion(name, &hi, &lo);
470     ok(hr == FUSION_E_INVALID_NAME ||
471        broken(hr == S_OK), /* .NET 1.x */
472        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
473     ok(hi == 0, "Expected 0, got %08x\n", hi);
474     ok(lo == 0, "Expected 0, got %08x\n", lo);
475
476     if (hr == S_OK)
477         win_skip(".NET 1.x doesn't handle ASM_NAME_PROCESSOR_ID_ARRAY"
478                  " and ASM_NAME_OSINFO_ARRAY correctly\n");
479     else
480         test_assembly_name_props(name, emptyname);
481
482     IAssemblyName_Release(name);
483
484     /* 'wine' */
485     to_widechar(namestr, "wine");
486     name = NULL;
487     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_SET_DEFAULT_VALUES, NULL);
488     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
489     ok(name != NULL, "Expected non-NULL name\n");
490
491     size = MAX_PATH;
492     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
493     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
494     ok_aw("wine", str);
495     ok(size == 5, "Expected 5, got %d\n", size);
496
497     size = MAX_PATH;
498     str[0] = '\0';
499     hr = IAssemblyName_GetName(name, &size, str);
500     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
501     ok_aw("wine", str);
502     ok(size == 5, "Expected 5, got %d\n", size);
503
504     hi = 0xbeefcace;
505     lo = 0xcafebabe;
506     hr = IAssemblyName_GetVersion(name, &hi, &lo);
507     ok(hr == FUSION_E_INVALID_NAME ||
508        broken(hr == S_OK), /* .NET 1.x */
509        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
510     ok(hi == 0, "Expected 0, got %08x\n", hi);
511     ok(lo == 0, "Expected 0, got %08x\n", lo);
512
513     if (hr == S_OK)
514         win_skip(".NET 1.x doesn't handle ASM_NAME_PROCESSOR_ID_ARRAY"
515                  " and ASM_NAME_OSINFO_ARRAY correctly\n");
516     else
517         test_assembly_name_props(name, winename);
518
519     IAssemblyName_Release(name);
520
521     /* check the contents of the AssemblyName with parsing */
522
523     /* 'wine' */
524     to_widechar(namestr, "wine");
525     name = NULL;
526     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
527     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
528     ok(name != NULL, "Expected non-NULL name\n");
529
530     size = MAX_PATH;
531     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
532     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
533     ok_aw("wine", str);
534     ok(size == 5, "Expected 5, got %d\n", size);
535
536     size = MAX_PATH;
537     str[0] = '\0';
538     hr = IAssemblyName_GetName(name, &size, str);
539     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
540     ok_aw("wine", str);
541     ok(size == 5, "Expected 5, got %d\n", size);
542
543     hi = 0xbeefcace;
544     lo = 0xcafebabe;
545     hr = IAssemblyName_GetVersion(name, &hi, &lo);
546     ok(hr == FUSION_E_INVALID_NAME ||
547        broken(hr == S_OK), /* .NET 1.x */
548        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
549     ok(hi == 0, "Expected 0, got %08x\n", hi);
550     ok(lo == 0, "Expected 0, got %08x\n", lo);
551
552     test_assembly_name_props(name, winename);
553
554     IAssemblyName_Release(name);
555
556     /* 'wine, Version=1.2.3.4' */
557     to_widechar(namestr, "wine, Version=1.2.3.4");
558     name = NULL;
559     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
560     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
561     ok(name != NULL, "Expected non-NULL name\n");
562
563     size = MAX_PATH;
564     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
565     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
566     ok_aw("wine, Version=1.2.3.4", str);
567     ok(size == 22, "Expected 22, got %d\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 == S_OK, "Expected S_OK, got %08x\n", hr);
580     ok(hi == 0x00010002, "Expected 0x00010002, got %08x\n", hi);
581     ok(lo == 0x00030004, "Expected 0x00030004, got %08x\n", lo);
582
583     test_assembly_name_props(name, vername);
584
585     IAssemblyName_Release(name);
586
587     /* Version isn't of the form 1.x.x.x */
588     to_widechar(namestr, "wine, Version=1.5");
589     name = NULL;
590     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
591     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
592     ok(name != NULL, "Expected non-NULL name\n");
593
594     size = MAX_PATH;
595     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
596     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
597     ok_aw("wine, Version=1.5", str);
598     ok(size == 18, "Expected 18, got %d\n", size);
599
600     size = MAX_PATH;
601     str[0] = '\0';
602     hr = IAssemblyName_GetName(name, &size, str);
603     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
604     ok_aw("wine", str);
605     ok(size == 5, "Expected 5, got %d\n", size);
606
607     hi = 0xbeefcace;
608     lo = 0xcafebabe;
609     hr = IAssemblyName_GetVersion(name, &hi, &lo);
610     ok(hr == FUSION_E_INVALID_NAME ||
611        broken(hr == S_OK), /* .NET 1.x */
612        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
613     ok(hi == 0 ||
614        broken(hi == 0x10005), /* .NET 1.x */
615        "Expected 0, got %08x\n", hi);
616     ok(lo == 0, "Expected 0, got %08x\n", lo);
617
618     test_assembly_name_props(name, badvername);
619
620     IAssemblyName_Release(name);
621
622     /* 'wine, Culture=neutral' */
623     to_widechar(namestr, "wine, Culture=neutral");
624     name = NULL;
625     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
626     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
627     ok(name != NULL, "Expected non-NULL name\n");
628
629     size = MAX_PATH;
630     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
631     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
632     ok_aw("wine, Culture=neutral", str);
633     ok(size == 22, "Expected 22, got %d\n", size);
634
635     size = MAX_PATH;
636     str[0] = '\0';
637     hr = IAssemblyName_GetName(name, &size, str);
638     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
639     ok_aw("wine", str);
640     ok(size == 5, "Expected 5, got %d\n", size);
641
642     hi = 0xbeefcace;
643     lo = 0xcafebabe;
644     hr = IAssemblyName_GetVersion(name, &hi, &lo);
645     ok(hr == FUSION_E_INVALID_NAME ||
646        broken(hr == S_OK), /* .NET 1.x */
647        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
648     ok(hi == 0, "Expected 0, got %08x\n", hi);
649     ok(lo == 0, "Expected 0, got %08x\n", lo);
650
651     test_assembly_name_props(name, neutralname);
652
653     IAssemblyName_Release(name);
654
655     /* 'wine, Culture=en' */
656     to_widechar(namestr, "wine, Culture=en");
657     name = NULL;
658     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
659     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
660     ok(name != NULL, "Expected non-NULL name\n");
661
662     size = MAX_PATH;
663     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
664     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
665     ok_aw("wine, Culture=en", str);
666     ok(size == 17, "Expected 17, got %d\n", size);
667
668     size = MAX_PATH;
669     str[0] = '\0';
670     hr = IAssemblyName_GetName(name, &size, str);
671     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
672     ok_aw("wine", str);
673     ok(size == 5, "Expected 5, got %d\n", size);
674
675     hi = 0xbeefcace;
676     lo = 0xcafebabe;
677     hr = IAssemblyName_GetVersion(name, &hi, &lo);
678     ok(hr == FUSION_E_INVALID_NAME ||
679        broken(hr == S_OK), /* .NET 1.x */
680        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
681     ok(hi == 0, "Expected 0, got %08x\n", hi);
682     ok(lo == 0, "Expected 0, got %08x\n", lo);
683
684     test_assembly_name_props(name, enname);
685
686     IAssemblyName_Release(name);
687
688     /* 'wine, PublicKeyToken=1234567890abcdef' */
689     to_widechar(namestr, "wine, PublicKeyToken=1234567890abcdef");
690     name = NULL;
691     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
692     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
693     ok(name != NULL, "Expected non-NULL name\n");
694
695     size = MAX_PATH;
696     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
697     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
698     ok_aw("wine, PublicKeyToken=1234567890abcdef", str);
699     ok(size == 38, "Expected 38, got %d\n", size);
700
701     size = MAX_PATH;
702     str[0] = '\0';
703     hr = IAssemblyName_GetName(name, &size, str);
704     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
705     ok_aw("wine", str);
706     ok(size == 5, "Expected 5, got %d\n", size);
707
708     hi = 0xbeefcace;
709     lo = 0xcafebabe;
710     hr = IAssemblyName_GetVersion(name, &hi, &lo);
711     ok(hr == FUSION_E_INVALID_NAME ||
712        broken(hr == S_OK), /* .NET 1.x */
713        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
714     ok(hi == 0, "Expected 0, got %08x\n", hi);
715     ok(lo == 0, "Expected 0, got %08x\n", lo);
716
717     test_assembly_name_props(name, pubkeyname);
718
719     IAssemblyName_Release(name);
720
721     /* invalid property */
722     to_widechar(namestr, "wine, BadProp=42");
723     name = NULL;
724     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
725     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
726     ok(name != NULL, "Expected non-NULL name\n");
727
728     size = MAX_PATH;
729     str[0] = '\0';
730     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
731     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
732     todo_wine
733     {
734         ok_aw("wine", str);
735         ok(size == 5, "Expected 5, got %d\n", size);
736     }
737
738     size = MAX_PATH;
739     str[0] = '\0';
740     hr = IAssemblyName_GetName(name, &size, str);
741     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
742     ok_aw("wine", str);
743     ok(size == 5, "Expected 5, got %d\n", size);
744
745     hi = 0xbeefcace;
746     lo = 0xcafebabe;
747     hr = IAssemblyName_GetVersion(name, &hi, &lo);
748     ok(hr == FUSION_E_INVALID_NAME ||
749        broken(hr == S_OK), /* .NET 1.x */
750        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
751     ok(hi == 0, "Expected 0, got %08x\n", hi);
752     ok(lo == 0, "Expected 0, got %08x\n", lo);
753
754     test_assembly_name_props(name, winename);
755
756     IAssemblyName_Release(name);
757
758     /* PublicKeyToken is not 16 chars long */
759     to_widechar(namestr, "wine, PublicKeyToken=567890abcdef");
760     name = (IAssemblyName *)0xdeadbeef;
761     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
762     if (hr == S_OK && name != (IAssemblyName *)0xdeadbeef)
763     {
764         win_skip(".NET 1.x doesn't check PublicKeyToken correctly\n");
765         IAssemblyName_Release(name);
766         return;
767     }
768     ok(hr == FUSION_E_INVALID_NAME,
769        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
770     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
771
772     /* PublicKeyToken contains invalid chars */
773     to_widechar(namestr, "wine, PublicKeyToken=1234567890ghijkl");
774     name = (IAssemblyName *)0xdeadbeef;
775     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
776     ok(hr == FUSION_E_INVALID_NAME,
777        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
778     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
779
780     /* no comma separator */
781     to_widechar(namestr, "wine PublicKeyToken=1234567890abcdef");
782     name = (IAssemblyName *)0xdeadbeef;
783     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
784     todo_wine
785     {
786         ok(hr == FUSION_E_INVALID_NAME,
787            "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
788         ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
789     }
790     if(SUCCEEDED(hr)) IAssemblyName_Release(name);
791
792     /* no '=' */
793     to_widechar(namestr, "wine, PublicKeyToken");
794     name = (IAssemblyName *)0xdeadbeef;
795     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
796     ok(hr == FUSION_E_INVALID_NAME,
797        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
798     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
799
800     /* no value */
801     to_widechar(namestr, "wine, PublicKeyToken=");
802     name = (IAssemblyName *)0xdeadbeef;
803     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
804     ok(hr == FUSION_E_INVALID_NAME,
805        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
806     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
807 }
808
809 START_TEST(asmname)
810 {
811     if (!init_functionpointers())
812     {
813         win_skip("fusion.dll not available\n");
814         return;
815     }
816
817     test_CreateAssemblyNameObject();
818 }