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
29 #include "wine/test.h"
30 #include "wine/list.h"
32 static HRESULT (WINAPI
*pCreateAssemblyEnum
)(IAssemblyEnum
**pEnum
,
33 IUnknown
*pUnkReserved
,
35 DWORD dwFlags
, LPVOID pvReserved
);
36 static HRESULT (WINAPI
*pCreateAssemblyNameObject
)(LPASSEMBLYNAME
*ppAssemblyNameObj
,
37 LPCWSTR szAssemblyName
, DWORD dwFlags
,
39 static HRESULT (WINAPI
*pGetCachePath
)(ASM_CACHE_FLAGS dwCacheFlags
,
40 LPWSTR pwzCachePath
, PDWORD pcchPath
);
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");
55 win_skip("mscoree.dll not available\n");
59 pLoadLibraryShim
= (void *)GetProcAddress(hmscoree
, "LoadLibraryShim");
60 if (!pLoadLibraryShim
)
62 win_skip("LoadLibraryShim not available\n");
63 FreeLibrary(hmscoree
);
67 hr
= pLoadLibraryShim(szFusion
, NULL
, NULL
, &hfusion
);
70 win_skip("fusion.dll not available\n");
71 FreeLibrary(hmscoree
);
75 pCreateAssemblyEnum
= (void *)GetProcAddress(hfusion
, "CreateAssemblyEnum");
76 pCreateAssemblyNameObject
= (void *)GetProcAddress(hfusion
, "CreateAssemblyNameObject");
77 pGetCachePath
= (void *)GetProcAddress(hfusion
, "GetCachePath");
79 if (!pCreateAssemblyEnum
||
80 !pCreateAssemblyNameObject
|| !pGetCachePath
)
82 win_skip("fusion.dll not implemented\n");
86 FreeLibrary(hmscoree
);
90 static inline void to_widechar(LPWSTR dest
, LPCSTR src
)
92 MultiByteToWideChar(CP_ACP
, 0, src
, -1, dest
, MAX_PATH
);
95 static inline void to_multibyte(LPSTR dest
, LPWSTR src
)
97 WideCharToMultiByte(CP_ACP
, 0, src
, -1, dest
, MAX_PATH
, NULL
, NULL
);
100 static BOOL
create_full_path(LPCSTR path
)
106 new_path
= HeapAlloc(GetProcessHeap(), 0, lstrlenA(path
) + 1);
110 lstrcpyA(new_path
, path
);
112 while ((len
= lstrlenA(new_path
)) && new_path
[len
- 1] == '\\')
113 new_path
[len
- 1] = 0;
115 while (!CreateDirectoryA(new_path
, NULL
))
118 DWORD last_error
= GetLastError();
120 if(last_error
== ERROR_ALREADY_EXISTS
)
123 if(last_error
!= ERROR_PATH_NOT_FOUND
)
129 if(!(slash
= strrchr(new_path
, '\\')))
135 len
= slash
- new_path
;
137 if(!create_full_path(new_path
))
143 new_path
[len
] = '\\';
146 HeapFree(GetProcessHeap(), 0, new_path
);
150 static void create_file_data(LPCSTR name
, LPCSTR data
, DWORD size
)
155 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
156 ok(file
!= INVALID_HANDLE_VALUE
, "Failure to open file %s\n", name
);
157 WriteFile(file
, data
, strlen(data
), &written
, NULL
);
161 SetFilePointer(file
, size
, NULL
, FILE_BEGIN
);
168 #define create_file(name, size) create_file_data(name, name, size)
170 static void test_CreateAssemblyEnum(void)
173 WCHAR namestr
[MAX_PATH
];
174 IAssemblyEnum
*asmenum
;
175 IAssemblyName
*asmname
;
177 to_widechar(namestr
, "wine");
179 hr
= pCreateAssemblyNameObject(&asmname
, namestr
, CANOF_PARSE_DISPLAY_NAME
, NULL
);
180 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
181 ok(asmname
!= NULL
, "Expected non-NULL asmname\n");
186 /* Crashes on .NET 1.x */
187 hr
= pCreateAssemblyEnum(NULL
, NULL
, asmname
, ASM_CACHE_GAC
, NULL
);
188 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
193 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, NULL
, ASM_CACHE_GAC
, NULL
);
194 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
195 ok(asmenum
!= NULL
, "Expected non-NULL asmenum\n");
197 IAssemblyEnum_Release(asmenum
);
199 /* dwFlags is ASM_CACHE_ROOT */
200 asmenum
= (IAssemblyEnum
*)0xdeadbeef;
201 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, NULL
, ASM_CACHE_ROOT
, NULL
);
202 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
203 ok(asmenum
== (IAssemblyEnum
*)0xdeadbeef,
204 "Expected asmenum to be unchanged, got %p\n", asmenum
);
206 /* invalid dwFlags */
207 asmenum
= (IAssemblyEnum
*)0xdeadbeef;
208 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, NULL
, 0, NULL
);
209 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
210 ok(asmenum
== (IAssemblyEnum
*)0xdeadbeef,
211 "Expected asmenum to be unchanged, got %p\n", asmenum
);
213 IAssemblyName_Release(asmname
);
216 typedef struct _tagASMNAME
222 static BOOL
enum_gac_assemblies(struct list
*assemblies
, int depth
, LPSTR path
)
224 WIN32_FIND_DATAA ffd
;
231 static CHAR parent
[MAX_PATH
];
233 sprintf(buf
, "%s\\*", path
);
234 hfind
= FindFirstFileA(buf
, &ffd
);
235 if (hfind
== INVALID_HANDLE_VALUE
)
240 if (!lstrcmpA(ffd
.cFileName
, ".") || !lstrcmpA(ffd
.cFileName
, ".."))
245 lstrcpyA(parent
, ffd
.cFileName
);
249 char culture
[MAX_PATH
];
250 char dll
[MAX_PATH
], exe
[MAX_PATH
];
252 /* Directories with no dll or exe will not be enumerated */
253 sprintf(dll
, "%s\\%s\\%s.dll", path
, ffd
.cFileName
, parent
);
254 sprintf(exe
, "%s\\%s\\%s.exe", path
, ffd
.cFileName
, parent
);
255 if (GetFileAttributesA(dll
) == INVALID_FILE_ATTRIBUTES
&&
256 GetFileAttributesA(exe
) == INVALID_FILE_ATTRIBUTES
)
259 ptr
= strstr(ffd
.cFileName
, "_");
265 lstrcpyA(culture
, ptr
);
266 *strstr(culture
, "_") = '\0';
269 lstrcpyA(culture
, "neutral");
271 ptr
= strchr(ptr
, '_');
273 sprintf(buf
, ", Version=%s, Culture=%s, PublicKeyToken=%s",
274 ffd
.cFileName
, culture
, ptr
);
275 lstrcpyA(disp
, parent
);
278 name
= HeapAlloc(GetProcessHeap(), 0, sizeof(ASMNAME
));
279 name
->data
= HeapAlloc(GetProcessHeap(), 0, lstrlenA(disp
) + 1);
280 lstrcpyA(name
->data
, disp
);
281 list_add_tail(assemblies
, &name
->entry
);
286 sprintf(buf
, "%s\\%s", path
, ffd
.cFileName
);
287 enum_gac_assemblies(assemblies
, depth
+ 1, buf
);
288 } while (FindNextFileA(hfind
, &ffd
) != 0);
294 static void test_enumerate(void)
296 struct list assemblies
= LIST_INIT(assemblies
);
297 struct list
*item
, *cursor
;
298 IAssemblyEnum
*asmenum
;
308 hr
= pGetCachePath(ASM_CACHE_GAC
, buf
, &size
);
309 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
311 to_multibyte(path
, buf
);
312 lstrcatA(path
, "_32");
313 enum_gac_assemblies(&assemblies
, 0, path
);
315 to_multibyte(path
, buf
);
316 lstrcatA(path
, "_64");
317 enum_gac_assemblies(&assemblies
, 0, path
);
319 to_multibyte(path
, buf
);
320 lstrcatA(path
, "_MSIL");
321 enum_gac_assemblies(&assemblies
, 0, path
);
323 to_multibyte(path
, buf
);
324 enum_gac_assemblies(&assemblies
, 0, path
);
327 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, NULL
, ASM_CACHE_GAC
, NULL
);
328 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
329 ok(asmenum
!= NULL
, "Expected non-NULL asmenum\n");
331 while (IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0) == S_OK
)
334 IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
335 to_multibyte(disp
, buf
);
338 LIST_FOR_EACH_SAFE(item
, cursor
, &assemblies
)
340 ASMNAME
*asmname
= LIST_ENTRY(item
, ASMNAME
, entry
);
342 if (!lstrcmpA(asmname
->data
, disp
))
346 list_remove(&asmname
->entry
);
347 HeapFree(GetProcessHeap(), 0, asmname
->data
);
348 HeapFree(GetProcessHeap(), 0, asmname
);
353 ok(found
, "Extra assembly enumerated: %s\n", disp
);
354 IAssemblyName_Release(next
);
357 /* enumeration is exhausted */
358 next
= (IAssemblyName
*)0xdeadbeef;
359 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
360 ok(hr
== S_FALSE
, "Expected S_FALSE, got %08x\n", hr
);
361 ok(next
== (IAssemblyName
*)0xdeadbeef,
362 "Expected next to be unchanged, got %p\n", next
);
364 LIST_FOR_EACH_SAFE(item
, cursor
, &assemblies
)
366 ASMNAME
*asmname
= LIST_ENTRY(item
, ASMNAME
, entry
);
368 ok(FALSE
, "Assembly not enumerated: %s\n", asmname
->data
);
370 list_remove(&asmname
->entry
);
371 HeapFree(GetProcessHeap(), 0, asmname
->data
);
372 HeapFree(GetProcessHeap(), 0, asmname
);
375 IAssemblyEnum_Release(asmenum
);
378 static void test_enumerate_name(void)
380 IAssemblyEnum
*asmenum
;
381 IAssemblyName
*asmname
, *next
;
386 WCHAR namestr
[MAX_PATH
];
387 CHAR exp
[6][MAX_PATH
];
391 lstrcpyA(exp
[0], "wine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
392 lstrcpyA(exp
[1], "wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=123456789abcdef0");
393 lstrcpyA(exp
[2], "wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
394 lstrcpyA(exp
[3], "Wine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
395 lstrcpyA(exp
[4], "Wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=123456789abcdef0");
396 lstrcpyA(exp
[5], "Wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
399 hr
= pGetCachePath(ASM_CACHE_GAC
, buf
, &size
);
400 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
402 to_multibyte(gac
, buf
);
403 create_full_path(gac
);
405 sprintf(path
, "%s\\Wine", gac
);
406 CreateDirectoryA(path
, NULL
);
408 sprintf(path
, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d", gac
);
409 CreateDirectoryA(path
, NULL
);
411 lstrcatA(path
, "\\Wine.dll");
412 create_file(path
, 100);
414 sprintf(path
, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d", gac
);
415 CreateDirectoryA(path
, NULL
);
417 lstrcatA(path
, "\\Wine.dll");
418 create_file(path
, 100);
420 sprintf(path
, "%s\\Wine\\1.0.1.2__123456789abcdef0", gac
);
421 CreateDirectoryA(path
, NULL
);
423 lstrcatA(path
, "\\Wine.dll");
424 create_file(path
, 100);
426 /* test case sensitivity */
427 to_widechar(namestr
, "wine");
429 hr
= pCreateAssemblyNameObject(&asmname
, namestr
, CANOF_PARSE_DISPLAY_NAME
, NULL
);
430 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
431 ok(asmname
!= NULL
, "Expected non-NULL asmname\n");
434 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, asmname
, ASM_CACHE_GAC
, NULL
);
435 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
436 ok(asmenum
!= NULL
, "Expected non-NULL asmenum\n");
439 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
440 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
441 ok(next
!= NULL
, "Expected non-NULL next\n");
444 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
445 to_multibyte(disp
, buf
);
446 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
447 ok(!lstrcmpA(disp
, exp
[0]),
448 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp
[0], exp
[1], disp
);
450 IAssemblyName_Release(next
);
453 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
454 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
455 ok(next
!= NULL
, "Expected non-NULL next\n");
458 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
459 to_multibyte(disp
, buf
);
460 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
461 ok(!lstrcmpA(disp
, exp
[1]) ||
462 !lstrcmpA(disp
, exp
[2]), /* Win98 */
463 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp
[1], exp
[2], disp
);
465 IAssemblyName_Release(next
);
468 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
469 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
470 ok(next
!= NULL
, "Expected non-NULL next\n");
473 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
474 to_multibyte(disp
, buf
);
475 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
476 ok(!lstrcmpA(disp
, exp
[2]) ||
477 !lstrcmpA(disp
, exp
[1]), /* Win98 */
478 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp
[2], exp
[1], disp
);
480 IAssemblyName_Release(next
);
482 next
= (IAssemblyName
*)0xdeadbeef;
483 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
484 ok(hr
== S_FALSE
, "Expected S_FALSE, got %08x\n", hr
);
485 ok(next
== (IAssemblyName
*)0xdeadbeef,
486 "Expected next to be unchanged, got %p\n", next
);
488 IAssemblyEnum_Release(asmenum
);
489 IAssemblyName_Release(asmname
);
492 to_widechar(namestr
, "Wine, Version=1.0.1.2");
494 hr
= pCreateAssemblyNameObject(&asmname
, namestr
, CANOF_PARSE_DISPLAY_NAME
, NULL
);
495 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
496 ok(asmname
!= NULL
, "Expected non-NULL asmname\n");
499 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, asmname
, ASM_CACHE_GAC
, NULL
);
500 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
501 ok(asmenum
!= NULL
, "Expected non-NULL asmenum\n");
504 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
505 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
506 ok(next
!= NULL
, "Expected non-NULL next\n");
509 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
510 to_multibyte(disp
, buf
);
511 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
512 ok(!lstrcmpA(disp
, exp
[4]) ||
513 !lstrcmpA(disp
, exp
[5]), /* Win98 */
514 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp
[4], exp
[5], disp
);
516 IAssemblyName_Release(next
);
519 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
520 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
521 ok(next
!= NULL
, "Expected non-NULL next\n");
524 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
525 to_multibyte(disp
, buf
);
526 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
527 ok(!lstrcmpA(disp
, exp
[5]) ||
528 !lstrcmpA(disp
, exp
[4]), /* Win98 */
529 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp
[5], exp
[4], disp
);
531 IAssemblyName_Release(next
);
533 next
= (IAssemblyName
*)0xdeadbeef;
534 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
535 ok(hr
== S_FALSE
, "Expected S_FALSE, got %08x\n", hr
);
536 ok(next
== (IAssemblyName
*)0xdeadbeef,
537 "Expected next to be unchanged, got %p\n", next
);
539 IAssemblyEnum_Release(asmenum
);
540 IAssemblyName_Release(asmname
);
542 /* only PublicKeyToken */
543 to_widechar(namestr
, "Wine, PublicKeyToken=16a3fcd171e93a8d");
545 hr
= pCreateAssemblyNameObject(&asmname
, namestr
, CANOF_PARSE_DISPLAY_NAME
, NULL
);
546 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
547 ok(asmname
!= NULL
, "Expected non-NULL asmname\n");
550 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, asmname
, ASM_CACHE_GAC
, NULL
);
551 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
552 ok(asmenum
!= NULL
, "Expected non-NULL asmenum\n");
555 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
556 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
557 ok(next
!= NULL
, "Expected non-NULL next\n");
560 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
561 to_multibyte(disp
, buf
);
562 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
563 ok(!lstrcmpA(disp
, exp
[3]), "Expected \"%s\", got \"%s\"\n", exp
[3], disp
);
565 IAssemblyName_Release(next
);
568 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
569 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
570 ok(next
!= NULL
, "Expected non-NULL next\n");
573 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
574 to_multibyte(disp
, buf
);
575 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
576 ok(!lstrcmpA(disp
, exp
[5]), "Expected \"%s\", got \"%s\"\n", exp
[5], disp
);
578 IAssemblyName_Release(next
);
580 next
= (IAssemblyName
*)0xdeadbeef;
581 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
582 ok(hr
== S_FALSE
, "Expected S_FALSE, got %08x\n", hr
);
583 ok(next
== (IAssemblyName
*)0xdeadbeef,
584 "Expected next to be unchanged, got %p\n", next
);
586 IAssemblyEnum_Release(asmenum
);
587 IAssemblyName_Release(asmname
);
590 to_widechar(namestr
, "wine, Culture=neutral");
592 hr
= pCreateAssemblyNameObject(&asmname
, namestr
, CANOF_PARSE_DISPLAY_NAME
, NULL
);
593 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
594 ok(asmname
!= NULL
, "Expected non-NULL asmname\n");
597 hr
= pCreateAssemblyEnum(&asmenum
, NULL
, asmname
, ASM_CACHE_GAC
, NULL
);
598 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
599 ok(asmenum
!= NULL
, "Expected non-NULL asmenum\n");
602 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
603 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
604 ok(next
!= NULL
, "Expected non-NULL next\n");
607 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
608 to_multibyte(disp
, buf
);
609 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
610 ok(!lstrcmpA(disp
, exp
[0]), "Expected \"%s\", got \"%s\"\n", exp
[0], disp
);
612 IAssemblyName_Release(next
);
615 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
616 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
617 ok(next
!= NULL
, "Expected non-NULL next\n");
620 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
621 to_multibyte(disp
, buf
);
622 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
623 ok(!lstrcmpA(disp
, exp
[1]) ||
624 !lstrcmpA(disp
, exp
[2]), /* Win98 */
625 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp
[1], exp
[2], disp
);
627 IAssemblyName_Release(next
);
630 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
631 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
632 ok(next
!= NULL
, "Expected non-NULL next\n");
635 hr
= IAssemblyName_GetDisplayName(next
, buf
, &size
, 0);
636 to_multibyte(disp
, buf
);
637 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
638 ok(!lstrcmpA(disp
, exp
[2]) ||
639 !lstrcmpA(disp
, exp
[1]), /* Win98 */
640 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp
[2], exp
[1], disp
);
642 IAssemblyName_Release(next
);
644 next
= (IAssemblyName
*)0xdeadbeef;
645 hr
= IAssemblyEnum_GetNextAssembly(asmenum
, NULL
, &next
, 0);
646 ok(hr
== S_FALSE
, "Expected S_FALSE, got %08x\n", hr
);
647 ok(next
== (IAssemblyName
*)0xdeadbeef,
648 "Expected next to be unchanged, got %p\n", next
);
650 IAssemblyEnum_Release(asmenum
);
651 IAssemblyName_Release(asmname
);
653 sprintf(path
, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d\\Wine.dll", gac
);
655 sprintf(path
, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d\\Wine.dll", gac
);
657 sprintf(path
, "%s\\Wine\\1.0.1.2__123456789abcdef0\\Wine.dll", gac
);
659 sprintf(path
, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d", gac
);
660 RemoveDirectoryA(path
);
661 sprintf(path
, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d", gac
);
662 RemoveDirectoryA(path
);
663 sprintf(path
, "%s\\Wine\\1.0.1.2__123456789abcdef0", gac
);
664 RemoveDirectoryA(path
);
665 sprintf(path
, "%s\\Wine", gac
);
666 RemoveDirectoryA(path
);
671 if (!init_functionpointers())
674 test_CreateAssemblyEnum();
676 test_enumerate_name();