push 5b1efc32b5a8acb1d5b5e60584746392dd0c436e
[wine/hacks.git] / dlls / fusion / tests / asmenum.c
blobcb6ea3dfdeb71c42242692d1ebf5aad0c6509974
1 /*
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
19 #define COBJMACROS
21 #include <stdio.h>
23 #include <windows.h>
24 #include <shlwapi.h>
25 #include <mscoree.h>
26 #include <fusion.h>
27 #include <corerror.h>
29 #include "wine/test.h"
30 #include "wine/list.h"
32 static HRESULT (WINAPI *pCreateAssemblyEnum)(IAssemblyEnum **pEnum,
33 IUnknown *pUnkReserved,
34 IAssemblyName *pName,
35 DWORD dwFlags, LPVOID pvReserved);
36 static HRESULT (WINAPI *pCreateAssemblyNameObject)(LPASSEMBLYNAME *ppAssemblyNameObj,
37 LPCWSTR szAssemblyName, DWORD dwFlags,
38 LPVOID pvReserved);
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)
46 HRESULT hr;
47 HMODULE hfusion;
48 HMODULE hmscoree;
50 static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
52 hmscoree = LoadLibraryA("mscoree.dll");
53 if (!hmscoree)
55 win_skip("mscoree.dll not available\n");
56 return FALSE;
59 pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
60 if (!pLoadLibraryShim)
62 win_skip("LoadLibraryShim not available\n");
63 FreeLibrary(hmscoree);
64 return FALSE;
67 hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion);
68 if (FAILED(hr))
70 win_skip("fusion.dll not available\n");
71 FreeLibrary(hmscoree);
72 return FALSE;
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");
83 return FALSE;
86 FreeLibrary(hmscoree);
87 return TRUE;
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)
102 LPSTR new_path;
103 BOOL ret = TRUE;
104 int len;
106 new_path = HeapAlloc(GetProcessHeap(), 0, lstrlenA(path) + 1);
107 if (!new_path)
108 return FALSE;
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))
117 LPSTR slash;
118 DWORD last_error = GetLastError();
120 if(last_error == ERROR_ALREADY_EXISTS)
121 break;
123 if(last_error != ERROR_PATH_NOT_FOUND)
125 ret = FALSE;
126 break;
129 if(!(slash = strrchr(new_path, '\\')))
131 ret = FALSE;
132 break;
135 len = slash - new_path;
136 new_path[len] = 0;
137 if(!create_full_path(new_path))
139 ret = FALSE;
140 break;
143 new_path[len] = '\\';
146 HeapFree(GetProcessHeap(), 0, new_path);
147 return ret;
150 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
152 HANDLE file;
153 DWORD written;
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);
159 if (size)
161 SetFilePointer(file, size, NULL, FILE_BEGIN);
162 SetEndOfFile(file);
165 CloseHandle(file);
168 #define create_file(name, size) create_file_data(name, name, size)
170 static void test_CreateAssemblyEnum(void)
172 HRESULT hr;
173 WCHAR namestr[MAX_PATH];
174 IAssemblyEnum *asmenum;
175 IAssemblyName *asmname;
177 to_widechar(namestr, "wine");
178 asmname = NULL;
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");
183 /* pEnum is NULL */
184 if (0)
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);
191 /* pName is NULL */
192 asmenum = NULL;
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
218 struct list entry;
219 LPSTR data;
220 } ASMNAME;
222 static BOOL enum_gac_assemblies(struct list *assemblies, int depth, LPSTR path)
224 WIN32_FIND_DATAA ffd;
225 CHAR buf[MAX_PATH];
226 CHAR disp[MAX_PATH];
227 ASMNAME *name;
228 HANDLE hfind;
229 LPSTR ptr;
231 static CHAR parent[MAX_PATH];
233 sprintf(buf, "%s\\*", path);
234 hfind = FindFirstFileA(buf, &ffd);
235 if (hfind == INVALID_HANDLE_VALUE)
236 return FALSE;
240 if (!lstrcmpA(ffd.cFileName, ".") || !lstrcmpA(ffd.cFileName, ".."))
241 continue;
243 if (depth == 0)
245 lstrcpyA(parent, ffd.cFileName);
247 else if (depth == 1)
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)
257 continue;
259 ptr = strstr(ffd.cFileName, "_");
260 *ptr = '\0';
261 ptr++;
263 if (*ptr != '_')
265 lstrcpyA(culture, ptr);
266 *strstr(culture, "_") = '\0';
268 else
269 lstrcpyA(culture, "neutral");
271 ptr = strchr(ptr, '_');
272 ptr++;
273 sprintf(buf, ", Version=%s, Culture=%s, PublicKeyToken=%s",
274 ffd.cFileName, culture, ptr);
275 lstrcpyA(disp, parent);
276 lstrcatA(disp, buf);
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);
283 continue;
286 sprintf(buf, "%s\\%s", path, ffd.cFileName);
287 enum_gac_assemblies(assemblies, depth + 1, buf);
288 } while (FindNextFileA(hfind, &ffd) != 0);
290 FindClose(hfind);
291 return TRUE;
294 static void test_enumerate(void)
296 struct list assemblies = LIST_INIT(assemblies);
297 struct list *item, *cursor;
298 IAssemblyEnum *asmenum;
299 IAssemblyName *next;
300 WCHAR buf[MAX_PATH];
301 CHAR path[MAX_PATH];
302 CHAR disp[MAX_PATH];
303 HRESULT hr;
304 BOOL found;
305 DWORD size;
307 size = MAX_PATH;
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);
326 asmenum = NULL;
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)
333 size = MAX_PATH;
334 IAssemblyName_GetDisplayName(next, buf, &size, 0);
335 to_multibyte(disp, buf);
337 found = FALSE;
338 LIST_FOR_EACH_SAFE(item, cursor, &assemblies)
340 ASMNAME *asmname = LIST_ENTRY(item, ASMNAME, entry);
342 if (!lstrcmpA(asmname->data, disp))
344 found = TRUE;
346 list_remove(&asmname->entry);
347 HeapFree(GetProcessHeap(), 0, asmname->data);
348 HeapFree(GetProcessHeap(), 0, asmname);
349 break;
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;
382 WCHAR buf[MAX_PATH];
383 CHAR gac[MAX_PATH];
384 CHAR path[MAX_PATH];
385 CHAR disp[MAX_PATH];
386 WCHAR namestr[MAX_PATH];
387 CHAR exp[6][MAX_PATH];
388 HRESULT hr;
389 DWORD size;
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");
398 size = MAX_PATH;
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");
428 asmname = NULL;
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");
433 asmenum = NULL;
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");
438 next = NULL;
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");
443 size = MAX_PATH;
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);
452 next = NULL;
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");
457 size = MAX_PATH;
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);
467 next = NULL;
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");
472 size = MAX_PATH;
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);
491 /* only Version */
492 to_widechar(namestr, "Wine, Version=1.0.1.2");
493 asmname = NULL;
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");
498 asmenum = NULL;
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");
503 next = NULL;
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");
508 size = MAX_PATH;
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);
518 next = NULL;
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");
523 size = MAX_PATH;
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");
544 asmname = NULL;
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");
549 asmenum = NULL;
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");
554 next = NULL;
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");
559 size = MAX_PATH;
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);
567 next = NULL;
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");
572 size = MAX_PATH;
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);
589 /* only Culture */
590 to_widechar(namestr, "wine, Culture=neutral");
591 asmname = NULL;
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");
596 asmenum = NULL;
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");
601 next = NULL;
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");
606 size = MAX_PATH;
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);
614 next = NULL;
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");
619 size = MAX_PATH;
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);
629 next = NULL;
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");
634 size = MAX_PATH;
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);
654 DeleteFileA(path);
655 sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d\\Wine.dll", gac);
656 DeleteFileA(path);
657 sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0\\Wine.dll", gac);
658 DeleteFileA(path);
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);
669 START_TEST(asmenum)
671 if (!init_functionpointers())
672 return;
674 test_CreateAssemblyEnum();
675 test_enumerate();
676 test_enumerate_name();