ReactOS  0.4.13-dev-73-gcfe54aa
classes.c
Go to the documentation of this file.
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2005 Aric Stewart 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 /* Actions handled in this module:
22  *
23  * RegisterClassInfo
24  * RegisterProgIdInfo
25  * RegisterExtensionInfo
26  * RegisterMIMEInfo
27  * UnregisterClassInfo
28  * UnregisterProgIdInfo
29  * UnregisterExtensionInfo
30  * UnregisterMIMEInfo
31  */
32 
33 #include <stdarg.h>
34 
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winerror.h"
38 #include "winreg.h"
39 #include "wine/debug.h"
40 #include "msipriv.h"
41 #include "winuser.h"
42 #include "wine/unicode.h"
43 
45 
47 {
49  MSIAPPID *appid;
50 
51  /* fill in the data */
52 
53  appid = msi_alloc_zero( sizeof(MSIAPPID) );
54  if (!appid)
55  return NULL;
56 
57  appid->AppID = msi_dup_record_field( row, 1 );
58  TRACE("loading appid %s\n", debugstr_w( appid->AppID ));
59 
61  deformat_string( package, buffer, &appid->RemoteServerName );
62 
63  appid->LocalServer = msi_dup_record_field(row,3);
64  appid->ServiceParameters = msi_dup_record_field(row,4);
65  appid->DllSurrogate = msi_dup_record_field(row,5);
66 
67  appid->ActivateAtStorage = !MSI_RecordIsNull(row,6);
68  appid->RunAsInteractiveUser = !MSI_RecordIsNull(row,7);
69 
70  list_add_tail( &package->appids, &appid->entry );
71 
72  return appid;
73 }
74 
76 {
77  static const WCHAR query[] = {
78  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
79  '`','A','p','p','I','d','`',' ','W','H','E','R','E',' ',
80  '`','A','p','p','I','d','`',' ','=',' ','\'','%','s','\'',0};
81  MSIRECORD *row;
82  MSIAPPID *appid;
83 
84  if (!name)
85  return NULL;
86 
87  /* check for appids already loaded */
89  {
90  if (!strcmpiW( appid->AppID, name ))
91  {
92  TRACE("found appid %s %p\n", debugstr_w(name), appid);
93  return appid;
94  }
95  }
96 
97  row = MSI_QueryGetRecord(package->db, query, name);
98  if (!row)
99  return NULL;
100 
101  appid = load_appid(package, row);
102  msiobj_release(&row->hdr);
103  return appid;
104 }
105 
107 static MSICLASS *load_given_class( MSIPACKAGE *package, LPCWSTR classid );
108 
110 {
111  MSIPROGID *progid;
112  LPCWSTR buffer;
113 
114  /* fill in the data */
115 
116  progid = msi_alloc_zero( sizeof(MSIPROGID) );
117  if (!progid)
118  return NULL;
119 
120  list_add_tail( &package->progids, &progid->entry );
121 
122  progid->ProgID = msi_dup_record_field(row,1);
123  TRACE("loading progid %s\n",debugstr_w(progid->ProgID));
124 
126  progid->Parent = load_given_progid(package,buffer);
127  if (progid->Parent == NULL && buffer)
128  FIXME("Unknown parent ProgID %s\n",debugstr_w(buffer));
129 
131  progid->Class = load_given_class(package,buffer);
132  if (progid->Class == NULL && buffer)
133  FIXME("Unknown class %s\n",debugstr_w(buffer));
134 
135  progid->Description = msi_dup_record_field(row,4);
136 
137  if (!MSI_RecordIsNull(row,6))
138  {
139  INT icon_index = MSI_RecordGetInteger(row,6);
142  static const WCHAR fmt[] = {'%','s',',','%','i',0};
143 
145 
146  progid->IconPath = msi_alloc( (strlenW(FilePath)+10)* sizeof(WCHAR) );
147 
148  sprintfW(progid->IconPath,fmt,FilePath,icon_index);
149 
151  }
152  else
153  {
155  if (buffer)
156  progid->IconPath = msi_build_icon_path(package, buffer);
157  }
158 
159  progid->CurVer = NULL;
160  progid->VersionInd = NULL;
161 
162  /* if we have a parent then we may be that parents CurVer */
163  if (progid->Parent && progid->Parent != progid)
164  {
165  MSIPROGID *parent = progid->Parent;
166 
167  while (parent->Parent && parent->Parent != parent)
168  parent = parent->Parent;
169 
170  /* FIXME: need to determine if we are really the CurVer */
171 
172  progid->CurVer = parent;
173  parent->VersionInd = progid;
174  }
175 
176  return progid;
177 }
178 
180 {
181  static const WCHAR query[] = {
182  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
183  '`','P','r','o','g','I','d','`',' ','W','H','E','R','E',' ',
184  '`','P','r','o','g','I','d','`',' ','=',' ','\'','%','s','\'',0};
185  MSIPROGID *progid;
186  MSIRECORD *row;
187 
188  if (!name)
189  return NULL;
190 
191  /* check for progids already loaded */
193  {
194  if (!strcmpiW( progid->ProgID, name ))
195  {
196  TRACE("found progid %s (%p)\n",debugstr_w(name), progid );
197  return progid;
198  }
199  }
200 
201  row = MSI_QueryGetRecord( package->db, query, name );
202  if (!row)
203  return NULL;
204 
205  progid = load_progid(package, row);
206  msiobj_release(&row->hdr);
207  return progid;
208 }
209 
211 {
212  MSICLASS *cls;
213  DWORD i;
214  LPCWSTR buffer;
215 
216  /* fill in the data */
217 
218  cls = msi_alloc_zero( sizeof(MSICLASS) );
219  if (!cls)
220  return NULL;
221 
222  list_add_tail( &package->classes, &cls->entry );
223 
224  cls->clsid = msi_dup_record_field( row, 1 );
225  TRACE("loading class %s\n",debugstr_w(cls->clsid));
226  cls->Context = msi_dup_record_field( row, 2 );
228  cls->Component = msi_get_loaded_component( package, buffer );
229 
231  cls->ProgID = load_given_progid(package, cls->ProgIDText);
232 
234 
236  if (buffer)
237  cls->AppID = load_given_appid(package, buffer);
238 
240 
241  if (!MSI_RecordIsNull(row,9))
242  {
243 
244  INT icon_index = MSI_RecordGetInteger(row,9);
247  static const WCHAR fmt[] = {'%','s',',','%','i',0};
248 
250 
251  cls->IconPath = msi_alloc( (strlenW(FilePath)+5)* sizeof(WCHAR) );
252 
253  sprintfW(cls->IconPath,fmt,FilePath,icon_index);
254 
256  }
257  else
258  {
260  if (buffer)
261  cls->IconPath = msi_build_icon_path(package, buffer);
262  }
263 
264  if (!MSI_RecordIsNull(row,10))
265  {
266  i = MSI_RecordGetInteger(row,10);
267  if (i != MSI_NULL_INTEGER && i > 0 && i < 4)
268  {
269  static const WCHAR ole2[] = {'o','l','e','2','.','d','l','l',0};
270  static const WCHAR ole32[] = {'o','l','e','3','2','.','d','l','l',0};
271 
272  switch(i)
273  {
274  case 1:
275  cls->DefInprocHandler = strdupW(ole2);
276  break;
277  case 2:
278  cls->DefInprocHandler32 = strdupW(ole32);
279  break;
280  case 3:
281  cls->DefInprocHandler = strdupW(ole2);
282  cls->DefInprocHandler32 = strdupW(ole32);
283  break;
284  }
285  }
286  else
287  {
290  }
291  }
293  deformat_string(package,buffer,&cls->Argument);
294 
296  cls->Feature = msi_get_loaded_feature(package, buffer);
297 
300  return cls;
301 }
302 
303 /*
304  * the Class table has 3 primary keys. Generally it is only
305  * referenced through the first CLSID key. However when loading
306  * all of the classes we need to make sure we do not ignore rows
307  * with other Context and ComponentIndexs
308  */
309 static MSICLASS *load_given_class(MSIPACKAGE *package, LPCWSTR classid)
310 {
311  static const WCHAR query[] = {
312  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
313  '`','C','l','a','s','s','`',' ','W','H','E','R','E',' ',
314  '`','C','L','S','I','D','`',' ','=',' ','\'','%','s','\'',0};
315  MSICLASS *cls;
316  MSIRECORD *row;
317 
318  if (!classid)
319  return NULL;
320 
321  /* check for classes already loaded */
322  LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
323  {
324  if (!strcmpiW( cls->clsid, classid ))
325  {
326  TRACE("found class %s (%p)\n",debugstr_w(classid), cls);
327  return cls;
328  }
329  }
330 
331  row = MSI_QueryGetRecord(package->db, query, classid);
332  if (!row)
333  return NULL;
334 
335  cls = load_class(package, row);
336  msiobj_release(&row->hdr);
337  return cls;
338 }
339 
340 static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR extension );
341 
342 static MSIMIME *load_mime( MSIPACKAGE* package, MSIRECORD *row )
343 {
344  LPCWSTR extension;
345  MSIMIME *mt;
346 
347  /* fill in the data */
348 
349  mt = msi_alloc_zero( sizeof(MSIMIME) );
350  if (!mt)
351  return mt;
352 
353  mt->ContentType = msi_dup_record_field( row, 1 );
354  TRACE("loading mime %s\n", debugstr_w(mt->ContentType));
355 
356  extension = MSI_RecordGetString( row, 2 );
357  mt->Extension = load_given_extension( package, extension );
358  mt->suffix = strdupW( extension );
359 
360  mt->clsid = msi_dup_record_field( row, 3 );
361  mt->Class = load_given_class( package, mt->clsid );
362 
363  list_add_tail( &package->mimes, &mt->entry );
364 
365  return mt;
366 }
367 
369 {
370  static const WCHAR query[] = {
371  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
372  '`','M','I','M','E','`',' ','W','H','E','R','E',' ',
373  '`','C','o','n','t','e','n','t','T','y','p','e','`',' ','=',' ','\'','%','s','\'',0};
374  MSIRECORD *row;
375  MSIMIME *mt;
376 
377  if (!mime)
378  return NULL;
379 
380  /* check for mime already loaded */
381  LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry )
382  {
383  if (!strcmpiW( mt->ContentType, mime ))
384  {
385  TRACE("found mime %s (%p)\n",debugstr_w(mime), mt);
386  return mt;
387  }
388  }
389 
390  row = MSI_QueryGetRecord(package->db, query, mime);
391  if (!row)
392  return NULL;
393 
394  mt = load_mime(package, row);
395  msiobj_release(&row->hdr);
396  return mt;
397 }
398 
400 {
401  MSIEXTENSION *ext;
402  LPCWSTR buffer;
403 
404  /* fill in the data */
405 
406  ext = msi_alloc_zero( sizeof(MSIEXTENSION) );
407  if (!ext)
408  return NULL;
409 
410  list_init( &ext->verbs );
411 
412  list_add_tail( &package->extensions, &ext->entry );
413 
414  ext->Extension = msi_dup_record_field( row, 1 );
415  TRACE("loading extension %s\n", debugstr_w(ext->Extension));
416 
418  ext->Component = msi_get_loaded_component( package, buffer );
419 
420  ext->ProgIDText = msi_dup_record_field( row, 3 );
421  ext->ProgID = load_given_progid( package, ext->ProgIDText );
422 
424  ext->Mime = load_given_mime( package, buffer );
425 
427  ext->Feature = msi_get_loaded_feature( package, buffer );
428  ext->action = INSTALLSTATE_UNKNOWN;
429  return ext;
430 }
431 
432 /*
433  * While the extension table has 2 primary keys, this function is only looking
434  * at the Extension key which is what is referenced as a foreign key
435  */
437 {
438  static const WCHAR query[] = {
439  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
440  '`','E','x','t','e','n','s','i','o','n','`',' ','W','H','E','R','E',' ',
441  '`','E','x','t','e','n','s','i','o','n','`',' ','=',' ','\'','%','s','\'',0};
442  MSIEXTENSION *ext;
443  MSIRECORD *row;
444 
445  if (!name)
446  return NULL;
447 
448  if (name[0] == '.')
449  name++;
450 
451  /* check for extensions already loaded */
453  {
454  if (!strcmpiW( ext->Extension, name ))
455  {
456  TRACE("extension %s already loaded %p\n", debugstr_w(name), ext);
457  return ext;
458  }
459  }
460 
461  row = MSI_QueryGetRecord( package->db, query, name );
462  if (!row)
463  return NULL;
464 
465  ext = load_extension(package, row);
466  msiobj_release(&row->hdr);
467  return ext;
468 }
469 
471 {
472  MSIPACKAGE* package = param;
473  MSIVERB *verb;
474  LPCWSTR buffer;
475  MSIEXTENSION *extension;
476 
478  extension = load_given_extension( package, buffer );
479  if (!extension)
480  {
481  ERR("Verb unable to find loaded extension %s\n", debugstr_w(buffer));
482  return ERROR_SUCCESS;
483  }
484 
485  /* fill in the data */
486 
487  verb = msi_alloc_zero( sizeof(MSIVERB) );
488  if (!verb)
489  return ERROR_OUTOFMEMORY;
490 
491  verb->Verb = msi_dup_record_field(row,2);
492  TRACE("loading verb %s\n",debugstr_w(verb->Verb));
493  verb->Sequence = MSI_RecordGetInteger(row,3);
494 
496  deformat_string(package,buffer,&verb->Command);
497 
499  deformat_string(package,buffer,&verb->Argument);
500 
501  /* associate the verb with the correct extension */
502  list_add_tail( &extension->verbs, &verb->entry );
503 
504  return ERROR_SUCCESS;
505 }
506 
508 {
509  MSICOMPONENT *comp;
510  LPCWSTR clsid;
512  LPCWSTR buffer;
513  MSIPACKAGE* package = param;
514  MSICLASS *cls;
515  BOOL match = FALSE;
516 
517  clsid = MSI_RecordGetString(rec,1);
518  context = MSI_RecordGetString(rec,2);
519  buffer = MSI_RecordGetString(rec,3);
520  comp = msi_get_loaded_component(package, buffer);
521 
522  LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
523  {
524  if (strcmpiW( clsid, cls->clsid ))
525  continue;
526  if (strcmpW( context, cls->Context ))
527  continue;
528  if (comp == cls->Component)
529  {
530  match = TRUE;
531  break;
532  }
533  }
534 
535  if (!match)
536  load_class(package, rec);
537 
538  return ERROR_SUCCESS;
539 }
540 
541 static UINT load_all_classes( MSIPACKAGE *package )
542 {
543  static const WCHAR query[] = {
544  'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ','`','C','l','a','s','s','`',0};
545  MSIQUERY *view;
546  UINT rc;
547 
548  rc = MSI_DatabaseOpenViewW(package->db, query, &view);
549  if (rc != ERROR_SUCCESS)
550  return ERROR_SUCCESS;
551 
553  msiobj_release(&view->hdr);
554  return rc;
555 }
556 
558 {
559  MSICOMPONENT *comp;
560  LPCWSTR buffer;
561  LPCWSTR extension;
562  MSIPACKAGE* package = param;
563  BOOL match = FALSE;
564  MSIEXTENSION *ext;
565 
566  extension = MSI_RecordGetString(rec,1);
567  buffer = MSI_RecordGetString(rec,2);
568  comp = msi_get_loaded_component(package, buffer);
569 
570  LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry )
571  {
572  if (strcmpiW(extension, ext->Extension))
573  continue;
574  if (comp == ext->Component)
575  {
576  match = TRUE;
577  break;
578  }
579  }
580 
581  if (!match)
582  load_extension(package, rec);
583 
584  return ERROR_SUCCESS;
585 }
586 
588 {
589  static const WCHAR query[] = {
590  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','E','x','t','e','n','s','i','o','n','`',0};
591  MSIQUERY *view;
592  UINT rc;
593 
594  rc = MSI_DatabaseOpenViewW( package->db, query, &view );
595  if (rc != ERROR_SUCCESS)
596  return ERROR_SUCCESS;
597 
599  msiobj_release(&view->hdr);
600  return rc;
601 }
602 
604 {
605  LPCWSTR buffer;
606  MSIPACKAGE* package = param;
607 
608  buffer = MSI_RecordGetString(rec,1);
609  load_given_progid(package,buffer);
610  return ERROR_SUCCESS;
611 }
612 
613 static UINT load_all_progids( MSIPACKAGE *package )
614 {
615  static const WCHAR query[] = {
616  'S','E','L','E','C','T',' ','`','P','r','o','g','I','d','`',' ','F','R','O','M',' ',
617  '`','P','r','o','g','I','d','`',0};
618  MSIQUERY *view;
619  UINT rc;
620 
621  rc = MSI_DatabaseOpenViewW(package->db, query, &view);
622  if (rc != ERROR_SUCCESS)
623  return ERROR_SUCCESS;
624 
626  msiobj_release(&view->hdr);
627  return rc;
628 }
629 
630 static UINT load_all_verbs( MSIPACKAGE *package )
631 {
632  static const WCHAR query[] = {
633  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','V','e','r','b','`',0};
634  MSIQUERY *view;
635  UINT rc;
636 
637  rc = MSI_DatabaseOpenViewW(package->db, query, &view);
638  if (rc != ERROR_SUCCESS)
639  return ERROR_SUCCESS;
640 
642  msiobj_release(&view->hdr);
643  return rc;
644 }
645 
647 {
648  LPCWSTR buffer;
649  MSIPACKAGE* package = param;
650 
651  buffer = MSI_RecordGetString(rec,1);
652  load_given_mime(package,buffer);
653  return ERROR_SUCCESS;
654 }
655 
656 static UINT load_all_mimes( MSIPACKAGE *package )
657 {
658  static const WCHAR query[] = {
659  'S','E','L','E','C','T',' ','`','C','o','n','t','e','n','t','T','y','p','e','`',' ',
660  'F','R','O','M',' ','`','M','I','M','E','`',0};
661  MSIQUERY *view;
662  UINT rc;
663 
664  rc = MSI_DatabaseOpenViewW(package->db, query, &view);
665  if (rc != ERROR_SUCCESS)
666  return ERROR_SUCCESS;
667 
669  msiobj_release(&view->hdr);
670  return rc;
671 }
672 
674 {
675  UINT r;
676 
677  TRACE("Loading all the class info and related tables\n");
678 
679  /* check if already loaded */
680  if (!list_empty( &package->classes ) ||
681  !list_empty( &package->mimes ) ||
682  !list_empty( &package->extensions ) ||
683  !list_empty( &package->progids )) return ERROR_SUCCESS;
684 
685  r = load_all_classes( package );
686  if (r != ERROR_SUCCESS) return r;
687 
688  r = load_all_extensions( package );
689  if (r != ERROR_SUCCESS) return r;
690 
691  r = load_all_progids( package );
692  if (r != ERROR_SUCCESS) return r;
693 
694  /* these loads must come after the other loads */
695  r = load_all_verbs( package );
696  if (r != ERROR_SUCCESS) return r;
697 
698  return load_all_mimes( package );
699 }
700 
702 {
703  static const WCHAR szRemoteServerName[] =
704  {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};
705  static const WCHAR szLocalService[] =
706  {'L','o','c','a','l','S','e','r','v','i','c','e',0};
707  static const WCHAR szService[] =
708  {'S','e','r','v','i','c','e','P','a','r','a','m','e','t','e','r','s',0};
709  static const WCHAR szDLL[] =
710  {'D','l','l','S','u','r','r','o','g','a','t','e',0};
711  static const WCHAR szActivate[] =
712  {'A','c','t','i','v','a','t','e','A','s','S','t','o','r','a','g','e',0};
713  static const WCHAR szY[] = {'Y',0};
714  static const WCHAR szRunAs[] = {'R','u','n','A','s',0};
715  static const WCHAR szUser[] =
716  {'I','n','t','e','r','a','c','t','i','v','e',' ','U','s','e','r',0};
717 
718  HKEY hkey2,hkey3;
719 
721  RegCreateKeyW( hkey2, appid->AppID, &hkey3 );
722  RegCloseKey(hkey2);
723  msi_reg_set_val_str( hkey3, NULL, app );
724 
725  if (appid->RemoteServerName)
726  msi_reg_set_val_str( hkey3, szRemoteServerName, appid->RemoteServerName );
727 
728  if (appid->LocalServer)
729  msi_reg_set_val_str( hkey3, szLocalService, appid->LocalServer );
730 
731  if (appid->ServiceParameters)
732  msi_reg_set_val_str( hkey3, szService, appid->ServiceParameters );
733 
734  if (appid->DllSurrogate)
735  msi_reg_set_val_str( hkey3, szDLL, appid->DllSurrogate );
736 
737  if (appid->ActivateAtStorage)
738  msi_reg_set_val_str( hkey3, szActivate, szY );
739 
740  if (appid->RunAsInteractiveUser)
741  msi_reg_set_val_str( hkey3, szRunAs, szUser );
742 
743  RegCloseKey(hkey3);
744  return ERROR_SUCCESS;
745 }
746 
748 {
749  static const WCHAR szFileType_fmt[] = {'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0};
750  const WCHAR *keypath;
751  MSIRECORD *uirow;
752  HKEY hkey, hkey2, hkey3;
753  MSICLASS *cls;
754  UINT r;
755 
756  r = load_classes_and_such( package );
757  if (r != ERROR_SUCCESS)
758  return r;
759 
760  if (is_64bit && package->platform == PLATFORM_INTEL)
761  keypath = szWow6432NodeCLSID;
762  else
763  keypath = szCLSID;
764 
765  if (RegCreateKeyW(HKEY_CLASSES_ROOT, keypath, &hkey) != ERROR_SUCCESS)
766  return ERROR_FUNCTION_FAILED;
767 
768  LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
769  {
770  MSICOMPONENT *comp;
771  MSIFILE *file;
772  DWORD size;
773  LPWSTR argument;
775 
776  comp = cls->Component;
777  if ( !comp )
778  continue;
779 
780  if (!comp->Enabled)
781  {
782  TRACE("component is disabled\n");
783  continue;
784  }
785 
786  feature = cls->Feature;
787  if (!feature)
788  continue;
789 
790  feature->Action = msi_get_feature_action( package, feature );
791  if (feature->Action != INSTALLSTATE_LOCAL &&
792  feature->Action != INSTALLSTATE_ADVERTISED )
793  {
794  TRACE("feature %s not scheduled for installation, skipping registration of class %s\n",
795  debugstr_w(feature->Feature), debugstr_w(cls->clsid));
796  continue;
797  }
798 
799  if (!comp->KeyPath || !(file = msi_get_loaded_file( package, comp->KeyPath )))
800  {
801  TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid));
802  continue;
803  }
804  TRACE("Registering class %s (%p)\n", debugstr_w(cls->clsid), cls);
805 
806  cls->action = INSTALLSTATE_LOCAL;
807 
808  RegCreateKeyW( hkey, cls->clsid, &hkey2 );
809 
810  if (cls->Description)
811  msi_reg_set_val_str( hkey2, NULL, cls->Description );
812 
813  RegCreateKeyW( hkey2, cls->Context, &hkey3 );
814 
815  /*
816  * FIXME: Implement install on demand (advertised components).
817  *
818  * ole32.dll should call msi.MsiProvideComponentFromDescriptor()
819  * when it needs an InProcServer that doesn't exist.
820  * The component advertise string should be in the "InProcServer" value.
821  */
822  size = lstrlenW( file->TargetPath )+1;
823  if (cls->Argument)
824  size += lstrlenW(cls->Argument)+1;
825 
826  argument = msi_alloc( size * sizeof(WCHAR) );
827  lstrcpyW( argument, file->TargetPath );
828 
829  if (cls->Argument)
830  {
831  lstrcatW( argument, szSpace );
832  lstrcatW( argument, cls->Argument );
833  }
834 
835  msi_reg_set_val_str( hkey3, NULL, argument );
836  msi_free(argument);
837 
838  RegCloseKey(hkey3);
839 
840  if (cls->ProgID || cls->ProgIDText)
841  {
842  LPCWSTR progid;
843 
844  if (cls->ProgID)
845  progid = cls->ProgID->ProgID;
846  else
847  progid = cls->ProgIDText;
848 
850 
851  if (cls->ProgID && cls->ProgID->VersionInd)
852  {
854  cls->ProgID->VersionInd->ProgID );
855  }
856  }
857 
858  if (cls->AppID)
859  {
860  MSIAPPID *appid = cls->AppID;
861  msi_reg_set_val_str( hkey2, szAppID, appid->AppID );
863  }
864 
865  if (cls->IconPath)
867 
868  if (cls->DefInprocHandler)
870 
871  if (cls->DefInprocHandler32)
873 
874  RegCloseKey(hkey2);
875 
876  /* if there is a FileTypeMask, register the FileType */
877  if (cls->FileTypeMask)
878  {
879  LPWSTR ptr, ptr2;
880  LPWSTR keyname;
881  INT index = 0;
882  ptr = cls->FileTypeMask;
883  while (ptr && *ptr)
884  {
885  ptr2 = strchrW(ptr,';');
886  if (ptr2)
887  *ptr2 = 0;
888  keyname = msi_alloc( (strlenW(szFileType_fmt) + strlenW(cls->clsid) + 4) * sizeof(WCHAR));
889  sprintfW( keyname, szFileType_fmt, cls->clsid, index );
890 
892  msi_free(keyname);
893 
894  if (ptr2)
895  ptr = ptr2+1;
896  else
897  ptr = NULL;
898 
899  index ++;
900  }
901  }
902 
903  uirow = MSI_CreateRecord(1);
904  MSI_RecordSetStringW( uirow, 1, cls->clsid );
906  msiobj_release(&uirow->hdr);
907  }
908  RegCloseKey(hkey);
909  return ERROR_SUCCESS;
910 }
911 
913 {
914  static const WCHAR szFileType[] = {'F','i','l','e','T','y','p','e','\\',0};
915  const WCHAR *keypath;
916  MSIRECORD *uirow;
917  MSICLASS *cls;
918  HKEY hkey, hkey2;
919  UINT r;
920 
921  r = load_classes_and_such( package );
922  if (r != ERROR_SUCCESS)
923  return r;
924 
925  if (is_64bit && package->platform == PLATFORM_INTEL)
926  keypath = szWow6432NodeCLSID;
927  else
928  keypath = szCLSID;
929 
930  if (RegOpenKeyW( HKEY_CLASSES_ROOT, keypath, &hkey ) != ERROR_SUCCESS)
931  return ERROR_SUCCESS;
932 
933  LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
934  {
936  MSICOMPONENT *comp;
938  LONG res;
939 
940  comp = cls->Component;
941  if (!comp)
942  continue;
943 
944  if (!comp->Enabled)
945  {
946  TRACE("component is disabled\n");
947  continue;
948  }
949 
950  feature = cls->Feature;
951  if (!feature)
952  continue;
953 
954  feature->Action = msi_get_feature_action( package, feature );
955  if (feature->Action != INSTALLSTATE_ABSENT)
956  {
957  TRACE("feature %s not scheduled for removal, skipping unregistration of class %s\n",
958  debugstr_w(feature->Feature), debugstr_w(cls->clsid));
959  continue;
960  }
961  TRACE("Unregistering class %s (%p)\n", debugstr_w(cls->clsid), cls);
962 
964 
965  res = RegDeleteTreeW( hkey, cls->clsid );
966  if (res != ERROR_SUCCESS)
967  WARN("Failed to delete class key %d\n", res);
968 
969  if (cls->AppID)
970  {
972  if (res == ERROR_SUCCESS)
973  {
974  res = RegDeleteKeyW( hkey2, cls->AppID->AppID );
975  if (res != ERROR_SUCCESS)
976  WARN("Failed to delete appid key %d\n", res);
977  RegCloseKey( hkey2 );
978  }
979  }
980  if (cls->FileTypeMask)
981  {
982  filetype = msi_alloc( (strlenW( szFileType ) + strlenW( cls->clsid ) + 1) * sizeof(WCHAR) );
983  if (filetype)
984  {
985  strcpyW( filetype, szFileType );
986  strcatW( filetype, cls->clsid );
988  msi_free( filetype );
989 
990  if (res != ERROR_SUCCESS)
991  WARN("Failed to delete file type %d\n", res);
992  }
993  }
994 
995  uirow = MSI_CreateRecord( 1 );
996  MSI_RecordSetStringW( uirow, 1, cls->clsid );
998  msiobj_release( &uirow->hdr );
999  }
1000  RegCloseKey( hkey );
1001  return ERROR_SUCCESS;
1002 }
1003 
1005 {
1006  while (progid)
1007  {
1008  if (progid->Class)
1009  return progid->Class->clsid;
1010  if (progid->Parent == progid)
1011  break;
1012  progid = progid->Parent;
1013  }
1014  return NULL;
1015 }
1016 
1018 {
1019  static const WCHAR szCurVer[] = {'C','u','r','V','e','r',0};
1020  HKEY hkey = 0;
1021  UINT rc;
1022 
1023  rc = RegCreateKeyW( HKEY_CLASSES_ROOT, progid->ProgID, &hkey );
1024  if (rc == ERROR_SUCCESS)
1025  {
1027 
1028  if (clsid)
1030  else
1031  TRACE("%s has no class\n", debugstr_w( progid->ProgID ) );
1032 
1033  if (progid->Description)
1034  msi_reg_set_val_str( hkey, NULL, progid->Description );
1035 
1036  if (progid->IconPath)
1037  msi_reg_set_subkey_val( hkey, szDefaultIcon, NULL, progid->IconPath );
1038 
1039  /* write out the current version */
1040  if (progid->CurVer)
1041  msi_reg_set_subkey_val( hkey, szCurVer, NULL, progid->CurVer->ProgID );
1042 
1043  RegCloseKey(hkey);
1044  }
1045  else
1046  ERR("failed to create key %s\n", debugstr_w( progid->ProgID ) );
1047 
1048  return rc;
1049 }
1050 
1052 {
1053  while (progid)
1054  {
1055  if (progid->Parent) progid = progid->Parent;
1056  if (progid->Class) return progid->Class;
1057  if (!progid->Parent || progid->Parent == progid) break;
1058  }
1059  return NULL;
1060 }
1061 
1063 {
1064  const MSICLASS *class = get_progid_class( progid );
1065  if (!class || !class->ProgID) return FALSE;
1066  return (class->action == INSTALLSTATE_LOCAL);
1067 }
1068 
1070 {
1071  const MSIEXTENSION *extension;
1072  LIST_FOR_EACH_ENTRY( extension, &package->extensions, MSIEXTENSION, entry )
1073  {
1074  if (extension->ProgID == progid && !list_empty( &extension->verbs ) &&
1075  extension->action == INSTALLSTATE_LOCAL) return TRUE;
1076  }
1077  return FALSE;
1078 }
1079 
1081 {
1082  MSIPROGID *progid;
1083  MSIRECORD *uirow;
1084  UINT r;
1085 
1086  r = load_classes_and_such( package );
1087  if (r != ERROR_SUCCESS)
1088  return r;
1089 
1091  {
1093  {
1094  TRACE("progid %s not scheduled to be installed\n", debugstr_w(progid->ProgID));
1095  continue;
1096  }
1097  TRACE("Registering progid %s\n", debugstr_w(progid->ProgID));
1098 
1100 
1101  uirow = MSI_CreateRecord( 1 );
1102  MSI_RecordSetStringW( uirow, 1, progid->ProgID );
1104  msiobj_release( &uirow->hdr );
1105  }
1106  return ERROR_SUCCESS;
1107 }
1108 
1110 {
1111  const MSICLASS *class = get_progid_class( progid );
1112  if (!class || !class->ProgID) return FALSE;
1113  return (class->action == INSTALLSTATE_ABSENT);
1114 }
1115 
1116 static BOOL has_extensions( const MSIPACKAGE *package, const MSIPROGID *progid )
1117 {
1118  const MSIEXTENSION *extension;
1119  LIST_FOR_EACH_ENTRY( extension, &package->extensions, MSIEXTENSION, entry )
1120  {
1121  if (extension->ProgID == progid && !list_empty( &extension->verbs )) return TRUE;
1122  }
1123  return FALSE;
1124 }
1125 
1127 {
1128  BOOL ret = FALSE;
1129  const MSIEXTENSION *extension;
1130  LIST_FOR_EACH_ENTRY( extension, &package->extensions, MSIEXTENSION, entry )
1131  {
1132  if (extension->ProgID == progid && !list_empty( &extension->verbs ) &&
1133  extension->action == INSTALLSTATE_ABSENT) ret = TRUE;
1134  else ret = FALSE;
1135  }
1136  return ret;
1137 }
1138 
1140 {
1141  MSIPROGID *progid;
1142  MSIRECORD *uirow;
1143  LONG res;
1144  UINT r;
1145 
1146  r = load_classes_and_such( package );
1147  if (r != ERROR_SUCCESS)
1148  return r;
1149 
1151  {
1152  if (!has_class_removed( progid ) ||
1153  (has_extensions( package, progid ) && !has_all_extensions_removed( package, progid )))
1154  {
1155  TRACE("progid %s not scheduled to be removed\n", debugstr_w(progid->ProgID));
1156  continue;
1157  }
1158  TRACE("Unregistering progid %s\n", debugstr_w(progid->ProgID));
1159 
1161  if (res != ERROR_SUCCESS)
1162  TRACE("Failed to delete progid key %d\n", res);
1163 
1164  uirow = MSI_CreateRecord( 1 );
1165  MSI_RecordSetStringW( uirow, 1, progid->ProgID );
1167  msiobj_release( &uirow->hdr );
1168  }
1169  return ERROR_SUCCESS;
1170 }
1171 
1173  MSICOMPONENT* component, const MSIEXTENSION* extension,
1174  MSIVERB* verb, INT* Sequence )
1175 {
1176  LPWSTR keyname;
1177  HKEY key;
1178  static const WCHAR szShell[] = {'s','h','e','l','l',0};
1179  static const WCHAR szCommand[] = {'c','o','m','m','a','n','d',0};
1180  static const WCHAR fmt[] = {'\"','%','s','\"',' ','%','s',0};
1181  static const WCHAR fmt2[] = {'\"','%','s','\"',0};
1182  LPWSTR command;
1183  DWORD size;
1184  LPWSTR advertise;
1185 
1186  keyname = msi_build_directory_name(4, progid, szShell, verb->Verb, szCommand);
1187 
1188  TRACE("Making Key %s\n",debugstr_w(keyname));
1189  RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key);
1190  size = strlenW(component->FullKeypath);
1191  if (verb->Argument)
1192  size += strlenW(verb->Argument);
1193  size += 4;
1194 
1195  command = msi_alloc(size * sizeof (WCHAR));
1196  if (verb->Argument)
1197  sprintfW(command, fmt, component->FullKeypath, verb->Argument);
1198  else
1199  sprintfW(command, fmt2, component->FullKeypath);
1200 
1202  msi_free(command);
1203 
1204  advertise = msi_create_component_advertise_string(package, component,
1205  extension->Feature->Feature);
1206  size = strlenW(advertise);
1207 
1208  if (verb->Argument)
1209  size += strlenW(verb->Argument);
1210  size += 4;
1211 
1212  command = msi_alloc_zero(size * sizeof (WCHAR));
1213 
1214  strcpyW(command,advertise);
1215  if (verb->Argument)
1216  {
1218  strcatW(command,verb->Argument);
1219  }
1220 
1221  msi_reg_set_val_multi_str( key, szCommand, command );
1222 
1223  RegCloseKey(key);
1224  msi_free(keyname);
1225  msi_free(advertise);
1226  msi_free(command);
1227 
1228  if (verb->Command)
1229  {
1230  keyname = msi_build_directory_name( 3, progid, szShell, verb->Verb );
1232  msi_free(keyname);
1233  }
1234 
1235  if (verb->Sequence != MSI_NULL_INTEGER)
1236  {
1237  if (*Sequence == MSI_NULL_INTEGER || verb->Sequence < *Sequence)
1238  {
1239  *Sequence = verb->Sequence;
1240  keyname = msi_build_directory_name( 2, progid, szShell );
1241  msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, keyname, NULL, verb->Verb );
1242  msi_free(keyname);
1243  }
1244  }
1245  return ERROR_SUCCESS;
1246 }
1247 
1249 {
1250  static const WCHAR szContentType[] = {'C','o','n','t','e','n','t',' ','T','y','p','e',0};
1251  HKEY hkey = NULL;
1252  MSIEXTENSION *ext;
1253  MSIRECORD *uirow;
1254  BOOL install_on_demand = TRUE;
1255  LONG res;
1256  UINT r;
1257 
1258  r = load_classes_and_such( package );
1259  if (r != ERROR_SUCCESS)
1260  return r;
1261 
1262  /* We need to set install_on_demand based on if the shell handles advertised
1263  * shortcuts and the like. Because Mike McCormack is working on this i am
1264  * going to default to TRUE
1265  */
1266 
1268  {
1269  LPWSTR extension;
1271 
1272  if (!ext->Component)
1273  continue;
1274 
1275  if (!ext->Component->Enabled)
1276  {
1277  TRACE("component is disabled\n");
1278  continue;
1279  }
1280 
1281  feature = ext->Feature;
1282  if (!feature)
1283  continue;
1284 
1285  /*
1286  * yes. MSDN says that these are based on _Feature_ not on
1287  * Component. So verify the feature is to be installed
1288  */
1289  feature->Action = msi_get_feature_action( package, feature );
1290  if (feature->Action != INSTALLSTATE_LOCAL &&
1291  !(install_on_demand && feature->Action == INSTALLSTATE_ADVERTISED))
1292  {
1293  TRACE("feature %s not scheduled for installation, skipping registration of extension %s\n",
1294  debugstr_w(feature->Feature), debugstr_w(ext->Extension));
1295  continue;
1296  }
1297  TRACE("Registering extension %s (%p)\n", debugstr_w(ext->Extension), ext);
1298 
1299  ext->action = INSTALLSTATE_LOCAL;
1300 
1301  extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) );
1302  if (extension)
1303  {
1304  extension[0] = '.';
1305  strcpyW( extension + 1, ext->Extension );
1306  res = RegCreateKeyW( HKEY_CLASSES_ROOT, extension, &hkey );
1307  msi_free( extension );
1308  if (res != ERROR_SUCCESS)
1309  WARN("Failed to create extension key %d\n", res);
1310  }
1311 
1312  if (ext->Mime)
1313  msi_reg_set_val_str( hkey, szContentType, ext->Mime->ContentType );
1314 
1315  if (ext->ProgID || ext->ProgIDText)
1316  {
1317  static const WCHAR szSN[] =
1318  {'\\','S','h','e','l','l','N','e','w',0};
1319  HKEY hkey2;
1320  LPWSTR newkey;
1321  LPCWSTR progid;
1322  MSIVERB *verb;
1323  INT Sequence = MSI_NULL_INTEGER;
1324 
1325  if (ext->ProgID)
1326  progid = ext->ProgID->ProgID;
1327  else
1328  progid = ext->ProgIDText;
1329 
1330  msi_reg_set_val_str( hkey, NULL, progid );
1331 
1332  newkey = msi_alloc( (strlenW(progid)+strlenW(szSN)+1) * sizeof(WCHAR));
1333 
1334  strcpyW(newkey,progid);
1335  strcatW(newkey,szSN);
1336  RegCreateKeyW(hkey,newkey,&hkey2);
1337  RegCloseKey(hkey2);
1338 
1339  msi_free(newkey);
1340 
1341  /* do all the verbs */
1342  LIST_FOR_EACH_ENTRY( verb, &ext->verbs, MSIVERB, entry )
1343  {
1344  register_verb( package, progid, ext->Component,
1345  ext, verb, &Sequence);
1346  }
1347  }
1348 
1349  RegCloseKey(hkey);
1350 
1351  uirow = MSI_CreateRecord(1);
1352  MSI_RecordSetStringW( uirow, 1, ext->Extension );
1354  msiobj_release(&uirow->hdr);
1355  }
1356  return ERROR_SUCCESS;
1357 }
1358 
1360 {
1361  MSIEXTENSION *ext;
1362  MSIRECORD *uirow;
1363  LONG res;
1364  UINT r;
1365 
1366  r = load_classes_and_such( package );
1367  if (r != ERROR_SUCCESS)
1368  return r;
1369 
1371  {
1372  LPWSTR extension;
1374 
1375  if (!ext->Component)
1376  continue;
1377 
1378  if (!ext->Component->Enabled)
1379  {
1380  TRACE("component is disabled\n");
1381  continue;
1382  }
1383 
1384  feature = ext->Feature;
1385  if (!feature)
1386  continue;
1387 
1388  feature->Action = msi_get_feature_action( package, feature );
1389  if (feature->Action != INSTALLSTATE_ABSENT)
1390  {
1391  TRACE("feature %s not scheduled for removal, skipping unregistration of extension %s\n",
1392  debugstr_w(feature->Feature), debugstr_w(ext->Extension));
1393  continue;
1394  }
1395  TRACE("Unregistering extension %s\n", debugstr_w(ext->Extension));
1396 
1397  ext->action = INSTALLSTATE_ABSENT;
1398 
1399  extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) );
1400  if (extension)
1401  {
1402  extension[0] = '.';
1403  strcpyW( extension + 1, ext->Extension );
1404  res = RegDeleteTreeW( HKEY_CLASSES_ROOT, extension );
1405  msi_free( extension );
1406  if (res != ERROR_SUCCESS)
1407  WARN("Failed to delete extension key %d\n", res);
1408  }
1409 
1410  if (ext->ProgID || ext->ProgIDText)
1411  {
1412  static const WCHAR shellW[] = {'\\','s','h','e','l','l',0};
1413  LPCWSTR progid;
1414  LPWSTR progid_shell;
1415 
1416  if (ext->ProgID)
1417  progid = ext->ProgID->ProgID;
1418  else
1419  progid = ext->ProgIDText;
1420 
1421  progid_shell = msi_alloc( (strlenW( progid ) + strlenW( shellW ) + 1) * sizeof(WCHAR) );
1422  if (progid_shell)
1423  {
1424  strcpyW( progid_shell, progid );
1425  strcatW( progid_shell, shellW );
1426  res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid_shell );
1427  msi_free( progid_shell );
1428  if (res != ERROR_SUCCESS)
1429  WARN("Failed to delete shell key %d\n", res);
1431  }
1432  }
1433 
1434  uirow = MSI_CreateRecord( 1 );
1435  MSI_RecordSetStringW( uirow, 1, ext->Extension );
1437  msiobj_release( &uirow->hdr );
1438  }
1439  return ERROR_SUCCESS;
1440 }
1441 
1443 {
1444  static const WCHAR szExtension[] = {'E','x','t','e','n','s','i','o','n',0};
1445  MSIRECORD *uirow;
1446  MSIMIME *mt;
1447  UINT r;
1448 
1449  r = load_classes_and_such( package );
1450  if (r != ERROR_SUCCESS)
1451  return r;
1452 
1453  LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry )
1454  {
1455  LPWSTR extension = NULL, key;
1456 
1457  /*
1458  * check if the MIME is to be installed. Either as requested by an
1459  * extension or Class
1460  */
1461  if ((!mt->Class || mt->Class->action != INSTALLSTATE_LOCAL) &&
1462  (!mt->Extension || mt->Extension->action != INSTALLSTATE_LOCAL))
1463  {
1464  TRACE("MIME %s not scheduled to be installed\n", debugstr_w(mt->ContentType));
1465  continue;
1466  }
1467 
1468  TRACE("Registering MIME type %s\n", debugstr_w(mt->ContentType));
1469 
1470  if (mt->Extension) extension = msi_alloc( (strlenW( mt->Extension->Extension ) + 2) * sizeof(WCHAR) );
1471  key = msi_alloc( (strlenW( mt->ContentType ) + strlenW( szMIMEDatabase ) + 1) * sizeof(WCHAR) );
1472 
1473  if (extension && key)
1474  {
1475  extension[0] = '.';
1476  strcpyW( extension + 1, mt->Extension->Extension );
1477 
1479  strcatW( key, mt->ContentType );
1480  msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szExtension, extension );
1481 
1482  if (mt->clsid)
1484  }
1485  msi_free( extension );
1486  msi_free( key );
1487 
1488  uirow = MSI_CreateRecord( 2 );
1489  MSI_RecordSetStringW( uirow, 1, mt->ContentType );
1490  MSI_RecordSetStringW( uirow, 2, mt->suffix );
1492  msiobj_release( &uirow->hdr );
1493  }
1494  return ERROR_SUCCESS;
1495 }
1496 
1498 {
1499  MSIRECORD *uirow;
1500  MSIMIME *mime;
1501  UINT r;
1502 
1503  r = load_classes_and_such( package );
1504  if (r != ERROR_SUCCESS)
1505  return r;
1506 
1507  LIST_FOR_EACH_ENTRY( mime, &package->mimes, MSIMIME, entry )
1508  {
1509  LONG res;
1510  LPWSTR mime_key;
1511 
1512  if ((!mime->Class || mime->Class->action != INSTALLSTATE_ABSENT) &&
1513  (!mime->Extension || mime->Extension->action != INSTALLSTATE_ABSENT))
1514  {
1515  TRACE("MIME %s not scheduled to be removed\n", debugstr_w(mime->ContentType));
1516  continue;
1517  }
1518 
1519  TRACE("Unregistering MIME type %s\n", debugstr_w(mime->ContentType));
1520 
1521  mime_key = msi_alloc( (strlenW( szMIMEDatabase ) + strlenW( mime->ContentType ) + 1) * sizeof(WCHAR) );
1522  if (mime_key)
1523  {
1524  strcpyW( mime_key, szMIMEDatabase );
1525  strcatW( mime_key, mime->ContentType );
1526  res = RegDeleteKeyW( HKEY_CLASSES_ROOT, mime_key );
1527  if (res != ERROR_SUCCESS)
1528  WARN("Failed to delete MIME key %d\n", res);
1529  msi_free( mime_key );
1530  }
1531 
1532  uirow = MSI_CreateRecord( 2 );
1533  MSI_RecordSetStringW( uirow, 1, mime->ContentType );
1534  MSI_RecordSetStringW( uirow, 2, mime->suffix );
1536  msiobj_release( &uirow->hdr );
1537  }
1538  return ERROR_SUCCESS;
1539 }
LPWSTR Argument
Definition: msipriv.h:682
LONG msi_reg_set_subkey_val(HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWSTR val) DECLSPEC_HIDDEN
Definition: registry.c:381
INTERNETFEATURELIST feature
Definition: misc.c:1689
enum platform platform
Definition: msipriv.h:388
MSICLASS * Class
Definition: msipriv.h:692
#define TRUE
Definition: types.h:120
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:649
INSTALLSTATE msi_get_feature_action(MSIPACKAGE *package, MSIFEATURE *feature)
Definition: action.c:771
static MSIPROGID * load_progid(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:109
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
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
const WCHAR * mime
Definition: mimefilter.c:512
Definition: http.c:6587
static MSICLASS * load_given_class(MSIPACKAGE *package, LPCWSTR classid)
Definition: classes.c:309
static UINT iterate_all_progids(MSIRECORD *rec, LPVOID param)
Definition: classes.c:603
Definition: match.c:28
static BOOL has_all_extensions_removed(const MSIPACKAGE *package, const MSIPROGID *progid)
Definition: classes.c:1126
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
struct list entry
Definition: msipriv.h:687
MSIFEATURE * Feature
Definition: msipriv.h:641
MSIOBJECTHDR hdr
Definition: msipriv.h:141
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
MSIEXTENSION * Extension
Definition: msipriv.h:689
MSICOMPONENT * Component
Definition: msipriv.h:631
LPWSTR Feature
Definition: msipriv.h:472
static MSIMIME * load_mime(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:342
INT Attributes
Definition: msipriv.h:642
LPWSTR IconPath
Definition: msipriv.h:637
uint8_t entry
Definition: isohybrid.c:63
#define WARN(fmt,...)
Definition: debug.h:111
INSTALLSTATE action
Definition: msipriv.h:659
WINE_DEFAULT_DEBUG_CHANNEL(msi)
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1240
static const WCHAR szCLSID[]
Definition: msipriv.h:1160
UINT ACTION_UnregisterProgIdInfo(MSIPACKAGE *package)
Definition: classes.c:1139
static UINT load_all_classes(MSIPACKAGE *package)
Definition: classes.c:541
GLuint buffer
Definition: glext.h:5915
#define MSI_NULL_INTEGER
Definition: msiquery.h:32
LPWSTR AppID
Definition: msipriv.h:615
static const MSICLASS * get_progid_class(const MSIPROGID *progid)
Definition: classes.c:1051
static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, MSICOMPONENT *component, const MSIEXTENSION *extension, MSIVERB *verb, INT *Sequence)
Definition: classes.c:1172
LPWSTR KeyPath
Definition: msipriv.h:507
static MSICLASS * load_class(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:210
static MSIAPPID * load_appid(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:46
INT Sequence
Definition: msipriv.h:680
MSIPROGID * VersionInd
Definition: msipriv.h:673
#define lstrlenW
Definition: compat.h:407
WCHAR * msi_build_icon_path(MSIPACKAGE *package, const WCHAR *icon_name)
Definition: action.c:3895
LPWSTR FileTypeMask
Definition: msipriv.h:636
int32_t INT
Definition: typedefs.h:56
static const BOOL is_64bit
Definition: msipriv.h:41
static const WCHAR szProgID[]
Definition: msipriv.h:1161
static const WCHAR szSpace[]
Definition: msipriv.h:1110
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1210
PCWSTR FilePath
static UINT load_classes_and_such(MSIPACKAGE *package)
Definition: classes.c:673
struct list verbs
Definition: msipriv.h:660
LPWSTR suffix
Definition: msipriv.h:690
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
LPWSTR clsid
Definition: msipriv.h:691
#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
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
BOOL MSI_RecordIsNull(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:369
static const WCHAR szAppID[]
Definition: msipriv.h:1163
static UINT iterate_all_classes(MSIRECORD *rec, LPVOID param)
Definition: classes.c:507
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3311
#define debugstr_w
Definition: kernel32.h:32
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *) DECLSPEC_HIDDEN
Definition: package.c:1946
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
static UINT load_all_progids(MSIPACKAGE *package)
Definition: classes.c:613
char * appid
Definition: mkisofs.c:161
LPWSTR Command
Definition: msipriv.h:681
smooth NULL
Definition: ftsmooth.c:416
char ext[3]
Definition: mkdosfs.c:358
LPWSTR szRemoteServerName
Definition: logoff.c:25
LONG msi_reg_set_val_str(HKEY hkey, LPCWSTR name, LPCWSTR value) DECLSPEC_HIDDEN
Definition: registry.c:360
static UINT load_all_verbs(MSIPACKAGE *package)
Definition: classes.c:630
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:482
GLuint index
Definition: glext.h:6031
struct list mimes
Definition: msipriv.h:412
static const WCHAR szWow6432NodeCLSID[]
Definition: msipriv.h:1177
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:674
LPWSTR DefInprocHandler
Definition: msipriv.h:638
LPWSTR Extension
Definition: msipriv.h:652
WCHAR * msi_create_component_advertise_string(MSIPACKAGE *package, MSICOMPONENT *component, const WCHAR *feature)
Definition: action.c:5712
DWORD deformat_string(MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
Definition: format.c:1016
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
LPWSTR Context
Definition: msipriv.h:630
struct list classes
Definition: msipriv.h:409
LPWSTR ProgIDText
Definition: msipriv.h:633
r parent
Definition: btrfs.c:2659
__wchar_t WCHAR
Definition: xmlstorage.h:180
MSIRECORD * MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...) DECLSPEC_HIDDEN
Definition: msiquery.c:206
static BOOL has_class_removed(const MSIPROGID *progid)
Definition: classes.c:1109
struct list appids
Definition: msipriv.h:413
LPWSTR Description
Definition: msipriv.h:634
GLfloat param
Definition: glext.h:5796
const char file[]
Definition: icontest.c:11
static MSIMIME * load_given_mime(MSIPACKAGE *package, LPCWSTR mime)
Definition: classes.c:368
static const WCHAR szVIProgID[]
Definition: msipriv.h:1162
UINT ACTION_UnregisterClassInfo(MSIPACKAGE *package)
Definition: classes.c:912
unsigned long DWORD
Definition: ntddk_ex.h:95
struct list progids
Definition: msipriv.h:411
MSIDATABASE * db
Definition: msipriv.h:386
UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
Definition: classes.c:747
MSIPROGID * ProgID
Definition: msipriv.h:654
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:242
LPWSTR Component
Definition: msipriv.h:502
MSICOMPONENT * msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component)
Definition: action.c:652
int ret
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:79
UINT ACTION_UnregisterExtensionInfo(MSIPACKAGE *package)
Definition: classes.c:1359
REFCLSID clsid
Definition: msctf.c:84
static MSIEXTENSION * load_given_extension(MSIPACKAGE *package, LPCWSTR extension)
Definition: classes.c:436
HKEY key
Definition: reg.c:42
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1202
UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)
Definition: classes.c:1080
static UINT register_progid(const MSIPROGID *progid)
Definition: classes.c:1017
static MSIAPPID * load_given_appid(MSIPACKAGE *package, LPCWSTR name)
Definition: classes.c:75
static const WCHAR szInprocHandler[]
Definition: msipriv.h:1165
MSIAPPID * AppID
Definition: msipriv.h:635
#define strcmpiW(s1, s2)
Definition: unicode.h:39
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1755
struct list extensions
Definition: msipriv.h:410
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:245
#define ERR(fmt,...)
Definition: debug.h:109
void msi_reduce_to_long_filename(WCHAR *filename)
Definition: files.c:863
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
LPWSTR clsid
Definition: msipriv.h:629
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
MSIFEATURE * Feature
Definition: msipriv.h:657
#define lstrcpyW
Definition: compat.h:406
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
Definition: record.c:1055
static MSIEXTENSION * load_extension(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:399
static UINT load_all_extensions(MSIPACKAGE *package)
Definition: classes.c:587
#define sprintfW
Definition: unicode.h:58
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
LPWSTR ProgID
Definition: msipriv.h:666
MSIPROGID * ProgID
Definition: msipriv.h:632
unsigned int UINT
Definition: ndis.h:50
static BOOL has_one_extension_installed(const MSIPACKAGE *package, const MSIPROGID *progid)
Definition: classes.c:1069
static UINT iterate_all_extensions(MSIRECORD *rec, LPVOID param)
Definition: classes.c:557
int command(const char *fmt,...)
Definition: ftp.c:266
static BOOL msi_free(void *mem)
Definition: msipriv.h:1227
LPWSTR FullKeypath
Definition: msipriv.h:515
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
GLuint res
Definition: glext.h:9613
const WCHAR * class
Definition: main.c:68
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1204
#define progid(str)
Definition: exdisp.idl:31
static IOleDocumentView * view
Definition: activex.c:1749
WCHAR * msi_build_directory_name(DWORD count,...)
Definition: action.c:2164
static BOOL has_class_installed(const MSIPROGID *progid)
Definition: classes.c:1062
static UINT register_appid(const MSIAPPID *appid, LPCWSTR app)
Definition: classes.c:701
LOCAL char * filetype(int t)
Definition: tree.c:114
LPWSTR DefInprocHandler32
Definition: msipriv.h:639
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
Definition: classes.c:1248
LPWSTR Verb
Definition: msipriv.h:679
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static MSIPROGID * load_given_progid(MSIPACKAGE *package, LPCWSTR progid)
Definition: classes.c:179
static const WCHAR szDefaultIcon[]
Definition: msipriv.h:1164
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static LPCWSTR get_clsid_of_progid(const MSIPROGID *progid)
Definition: classes.c:1004
LONG msi_reg_set_val_multi_str(HKEY hkey, LPCWSTR name, LPCWSTR value) DECLSPEC_HIDDEN
Definition: registry.c:368
UINT ACTION_UnregisterMIMEInfo(MSIPACKAGE *package)
Definition: classes.c:1497
static const WCHAR szInprocHandler32[]
Definition: msipriv.h:1166
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID) DECLSPEC_HIDDEN
Definition: msiquery.c:168
LPWSTR Argument
Definition: msipriv.h:640
UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package)
Definition: classes.c:1442
static const WCHAR szMIMEDatabase[]
Definition: msipriv.h:1167
Definition: dsound.c:943
static UINT iterate_load_verb(MSIRECORD *row, LPVOID param)
Definition: classes.c:470
LPWSTR ContentType
Definition: msipriv.h:688
INSTALLSTATE action
Definition: msipriv.h:644
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
struct list entry
Definition: msipriv.h:628
Definition: path.c:42
static UINT iterate_all_mimes(MSIRECORD *rec, LPVOID param)
Definition: classes.c:646
Definition: fci.c:126
static BOOL has_extensions(const MSIPACKAGE *package, const MSIPROGID *progid)
Definition: classes.c:1116
static UINT load_all_mimes(MSIPACKAGE *package)
Definition: classes.c:656
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **) DECLSPEC_HIDDEN
Definition: msiquery.c:111