sync msi to wine 1.1.39

svn path=/trunk/; revision=45738
This commit is contained in:
Christoph von Wittich 2010-03-01 12:01:30 +00:00
parent 764beadd15
commit b7a1c59029
19 changed files with 836 additions and 279 deletions

View file

@ -886,10 +886,24 @@ static BOOL ACTION_HandleCustomAction( MSIPACKAGE* package, LPCWSTR action,
static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
LPCWSTR dir; LPCWSTR dir, component;
LPWSTR full_path; LPWSTR full_path;
MSIRECORD *uirow; MSIRECORD *uirow;
MSIFOLDER *folder; MSIFOLDER *folder;
MSICOMPONENT *comp;
component = MSI_RecordGetString(row, 2);
comp = get_loaded_component(package, component);
if (!comp)
return ERROR_SUCCESS;
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
comp->Action = comp->Installed;
return ERROR_SUCCESS;
}
comp->Action = INSTALLSTATE_LOCAL;
dir = MSI_RecordGetString(row,1); dir = MSI_RecordGetString(row,1);
if (!dir) if (!dir)
@ -951,7 +965,7 @@ UINT msi_create_component_directories( MSIPACKAGE *package )
/* create all the folders required by the components are going to install */ /* create all the folders required by the components are going to install */
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{ {
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL)) if (comp->ActionRequest != INSTALLSTATE_LOCAL)
continue; continue;
msi_create_directory( package, comp->Directory ); msi_create_directory( package, comp->Directory );
} }
@ -983,10 +997,24 @@ static UINT ACTION_CreateFolders(MSIPACKAGE *package)
static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param )
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
LPCWSTR dir; LPCWSTR dir, component;
LPWSTR full_path; LPWSTR full_path;
MSIRECORD *uirow; MSIRECORD *uirow;
MSIFOLDER *folder; MSIFOLDER *folder;
MSICOMPONENT *comp;
component = MSI_RecordGetString(row, 2);
comp = get_loaded_component(package, component);
if (!comp)
return ERROR_SUCCESS;
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
comp->Action = comp->Installed;
return ERROR_SUCCESS;
}
comp->Action = INSTALLSTATE_ABSENT;
dir = MSI_RecordGetString( row, 1 ); dir = MSI_RecordGetString( row, 1 );
if (!dir) if (!dir)
@ -2231,16 +2259,12 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
if (!comp) if (!comp)
return ERROR_SUCCESS; return ERROR_SUCCESS;
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL)) if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{ {
TRACE("Skipping write due to disabled component %s\n", TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
debugstr_w(component));
comp->Action = comp->Installed; comp->Action = comp->Installed;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
comp->Action = INSTALLSTATE_LOCAL; comp->Action = INSTALLSTATE_LOCAL;
name = MSI_RecordGetString(row, 4); name = MSI_RecordGetString(row, 4);
@ -2623,7 +2647,7 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
{ {
ComponentList *cl; ComponentList *cl;
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL )) if (feature->ActionRequest != INSTALLSTATE_LOCAL)
continue; continue;
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
@ -2638,7 +2662,7 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
{ {
ComponentList *cl; ComponentList *cl;
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ABSENT )) if (feature->ActionRequest != INSTALLSTATE_ABSENT)
continue; continue;
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
@ -2704,8 +2728,8 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
debugstr_w(comp->FullKeypath), debugstr_w(comp->FullKeypath),
comp->RefCount); comp->RefCount);
if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL) || if (comp->ActionRequest == INSTALLSTATE_LOCAL ||
ACTION_VerifyComponentForAction( comp, INSTALLSTATE_SOURCE)) comp->ActionRequest == INSTALLSTATE_SOURCE)
{ {
if (!comp->FullKeypath) if (!comp->FullKeypath)
continue; continue;
@ -2771,7 +2795,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
} }
RegCloseKey(hkey); RegCloseKey(hkey);
} }
else if (ACTION_VerifyComponentForAction(comp, INSTALLSTATE_ABSENT)) else if (comp->ActionRequest == INSTALLSTATE_ABSENT)
{ {
if (package->Context == MSIINSTALLCONTEXT_MACHINE) if (package->Context == MSIINSTALLCONTEXT_MACHINE)
MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid); MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid);
@ -2862,28 +2886,25 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
HMODULE module; HMODULE module;
HRESULT hr; HRESULT hr;
static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
component = MSI_RecordGetString(row,3); component = MSI_RecordGetString(row,3);
comp = get_loaded_component(package,component); comp = get_loaded_component(package,component);
if (!comp) if (!comp)
return ERROR_SUCCESS; return ERROR_SUCCESS;
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL)) if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{ {
TRACE("Skipping typelib reg due to disabled component\n"); TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
comp->Action = comp->Installed; comp->Action = comp->Installed;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
comp->Action = INSTALLSTATE_LOCAL; comp->Action = INSTALLSTATE_LOCAL;
file = get_loaded_file( package, comp->KeyPath ); file = get_loaded_file( package, comp->KeyPath );
if (!file) if (!file)
return ERROR_SUCCESS; return ERROR_SUCCESS;
ui_actiondata( package, szRegisterTypeLibraries, row );
module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE ); module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE );
if (module) if (module)
{ {
@ -2913,11 +2934,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
ERR("Failed to register type library %s\n", ERR("Failed to register type library %s\n",
debugstr_w(tl_struct.path)); debugstr_w(tl_struct.path));
else else
{
ui_actiondata(package,szRegisterTypeLibraries,row);
TRACE("Registered %s\n", debugstr_w(tl_struct.path)); TRACE("Registered %s\n", debugstr_w(tl_struct.path));
}
ITypeLib_Release(tl_struct.ptLib); ITypeLib_Release(tl_struct.ptLib);
msi_free(tl_struct.path); msi_free(tl_struct.path);
@ -2935,7 +2952,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
if (FAILED(hr)) if (FAILED(hr))
{ {
ERR("Failed to load type library: %08x\n", hr); ERR("Failed to load type library: %08x\n", hr);
return ERROR_FUNCTION_FAILED; return ERROR_INSTALL_FAILURE;
} }
ITypeLib_Release(tlib); ITypeLib_Release(tlib);
@ -2967,31 +2984,119 @@ static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
return rc; return rc;
} }
static UINT ITERATE_UnregisterTypeLibraries( MSIRECORD *row, LPVOID param )
{
MSIPACKAGE *package = param;
LPCWSTR component, guid;
MSICOMPONENT *comp;
GUID libid;
UINT version;
LCID language;
SYSKIND syskind;
HRESULT hr;
component = MSI_RecordGetString( row, 3 );
comp = get_loaded_component( package, component );
if (!comp)
return ERROR_SUCCESS;
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
comp->Action = comp->Installed;
return ERROR_SUCCESS;
}
comp->Action = INSTALLSTATE_ABSENT;
ui_actiondata( package, szUnregisterTypeLibraries, row );
guid = MSI_RecordGetString( row, 1 );
CLSIDFromString( (LPWSTR)guid, &libid );
version = MSI_RecordGetInteger( row, 4 );
language = MSI_RecordGetInteger( row, 2 );
#ifdef _WIN64
syskind = SYS_WIN64;
#else
syskind = SYS_WIN32;
#endif
hr = UnRegisterTypeLib( &libid, (version >> 8) & 0xffff, version & 0xff, language, syskind );
if (FAILED(hr))
{
WARN("Failed to unregister typelib: %08x\n", hr);
}
return ERROR_SUCCESS;
}
static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
{
UINT rc;
MSIQUERY *view;
static const WCHAR query[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','T','y','p','e','L','i','b','`',0};
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords( view, NULL, ITERATE_UnregisterTypeLibraries, package );
msiobj_release( &view->hdr );
return rc;
}
static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row )
{
static const WCHAR szlnk[] = {'.','l','n','k',0};
LPCWSTR directory, extension;
LPWSTR link_folder, link_file, filename;
directory = MSI_RecordGetString( row, 2 );
link_folder = resolve_folder( package, directory, FALSE, FALSE, TRUE, NULL );
/* may be needed because of a bug somewhere else */
create_full_pathW( link_folder );
filename = msi_dup_record_field( row, 3 );
reduce_to_longfilename( filename );
extension = strchrW( filename, '.' );
if (!extension || strcmpiW( extension, szlnk ))
{
int len = strlenW( filename );
filename = msi_realloc( filename, len * sizeof(WCHAR) + sizeof(szlnk) );
memcpy( filename + len, szlnk, sizeof(szlnk) );
}
link_file = build_directory_name( 2, link_folder, filename );
msi_free( link_folder );
msi_free( filename );
return link_file;
}
static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
LPWSTR target_file, target_folder, filename; LPWSTR link_file, deformated, path;
LPCWSTR buffer, extension; LPCWSTR component, target;
MSICOMPONENT *comp; MSICOMPONENT *comp;
static const WCHAR szlnk[]={'.','l','n','k',0};
IShellLinkW *sl = NULL; IShellLinkW *sl = NULL;
IPersistFile *pf = NULL; IPersistFile *pf = NULL;
HRESULT res; HRESULT res;
buffer = MSI_RecordGetString(row,4); component = MSI_RecordGetString(row, 4);
comp = get_loaded_component(package,buffer); comp = get_loaded_component(package, component);
if (!comp) if (!comp)
return ERROR_SUCCESS; return ERROR_SUCCESS;
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL )) if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{ {
TRACE("Skipping shortcut creation due to disabled component\n"); TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
comp->Action = comp->Installed; comp->Action = comp->Installed;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
comp->Action = INSTALLSTATE_LOCAL; comp->Action = INSTALLSTATE_LOCAL;
ui_actiondata(package,szCreateShortcuts,row); ui_actiondata(package,szCreateShortcuts,row);
@ -3012,31 +3117,10 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
goto err; goto err;
} }
buffer = MSI_RecordGetString(row,2); target = MSI_RecordGetString(row, 5);
target_folder = resolve_folder(package, buffer,FALSE,FALSE,TRUE,NULL); if (strchrW(target, '['))
/* may be needed because of a bug somewhere else */
create_full_pathW(target_folder);
filename = msi_dup_record_field( row, 3 );
reduce_to_longfilename(filename);
extension = strchrW(filename,'.');
if (!extension || strcmpiW(extension,szlnk))
{ {
int len = strlenW(filename); deformat_string(package, target, &deformated);
filename = msi_realloc(filename, len * sizeof(WCHAR) + sizeof(szlnk));
memcpy(filename + len, szlnk, sizeof(szlnk));
}
target_file = build_directory_name(2, target_folder, filename);
msi_free(target_folder);
msi_free(filename);
buffer = MSI_RecordGetString(row,5);
if (strchrW(buffer,'['))
{
LPWSTR deformated;
deformat_string(package,buffer,&deformated);
IShellLinkW_SetPath(sl,deformated); IShellLinkW_SetPath(sl,deformated);
msi_free(deformated); msi_free(deformated);
} }
@ -3048,17 +3132,16 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
if (!MSI_RecordIsNull(row,6)) if (!MSI_RecordIsNull(row,6))
{ {
LPWSTR deformated; LPCWSTR arguments = MSI_RecordGetString(row, 6);
buffer = MSI_RecordGetString(row,6); deformat_string(package, arguments, &deformated);
deformat_string(package,buffer,&deformated);
IShellLinkW_SetArguments(sl,deformated); IShellLinkW_SetArguments(sl,deformated);
msi_free(deformated); msi_free(deformated);
} }
if (!MSI_RecordIsNull(row,7)) if (!MSI_RecordIsNull(row,7))
{ {
buffer = MSI_RecordGetString(row,7); LPCWSTR description = MSI_RecordGetString(row, 7);
IShellLinkW_SetDescription(sl,buffer); IShellLinkW_SetDescription(sl, description);
} }
if (!MSI_RecordIsNull(row,8)) if (!MSI_RecordIsNull(row,8))
@ -3066,20 +3149,18 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
if (!MSI_RecordIsNull(row,9)) if (!MSI_RecordIsNull(row,9))
{ {
LPWSTR Path;
INT index; INT index;
LPCWSTR icon = MSI_RecordGetString(row, 9);
buffer = MSI_RecordGetString(row,9); path = build_icon_path(package, icon);
Path = build_icon_path(package,buffer);
index = MSI_RecordGetInteger(row,10); index = MSI_RecordGetInteger(row,10);
/* no value means 0 */ /* no value means 0 */
if (index == MSI_NULL_INTEGER) if (index == MSI_NULL_INTEGER)
index = 0; index = 0;
IShellLinkW_SetIconLocation(sl,Path,index); IShellLinkW_SetIconLocation(sl, path, index);
msi_free(Path); msi_free(path);
} }
if (!MSI_RecordIsNull(row,11)) if (!MSI_RecordIsNull(row,11))
@ -3087,18 +3168,19 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
if (!MSI_RecordIsNull(row,12)) if (!MSI_RecordIsNull(row,12))
{ {
LPWSTR Path; LPCWSTR wkdir = MSI_RecordGetString(row, 12);
buffer = MSI_RecordGetString(row,12); path = resolve_folder(package, wkdir, FALSE, FALSE, TRUE, NULL);
Path = resolve_folder(package, buffer, FALSE, FALSE, TRUE, NULL); if (path)
if (Path) IShellLinkW_SetWorkingDirectory(sl, path);
IShellLinkW_SetWorkingDirectory(sl,Path); msi_free(path);
msi_free(Path);
} }
TRACE("Writing shortcut to %s\n",debugstr_w(target_file)); link_file = get_link_file(package, row);
IPersistFile_Save(pf,target_file,FALSE);
msi_free(target_file); TRACE("Writing shortcut to %s\n", debugstr_w(link_file));
IPersistFile_Save(pf, link_file, FALSE);
msi_free(link_file);
err: err:
if (pf) if (pf)
@ -3133,6 +3215,58 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
return rc; return rc;
} }
static UINT ITERATE_RemoveShortcuts( MSIRECORD *row, LPVOID param )
{
MSIPACKAGE *package = param;
LPWSTR link_file;
LPCWSTR component;
MSICOMPONENT *comp;
component = MSI_RecordGetString( row, 4 );
comp = get_loaded_component( package, component );
if (!comp)
return ERROR_SUCCESS;
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
comp->Action = comp->Installed;
return ERROR_SUCCESS;
}
comp->Action = INSTALLSTATE_ABSENT;
ui_actiondata( package, szRemoveShortcuts, row );
link_file = get_link_file( package, row );
TRACE("Removing shortcut file %s\n", debugstr_w( link_file ));
if (!DeleteFileW( link_file ))
{
WARN("Failed to remove shortcut file %u\n", GetLastError());
}
msi_free( link_file );
return ERROR_SUCCESS;
}
static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
{
UINT rc;
MSIQUERY *view;
static const WCHAR query[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','S','h','o','r','t','c','u','t','`',0};
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveShortcuts, package );
msiobj_release( &view->hdr );
return rc;
}
static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param) static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
{ {
MSIPACKAGE* package = param; MSIPACKAGE* package = param;
@ -3510,17 +3644,15 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
component = MSI_RecordGetString(row, 8); component = MSI_RecordGetString(row, 8);
comp = get_loaded_component(package,component); comp = get_loaded_component(package,component);
if (!comp)
return ERROR_SUCCESS;
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL)) if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{ {
TRACE("Skipping ini file due to disabled component %s\n", TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
debugstr_w(component));
comp->Action = comp->Installed; comp->Action = comp->Installed;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
comp->Action = INSTALLSTATE_LOCAL; comp->Action = INSTALLSTATE_LOCAL;
identifier = MSI_RecordGetString(row,1); identifier = MSI_RecordGetString(row,1);
@ -3818,10 +3950,9 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
BOOL absent = FALSE; BOOL absent = FALSE;
MSIRECORD *uirow; MSIRECORD *uirow;
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL ) && if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_SOURCE ) && feature->ActionRequest != INSTALLSTATE_SOURCE &&
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )) feature->ActionRequest != INSTALLSTATE_ADVERTISED) absent = TRUE;
absent = TRUE;
size = 1; size = 1;
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
@ -4359,32 +4490,34 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
LPCWSTR compgroupid=NULL; LPCWSTR compgroupid, component, feature, qualifier, text;
LPCWSTR feature=NULL; LPWSTR advertise = NULL, output = NULL;
LPCWSTR text = NULL;
LPCWSTR qualifier = NULL;
LPCWSTR component = NULL;
LPWSTR advertise = NULL;
LPWSTR output = NULL;
HKEY hkey; HKEY hkey;
UINT rc = ERROR_SUCCESS; UINT rc;
MSICOMPONENT *comp; MSICOMPONENT *comp;
DWORD sz = 0; MSIFEATURE *feat;
DWORD sz;
MSIRECORD *uirow; MSIRECORD *uirow;
component = MSI_RecordGetString(rec,3); feature = MSI_RecordGetString(rec, 5);
comp = get_loaded_component(package,component); feat = get_loaded_feature(package, feature);
if (!feat)
return ERROR_SUCCESS;
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL ) && if (feat->ActionRequest != INSTALLSTATE_LOCAL &&
!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_SOURCE ) && feat->ActionRequest != INSTALLSTATE_SOURCE &&
!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_ADVERTISED )) feat->ActionRequest != INSTALLSTATE_ADVERTISED)
{ {
TRACE("Skipping: Component %s not scheduled for install\n", TRACE("Feature %s not scheduled for installation\n", debugstr_w(feature));
debugstr_w(component)); feat->Action = feat->Installed;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
component = MSI_RecordGetString(rec, 3);
comp = get_loaded_component(package, component);
if (!comp)
return ERROR_SUCCESS;
compgroupid = MSI_RecordGetString(rec,1); compgroupid = MSI_RecordGetString(rec,1);
qualifier = MSI_RecordGetString(rec,2); qualifier = MSI_RecordGetString(rec,2);
@ -4393,8 +4526,6 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
goto end; goto end;
text = MSI_RecordGetString(rec,4); text = MSI_RecordGetString(rec,4);
feature = MSI_RecordGetString(rec,5);
advertise = create_component_advertise_string(package, comp, feature); advertise = create_component_advertise_string(package, comp, feature);
sz = strlenW(advertise); sz = strlenW(advertise);
@ -4452,6 +4583,80 @@ static UINT ACTION_PublishComponents(MSIPACKAGE *package)
return rc; return rc;
} }
static UINT ITERATE_UnpublishComponent( MSIRECORD *rec, LPVOID param )
{
static const WCHAR szInstallerComponents[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'I','n','s','t','a','l','l','e','r','\\',
'C','o','m','p','o','n','e','n','t','s','\\',0};
MSIPACKAGE *package = param;
LPCWSTR compgroupid, component, feature, qualifier;
MSICOMPONENT *comp;
MSIFEATURE *feat;
MSIRECORD *uirow;
WCHAR squashed[GUID_SIZE], keypath[MAX_PATH];
LONG res;
feature = MSI_RecordGetString( rec, 5 );
feat = get_loaded_feature( package, feature );
if (!feat)
return ERROR_SUCCESS;
if (feat->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Feature %s not scheduled for removal\n", debugstr_w(feature));
feat->Action = feat->Installed;
return ERROR_SUCCESS;
}
component = MSI_RecordGetString( rec, 3 );
comp = get_loaded_component( package, component );
if (!comp)
return ERROR_SUCCESS;
compgroupid = MSI_RecordGetString( rec, 1 );
qualifier = MSI_RecordGetString( rec, 2 );
squash_guid( compgroupid, squashed );
strcpyW( keypath, szInstallerComponents );
strcatW( keypath, squashed );
res = RegDeleteKeyW( HKEY_CURRENT_USER, keypath );
if (res != ERROR_SUCCESS)
{
WARN("Unable to delete component key %d\n", res);
}
uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, compgroupid );
MSI_RecordSetStringW( uirow, 2, qualifier );
ui_actiondata( package, szUnpublishComponents, uirow );
msiobj_release( &uirow->hdr );
return ERROR_SUCCESS;
}
static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
{
UINT rc;
MSIQUERY *view;
static const WCHAR query[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','P','u','b','l','i','s','h',
'C','o','m','p','o','n','e','n','t','`',0};
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords( view, NULL, ITERATE_UnpublishComponent, package );
msiobj_release( &view->hdr );
return rc;
}
static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
@ -4597,7 +4802,7 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
MSICOMPONENT *comp; MSICOMPONENT *comp;
SC_HANDLE scm, service = NULL; SC_HANDLE scm = NULL, service = NULL;
LPCWSTR *vector = NULL; LPCWSTR *vector = NULL;
LPWSTR name, args; LPWSTR name, args;
DWORD event, numargs; DWORD event, numargs;
@ -4612,7 +4817,10 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
event = MSI_RecordGetInteger(rec, 3); event = MSI_RecordGetInteger(rec, 3);
if (!(event & msidbServiceControlEventStart)) if (!(event & msidbServiceControlEventStart))
return ERROR_SUCCESS; {
r = ERROR_SUCCESS;
goto done;
}
scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
if (!scm) if (!scm)
@ -4893,15 +5101,17 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
driver_file = msi_find_file(package, MSI_RecordGetString(rec, 4)); driver_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5)); setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));
if (!driver_file || !setup_file) if (!driver_file)
{ {
ERR("ODBC Driver entry not found!\n"); ERR("ODBC Driver entry not found!\n");
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
len = lstrlenW(desc) + lstrlenW(driver_fmt) + lstrlenW(driver_file->FileName) + len = lstrlenW(desc) + lstrlenW(driver_fmt) + lstrlenW(driver_file->FileName);
lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName) + if (setup_file)
lstrlenW(usage_fmt) + 1; len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);
len += lstrlenW(usage_fmt) + 1;
driver = msi_alloc(len * sizeof(WCHAR)); driver = msi_alloc(len * sizeof(WCHAR));
if (!driver) if (!driver)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
@ -4913,8 +5123,11 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
sprintfW(ptr, driver_fmt, driver_file->FileName); sprintfW(ptr, driver_fmt, driver_file->FileName);
ptr += lstrlenW(ptr) + 1; ptr += lstrlenW(ptr) + 1;
if (setup_file)
{
sprintfW(ptr, setup_fmt, setup_file->FileName); sprintfW(ptr, setup_fmt, setup_file->FileName);
ptr += lstrlenW(ptr) + 1; ptr += lstrlenW(ptr) + 1;
}
lstrcpyW(ptr, usage_fmt); lstrcpyW(ptr, usage_fmt);
ptr += lstrlenW(ptr) + 1; ptr += lstrlenW(ptr) + 1;
@ -4957,14 +5170,16 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
translator_file = msi_find_file(package, MSI_RecordGetString(rec, 4)); translator_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5)); setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));
if (!translator_file || !setup_file) if (!translator_file)
{ {
ERR("ODBC Translator entry not found!\n"); ERR("ODBC Translator entry not found!\n");
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
len = lstrlenW(desc) + lstrlenW(translator_fmt) + lstrlenW(translator_file->FileName) + len = lstrlenW(desc) + lstrlenW(translator_fmt) + lstrlenW(translator_file->FileName) + 1;
lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName) + 1; if (setup_file)
len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);
translator = msi_alloc(len * sizeof(WCHAR)); translator = msi_alloc(len * sizeof(WCHAR));
if (!translator) if (!translator)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
@ -4976,8 +5191,11 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
sprintfW(ptr, translator_fmt, translator_file->FileName); sprintfW(ptr, translator_fmt, translator_file->FileName);
ptr += lstrlenW(ptr) + 1; ptr += lstrlenW(ptr) + 1;
if (setup_file)
{
sprintfW(ptr, setup_fmt, setup_file->FileName); sprintfW(ptr, setup_fmt, setup_file->FileName);
ptr += lstrlenW(ptr) + 1; ptr += lstrlenW(ptr) + 1;
}
*ptr = '\0'; *ptr = '\0';
translator_path = strdupW(translator_file->TargetPath); translator_path = strdupW(translator_file->TargetPath);
@ -5021,8 +5239,8 @@ static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param )
if (!attrs) if (!attrs)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
sprintfW(attrs, attrs_fmt, desc); len = sprintfW(attrs, attrs_fmt, desc);
attrs[len - 1] = '\0'; attrs[len + 1] = 0;
if (!SQLConfigDataSourceW(NULL, request, driver, attrs)) if (!SQLConfigDataSourceW(NULL, request, driver, attrs))
{ {
@ -5076,6 +5294,120 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package )
return rc; return rc;
} }
static UINT ITERATE_RemoveODBCDriver( MSIRECORD *rec, LPVOID param )
{
DWORD usage;
LPCWSTR desc;
desc = MSI_RecordGetString( rec, 3 );
if (!SQLRemoveDriverW( desc, FALSE, &usage ))
{
WARN("Failed to remove ODBC driver\n");
}
else if (!usage)
{
FIXME("Usage count reached 0\n");
}
return ERROR_SUCCESS;
}
static UINT ITERATE_RemoveODBCTranslator( MSIRECORD *rec, LPVOID param )
{
DWORD usage;
LPCWSTR desc;
desc = MSI_RecordGetString( rec, 3 );
if (!SQLRemoveTranslatorW( desc, &usage ))
{
WARN("Failed to remove ODBC translator\n");
}
else if (!usage)
{
FIXME("Usage count reached 0\n");
}
return ERROR_SUCCESS;
}
static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param )
{
LPWSTR attrs;
LPCWSTR desc, driver;
WORD request = ODBC_REMOVE_SYS_DSN;
INT registration;
DWORD len;
static const WCHAR attrs_fmt[] = {
'D','S','N','=','%','s',0 };
desc = MSI_RecordGetString( rec, 3 );
driver = MSI_RecordGetString( rec, 4 );
registration = MSI_RecordGetInteger( rec, 5 );
if (registration == msidbODBCDataSourceRegistrationPerMachine) request = ODBC_REMOVE_SYS_DSN;
else if (registration == msidbODBCDataSourceRegistrationPerUser) request = ODBC_REMOVE_DSN;
len = strlenW( attrs_fmt ) + strlenW( desc ) + 1 + 1;
attrs = msi_alloc( len * sizeof(WCHAR) );
if (!attrs)
return ERROR_OUTOFMEMORY;
FIXME("Use ODBCSourceAttribute table\n");
len = sprintfW( attrs, attrs_fmt, desc );
attrs[len + 1] = 0;
if (!SQLConfigDataSourceW( NULL, request, driver, attrs ))
{
WARN("Failed to remove ODBC data source\n");
}
msi_free( attrs );
return ERROR_SUCCESS;
}
static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
{
UINT rc;
MSIQUERY *view;
static const WCHAR driver_query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'O','D','B','C','D','r','i','v','e','r',0 };
static const WCHAR translator_query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 };
static const WCHAR source_query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'O','D','B','C','D','a','t','a','S','o','u','r','c','e',0 };
rc = MSI_DatabaseOpenViewW( package->db, driver_query, &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDriver, package );
msiobj_release( &view->hdr );
rc = MSI_DatabaseOpenViewW( package->db, translator_query, &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCTranslator, package );
msiobj_release( &view->hdr );
rc = MSI_DatabaseOpenViewW( package->db, source_query, &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDataSource, package );
msiobj_release( &view->hdr );
return rc;
}
#define ENV_ACT_SETALWAYS 0x1 #define ENV_ACT_SETALWAYS 0x1
#define ENV_ACT_SETABSENT 0x2 #define ENV_ACT_SETABSENT 0x2
#define ENV_ACT_REMOVE 0x4 #define ENV_ACT_REMOVE 0x4
@ -6125,6 +6457,30 @@ done:
return r; return r;
} }
static UINT ACTION_ValidateProductID( MSIPACKAGE *package )
{
LPWSTR key, template, id;
UINT r = ERROR_SUCCESS;
id = msi_dup_property( package, szProductID );
if (id)
{
msi_free( id );
return ERROR_SUCCESS;
}
template = msi_dup_property( package, szPIDTemplate );
key = msi_dup_property( package, szPIDKEY );
if (key && template)
{
FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) );
r = MSI_SetPropertyW( package, szProductID, key );
}
msi_free( template );
msi_free( key );
return r;
}
static UINT ACTION_ScheduleReboot( MSIPACKAGE *package ) static UINT ACTION_ScheduleReboot( MSIPACKAGE *package )
{ {
TRACE("\n"); TRACE("\n");
@ -6132,6 +6488,24 @@ static UINT ACTION_ScheduleReboot( MSIPACKAGE *package )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package )
{
TRACE("%p\n", package);
return ERROR_SUCCESS;
}
static UINT ACTION_DisableRollback( MSIPACKAGE *package )
{
FIXME("%p\n", package);
return ERROR_SUCCESS;
}
static UINT ACTION_InstallAdminPackage( MSIPACKAGE *package )
{
FIXME("%p\n", package);
return ERROR_SUCCESS;
}
static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
LPCSTR action, LPCWSTR table ) LPCSTR action, LPCWSTR table )
{ {
@ -6156,12 +6530,6 @@ static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package )
{
TRACE("%p\n", package);
return ERROR_SUCCESS;
}
static UINT ACTION_RemoveIniValues( MSIPACKAGE *package ) static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
{ {
static const WCHAR table[] = static const WCHAR table[] =
@ -6194,13 +6562,6 @@ static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table ); return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table );
} }
static UINT ACTION_ValidateProductID( MSIPACKAGE *package )
{
static const WCHAR table[] = {
'P','r','o','d','u','c','t','I','D',0 };
return msi_unimplemented_action_stub( package, "ValidateProductID", table );
}
static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package ) static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
{ {
static const WCHAR table[] = { static const WCHAR table[] = {
@ -6215,12 +6576,6 @@ static UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table ); return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table );
} }
static UINT ACTION_UnregisterFonts( MSIPACKAGE *package )
{
static const WCHAR table[] = { 'F','o','n','t',0 };
return msi_unimplemented_action_stub( package, "UnregisterFonts", table );
}
static UINT ACTION_RMCCPSearch( MSIPACKAGE *package ) static UINT ACTION_RMCCPSearch( MSIPACKAGE *package )
{ {
static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 }; static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 };
@ -6257,36 +6612,18 @@ static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table ); return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table );
} }
static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
{
static const WCHAR table[] = { 'O','D','B','C','D','r','i','v','e','r',0 };
return msi_unimplemented_action_stub( package, "RemoveODBC", table );
}
static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package ) static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package )
{ {
static const WCHAR table[] = { 'R','e','m','o','v','e','R','e','g','i','s','t','r','y',0 }; static const WCHAR table[] = { 'R','e','m','o','v','e','R','e','g','i','s','t','r','y',0 };
return msi_unimplemented_action_stub( package, "RemoveRegistryValues", table ); return msi_unimplemented_action_stub( package, "RemoveRegistryValues", table );
} }
static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
{
static const WCHAR table[] = { 'S','h','o','r','t','c','u','t',0 };
return msi_unimplemented_action_stub( package, "RemoveShortcuts", table );
}
static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
{ {
static const WCHAR table[] = { 'D','i','r','e','c','t','o','r','y',0 }; static const WCHAR table[] = { 'D','i','r','e','c','t','o','r','y',0 };
return msi_unimplemented_action_stub( package, "SetODBCFolders", table ); return msi_unimplemented_action_stub( package, "SetODBCFolders", table );
} }
static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
{
static const WCHAR table[] = { 'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t',0 };
return msi_unimplemented_action_stub( package, "UnpublishComponents", table );
}
static UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package ) static UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package )
{ {
static const WCHAR table[] = { 'A','p','p','I','d',0 }; static const WCHAR table[] = { 'A','p','p','I','d',0 };
@ -6311,12 +6648,6 @@ static UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package )
return msi_unimplemented_action_stub( package, "UnregisterProgIdInfo", table ); return msi_unimplemented_action_stub( package, "UnregisterProgIdInfo", table );
} }
static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
{
static const WCHAR table[] = { 'T','y','p','e','L','i','b',0 };
return msi_unimplemented_action_stub( package, "UnregisterTypeLibraries", table );
}
typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*); typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);
static const struct static const struct
@ -6335,13 +6666,13 @@ StandardActions[] =
{ szCreateFolders, ACTION_CreateFolders }, { szCreateFolders, ACTION_CreateFolders },
{ szCreateShortcuts, ACTION_CreateShortcuts }, { szCreateShortcuts, ACTION_CreateShortcuts },
{ szDeleteServices, ACTION_DeleteServices }, { szDeleteServices, ACTION_DeleteServices },
{ szDisableRollback, NULL }, { szDisableRollback, ACTION_DisableRollback },
{ szDuplicateFiles, ACTION_DuplicateFiles }, { szDuplicateFiles, ACTION_DuplicateFiles },
{ szExecuteAction, ACTION_ExecuteAction }, { szExecuteAction, ACTION_ExecuteAction },
{ szFileCost, ACTION_FileCost }, { szFileCost, ACTION_FileCost },
{ szFindRelatedProducts, ACTION_FindRelatedProducts }, { szFindRelatedProducts, ACTION_FindRelatedProducts },
{ szForceReboot, ACTION_ForceReboot }, { szForceReboot, ACTION_ForceReboot },
{ szInstallAdminPackage, NULL }, { szInstallAdminPackage, ACTION_InstallAdminPackage },
{ szInstallExecute, ACTION_InstallExecute }, { szInstallExecute, ACTION_InstallExecute },
{ szInstallExecuteAgain, ACTION_InstallExecute }, { szInstallExecuteAgain, ACTION_InstallExecute },
{ szInstallFiles, ACTION_InstallFiles}, { szInstallFiles, ACTION_InstallFiles},

