ReactOS  0.4.13-dev-464-g6b95727
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 
23 #define COBJMACROS
24 #define INITGUID
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "winsxs.h"
30 #include "msxml2.h"
31 
32 #include "wine/debug.h"
33 #include "wine/list.h"
34 #include "wine/unicode.h"
35 #include "sxs_private.h"
36 
38 
39 static const WCHAR cache_mutex_nameW[] =
40  {'_','_','W','I','N','E','_','S','X','S','_','C','A','C','H','E','_','M','U','T','E','X','_','_',0};
41 
42 static const WCHAR win32W[] = {'w','i','n','3','2',0};
43 static const WCHAR win32_policyW[] = {'w','i','n','3','2','-','p','o','l','i','c','y',0};
44 static const WCHAR backslashW[] = {'\\',0};
45 
46 struct cache
47 {
51 };
52 
53 static inline struct cache *impl_from_IAssemblyCache(IAssemblyCache *iface)
54 {
55  return CONTAINING_RECORD(iface, struct cache, IAssemblyCache_iface);
56 }
57 
59  IAssemblyCache *iface,
60  REFIID riid,
61  void **obj )
62 {
63  struct cache *cache = impl_from_IAssemblyCache(iface);
64 
65  TRACE("%p, %s, %p\n", cache, debugstr_guid(riid), obj);
66 
67  *obj = NULL;
68 
69  if (IsEqualIID(riid, &IID_IUnknown) ||
70  IsEqualIID(riid, &IID_IAssemblyCache))
71  {
72  IAssemblyCache_AddRef( iface );
73  *obj = cache;
74  return S_OK;
75  }
76 
77  return E_NOINTERFACE;
78 }
79 
81 {
82  struct cache *cache = impl_from_IAssemblyCache(iface);
83  return InterlockedIncrement( &cache->refs );
84 }
85 
87 {
88  struct cache *cache = impl_from_IAssemblyCache(iface);
90 
91  if (!refs)
92  {
93  TRACE("destroying %p\n", cache);
95  HeapFree( GetProcessHeap(), 0, cache );
96  }
97  return refs;
98 }
99 
100 static unsigned int build_sxs_path( WCHAR *path )
101 {
102  static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0};
103  unsigned int len = GetWindowsDirectoryW( path, MAX_PATH );
104 
105  memcpy( path + len, winsxsW, sizeof(winsxsW) );
106  return len + ARRAY_SIZE(winsxsW) - 1;
107 }
108 
109 static WCHAR *build_assembly_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
110  const WCHAR *version, unsigned int *len )
111 {
112  static const WCHAR fmtW[] =
113  {'%','s','_','%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
114  unsigned int buflen = ARRAY_SIZE(fmtW);
115  WCHAR *ret, *p;
116 
117  buflen += strlenW( arch );
118  buflen += strlenW( name );
119  buflen += strlenW( token );
120  buflen += strlenW( version );
121  if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
122  *len = sprintfW( ret, fmtW, arch, name, token, version );
123  for (p = ret; *p; p++) *p = tolowerW( *p );
124  return ret;
125 }
126 
127 static WCHAR *build_manifest_path( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
128  const WCHAR *version )
129 {
130  static const WCHAR fmtW[] =
131  {'%','s','m','a','n','i','f','e','s','t','s','\\','%','s','.','m','a','n','i','f','e','s','t',0};
132  WCHAR *path = NULL, *ret, sxsdir[MAX_PATH];
133  unsigned int len;
134 
135  if (!(path = build_assembly_name( arch, name, token, version, &len ))) return NULL;
136  len += ARRAY_SIZE(fmtW);
137  len += build_sxs_path( sxsdir );
138  if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
139  {
140  HeapFree( GetProcessHeap(), 0, path );
141  return NULL;
142  }
143  sprintfW( ret, fmtW, sxsdir, path );
144  HeapFree( GetProcessHeap(), 0, path );
145  return ret;
146 }
147 
148 static WCHAR *build_policy_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
149  unsigned int *len )
150 {
151  static const WCHAR fmtW[] =
152  {'%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
153  unsigned int buflen = ARRAY_SIZE(fmtW);
154  WCHAR *ret, *p;
155 
156  buflen += strlenW( arch );
157  buflen += strlenW( name );
158  buflen += strlenW( token );
159  if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
160  *len = sprintfW( ret, fmtW, arch, name, token );
161  for (p = ret; *p; p++) *p = tolowerW( *p );
162  return 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 += strlenW( version );
177  if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
178  {
179  HeapFree( GetProcessHeap(), 0, path );
180  return NULL;
181  }
182  sprintfW( 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 (!strcmpW( type, win32W )) path = build_manifest_path( arch, name, token, version );
239  else if (!strcmpW( 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 = strrchrW( path, '\\' ))) *p = 0;
257  len = strlenW( path ) + 1;
258  if (info->pszCurrentAssemblyPathBuf)
259  {
260  if (info->cchBuf < len)
261  {
262  info->cchBuf = len;
264  }
265  else strcpyW( 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 || (strcmpW( a->type, win32W ) && strcmpW( 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 (!strcmpW( 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 += strlenW( 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  strcpyW( ret, sxsdir );
513  strcatW( ret, policiesW );
515  strcatW( ret, name );
517  strcatW( ret, backslashW );
518  strcatW( ret, version );
519  strcatW( 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 = strrchrW( manifest, '\\' );
553  if (!p) p = strrchrW( manifest, '/' );
554  if (!p) return strdupW( manifest );
555 
556  len = p - manifest + 1;
557  if (!(src = HeapAlloc( GetProcessHeap(), 0, (len + strlenW( file->name ) + 1) * sizeof(WCHAR) )))
558  return NULL;
559 
560  memcpy( src, manifest, len * sizeof(WCHAR) );
561  strcpyW( 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  strcpyW( ret, sxsdir );
583  strcatW( ret, manifestsW );
584  strcatW( ret, fullname );
585  strcatW( 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 + strlenW( file->name );
643  if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) )))
644  {
645  HeapFree( GetProcessHeap(), 0, src );
646  goto done;
647  }
648  strcpyW( dst, sxsdir );
649  strcatW( dst, name );
651 
652  strcatW( dst, backslashW );
653  strcatW( dst, file->name );
654  for (p = dst; *p; p++) *p = tolowerW( *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 
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  strcpyW( dirname, sxsdir );
724  strcpyW( dirname + len_sxsdir, name );
725 
727  {
728  len = len_sxsdir + len_name + 1 + strlenW( file->name );
729  if (!(filename = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) goto done;
732  strcatW( 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 = strrchrW( 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:46
char * name
Definition: wpp.c:36
disp
Definition: i386-dis.c:3181
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
#define REFIID
Definition: guiddef.h:113
#define CloseHandle
Definition: compat.h:398
#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:183
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#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:109
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:100
static const WCHAR win32_policyW[]
Definition: cache.c:43
static void cache_unlock(struct cache *cache)
Definition: cache.c:192
__cdecl __MINGW_NOTHROW char * dirname(char *)
static const WCHAR typeW[]
Definition: name.c:49
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:1934
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:571
const char * filename
Definition: ioapi.h:135
BSTR name
Definition: cache.c:321
static struct cache * impl_from_IAssemblyCache(IAssemblyCache *iface)
Definition: cache.c:53
short VARIANT_BOOL
Definition: compat.h:1931
Definition: send.c:47
static int init
Definition: wintirpc.c:33
static const WCHAR backslashW[]
Definition: cache.c:44
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:127
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:2704
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:64
HANDLE lock
Definition: cache.c:50
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
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:39
#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:395
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:58
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
static const WCHAR win32W[]
Definition: cache.c:42
WINE_UNICODE_INLINE WCHAR tolowerW(WCHAR ch)
Definition: unicode.h:135
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT WINAPI CreateAssemblyNameObject(IAssemblyName **ppAssemblyNameObj, LPCWSTR szAssemblyName, DWORD dwFlags, LPVOID pvReserved)
Definition: asmname.c:795
Definition: cookie.c:170
#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:564
LONG refs
Definition: cache.c:49
int ret
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:651
__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:48
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
WINE_UNICODE_INLINE WCHAR * strrchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:254
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:3234
__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
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
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
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1991
#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
Definition: services.c:325
GLenum GLenum dst
Definition: glext.h:6340
#define sprintfW
Definition: unicode.h:58
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
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:522
#define list
Definition: rosglue.h:35
BSTR token
Definition: cache.c:330
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
#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:148
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1897
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
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
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:48
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:50
static void free_assembly(struct assembly *assembly)
Definition: cache.c:334
#define HeapFree(x, y, z)
Definition: compat.h:394
static ULONG WINAPI cache_Release(IAssemblyCache *iface)
Definition: cache.c:86
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
static ULONG WINAPI cache_AddRef(IAssemblyCache *iface)
Definition: cache.c:80
#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