ReactOS 0.4.15-dev-5664-g3bf4ef6
classes.c File Reference
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "wine/debug.h"
#include "msipriv.h"
#include "winuser.h"
Include dependency graph for classes.c:

Go to the source code of this file.

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msi)
 
static MSIAPPIDload_appid (MSIPACKAGE *package, MSIRECORD *row)
 
static MSIAPPIDload_given_appid (MSIPACKAGE *package, LPCWSTR name)
 
static MSIPROGIDload_given_progid (MSIPACKAGE *package, LPCWSTR progid)
 
static MSICLASSload_given_class (MSIPACKAGE *package, LPCWSTR classid)
 
static MSIPROGIDload_progid (MSIPACKAGE *package, MSIRECORD *row)
 
static MSICLASSload_class (MSIPACKAGE *package, MSIRECORD *row)
 
static MSIEXTENSIONload_given_extension (MSIPACKAGE *package, LPCWSTR extension)
 
static MSIMIMEload_mime (MSIPACKAGE *package, MSIRECORD *row)
 
static MSIMIMEload_given_mime (MSIPACKAGE *package, LPCWSTR mime)
 
static MSIEXTENSIONload_extension (MSIPACKAGE *package, MSIRECORD *row)
 
static UINT iterate_load_verb (MSIRECORD *row, LPVOID param)
 
static UINT iterate_all_classes (MSIRECORD *rec, LPVOID param)
 
static UINT load_all_classes (MSIPACKAGE *package)
 
static UINT iterate_all_extensions (MSIRECORD *rec, LPVOID param)
 
static UINT load_all_extensions (MSIPACKAGE *package)
 
static UINT iterate_all_progids (MSIRECORD *rec, LPVOID param)
 
static UINT load_all_progids (MSIPACKAGE *package)
 
static UINT load_all_verbs (MSIPACKAGE *package)
 
static UINT iterate_all_mimes (MSIRECORD *rec, LPVOID param)
 
static UINT load_all_mimes (MSIPACKAGE *package)
 
static UINT load_classes_and_such (MSIPACKAGE *package)
 
static UINT register_appid (const MSIAPPID *appid, LPCWSTR app)
 
UINT ACTION_RegisterClassInfo (MSIPACKAGE *package)
 
UINT ACTION_UnregisterClassInfo (MSIPACKAGE *package)
 
static LPCWSTR get_clsid_of_progid (const MSIPROGID *progid)
 
static UINT register_progid (const MSIPROGID *progid)
 
static const MSICLASSget_progid_class (const MSIPROGID *progid)
 
static BOOL has_class_installed (const MSIPROGID *progid)
 
static BOOL has_one_extension_installed (const MSIPACKAGE *package, const MSIPROGID *progid)
 
UINT ACTION_RegisterProgIdInfo (MSIPACKAGE *package)
 
static BOOL has_class_removed (const MSIPROGID *progid)
 
static BOOL has_extensions (const MSIPACKAGE *package, const MSIPROGID *progid)
 
static BOOL has_all_extensions_removed (const MSIPACKAGE *package, const MSIPROGID *progid)
 
UINT ACTION_UnregisterProgIdInfo (MSIPACKAGE *package)
 
static UINT register_verb (MSIPACKAGE *package, LPCWSTR progid, MSICOMPONENT *component, const MSIEXTENSION *extension, MSIVERB *verb, INT *Sequence)
 
UINT ACTION_RegisterExtensionInfo (MSIPACKAGE *package)
 
UINT ACTION_UnregisterExtensionInfo (MSIPACKAGE *package)
 
UINT ACTION_RegisterMIMEInfo (MSIPACKAGE *package)
 
UINT ACTION_UnregisterMIMEInfo (MSIPACKAGE *package)
 

Function Documentation

◆ ACTION_RegisterClassInfo()

UINT ACTION_RegisterClassInfo ( MSIPACKAGE package)

