msi: Implement the SelfUnregModules standard action.
This commit is contained in:
parent
3864ddf9f2
commit
f5af1ca399
|
@ -3705,6 +3705,89 @@ static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ITERATE_SelfUnregModules( MSIRECORD *row, LPVOID param )
|
||||
{
|
||||
static const WCHAR regsvr32[] =
|
||||
{'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','u',' ','\"',0};
|
||||
static const WCHAR close[] = {'\"',0};
|
||||
MSIPACKAGE *package = param;
|
||||
LPCWSTR filename;
|
||||
LPWSTR cmdline;
|
||||
MSIFILE *file;
|
||||
DWORD len;
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
BOOL ret;
|
||||
MSIRECORD *uirow;
|
||||
LPWSTR uipath, p;
|
||||
|
||||
memset( &si, 0, sizeof(STARTUPINFOW) );
|
||||
|
||||
filename = MSI_RecordGetString( row, 1 );
|
||||
file = get_loaded_file( package, filename );
|
||||
|
||||
if (!file)
|
||||
{
|
||||
ERR("Unable to find file id %s\n", debugstr_w(filename));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
len = strlenW( regsvr32 ) + strlenW( file->TargetPath ) + 2;
|
||||
|
||||
cmdline = msi_alloc( len * sizeof(WCHAR) );
|
||||
strcpyW( cmdline, regsvr32 );
|
||||
strcatW( cmdline, file->TargetPath );
|
||||
strcatW( cmdline, close );
|
||||
|
||||
TRACE("Unregistering %s\n", debugstr_w(cmdline));
|
||||
|
||||
ret = CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, c_colon, &si, &pi );
|
||||
if (ret)
|
||||
{
|
||||
CloseHandle( pi.hThread );
|
||||
msi_dialog_check_messages( pi.hProcess );
|
||||
CloseHandle( pi.hProcess );
|
||||
}
|
||||
|
||||
msi_free( cmdline );
|
||||
|
||||
uirow = MSI_CreateRecord( 2 );
|
||||
uipath = strdupW( file->TargetPath );
|
||||
if ((p = strrchrW( uipath, '\\' )))
|
||||
{
|
||||
*p = 0;
|
||||
MSI_RecordSetStringW( uirow, 1, ++p );
|
||||
}
|
||||
MSI_RecordSetStringW( uirow, 2, uipath );
|
||||
ui_actiondata( package, szSelfUnregModules, uirow );
|
||||
msiobj_release( &uirow->hdr );
|
||||
msi_free( uipath );
|
||||
/* FIXME call ui_progress? */
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ACTION_SelfUnregModules( MSIPACKAGE *package )
|
||||
{
|
||||
UINT rc;
|
||||
MSIQUERY *view;
|
||||
static const WCHAR query[] =
|
||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','S','e','l','f','R','e','g','`',0};
|
||||
|
||||
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("no SelfReg table\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
MSI_IterateRecords( view, NULL, ITERATE_SelfUnregModules, package );
|
||||
msiobj_release( &view->hdr );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
|
||||
{
|
||||
MSIFEATURE *feature;
|
||||
|
@ -6111,12 +6194,6 @@ static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
|
|||
return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table );
|
||||
}
|
||||
|
||||
static UINT ACTION_SelfUnregModules( MSIPACKAGE *package )
|
||||
{
|
||||
static const WCHAR table[] = { 'S','e','l','f','R','e','g',0 };
|
||||
return msi_unimplemented_action_stub( package, "SelfUnregModules", table );
|
||||
}
|
||||
|
||||
static UINT ACTION_ValidateProductID( MSIPACKAGE *package )
|
||||
{
|
||||
static const WCHAR table[] = {
|
||||
|
|
|
@ -1145,6 +1145,30 @@ static const CHAR rf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
|
|||
"InstallValidate\t\t1400\n"
|
||||
"LaunchConditions\t\t100\n";
|
||||
|
||||
|
||||
static const CHAR sr_selfreg_dat[] = "File_\tCost\n"
|
||||
"s72\tI2\n"
|
||||
"SelfReg\tFile_\n"
|
||||
"one.txt\t1\n";
|
||||
|
||||
static const CHAR sr_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
|
||||
"s72\tS255\tI2\n"
|
||||
"InstallExecuteSequence\tAction\n"
|
||||
"CostFinalize\t\t1000\n"
|
||||
"CostInitialize\t\t800\n"
|
||||
"FileCost\t\t900\n"
|
||||
"ResolveSource\t\t950\n"
|
||||
"MoveFiles\t\t1700\n"
|
||||
"SelfUnregModules\t\t3900\n"
|
||||
"InstallFiles\t\t4000\n"
|
||||
"DuplicateFiles\t\t4500\n"
|
||||
"WriteEnvironmentStrings\t\t4550\n"
|
||||
"CreateShortcuts\t\t4600\n"
|
||||
"InstallFinalize\t\t6600\n"
|
||||
"InstallInitialize\t\t1500\n"
|
||||
"InstallValidate\t\t1400\n"
|
||||
"LaunchConditions\t\t100\n";
|
||||
|
||||
typedef struct _msi_table
|
||||
{
|
||||
const CHAR *filename;
|
||||
|
@ -1902,6 +1926,19 @@ static const msi_table sds_tables[] =
|
|||
ADD_TABLE(property)
|
||||
};
|
||||
|
||||
static const msi_table sr_tables[] =
|
||||
{
|
||||
ADD_TABLE(component),
|
||||
ADD_TABLE(directory),
|
||||
ADD_TABLE(feature),
|
||||
ADD_TABLE(feature_comp),
|
||||
ADD_TABLE(file),
|
||||
ADD_TABLE(sr_selfreg),
|
||||
ADD_TABLE(sr_install_exec_seq),
|
||||
ADD_TABLE(media),
|
||||
ADD_TABLE(property)
|
||||
};
|
||||
|
||||
/* cabinet definitions */
|
||||
|
||||
/* make the max size large so there is only one cab file */
|
||||
|
@ -7635,6 +7672,34 @@ static void test_delete_services(void)
|
|||
delete_test_files();
|
||||
}
|
||||
|
||||
static void test_self_registration(void)
|
||||
{
|
||||
UINT r;
|
||||
|
||||
create_test_files();
|
||||
create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
|
||||
|
||||
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
||||
|
||||
r = MsiInstallProductA(msifile, NULL);
|
||||
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
||||
|
||||
ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
|
||||
ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
|
||||
ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
|
||||
ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
|
||||
ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
|
||||
ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
|
||||
ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
|
||||
ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
|
||||
ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
|
||||
ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
|
||||
ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
|
||||
ok(delete_pf("msitest", FALSE), "Directory not created\n");
|
||||
|
||||
delete_test_files();
|
||||
}
|
||||
|
||||
START_TEST(install)
|
||||
{
|
||||
DWORD len;
|
||||
|
@ -7730,6 +7795,7 @@ START_TEST(install)
|
|||
test_remove_folder();
|
||||
test_start_services();
|
||||
test_delete_services();
|
||||
test_self_registration();
|
||||
|
||||
DeleteFileA(log_file);
|
||||
|
||||
|
|
Loading…
Reference in New Issue