View file

@ -809,16 +809,17 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
continue; continue;
feature = cls->Feature; feature = cls->Feature;
if (!feature)
continue;
/* /*
* MSDN says that these are based on Feature not on Component. * MSDN says that these are based on Feature not on Component.
*/ */
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL ) && if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )) feature->ActionRequest != INSTALLSTATE_ADVERTISED )
{ {
TRACE("Skipping class %s reg due to disabled feature %s\n", TRACE("Feature %s not scheduled for installation, skipping regstration of class %s\n",
debugstr_w(cls->clsid), debugstr_w(feature->Feature)); debugstr_w(feature->Feature), debugstr_w(cls->clsid));
continue; continue;
} }
@ -1142,18 +1143,18 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
continue; continue;
feature = ext->Feature; feature = ext->Feature;
if (!feature)
continue;
/* /*
* yes. MSDN says that these are based on _Feature_ not on * yes. MSDN says that these are based on _Feature_ not on
* Component. So verify the feature is to be installed * Component. So verify the feature is to be installed
*/ */
if ((!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL )) && if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
!(install_on_demand && !(install_on_demand && feature->ActionRequest == INSTALLSTATE_ADVERTISED))
ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )))
{ {
TRACE("Skipping extension %s reg due to disabled feature %s\n", TRACE("Feature %s not scheduled for installation, skipping registration of extension %s\n",
debugstr_w(ext->Extension), debugstr_w(feature->Feature)); debugstr_w(feature->Feature), debugstr_w(ext->Extension));
continue; continue;
} }