Definition at line 690 of file classes.c.

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 ))
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 &&
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
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 {
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}
#define RegCloseKey(hKey)
Definition: registry.h:47
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
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
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1199
#define wcschr
Definition: compat.h:17
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
INSTALLSTATE msi_get_feature_action(MSIPACKAGE *package, MSIFEATURE *feature)
Definition: action.c:627
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:574
UINT msi_schedule_action(MSIPACKAGE *package, UINT script, const WCHAR *action)
Definition: custom.c:90
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
#define swprintf
Definition: precomp.h:40
#define progid(str)
Definition: exdisp.idl:31
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
char * appid
Definition: mkisofs.c:161
static PVOID ptr
Definition: dispmode.c:27
INTERNETFEATURELIST feature
Definition: misc.c:1719
static UINT load_classes_and_such(MSIPACKAGE *package)
Definition: classes.c:631
static UINT register_appid(const MSIAPPID *appid, LPCWSTR app)
Definition: classes.c:659
@ INSTALLMESSAGE_ACTIONDATA
Definition: msi.h:103
@ INSTALLSTATE_LOCAL
Definition: msi.h:46
@ INSTALLSTATE_ADVERTISED
Definition: msi.h:44
static void msi_free(void *mem)
Definition: msipriv.h:1159
@ SCRIPT_INSTALL
Definition: msipriv.h:385
@ SCRIPT_NONE
Definition: msipriv.h:384
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *) DECLSPEC_HIDDEN
Definition: package.c:1914
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
LONG msi_reg_set_subkey_val(HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWSTR val) DECLSPEC_HIDDEN
Definition: registry.c:230
@ PLATFORM_INTEL
Definition: msipriv.h:366
LONG msi_reg_set_val_str(HKEY hkey, LPCWSTR name, LPCWSTR value) DECLSPEC_HIDDEN
Definition: registry.c:209
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:597
unsigned int UINT
Definition: ndis.h:50
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define L(x)
Definition: ntvdm.h:50
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define TRACE(s)
Definition: solgame.cpp:4
Definition: fci.c:127
LPWSTR clsid
Definition: msipriv.h:652
LPWSTR IconPath
Definition: msipriv.h:660
LPWSTR Argument
Definition: msipriv.h:663
LPWSTR ProgIDText
Definition: msipriv.h:656
INSTALLSTATE action
Definition: msipriv.h:667
LPWSTR DefInprocHandler
Definition: msipriv.h:661
MSIAPPID * AppID
Definition: msipriv.h:658
LPWSTR FileTypeMask
Definition: msipriv.h:659
LPWSTR Description
Definition: msipriv.h:657
LPWSTR DefInprocHandler32
Definition: msipriv.h:662
LPWSTR Context
Definition: msipriv.h:653
MSICOMPONENT * Component
Definition: msipriv.h:654
MSIFEATURE * Feature
Definition: msipriv.h:664
MSIPROGID * ProgID
Definition: msipriv.h:655
LPWSTR KeyPath
Definition: msipriv.h:530
struct list classes
Definition: msipriv.h:426
enum platform platform
Definition: msipriv.h:396
enum script script
Definition: msipriv.h:432
LPWSTR ProgID
Definition: msipriv.h:689
MSIPROGID * VersionInd
Definition: msipriv.h:696
MSIOBJECTHDR hdr
Definition: msipriv.h:151
int32_t INT
Definition: typedefs.h:58
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

◆ ACTION_RegisterExtensionInfo()

UINT ACTION_RegisterExtensionInfo ( MSIPACKAGE package)

Definition at line 1196 of file classes.c.

1197{
1198 HKEY hkey = NULL;
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;
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
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}
#define WARN(fmt,...)
Definition: debug.h:112
#define TRUE
Definition: types.h:120
static const WCHAR *const ext[]
Definition: module.c:53
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint res
Definition: glext.h:9613
static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, MSICOMPONENT *component, const MSIEXTENSION *extension, MSIVERB *verb, INT *Sequence)
Definition: classes.c:1124
#define MSI_NULL_INTEGER
Definition: msiquery.h:32
long LONG
Definition: pedump.c:60
struct list extensions
Definition: msipriv.h:427

