ReactOS  0.4.14-dev-606-g14ebc0b
cache.c
Go to the documentation of this file.
1 /*
2  * IAssemblyCache implementation
3  *
4  * Copyright 2010 Hans Leidekker for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdarg.h>
22 #ifdef __REACTOS__
23 #include <wchar.h>
24 #endif
25 
26 #define COBJMACROS
27 #define INITGUID
28 
29 #include "windef.h"
30 #include "winbase.h"
31 #include "ole2.h"
32 #include "winsxs.h"
33 #include "msxml2.h"
34 
35 #include "wine/debug.h"
36 #include "wine/list.h"
37 #include "sxs_private.h"
38 
40 
41 static const WCHAR cache_mutex_nameW[] =
42  {'_','_','W','I','N','E','_','S','X','S','_','C','A','C','H','E','_','M','U','T','E','X','_','_',0};
43 
44 static const WCHAR win32W[] = {'w','i','n','3','2',0};
45 static const WCHAR win32_policyW[] = {'w','i','n','3','2','-','p','o','l','i','c','y',0};
46 static const WCHAR backslashW[] = {'\\',0};
47 
48 struct cache
49 {
53 };
54 
55 static inline struct cache *impl_from_IAssemblyCache(IAssemblyCache *iface)
56 {
57  return CONTAINING_RECORD(iface, struct cache, IAssemblyCache_iface);
58 }
59 
61  IAssemblyCache *iface,
62  REFIID riid,
63  void **obj )
64 {
65  struct cache *cache = impl_from_IAssemblyCache(iface);
66 
67  TRACE("%p, %s, %p\n", cache, debugstr_guid(riid), obj);
68 
69  *obj = NULL;
70 
71  if (IsEqualIID(riid, &IID_IUnknown) ||
72  IsEqualIID(riid, &IID_IAssemblyCache))
73  {
74  IAssemblyCache_AddRef( iface );
75  *obj = cache;
76  return S_OK;
77  }
78 
79  return E_NOINTERFACE;
80 }
81 
83 {
84  struct cache *cache = impl_from_IAssemblyCache(iface);
85  return InterlockedIncrement( &cache->refs );
86 }
87 
89 {
90  struct cache *cache = impl_from_IAssemblyCache(iface);
92 
93  if (!refs)
94  {
95  TRACE("destroying %p\n", cache);
97  HeapFree( GetProcessHeap(), 0, cache );
98  }
99  return refs;
100 }
101 
102 static unsigned int build_sxs_path( WCHAR *path )
103 {
104  static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0};
105  unsigned int len = GetWindowsDirectoryW( path, MAX_PATH );
106 
107  memcpy( path + len, winsxsW, sizeof(winsxsW) );
108  return len + ARRAY_SIZE(winsxsW) - 1;
109 }
110 
111 static WCHAR *build_assembly_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
112  const WCHAR *version, unsigned int *len )
113 {
114  static const WCHAR fmtW[] =
115  {'%','s','_','%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
116  unsigned int buflen = ARRAY_SIZE(fmtW);
117  WCHAR *ret;
118 
119  buflen += lstrlenW( arch );
120  buflen += lstrlenW( name );
121  buflen += lstrlenW( token );
122  buflen += lstrlenW( version );
123  if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
124  *len = swprintf( ret, fmtW, arch, name, token, version );
125  return _wcslwr( ret );
126 }
127 
128 static WCHAR *build_manifest_path( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
129  const WCHAR *version )
130 {
131  static const WCHAR fmtW[] =
132  {'%','s','m','a','n','i','f','e','s','t','s','\\','%','s','.','m','a','n','i','f','e','s','t',0};
133  WCHAR *path = NULL, *ret, sxsdir[MAX_PATH];
134  unsigned int len;
135 
136  if (!(path = build_assembly_name( arch, name, token, version, &len ))) return NULL;
137  len += ARRAY_SIZE(fmtW);
138  len += build_sxs_path( sxsdir );
139  if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
140  {
141  HeapFree( GetProcessHeap(), 0, path );
142  return NULL;
143  }
144  swprintf( ret, fmtW, sxsdir, path );
145  HeapFree( GetProcessHeap(), 0, path );
146  return ret;
147 }
148 
149 static WCHAR *build_policy_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
150  unsigned int *len )
151 {
152  static const WCHAR fmtW[] =
153  {'%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
154  unsigned int buflen = ARRAY_SIZE(fmtW);
155  WCHAR *ret;
156 
157  buflen += lstrlenW( arch );
158  buflen += lstrlenW( name );
159  buflen += lstrlenW( token );
160  if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
161  *len = swprintf( ret, fmtW, arch, name, token );
162  return _wcslwr( ret );
163 }
164 
165 static WCHAR *build_policy_path( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
166  const WCHAR *version )
167 {
168  static const WCHAR fmtW[] =
169  {'%','s','p','o','l','i','c','i','e','s','\\','%','s','\\','%','s','.','p','o','l','i','c','y',0};
170  WCHAR *path = NULL, *ret, sxsdir[MAX_PATH];
171  unsigned int len;
172 
173  if (!(path = build_policy_name( arch, name, token, &len ))) return NULL;
174  len += ARRAY_SIZE(fmtW);
175  len += build_sxs_path( sxsdir );
176  len += lstrlenW( version );
177  if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
178  {
179  HeapFree( GetProcessHeap(), 0, path );
180  return NULL;
181  }
182  swprintf( ret, fmtW, sxsdir, path, version );
183  HeapFree( GetProcessHeap(), 0, path );
184  return ret;
185 }
186 
187 static void cache_lock( struct cache *cache )
188 {
190 }
191 
192 static void cache_unlock( struct cache *cache )
193 {
194  ReleaseMutex( cache->lock );
195 }
196 
197 #define ASSEMBLYINFO_FLAG_INSTALLED 1
198 
200  IAssemblyCache *iface,
201  DWORD flags,
204 {
205  struct cache *cache = impl_from_IAssemblyCache( iface );
206  IAssemblyName *name_obj;
207  const WCHAR *arch, *name, *token, *type, *version;
208  WCHAR *p, *path = NULL;
209  unsigned int len;
210  HRESULT hr;
211 
212  TRACE("%p, 0x%08x, %s, %p\n", iface, flags, debugstr_w(assembly_name), info);
213 
214  if (flags || (info && info->cbAssemblyInfo != sizeof(*info)))
215  return E_INVALIDARG;
216 
218  if (FAILED( hr ))
219  return hr;
220 
221  arch = get_name_attribute( name_obj, NAME_ATTR_ID_ARCH );
226  if (!arch || !name || !token || !type || !version)
227  {
228  IAssemblyName_Release( name_obj );
230  }
231  if (!info)
232  {
233  IAssemblyName_Release( name_obj );
234  return S_OK;
235  }
236  cache_lock( cache );
237 
238  if (!wcscmp( type, win32W )) path = build_manifest_path( arch, name, token, version );
239  else if (!wcscmp( type, win32_policyW )) path = build_policy_path( arch, name, token, version );
240  else
241  {
243  goto done;
244  }
245  if (!path)
246  {
247  hr = E_OUTOFMEMORY;
248  goto done;
249  }
250  hr = S_OK;
251  if (GetFileAttributesW( path ) != INVALID_FILE_ATTRIBUTES) /* FIXME: better check */
252  {
253  info->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED;
254  TRACE("assembly is installed\n");
255  }
256  if ((p = wcsrchr( path, '\\' ))) *p = 0;
257  len = lstrlenW( path ) + 1;
258  if (info->pszCurrentAssemblyPathBuf)
259  {
260  if (info->cchBuf < len)
261  {
262  info->cchBuf = len;
264  }
265  else lstrcpyW( info->pszCurrentAssemblyPathBuf, path );
266  }
267 
268 done:
269  HeapFree( GetProcessHeap(), 0, path );
270  IAssemblyName_Release( name_obj );
271  cache_unlock( cache );
272  return hr;
273 }
274 
276  IAssemblyCache *iface,
277  DWORD flags,
278  PVOID reserved,
280  LPCWSTR name )
281 {
282  FIXME("%p, 0x%08x, %p, %p, %s\n", iface, flags, reserved, item, debugstr_w(name));
283  return E_NOTIMPL;
284 }
285 
287  IAssemblyCache *iface,
288  IUnknown **reserved)
289 {
290  FIXME("%p\n", reserved);
291  return E_NOTIMPL;
292 }
293 
294 static BSTR get_attribute_value( IXMLDOMNamedNodeMap *map, const WCHAR *value_name )
295 {
296  HRESULT hr;
297  IXMLDOMNode *attr;
298  VARIANT var;
299  BSTR str;
300 
301  str = SysAllocString( value_name );
302  hr = IXMLDOMNamedNodeMap_getNamedItem( map, str, &attr );
303  SysFreeString( str );
304  if (hr != S_OK) return NULL;
305 
306  hr = IXMLDOMNode_get_nodeValue( attr, &var );
307  IXMLDOMNode_Release( attr );
308  if (hr != S_OK) return NULL;
309  if (V_VT(&var) != VT_BSTR)
310  {
311  VariantClear( &var );
312  return NULL;
313  }
314  TRACE("%s=%s\n", debugstr_w(value_name), debugstr_w(V_BSTR( &var )));
315  return V_BSTR( &var );
316 }
317 
318 struct file
319 {
320  struct list entry;
322 };
323 
324 struct assembly
325 {
331  struct list files;
332 };
333 
334 static void free_assembly( struct assembly *assembly )
335 {
336  struct list *item, *cursor;
337 
338  if (!assembly) return;
345  {
346  struct file *file = LIST_ENTRY( item, struct file, entry );
347  list_remove( &file->entry );
348  SysFreeString( file->name );
349  HeapFree( GetProcessHeap(), 0, file );
350  }
352 }
353 
355 {
356  static const WCHAR fileW[] = {'f','i','l','e',0};
357  static const WCHAR nameW[] = {'n','a','m','e',0};
358  IXMLDOMNamedNodeMap *attrs;
360  IXMLDOMNode *node;
361  struct file *f;
362  BSTR str;
363  HRESULT hr;
364  LONG len;
365 
366  str = SysAllocString( fileW );
367  hr = IXMLDOMDocument_getElementsByTagName( doc, str, &list );
368  SysFreeString( str );
369  if (hr != S_OK) return hr;
370 
371  hr = IXMLDOMNodeList_get_length( list, &len );
372  if (hr != S_OK) goto done;
373  TRACE("found %d files\n", len);
374  if (!len)
375  {
377  goto done;
378  }
379 
380  for (;;)
381  {
382  hr = IXMLDOMNodeList_nextNode( list, &node );
383  if (hr != S_OK || !node)
384  {
385  hr = S_OK;
386  break;
387  }
388 
389  /* FIXME: validate node type */
390 
391  hr = IXMLDOMNode_get_attributes( node, &attrs );
392  IXMLDOMNode_Release( node );
393  if (hr != S_OK)
394  goto done;
395 
396  if (!(f = HeapAlloc( GetProcessHeap(), 0, sizeof(struct file) )))
397  {
398  IXMLDOMNamedNodeMap_Release( attrs );
399  hr = E_OUTOFMEMORY;
400  goto done;
401  }
402 
403  f->name = get_attribute_value( attrs, nameW );
404  IXMLDOMNamedNodeMap_Release( attrs );
405  if (!f->name)
406  {
407  HeapFree( GetProcessHeap(), 0, f );
409  goto done;
410  }
411  list_add_tail( &assembly->files, &f->entry );
412  }
413 
414  if (list_empty( &assembly->files ))
415  {
416  WARN("no files found\n");
418  }
419 
420 done:
421  IXMLDOMNodeList_Release( list );
422  return hr;
423 }
424 
426 {
427  static const WCHAR identityW[] = {'a','s','s','e','m','b','l','y','I','d','e','n','t','i','t','y',0};
428  static const WCHAR typeW[] = {'t','y','p','e',0};
429  static const WCHAR nameW[] = {'n','a','m','e',0};
430  static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
431  static const WCHAR architectureW[] = {'p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e',0};
432  static const WCHAR tokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
434  IXMLDOMNode *node = NULL;
435  IXMLDOMNamedNodeMap *attrs = NULL;
436  struct assembly *a = NULL;
437  BSTR str;
438  HRESULT hr;
439  LONG len;
440 
441  str = SysAllocString( identityW );
442  hr = IXMLDOMDocument_getElementsByTagName( doc, str, &list );
443  SysFreeString( str );
444  if (hr != S_OK) goto done;
445 
446  hr = IXMLDOMNodeList_get_length( list, &len );
447  if (hr != S_OK) goto done;
448  if (!len)
449  {
451  goto done;
452  }
453  hr = IXMLDOMNodeList_nextNode( list, &node );
454  if (hr != S_OK) goto done;
455  if (!node)
456  {
458  goto done;
459  }
460  if (!(a = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct assembly) )))
461  {
462  hr = E_OUTOFMEMORY;
463  goto done;
464  }
465  list_init( &a->files );
466 
467  hr = IXMLDOMNode_get_attributes( node, &attrs );
468  if (hr != S_OK) goto done;
469 
470  a->type = get_attribute_value( attrs, typeW );
471  a->name = get_attribute_value( attrs, nameW );
472  a->version = get_attribute_value( attrs, versionW );
473  a->arch = get_attribute_value( attrs, architectureW );
474  a->token = get_attribute_value( attrs, tokenW );
475 
476  if (!a->type || (wcscmp( a->type, win32W ) && wcscmp( a->type, win32_policyW )) ||
477  !a->name || !a->version || !a->arch || !a->token)
478  {
479  WARN("invalid win32 assembly\n");
481  goto done;
482  }
483  if (!wcscmp( a->type, win32W )) hr = parse_files( doc, a );
484 
485 done:
486  if (attrs) IXMLDOMNamedNodeMap_Release( attrs );
487  if (node) IXMLDOMNode_Release( node );
488  if (list) IXMLDOMNodeList_Release( list );
489  if (hr == S_OK) *assembly = a;
490  else free_assembly( a );
491  return hr;
492 }
493 
494 static WCHAR *build_policy_filename( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
495  const WCHAR *version )
496 {
497  static const WCHAR policiesW[] = {'p','o','l','i','c','i','e','s','\\',0};
498  static const WCHAR suffixW[] = {'.','p','o','l','i','c','y',0};
499  WCHAR sxsdir[MAX_PATH], *ret, *fullname;
500  unsigned int len;
501 
502  if (!(fullname = build_policy_name( arch, name, token, &len ))) return NULL;
503  len += build_sxs_path( sxsdir );
504  len += ARRAY_SIZE(policiesW) - 1;
505  len += lstrlenW( version );
506  len += ARRAY_SIZE(suffixW) - 1;
507  if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
508  {
509  HeapFree( GetProcessHeap(), 0, fullname );
510  return NULL;
511  }
512  lstrcpyW( ret, sxsdir );
513  lstrcatW( ret, policiesW );
515  lstrcatW( ret, name );
517  lstrcatW( ret, backslashW );
518  lstrcatW( ret, version );
519  lstrcatW( ret, suffixW );
520 
521  HeapFree( GetProcessHeap(), 0, fullname );
522  return ret;
523 }
524 
526 {
527  WCHAR *dst;
528  BOOL ret;
529 
530  /* FIXME: handle catalog file */
531 
533  if (!dst) return E_OUTOFMEMORY;
534 
535  ret = CopyFileW( manifest, dst, FALSE );
536  HeapFree( GetProcessHeap(), 0, dst );
537  if (!ret)
538  {
540  WARN("failed to copy policy manifest file 0x%08x\n", hr);
541  return hr;
542  }
543  return S_OK;
544 }
545 
546 static WCHAR *build_source_filename( const WCHAR *manifest, struct file *file )
547 {
548  WCHAR *src;
549  const WCHAR *p;
550  int len;
551 
552  p = wcsrchr( manifest, '\\' );
553  if (!p) p = wcsrchr( manifest, '/' );
554  if (!p) return strdupW( manifest );
555 
556  len = p - manifest + 1;
557  if (!(src = HeapAlloc( GetProcessHeap(), 0, (len + lstrlenW( file->name ) + 1) * sizeof(WCHAR) )))
558  return NULL;
559 
560  memcpy( src, manifest, len * sizeof(WCHAR) );
561  lstrcpyW( src + len, file->name );
562  return src;
563 }
564 
565 static WCHAR *build_manifest_filename( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
566  const WCHAR *version )
567 {
568  static const WCHAR manifestsW[] = {'m','a','n','i','f','e','s','t','s','\\',0};
569  static const WCHAR suffixW[] = {'.','m','a','n','i','f','e','s','t',0};
570  WCHAR sxsdir[MAX_PATH], *ret, *fullname;
571  unsigned int len;
572 
573  if (!(fullname = build_assembly_name( arch, name, token, version, &len ))) return NULL;
574  len += build_sxs_path( sxsdir );
575  len += ARRAY_SIZE(manifestsW) - 1;
576  len += ARRAY_SIZE(suffixW) - 1;
577  if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
578  {
579  HeapFree( GetProcessHeap(), 0, fullname );
580  return NULL;
581  }
582  lstrcpyW( ret, sxsdir );
583  lstrcatW( ret, manifestsW );
584  lstrcatW( ret, fullname );
585  lstrcatW( ret, suffixW );
586 
587  HeapFree( GetProcessHeap(), 0, fullname );
588  return ret;
589 }
590 
592 {
593  HRESULT hr;
594  VARIANT var;
595  VARIANT_BOOL b;
596  BSTR str;
597 
599  VariantInit( &var );
600  V_VT( &var ) = VT_BSTR;
601  V_BSTR( &var ) = str;
602  hr = IXMLDOMDocument_load( doc, var, &b );
603  SysFreeString( str );
604  if (hr != S_OK) return hr;
605  if (!b)
606  {
607  WARN("failed to load manifest\n");
608  return S_FALSE;
609  }
610  return S_OK;
611 }
612 
614 {
615  WCHAR sxsdir[MAX_PATH], *p, *name, *dst, *src;
616  unsigned int len, len_name, len_sxsdir = build_sxs_path( sxsdir );
617  struct file *file;
619  BOOL ret;
620 
622  if (!dst) return E_OUTOFMEMORY;
623 
624  ret = CopyFileW( manifest, dst, FALSE );
625  HeapFree( GetProcessHeap(), 0, dst );
626  if (!ret)
627  {
629  WARN("failed to copy manifest file 0x%08x\n", hr);
630  return hr;
631  }
632 
634  &len_name );
635  if (!name) return E_OUTOFMEMORY;
636 
637  /* FIXME: this should be a transaction */
639  {
640  if (!(src = build_source_filename( manifest, file ))) goto done;
641 
642  len = len_sxsdir + len_name + lstrlenW( file->name );
643  if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) )))
644  {
645  HeapFree( GetProcessHeap(), 0, src );
646  goto done;
647  }
648  lstrcpyW( dst, sxsdir );
649  lstrcatW( dst, name );
651 
652  lstrcatW( dst, backslashW );
653  lstrcatW( dst, file->name );
654  for (p = dst; *p; p++) *p = towlower( *p );
655 
656  ret = CopyFileW( src, dst, FALSE );
657  HeapFree( GetProcessHeap(), 0, src );
658  HeapFree( GetProcessHeap(), 0, dst );
659  if (!ret)
660  {
662  WARN("failed to copy file 0x%08x\n", hr);
663  goto done;
664  }
665  }
666  hr = S_OK;
667 
668 done:
669  HeapFree( GetProcessHeap(), 0, name );
670  return hr;
671 }
672 
674  IAssemblyCache *iface,
675  DWORD flags,
676  LPCWSTR path,
678 {
679  struct cache *cache = impl_from_IAssemblyCache( iface );
680  HRESULT hr, init;
681  IXMLDOMDocument *doc = NULL;
682  struct assembly *assembly = NULL;
683 
684  TRACE("%p, 0x%08x, %s, %p\n", iface, flags, debugstr_w(path), ref);
685 
686  cache_lock( cache );
687  init = CoInitialize( NULL );
688 
689  hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&doc );
690  if (hr != S_OK)
691  goto done;
692 
693  if ((hr = load_manifest( doc, path )) != S_OK) goto done;
694  if ((hr = parse_assembly( doc, &assembly )) != S_OK) goto done;
695 
696  /* FIXME: verify name attributes */
697 
698  if (!wcscmp( assembly->type, win32_policyW ))
700  else
702 
703 done:
705  if (doc) IXMLDOMDocument_Release( doc );
706  if (SUCCEEDED(init)) CoUninitialize();
707  cache_unlock( cache );
708  return hr;
709 }
710 
712 {
713  WCHAR sxsdir[MAX_PATH], *name, *dirname, *filename;
714  unsigned int len, len_name, len_sxsdir = build_sxs_path( sxsdir );
716  struct file *file;
717 
719  &len_name );
720  if (!name) return E_OUTOFMEMORY;
721  if (!(dirname = HeapAlloc( GetProcessHeap(), 0, (len_sxsdir + len_name + 1) * sizeof(WCHAR) )))
722  goto done;
723  lstrcpyW( dirname, sxsdir );
724  lstrcpyW( dirname + len_sxsdir, name );
725 
727  {
728  len = len_sxsdir + len_name + 1 + lstrlenW( file->name );
729  if (!(filename = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) goto done;
732  lstrcatW( filename, file->name );
733 
734  if (!DeleteFileW( filename )) WARN( "failed to delete file %u\n", GetLastError() );
736  }
738  hr = S_OK;
739 
740 done:
742  HeapFree( GetProcessHeap(), 0, name );
743  return hr;
744 }
745 
747  IAssemblyCache *iface,
748  DWORD flags,
751  ULONG *disp )
752 {
753  struct cache *cache = impl_from_IAssemblyCache( iface );
754  HRESULT hr, init;
755  IXMLDOMDocument *doc = NULL;
756  struct assembly *assembly = NULL;
757  IAssemblyName *name_obj = NULL;
758  const WCHAR *arch, *name, *token, *type, *version;
759  WCHAR *p, *path = NULL;
760 
761  TRACE("%p, 0x%08x, %s, %p, %p\n", iface, flags, debugstr_w(assembly_name), ref, disp);
762 
763  if (ref)
764  {
765  FIXME("application reference not supported\n");
766  return E_NOTIMPL;
767  }
768  cache_lock( cache );
769  init = CoInitialize( NULL );
770 
772  if (FAILED( hr ))
773  goto done;
774 
780  if (!arch || !name || !token || !type || !version)
781  {
782  hr = E_INVALIDARG;
783  goto done;
784  }
787  else
788  {
789  hr = E_INVALIDARG;
790  goto done;
791  }
792 
793  hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&doc );
794  if (hr != S_OK)
795  goto done;
796 
797  if ((hr = load_manifest( doc, path )) != S_OK) goto done;
798  if ((hr = parse_assembly( doc, &assembly )) != S_OK) goto done;
799 
800  if (!DeleteFileW( path )) WARN( "unable to remove manifest file %u\n", GetLastError() );
801  else if ((p = wcsrchr( path, '\\' )))
802  {
803  *p = 0;
805  }
807 
808 done:
809  if (name_obj) IAssemblyName_Release( name_obj );
810  HeapFree( GetProcessHeap(), 0, path );
812  if (doc) IXMLDOMDocument_Release( doc );
813  if (SUCCEEDED(init)) CoUninitialize();
814  cache_unlock( cache );
815  return hr;
816 }
817 
818 static const IAssemblyCacheVtbl cache_vtbl =
819 {
821  cache_AddRef,
828 };
829 
830 /******************************************************************
831  * CreateAssemblyCache (SXS.@)
832  */
834 {
835  struct cache *cache;
836 
837  TRACE("%p, %u\n", obj, reserved);
838 
839  if (!obj)
840  return E_INVALIDARG;
841 
842  *obj = NULL;
843 
844  cache = HeapAlloc( GetProcessHeap(), 0, sizeof(struct cache) );
845  if (!cache)
846  return E_OUTOFMEMORY;
847 
849  cache->refs = 1;
851  if (!cache->lock)
852  {
853  HeapFree( GetProcessHeap(), 0, cache );
854  return HRESULT_FROM_WIN32( GetLastError() );
855  }
857  return S_OK;
858 }
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
Definition: cache.c:48
disp
Definition: i386-dis.c:3181
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
#define REFIID
Definition: guiddef.h:118
#define CloseHandle
Definition: compat.h:406
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
const WCHAR * get_name_attribute(IAssemblyName *iface, enum name_attr_id id)
Definition: name.c:185
#define ASSEMBLYINFO_FLAG_INSTALLED
Definition: cache.c:197
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static WCHAR * build_assembly_name(const WCHAR *arch, const WCHAR *name, const WCHAR *token, const WCHAR *version, unsigned int *len)
Definition: cache.c:111
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
REFIID riid
Definition: precomp.h:44
BSTR arch
Definition: cache.c:329
#define WARN(fmt,...)
Definition: debug.h:111
static unsigned int build_sxs_path(WCHAR *path)
Definition: cache.c:102
static const WCHAR win32_policyW[]
Definition: cache.c:45
static void cache_unlock(struct cache *cache)
Definition: cache.c:192
__cdecl __MINGW_NOTHROW char * dirname(char *)
static const WCHAR typeW[]
Definition: name.c:51
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static HRESULT WINAPI cache_CreateAssemblyCacheItem(IAssemblyCache *iface, DWORD flags, PVOID reserved, IAssemblyCacheItem **item, LPCWSTR name)
Definition: cache.c:275
static WCHAR * build_source_filename(const WCHAR *manifest, struct file *file)
Definition: cache.c:546
struct list files
Definition: cache.c:331
static HRESULT WINAPI cache_Reserved(IAssemblyCache *iface, IUnknown **reserved)
Definition: cache.c:286
static const IAssemblyCacheVtbl cache_vtbl
Definition: cache.c:818
OLECHAR * BSTR
Definition: compat.h:1942
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
const char * filename
Definition: ioapi.h:135
BSTR name
Definition: cache.c:321
static struct cache * impl_from_IAssemblyCache(IAssemblyCache *iface)
Definition: cache.c:55
#define lstrlenW
Definition: compat.h:415
short VARIANT_BOOL
Definition: compat.h:1939
Definition: send.c:47
static int init
Definition: wintirpc.c:33
static const WCHAR backslashW[]
Definition: cache.c:46
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
static BSTR get_attribute_value(IXMLDOMNamedNodeMap *map, const WCHAR *value_name)
Definition: cache.c:294
static WCHAR * build_policy_path(const WCHAR *arch, const WCHAR *name, const WCHAR *token, const WCHAR *version)
Definition: cache.c:165
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
static WCHAR * build_manifest_path(const WCHAR *arch, const WCHAR *name, const WCHAR *token, const WCHAR *version)
Definition: cache.c:128
struct node node
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
char name[1]
Definition: fci.c:135
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define a
Definition: ke_i.h:78
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
HRESULT WINAPI CreateAssemblyCache(IAssemblyCache **obj, DWORD reserved)
Definition: cache.c:833
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
#define debugstr_w
Definition: kernel32.h:32
BSTR version
Definition: cache.c:328
#define FIXME(fmt,...)
Definition: debug.h:110
r reserved
Definition: btrfs.c:2865
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
HANDLE lock
Definition: cache.c:52
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
static HRESULT uninstall_assembly(struct assembly *assembly)
Definition: cache.c:711
#define debugstr_guid
Definition: kernel32.h:35
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define b
Definition: ke_i.h:79
static HRESULT WINAPI cache_QueryAssemblyInfo(IAssemblyCache *iface, DWORD flags, LPCWSTR assembly_name, ASSEMBLY_INFO *info)
Definition: cache.c:199
static HRESULT parse_files(IXMLDOMDocument *doc, struct assembly *assembly)
Definition: cache.c:354
static const WCHAR nameW[]
Definition: main.c:46
static const WCHAR cache_mutex_nameW[]
Definition: cache.c:41
#define ERROR_SXS_MANIFEST_FORMAT_ERROR
Definition: winerror.h:2145
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
WINE_DEFAULT_DEBUG_CHANNEL(sxs)
const GUID IID_IUnknown
static HRESULT WINAPI cache_QueryInterface(IAssemblyCache *iface, REFIID riid, void **obj)
Definition: cache.c:60
#define MAX_PATH
Definition: compat.h:26
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
static const WCHAR win32W[]
Definition: cache.c:44
char * name
Definition: compiler.c:66
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT WINAPI CreateAssemblyNameObject(IAssemblyName **ppAssemblyNameObj, LPCWSTR szAssemblyName, DWORD dwFlags, LPVOID pvReserved)
Definition: asmname.c:797
Definition: cookie.c:201
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
Definition: _map.h:44
GLbitfield flags
Definition: glext.h:7161
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
LONG refs
Definition: cache.c:51
int ret
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
__u8 attr
Definition: mkdosfs.c:359
#define InterlockedDecrement
Definition: armddk.h:52
static IOleCache * cache
Definition: ole2.c:75
#define V_VT(A)
Definition: oleauto.h:211
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
Definition: _list.h:228
IAssemblyCache IAssemblyCache_iface
Definition: cache.c:50
GLenum src
Definition: glext.h:6340
static void cache_lock(struct cache *cache)
Definition: cache.c:187
static HRESULT parse_assembly(IXMLDOMDocument *doc, struct assembly **assembly)
Definition: cache.c:425
BSTR type
Definition: cache.c:326
#define V_BSTR(A)
Definition: oleauto.h:226
BSTR name
Definition: cache.c:327
static HRESULT install_assembly(const WCHAR *manifest, struct assembly *assembly)
Definition: cache.c:613
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
_CRTIMP wchar_t *__cdecl _wcslwr(_Inout_z_ wchar_t *_String)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
#define S_OK
Definition: intsafe.h:59
#define ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE
Definition: winerror.h:2231
static HRESULT install_policy(const WCHAR *manifest, struct assembly *assembly)
Definition: cache.c:525
#define InterlockedIncrement
Definition: armddk.h:53
static ATOM item
Definition: dde.c:856
#define ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE
Definition: winerror.h:2220
const char cursor[]
Definition: icontest.c:13
#define lstrcpyW
Definition: compat.h:414
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ARRAY_SIZE(a)
Definition: main.h:24
static HRESULT WINAPI cache_UninstallAssembly(IAssemblyCache *iface, DWORD flags, LPCWSTR assembly_name, LPCFUSION_INSTALL_REFERENCE ref, ULONG *disp)
Definition: cache.c:746
#define f
Definition: ke_i.h:83
#define E_NOTIMPL
Definition: ddrawi.h:99
GLenum GLenum dst
Definition: glext.h:6340
static HRESULT load_manifest(IXMLDOMDocument *doc, const WCHAR *filename)
Definition: cache.c:591
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
#define list
Definition: rosglue.h:35
BSTR token
Definition: cache.c:330
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
struct list entry
Definition: fci.c:128
static WCHAR * build_policy_name(const WCHAR *arch, const WCHAR *name, const WCHAR *token, unsigned int *len)
Definition: cache.c:149
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
Definition: name.c:38
static WCHAR * build_policy_filename(const WCHAR *arch, const WCHAR *name, const WCHAR *token, const WCHAR *version)
Definition: cache.c:494
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
unsigned int ULONG
Definition: retypes.h:1
#define towlower(c)
Definition: wctype.h:97
static HRESULT WINAPI cache_InstallAssembly(IAssemblyCache *iface, DWORD flags, LPCWSTR path, LPCFUSION_INSTALL_REFERENCE ref)
Definition: cache.c:673
static const CHAR manifest[]
Definition: v6util.h:39
static const WCHAR tokenW[]
Definition: name.c:50
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
#define LIST_ENTRY(type)
Definition: queue.h:175
#define INFINITE
Definition: serial.h:102
static const WCHAR fileW[]
Definition: url.c:111
static const WCHAR versionW[]
Definition: name.c:52
static void free_assembly(struct assembly *assembly)
Definition: cache.c:334
#define HeapFree(x, y, z)
Definition: compat.h:402
static ULONG WINAPI cache_Release(IAssemblyCache *iface)
Definition: cache.c:88
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
static ULONG WINAPI cache_AddRef(IAssemblyCache *iface)
Definition: cache.c:82
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static WCHAR * build_manifest_filename(const WCHAR *arch, const WCHAR *name, const WCHAR *token, const WCHAR *version)
Definition: cache.c:565
Definition: dlist.c:348
const struct _GUID CLSID_DOMDocument
Definition: fci.c:126
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
GLuint const GLchar * name
Definition: glext.h:6031