msxml3: Reorganize parse_buffer function (make use of libxml2 parserInternals.h).
[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         if (i == ASM_NAME_PUBLIC_KEY_TOKEN)
366             lstrcpyA((LPSTR)expect, vals[i].val);
367
368         ok(hr == vals[i].hr, "%d: prop %d: Expected %08x, got %08x\n", line, i, vals[i].hr, hr);
369         ok(!lstrcmpW(str, expect), "%d: prop %d: Expected \"%s\", got \"%s\"\n", line, i, vals[i].val, val);
370         ok(size == vals[i].size, "%d: prop %d: Expected %d, got %d\n", line, i, vals[i].size, size);
371     }
372 }
373
374 #define test_assembly_name_props(name, vals) \
375     test_assembly_name_props_line(name, vals, __LINE__);
376
377 static void test_CreateAssemblyNameObject(void)
378 {
379     IAssemblyName *name;
380     WCHAR str[MAX_PATH];
381     WCHAR namestr[MAX_PATH];
382     DWORD size, hi, lo;
383     HRESULT hr;
384
385     static const WCHAR empty[] = {0};
386
387     /* NULL ppAssemblyNameObj */
388     to_widechar(namestr, "wine.dll");
389     hr = pCreateAssemblyNameObject(NULL, namestr, 0, NULL);
390     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
391
392     /* NULL szAssemblyName, CANOF_PARSE_DISPLAY_NAME */
393     name = (IAssemblyName *)0xdeadbeef;
394     hr = pCreateAssemblyNameObject(&name, NULL, CANOF_PARSE_DISPLAY_NAME, NULL);
395     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
396     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
397
398     /* empty szAssemblyName, CANOF_PARSE_DISPLAY_NAME */
399     name = (IAssemblyName *)0xdeadbeef;
400     hr = pCreateAssemblyNameObject(&name, empty, 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     /* check the contents of the AssemblyName for default values */
405
406     /* NULL szAssemblyName */
407     name = NULL;
408     hr = pCreateAssemblyNameObject(&name, NULL, CANOF_SET_DEFAULT_VALUES, NULL);
409     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
410     ok(name != NULL, "Expected non-NULLNULL name\n");
411
412     size = MAX_PATH;
413     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
414     ok(hr == FUSION_E_INVALID_NAME,
415        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
416
417     size = MAX_PATH;
418     str[0] = '\0';
419     hr = IAssemblyName_GetName(name, &size, str);
420     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
421     ok(lstrlenW(str) == 0, "Expected empty name\n");
422     ok(size == 0, "Expected 0, got %d\n", size);
423
424     hi = 0xbeefcace;
425     lo = 0xcafebabe;
426     hr = IAssemblyName_GetVersion(name, &hi, &lo);
427     ok(hr == FUSION_E_INVALID_NAME,
428        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
429     ok(hi == 0, "Expected 0, got %08x\n", hi);
430     ok(lo == 0, "Expected 0, got %08x\n", lo);
431
432     test_assembly_name_props(name, defaults);
433
434     IAssemblyName_Release(name);
435
436     /* empty szAssemblyName */
437     name = NULL;
438     hr = pCreateAssemblyNameObject(&name, empty, CANOF_SET_DEFAULT_VALUES, NULL);
439     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
440     ok(name != NULL, "Expected non-NULLNULL name\n");
441
442     size = MAX_PATH;
443     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
444     ok(hr == FUSION_E_INVALID_NAME,
445        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
446
447     size = MAX_PATH;
448     str[0] = '\0';
449     hr = IAssemblyName_GetName(name, &size, str);
450     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
451     ok(lstrlenW(str) == 0, "Expected empty name\n");
452     ok(size == 1, "Expected 1, got %d\n", size);
453
454     hi = 0xbeefcace;
455     lo = 0xcafebabe;
456     hr = IAssemblyName_GetVersion(name, &hi, &lo);
457     ok(hr == FUSION_E_INVALID_NAME,
458        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
459     ok(hi == 0, "Expected 0, got %08x\n", hi);
460     ok(lo == 0, "Expected 0, got %08x\n", lo);
461
462     test_assembly_name_props(name, emptyname);
463
464     IAssemblyName_Release(name);
465
466     /* 'wine' */
467     to_widechar(namestr, "wine");
468     name = NULL;
469     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_SET_DEFAULT_VALUES, NULL);
470     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
471     ok(name != NULL, "Expected non-NULLNULL name\n");
472
473     size = MAX_PATH;
474     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
475     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
476     ok_aw("wine", str);
477     ok(size == 5, "Expected 5, got %d\n", size);
478
479     size = MAX_PATH;
480     str[0] = '\0';
481     hr = IAssemblyName_GetName(name, &size, str);
482     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
483     ok_aw("wine", str);
484     ok(size == 5, "Expected 5, got %d\n", size);
485
486     hi = 0xbeefcace;
487     lo = 0xcafebabe;
488     hr = IAssemblyName_GetVersion(name, &hi, &lo);
489     ok(hr == FUSION_E_INVALID_NAME,
490        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
491     ok(hi == 0, "Expected 0, got %08x\n", hi);
492     ok(lo == 0, "Expected 0, got %08x\n", lo);
493
494     test_assembly_name_props(name, winename);
495
496     IAssemblyName_Release(name);
497
498     /* check the contents of the AssemblyName with parsing */
499
500     /* 'wine' */
501     to_widechar(namestr, "wine");
502     name = NULL;
503     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
504     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
505     ok(name != NULL, "Expected non-NULLNULL name\n");
506
507     size = MAX_PATH;
508     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
509     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
510     ok_aw("wine", str);
511     ok(size == 5, "Expected 5, got %d\n", size);
512
513     size = MAX_PATH;
514     str[0] = '\0';
515     hr = IAssemblyName_GetName(name, &size, str);
516     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
517     ok_aw("wine", str);
518     ok(size == 5, "Expected 5, got %d\n", size);
519
520     hi = 0xbeefcace;
521     lo = 0xcafebabe;
522     hr = IAssemblyName_GetVersion(name, &hi, &lo);
523     ok(hr == FUSION_E_INVALID_NAME,
524        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
525     ok(hi == 0, "Expected 0, got %08x\n", hi);
526     ok(lo == 0, "Expected 0, got %08x\n", lo);
527
528     test_assembly_name_props(name, winename);
529
530     IAssemblyName_Release(name);
531
532     /* 'wine, Version=1.2.3.4' */
533     to_widechar(namestr, "wine, Version=1.2.3.4");
534     name = NULL;
535     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
536     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
537     ok(name != NULL, "Expected non-NULLNULL name\n");
538
539     size = MAX_PATH;
540     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
541     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
542     ok_aw("wine, Version=1.2.3.4", str);
543     ok(size == 22, "Expected 22, got %d\n", size);
544
545     size = MAX_PATH;
546     str[0] = '\0';
547     hr = IAssemblyName_GetName(name, &size, str);
548     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
549     ok_aw("wine", str);
550     ok(size == 5, "Expected 5, got %d\n", size);
551
552     hi = 0xbeefcace;
553     lo = 0xcafebabe;
554     hr = IAssemblyName_GetVersion(name, &hi, &lo);
555     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
556     ok(hi == 0x00010002, "Expected 0x00010002, got %08x\n", hi);
557     ok(lo == 0x00030004, "Expected 0x00030004, got %08x\n", lo);
558
559     test_assembly_name_props(name, vername);
560
561     IAssemblyName_Release(name);
562
563     /* Version isn't of the form 1.x.x.x */
564     to_widechar(namestr, "wine, Version=1.5");
565     name = NULL;
566     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
567     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
568     ok(name != NULL, "Expected non-NULLNULL name\n");
569
570     size = MAX_PATH;
571     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
572     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
573     ok_aw("wine, Version=1.5", str);
574     ok(size == 18, "Expected 18, got %d\n", size);
575
576     size = MAX_PATH;
577     str[0] = '\0';
578     hr = IAssemblyName_GetName(name, &size, str);
579     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
580     ok_aw("wine", str);
581     ok(size == 5, "Expected 5, got %d\n", size);
582
583     hi = 0xbeefcace;
584     lo = 0xcafebabe;
585     hr = IAssemblyName_GetVersion(name, &hi, &lo);
586     ok(hr == FUSION_E_INVALID_NAME,
587        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
588     ok(hi == 0, "Expected 0, got %08x\n", hi);
589     ok(lo == 0, "Expected 0, got %08x\n", lo);
590
591     test_assembly_name_props(name, badvername);
592
593     IAssemblyName_Release(name);
594
595     /* 'wine, Culture=neutral' */
596     to_widechar(namestr, "wine, Culture=neutral");
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-NULLNULL 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, Culture=neutral", str);
606     ok(size == 22, "Expected 22, 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        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
620     ok(hi == 0, "Expected 0, got %08x\n", hi);
621     ok(lo == 0, "Expected 0, got %08x\n", lo);
622
623     test_assembly_name_props(name, neutralname);
624
625     IAssemblyName_Release(name);
626
627     /* 'wine, Culture=en' */
628     to_widechar(namestr, "wine, Culture=en");
629     name = NULL;
630     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
631     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
632     ok(name != NULL, "Expected non-NULLNULL name\n");
633
634     size = MAX_PATH;
635     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
636     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
637     ok_aw("wine, Culture=en", str);
638     ok(size == 17, "Expected 17, got %d\n", size);
639
640     size = MAX_PATH;
641     str[0] = '\0';
642     hr = IAssemblyName_GetName(name, &size, str);
643     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
644     ok_aw("wine", str);
645     ok(size == 5, "Expected 5, got %d\n", size);
646
647     hi = 0xbeefcace;
648     lo = 0xcafebabe;
649     hr = IAssemblyName_GetVersion(name, &hi, &lo);
650     ok(hr == FUSION_E_INVALID_NAME,
651        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
652     ok(hi == 0, "Expected 0, got %08x\n", hi);
653     ok(lo == 0, "Expected 0, got %08x\n", lo);
654
655     test_assembly_name_props(name, enname);
656
657     IAssemblyName_Release(name);
658
659     /* 'wine, PublicKeyToken=1234567890abcdef' */
660     to_widechar(namestr, "wine, PublicKeyToken=1234567890abcdef");
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-NULLNULL 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, PublicKeyToken=1234567890abcdef", str);
670     ok(size == 38, "Expected 38, 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        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
684     ok(hi == 0, "Expected 0, got %08x\n", hi);
685     ok(lo == 0, "Expected 0, got %08x\n", lo);
686
687     test_assembly_name_props(name, pubkeyname);
688
689     IAssemblyName_Release(name);
690
691     /* PublicKeyToken is not 16 chars long */
692     to_widechar(namestr, "wine, PublicKeyToken=567890abcdef");
693     name = (IAssemblyName *)0xdeadbeef;
694     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
695     ok(hr == FUSION_E_INVALID_NAME,
696        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
697     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
698
699     /* PublicKeyToken contains invalid chars */
700     to_widechar(namestr, "wine, PublicKeyToken=1234567890ghijkl");
701     name = (IAssemblyName *)0xdeadbeef;
702     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
703     ok(hr == FUSION_E_INVALID_NAME,
704        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
705     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
706
707     /* no comma separator */
708     to_widechar(namestr, "wine PublicKeyToken=1234567890abcdef");
709     name = (IAssemblyName *)0xdeadbeef;
710     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
711     todo_wine
712     {
713         ok(hr == FUSION_E_INVALID_NAME,
714            "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
715         ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
716     }
717
718     /* no '=' */
719     to_widechar(namestr, "wine, PublicKeyToken");
720     name = (IAssemblyName *)0xdeadbeef;
721     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
722     ok(hr == FUSION_E_INVALID_NAME,
723        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
724     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
725
726     /* no value */
727     to_widechar(namestr, "wine, PublicKeyToken=");
728     name = (IAssemblyName *)0xdeadbeef;
729     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
730     ok(hr == FUSION_E_INVALID_NAME,
731        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
732     ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
733
734     /* invalid property */
735     to_widechar(namestr, "wine, BadProp=42");
736     name = NULL;
737     hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
738     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
739     ok(name != NULL, "Expected non-NULLNULL name\n");
740
741     size = MAX_PATH;
742     hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
743     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
744     todo_wine
745     {
746         ok_aw("wine", str);
747         ok(size == 5, "Expected 5, got %d\n", size);
748     }
749
750     size = MAX_PATH;
751     str[0] = '\0';
752     hr = IAssemblyName_GetName(name, &size, str);
753     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
754     ok_aw("wine", str);
755     ok(size == 5, "Expected 5, got %d\n", size);
756
757     hi = 0xbeefcace;
758     lo = 0xcafebabe;
759     hr = IAssemblyName_GetVersion(name, &hi, &lo);
760     ok(hr == FUSION_E_INVALID_NAME,
761        "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
762     ok(hi == 0, "Expected 0, got %08x\n", hi);
763     ok(lo == 0, "Expected 0, got %08x\n", lo);
764
765     test_assembly_name_props(name, winename);
766
767     IAssemblyName_Release(name);
768 }
769
770 START_TEST(asmname)
771 {
772     if (!init_functionpointers())
773     {
774         skip("fusion.dll not available\n");
775         return;
776     }
777
778     test_CreateAssemblyNameObject();
779 }