Module: wine Branch: master Commit: e64a699b07a73c5f360c1a8d14b7fdf6ad0ac436 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e64a699b07a73c5f360c1a8d14...
Author: James Hawkins jhawkins@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 *