ReactOS  0.4.14-dev-49-gfb4591c
assembly.c
Go to the documentation of this file.
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
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 
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winreg.h"
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
30 #include "msipriv.h"
31 
33 
34 static HRESULT (WINAPI *pCreateAssemblyCacheNet10)( IAssemblyCache **, DWORD );
35 static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD );
36 static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD );
37 static HRESULT (WINAPI *pCreateAssemblyCacheNet40)( IAssemblyCache **, DWORD );
38 static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD );
39 static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * );
40 static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * );
41 static HRESULT (WINAPI *pCreateAssemblyNameObject)( IAssemblyName **, LPCWSTR, DWORD, LPVOID );
42 static HRESULT (WINAPI *pCreateAssemblyEnum)( IAssemblyEnum **, IUnknown *, IAssemblyName *, DWORD, LPVOID );
43 
45 
47 {
48  static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
49  static const WCHAR szMscoree[] = {'\\','m','s','c','o','r','e','e','.','d','l','l',0};
50  static const WCHAR szSxs[] = {'s','x','s','.','d','l','l',0};
51  static const WCHAR szVersion10[] = {'v','1','.','0','.','3','7','0','5',0};
52  static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0};
53  static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0};
54  static const WCHAR szVersion40[] = {'v','4','.','0','.','3','0','3','1','9',0};
57 
58  if (!hsxs && !(hsxs = LoadLibraryW( szSxs ))) return FALSE;
59  if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" )))
60  {
61  FreeLibrary( hsxs );
62  hsxs = NULL;
63  return FALSE;
64  }
65  strcpyW( path + len, szMscoree );
66  if (hmscoree || !(hmscoree = LoadLibraryW( path ))) return TRUE;
67  pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ); /* missing from v1.0.3705 */
68  if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" )))
69  {
71  hmscoree = NULL;
72  return TRUE;
73  }
74  if (!pLoadLibraryShim( szFusion, szVersion10, NULL, &hfusion10 ))
75  pCreateAssemblyCacheNet10 = (void *)GetProcAddress( hfusion10, "CreateAssemblyCache" );
76 
77  if (!pLoadLibraryShim( szFusion, szVersion11, NULL, &hfusion11 ))
78  pCreateAssemblyCacheNet11 = (void *)GetProcAddress( hfusion11, "CreateAssemblyCache" );
79 
80  if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 ))
81  pCreateAssemblyCacheNet20 = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" );
82 
83  if (!pLoadLibraryShim( szFusion, szVersion40, NULL, &hfusion40 ))
84  {
85  pCreateAssemblyCacheNet40 = (void *)GetProcAddress( hfusion40, "CreateAssemblyCache" );
86  pCreateAssemblyNameObject = (void *)GetProcAddress( hfusion40, "CreateAssemblyNameObject" );
87  pCreateAssemblyEnum = (void *)GetProcAddress( hfusion40, "CreateAssemblyEnum" );
88  }
89  return TRUE;
90 }
91 
93 {
94  if (!init_function_pointers()) return FALSE;
95  if (pCreateAssemblyCacheSxs( &package->cache_sxs, 0 ) != S_OK) return FALSE;
96  if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet10( &package->cache_net[CLR_VERSION_V10], 0 );
97  if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 );
98  if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 );
99  if (pCreateAssemblyCacheNet40) pCreateAssemblyCacheNet40( &package->cache_net[CLR_VERSION_V40], 0 );
100  return TRUE;
101 }
102 
104 {
105  UINT i;
106 
107  if (package->cache_sxs)
108  {
109  IAssemblyCache_Release( package->cache_sxs );
110  package->cache_sxs = NULL;
111  }
112  for (i = 0; i < CLR_VERSION_MAX; i++)
113  {
114  if (package->cache_net[i])
115  {
116  IAssemblyCache_Release( package->cache_net[i] );
117  package->cache_net[i] = NULL;
118  }
119  }
120  pCreateAssemblyCacheNet10 = NULL;
121  pCreateAssemblyCacheNet11 = NULL;
122  pCreateAssemblyCacheNet20 = NULL;
123  pCreateAssemblyCacheNet40 = NULL;
129  FreeLibrary( hsxs );
130  hfusion10 = NULL;
131  hfusion11 = NULL;
132  hfusion20 = NULL;
133  hfusion40 = NULL;
134  hmscoree = NULL;
135  hsxs = NULL;
136 }
137 
138 static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp )
139 {
140  static const WCHAR query[] = {
141  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
142  '`','M','s','i','A','s','s','e','m','b','l','y','`',' ',
143  'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
144  ' ','=',' ','\'','%','s','\'',0};
145  MSIQUERY *view;
146  MSIRECORD *rec;
147  UINT r;
148 
149  r = MSI_OpenQuery( package->db, &view, query, comp );
150  if (r != ERROR_SUCCESS)
151  return NULL;
152 
153  r = MSI_ViewExecute( view, NULL );
154  if (r != ERROR_SUCCESS)
155  {
156  msiobj_release( &view->hdr );
157  return NULL;
158  }
159  r = MSI_ViewFetch( view, &rec );
160  if (r != ERROR_SUCCESS)
161  {
162  msiobj_release( &view->hdr );
163  return NULL;
164  }
165  if (!MSI_RecordGetString( rec, 4 ))
166  TRACE("component is a global assembly\n");
167 
168  msiobj_release( &view->hdr );
169  return rec;
170 }
171 
173 {
177 };
178 
180 {
181  static const WCHAR fmtW[] = {'%','s','=','"','%','s','"',0};
182  static const WCHAR nameW[] = {'n','a','m','e',0};
183  struct assembly_name *name = param;
184  const WCHAR *attr = MSI_RecordGetString( rec, 2 );
185  const WCHAR *value = MSI_RecordGetString( rec, 3 );
186  int len = strlenW( fmtW ) + strlenW( attr ) + strlenW( value );
187 
188  if (!(name->attrs[name->index] = msi_alloc( len * sizeof(WCHAR) )))
189  return ERROR_OUTOFMEMORY;
190 
191  if (!strcmpiW( attr, nameW )) strcpyW( name->attrs[name->index++], value );
192  else sprintfW( name->attrs[name->index++], fmtW, attr, value );
193  return ERROR_SUCCESS;
194 }
195 
197 {
198  static const WCHAR commaW[] = {',',0};
199  static const WCHAR queryW[] = {
200  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
201  '`','M','s','i','A','s','s','e','m','b','l','y','N','a','m','e','`',' ',
202  'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
203  ' ','=',' ','\'','%','s','\'',0};
204  struct assembly_name name;
205  WCHAR *display_name = NULL;
206  MSIQUERY *view;
207  UINT i, r;
208  int len;
209 
210  r = MSI_OpenQuery( db, &view, queryW, comp );
211  if (r != ERROR_SUCCESS)
212  return NULL;
213 
214  name.count = 0;
215  name.index = 0;
216  name.attrs = NULL;
217  MSI_IterateRecords( view, &name.count, NULL, NULL );
218  if (!name.count) goto done;
219 
220  name.attrs = msi_alloc( name.count * sizeof(WCHAR *) );
221  if (!name.attrs) goto done;
222 
224 
225  len = 0;
226  for (i = 0; i < name.count; i++) len += strlenW( name.attrs[i] ) + 1;
227 
228  display_name = msi_alloc( (len + 1) * sizeof(WCHAR) );
229  if (display_name)
230  {
231  display_name[0] = 0;
232  for (i = 0; i < name.count; i++)
233  {
234  strcatW( display_name, name.attrs[i] );
235  if (i < name.count - 1) strcatW( display_name, commaW );
236  }
237  }
238 
239 done:
240  msiobj_release( &view->hdr );
241  if (name.attrs)
242  {
243  for (i = 0; i < name.count; i++) msi_free( name.attrs[i] );
244  msi_free( name.attrs );
245  }
246  return display_name;
247 }
248 
249 static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_name )
250 {
251  HRESULT hr;
253 
254  if (!cache) return FALSE;
255 
256  memset( &info, 0, sizeof(info) );
257  info.cbAssemblyInfo = sizeof(info);
258  hr = IAssemblyCache_QueryAssemblyInfo( cache, 0, display_name, &info );
259  if (hr == S_OK /* sxs version */ || hr == E_NOT_SUFFICIENT_BUFFER)
260  {
261  return (info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED);
262  }
263  TRACE("QueryAssemblyInfo returned 0x%08x\n", hr);
264  return FALSE;
265 }
266 
267 WCHAR *msi_get_assembly_path( MSIPACKAGE *package, const WCHAR *displayname )
268 {
269  HRESULT hr;
272 
273  if (!cache) return NULL;
274 
275  memset( &info, 0, sizeof(info) );
276  info.cbAssemblyInfo = sizeof(info);
277  hr = IAssemblyCache_QueryAssemblyInfo( cache, 0, displayname, &info );
278  if (hr != E_NOT_SUFFICIENT_BUFFER) return NULL;
279 
280  if (!(info.pszCurrentAssemblyPathBuf = msi_alloc( info.cchBuf * sizeof(WCHAR) ))) return NULL;
281 
282  hr = IAssemblyCache_QueryAssemblyInfo( cache, 0, displayname, &info );
283  if (FAILED( hr ))
284  {
285  msi_free( info.pszCurrentAssemblyPathBuf );
286  return NULL;
287  }
288  TRACE("returning %s\n", debugstr_w(info.pszCurrentAssemblyPathBuf));
289  return info.pszCurrentAssemblyPathBuf;
290 }
291 
292 IAssemblyEnum *msi_create_assembly_enum( MSIPACKAGE *package, const WCHAR *displayname )
293 {
294  HRESULT hr;
297  WCHAR *str;
298  UINT len = 0;
299 
300  if (!pCreateAssemblyNameObject || !pCreateAssemblyEnum) return NULL;
301 
302  hr = pCreateAssemblyNameObject( &name, displayname, CANOF_PARSE_DISPLAY_NAME, NULL );
303  if (FAILED( hr )) return NULL;
304 
305  hr = IAssemblyName_GetName( name, &len, NULL );
306  if (hr != E_NOT_SUFFICIENT_BUFFER || !(str = msi_alloc( len * sizeof(WCHAR) )))
307  {
308  IAssemblyName_Release( name );
309  return NULL;
310  }
311 
312  hr = IAssemblyName_GetName( name, &len, str );
313  IAssemblyName_Release( name );
314  if (FAILED( hr ))
315  {
316  msi_free( str );
317  return NULL;
318  }
319 
320  hr = pCreateAssemblyNameObject( &name, str, 0, NULL );
321  msi_free( str );
322  if (FAILED( hr )) return NULL;
323 
324  hr = pCreateAssemblyEnum( &ret, NULL, name, ASM_CACHE_GAC, NULL );
325  IAssemblyName_Release( name );
326  if (FAILED( hr )) return NULL;
327 
328  return ret;
329 }
330 
331 static const WCHAR clr_version_v10[] = {'v','1','.','0','.','3','7','0','5',0};
332 static const WCHAR clr_version_v11[] = {'v','1','.','1','.','4','3','2','2',0};
333 static const WCHAR clr_version_v20[] = {'v','2','.','0','.','5','0','7','2','7',0};
334 static const WCHAR clr_version_v40[] = {'v','4','.','0','.','3','0','3','1','9',0};
335 static const WCHAR clr_version_unknown[] = {'u','n','k','n','o','w','n',0};
336 
337 static const WCHAR *clr_version[] =
338 {
343 };
344 
346 {
347  if (version >= sizeof(clr_version)/sizeof(clr_version[0])) return clr_version_unknown;
348  return clr_version[version];
349 }
350 
351 /* assembly caches must be initialized */
353 {
354  MSIRECORD *rec;
355  MSIASSEMBLY *a;
356 
357  if (!(rec = get_assembly_record( package, comp->Component ))) return NULL;
358  if (!(a = msi_alloc_zero( sizeof(MSIASSEMBLY) )))
359  {
360  msiobj_release( &rec->hdr );
361  return NULL;
362  }
363  a->feature = strdupW( MSI_RecordGetString( rec, 2 ) );
364  TRACE("feature %s\n", debugstr_w(a->feature));
365 
366  a->manifest = strdupW( MSI_RecordGetString( rec, 3 ) );
367  TRACE("manifest %s\n", debugstr_w(a->manifest));
368 
369  a->application = strdupW( MSI_RecordGetString( rec, 4 ) );
370  TRACE("application %s\n", debugstr_w(a->application));
371 
372  a->attributes = MSI_RecordGetInteger( rec, 5 );
373  TRACE("attributes %u\n", a->attributes);
374 
375  if (!(a->display_name = get_assembly_display_name( package->db, comp->Component, a )))
376  {
377  WARN("can't get display name\n");
378  msiobj_release( &rec->hdr );
379  msi_free( a->feature );
380  msi_free( a->manifest );
381  msi_free( a->application );
382  msi_free( a );
383  return NULL;
384  }
385  TRACE("display name %s\n", debugstr_w(a->display_name));
386 
387  if (a->application)
388  {
389  /* We can't check the manifest here because the target path may still change.
390  So we assume that the assembly is not installed and lean on the InstallFiles
391  action to determine which files need to be installed.
392  */
393  a->installed = FALSE;
394  }
395  else
396  {
397  if (a->attributes == msidbAssemblyAttributesWin32)
398  a->installed = is_assembly_installed( package->cache_sxs, a->display_name );
399  else
400  {
401  UINT i;
402  for (i = 0; i < CLR_VERSION_MAX; i++)
403  {
404  a->clr_version[i] = is_assembly_installed( package->cache_net[i], a->display_name );
405  if (a->clr_version[i])
406  {
407  TRACE("runtime version %s\n", debugstr_w(get_clr_version_str( i )));
408  a->installed = TRUE;
409  break;
410  }
411  }
412  }
413  }
414  TRACE("assembly is %s\n", a->installed ? "installed" : "not installed");
415  msiobj_release( &rec->hdr );
416  return a;
417 }
418 
420 {
421  DWORD len;
422  HRESULT hr;
424  WCHAR *strW;
425 
426  if (!pGetFileVersion) return CLR_VERSION_V10;
427 
428  hr = pGetFileVersion( filename, NULL, 0, &len );
430  if ((strW = msi_alloc( len * sizeof(WCHAR) )))
431  {
432  hr = pGetFileVersion( filename, strW, len, &len );
433  if (hr == S_OK)
434  {
435  UINT i;
436  for (i = 0; i < CLR_VERSION_MAX; i++)
437  if (!strcmpW( strW, clr_version[i] )) version = i;
438  }
439  msi_free( strW );
440  }
441  return version;
442 }
443 
445 {
446  HRESULT hr;
447  const WCHAR *manifest;
449  MSIASSEMBLY *assembly = comp->assembly;
451 
452  if (comp->assembly->feature)
453  feature = msi_get_loaded_feature( package, comp->assembly->feature );
454 
455  if (assembly->application)
456  {
457  if (feature) feature->Action = INSTALLSTATE_LOCAL;
458  return ERROR_SUCCESS;
459  }
460  if (assembly->attributes == msidbAssemblyAttributesWin32)
461  {
462  if (!assembly->manifest)
463  {
464  WARN("no manifest\n");
465  return ERROR_FUNCTION_FAILED;
466  }
468  cache = package->cache_sxs;
469  }
470  else
471  {
472  manifest = msi_get_loaded_file( package, comp->KeyPath )->TargetPath;
473  cache = package->cache_net[get_clr_version( manifest )];
474  if (!cache) return ERROR_SUCCESS;
475  }
476  TRACE("installing assembly %s\n", debugstr_w(manifest));
477 
478  hr = IAssemblyCache_InstallAssembly( cache, 0, manifest, NULL );
479  if (hr != S_OK)
480  {
481  ERR("Failed to install assembly %s (0x%08x)\n", debugstr_w(manifest), hr);
482  return ERROR_FUNCTION_FAILED;
483  }
484  if (feature) feature->Action = INSTALLSTATE_LOCAL;
485  assembly->installed = TRUE;
486  return ERROR_SUCCESS;
487 }
488 
490 {
491  HRESULT hr;
493  MSIASSEMBLY *assembly = comp->assembly;
495 
496  if (comp->assembly->feature)
497  feature = msi_get_loaded_feature( package, comp->assembly->feature );
498 
499  if (assembly->application)
500  {
501  if (feature) feature->Action = INSTALLSTATE_ABSENT;
502  return ERROR_SUCCESS;
503  }
504  TRACE("removing %s\n", debugstr_w(assembly->display_name));
505 
506  if (assembly->attributes == msidbAssemblyAttributesWin32)
507  {
508  cache = package->cache_sxs;
509  hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL );
510  if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr);
511  }
512  else
513  {
514  unsigned int i;
515  for (i = 0; i < CLR_VERSION_MAX; i++)
516  {
517  if (!assembly->clr_version[i]) continue;
518  cache = package->cache_net[i];
519  if (cache)
520  {
521  hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL );
522  if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr);
523  }
524  }
525  }
526  if (feature) feature->Action = INSTALLSTATE_ABSENT;
527  assembly->installed = FALSE;
528  return ERROR_SUCCESS;
529 }
530 
532 {
533  UINT i;
534  WCHAR *ret;
535 
536  if (!(ret = msi_alloc( (strlenW( filename ) + 1) * sizeof(WCHAR) )))
537  return NULL;
538 
539  for (i = 0; filename[i]; i++)
540  {
541  if (filename[i] == '\\' || filename[i] == '/') ret[i] = '|';
542  else ret[i] = filename[i];
543  }
544  ret[i] = 0;
545  return ret;
546 }
547 
548 static LONG open_assemblies_key( UINT context, BOOL win32, HKEY *hkey )
549 {
550  static const WCHAR path_win32[] =
551  {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
552  'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0};
553  static const WCHAR path_dotnet[] =
554  {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
555  'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',0};
556  static const WCHAR classes_path_win32[] =
557  {'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0};
558  static const WCHAR classes_path_dotnet[] =
559  {'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',0};
560  HKEY root;
561  const WCHAR *path;
562 
564  {
566  if (win32) path = classes_path_win32;
567  else path = classes_path_dotnet;
568  }
569  else
570  {
572  if (win32) path = path_win32;
573  else path = path_dotnet;
574  }
575  return RegCreateKeyW( root, path, hkey );
576 }
577 
579 {
580  LONG res;
581  HKEY root;
582  WCHAR *path;
583 
585  return ERROR_OUTOFMEMORY;
586 
587  if ((res = open_assemblies_key( context, win32, &root )))
588  {
589  msi_free( path );
590  return res;
591  }
592  res = RegCreateKeyW( root, path, hkey );
593  RegCloseKey( root );
594  msi_free( path );
595  return res;
596 }
597 
599 {
600  LONG res;
601  HKEY root;
602  WCHAR *path;
603 
605  return ERROR_OUTOFMEMORY;
606 
607  if ((res = open_assemblies_key( context, win32, &root )))
608  {
609  msi_free( path );
610  return res;
611  }
612  res = RegDeleteKeyW( root, path );
613  RegCloseKey( root );
614  msi_free( path );
615  return res;
616 }
617 
619 {
620  static const WCHAR path_win32[] =
621  {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
622  'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',
623  'G','l','o','b','a','l',0};
624  static const WCHAR path_dotnet[] =
625  {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
626  'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',
627  'G','l','o','b','a','l',0};
628  static const WCHAR classes_path_win32[] =
629  {'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',
630  'G','l','o','b','a','l',0};
631  static const WCHAR classes_path_dotnet[] =
632  {'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\','G','l','o','b','a','l',0};
633  HKEY root;
634  const WCHAR *path;
635 
637  {
639  if (win32) path = classes_path_win32;
640  else path = classes_path_dotnet;
641  }
642  else
643  {
645  if (win32) path = path_win32;
646  else path = path_dotnet;
647  }
648  return RegCreateKeyW( root, path, hkey );
649 }
650 
652 {
653  MSICOMPONENT *comp;
654 
656  {
657  LONG res;
658  HKEY hkey;
659  GUID guid;
660  DWORD size;
661  WCHAR buffer[43];
662  MSIRECORD *uirow;
663  MSIASSEMBLY *assembly = comp->assembly;
664  BOOL win32;
665 
666  if (!assembly || !comp->ComponentId) continue;
667 
668  comp->Action = msi_get_component_action( package, comp );
669  if (comp->Action != INSTALLSTATE_LOCAL)
670  {
671  TRACE("component not scheduled for installation %s\n", debugstr_w(comp->Component));
672  continue;
673  }
674  TRACE("publishing %s\n", debugstr_w(comp->Component));
675 
676  CLSIDFromString( package->ProductCode, &guid );
678  buffer[20] = '>';
679  CLSIDFromString( comp->ComponentId, &guid );
680  encode_base85_guid( &guid, buffer + 21 );
681  buffer[42] = 0;
682 
683  win32 = assembly->attributes & msidbAssemblyAttributesWin32;
684  if (assembly->application)
685  {
686  MSIFILE *file = msi_get_loaded_file( package, assembly->application );
687  if ((res = open_local_assembly_key( package->Context, win32, file->TargetPath, &hkey )))
688  {
689  WARN("failed to open local assembly key %d\n", res);
690  return ERROR_FUNCTION_FAILED;
691  }
692  }
693  else
694  {
695  if ((res = open_global_assembly_key( package->Context, win32, &hkey )))
696  {
697  WARN("failed to open global assembly key %d\n", res);
698  return ERROR_FUNCTION_FAILED;
699  }
700  }
701  size = sizeof(buffer);
702  if ((res = RegSetValueExW( hkey, assembly->display_name, 0, REG_MULTI_SZ, (const BYTE *)buffer, size )))
703  {
704  WARN("failed to set assembly value %d\n", res);
705  }
706  RegCloseKey( hkey );
707 
708  uirow = MSI_CreateRecord( 2 );
709  MSI_RecordSetStringW( uirow, 2, assembly->display_name );
711  msiobj_release( &uirow->hdr );
712  }
713  return ERROR_SUCCESS;
714 }
715 
717 {
718  MSICOMPONENT *comp;
719 
721  {
722  LONG res;
723  MSIRECORD *uirow;
724  MSIASSEMBLY *assembly = comp->assembly;
725  BOOL win32;
726 
727  if (!assembly || !comp->ComponentId) continue;
728 
729  comp->Action = msi_get_component_action( package, comp );
730  if (comp->Action != INSTALLSTATE_ABSENT)
731  {
732  TRACE("component not scheduled for removal %s\n", debugstr_w(comp->Component));
733  continue;
734  }
735  TRACE("unpublishing %s\n", debugstr_w(comp->Component));
736 
737  win32 = assembly->attributes & msidbAssemblyAttributesWin32;
738  if (assembly->application)
739  {
740  MSIFILE *file = msi_get_loaded_file( package, assembly->application );
741  if ((res = delete_local_assembly_key( package->Context, win32, file->TargetPath )))
742  WARN("failed to delete local assembly key %d\n", res);
743  }
744  else
745  {
746  HKEY hkey;
747  if ((res = open_global_assembly_key( package->Context, win32, &hkey )))
748  WARN("failed to delete global assembly key %d\n", res);
749  else
750  {
751  if ((res = RegDeleteValueW( hkey, assembly->display_name )))
752  WARN("failed to delete global assembly value %d\n", res);
753  RegCloseKey( hkey );
754  }
755  }
756 
757  uirow = MSI_CreateRecord( 2 );
758  MSI_RecordSetStringW( uirow, 2, assembly->display_name );
760  msiobj_release( &uirow->hdr );
761  }
762  return ERROR_SUCCESS;
763 }
static const WCHAR clr_version_v40[]
Definition: assembly.c:334
static LPVOID
Definition: assembly.c:39
LPWSTR ProductCode
Definition: msipriv.h:426
Definition: cache.c:46
INTERNETFEATURELIST feature
Definition: misc.c:1689
#define TRUE
Definition: types.h:120
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:649
IAssemblyCache * cache_net[CLR_VERSION_MAX]
Definition: msipriv.h:406
clr_version
Definition: msipriv.h:365
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
MSIFEATURE * msi_get_loaded_feature(MSIPACKAGE *package, const WCHAR *Feature)
Definition: action.c:663
static HMODULE hfusion11
Definition: assembly.c:44
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ASSEMBLYINFO_FLAG_INSTALLED
Definition: cache.c:197
HRESULT hr
Definition: shlfolder.c:183
static const WCHAR * get_clr_version_str(enum clr_version version)
Definition: assembly.c:345
static HRESULT(WINAPI *pCreateAssemblyCacheNet10)(IAssemblyCache **
MSIASSEMBLY * assembly
Definition: msipriv.h:517
Definition: http.c:6587
static WCHAR * get_assembly_display_name(MSIDATABASE *db, const WCHAR *comp, MSIASSEMBLY *assembly)
Definition: assembly.c:196
GLsizei const GLchar ** path
Definition: glext.h:7234
static HMODULE hmscoree
Definition: assembly.c:44
MSIOBJECTHDR hdr
Definition: msipriv.h:141
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define HKEY_CURRENT_USER
Definition: winreg.h:11
struct _root root
struct file_info manifest
Definition: actctx.c:447
#define WARN(fmt,...)
Definition: debug.h:111
MSIASSEMBLY * msi_load_assembly(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: assembly.c:352
UINT MSI_ViewExecute(MSIQUERY *, MSIRECORD *) DECLSPEC_HIDDEN
Definition: msiquery.c:443
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
GLuint buffer
Definition: glext.h:5915
WCHAR * msi_get_assembly_path(MSIPACKAGE *package, const WCHAR *displayname)
Definition: assembly.c:267
WINE_DEFAULT_DEBUG_CHANNEL(msi)
INSTALLSTATE Action
Definition: msipriv.h:510
INSTALLSTATE msi_get_component_action(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: action.c:755
LPWSTR KeyPath
Definition: msipriv.h:507
const char * filename
Definition: ioapi.h:135
static DWORD
Definition: assembly.c:34
static const WCHAR clr_version_v10[]
Definition: assembly.c:331
static BOOL init_function_pointers(void)
Definition: assembly.c:46
static HMODULE hfusion20
Definition: assembly.c:44
static const WCHAR clr_version_v20[]
Definition: assembly.c:333
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1210
struct _test_info info[]
Definition: SetCursorPos.c:19
UINT MSI_OpenQuery(MSIDATABASE *, MSIQUERY **, LPCWSTR,...) DECLSPEC_HIDDEN
Definition: msiquery.c:143
static LPCWSTR
Definition: assembly.c:39
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
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 GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const GUID * guid
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
UINT MSI_ViewFetch(MSIQUERY *, MSIRECORD **) DECLSPEC_HIDDEN
Definition: msiquery.c:364
static LONG open_local_assembly_key(UINT context, BOOL win32, const WCHAR *filename, HKEY *hkey)
Definition: assembly.c:578
unsigned int BOOL
Definition: ntddk_ex.h:94
WCHAR strW[12]
Definition: clipboard.c:2029
long LONG
Definition: pedump.c:60
#define a
Definition: ke_i.h:78
#define REG_MULTI_SZ
Definition: nt_native.h:1501
static MSIRECORD * get_assembly_record(MSIPACKAGE *package, const WCHAR *comp)
Definition: assembly.c:138
#define debugstr_w
Definition: kernel32.h:32
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *) DECLSPEC_HIDDEN
Definition: package.c:1946
WCHAR ** attrs
Definition: assembly.c:176
void msi_destroy_assembly_caches(MSIPACKAGE *package)
Definition: assembly.c:103
const WCHAR * str
IAssemblyEnum * msi_create_assembly_enum(MSIPACKAGE *package, const WCHAR *displayname)
Definition: assembly.c:292
#define LoadLibraryW(x)
Definition: compat.h:404
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:64
static BOOL is_assembly_installed(IAssemblyCache *cache, const WCHAR *display_name)
Definition: assembly.c:249
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:482
LPWSTR feature
Definition: msipriv.h:489
static const WCHAR nameW[]
Definition: main.c:46
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:674
static enum clr_version get_clr_version(const WCHAR *filename)
Definition: assembly.c:419
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:405
GLsizeiptr size
Definition: glext.h:5919
BOOL msi_init_assembly_caches(MSIPACKAGE *package)
Definition: assembly.c:92
static HMODULE hfusion10
Definition: assembly.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
IAssemblyCache * cache_sxs
Definition: msipriv.h:407
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
static LONG open_assemblies_key(UINT context, BOOL win32, HKEY *hkey)
Definition: assembly.c:548
unsigned long DWORD
Definition: ntddk_ex.h:95
MSIDATABASE * db
Definition: msipriv.h:386
Definition: cookie.c:170
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:242
LPWSTR Component
Definition: msipriv.h:502
static UINT get_assembly_name_attribute(MSIRECORD *rec, LPVOID param)
Definition: assembly.c:179
struct list components
Definition: msipriv.h:392
static HMODULE hfusion40
Definition: assembly.c:44
int ret
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:79
UINT msi_install_assembly(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: assembly.c:444
static IOleCache * cache
Definition: ole2.c:75
uint32_t entry
Definition: isohybrid.c:63
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1199
UINT msi_uninstall_assembly(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: assembly.c:489
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:2345
static LONG delete_local_assembly_key(UINT context, BOOL win32, const WCHAR *filename)
Definition: assembly.c:598
static HMODULE hsxs
Definition: assembly.c:44
#define strcmpiW(s1, s2)
Definition: unicode.h:39
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:245
UINT ACTION_MsiPublishAssemblies(MSIPACKAGE *package)
Definition: assembly.c:651
#define ERR(fmt,...)
Definition: debug.h:109
LPWSTR ComponentId
Definition: msipriv.h:503
static HMODULE *static LPWSTR
Definition: assembly.c:40
#define S_OK
Definition: intsafe.h:59
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
Definition: services.c:325
#define sprintfW
Definition: unicode.h:58
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
static const WCHAR clr_version_unknown[]
Definition: assembly.c:335
unsigned int UINT
Definition: ndis.h:50
static LONG open_global_assembly_key(UINT context, BOOL win32, HKEY *hkey)
Definition: assembly.c:618
UINT Context
Definition: msipriv.h:437
static BOOL msi_free(void *mem)
Definition: msipriv.h:1227
static const WCHAR clr_version_v11[]
Definition: assembly.c:332
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
static WCHAR * build_local_assembly_path(const WCHAR *filename)
Definition: assembly.c:531
GLuint res
Definition: glext.h:9613
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1204
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2247
static IOleDocumentView * view
Definition: activex.c:1749
#define GetProcAddress(x, y)
Definition: compat.h:410
static const CHAR manifest[]
Definition: v6util.h:39
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID) DECLSPEC_HIDDEN
Definition: msiquery.c:168
#define memset(x, y, z)
Definition: compat.h:39
LPWSTR TargetPath
Definition: msipriv.h:594
static LPWSTR strdupW(LPCWSTR src)
Definition: assembly.c:67
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
BOOL encode_base85_guid(GUID *, LPWSTR) DECLSPEC_HIDDEN
Definition: registry.c:316
UINT ACTION_MsiUnpublishAssemblies(MSIPACKAGE *package)
Definition: assembly.c:716
Definition: fci.c:126
GLuint const GLchar * name
Definition: glext.h:6031