msi: Implement the RemoveIniValues standard action.
This commit is contained in:
parent
1fe30e0015
commit
b891d0888a
|
@ -3827,18 +3827,49 @@ end:
|
||||||
return rc;
|
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)
|
static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
LPCWSTR component, section, key, value, identifier, dirproperty;
|
LPCWSTR component, section, key, value, identifier;
|
||||||
LPWSTR deformated_section, deformated_key, deformated_value;
|
LPWSTR deformated_section, deformated_key, deformated_value, fullname;
|
||||||
LPWSTR folder, filename, fullname = NULL;
|
|
||||||
LPCWSTR filenameptr;
|
|
||||||
MSIRECORD * uirow;
|
MSIRECORD * uirow;
|
||||||
INT action;
|
INT action;
|
||||||
MSICOMPONENT *comp;
|
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);
|
component = MSI_RecordGetString(row, 8);
|
||||||
comp = get_loaded_component(package,component);
|
comp = get_loaded_component(package,component);
|
||||||
|
@ -3854,7 +3885,6 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
||||||
comp->Action = INSTALLSTATE_LOCAL;
|
comp->Action = INSTALLSTATE_LOCAL;
|
||||||
|
|
||||||
identifier = MSI_RecordGetString(row,1);
|
identifier = MSI_RecordGetString(row,1);
|
||||||
dirproperty = MSI_RecordGetString(row,3);
|
|
||||||
section = MSI_RecordGetString(row,4);
|
section = MSI_RecordGetString(row,4);
|
||||||
key = MSI_RecordGetString(row,5);
|
key = MSI_RecordGetString(row,5);
|
||||||
value = MSI_RecordGetString(row,6);
|
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,key,&deformated_key);
|
||||||
deformat_string(package,value,&deformated_value);
|
deformat_string(package,value,&deformated_value);
|
||||||
|
|
||||||
filename = msi_dup_record_field(row, 2);
|
fullname = get_ini_file_name(package, row);
|
||||||
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);
|
|
||||||
|
|
||||||
if (action == 0)
|
if (action == 0)
|
||||||
{
|
{
|
||||||
|
@ -3921,10 +3930,7 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
||||||
ui_actiondata(package,szWriteIniValues,uirow);
|
ui_actiondata(package,szWriteIniValues,uirow);
|
||||||
msiobj_release( &uirow->hdr );
|
msiobj_release( &uirow->hdr );
|
||||||
|
|
||||||
cleanup:
|
|
||||||
msi_free(filename);
|
|
||||||
msi_free(fullname);
|
msi_free(fullname);
|
||||||
msi_free(folder);
|
|
||||||
msi_free(deformated_key);
|
msi_free(deformated_key);
|
||||||
msi_free(deformated_value);
|
msi_free(deformated_value);
|
||||||
msi_free(deformated_section);
|
msi_free(deformated_section);
|
||||||
|
@ -3951,6 +3957,163 @@ static UINT ACTION_WriteIniValues(MSIPACKAGE *package)
|
||||||
return rc;
|
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)
|
static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
|
@ -6784,13 +6947,6 @@ static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
|
||||||
return ERROR_SUCCESS;
|
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 UINT ACTION_PatchFiles( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] = { 'P','a','t','c','h',0 };
|
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 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 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 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 */
|
/* 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);
|
||||||
|
|
|
@ -222,6 +222,15 @@ enum msidbRemoveFileInstallMode
|
||||||
msidbRemoveFileInstallModeOnBoth = 0x00000003,
|
msidbRemoveFileInstallModeOnBoth = 0x00000003,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
msidbIniFileActionAddLine = 0x00000000,
|
||||||
|
msidbIniFileActionCreateLine = 0x00000001,
|
||||||
|
msidbIniFileActionRemoveLine = 0x00000002,
|
||||||
|
msidbIniFileActionAddTag = 0x00000003,
|
||||||
|
msidbIniFileActionRemoveTag = 0x00000004
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Windows SDK braindamage alert
|
* Windows SDK braindamage alert
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue