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