◆ ACTION_RegisterMIMEInfo()

UINT ACTION_RegisterMIMEInfo ( MSIPACKAGE package)

Definition at line 1392 of file classes.c.

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}
Definition: copy.c:22
INSTALLSTATE action
Definition: msipriv.h:682
LPWSTR Extension
Definition: msipriv.h:675
MSIEXTENSION * Extension
Definition: msipriv.h:712
LPWSTR ContentType
Definition: msipriv.h:711
LPWSTR clsid
Definition: msipriv.h:714
MSICLASS * Class
Definition: msipriv.h:715
LPWSTR suffix
Definition: msipriv.h:713
struct list mimes
Definition: msipriv.h:429

◆ ACTION_RegisterProgIdInfo()

UINT ACTION_RegisterProgIdInfo ( MSIPACKAGE package)

Definition at line 1026 of file classes.c.

1027{
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}
static BOOL has_class_installed(const MSIPROGID *progid)
Definition: classes.c:1008
static BOOL has_one_extension_installed(const MSIPACKAGE *package, const MSIPROGID *progid)
Definition: classes.c:1015
static UINT register_progid(const MSIPROGID *progid)
Definition: classes.c:964
struct list progids
Definition: msipriv.h:428

◆ ACTION_UnregisterClassInfo()

UINT ACTION_UnregisterClassInfo ( MSIPACKAGE package)

Definition at line 857 of file classes.c.

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 ))
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 );
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}
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3291
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1746
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
@ INSTALLSTATE_ABSENT
Definition: msi.h:45
LOCAL char * filetype(int t)
Definition: tree.c:114
LPWSTR AppID
Definition: msipriv.h:638

◆ ACTION_UnregisterExtensionInfo()

UINT ACTION_UnregisterExtensionInfo ( MSIPACKAGE package)

Definition at line 1307 of file classes.c.

1308{
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 {
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}

◆ ACTION_UnregisterMIMEInfo()

UINT ACTION_UnregisterMIMEInfo ( MSIPACKAGE package)

Definition at line 1450 of file classes.c.

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
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}
const WCHAR * mime
Definition: mimefilter.c:512

◆ ACTION_UnregisterProgIdInfo()

UINT ACTION_UnregisterProgIdInfo ( MSIPACKAGE package)

Definition at line 1088 of file classes.c.

1089{
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}
static BOOL has_extensions(const MSIPACKAGE *package, const MSIPROGID *progid)
Definition: classes.c:1065
static BOOL has_all_extensions_removed(const MSIPACKAGE *package, const MSIPROGID *progid)
Definition: classes.c:1075
static BOOL has_class_removed(const MSIPROGID *progid)
Definition: classes.c:1058

◆ get_clsid_of_progid()

static LPCWSTR get_clsid_of_progid ( const MSIPROGID progid)
static

Definition at line 951 of file classes.c.

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}

Referenced by register_progid().

◆ get_progid_class()

static const MSICLASS * get_progid_class ( const MSIPROGID progid)
static

Definition at line 997 of file classes.c.

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}

Referenced by has_class_installed(), and has_class_removed().

◆ has_all_extensions_removed()

static BOOL has_all_extensions_removed ( const MSIPACKAGE package,
const MSIPROGID progid 
)
static

Definition at line 1075 of file classes.c.

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}
static int list_empty(struct list_entry *head)
Definition: list.h:58
#define FALSE
Definition: types.h:117
struct list verbs
Definition: msipriv.h:683
MSIPROGID * ProgID
Definition: msipriv.h:677
int ret

Referenced by ACTION_UnregisterProgIdInfo().

◆ has_class_installed()

static BOOL has_class_installed ( const MSIPROGID progid)
static

Definition at line 1008 of file classes.c.

1009{
1010 const MSICLASS *class = get_progid_class( progid );
1011 if (!class || !class->ProgID) return FALSE;
1012 return (class->action == INSTALLSTATE_LOCAL);
1013}
const WCHAR * class
Definition: main.c:68
static const MSICLASS * get_progid_class(const MSIPROGID *progid)
Definition: classes.c:997

