msi: Implement the RemoveIniValues standard action.
This commit is contained in:
parent
1fe30e0015
commit
b891d0888a
|
@ -3827,18 +3827,49 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static WCHAR *get_ini_file_name( MSIPACKAGE *package, MSIRECORD *row )
|
||||
{
|
||||
WCHAR *filename, *ptr, *folder, *ret;
|
||||
const WCHAR *dirprop;
|
||||
|
||||
filename = msi_dup_record_field( row, 2 );
|
||||
if (filename && (ptr = strchrW( filename, '|' )))
|
||||
ptr++;
|
||||
else
|
||||
ptr = filename;
|
||||
|
||||
dirprop = MSI_RecordGetString( row, 3 );
|
||||
if (dirprop)
|
||||
{
|
||||
folder = resolve_folder( package, dirprop, FALSE, FALSE, TRUE, NULL );
|
||||
if (!folder)
|
||||
folder = msi_dup_property( package, dirprop );
|
||||
}
|
||||
else
|
||||
folder = msi_dup_property( package, szWindowsFolder );
|
||||
|
||||
if (!folder)
|
||||
{
|
||||
ERR("Unable to resolve folder %s\n", debugstr_w(dirprop));
|
||||
msi_free( filename );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = build_directory_name( 2, folder, ptr );
|
||||
|
||||
msi_free( filename );
|
||||
msi_free( folder );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
||||
{
|
||||
MSIPACKAGE *package = param;
|
||||
LPCWSTR component, section, key, value, identifier, dirproperty;
|
||||
LPWSTR deformated_section, deformated_key, deformated_value;
|
||||
LPWSTR folder, filename, fullname = NULL;
|
||||
LPCWSTR filenameptr;
|
||||
LPCWSTR component, section, key, value, identifier;
|
||||
LPWSTR deformated_section, deformated_key, deformated_value, fullname;
|
||||
MSIRECORD * uirow;
|
||||
INT action;
|
||||
MSICOMPONENT *comp;
|
||||
static const WCHAR szWindowsFolder[] =
|
||||
{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
|
||||
|
||||
component = MSI_RecordGetString(row, 8);
|
||||
comp = get_loaded_component(package,component);
|
||||
|
@ -3854,7 +3885,6 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
|||
comp->Action = INSTALLSTATE_LOCAL;
|
||||
|
||||
identifier = MSI_RecordGetString(row,1);
|
||||
dirproperty = MSI_RecordGetString(row,3);
|
||||
section = MSI_RecordGetString(row,4);
|
||||
key = MSI_RecordGetString(row,5);
|
||||
value = MSI_RecordGetString(row,6);
|
||||
|
@ -3864,28 +3894,7 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
|||
deformat_string(package,key,&deformated_key);
|
||||
deformat_string(package,value,&deformated_value);
|
||||
|
||||
filename = msi_dup_record_field(row, 2);
|
||||
if (filename && (filenameptr = strchrW(filename, '|')))
|
||||
filenameptr++;
|
||||
else
|
||||
filenameptr = filename;
|
||||
|
||||
if (dirproperty)
|
||||
{
|
||||
folder = resolve_folder(package, dirproperty, FALSE, FALSE, TRUE, NULL);
|
||||
if (!folder)
|
||||
folder = msi_dup_property( package, dirproperty );
|
||||
}
|
||||
else
|
||||
folder = msi_dup_property( package, szWindowsFolder );
|
||||
|
||||
if (!folder)
|
||||
{
|
||||
ERR("Unable to resolve folder! (%s)\n",debugstr_w(dirproperty));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fullname = build_directory_name(2, folder, filenameptr);
|
||||
fullname = get_ini_file_name(package, row);
|
||||
|
||||
if (action == 0)
|
||||
{
|
||||
|
@ -3921,10 +3930,7 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
|||
ui_actiondata(package,szWriteIniValues,uirow);
|
||||
msiobj_release( &uirow->hdr );
|
||||
|
||||
cleanup:
|
||||
msi_free(filename);
|
||||
msi_free(fullname);
|
||||
msi_free(folder);
|
||||
msi_free(deformated_key);
|
||||
msi_free(deformated_value);
|
||||
msi_free(deformated_section);
|
||||
|
@ -3951,6 +3957,163 @@ static UINT ACTION_WriteIniValues(MSIPACKAGE *package)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static UINT ITERATE_RemoveIniValuesOnUninstall( MSIRECORD *row, LPVOID param )
|
||||
{
|
||||
MSIPACKAGE *package = param;
|
||||
LPCWSTR component, section, key, value, identifier;
|
||||
LPWSTR deformated_section, deformated_key, deformated_value, filename;
|
||||
MSICOMPONENT *comp;
|
||||
MSIRECORD *uirow;
|
||||
INT action;
|
||||
|
||||
component = MSI_RecordGetString( row, 8 );
|
||||
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;
|
||||
|
||||
identifier = MSI_RecordGetString( row, 1 );
|
||||
section = MSI_RecordGetString( row, 4 );
|
||||
key = MSI_RecordGetString( row, 5 );
|
||||
value = MSI_RecordGetString( row, 6 );
|
||||
action = MSI_RecordGetInteger( row, 7 );
|
||||
|
||||
deformat_string( package, section, &deformated_section );
|
||||
deformat_string( package, key, &deformated_key );
|
||||
deformat_string( package, value, &deformated_value );
|
||||
|
||||
if (action == msidbIniFileActionAddLine || action == msidbIniFileActionCreateLine)
|
||||
{
|
||||
filename = get_ini_file_name( package, row );
|
||||
|
||||
TRACE("Removing key %s from section %s in %s\n",
|
||||
debugstr_w(deformated_key), debugstr_w(deformated_section), debugstr_w(filename));
|
||||
|
||||
if (!WritePrivateProfileStringW( deformated_section, deformated_key, NULL, filename ))
|
||||
{
|
||||
WARN("Unable to remove key %u\n", GetLastError());
|
||||
}
|
||||
msi_free( filename );
|
||||
}
|
||||
else
|
||||
FIXME("Unsupported action %d\n", action);
|
||||
|
||||
|
||||
uirow = MSI_CreateRecord( 4 );
|
||||
MSI_RecordSetStringW( uirow, 1, identifier );
|
||||
MSI_RecordSetStringW( uirow, 2, deformated_section );
|
||||
MSI_RecordSetStringW( uirow, 3, deformated_key );
|
||||
MSI_RecordSetStringW( uirow, 4, deformated_value );
|
||||
ui_actiondata( package, szRemoveIniValues, uirow );
|
||||
msiobj_release( &uirow->hdr );
|
||||
|
||||
msi_free( deformated_key );
|
||||
msi_free( deformated_value );
|
||||
msi_free( deformated_section );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ITERATE_RemoveIniValuesOnInstall( MSIRECORD *row, LPVOID param )
|
||||
{
|
||||
MSIPACKAGE *package = param;
|
||||
LPCWSTR component, section, key, value, identifier;
|
||||
LPWSTR deformated_section, deformated_key, deformated_value, filename;
|
||||
MSICOMPONENT *comp;
|
||||
MSIRECORD *uirow;
|
||||
INT action;
|
||||
|
||||
component = MSI_RecordGetString( row, 8 );
|
||||
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;
|
||||
|
||||
identifier = MSI_RecordGetString( row, 1 );
|
||||
section = MSI_RecordGetString( row, 4 );
|
||||
key = MSI_RecordGetString( row, 5 );
|
||||
value = MSI_RecordGetString( row, 6 );
|
||||
action = MSI_RecordGetInteger( row, 7 );
|
||||
|
||||
deformat_string( package, section, &deformated_section );
|
||||
deformat_string( package, key, &deformated_key );
|
||||
deformat_string( package, value, &deformated_value );
|
||||
|
||||
if (action == msidbIniFileActionRemoveLine)
|
||||
{
|
||||
filename = get_ini_file_name( package, row );
|
||||
|
||||
TRACE("Removing key %s from section %s in %s\n",
|
||||
debugstr_w(deformated_key), debugstr_w(deformated_section), debugstr_w(filename));
|
||||
|
||||
if (!WritePrivateProfileStringW( deformated_section, deformated_key, NULL, filename ))
|
||||
{
|
||||
WARN("Unable to remove key %u\n", GetLastError());
|
||||
}
|
||||
msi_free( filename );
|
||||
}
|
||||
else
|
||||
FIXME("Unsupported action %d\n", action);
|
||||
|
||||
uirow = MSI_CreateRecord( 4 );
|
||||
MSI_RecordSetStringW( uirow, 1, identifier );
|
||||
MSI_RecordSetStringW( uirow, 2, deformated_section );
|
||||
MSI_RecordSetStringW( uirow, 3, deformated_key );
|
||||
MSI_RecordSetStringW( uirow, 4, deformated_value );
|
||||
ui_actiondata( package, szRemoveIniValues, uirow );
|
||||
msiobj_release( &uirow->hdr );
|
||||
|
||||
msi_free( deformated_key );
|
||||
msi_free( deformated_value );
|
||||
msi_free( deformated_section );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
|
||||
{
|
||||
UINT rc;
|
||||
MSIQUERY *view;
|
||||
static const WCHAR query[] =
|
||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','I','n','i','F','i','l','e','`',0};
|
||||
static const WCHAR remove_query[] =
|
||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','R','e','m','o','v','e','I','n','i','F','i','l','e','`',0};
|
||||
|
||||
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveIniValuesOnUninstall, package );
|
||||
msiobj_release( &view->hdr );
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = MSI_DatabaseOpenViewW( package->db, remove_query, &view );
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveIniValuesOnInstall, package );
|
||||
msiobj_release( &view->hdr );
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
|
||||
{
|
||||
MSIPACKAGE *package = param;
|
||||
|
@ -6784,13 +6947,6 @@ static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
|
||||
{
|
||||
static const WCHAR table[] =
|
||||
{'R','e','m','o','v','e','I','n','i','F','i','l','e',0 };
|
||||
return msi_unimplemented_action_stub( package, "RemoveIniValues", table );
|
||||
}
|
||||
|
||||
static UINT ACTION_PatchFiles( MSIPACKAGE *package )
|
||||
{
|
||||
static const WCHAR table[] = { 'P','a','t','c','h',0 };
|
||||
|
|
|
@ -1080,6 +1080,7 @@ static const WCHAR szHCR[] = {'H','K','E','Y','_','C','L','A','S','S','E','S','_
|
|||
static const WCHAR szHCU[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',0};
|
||||
static const WCHAR szHLM[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\',0};
|
||||
static const WCHAR szHU[] = {'H','K','E','Y','_','U','S','E','R','S','\\',0};
|
||||
static const WCHAR szWindowsFolder[] = {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
|
||||
|
||||
/* memory allocation macro functions */
|
||||
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
|
||||
|
|
|
@ -222,6 +222,15 @@ enum msidbRemoveFileInstallMode
|
|||
msidbRemoveFileInstallModeOnBoth = 0x00000003,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
msidbIniFileActionAddLine = 0x00000000,
|
||||
msidbIniFileActionCreateLine = 0x00000001,
|
||||
msidbIniFileActionRemoveLine = 0x00000002,
|
||||
msidbIniFileActionAddTag = 0x00000003,
|
||||
msidbIniFileActionRemoveTag = 0x00000004
|
||||
};
|
||||
|
||||
/*
|
||||
* Windows SDK braindamage alert
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue