msi [2/2]: Remove files in the RemoveFiles table
James Hawkins
truiken at gmail.com
Tue Jun 19 19:49:31 CDT 2007
Hi,
Changelog:
* Remove files in the RemoveFiles table.
dlls/msi/files.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/msi/tests/install.c | 17 ++++----
include/msidefs.h | 7 +++
3 files changed, 111 insertions(+), 9 deletions(-)
--
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 42f954c..31466d5 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -959,7 +959,7 @@ static int msi_compare_file_version( MSI
return lstrcmpW( version, file->Version );
}
-UINT ACTION_RemoveFiles( MSIPACKAGE *package )
+static void remove_package_files( MSIPACKAGE *package )
{
MSIFILE *file;
@@ -1003,6 +1003,100 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *pac
msi_free( uipath );
/* FIXME: call ui_progress here? */
}
+}
+
+static BOOL verify_comp_for_removal(UINT install_mode, UINT request)
+{
+ if (install_mode == msidbRemoveFileInstallModeOnInstall &&
+ request == INSTALLSTATE_LOCAL)
+ return TRUE;
+
+ if (install_mode == msidbRemoveFileInstallModeOnRemove &&
+ request == INSTALLSTATE_ABSENT)
+ return TRUE;
+
+ if (install_mode == msidbRemoveFileInstallModeOnBoth)
+ return TRUE;
+
+ return FALSE;
+}
+
+static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param)
+{
+ MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSICOMPONENT *comp;
+ LPCWSTR component, filename, dirprop;
+ UINT install_mode;
+ LPWSTR dir = NULL, path = NULL;
+ DWORD size;
+ UINT r;
+
+ static const WCHAR backslash[] = {'\\',0};
+
+ component = MSI_RecordGetString(row, 2);
+ filename = MSI_RecordGetString(row, 3);
+ dirprop = MSI_RecordGetString(row, 4);
+ install_mode = MSI_RecordGetInteger(row, 5);
+
+ TRACE("Removing %s\n", debugstr_w(filename));
+
+ comp = get_loaded_component(package,component);
+ if (!comp)
+ {
+ ERR("Invalid component: %s\n", debugstr_w(component));
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ if (!verify_comp_for_removal(install_mode, comp->ActionRequest))
+ {
+ TRACE("Skipping removal due to missing conditions\n");
+ comp->Action = comp->Installed;
+ return ERROR_SUCCESS;
+ }
+
+ dir = msi_dup_property(package, dirprop);
+ if (!dir)
+ return ERROR_OUTOFMEMORY;
+
+ size = lstrlenW(filename) + lstrlenW(dir) + 2;
+ path = msi_alloc(size * sizeof(WCHAR));
+ if (!path)
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ lstrcpyW(path, dir);
+ lstrcatW(path, backslash);
+ lstrcatW(path, filename);
+
+ TRACE("Deleting misc file: %s\n", debugstr_w(path));
+ if (!DeleteFileW(path))
+ TRACE("DeleteFileW failed: %d\n", GetLastError());
+
+done:
+ msi_free(path);
+ msi_free(dir);
+ return ERROR_SUCCESS;
+}
+
+UINT ACTION_RemoveFiles( MSIPACKAGE *package )
+{
+ MSIQUERY *view;
+ UINT rc;
+
+ static const WCHAR ExecSeqQuery[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','R','e','m','o','v','e','F','i','l','e','`',0};
+
+ remove_package_files( package );
+
+ rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+ if (rc != ERROR_SUCCESS)
+ return ERROR_SUCCESS;
+
+ rc = MSI_IterateRecords(view, NULL, ITERATE_RemoveFiles, package);
+ msiobj_release(&view->hdr);
return ERROR_SUCCESS;
}
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index f77ce67..3f27247 100755
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -1671,18 +1671,18 @@ static void test_removefiles(void)
ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
ok(!pf_exists("msitest\\helium"), "File installed\n");
ok(pf_exists("msitest\\lithium"), "File not installed\n");
+ ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
+ ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
ok(pf_exists("msitest\\becquerel"), "File not installed\n");
ok(pf_exists("msitest\\dioptre"), "File not installed\n");
ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
+ ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
+ ok(!pf_exists("msitest\\block"), "File not deleted\n");
+ ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
ok(pf_exists("msitest"), "File not installed\n");
todo_wine
{
- ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
- ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
- ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
- ok(!pf_exists("msitest\\block"), "File not deleted\n");
- ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
}
create_pf("msitest\\furlong", TRUE);
@@ -1700,14 +1700,14 @@ static void test_removefiles(void)
ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
- ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
+ ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
+ ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
todo_wine
{
ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
- ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
- ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
+ ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
}
ok(delete_pf("msitest", FALSE), "File deleted\n");
diff --git a/include/msidefs.h b/include/msidefs.h
index 9e1e75d..bf80c7e 100644
--- a/include/msidefs.h
+++ b/include/msidefs.h
@@ -200,6 +200,13 @@ enum msidbServiceControlEvent
msidbServiceControlEventUninstallDelete = 0x00000080,
};
+enum msidbRemoveFileInstallMode
+{
+ msidbRemoveFileInstallModeOnInstall = 0x00000001,
+ msidbRemoveFileInstallModeOnRemove = 0x00000002,
+ msidbRemoveFileInstallModeOnBoth = 0x00000003,
+};
+
/*
* Windows SDK braindamage alert
*
--
1.4.1
More information about the wine-patches
mailing list