Referenced by ACTION_RegisterProgIdInfo().

◆ has_class_removed()

static BOOL has_class_removed ( const MSIPROGID progid)
static

Definition at line 1058 of file classes.c.

1059{
1060 const MSICLASS *class = get_progid_class( progid );
1061 if (!class || !class->ProgID) return FALSE;
1062 return (class->action == INSTALLSTATE_ABSENT);
1063}

Referenced by ACTION_UnregisterProgIdInfo().

◆ has_extensions()

static BOOL has_extensions ( const MSIPACKAGE package,
const MSIPROGID progid 
)
static

Definition at line 1065 of file classes.c.

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}

Referenced by ACTION_UnregisterProgIdInfo().

◆ has_one_extension_installed()

static BOOL has_one_extension_installed ( const MSIPACKAGE package,
const MSIPROGID progid 
)
static

Definition at line 1015 of file classes.c.

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}

Referenced by ACTION_RegisterProgIdInfo().

◆ iterate_all_classes()

static UINT iterate_all_classes ( MSIRECORD rec,
LPVOID  param 
)
static

Definition at line 477 of file classes.c.

478{
479 MSICOMPONENT *comp;
483 MSIPACKAGE* package = param;
484 MSICLASS *cls;
485 BOOL match = FALSE;
486
487 clsid = MSI_RecordGetString(rec,1);
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}
#define wcsicmp
Definition: compat.h:15
MSICOMPONENT * msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component)
Definition: action.c:552
GLuint buffer
Definition: glext.h:5915
REFCLSID clsid
Definition: msctf.c:82
static MSICLASS * load_class(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:198
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
Definition: http.c:7252
Definition: match.c:28

Referenced by load_all_classes().

◆ iterate_all_extensions()

static UINT iterate_all_extensions ( MSIRECORD rec,
LPVOID  param 
)
static

Definition at line 525 of file classes.c.

526{
527 MSICOMPONENT *comp;
529 LPCWSTR extension;
530 MSIPACKAGE* package = param;
531 BOOL match = FALSE;
533
534 extension = MSI_RecordGetString(rec,1);
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}
static MSIEXTENSION * load_extension(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:373

Referenced by load_all_extensions().

◆ iterate_all_mimes()

static UINT iterate_all_mimes ( MSIRECORD rec,
LPVOID  param 
)
static

Definition at line 607 of file classes.c.

608{
610 MSIPACKAGE* package = param;
611
613 load_given_mime(package,buffer);
614 return ERROR_SUCCESS;
615}
static MSIMIME * load_given_mime(MSIPACKAGE *package, LPCWSTR mime)
Definition: classes.c:346

Referenced by load_all_mimes().

◆ iterate_all_progids()

static UINT iterate_all_progids ( MSIRECORD rec,
LPVOID  param 
)
static

Definition at line 569 of file classes.c.

570{
572 MSIPACKAGE* package = param;
573
575 load_given_progid(package,buffer);
576 return ERROR_SUCCESS;
577}
static MSIPROGID * load_given_progid(MSIPACKAGE *package, LPCWSTR progid)
Definition: classes.c:171

Referenced by load_all_progids().

◆ iterate_load_verb()

static UINT iterate_load_verb ( MSIRECORD row,
LPVOID  param 
)
static

Definition at line 440 of file classes.c.

441{
442 MSIPACKAGE* package = param;
443 MSIVERB *verb;
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}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
DWORD deformat_string(MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
Definition: format.c:1016
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
static MSIEXTENSION * load_given_extension(MSIPACKAGE *package, LPCWSTR extension)
Definition: classes.c:410
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
Definition: record.c:1002
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:213

Referenced by load_all_verbs().

◆ load_all_classes()

static UINT load_all_classes ( MSIPACKAGE package)
static

Definition at line 511 of file classes.c.

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}
static UINT iterate_all_classes(MSIRECORD *rec, LPVOID param)
Definition: classes.c:477
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID) DECLSPEC_HIDDEN
Definition: msiquery.c:163
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **) DECLSPEC_HIDDEN
MSIDATABASE * db
Definition: msipriv.h:394

