James Hawkins : msi: Remove misc files from the RemoveFile table.
Alexandre Julliard
julliard at winehq.org
Tue Aug 19 08:46:48 CDT 2008
Module: wine
Branch: master
Commit: e64a699b07a73c5f360c1a8d14b7fdf6ad0ac436
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e64a699b07a73c5f360c1a8d14b7fdf6ad0ac436
Author: James Hawkins <jhawkins at codeweavers.com>
Date: Mon Aug 18 23:03:00 2008 -0500
msi: Remove misc files from the RemoveFile table.
---
dlls/msi/files.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/msi/tests/install.c | 26 +++++--------
include/msidefs.h | 7 ++++
3 files changed, 107 insertions(+), 16 deletions(-)
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 521cdb3..f826806 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -435,9 +435,99 @@ UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
return rc;
}
+static BOOL verify_comp_for_removal(MSICOMPONENT *comp, UINT install_mode)
+{
+ INSTALLSTATE request = comp->ActionRequest;
+
+ if (install_mode == msidbRemoveFileInstallModeOnInstall &&
+ (request == INSTALLSTATE_LOCAL || request == INSTALLSTATE_SOURCE))
+ return TRUE;
+
+ if (request == INSTALLSTATE_ABSENT)
+ {
+ if (!comp->ComponentId)
+ return FALSE;
+
+ if (install_mode == msidbRemoveFileInstallModeOnRemove)
+ 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;
+
+ component = MSI_RecordGetString(row, 2);
+ filename = MSI_RecordGetString(row, 3);
+ dirprop = MSI_RecordGetString(row, 4);
+ install_mode = MSI_RecordGetInteger(row, 5);
+
+ 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(comp, install_mode))
+ {
+ 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, 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;
MSIFILE *file;
+ UINT r;
+
+ static const WCHAR query[] = {
+ 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','R','e','m','o','v','e','F','i','l','e','`',0};
+
+ r = MSI_DatabaseOpenViewW(package->db, query, &view);
+ if (r == ERROR_SUCCESS)
+ {
+ MSI_IterateRecords(view, NULL, ITERATE_RemoveFiles, package);
+ msiobj_release(&view->hdr);
+ }
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 04f9e4b..a60b3ab 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -4206,19 +4206,16 @@ 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\\firkin"), "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\\firkin"), "File not deleted\n");
- ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
- ok(!pf_exists("msitest\\furlong"), "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);
create_pf("msitest\\firkin", TRUE);
@@ -4235,15 +4232,12 @@ static void test_removefiles(void)
ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
ok(delete_pf("msitest\\fortnight", TRUE), "File 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\\attoparsec", TRUE), "File 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");
- todo_wine
- {
- 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", FALSE), "File deleted\n");
DeleteFile(msifile);
diff --git a/include/msidefs.h b/include/msidefs.h
index 141e203..d87569f 100644
--- a/include/msidefs.h
+++ b/include/msidefs.h
@@ -215,6 +215,13 @@ enum msidbSumInfoSourceType
msidbSumInfoSourceTypeLUAPackage = 0x00000008,
};
+enum msidbRemoveFileInstallMode
+{
+ msidbRemoveFileInstallModeOnInstall = 0x00000001,
+ msidbRemoveFileInstallModeOnRemove = 0x00000002,
+ msidbRemoveFileInstallModeOnBoth = 0x00000003,
+};
+
/*
* Windows SDK braindamage alert
*
More information about the wine-cvs
mailing list