ReactOS 0.4.15-dev-8100-g1887773
asmenum.c
Go to the documentation of this file.
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
32static HRESULT (WINAPI *pCreateAssemblyEnum)(IAssemblyEnum **pEnum,
36static HRESULT (WINAPI *pCreateAssemblyNameObject)(IAssemblyName **ppAssemblyNameObj,
39static HRESULT (WINAPI *pGetCachePath)(ASM_CACHE_FLAGS dwCacheFlags,
41static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion,
43
45{
46 HRESULT hr;
47 HMODULE hfusion;
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");
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");
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
87 return TRUE;
88}
89
90static inline void to_widechar(LPWSTR dest, LPCSTR src)
91{
93}
94
95static inline void to_multibyte(LPSTR dest, LPWSTR src)
96{
98}
99
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;
119
121 break;
122
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
151{
152 HANDLE file;
153 DWORD written;
154
157 return FALSE;
158
159 WriteFile(file, data, strlen(data), &written, NULL);
160
161 if (size)
162 {
165 }
166
168 return TRUE;
169}
170
171static void test_CreateAssemblyEnum(void)
172{
173 HRESULT hr;
174 WCHAR namestr[MAX_PATH];
175 IAssemblyEnum *asmenum;
176 IAssemblyName *asmname;
177
178 to_widechar(namestr, "wine");
179 asmname = NULL;
180 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
181 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
182 ok(asmname != NULL, "Expected non-NULL asmname\n");
183
184 /* pEnum is NULL */
185 if (0)
186 {
187 /* Crashes on .NET 1.x */
188 hr = pCreateAssemblyEnum(NULL, NULL, asmname, ASM_CACHE_GAC, NULL);
189 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
190 }
191
192 /* pName is NULL */
193 asmenum = NULL;
194 hr = pCreateAssemblyEnum(&asmenum, NULL, NULL, ASM_CACHE_GAC, NULL);
195 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
196 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
197
198 IAssemblyEnum_Release(asmenum);
199
200 /* dwFlags is ASM_CACHE_ROOT */
201 asmenum = (IAssemblyEnum *)0xdeadbeef;
202 hr = pCreateAssemblyEnum(&asmenum, NULL, NULL, ASM_CACHE_ROOT, NULL);
203 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
204 ok(asmenum == (IAssemblyEnum *)0xdeadbeef,
205 "Expected asmenum to be unchanged, got %p\n", asmenum);
206
207 /* invalid dwFlags */
208 asmenum = (IAssemblyEnum *)0xdeadbeef;
209 hr = pCreateAssemblyEnum(&asmenum, NULL, NULL, 0, NULL);
210 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
211 ok(asmenum == (IAssemblyEnum *)0xdeadbeef,
212 "Expected asmenum to be unchanged, got %p\n", asmenum);
213
214 IAssemblyName_Release(asmname);
215}
216
217typedef struct _tagASMNAME
218{
219 struct list entry;
220 char data[1];
222
223static void enum_gac_assembly_dirs(struct list *assemblies, const char *parent, char path[MAX_PATH])
224{
225 static const char format[] = "%s, Version=%s, Culture=%s, PublicKeyToken=%s";
227 ASMNAME *name;
228 HANDLE hfind;
229 int len;
230 char *ptr, *end = path + strlen( path );
231
232 lstrcpynA( end, "\\*", path + MAX_PATH - end );
233 hfind = FindFirstFileA(path, &ffd);
234 if (hfind == INVALID_HANDLE_VALUE) return;
235 end++;
236
237 do
238 {
239 char culture[MAX_PATH];
240
241 if (!strcmp(ffd.cFileName, ".") || !strcmp(ffd.cFileName, "..")) continue;
242
243 *end = 0;
244 /* Directories with no dll or exe will not be enumerated */
245 sprintf(end, "%s\\%s.dll", ffd.cFileName, parent);
247 {
248 sprintf(end, "%s\\%s.exe", ffd.cFileName, parent);
250 }
251
252 if (!(ptr = strchr(ffd.cFileName, '_'))) continue;
253 *ptr++ = 0;
254
255 if (*ptr != '_')
256 {
258 *strchr(culture, '_') = 0;
259 }
260 else
261 lstrcpyA(culture, "neutral");
262
263 ptr = strchr(ptr, '_');
264 ptr++;
265 len = sizeof(format) + strlen(parent) + strlen(ffd.cFileName) + strlen(culture) + strlen(ptr);
266
268 sprintf( name->data, format, parent, ffd.cFileName, culture, ptr);
269 list_add_tail(assemblies, &name->entry);
270 } while (FindNextFileA(hfind, &ffd) != 0);
271
272 FindClose(hfind);
273}
274
275static void enum_gac_assemblies(struct list *assemblies, char path[MAX_PATH])
276{
278 HANDLE hfind;
279 char *end = path + strlen( path );
280
281 lstrcpynA( end, "\\*", path + MAX_PATH - end );
282 hfind = FindFirstFileA(path, &ffd);
283 if (hfind == INVALID_HANDLE_VALUE) return;
284 end++;
285
286 do
287 {
288 if (!strcmp(ffd.cFileName, ".") || !strcmp(ffd.cFileName, "..")) continue;
289 lstrcpynA( end, ffd.cFileName, path + MAX_PATH - end );
290 enum_gac_assembly_dirs( assemblies, ffd.cFileName, path );
291 } while (FindNextFileA(hfind, &ffd) != 0);
292
293 FindClose(hfind);
294}
295
296static void test_enumerate(void)
297{
298 struct list assemblies = LIST_INIT(assemblies);
299 struct list *item, *cursor;
300 IAssemblyEnum *asmenum;
304 CHAR disp[MAX_PATH];
305 HRESULT hr;
306 BOOL found;
307 DWORD size;
308
309 size = MAX_PATH;
310 hr = pGetCachePath(ASM_CACHE_GAC, buf, &size);
311 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
312
314 lstrcatA(path, "_32");
315 enum_gac_assemblies(&assemblies, path);
316
318 lstrcatA(path, "_64");
319 enum_gac_assemblies(&assemblies, path);
320
322 lstrcatA(path, "_MSIL");
323 enum_gac_assemblies(&assemblies, path);
324
326 enum_gac_assemblies(&assemblies, path);
327
328 asmenum = NULL;
329 hr = pCreateAssemblyEnum(&asmenum, NULL, NULL, ASM_CACHE_GAC, NULL);
330 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
331 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
332
333 while (IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0) == S_OK)
334 {
335 size = MAX_PATH;
336 IAssemblyName_GetDisplayName(next, buf, &size, 0);
337 to_multibyte(disp, buf);
338
339 found = FALSE;
340 LIST_FOR_EACH_SAFE(item, cursor, &assemblies)
341 {
342 ASMNAME *asmname = LIST_ENTRY(item, ASMNAME, entry);
343
344 if (!lstrcmpA(asmname->data, disp))
345 {
346 found = TRUE;
347
348 list_remove(&asmname->entry);
349 HeapFree(GetProcessHeap(), 0, asmname);
350 break;
351 }
352 }
353
354 ok(found, "Extra assembly enumerated: %s\n", disp);
355 IAssemblyName_Release(next);
356 }
357
358 /* enumeration is exhausted */
359 next = (IAssemblyName *)0xdeadbeef;
360 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
361 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
362 ok(next == (IAssemblyName *)0xdeadbeef,
363 "Expected next to be unchanged, got %p\n", next);
364
365 LIST_FOR_EACH_SAFE(item, cursor, &assemblies)
366 {
367 ASMNAME *asmname = LIST_ENTRY(item, ASMNAME, entry);
368
369 ok(FALSE, "Assembly not enumerated: %s\n", asmname->data);
370
371 list_remove(&asmname->entry);
372 HeapFree(GetProcessHeap(), 0, asmname);
373 }
374
375 IAssemblyEnum_Release(asmenum);
376}
377
378static void test_enumerate_name(void)
379{
380 IAssemblyEnum *asmenum;
381 IAssemblyName *asmname, *next;
383 CHAR gac[MAX_PATH];
385 CHAR disp[MAX_PATH];
386 WCHAR namestr[MAX_PATH];
387 CHAR exp[6][MAX_PATH];
388 HRESULT hr;
389 DWORD size;
390
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");
397
398 size = MAX_PATH;
399 hr = pGetCachePath(ASM_CACHE_GAC, buf, &size);
400 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
401
402 to_multibyte(gac, buf);
403 create_full_path(gac);
404
405 sprintf(path, "%s\\Wine", gac);
407
408 sprintf(path, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d", gac);
410
411 lstrcatA(path, "\\Wine.dll");
412 if (!create_file_data(path, path, 100))
413 {
414 win_skip("Failed to open file %s, skipping name enumeration tests\n", path);
415 goto done;
416 }
417
418 sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d", gac);
420
421 lstrcatA(path, "\\Wine.dll");
422 if (!create_file_data(path, path, 100))
423 {
424 win_skip("Failed to open file %s, skipping name enumeration tests\n", path);
425 goto done;
426 }
427
428 sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0", gac);
430
431 lstrcatA(path, "\\Wine.dll");
432 if (!create_file_data(path, path, 100))
433 {
434 win_skip("Failed to open file %s, skipping name enumeration tests\n", path);
435 goto done;
436 }
437
438 /* test case sensitivity */
439 to_widechar(namestr, "wine");
440 asmname = NULL;
441 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
442 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
443 ok(asmname != NULL, "Expected non-NULL asmname\n");
444
445 asmenum = NULL;
446 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
447 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
448 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
449
450 next = NULL;
451 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
452 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
453 ok(next != NULL, "Expected non-NULL next\n");
454
455 size = MAX_PATH;
456 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
457 to_multibyte(disp, buf);
458 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
459 ok(!lstrcmpA(disp, exp[0]),
460 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[0], exp[1], disp);
461
462 IAssemblyName_Release(next);
463
464 next = NULL;
465 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
466 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
467 ok(next != NULL, "Expected non-NULL next\n");
468
469 size = MAX_PATH;
470 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
471 to_multibyte(disp, buf);
472 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
473 ok(!lstrcmpA(disp, exp[1]) ||
474 !lstrcmpA(disp, exp[2]), /* Win98 */
475 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[1], exp[2], disp);
476
477 IAssemblyName_Release(next);
478
479 next = NULL;
480 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
481 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
482 ok(next != NULL, "Expected non-NULL next\n");
483
484 size = MAX_PATH;
485 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
486 to_multibyte(disp, buf);
487 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
488 ok(!lstrcmpA(disp, exp[2]) ||
489 !lstrcmpA(disp, exp[1]), /* Win98 */
490 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[2], exp[1], disp);
491
492 IAssemblyName_Release(next);
493
494 next = (IAssemblyName *)0xdeadbeef;
495 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
496 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
497 ok(next == (IAssemblyName *)0xdeadbeef,
498 "Expected next to be unchanged, got %p\n", next);
499
500 IAssemblyEnum_Release(asmenum);
501 IAssemblyName_Release(asmname);
502
503 /* only Version */
504 to_widechar(namestr, "Wine, Version=1.0.1.2");
505 asmname = NULL;
506 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
507 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
508 ok(asmname != NULL, "Expected non-NULL asmname\n");
509
510 asmenum = NULL;
511 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
512 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
513 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
514
515 next = NULL;
516 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
517 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
518 ok(next != NULL, "Expected non-NULL next\n");
519
520 size = MAX_PATH;
521 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
522 to_multibyte(disp, buf);
523 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
524 ok(!lstrcmpA(disp, exp[4]) ||
525 !lstrcmpA(disp, exp[5]), /* Win98 */
526 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[4], exp[5], disp);
527
528 IAssemblyName_Release(next);
529
530 next = NULL;
531 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
532 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
533 ok(next != NULL, "Expected non-NULL next\n");
534
535 size = MAX_PATH;
536 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
537 to_multibyte(disp, buf);
538 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
539 ok(!lstrcmpA(disp, exp[5]) ||
540 !lstrcmpA(disp, exp[4]), /* Win98 */
541 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[5], exp[4], disp);
542
543 IAssemblyName_Release(next);
544
545 next = (IAssemblyName *)0xdeadbeef;
546 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
547 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
548 ok(next == (IAssemblyName *)0xdeadbeef,
549 "Expected next to be unchanged, got %p\n", next);
550
551 IAssemblyEnum_Release(asmenum);
552 IAssemblyName_Release(asmname);
553
554 /* only PublicKeyToken */
555 to_widechar(namestr, "Wine, PublicKeyToken=16a3fcd171e93a8d");
556 asmname = NULL;
557 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
558 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
559 ok(asmname != NULL, "Expected non-NULL asmname\n");
560
561 asmenum = NULL;
562 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
563 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
564 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
565
566 next = NULL;
567 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
568 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
569 ok(next != NULL, "Expected non-NULL next\n");
570
571 size = MAX_PATH;
572 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
573 to_multibyte(disp, buf);
574 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
575 ok(!lstrcmpA(disp, exp[3]), "Expected \"%s\", got \"%s\"\n", exp[3], disp);
576
577 IAssemblyName_Release(next);
578
579 next = NULL;
580 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
581 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
582 ok(next != NULL, "Expected non-NULL next\n");
583
584 size = MAX_PATH;
585 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
586 to_multibyte(disp, buf);
587 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
588 ok(!lstrcmpA(disp, exp[5]), "Expected \"%s\", got \"%s\"\n", exp[5], disp);
589
590 IAssemblyName_Release(next);
591
592 next = (IAssemblyName *)0xdeadbeef;
593 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
594 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
595 ok(next == (IAssemblyName *)0xdeadbeef,
596 "Expected next to be unchanged, got %p\n", next);
597
598 IAssemblyEnum_Release(asmenum);
599 IAssemblyName_Release(asmname);
600
601 /* only Culture */
602 to_widechar(namestr, "wine, Culture=neutral");
603 asmname = NULL;
604 hr = pCreateAssemblyNameObject(&asmname, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
605 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
606 ok(asmname != NULL, "Expected non-NULL asmname\n");
607
608 asmenum = NULL;
609 hr = pCreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
610 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
611 ok(asmenum != NULL, "Expected non-NULL asmenum\n");
612
613 next = NULL;
614 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
615 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
616 ok(next != NULL, "Expected non-NULL next\n");
617
618 size = MAX_PATH;
619 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
620 to_multibyte(disp, buf);
621 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
622 ok(!lstrcmpA(disp, exp[0]), "Expected \"%s\", got \"%s\"\n", exp[0], disp);
623
624 IAssemblyName_Release(next);
625
626 next = NULL;
627 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
628 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
629 ok(next != NULL, "Expected non-NULL next\n");
630
631 size = MAX_PATH;
632 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
633 to_multibyte(disp, buf);
634 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
635 ok(!lstrcmpA(disp, exp[1]) ||
636 !lstrcmpA(disp, exp[2]), /* Win98 */
637 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[1], exp[2], disp);
638
639 IAssemblyName_Release(next);
640
641 next = NULL;
642 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
643 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
644 ok(next != NULL, "Expected non-NULL next\n");
645
646 size = MAX_PATH;
647 hr = IAssemblyName_GetDisplayName(next, buf, &size, 0);
648 to_multibyte(disp, buf);
649 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
650 ok(!lstrcmpA(disp, exp[2]) ||
651 !lstrcmpA(disp, exp[1]), /* Win98 */
652 "Expected \"%s\" or \"%s\", got \"%s\"\n", exp[2], exp[1], disp);
653
654 IAssemblyName_Release(next);
655
656 next = (IAssemblyName *)0xdeadbeef;
657 hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
658 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
659 ok(next == (IAssemblyName *)0xdeadbeef,
660 "Expected next to be unchanged, got %p\n", next);
661
662 IAssemblyEnum_Release(asmenum);
663 IAssemblyName_Release(asmname);
664
665done:
666 sprintf(path, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d\\Wine.dll", gac);
668 sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d\\Wine.dll", gac);
670 sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0\\Wine.dll", gac);
672 sprintf(path, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d", gac);
674 sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d", gac);
676 sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0", gac);
678 sprintf(path, "%s\\Wine", gac);
680}
681
683{
685 return;
686
690}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
Definition: list.h:37
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR szDllName[]
Definition: sip.c:61
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define FILE_BEGIN
Definition: compat.h:761
#define CP_ACP
Definition: compat.h:109
#define SetFilePointer
Definition: compat.h:743
#define lstrcpynA
Definition: compat.h:751
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, int depth, const WCHAR *prefix, LPWSTR path)
Definition: asmenum.c:307
struct _tagASMNAME ASMNAME
static const WCHAR culture[]
Definition: asmname.c:67
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
HANDLE WINAPI FindFirstFileA(IN LPCSTR lpFileName, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:263
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileA(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:336
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4194
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
ASM_CACHE_FLAGS
Definition: fusion.idl:27
@ ASM_CACHE_ROOT
Definition: fusion.idl:31
@ ASM_CACHE_GAC
Definition: fusion.idl:29
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
const char cursor[]
Definition: icontest.c:13
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static LPSTR pName
Definition: security.c:75
static LPCSTR DWORD void * pvReserved
Definition: str.c:196
static BOOL create_full_path(LPCSTR path)
Definition: asmenum.c:100
static BOOL init_functionpointers(void)
Definition: asmenum.c:44
static LPWSTR pwzCachePath
Definition: asmenum.c:40
static void to_multibyte(LPSTR dest, LPWSTR src)
Definition: asmenum.c:95
static BOOL create_file_data(LPCSTR name, LPCSTR data, DWORD size)
Definition: asmenum.c:150
static IUnknown * pUnkReserved
Definition: asmenum.c:33
static void test_enumerate(void)
Definition: asmenum.c:296
static IUnknown IAssemblyName DWORD dwFlags
Definition: asmenum.c:35
static void test_CreateAssemblyEnum(void)
Definition: asmenum.c:171
static LPCWSTR szVersion
Definition: asmenum.c:41
static void enum_gac_assembly_dirs(struct list *assemblies, const char *parent, char path[MAX_PATH])
Definition: asmenum.c:223
static LPCWSTR LPVOID HMODULE * phModDll
Definition: asmenum.c:42
static void test_enumerate_name(void)
Definition: asmenum.c:378
static LPCWSTR szAssemblyName
Definition: asmenum.c:37
static LPWSTR PDWORD pcchPath
Definition: asmenum.c:40
static void to_widechar(LPWSTR dest, LPCSTR src)
Definition: asmenum.c:90
static HMODULE hmscoree
Definition: fusion.c:24
static char * dest
Definition: rtl.c:135
static ATOM item
Definition: dde.c:856
DWORD exp
Definition: msg.c:16058
#define GENERIC_WRITE
Definition: nt_native.h:90
DWORD * PDWORD
Definition: pedump.c:68
static unsigned __int64 next
Definition: rand_nt.c:6
#define offsetof(TYPE, MEMBER)
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
#define win_skip
Definition: test.h:163
HRESULT hr
Definition: shlfolder.c:183
struct list entry
Definition: asmenum.c:48
char data[1]
Definition: asmenum.c:220
Definition: fci.c:127
Definition: name.c:39
#define LIST_INIT(head)
Definition: queue.h:197
#define LIST_ENTRY(type)
Definition: queue.h:175
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
@ CANOF_PARSE_DISPLAY_NAME
Definition: winsxs.idl:193
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175