Referenced by load_classes_and_such().

◆ load_all_extensions()

static UINT load_all_extensions ( MSIPACKAGE package)
static

Definition at line 555 of file classes.c.

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}
static UINT iterate_all_extensions(MSIRECORD *rec, LPVOID param)
Definition: classes.c:525

Referenced by load_classes_and_such().

◆ load_all_mimes()

static UINT load_all_mimes ( MSIPACKAGE package)
static

Definition at line 617 of file classes.c.

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}
static UINT iterate_all_mimes(MSIRECORD *rec, LPVOID param)
Definition: classes.c:607

Referenced by load_classes_and_such().

◆ load_all_progids()

static UINT load_all_progids ( MSIPACKAGE package)
static

Definition at line 579 of file classes.c.

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}
static UINT iterate_all_progids(MSIRECORD *rec, LPVOID param)
Definition: classes.c:569

Referenced by load_classes_and_such().

◆ load_all_verbs()

static UINT load_all_verbs ( MSIPACKAGE package)
static

Definition at line 593 of file classes.c.

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}
static UINT iterate_load_verb(MSIRECORD *row, LPVOID param)
Definition: classes.c:440

Referenced by load_classes_and_such().

◆ load_appid()

static MSIAPPID * load_appid ( MSIPACKAGE package,
MSIRECORD row 
)
static

Definition at line 45 of file classes.c.

46{
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}
BOOL MSI_RecordIsNull(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:321
struct list appids
Definition: msipriv.h:430

Referenced by load_given_appid().

◆ load_class()

static MSICLASS * load_class ( MSIPACKAGE package,
MSIRECORD row 
)
static

Definition at line 198 of file classes.c.

199{
200 MSICLASS *cls;
201 DWORD i;
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 {
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}
PCWSTR FilePath
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
MSIFEATURE * msi_get_loaded_feature(MSIPACKAGE *package, const WCHAR *Feature)
Definition: action.c:563
WCHAR * msi_build_icon_path(MSIPACKAGE *package, const WCHAR *icon_name)
Definition: action.c:3711
void msi_reduce_to_long_filename(WCHAR *filename)
Definition: files.c:1074
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
static MSIAPPID * load_given_appid(MSIPACKAGE *package, LPCWSTR name)
Definition: classes.c:74
@ INSTALLSTATE_UNKNOWN
Definition: msi.h:42
INT Attributes
Definition: msipriv.h:665
struct list entry
Definition: msipriv.h:651

Referenced by iterate_all_classes(), and load_given_class().

◆ load_classes_and_such()

static UINT load_classes_and_such ( MSIPACKAGE package)
static

Definition at line 631 of file classes.c.

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}
static UINT load_all_classes(MSIPACKAGE *package)
Definition: classes.c:511
static UINT load_all_verbs(MSIPACKAGE *package)
Definition: classes.c:593
static UINT load_all_mimes(MSIPACKAGE *package)
Definition: classes.c:617
static UINT load_all_progids(MSIPACKAGE *package)
Definition: classes.c:579
static UINT load_all_extensions(MSIPACKAGE *package)
Definition: classes.c:555

Referenced by ACTION_RegisterClassInfo(), ACTION_RegisterExtensionInfo(), ACTION_RegisterMIMEInfo(), ACTION_RegisterProgIdInfo(), ACTION_UnregisterClassInfo(), ACTION_UnregisterExtensionInfo(), ACTION_UnregisterMIMEInfo(), and ACTION_UnregisterProgIdInfo().

◆ load_extension()

static MSIEXTENSION * load_extension ( MSIPACKAGE package,
MSIRECORD row 
)
static

Definition at line 373 of file classes.c.

374{
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}
static void list_init(struct list_entry *head)
Definition: list.h:51

Referenced by iterate_all_extensions(), and load_given_extension().

◆ load_given_appid()

static MSIAPPID * load_given_appid ( MSIPACKAGE package,
LPCWSTR  name 
)
static

Definition at line 74 of file classes.c.

75{
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}
static MSIAPPID * load_appid(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:45
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...) DECLSPEC_HIDDEN
Definition: msiquery.c:201
Definition: name.c:39

Referenced by load_class().

◆ load_given_class()

static MSICLASS * load_given_class ( MSIPACKAGE package,
LPCWSTR  classid 
)
static

Definition at line 291 of file classes.c.

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}

