ReactOS  0.4.15-dev-1171-gab82533
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 
32 static HRESULT (WINAPI *pCreateAssemblyEnum)(IAssemblyEnum **pEnum,
36 static HRESULT (WINAPI *pCreateAssemblyNameObject)(IAssemblyName **ppAssemblyNameObj,
39 static HRESULT (WINAPI *pGetCachePath)(ASM_CACHE_FLAGS dwCacheFlags,
41 static 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 
90 static inline void to_widechar(LPWSTR dest, LPCSTR src)
91 {
93 }
94 
95 static 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 
156  if (file == INVALID_HANDLE_VALUE)
157  return FALSE;
158 
159  WriteFile(file, data, strlen(data), &written, NULL);
160 
161  if (size)
162  {
165  }
166 
167  CloseHandle(file);
168  return TRUE;
169 }
170 
171 static 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 
217 typedef struct _tagASMNAME
218 {
219  struct list entry;
220  char data[1];
221 } ASMNAME;
222 
223 static 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";
226  WIN32_FIND_DATAA ffd;
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  {
257  lstrcpyA(culture, ptr);
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 
275 static void enum_gac_assemblies(struct list *assemblies, char path[MAX_PATH])
276 {
277  WIN32_FIND_DATAA ffd;
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 
296 static void test_enumerate(void)
297 {
298  struct list assemblies = LIST_INIT(assemblies);
299  struct list *item, *cursor;
300  IAssemblyEnum *asmenum;
302  WCHAR buf[MAX_PATH];
303  CHAR path[MAX_PATH];
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);
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 
378 static void test_enumerate_name(void)
379 {
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;
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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 
665 done:
666  sprintf(path, "%s\\Wine\\1.0.0.0__16a3fcd171e93a8d\\Wine.dll", gac);
667  DeleteFileA(path);
668  sprintf(path, "%s\\Wine\\1.0.1.2__16a3fcd171e93a8d\\Wine.dll", gac);
669  DeleteFileA(path);
670  sprintf(path, "%s\\Wine\\1.0.1.2__123456789abcdef0\\Wine.dll", gac);
671  DeleteFileA(path);
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 
682 START_TEST(asmenum)
683 {
684  if (!init_functionpointers())
685  return;
686 
688  test_enumerate();
690 }
disp
Definition: i386-dis.c:3181
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static void test_enumerate(void)
Definition: asmenum.c:296
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
#define CloseHandle
Definition: compat.h:487
static void to_multibyte(LPSTR dest, LPWSTR src)
Definition: asmenum.c:95
#define WideCharToMultiByte
Definition: compat.h:111
HRESULT hr
Definition: shlfolder.c:183
static const WCHAR szDllName[]
Definition: sip.c:61
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define TRUE
Definition: types.h:120
static HMODULE hmscoree
Definition: assembly.c:44
#define CP_ACP
Definition: compat.h:109
char CHAR
Definition: xmlstorage.h:175
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
static void enum_gac_assemblies(struct list *assemblies, char path[MAX_PATH])
Definition: asmenum.c:275
static IUnknown IAssemblyName * pName
Definition: asmenum.c:33
static void to_widechar(LPWSTR dest, LPCSTR src)
Definition: asmenum.c:90
static void test_CreateAssemblyEnum(void)
Definition: asmenum.c:171
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
struct _tagASMNAME ASMNAME
GLuint GLuint end
Definition: gl.h:1545
#define FILE_BEGIN
Definition: compat.h:509
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
BOOL WINAPI FindNextFileA(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:336
char * LPSTR
Definition: xmlstorage.h:182
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static HRESULT(WINAPI *pCreateAssemblyEnum)(IAssemblyEnum **pEnum
ASM_CACHE_FLAGS
Definition: fusion.idl:26
#define sprintf(buf, format,...)
Definition: sprintf.c:55
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define FALSE
Definition: types.h:117
static IUnknown IAssemblyName DWORD dwFlags
Definition: asmenum.c:33
static BOOL init_functionpointers(void)
Definition: asmenum.c:44
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
#define GENERIC_WRITE
Definition: nt_native.h:90
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
static PVOID ptr
Definition: dispmode.c:27
static BOOL create_full_path(LPCSTR path)
Definition: asmenum.c:100
static LPWSTR pwzCachePath
Definition: asmenum.c:40
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
static void enum_gac_assembly_dirs(struct list *assemblies, const char *parent, char path[MAX_PATH])
Definition: asmenum.c:223
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
const char * LPCSTR
Definition: xmlstorage.h:183
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
static LPCWSTR LPVOID HMODULE * phModDll
Definition: asmenum.c:41
#define FreeLibrary(x)
Definition: compat.h:496
char data[1]
Definition: asmenum.c:220
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
r parent
Definition: btrfs.c:2944
#define LIST_INIT(head)
Definition: queue.h:197
__wchar_t WCHAR
Definition: xmlstorage.h:180
struct list entry
Definition: asmenum.c:48
LONG HRESULT
Definition: typedefs.h:79
static void test_enumerate_name(void)
Definition: asmenum.c:378
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
static BOOL create_file_data(LPCSTR name, LPCSTR data, DWORD size)
Definition: asmenum.c:150
unsigned long DWORD
Definition: ntddk_ex.h:95
static LPWSTR PDWORD pcchPath
Definition: asmenum.c:40
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
static LPCWSTR szAssemblyName
Definition: asmenum.c:37
static IUnknown * pUnkReserved
Definition: asmenum.c:33
START_TEST(asmenum)
Definition: asmenum.c:682
int ret
uint32_t entry
Definition: isohybrid.c:63
GLenum GLsizei len
Definition: glext.h:6722
Definition: _list.h:228
GLenum src
Definition: glext.h:6340
static IUnknown IAssemblyName DWORD LPVOID pvReserved
Definition: asmenum.c:33
#define S_OK
Definition: intsafe.h:51
#define CREATE_ALWAYS
Definition: disk.h:72
static unsigned __int64 next
Definition: rand_nt.c:6
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
static ATOM item
Definition: dde.c:856
const char cursor[]
Definition: icontest.c:13
static LPCWSTR szVersion
Definition: asmenum.c:41
#define ok(value,...)
Definition: atltest.h:57
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
DWORD exp
Definition: msg.c:16033
#define lstrcpynA
Definition: compat.h:499
DWORD * PDWORD
Definition: pedump.c:68
#define MultiByteToWideChar
Definition: compat.h:110
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: name.c:38
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define GetProcAddress(x, y)
Definition: compat.h:501
static char * dest
Definition: rtl.c:135
static const WCHAR culture[]
Definition: asmname.c:67
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:488
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define LIST_ENTRY(type)
Definition: queue.h:175
#define win_skip
Definition: test.h:149
HANDLE WINAPI FindFirstFileA(IN LPCSTR lpFileName, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:263
#define HeapFree(x, y, z)
Definition: compat.h:483
#define SetFilePointer
Definition: compat.h:491
Definition: fci.c:126
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
GLuint const GLchar * name
Definition: glext.h:6031