- Add winetests for credui, cryptnet, cryptui, dnsapi, fusion
[reactos.git] / rostests / winetests / fusion / asmenum.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 <shlwapi.h>
25 #include <mscoree.h>
26 #include <fusion.h>
27 #include <corerror.h>
28
29 #include "wine/test.h"
30 #include "wine/list.h"
31
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);
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 {
55 win_skip("mscoree.dll not available\n");
56 return FALSE;
57 }
58
59 pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim");
60 if (!pLoadLibraryShim)
61 {
62 win_skip("LoadLibraryShim not available\n");
63 FreeLibrary(hmscoree);
64 return FALSE;
65 }
66
67 hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion);
68 if (FAILED(hr))
69 {
70 win_skip("fusion.dll not available\n");
71 FreeLibrary(hmscoree);
72 return FALSE;
73 }
74
75 pCreateAssemblyEnum = (void *)GetProcAddress(hfusion, "CreateAssemblyEnum");
76 pCreateAssemblyNameObject = (void *)GetProcAddress(hfusion, "CreateAssemblyNameObject");
77 pGetCachePath = (void *)GetProcAddress(hfusion, "GetCachePath");
78
79 if (!pCreateAssemblyEnum ||
80 !pCreateAssemblyNameObject || !pGetCachePath)
81 {
82 win_skip("fusion.dll not implemented\n");
83 return FALSE;
84 }
85
86 FreeLibrary(hmscoree);
87 return TRUE;
88 }
89
90 static inline void to_widechar(LPWSTR dest, LPCSTR src)
91 {
92 MultiByteToWideChar(CP_ACP, 0, src, -1, dest, MAX_PATH);
93 }
94
95 static inline void to_multibyte(LPSTR dest, LPWSTR src)
96 {
97 WideCharToMultiByte(CP_ACP, 0, src, -1, dest, MAX_PATH, NULL, NULL);
98 }
99
100 static BOOL create_full_path(LPCSTR path)
101 {
102 LPSTR new_path;
103 BOOL ret = TRUE;
104 int len;
105
106 new_path = HeapAlloc(GetProcessHeap(), 0, lstrlenA(path) + 1);
107 if (!new_path)
108 return FALSE;
109
110 lstrcpyA(new_path, path);
111
112 while ((len = lstrlenA(new_path)) && new_path[len - 1] == '\\')
113 new_path[len - 1] = 0;
114
115 while (!CreateDirectoryA(new_path, NULL))
116 {
117 LPSTR slash;
118 DWORD last_error = GetLastError();
119
120 if(last_error == ERROR_ALREADY_EXISTS)
121 break;
122
123 if(last_error != ERROR_PATH_NOT_FOUND)
124 {
125 ret = FALSE;
126 break;
127 }
128
129 if(!(slash = strrchr(new_path, '\\')))
130 {
131 ret = FALSE;
132 break;
133 }
134
135 len = slash - new_path;
136 new_path[len] = 0;
137 if(!create_full_path(new_path))
138 {
139 ret = FALSE;
140 break;
141 }
142
143 new_path[len] = '\\';
144 }
145
146 HeapFree(GetProcessHeap(), 0, new_path);
147 return ret;
148 }
149
150 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
151 {
152 HANDLE file;
153 DWORD written;
154
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);
158
159 if (size)
160 {
161 SetFilePointer(file, size, NULL, FILE_BEGIN);
162 SetEndOfFile(file);
163 }
164
165 CloseHandle(file);
166 }
167
168 #define create_file(name, size) create_file_data(name, name, size)
169
170 static void test_CreateAssemblyEnum(void)
171 {
172 HRESULT hr;
173 WCHAR namestr[MAX_PATH];
174 IAssemblyEnum *asmenum;
175 IAssemblyName *asmname;
176
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");
182
183 /* pEnum is NULL */
184 if (0)
185 {
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);
189 }
190
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");
196
197 IAssemblyEnum_Release(asmenum);
198
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);
205
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);
212 }
213
214 typedef struct _tagASMNAME
215 {
216 struct list entry;
217 LPSTR data;
218 } ASMNAME;
219
220 static BOOL enum_gac_assemblies(struct list *assemblies, int depth, LPSTR path)
221 {
222 WIN32_FIND_DATAA ffd;
223 CHAR buf[MAX_PATH];
224 CHAR disp[MAX_PATH];
225 ASMNAME *name;
226 HANDLE hfind;
227 LPSTR ptr;
228
229 static CHAR parent[MAX_PATH];
230
231 sprintf(buf, "%s\\*", path);
232 hfind = FindFirstFileA(buf, &ffd);
233 if (hfind == INVALID_HANDLE_VALUE)
234 return FALSE;
235
236 do
237 {
238 if (!lstrcmpA(ffd.cFileName, ".") || !lstrcmpA(ffd.cFileName, ".."))
239 continue;
240
241 if (depth == 0)
242 {
243 sprintf(parent, "%s, ", ffd.cFileName);
244 }
245 else if (depth == 1)
246 {
247 char culture[MAX_PATH];
248
249 ptr = strstr(ffd.cFileName, "_");
250 *ptr = '\0';
251 ptr++;
252
253 if (*ptr != '_')
254 {
255 lstrcpyA(culture, ptr);
256 *strstr(culture, "_") = '\0';
257 }
258 else
259 lstrcpyA(culture, "neutral");
260
261 ptr = strchr(ptr, '_');
262 ptr++;
263 sprintf(buf, "Version=%s, Culture=%s, PublicKeyToken=%s",
264 ffd.cFileName, culture, ptr);
265 lstrcpyA(disp, parent);
266 lstrcatA(disp, buf);
267
268 name = HeapAlloc(GetProcessHeap(), 0, sizeof(ASMNAME));
269 name->data = HeapAlloc(GetProcessHeap(), 0, lstrlenA(disp) + 1);
270 lstrcpyA(name->data, disp);
271 list_add_tail(assemblies, &name->entry);
272
273 continue;
274 }
275
276 sprintf(buf, "%s\\%s", path, ffd.cFileName);
277 enum_gac_assemblies(assemblies, depth + 1, buf);
278 } while (FindNextFileA(hfind, &ffd) != 0);
279
280 FindClose(hfind);
281 return TRUE;
282 }
283
284 static void test_enumerate(void)
285 {
286 struct list assemblies = LIST_INIT(assemblies);
287 struct list *item, *cursor;
288 IAssemblyEnum *asmenum;
289 IAssemblyName *next;
290 WCHAR buf[MAX_PATH];
291 CHAR path[MAX_PATH];
292 CHAR disp[MAX_PATH];
293 HRESULT hr;
294 BOOL found;
295 DWORD size;
296
297 size = MAX_PATH;
298 hr = pGetCachePath(ASM_CACHE_GAC, buf, &size);
299 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
300
301 to_multibyte(path, buf);
302 lstrcatA(path, "_32");
303 enum_gac_assemblies(&assemblies, 0, path);
304
305 to_multibyte(path, buf);
306 lstrcatA(path, "_64");
307 enum_gac_assemblies(&assemblies, 0, path);
308
309 to_multibyte(path, buf);
310 lstrcatA(path, "_MSIL");
311 enum_gac_assemblies(&assemblies, 0, path);
312
313 to_multibyte(path, buf);
314 enum_gac_assemblies(&assemblies, 0, path);
315
316 asmenum = NULL;
317 hr = pCreateAssemblyEnum(&asmenum, NULL, NULL, ASM_CACHE_GAC, NULL);
318 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
319 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
320
321 while (IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0) == S_OK)
322 {
323 size = MAX_PATH;
324 IAssemblyName_GetDisplayName(next, buf, &size, 0);
325 to_multibyte(disp, buf);
326
327 found = FALSE;
328 LIST_FOR_EACH_SAFE(item, cursor, &assemblies)
329 {
330 ASMNAME *asmname = LIST_ENTRY(item, ASMNAME, entry);
331
332 if (!lstrcmpA(asmname->data, disp))
333 {
334 found = TRUE;
335
336 list_remove(&asmname->entry);
337 HeapFree(GetProcessHeap(), 0, asmname->data);
338 HeapFree(GetProcessHeap(), 0, asmname);
339 break;
340 }
341 }
342
343 ok(found, "Extra assembly enumerated: %s\n", disp);
344 IAssemblyName_Release(next);
345 }
346
347 /* enumeration is exhausted */
348 next = (IAssemblyName *)0xdeadbeef;
349 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
350 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
351 ok(next == (IAssemblyName *)0xdeadbeef,
352 "Expected next to be unchanged, got %p\n", next);
353
354 LIST_FOR_EACH_SAFE(item, cursor, &assemblies)
355 {
356 ASMNAME *asmname = LIST_ENTRY(item, ASMNAME, entry);
357
358 ok(FALSE, "Assembly not enumerated: %s\n", asmname->data);
359
360 list_remove(&asmname->entry);
361 HeapFree(GetProcessHeap(), 0, asmname->data);
362 HeapFree(GetProcessHeap(), 0, asmname);
363 }
364
365 IAssemblyEnum_Release(asmenum);
366 }
367
368 static void test_enumerate_name(void)
369 {
370 IAssemblyEnum *asmenum;
371 IAssemblyName *asmname, *next;
372 WCHAR buf[MAX_PATH];
373 CHAR gac[MAX_PATH];
374 CHAR path[MAX_PATH];
375 CHAR disp[MAX_PATH];
376 WCHAR namestr[MAX_PATH];
377 CHAR exp[6][MAX_PATH];
378 HRESULT hr;
379 DWORD size;
380
381 lstrcpyA(exp[0], "wine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
382 lstrcpyA(exp[1], "wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=123456789abcdef0");
383 lstrcpyA(exp[2], "wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
384 lstrcpyA(exp[3], "Wine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
385 lstrcpyA(exp[4], "Wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=123456789abcdef0");
386 lstrcpyA(exp[5], "Wine, Version=1.0.1.2, Culture=neutral, PublicKeyToken=16a3fcd171e93a8d");
387
388 size = MAX_PATH;
389 hr = pGetCachePath(ASM_CACHE_GAC, buf, &size);
390 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
391
392 to_multibyte(gac, buf);
393 create_full_path(gac);
394
395 sprintf(path, "%s\\Wine", gac);
396 CreateDirectoryA(path, NULL);
397
398 sprintf(path, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d", gac);
399 CreateDirectoryA(path, NULL);
400
401 lstrcatA(path, "\\Wine.dll");
402 create_file(path, 100);
403
404 sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d", gac);
405 CreateDirectoryA(path, NULL);
406
407 lstrcatA(path, "\\Wine.dll");
408 create_file(path, 100);
409
410 sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0", gac);
411 CreateDirectoryA(path, NULL);
412
413 lstrcatA(path, "\\Wine.dll");
414 create_file(path, 100);
415
416 /* test case sensitivity */
417 to_widechar(namestr, "wine");
418 asmname = NULL;
419 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
420 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
421 ok(asmname != NULL, "Expected non-NULL asmname\n");
422
423 asmenum = NULL;
424 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
425 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
426 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
427
428 next = NULL;
429 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
430 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
431 ok(next != NULL, "Expected non-NULL next\n");
432
433 size = MAX_PATH;
434 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
435 to_multibyte(disp, buf);
436 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
437 ok(!lstrcmpA(disp, exp[0]) ||
438 !lstrcmpA(disp, exp[1]),
439 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[0], exp[1], disp);
440
441 IAssemblyName_Release(next);
442
443 next = NULL;
444 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
445 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
446 ok(next != NULL, "Expected non-NULL next\n");
447
448 size = MAX_PATH;
449 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
450 to_multibyte(disp, buf);
451 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
452 ok(!lstrcmpA(disp, exp[1]) ||
453 !lstrcmpA(disp, exp[2]),
454 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[1], exp[2], disp);
455
456 IAssemblyName_Release(next);
457
458 next = NULL;
459 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
460 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
461 ok(next != NULL, "Expected non-NULL next\n");
462
463 size = MAX_PATH;
464 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
465 to_multibyte(disp, buf);
466 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
467 ok(!lstrcmpA(disp, exp[2]), "Expected \"%s\", got \"%s\"\n", exp[2], disp);
468
469 IAssemblyName_Release(next);
470
471 next = (IAssemblyName *)0xdeadbeef;
472 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
473 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
474 ok(next == (IAssemblyName *)0xdeadbeef,
475 "Expected next to be unchanged, got %p\n", next);
476
477 IAssemblyEnum_Release(asmenum);
478 IAssemblyName_Release(asmname);
479
480 /* only Version */
481 to_widechar(namestr, "Wine, Version=1.0.1.2");
482 asmname = NULL;
483 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
484 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
485 ok(asmname != NULL, "Expected non-NULL asmname\n");
486
487 asmenum = NULL;
488 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
489 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
490 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
491
492 next = NULL;
493 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
494 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
495 ok(next != NULL, "Expected non-NULL next\n");
496
497 size = MAX_PATH;
498 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
499 to_multibyte(disp, buf);
500 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
501 ok(!lstrcmpA(disp, exp[4]), "Expected \"%s\", got \"%s\"\n", exp[4], disp);
502
503 IAssemblyName_Release(next);
504
505 next = NULL;
506 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
507 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
508 ok(next != NULL, "Expected non-NULL next\n");
509
510 size = MAX_PATH;
511 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
512 to_multibyte(disp, buf);
513 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
514 ok(!lstrcmpA(disp, exp[5]), "Expected \"%s\", got \"%s\"\n", exp[5], disp);
515
516 IAssemblyName_Release(next);
517
518 next = (IAssemblyName *)0xdeadbeef;
519 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
520 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
521 ok(next == (IAssemblyName *)0xdeadbeef,
522 "Expected next to be unchanged, got %p\n", next);
523
524 IAssemblyEnum_Release(asmenum);
525 IAssemblyName_Release(asmname);
526
527 /* only PublicKeyToken */
528 to_widechar(namestr, "Wine, PublicKeyToken=16a3fcd171e93a8d");
529 asmname = NULL;
530 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
531 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
532 ok(asmname != NULL, "Expected non-NULL asmname\n");
533
534 asmenum = NULL;
535 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
536 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
537 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
538
539 next = NULL;
540 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
541 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
542 ok(next != NULL, "Expected non-NULL next\n");
543
544 size = MAX_PATH;
545 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
546 to_multibyte(disp, buf);
547 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
548 ok(!lstrcmpA(disp, exp[3]), "Expected \"%s\", got \"%s\"\n", exp[3], disp);
549
550 IAssemblyName_Release(next);
551
552 next = NULL;
553 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
554 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
555 ok(next != NULL, "Expected non-NULL next\n");
556
557 size = MAX_PATH;
558 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
559 to_multibyte(disp, buf);
560 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
561 ok(!lstrcmpA(disp, exp[5]), "Expected \"%s\", got \"%s\"\n", exp[5], disp);
562
563 IAssemblyName_Release(next);
564
565 next = (IAssemblyName *)0xdeadbeef;
566 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
567 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
568 ok(next == (IAssemblyName *)0xdeadbeef,
569 "Expected next to be unchanged, got %p\n", next);
570
571 IAssemblyEnum_Release(asmenum);
572 IAssemblyName_Release(asmname);
573
574 /* only Culture */
575 to_widechar(namestr, "wine, Culture=neutral");
576 asmname = NULL;
577 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
578 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
579 ok(asmname != NULL, "Expected non-NULL asmname\n");
580
581 asmenum = NULL;
582 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
583 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
584 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
585
586 next = NULL;
587 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
588 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
589 ok(next != NULL, "Expected non-NULL next\n");
590
591 size = MAX_PATH;
592 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
593 to_multibyte(disp, buf);
594 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
595 ok(!lstrcmpA(disp, exp[0]), "Expected \"%s\", got \"%s\"\n", exp[0], disp);
596
597 IAssemblyName_Release(next);
598
599 next = NULL;
600 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
601 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
602 ok(next != NULL, "Expected non-NULL next\n");
603
604 size = MAX_PATH;
605 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
606 to_multibyte(disp, buf);
607 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
608 ok(!lstrcmpA(disp, exp[1]) ||
609 !lstrcmpA(disp, exp[2]),
610 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[1], exp[2], disp);
611
612 IAssemblyName_Release(next);
613
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");
618
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]),
625 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[1], exp[2], disp);
626
627 IAssemblyName_Release(next);
628
629 next = (IAssemblyName *)0xdeadbeef;
630 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
631 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
632 ok(next == (IAssemblyName *)0xdeadbeef,
633 "Expected next to be unchanged, got %p\n", next);
634
635 IAssemblyEnum_Release(asmenum);
636 IAssemblyName_Release(asmname);
637
638 sprintf(path, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d\\Wine.dll", gac);
639 DeleteFileA(path);
640 sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d\\Wine.dll", gac);
641 DeleteFileA(path);
642 sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0\\Wine.dll", gac);
643 DeleteFileA(path);
644 sprintf(path, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d", gac);
645 RemoveDirectoryA(path);
646 sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d", gac);
647 RemoveDirectoryA(path);
648 sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0", gac);
649 RemoveDirectoryA(path);
650 sprintf(path, "%s\\Wine", gac);
651 RemoveDirectoryA(path);
652 }
653
654 START_TEST(asmenum)
655 {
656 if (!init_functionpointers())
657 return;
658
659 test_CreateAssemblyEnum();
660 test_enumerate();
661 test_enumerate_name();
662 }