Referenced by load_mime(), and load_progid().

◆ load_given_extension()

static MSIEXTENSION * load_given_extension ( MSIPACKAGE package,
LPCWSTR  extension 
)
static

Definition at line 410 of file classes.c.

411{
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}

Referenced by iterate_load_verb(), and load_mime().

◆ load_given_mime()

static MSIMIME * load_given_mime ( MSIPACKAGE package,
LPCWSTR  mime 
)
static

Definition at line 346 of file classes.c.

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}
static MSIMIME * load_mime(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:320

Referenced by iterate_all_mimes(), and load_extension().

◆ load_given_progid()

static MSIPROGID * load_given_progid ( MSIPACKAGE package,
LPCWSTR  progid 
)
static

Definition at line 171 of file classes.c.

172{
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}
static MSIPROGID * load_progid(MSIPACKAGE *package, MSIRECORD *row)
Definition: classes.c:104

Referenced by iterate_all_progids(), load_class(), load_extension(), and load_progid().

◆ load_mime()

static MSIMIME * load_mime ( MSIPACKAGE package,
MSIRECORD row 
)
static

Definition at line 320 of file classes.c.

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}
static MSICLASS * load_given_class(MSIPACKAGE *package, LPCWSTR classid)
Definition: classes.c:291
struct list entry
Definition: msipriv.h:710

Referenced by load_given_mime().

◆ load_progid()

static MSIPROGID * load_progid ( MSIPACKAGE package,
MSIRECORD row 
)
static

Definition at line 104 of file classes.c.

105{
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}
#define FIXME(fmt,...)
Definition: debug.h:111
r parent
Definition: btrfs.c:3010

Referenced by load_given_progid().

◆ register_appid()

static UINT register_appid ( const MSIAPPID appid,
LPCWSTR  app 
)
static

Definition at line 659 of file classes.c.

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}

Referenced by ACTION_RegisterClassInfo().

◆ register_progid()

static UINT register_progid ( const MSIPROGID progid)
static

Definition at line 964 of file classes.c.

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}
static LPCWSTR get_clsid_of_progid(const MSIPROGID *progid)
Definition: classes.c:951

Referenced by ACTION_RegisterProgIdInfo().

◆ register_verb()

static UINT register_verb ( MSIPACKAGE package,
LPCWSTR  progid,
MSICOMPONENT component,
const MSIEXTENSION extension,
MSIVERB verb,
INT Sequence 
)
static

Definition at line 1124 of file classes.c.

1127{
1128 LPWSTR keyname;
1129 HKEY key;
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));
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
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
1172 msi_free(keyname);
1173 msi_free(advertise);
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" );
1190 msi_free(keyname);
1191 }
1192 }
1193 return ERROR_SUCCESS;
1194}
WCHAR * msi_create_component_advertise_string(MSIPACKAGE *package, MSICOMPONENT *component, const WCHAR *feature)
Definition: action.c:5465
WCHAR *WINAPIV msi_build_directory_name(DWORD count,...)
Definition: action.c:2008
LONG msi_reg_set_val_multi_str(HKEY hkey, LPCWSTR name, LPCWSTR value) DECLSPEC_HIDDEN
Definition: registry.c:217
LPWSTR FullKeypath
Definition: msipriv.h:538
MSIFEATURE * Feature
Definition: msipriv.h:680
LPWSTR Feature
Definition: msipriv.h:495
LPWSTR Command
Definition: msipriv.h:704
INT Sequence
Definition: msipriv.h:703
LPWSTR Argument
Definition: msipriv.h:705
LPWSTR Verb
Definition: msipriv.h:702

Referenced by ACTION_RegisterExtensionInfo().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msi  )