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