2 * Copyright 2008 James Hawkins
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.
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.
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
28 #include "wine/test.h"
30 /* ok-like statement which takes two unicode strings or one unicode and one ANSI string as arguments */
31 static CHAR string1[MAX_PATH];
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);
38 static HRESULT (WINAPI *pCreateAssemblyNameObject)(LPASSEMBLYNAME *ppAssemblyNameObj,
39 LPCWSTR szAssemblyName, DWORD dwFlags,
41 static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion,
42 LPVOID pvReserved, HMODULE *phModDll);
44 static BOOL init_functionpointers(void)
50 static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
52 hmscoree = LoadLibraryA("mscoree.dll");
56 pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
57 if (!pLoadLibraryShim)
59 FreeLibrary(hmscoree);
63 hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion);
67 pCreateAssemblyNameObject = (void *)GetProcAddress(hfusion, "CreateAssemblyNameObject");
68 if (!pCreateAssemblyNameObject)
74 typedef struct _tagASMPROP_RES
81 static const ASMPROP_RES defaults[ASM_NAME_MAX_PARAMS] =
98 {S_FALSE, "", MAX_PATH},
99 {S_FALSE, "", MAX_PATH},
101 {S_OK, "", MAX_PATH},
113 static const ASMPROP_RES emptyname[ASM_NAME_MAX_PARAMS] =
130 {S_FALSE, "", MAX_PATH},
131 {S_FALSE, "", MAX_PATH},
133 {S_OK, "", MAX_PATH},
145 static const ASMPROP_RES winename[ASM_NAME_MAX_PARAMS] =
162 {S_FALSE, "", MAX_PATH},
163 {S_FALSE, "", MAX_PATH},
165 {S_OK, "", MAX_PATH},
177 static const ASMPROP_RES vername[ASM_NAME_MAX_PARAMS] =
194 {S_FALSE, "", MAX_PATH},
195 {S_FALSE, "", MAX_PATH},
197 {S_OK, "", MAX_PATH},
209 static const ASMPROP_RES badvername[ASM_NAME_MAX_PARAMS] =
226 {S_FALSE, "", MAX_PATH},
227 {S_FALSE, "", MAX_PATH},
229 {S_OK, "", MAX_PATH},
241 static const ASMPROP_RES neutralname[ASM_NAME_MAX_PARAMS] =
258 {S_FALSE, "", MAX_PATH},
259 {S_FALSE, "", MAX_PATH},
261 {S_OK, "", MAX_PATH},
273 static const ASMPROP_RES enname[ASM_NAME_MAX_PARAMS] =
290 {S_FALSE, "", MAX_PATH},
291 {S_FALSE, "", MAX_PATH},
293 {S_OK, "", MAX_PATH},
305 static const ASMPROP_RES pubkeyname[ASM_NAME_MAX_PARAMS] =
308 {S_OK, "\x12\x34\x56\x78\x90\xab\xcd\xef", 8},
322 {S_OK, "", MAX_PATH},
323 {S_OK, "", MAX_PATH},
325 {S_OK, "", MAX_PATH},
337 static inline void to_widechar(LPWSTR dest, LPCSTR src)
339 MultiByteToWideChar(CP_ACP, 0, src, -1, dest, MAX_PATH);
342 static inline void to_multibyte(LPSTR dest, LPWSTR src)
344 WideCharToMultiByte(CP_ACP, 0, src, -1, dest, MAX_PATH, NULL, NULL);
347 static void test_assembly_name_props_line(IAssemblyName *name,
348 const ASMPROP_RES *vals, int line)
352 WCHAR expect[MAX_PATH];
356 for (i = 0; i < ASM_NAME_MAX_PARAMS; i++)
358 to_widechar(expect, vals[i].val);
361 ZeroMemory(str, MAX_PATH);
362 hr = IAssemblyName_GetProperty(name, i, str, &size);
363 to_multibyte(val, str);
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)
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");
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);
380 #define test_assembly_name_props(name, vals) \
381 test_assembly_name_props_line(name, vals, __LINE__);
383 static void test_CreateAssemblyNameObject(void)
387 WCHAR namestr[MAX_PATH];
391 static const WCHAR empty[] = {0};
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);
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);
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);
410 /* check the contents of the AssemblyName for default values */
412 /* NULL szAssemblyName */
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");
419 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
420 ok(hr == FUSION_E_INVALID_NAME,
421 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
425 hr = IAssemblyName_GetName(name, &size, str);
426 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
427 ok(lstrlenW(str) == 0, "Expected empty name\n");
428 ok(size == 0, "Expected 0, got %d\n", size);
432 hr = IAssemblyName_GetVersion(name, &hi, &lo);
433 ok(hr == FUSION_E_INVALID_NAME,
434 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
435 ok(hi == 0, "Expected 0, got %08x\n", hi);
436 ok(lo == 0, "Expected 0, got %08x\n", lo);
438 test_assembly_name_props(name, defaults);
440 IAssemblyName_Release(name);
442 /* empty szAssemblyName */
444 hr = pCreateAssemblyNameObject(&name, empty, CANOF_SET_DEFAULT_VALUES, NULL);
445 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
446 ok(name != NULL, "Expected non-NULL name\n");
449 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
450 ok(hr == FUSION_E_INVALID_NAME,
451 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
455 hr = IAssemblyName_GetName(name, &size, str);
456 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
457 ok(lstrlenW(str) == 0, "Expected empty name\n");
458 ok(size == 1, "Expected 1, got %d\n", size);
462 hr = IAssemblyName_GetVersion(name, &hi, &lo);
463 ok(hr == FUSION_E_INVALID_NAME,
464 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
465 ok(hi == 0, "Expected 0, got %08x\n", hi);
466 ok(lo == 0, "Expected 0, got %08x\n", lo);
468 test_assembly_name_props(name, emptyname);
470 IAssemblyName_Release(name);
473 to_widechar(namestr, "wine");
475 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_SET_DEFAULT_VALUES, NULL);
476 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
477 ok(name != NULL, "Expected non-NULL name\n");
480 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
481 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
483 ok(size == 5, "Expected 5, got %d\n", size);
487 hr = IAssemblyName_GetName(name, &size, str);
488 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
490 ok(size == 5, "Expected 5, got %d\n", size);
494 hr = IAssemblyName_GetVersion(name, &hi, &lo);
495 ok(hr == FUSION_E_INVALID_NAME,
496 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
497 ok(hi == 0, "Expected 0, got %08x\n", hi);
498 ok(lo == 0, "Expected 0, got %08x\n", lo);
500 test_assembly_name_props(name, winename);
502 IAssemblyName_Release(name);
504 /* check the contents of the AssemblyName with parsing */
507 to_widechar(namestr, "wine");
509 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
510 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
511 ok(name != NULL, "Expected non-NULL name\n");
514 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
515 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
517 ok(size == 5, "Expected 5, got %d\n", size);
521 hr = IAssemblyName_GetName(name, &size, str);
522 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
524 ok(size == 5, "Expected 5, got %d\n", size);
528 hr = IAssemblyName_GetVersion(name, &hi, &lo);
529 ok(hr == FUSION_E_INVALID_NAME,
530 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
531 ok(hi == 0, "Expected 0, got %08x\n", hi);
532 ok(lo == 0, "Expected 0, got %08x\n", lo);
534 test_assembly_name_props(name, winename);
536 IAssemblyName_Release(name);
538 /* 'wine, Version=1.2.3.4' */
539 to_widechar(namestr, "wine, Version=1.2.3.4");
541 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
542 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
543 ok(name != NULL, "Expected non-NULL name\n");
546 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
547 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
548 ok_aw("wine, Version=1.2.3.4", str);
549 ok(size == 22, "Expected 22, got %d\n", size);
553 hr = IAssemblyName_GetName(name, &size, str);
554 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
556 ok(size == 5, "Expected 5, got %d\n", size);
560 hr = IAssemblyName_GetVersion(name, &hi, &lo);
561 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
562 ok(hi == 0x00010002, "Expected 0x00010002, got %08x\n", hi);
563 ok(lo == 0x00030004, "Expected 0x00030004, got %08x\n", lo);
565 test_assembly_name_props(name, vername);
567 IAssemblyName_Release(name);
569 /* Version isn't of the form 1.x.x.x */
570 to_widechar(namestr, "wine, Version=1.5");
572 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
573 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
574 ok(name != NULL, "Expected non-NULL name\n");
577 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
578 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
579 ok_aw("wine, Version=1.5", str);
580 ok(size == 18, "Expected 18, got %d\n", size);
584 hr = IAssemblyName_GetName(name, &size, str);
585 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
587 ok(size == 5, "Expected 5, got %d\n", size);
591 hr = IAssemblyName_GetVersion(name, &hi, &lo);
592 ok(hr == FUSION_E_INVALID_NAME,
593 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
594 ok(hi == 0, "Expected 0, got %08x\n", hi);
595 ok(lo == 0, "Expected 0, got %08x\n", lo);
597 test_assembly_name_props(name, badvername);
599 IAssemblyName_Release(name);
601 /* 'wine, Culture=neutral' */
602 to_widechar(namestr, "wine, Culture=neutral");
604 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
605 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
606 ok(name != NULL, "Expected non-NULL name\n");
609 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
610 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
611 ok_aw("wine, Culture=neutral", str);
612 ok(size == 22, "Expected 22, got %d\n", size);
616 hr = IAssemblyName_GetName(name, &size, str);
617 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
619 ok(size == 5, "Expected 5, got %d\n", size);
623 hr = IAssemblyName_GetVersion(name, &hi, &lo);
624 ok(hr == FUSION_E_INVALID_NAME,
625 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
626 ok(hi == 0, "Expected 0, got %08x\n", hi);
627 ok(lo == 0, "Expected 0, got %08x\n", lo);
629 test_assembly_name_props(name, neutralname);
631 IAssemblyName_Release(name);
633 /* 'wine, Culture=en' */
634 to_widechar(namestr, "wine, Culture=en");
636 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
637 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
638 ok(name != NULL, "Expected non-NULL name\n");
641 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
642 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
643 ok_aw("wine, Culture=en", str);
644 ok(size == 17, "Expected 17, got %d\n", size);
648 hr = IAssemblyName_GetName(name, &size, str);
649 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
651 ok(size == 5, "Expected 5, got %d\n", size);
655 hr = IAssemblyName_GetVersion(name, &hi, &lo);
656 ok(hr == FUSION_E_INVALID_NAME,
657 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
658 ok(hi == 0, "Expected 0, got %08x\n", hi);
659 ok(lo == 0, "Expected 0, got %08x\n", lo);
661 test_assembly_name_props(name, enname);
663 IAssemblyName_Release(name);
665 /* 'wine, PublicKeyToken=1234567890abcdef' */
666 to_widechar(namestr, "wine, PublicKeyToken=1234567890abcdef");
668 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
669 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
670 ok(name != NULL, "Expected non-NULL name\n");
673 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
674 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
675 ok_aw("wine, PublicKeyToken=1234567890abcdef", str);
676 ok(size == 38, "Expected 38, got %d\n", size);
680 hr = IAssemblyName_GetName(name, &size, str);
681 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
683 ok(size == 5, "Expected 5, got %d\n", size);
687 hr = IAssemblyName_GetVersion(name, &hi, &lo);
688 ok(hr == FUSION_E_INVALID_NAME,
689 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
690 ok(hi == 0, "Expected 0, got %08x\n", hi);
691 ok(lo == 0, "Expected 0, got %08x\n", lo);
693 test_assembly_name_props(name, pubkeyname);
695 IAssemblyName_Release(name);
697 /* PublicKeyToken is not 16 chars long */
698 to_widechar(namestr, "wine, PublicKeyToken=567890abcdef");
699 name = (IAssemblyName *)0xdeadbeef;
700 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
701 ok(hr == FUSION_E_INVALID_NAME,
702 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
703 ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
705 /* PublicKeyToken contains invalid chars */
706 to_widechar(namestr, "wine, PublicKeyToken=1234567890ghijkl");
707 name = (IAssemblyName *)0xdeadbeef;
708 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
709 ok(hr == FUSION_E_INVALID_NAME,
710 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
711 ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
713 /* no comma separator */
714 to_widechar(namestr, "wine PublicKeyToken=1234567890abcdef");
715 name = (IAssemblyName *)0xdeadbeef;
716 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
719 ok(hr == FUSION_E_INVALID_NAME,
720 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
721 ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
725 to_widechar(namestr, "wine, PublicKeyToken");
726 name = (IAssemblyName *)0xdeadbeef;
727 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
728 ok(hr == FUSION_E_INVALID_NAME,
729 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
730 ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
733 to_widechar(namestr, "wine, PublicKeyToken=");
734 name = (IAssemblyName *)0xdeadbeef;
735 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
736 ok(hr == FUSION_E_INVALID_NAME,
737 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
738 ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name);
740 /* invalid property */
741 to_widechar(namestr, "wine, BadProp=42");
743 hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
744 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
745 ok(name != NULL, "Expected non-NULL name\n");
748 hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
749 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
753 ok(size == 5, "Expected 5, got %d\n", size);
758 hr = IAssemblyName_GetName(name, &size, str);
759 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
761 ok(size == 5, "Expected 5, got %d\n", size);
765 hr = IAssemblyName_GetVersion(name, &hi, &lo);
766 ok(hr == FUSION_E_INVALID_NAME,
767 "Expected FUSION_E_INVALID_NAME, got %08x\n", hr);
768 ok(hi == 0, "Expected 0, got %08x\n", hi);
769 ok(lo == 0, "Expected 0, got %08x\n", lo);
771 test_assembly_name_props(name, winename);
773 IAssemblyName_Release(name);
778 if (!init_functionpointers())
780 skip("fusion.dll not available\n");
784 test_CreateAssemblyNameObject();