View file

@ -125,20 +125,14 @@ static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ) UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
{ {
LPWSTR encname;
HRESULT r; HRESULT r;
encname = encode_streamname(FALSE, stname); TRACE("%s\n", debugstr_w(stname));
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname)); if (clone_open_stream( db, stname, stm ) == ERROR_SUCCESS)
if (clone_open_stream( db, encname, stm ) == ERROR_SUCCESS)
{
msi_free( encname );
return ERROR_SUCCESS; return ERROR_SUCCESS;
}
r = IStorage_OpenStream( db->storage, encname, NULL, r = IStorage_OpenStream( db->storage, stname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm ); STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if( FAILED( r ) ) if( FAILED( r ) )
{ {
@ -147,15 +141,13 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry ) LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
{ {
TRACE("looking for %s in transform storage\n", debugstr_w(stname) ); TRACE("looking for %s in transform storage\n", debugstr_w(stname) );
r = IStorage_OpenStream( transform->stg, encname, NULL, r = IStorage_OpenStream( transform->stg, stname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm ); STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if (SUCCEEDED(r)) if (SUCCEEDED(r))
break; break;
} }
} }
msi_free( encname );
if( SUCCEEDED(r) ) if( SUCCEEDED(r) )
{ {
MSISTREAM *stream; MSISTREAM *stream;
@ -181,10 +173,15 @@ UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
ULONG sz, count; ULONG sz, count;
IStream *stm = NULL; IStream *stm = NULL;
STATSTG stat; STATSTG stat;
LPWSTR encname;
encname = encode_streamname( FALSE, stname );
r = db_get_raw_stream( db, encname, &stm );
msi_free( encname );
r = db_get_raw_stream( db, stname, &stm );
if( r != ERROR_SUCCESS) if( r != ERROR_SUCCESS)
return ret; return ret;
r = IStream_Stat(stm, &stat, STATFLAG_NONAME ); r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
if( FAILED( r ) ) if( FAILED( r ) )
{ {
@ -225,16 +222,6 @@ end:
return ret; return ret;
} }
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
{
MSITRANSFORM *t;
t = msi_alloc( sizeof *t );
t->stg = stg;
IStorage_AddRef( stg );
list_add_tail( &db->transforms, &t->entry );
}
static void free_transforms( MSIDATABASE *db ) static void free_transforms( MSIDATABASE *db )
{ {
while( !list_empty( &db->transforms ) ) while( !list_empty( &db->transforms ) )
@ -259,6 +246,19 @@ static void free_streams( MSIDATABASE *db )
} }
} }
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
{
MSITRANSFORM *t;
t = msi_alloc( sizeof *t );
t->stg = stg;
IStorage_AddRef( stg );
list_add_tail( &db->transforms, &t->entry );
/* the transform may add or replace streams */
free_streams( db );
}
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg ) static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
{ {
MSIDATABASE *db = (MSIDATABASE *) arg; MSIDATABASE *db = (MSIDATABASE *) arg;

View file

@ -386,9 +386,6 @@ static UINT ControlEvent_ReinstallMode(MSIPACKAGE *package, LPCWSTR argument,
static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument, static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument,
msi_dialog *dialog) msi_dialog *dialog)
{ {
static const WCHAR szProductID[] = {'P','r','o','d','u','c','t','I','D',0};
static const WCHAR szPIDTemplate[] = {'P','I','D','T','e','m','p','l','a','t','e',0};
static const WCHAR szPIDKEY[] = {'P','I','D','K','E','Y',0};
LPWSTR key, template; LPWSTR key, template;
UINT ret = ERROR_SUCCESS; UINT ret = ERROR_SUCCESS;

View file

@ -108,7 +108,7 @@ static void schedule_install_files(MSIPACKAGE *package)
LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry) LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry)
{ {
if (!ACTION_VerifyComponentForAction(file->Component, INSTALLSTATE_LOCAL)) if (file->Component->ActionRequest != INSTALLSTATE_LOCAL)
{ {
TRACE("File %s is not scheduled for install\n", debugstr_w(file->File)); TRACE("File %s is not scheduled for install\n", debugstr_w(file->File));
@ -358,19 +358,15 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param)
component = MSI_RecordGetString(row,2); component = MSI_RecordGetString(row,2);
comp = get_loaded_component(package,component); comp = get_loaded_component(package,component);
if (!comp)
return ERROR_SUCCESS;
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL )) if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{ {
TRACE("Skipping copy due to disabled component %s\n", TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
debugstr_w(component));
/* the action taken was the same as the current install state */
if (comp)
comp->Action = comp->Installed; comp->Action = comp->Installed;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
comp->Action = INSTALLSTATE_LOCAL; comp->Action = INSTALLSTATE_LOCAL;
file_key = MSI_RecordGetString(row,3); file_key = MSI_RecordGetString(row,3);

View file

@ -66,6 +66,21 @@ typedef struct _tagTT_NAME_RECORD {
static const WCHAR szRegisterFonts[] = static const WCHAR szRegisterFonts[] =
{'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; {'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
static const WCHAR szUnregisterFonts[] =
{'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0};
static const WCHAR regfont1[] =
{'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s',' ','N','T','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'F','o','n','t','s',0};
static const WCHAR regfont2[] =
{'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'F','o','n','t','s',0};
/* /*
* Code based off of code located here * Code based off of code located here
@ -174,20 +189,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
LPWSTR name; LPWSTR name;
LPCWSTR filename; LPCWSTR filename;
MSIFILE *file; MSIFILE *file;
static const WCHAR regfont1[] = HKEY hkey1, hkey2;
{'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s',' ','N','T','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'F','o','n','t','s',0};
static const WCHAR regfont2[] =
{'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'F','o','n','t','s',0};
HKEY hkey1;
HKEY hkey2;
MSIRECORD *uirow; MSIRECORD *uirow;
LPWSTR uipath, p; LPWSTR uipath, p;
@ -199,10 +201,9 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
/* check to make sure that component is installed */ if (file->Component->ActionRequest != INSTALLSTATE_LOCAL)
if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL))
{ {
TRACE("Skipping: Component not scheduled for install\n"); TRACE("Component not scheduled for installation\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -259,3 +260,81 @@ UINT ACTION_RegisterFonts(MSIPACKAGE *package)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param )
{
MSIPACKAGE *package = param;
LPWSTR name;
LPCWSTR filename;
MSIFILE *file;
HKEY hkey1, hkey2;
MSIRECORD *uirow;
LPWSTR uipath, p;
filename = MSI_RecordGetString( row, 1 );
file = get_loaded_file( package, filename );
if (!file)
{
ERR("Unable to load file\n");
return ERROR_SUCCESS;
}
if (file->Component->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal\n");
return ERROR_SUCCESS;
}
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont1, &hkey1 );
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 );
if (MSI_RecordIsNull( row, 2 ))
name = load_ttfname_from( file->TargetPath );
else
name = msi_dup_record_field( row, 2 );
if (name)
{
RegDeleteValueW( hkey1, name );
RegDeleteValueW( hkey2, name );
}
msi_free( name );
RegCloseKey( hkey1 );
RegCloseKey( hkey2 );
/* the UI chunk */
uirow = MSI_CreateRecord( 1 );
uipath = strdupW( file->TargetPath );
p = strrchrW( uipath,'\\' );
if (p) p++;
else p = uipath;
MSI_RecordSetStringW( uirow, 1, p );
ui_actiondata( package, szUnregisterFonts, uirow );
msiobj_release( &uirow->hdr );
msi_free( uipath );
/* FIXME: call ui_progress? */
return ERROR_SUCCESS;
}
UINT ACTION_UnregisterFonts( MSIPACKAGE *package )
{
UINT r;
MSIQUERY *view;
static const WCHAR query[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','F','o','n','t','`',0};
r = MSI_DatabaseOpenViewW( package->db, query, &view );
if (r != ERROR_SUCCESS)
{
TRACE("MSI_DatabaseOpenViewW failed: %u\n", r);
return ERROR_SUCCESS;
}
MSI_IterateRecords( view, NULL, ITERATE_UnregisterFonts, package );
msiobj_release( &view->hdr );
return ERROR_SUCCESS;
}

View file

@ -604,28 +604,6 @@ void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
} }
BOOL ACTION_VerifyComponentForAction( const MSICOMPONENT* comp, INSTALLSTATE check )
{
if (!comp)
return FALSE;
if (comp->ActionRequest == check)
return TRUE;
else
return FALSE;
}
BOOL ACTION_VerifyFeatureForAction( const MSIFEATURE* feature, INSTALLSTATE check )
{
if (!feature)
return FALSE;
if (feature->ActionRequest == check)
return TRUE;
else
return FALSE;
}
void reduce_to_longfilename(WCHAR* filename) void reduce_to_longfilename(WCHAR* filename)
{ {
LPWSTR p = strchrW(filename,'|'); LPWSTR p = strchrW(filename,'|');

View file

@ -661,6 +661,8 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
MSIPACKAGE *package; MSIPACKAGE *package;
BOOL r = FALSE; BOOL r = FALSE;
TRACE("%d %d\n", hInstall, iRunMode);
package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
if (!package) if (!package)
{ {
@ -706,8 +708,16 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
r = package->commit_action_running; r = package->commit_action_running;
break; break;
case MSIRUNMODE_MAINTENANCE:
r = msi_get_property_int( package, szInstalled, 0 ) != 0;
break;
case MSIRUNMODE_REBOOTATEND:
r = package->need_reboot;
break;
default: default:
FIXME("%d %d\n", hInstall, iRunMode); FIXME("unimplemented run mode: %d\n", iRunMode);
r = TRUE; r = TRUE;
} }
@ -719,8 +729,52 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
*/ */
UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState) UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
{ {
FIXME("%d %d %d\n", hInstall, iRunMode, fState); MSIPACKAGE *package;
UINT r;
TRACE("%d %d %d\n", hInstall, iRunMode, fState);
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
if (!package)
{
HRESULT hr;
IWineMsiRemotePackage *remote_package;
remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
if (!remote_package)
return FALSE;
hr = IWineMsiRemotePackage_SetMode( remote_package, iRunMode, fState );
IWineMsiRemotePackage_Release( remote_package );
if (FAILED(hr))
{
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
return HRESULT_CODE(hr);
return ERROR_FUNCTION_FAILED;
}
return ERROR_SUCCESS; return ERROR_SUCCESS;
}
switch (iRunMode)
{
case MSIRUNMODE_REBOOTATEND:
package->need_reboot = 1;
r = ERROR_SUCCESS;
break;
case MSIRUNMODE_REBOOTNOW:
FIXME("unimplemented run mode: %d\n", iRunMode);
r = ERROR_FUNCTION_FAILED;
break;
default:
r = ERROR_ACCESS_DENIED;
}
return r;
} }
/*********************************************************************** /***********************************************************************

View file

@ -1613,6 +1613,93 @@ done:
return r; return r;
} }
UINT WINAPI MsiGetPatchInfoA( LPCSTR patch, LPCSTR attr, LPSTR buffer, LPDWORD buflen )
{
UINT r = ERROR_OUTOFMEMORY;
DWORD size;
LPWSTR patchW = NULL, attrW = NULL, bufferW = NULL;
TRACE("%s %s %p %p\n", debugstr_a(patch), debugstr_a(attr), buffer, buflen);
if (!patch || !attr)
return ERROR_INVALID_PARAMETER;
if (!(patchW = strdupAtoW( patch )))
goto done;
if (!(attrW = strdupAtoW( attr )))
goto done;
size = 0;
r = MsiGetPatchInfoW( patchW, attrW, NULL, &size );
if (r != ERROR_SUCCESS)
goto done;
size++;
if (!(bufferW = msi_alloc( size * sizeof(WCHAR) )))
{
r = ERROR_OUTOFMEMORY;
goto done;
}
r = MsiGetPatchInfoW( patchW, attrW, bufferW, &size );
if (r == ERROR_SUCCESS)
{
int len = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
if (len > *buflen)
r = ERROR_MORE_DATA;
else if (buffer)
WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, *buflen, NULL, NULL );
*buflen = len - 1;
}
done:
msi_free( patchW );
msi_free( attrW );
msi_free( bufferW );
return r;
}
UINT WINAPI MsiGetPatchInfoW( LPCWSTR patch, LPCWSTR attr, LPWSTR buffer, LPDWORD buflen )
{
UINT r;
WCHAR product[GUID_SIZE];
DWORD index;
TRACE("%s %s %p %p\n", debugstr_w(patch), debugstr_w(attr), buffer, buflen);
if (!patch || !attr)
return ERROR_INVALID_PARAMETER;
if (strcmpW( INSTALLPROPERTY_LOCALPACKAGEW, attr ))
return ERROR_UNKNOWN_PROPERTY;
index = 0;
while (1)
{
r = MsiEnumProductsW( index, product );
if (r != ERROR_SUCCESS)
break;
r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_USERMANAGED, attr, buffer, buflen );
if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
return r;
r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, attr, buffer, buflen );
if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
return r;
r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_MACHINE, attr, buffer, buflen );
if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
return r;
index++;
}
return ERROR_UNKNOWN_PRODUCT;
}
UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes) UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
{ {
LPWSTR szwLogFile = NULL; LPWSTR szwLogFile = NULL;

View file

@ -171,8 +171,8 @@
175 stdcall MsiApplyPatchW(wstr wstr long wstr) 175 stdcall MsiApplyPatchW(wstr wstr long wstr)
176 stdcall MsiAdvertiseScriptA(str long ptr long) 176 stdcall MsiAdvertiseScriptA(str long ptr long)
177 stdcall MsiAdvertiseScriptW(wstr long ptr long) 177 stdcall MsiAdvertiseScriptW(wstr long ptr long)
178 stub MsiGetPatchInfoA 178 stdcall MsiGetPatchInfoA(str str ptr ptr)
179 stub MsiGetPatchInfoW 179 stdcall MsiGetPatchInfoW(wstr wstr ptr ptr)
180 stdcall MsiEnumPatchesA(str long ptr ptr ptr) 180 stdcall MsiEnumPatchesA(str long ptr ptr ptr)
181 stdcall MsiEnumPatchesW(str long ptr ptr ptr) 181 stdcall MsiEnumPatchesW(str long ptr ptr ptr)
182 stdcall -private DllGetVersion(ptr) 182 stdcall -private DllGetVersion(ptr)

View file

@ -20,17 +20,21 @@
#include "windef.h" #include "windef.h"
/*UTF-8*/
#pragma code_page(65001)
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE STRINGTABLE DISCARDABLE
{ {
4 "The specified installation package could not be opened. Please check the file path and try again." 4 "Impossibile aprire il pacchetto di installazione specificato. Per favore controlla l'indirizzo del file e riprova."
5 "percorso %s non trovato" 5 "percorso %s non trovato"
9 "inserire disco %s" 9 "inserire disco %s"
10 "parametri incorretti" 10 "parametri incorretti"
11 "immettere il nome della cartella che contiene %s" 11 "immettere il nome della cartella che contiene %s"
12 "sorgente di installazione per la funzionalità mancante" 12 "sorgente di installazione per la funzionalità mancante"
13 "periferica di rete per la funzionalità mancante" 13 "periferica di rete per la funzionalità mancante"
14 "funzionalità da:" 14 "funzionalità da:"
15 "selezionare la cartella che contiene %s" 15 "selezionare la cartella che contiene %s"
} }
#pragma code_page(default)

View file

@ -961,6 +961,7 @@ extern UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);
extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package);
extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);
extern UINT ACTION_RegisterFonts(MSIPACKAGE *package); extern UINT ACTION_RegisterFonts(MSIPACKAGE *package);
extern UINT ACTION_UnregisterFonts(MSIPACKAGE *package);
/* Helpers */ /* Helpers */
extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data ); extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data );
@ -981,8 +982,6 @@ extern void msi_free_action_script(MSIPACKAGE *package, UINT script);
extern LPWSTR build_icon_path(MSIPACKAGE *, LPCWSTR); extern LPWSTR build_icon_path(MSIPACKAGE *, LPCWSTR);
extern LPWSTR build_directory_name(DWORD , ...); extern LPWSTR build_directory_name(DWORD , ...);
extern BOOL create_full_pathW(const WCHAR *path); extern BOOL create_full_pathW(const WCHAR *path);
extern BOOL ACTION_VerifyComponentForAction(const MSICOMPONENT*, INSTALLSTATE);
extern BOOL ACTION_VerifyFeatureForAction(const MSIFEATURE*, INSTALLSTATE);
extern void reduce_to_longfilename(WCHAR*); extern void reduce_to_longfilename(WCHAR*);
extern LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR); extern LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR);
extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature); extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature);
@ -1071,6 +1070,11 @@ static const WCHAR szFindRelatedProducts[] = {'F','i','n','d','R','e','l','a','t
static const WCHAR szAllUsers[] = {'A','L','L','U','S','E','R','S',0}; static const WCHAR szAllUsers[] = {'A','L','L','U','S','E','R','S',0};
static const WCHAR szCustomActionData[] = {'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0}; static const WCHAR szCustomActionData[] = {'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0};
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0}; static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
static const WCHAR szProductID[] = {'P','r','o','d','u','c','t','I','D',0};
static const WCHAR szPIDTemplate[] = {'P','I','D','T','e','m','p','l','a','t','e',0};
static const WCHAR szPIDKEY[] = {'P','I','D','K','E','Y',0};
static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
static const WCHAR szSumInfo[] = {5 ,'S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0};
/* memory allocation macro functions */ /* memory allocation macro functions */
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1); static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);

View file

@ -64,6 +64,7 @@ interface IWineMsiRemotePackage : IUnknown
HRESULT SetTargetPath( [in] BSTR folder, [in] BSTR value ); HRESULT SetTargetPath( [in] BSTR folder, [in] BSTR value );
HRESULT GetSourcePath( [in] BSTR folder, [out] BSTR *value, [out] DWORD *size ); HRESULT GetSourcePath( [in] BSTR folder, [out] BSTR *value, [out] DWORD *size );
HRESULT GetMode( [in] MSIRUNMODE mode, [out] BOOL *ret ); HRESULT GetMode( [in] MSIRUNMODE mode, [out] BOOL *ret );
HRESULT SetMode( [in] MSIRUNMODE mode, [in] BOOL state );
HRESULT GetFeatureState( [in] BSTR feature, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action ); HRESULT GetFeatureState( [in] BSTR feature, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action );
HRESULT SetFeatureState( [in] BSTR feature, [in] INSTALLSTATE state ); HRESULT SetFeatureState( [in] BSTR feature, [in] INSTALLSTATE state );
HRESULT GetComponentState( [in] BSTR component, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action ); HRESULT GetComponentState( [in] BSTR component, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action );

View file

@ -2104,6 +2104,13 @@ static HRESULT WINAPI mrp_GetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode
return S_OK; return S_OK;
} }
static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL state )
{
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
UINT r = MsiSetMode(This->package, mode, state);
return HRESULT_FROM_WIN32(r);
}
static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature,
INSTALLSTATE *installed, INSTALLSTATE *action ) INSTALLSTATE *installed, INSTALLSTATE *action )
{ {
@ -2196,6 +2203,7 @@ static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
mrp_SetTargetPath, mrp_SetTargetPath,
mrp_GetSourcePath, mrp_GetSourcePath,
mrp_GetMode, mrp_GetMode,
mrp_SetMode,
mrp_GetFeatureState, mrp_GetFeatureState,
mrp_SetFeatureState, mrp_SetFeatureState,
mrp_GetComponentState, mrp_GetComponentState,

View file

@ -32,6 +32,7 @@
#include "query.h" #include "query.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(msidb); WINE_DEFAULT_DEBUG_CHANNEL(msidb);
@ -486,7 +487,8 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
STATSTG stat; STATSTG stat;
STREAM *stream = NULL; STREAM *stream = NULL;
HRESULT hr; HRESULT hr;
UINT count = 0, size; UINT r, count = 0, size;
LPWSTR encname;
hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum); hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum);
if (FAILED(hr)) if (FAILED(hr))
@ -505,7 +507,10 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
break; break;
if (stat.type != STGTY_STREAM) if (stat.type != STGTY_STREAM)
{
CoTaskMemFree(stat.pwcsName);
continue; continue;
}
/* table streams are not in the _Streams table */ /* table streams are not in the _Streams table */
if (*stat.pwcsName == 0x4840) if (*stat.pwcsName == 0x4840)
@ -522,13 +527,22 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
break; break;
} }
hr = IStorage_OpenStream(sv->db->storage, stat.pwcsName, 0, if (!strcmpW(stat.pwcsName, szSumInfo))
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); {
/* summary information stream is not encoded */
r = db_get_raw_stream(sv->db, stat.pwcsName, &stream->stream);
}
else
{
encname = encode_streamname(FALSE, stat.pwcsName);
r = db_get_raw_stream(sv->db, encname, &stream->stream);
msi_free(encname);
}
CoTaskMemFree(stat.pwcsName); CoTaskMemFree(stat.pwcsName);
if (FAILED(hr)) if (r != ERROR_SUCCESS)
{ {
WARN("failed to open stream: %08x\n", hr); WARN("unable to get stream %u\n", r);
count = -1; count = -1;
break; break;
} }

View file

@ -86,9 +86,6 @@ static HRESULT (WINAPI *pPropVariantChangeType)
#define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER)) #define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER))
static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
'I','n','f','o','r','m','a','t','i','o','n',0 };
static void free_prop( PROPVARIANT *prop ) static void free_prop( PROPVARIANT *prop )
{ {
if (prop->vt == VT_LPSTR ) if (prop->vt == VT_LPSTR )

View file

@ -1168,7 +1168,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
{ {
MSITABLEVIEW *tv = (MSITABLEVIEW*)view; MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT r; UINT r;
LPWSTR full_name = NULL; LPWSTR encname, full_name = NULL;
if( !view->ops->fetch_int ) if( !view->ops->fetch_int )
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
@ -1180,11 +1180,13 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
return r; return r;
} }
r = db_get_raw_stream( tv->db, full_name, stm ); encname = encode_streamname( FALSE, full_name );
r = db_get_raw_stream( tv->db, encname, stm );
if( r ) if( r )
ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r); ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
msi_free( full_name );
msi_free( full_name );
msi_free( encname );
return r; return r;
} }

View file

@ -166,9 +166,9 @@ static int sqliteKeywordCode(const WCHAR *z, int n){
*/ */
static const char isIdChar[] = { static const char isIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 2x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */

View file

@ -503,6 +503,10 @@ UINT WINAPI MsiGetPatchInfoExA(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR
UINT WINAPI MsiGetPatchInfoExW(LPCWSTR, LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, LPWSTR, LPDWORD); UINT WINAPI MsiGetPatchInfoExW(LPCWSTR, LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, LPWSTR, LPDWORD);
#define MsiGetPatchInfoEx WINELIB_NAME_AW(MsiGetPatchInfoEx) #define MsiGetPatchInfoEx WINELIB_NAME_AW(MsiGetPatchInfoEx)
UINT WINAPI MsiGetPatchInfoA(LPCSTR, LPCSTR, LPSTR, LPDWORD);
UINT WINAPI MsiGetPatchInfoW(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD);
#define MsiGetPatchInfo WINELIB_NAME_AW(MsiGetPatchInfo)
UINT WINAPI MsiEnableLogA(DWORD, LPCSTR, DWORD); UINT WINAPI MsiEnableLogA(DWORD, LPCSTR, DWORD);
UINT WINAPI MsiEnableLogW(DWORD, LPCWSTR, DWORD); UINT WINAPI MsiEnableLogW(DWORD, LPCWSTR, DWORD);
#define MsiEnableLog WINELIB_NAME_AW(MsiEnableLog) #define MsiEnableLog WINELIB_NAME_AW(MsiEnableLog)