- build a standard Wine list of classes instead of using an array
- use class pointers instead of array indexes
This commit is contained in:
parent
80fdebbb49
commit
a391a98a9d
|
@ -133,6 +133,7 @@ typedef struct tagMSIAPPID
|
||||||
|
|
||||||
typedef struct tagMSICLASS
|
typedef struct tagMSICLASS
|
||||||
{
|
{
|
||||||
|
struct list entry;
|
||||||
WCHAR CLSID[IDENTIFIER_SIZE]; /* Primary Key */
|
WCHAR CLSID[IDENTIFIER_SIZE]; /* Primary Key */
|
||||||
WCHAR Context[IDENTIFIER_SIZE]; /* Primary Key */
|
WCHAR Context[IDENTIFIER_SIZE]; /* Primary Key */
|
||||||
MSICOMPONENT *Component;
|
MSICOMPONENT *Component;
|
||||||
|
@ -169,7 +170,7 @@ typedef struct tagMSIPROGID
|
||||||
{
|
{
|
||||||
LPWSTR ProgID; /* Primary Key */
|
LPWSTR ProgID; /* Primary Key */
|
||||||
INT ParentIndex;
|
INT ParentIndex;
|
||||||
INT ClassIndex;
|
MSICLASS *Class;
|
||||||
LPWSTR Description;
|
LPWSTR Description;
|
||||||
LPWSTR IconPath;
|
LPWSTR IconPath;
|
||||||
/* not in the table, set during installation */
|
/* not in the table, set during installation */
|
||||||
|
@ -192,7 +193,7 @@ typedef struct tagMSIMIME
|
||||||
LPWSTR ContentType; /* Primary Key */
|
LPWSTR ContentType; /* Primary Key */
|
||||||
INT ExtensionIndex;
|
INT ExtensionIndex;
|
||||||
WCHAR CLSID[IDENTIFIER_SIZE];
|
WCHAR CLSID[IDENTIFIER_SIZE];
|
||||||
INT ClassIndex;
|
MSICLASS *Class;
|
||||||
/* not in the table, set during installation */
|
/* not in the table, set during installation */
|
||||||
BOOL InstallMe;
|
BOOL InstallMe;
|
||||||
} MSIMIME;
|
} MSIMIME;
|
||||||
|
|
|
@ -118,7 +118,7 @@ static MSIAPPID *load_given_appid( MSIPACKAGE *package, LPCWSTR name )
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT load_given_progid(MSIPACKAGE *package, LPCWSTR progid);
|
static INT load_given_progid(MSIPACKAGE *package, LPCWSTR progid);
|
||||||
static INT load_given_class(MSIPACKAGE *package, LPCWSTR classid);
|
static MSICLASS *load_given_class( MSIPACKAGE *package, LPCWSTR classid );
|
||||||
|
|
||||||
static INT load_progid(MSIPACKAGE* package, MSIRECORD *row)
|
static INT load_progid(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
{
|
{
|
||||||
|
@ -145,8 +145,8 @@ static INT load_progid(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
FIXME("Unknown parent ProgID %s\n",debugstr_w(buffer));
|
FIXME("Unknown parent ProgID %s\n",debugstr_w(buffer));
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,3);
|
buffer = MSI_RecordGetString(row,3);
|
||||||
package->progids[index].ClassIndex = load_given_class(package,buffer);
|
package->progids[index].Class = load_given_class(package,buffer);
|
||||||
if (package->progids[index].ClassIndex< 0 && buffer)
|
if (package->progids[index].Class == NULL && buffer)
|
||||||
FIXME("Unknown class %s\n",debugstr_w(buffer));
|
FIXME("Unknown class %s\n",debugstr_w(buffer));
|
||||||
|
|
||||||
package->progids[index].Description = load_dynamic_stringW(row,4);
|
package->progids[index].Description = load_dynamic_stringW(row,4);
|
||||||
|
@ -228,42 +228,37 @@ static INT load_given_progid(MSIPACKAGE *package, LPCWSTR progid)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT load_class(MSIPACKAGE* package, MSIRECORD *row)
|
static MSICLASS *load_class( MSIPACKAGE* package, MSIRECORD *row )
|
||||||
{
|
{
|
||||||
DWORD index = package->loaded_classes;
|
MSICLASS *cls;
|
||||||
DWORD sz,i;
|
DWORD sz,i;
|
||||||
LPCWSTR buffer;
|
LPCWSTR buffer;
|
||||||
|
|
||||||
/* fill in the data */
|
/* fill in the data */
|
||||||
|
|
||||||
package->loaded_classes++;
|
cls = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSICLASS) );
|
||||||
if (package->loaded_classes== 1)
|
if (!cls)
|
||||||
package->classes = HeapAlloc(GetProcessHeap(),0,sizeof(MSICLASS));
|
return NULL;
|
||||||
else
|
|
||||||
package->classes = HeapReAlloc(GetProcessHeap(),0,
|
|
||||||
package->classes, package->loaded_classes * sizeof(MSICLASS));
|
|
||||||
|
|
||||||
memset(&package->classes[index],0,sizeof(MSICLASS));
|
|
||||||
|
|
||||||
sz = IDENTIFIER_SIZE;
|
sz = IDENTIFIER_SIZE;
|
||||||
MSI_RecordGetStringW(row, 1, package->classes[index].CLSID, &sz);
|
MSI_RecordGetStringW(row, 1, cls->CLSID, &sz);
|
||||||
TRACE("loading class %s\n",debugstr_w(package->classes[index].CLSID));
|
TRACE("loading class %s\n",debugstr_w(cls->CLSID));
|
||||||
sz = IDENTIFIER_SIZE;
|
sz = IDENTIFIER_SIZE;
|
||||||
MSI_RecordGetStringW(row, 2, package->classes[index].Context, &sz);
|
MSI_RecordGetStringW(row, 2, cls->Context, &sz);
|
||||||
buffer = MSI_RecordGetString(row,3);
|
buffer = MSI_RecordGetString(row,3);
|
||||||
package->classes[index].Component = get_loaded_component(package, buffer);
|
cls->Component = get_loaded_component(package, buffer);
|
||||||
|
|
||||||
package->classes[index].ProgIDText = load_dynamic_stringW(row,4);
|
cls->ProgIDText = load_dynamic_stringW(row,4);
|
||||||
package->classes[index].ProgIDIndex =
|
cls->ProgIDIndex =
|
||||||
load_given_progid(package, package->classes[index].ProgIDText);
|
load_given_progid(package, cls->ProgIDText);
|
||||||
|
|
||||||
package->classes[index].Description = load_dynamic_stringW(row,5);
|
cls->Description = load_dynamic_stringW(row,5);
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,6);
|
buffer = MSI_RecordGetString(row,6);
|
||||||
if (buffer)
|
if (buffer)
|
||||||
package->classes[index].AppID = load_given_appid(package, buffer);
|
cls->AppID = load_given_appid(package, buffer);
|
||||||
|
|
||||||
package->classes[index].FileTypeMask = load_dynamic_stringW(row,7);
|
cls->FileTypeMask = load_dynamic_stringW(row,7);
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,9))
|
if (!MSI_RecordIsNull(row,9))
|
||||||
{
|
{
|
||||||
|
@ -275,11 +270,11 @@ static INT load_class(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
|
|
||||||
build_icon_path(package,FileName,&FilePath);
|
build_icon_path(package,FileName,&FilePath);
|
||||||
|
|
||||||
package->classes[index].IconPath =
|
cls->IconPath =
|
||||||
HeapAlloc(GetProcessHeap(),0,(strlenW(FilePath)+5)*
|
HeapAlloc(GetProcessHeap(),0,(strlenW(FilePath)+5)*
|
||||||
sizeof(WCHAR));
|
sizeof(WCHAR));
|
||||||
|
|
||||||
sprintfW(package->classes[index].IconPath,fmt,FilePath,icon_index);
|
sprintfW(cls->IconPath,fmt,FilePath,icon_index);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(),0,FilePath);
|
HeapFree(GetProcessHeap(),0,FilePath);
|
||||||
HeapFree(GetProcessHeap(),0,FileName);
|
HeapFree(GetProcessHeap(),0,FileName);
|
||||||
|
@ -288,7 +283,7 @@ static INT load_class(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
{
|
{
|
||||||
buffer = MSI_RecordGetString(row,8);
|
buffer = MSI_RecordGetString(row,8);
|
||||||
if (buffer)
|
if (buffer)
|
||||||
build_icon_path(package,buffer,&(package->classes[index].IconPath));
|
build_icon_path(package,buffer,&(cls->IconPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,10))
|
if (!MSI_RecordIsNull(row,10))
|
||||||
|
@ -302,33 +297,33 @@ static INT load_class(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
switch(i)
|
switch(i)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
package->classes[index].DefInprocHandler = strdupW(ole2);
|
cls->DefInprocHandler = strdupW(ole2);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
package->classes[index].DefInprocHandler32 = strdupW(ole32);
|
cls->DefInprocHandler32 = strdupW(ole32);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
package->classes[index].DefInprocHandler = strdupW(ole2);
|
cls->DefInprocHandler = strdupW(ole2);
|
||||||
package->classes[index].DefInprocHandler32 = strdupW(ole32);
|
cls->DefInprocHandler32 = strdupW(ole32);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
package->classes[index].DefInprocHandler32 = load_dynamic_stringW(
|
cls->DefInprocHandler32 = load_dynamic_stringW(
|
||||||
row, 10);
|
row, 10);
|
||||||
reduce_to_longfilename(package->classes[index].DefInprocHandler32);
|
reduce_to_longfilename(cls->DefInprocHandler32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer = MSI_RecordGetString(row,11);
|
buffer = MSI_RecordGetString(row,11);
|
||||||
deformat_string(package,buffer,&package->classes[index].Argument);
|
deformat_string(package,buffer,&cls->Argument);
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,12);
|
buffer = MSI_RecordGetString(row,12);
|
||||||
package->classes[index].Feature = get_loaded_feature(package,buffer);
|
cls->Feature = get_loaded_feature(package,buffer);
|
||||||
|
|
||||||
package->classes[index].Attributes = MSI_RecordGetInteger(row,13);
|
cls->Attributes = MSI_RecordGetInteger(row,13);
|
||||||
|
|
||||||
return index;
|
return cls;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -337,36 +332,36 @@ static INT load_class(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
* all of the classes we need to make sure we do not ignore rows
|
* all of the classes we need to make sure we do not ignore rows
|
||||||
* with other Context and ComponentIndexs
|
* with other Context and ComponentIndexs
|
||||||
*/
|
*/
|
||||||
static INT load_given_class(MSIPACKAGE *package, LPCWSTR classid)
|
static MSICLASS *load_given_class(MSIPACKAGE *package, LPCWSTR classid)
|
||||||
{
|
{
|
||||||
INT rc;
|
MSICLASS *cls;
|
||||||
MSIRECORD *row;
|
MSIRECORD *row;
|
||||||
INT i;
|
|
||||||
static const WCHAR ExecSeqQuery[] =
|
static const WCHAR ExecSeqQuery[] =
|
||||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
'`','C','l','a','s','s','`',' ','W','H','E','R','E',' ',
|
'`','C','l','a','s','s','`',' ','W','H','E','R','E',' ',
|
||||||
'`','C','L','S','I','D','`',' ','=',' ','\'','%','s','\'',0};
|
'`','C','L','S','I','D','`',' ','=',' ','\'','%','s','\'',0};
|
||||||
|
|
||||||
|
|
||||||
if (!classid)
|
if (!classid)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
/* check for classes already loaded */
|
/* check for classes already loaded */
|
||||||
for (i = 0; i < package->loaded_classes; i++)
|
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
|
||||||
if (strcmpiW(package->classes[i].CLSID,classid)==0)
|
|
||||||
{
|
{
|
||||||
TRACE("found class %s at index %i\n",debugstr_w(classid), i);
|
if (lstrcmpiW( cls->CLSID, classid )==0)
|
||||||
return i;
|
{
|
||||||
|
TRACE("found class %s (%p)\n",debugstr_w(classid), cls);
|
||||||
|
return cls;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, classid);
|
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, classid);
|
||||||
if (!row)
|
if (!row)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
rc = load_class(package, row);
|
cls = load_class(package, row);
|
||||||
msiobj_release(&row->hdr);
|
msiobj_release(&row->hdr);
|
||||||
|
|
||||||
return rc;
|
return cls;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT load_given_extension(MSIPACKAGE *package, LPCWSTR extension);
|
static INT load_given_extension(MSIPACKAGE *package, LPCWSTR extension);
|
||||||
|
@ -398,7 +393,7 @@ static INT load_mime(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
|
|
||||||
sz = IDENTIFIER_SIZE;
|
sz = IDENTIFIER_SIZE;
|
||||||
MSI_RecordGetStringW(row,3,package->mimes[index].CLSID,&sz);
|
MSI_RecordGetStringW(row,3,package->mimes[index].CLSID,&sz);
|
||||||
package->mimes[index].ClassIndex= load_given_class(package,
|
package->mimes[index].Class = load_given_class(package,
|
||||||
package->mimes[index].CLSID);
|
package->mimes[index].CLSID);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
@ -571,7 +566,7 @@ static UINT iterate_all_classes(MSIRECORD *rec, LPVOID param)
|
||||||
LPCWSTR context;
|
LPCWSTR context;
|
||||||
LPCWSTR buffer;
|
LPCWSTR buffer;
|
||||||
MSIPACKAGE* package =(MSIPACKAGE*)param;
|
MSIPACKAGE* package =(MSIPACKAGE*)param;
|
||||||
INT i;
|
MSICLASS *cls;
|
||||||
BOOL match = FALSE;
|
BOOL match = FALSE;
|
||||||
|
|
||||||
clsid = MSI_RecordGetString(rec,1);
|
clsid = MSI_RecordGetString(rec,1);
|
||||||
|
@ -579,13 +574,13 @@ static UINT iterate_all_classes(MSIRECORD *rec, LPVOID param)
|
||||||
buffer = MSI_RecordGetString(rec,3);
|
buffer = MSI_RecordGetString(rec,3);
|
||||||
comp = get_loaded_component(package,buffer);
|
comp = get_loaded_component(package,buffer);
|
||||||
|
|
||||||
for (i = 0; i < package->loaded_classes; i++)
|
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
|
||||||
{
|
{
|
||||||
if (strcmpiW(clsid,package->classes[i].CLSID))
|
if (strcmpiW( clsid, cls->CLSID ))
|
||||||
continue;
|
continue;
|
||||||
if (strcmpW(context,package->classes[i].Context))
|
if (strcmpW( context, cls->Context ))
|
||||||
continue;
|
continue;
|
||||||
if (comp == package->classes[i].Component)
|
if (comp == cls->Component)
|
||||||
{
|
{
|
||||||
match = TRUE;
|
match = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -740,7 +735,8 @@ static void load_classes_and_such(MSIPACKAGE *package)
|
||||||
TRACE("Loading all the class info and related tables\n");
|
TRACE("Loading all the class info and related tables\n");
|
||||||
|
|
||||||
/* check if already loaded */
|
/* check if already loaded */
|
||||||
if (package->classes || package->extensions || package->progids ||
|
if (!list_empty( &package->classes ) ||
|
||||||
|
package->extensions || package->progids ||
|
||||||
package->verbs || package->mimes)
|
package->verbs || package->mimes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -887,7 +883,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
static const WCHAR szFileType_fmt[] = {'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0};
|
static const WCHAR szFileType_fmt[] = {'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0};
|
||||||
HKEY hkey,hkey2,hkey3;
|
HKEY hkey,hkey2,hkey3;
|
||||||
BOOL install_on_demand = FALSE;
|
BOOL install_on_demand = FALSE;
|
||||||
int i;
|
MSICLASS *cls;
|
||||||
|
|
||||||
if (!package)
|
if (!package)
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
@ -902,7 +898,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
* check, and i am told our builtin OLE does not support it
|
* check, and i am told our builtin OLE does not support it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < package->loaded_classes; i++)
|
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
|
||||||
{
|
{
|
||||||
MSICOMPONENT *comp;
|
MSICOMPONENT *comp;
|
||||||
MSIFILE *file;
|
MSIFILE *file;
|
||||||
|
@ -910,11 +906,11 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
LPWSTR argument;
|
LPWSTR argument;
|
||||||
MSIFEATURE *feature;
|
MSIFEATURE *feature;
|
||||||
|
|
||||||
comp = package->classes[i].Component;
|
comp = cls->Component;
|
||||||
if ( !comp )
|
if ( !comp )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
feature = package->classes[i].Feature;
|
feature = cls->Feature;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* yes. MSDN says that these are based on _Feature_ not on
|
* yes. MSDN says that these are based on _Feature_ not on
|
||||||
|
@ -925,34 +921,32 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )))
|
ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )))
|
||||||
{
|
{
|
||||||
TRACE("Skipping class %s reg due to disabled feature %s\n",
|
TRACE("Skipping class %s reg due to disabled feature %s\n",
|
||||||
debugstr_w(package->classes[i].CLSID),
|
debugstr_w(cls->CLSID),
|
||||||
debugstr_w(feature->Feature));
|
debugstr_w(feature->Feature));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Registering index %i class %s\n",i,
|
TRACE("Registering class %s (%p)\n", debugstr_w(cls->CLSID), cls);
|
||||||
debugstr_w(package->classes[i].CLSID));
|
|
||||||
|
|
||||||
package->classes[i].Installed = TRUE;
|
cls->Installed = TRUE;
|
||||||
if (package->classes[i].ProgIDIndex >= 0)
|
if (cls->ProgIDIndex >= 0)
|
||||||
mark_progid_for_install(package, package->classes[i].ProgIDIndex);
|
mark_progid_for_install( package, cls->ProgIDIndex );
|
||||||
|
|
||||||
RegCreateKeyW(hkey,package->classes[i].CLSID,&hkey2);
|
RegCreateKeyW( hkey, cls->CLSID, &hkey2 );
|
||||||
|
|
||||||
if (package->classes[i].Description)
|
if (cls->Description)
|
||||||
RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)package->classes[i].
|
RegSetValueExW( hkey2, NULL, 0, REG_SZ, (LPBYTE)cls->Description,
|
||||||
Description, (strlenW(package->classes[i].
|
(strlenW(cls->Description)+1)*sizeof(WCHAR));
|
||||||
Description)+1)*sizeof(WCHAR));
|
|
||||||
|
|
||||||
RegCreateKeyW(hkey2,package->classes[i].Context,&hkey3);
|
RegCreateKeyW( hkey2, cls->Context, &hkey3 );
|
||||||
file = get_loaded_file( package, comp->KeyPath );
|
file = get_loaded_file( package, comp->KeyPath );
|
||||||
|
|
||||||
|
|
||||||
/* the context server is a short path name
|
/* the context server is a short path name
|
||||||
* except for if it is InprocServer32...
|
* except for if it is InprocServer32...
|
||||||
*/
|
*/
|
||||||
if (strcmpiW(package->classes[i].Context,szInprocServer32)!=0)
|
if (strcmpiW( cls->Context, szInprocServer32 )!=0)
|
||||||
{
|
{
|
||||||
sz = 0;
|
sz = 0;
|
||||||
sz = GetShortPathNameW( file->TargetPath, NULL, 0 );
|
sz = GetShortPathNameW( file->TargetPath, NULL, 0 );
|
||||||
|
@ -965,20 +959,19 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
{
|
{
|
||||||
size = sz * sizeof(WCHAR);
|
size = sz * sizeof(WCHAR);
|
||||||
|
|
||||||
if (package->classes[i].Argument)
|
if (cls->Argument)
|
||||||
{
|
{
|
||||||
size += strlenW(package->classes[i].Argument) *
|
size += strlenW(cls->Argument) * sizeof(WCHAR);
|
||||||
sizeof(WCHAR);
|
|
||||||
size += sizeof(WCHAR);
|
size += sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
|
argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
|
||||||
GetShortPathNameW( file->TargetPath, argument, sz );
|
GetShortPathNameW( file->TargetPath, argument, sz );
|
||||||
|
|
||||||
if (package->classes[i].Argument)
|
if (cls->Argument)
|
||||||
{
|
{
|
||||||
strcatW(argument,szSpace);
|
strcatW(argument,szSpace);
|
||||||
strcatW(argument,package->classes[i].Argument);
|
strcatW( argument, cls->Argument );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -986,19 +979,19 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
{
|
{
|
||||||
size = lstrlenW( file->TargetPath ) * sizeof(WCHAR);
|
size = lstrlenW( file->TargetPath ) * sizeof(WCHAR);
|
||||||
|
|
||||||
if (package->classes[i].Argument)
|
if (cls->Argument)
|
||||||
{
|
{
|
||||||
size += strlenW(package->classes[i].Argument) * sizeof(WCHAR);
|
size += strlenW(cls->Argument) * sizeof(WCHAR);
|
||||||
size += sizeof(WCHAR);
|
size += sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
|
argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
|
||||||
strcpyW( argument, file->TargetPath );
|
strcpyW( argument, file->TargetPath );
|
||||||
|
|
||||||
if (package->classes[i].Argument)
|
if (cls->Argument)
|
||||||
{
|
{
|
||||||
strcatW(argument,szSpace);
|
strcatW(argument,szSpace);
|
||||||
strcatW(argument,package->classes[i].Argument);
|
strcatW( argument, cls->Argument );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1010,29 +1003,25 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
|
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
|
|
||||||
if (package->classes[i].ProgIDIndex >= 0 ||
|
if (cls->ProgIDIndex >= 0 || cls->ProgIDText)
|
||||||
package->classes[i].ProgIDText)
|
|
||||||
{
|
{
|
||||||
LPCWSTR progid;
|
LPCWSTR progid;
|
||||||
|
|
||||||
if (package->classes[i].ProgIDIndex >= 0)
|
if (cls->ProgIDIndex >= 0)
|
||||||
progid = package->progids[
|
progid = package->progids[cls->ProgIDIndex].ProgID;
|
||||||
package->classes[i].ProgIDIndex].ProgID;
|
|
||||||
else
|
else
|
||||||
progid = package->classes[i].ProgIDText;
|
progid = cls->ProgIDText;
|
||||||
|
|
||||||
RegCreateKeyW(hkey2,szProgID,&hkey3);
|
RegCreateKeyW(hkey2,szProgID,&hkey3);
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)progid,
|
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)progid,
|
||||||
(strlenW(progid)+1) *sizeof(WCHAR));
|
(strlenW(progid)+1) *sizeof(WCHAR));
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
|
|
||||||
if (package->classes[i].ProgIDIndex >= 0 &&
|
if (cls->ProgIDIndex >= 0 &&
|
||||||
package->progids[package->classes[i].ProgIDIndex].
|
package->progids[cls->ProgIDIndex].VersionIndIndex >= 0)
|
||||||
VersionIndIndex >= 0)
|
|
||||||
{
|
{
|
||||||
LPWSTR viprogid = strdupW(package->progids[package->progids[
|
LPWSTR viprogid = strdupW(package->progids[package->progids[
|
||||||
package->classes[i].ProgIDIndex].VersionIndIndex].
|
cls->ProgIDIndex].VersionIndIndex].ProgID);
|
||||||
ProgID);
|
|
||||||
RegCreateKeyW(hkey2,szVIProgID,&hkey3);
|
RegCreateKeyW(hkey2,szVIProgID,&hkey3);
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)viprogid,
|
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)viprogid,
|
||||||
(strlenW(viprogid)+1) *sizeof(WCHAR));
|
(strlenW(viprogid)+1) *sizeof(WCHAR));
|
||||||
|
@ -1041,77 +1030,71 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->classes[i].AppID)
|
if (cls->AppID)
|
||||||
{
|
{
|
||||||
MSIAPPID *appid = package->classes[i].AppID;
|
MSIAPPID *appid = cls->AppID;
|
||||||
|
|
||||||
RegSetValueExW( hkey2, szAppID, 0, REG_SZ, (LPBYTE)appid->AppID,
|
RegSetValueExW( hkey2, szAppID, 0, REG_SZ, (LPBYTE)appid->AppID,
|
||||||
(lstrlenW(appid->AppID)+1)*sizeof(WCHAR) );
|
(lstrlenW(appid->AppID)+1)*sizeof(WCHAR) );
|
||||||
|
|
||||||
register_appid( appid, package->classes[i].Description );
|
register_appid( appid, cls->Description );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->classes[i].IconPath)
|
if (cls->IconPath)
|
||||||
{
|
{
|
||||||
static const WCHAR szDefaultIcon[] =
|
static const WCHAR szDefaultIcon[] =
|
||||||
{'D','e','f','a','u','l','t','I','c','o','n',0};
|
{'D','e','f','a','u','l','t','I','c','o','n',0};
|
||||||
|
|
||||||
RegCreateKeyW(hkey2,szDefaultIcon,&hkey3);
|
RegCreateKeyW(hkey2,szDefaultIcon,&hkey3);
|
||||||
|
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,
|
RegSetValueExW( hkey3, NULL, 0, REG_SZ, (LPVOID)cls->IconPath,
|
||||||
(LPVOID)package->classes[i].IconPath,
|
(strlenW(cls->IconPath)+1) * sizeof(WCHAR));
|
||||||
(strlenW(package->classes[i].IconPath)+1) *
|
|
||||||
sizeof(WCHAR));
|
|
||||||
|
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->classes[i].DefInprocHandler)
|
if (cls->DefInprocHandler)
|
||||||
{
|
{
|
||||||
static const WCHAR szInproc[] =
|
static const WCHAR szInproc[] =
|
||||||
{'I','n','p','r','o','c','H','a','n','d','l','e','r',0};
|
{'I','n','p','r','o','c','H','a','n','d','l','e','r',0};
|
||||||
|
|
||||||
size = (strlenW(package->classes[i].DefInprocHandler) + 1) *
|
size = (strlenW(cls->DefInprocHandler) + 1) * sizeof(WCHAR);
|
||||||
sizeof(WCHAR);
|
|
||||||
RegCreateKeyW(hkey2,szInproc,&hkey3);
|
RegCreateKeyW(hkey2,szInproc,&hkey3);
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,
|
RegSetValueExW(hkey3,NULL,0,REG_SZ,
|
||||||
(LPVOID)package->classes[i].DefInprocHandler, size);
|
(LPBYTE)cls->DefInprocHandler, size);
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->classes[i].DefInprocHandler32)
|
if (cls->DefInprocHandler32)
|
||||||
{
|
{
|
||||||
static const WCHAR szInproc32[] =
|
static const WCHAR szInproc32[] =
|
||||||
{'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',
|
{'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',
|
||||||
0};
|
0};
|
||||||
size = (strlenW(package->classes[i].DefInprocHandler32) + 1) *
|
size = (strlenW(cls->DefInprocHandler32) + 1) * sizeof(WCHAR);
|
||||||
sizeof(WCHAR);
|
|
||||||
|
|
||||||
RegCreateKeyW(hkey2,szInproc32,&hkey3);
|
RegCreateKeyW(hkey2,szInproc32,&hkey3);
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,
|
RegSetValueExW(hkey3,NULL,0,REG_SZ,
|
||||||
(LPVOID)package->classes[i].DefInprocHandler32,size);
|
(LPBYTE)cls->DefInprocHandler32,size);
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hkey2);
|
RegCloseKey(hkey2);
|
||||||
|
|
||||||
/* if there is a FileTypeMask, register the FileType */
|
/* if there is a FileTypeMask, register the FileType */
|
||||||
if (package->classes[i].FileTypeMask)
|
if (cls->FileTypeMask)
|
||||||
{
|
{
|
||||||
LPWSTR ptr, ptr2;
|
LPWSTR ptr, ptr2;
|
||||||
LPWSTR keyname;
|
LPWSTR keyname;
|
||||||
INT index = 0;
|
INT index = 0;
|
||||||
ptr = package->classes[i].FileTypeMask;
|
ptr = cls->FileTypeMask;
|
||||||
while (ptr && *ptr)
|
while (ptr && *ptr)
|
||||||
{
|
{
|
||||||
ptr2 = strchrW(ptr,';');
|
ptr2 = strchrW(ptr,';');
|
||||||
if (ptr2)
|
if (ptr2)
|
||||||
*ptr2 = 0;
|
*ptr2 = 0;
|
||||||
keyname = HeapAlloc(GetProcessHeap(),0,(strlenW(szFileType_fmt)+
|
keyname = HeapAlloc(GetProcessHeap(),0,(strlenW(szFileType_fmt)+
|
||||||
strlenW(package->classes[i].CLSID) + 4)
|
strlenW(cls->CLSID) + 4) * sizeof(WCHAR));
|
||||||
* sizeof(WCHAR));
|
sprintfW( keyname, szFileType_fmt, cls->CLSID, index );
|
||||||
sprintfW(keyname,szFileType_fmt, package->classes[i].CLSID,
|
|
||||||
index);
|
|
||||||
|
|
||||||
RegCreateKeyW(HKEY_CLASSES_ROOT,keyname,&hkey2);
|
RegCreateKeyW(HKEY_CLASSES_ROOT,keyname,&hkey2);
|
||||||
RegSetValueExW(hkey2,NULL,0,REG_SZ, (LPVOID)ptr,
|
RegSetValueExW(hkey2,NULL,0,REG_SZ, (LPVOID)ptr,
|
||||||
|
@ -1130,7 +1113,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
|
|
||||||
uirow = MSI_CreateRecord(1);
|
uirow = MSI_CreateRecord(1);
|
||||||
|
|
||||||
MSI_RecordSetStringW(uirow,1,package->classes[i].CLSID);
|
MSI_RecordSetStringW( uirow, 1, cls->CLSID );
|
||||||
ui_actiondata(package,szRegisterClassInfo,uirow);
|
ui_actiondata(package,szRegisterClassInfo,uirow);
|
||||||
msiobj_release(&uirow->hdr);
|
msiobj_release(&uirow->hdr);
|
||||||
}
|
}
|
||||||
|
@ -1157,16 +1140,14 @@ static UINT register_progid_base(MSIPACKAGE* package, MSIPROGID* progid,
|
||||||
sizeof(WCHAR));
|
sizeof(WCHAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progid->ClassIndex >= 0)
|
if (progid->Class)
|
||||||
{
|
{
|
||||||
RegCreateKeyW(hkey,szCLSID,&hkey2);
|
RegCreateKeyW(hkey,szCLSID,&hkey2);
|
||||||
RegSetValueExW(hkey2,NULL,0,REG_SZ,
|
RegSetValueExW( hkey2, NULL, 0, REG_SZ, (LPBYTE)progid->Class->CLSID,
|
||||||
(LPVOID)package->classes[progid->ClassIndex].CLSID,
|
(strlenW(progid->Class->CLSID)+1) * sizeof(WCHAR) );
|
||||||
(strlenW(package->classes[progid->ClassIndex].CLSID)+1)
|
|
||||||
* sizeof(WCHAR));
|
|
||||||
|
|
||||||
if (clsid)
|
if (clsid)
|
||||||
strcpyW(clsid,package->classes[progid->ClassIndex].CLSID);
|
strcpyW( clsid, progid->Class->CLSID );
|
||||||
|
|
||||||
RegCloseKey(hkey2);
|
RegCloseKey(hkey2);
|
||||||
}
|
}
|
||||||
|
@ -1273,8 +1254,8 @@ UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)
|
||||||
|
|
||||||
/* check if this progid is to be installed */
|
/* check if this progid is to be installed */
|
||||||
package->progids[i].InstallMe = ((package->progids[i].InstallMe) ||
|
package->progids[i].InstallMe = ((package->progids[i].InstallMe) ||
|
||||||
(package->progids[i].ClassIndex >= 0 &&
|
(package->progids[i].Class &&
|
||||||
package->classes[package->progids[i].ClassIndex].Installed));
|
package->progids[i].Class->Installed));
|
||||||
|
|
||||||
if (!package->progids[i].InstallMe)
|
if (!package->progids[i].InstallMe)
|
||||||
{
|
{
|
||||||
|
@ -1536,8 +1517,8 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package)
|
||||||
* extension or Class
|
* extension or Class
|
||||||
*/
|
*/
|
||||||
package->mimes[i].InstallMe = ((package->mimes[i].InstallMe) ||
|
package->mimes[i].InstallMe = ((package->mimes[i].InstallMe) ||
|
||||||
(package->mimes[i].ClassIndex >= 0 &&
|
(package->mimes[i].Class &&
|
||||||
package->classes[package->mimes[i].ClassIndex].Installed) ||
|
package->mimes[i].Class->Installed) ||
|
||||||
(package->mimes[i].ExtensionIndex >=0 &&
|
(package->mimes[i].ExtensionIndex >=0 &&
|
||||||
package->extensions[package->mimes[i].ExtensionIndex].Installed));
|
package->extensions[package->mimes[i].ExtensionIndex].Installed));
|
||||||
|
|
||||||
|
|
|
@ -486,19 +486,19 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up extension, progid, class and verb structures */
|
/* clean up extension, progid, class and verb structures */
|
||||||
for (i = 0; i < package->loaded_classes; i++)
|
LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(),0,package->classes[i].Description);
|
MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry );
|
||||||
HeapFree(GetProcessHeap(),0,package->classes[i].FileTypeMask);
|
|
||||||
HeapFree(GetProcessHeap(),0,package->classes[i].IconPath);
|
|
||||||
HeapFree(GetProcessHeap(),0,package->classes[i].DefInprocHandler);
|
|
||||||
HeapFree(GetProcessHeap(),0,package->classes[i].DefInprocHandler32);
|
|
||||||
HeapFree(GetProcessHeap(),0,package->classes[i].Argument);
|
|
||||||
HeapFree(GetProcessHeap(),0,package->classes[i].ProgIDText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (package->classes && package->loaded_classes > 0)
|
list_remove( &cls->entry );
|
||||||
HeapFree(GetProcessHeap(),0,package->classes);
|
HeapFree( GetProcessHeap(), 0, cls->Description );
|
||||||
|
HeapFree( GetProcessHeap(), 0, cls->FileTypeMask );
|
||||||
|
HeapFree( GetProcessHeap(), 0, cls->IconPath );
|
||||||
|
HeapFree( GetProcessHeap(), 0, cls->DefInprocHandler );
|
||||||
|
HeapFree( GetProcessHeap(), 0, cls->DefInprocHandler32 );
|
||||||
|
HeapFree( GetProcessHeap(), 0, cls->Argument );
|
||||||
|
HeapFree( GetProcessHeap(), 0, cls->ProgIDText );
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < package->loaded_extensions; i++)
|
for (i = 0; i < package->loaded_extensions; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -192,8 +192,7 @@ typedef struct tagMSIPACKAGE
|
||||||
LPWSTR ActionFormat;
|
LPWSTR ActionFormat;
|
||||||
LPWSTR LastAction;
|
LPWSTR LastAction;
|
||||||
|
|
||||||
struct tagMSICLASS *classes;
|
struct list classes;
|
||||||
UINT loaded_classes;
|
|
||||||
struct tagMSIEXTENSION *extensions;
|
struct tagMSIEXTENSION *extensions;
|
||||||
UINT loaded_extensions;
|
UINT loaded_extensions;
|
||||||
struct tagMSIPROGID *progids;
|
struct tagMSIPROGID *progids;
|
||||||
|
|
|
@ -387,6 +387,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
|
||||||
package->next_dialog = NULL;
|
package->next_dialog = NULL;
|
||||||
list_init( &package->subscriptions );
|
list_init( &package->subscriptions );
|
||||||
list_init( &package->appids );
|
list_init( &package->appids );
|
||||||
|
list_init( &package->classes );
|
||||||
|
|
||||||
/* OK, here is where we do a slew of things to the database to
|
/* OK, here is where we do a slew of things to the database to
|
||||||
* prep for all that is to come as a package */
|
* prep for all that is to come as a package */
|
||||||
|
|
Loading…
Reference in New Issue