Hans Leidekker : msi: Assume a file is present if the target exists with the same size and there 's no file version or hash to verify.

Alexandre Julliard julliard at winehq.org
Tue Mar 8 11:03:51 CST 2011


Module: wine
Branch: master
Commit: 429407cfb6418d64592326d21aa19a25656f2ac4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=429407cfb6418d64592326d21aa19a25656f2ac4

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Tue Mar  8 10:09:01 2011 +0100

msi: Assume a file is present if the target exists with the same size and there's no file version or hash to verify.

---

 dlls/msi/files.c         |   31 +++++++++++++++++++----------
 dlls/msi/msipriv.h       |    1 +
 dlls/msi/tests/install.c |   47 ++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 493baed..4736fce 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -119,12 +119,21 @@ static msi_file_state calculate_install_state( MSIFILE *file )
     {
         return msifs_overwrite;
     }
-    if (file->hash.dwFileHashInfoSize && msi_file_hash_matches( file ))
+    if (file->hash.dwFileHashInfoSize)
     {
-        TRACE("file hashes match, not overwriting\n");
-        return msifs_present;
+        if (msi_file_hash_matches( file ))
+        {
+            TRACE("file hashes match, not overwriting\n");
+            return msifs_hashmatch;
+        }
+        else
+        {
+            TRACE("file hashes do not match, overwriting\n");
+            return msifs_overwrite;
+        }
     }
-    return msifs_overwrite;
+    /* assume present */
+    return msifs_present;
 }
 
 static void schedule_install_files(MSIPACKAGE *package)
@@ -299,6 +308,13 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
             ERR("Unable to load media info for %s (%u)\n", debugstr_w(file->File), rc);
             return ERROR_FUNCTION_FAILED;
         }
+        if (!file->Component->Enabled) continue;
+
+        if (file->state != msifs_hashmatch && (rc = ready_media( package, file, mi )))
+        {
+            ERR("Failed to ready media for %s\n", debugstr_w(file->File));
+            goto done;
+        }
 
         if (file->state != msifs_missing && !mi->is_continuous && file->state != msifs_overwrite)
             continue;
@@ -308,13 +324,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
         {
             MSICABDATA data;
 
-            rc = ready_media(package, file, mi);
-            if (rc != ERROR_SUCCESS)
-            {
-                ERR("Failed to ready media for %s\n", debugstr_w(file->File));
-                goto done;
-            }
-
             data.mi = mi;
             data.package = package;
             data.cb = installfiles_cb;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 10f51de..096678c 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -499,6 +499,7 @@ typedef enum _msi_file_state {
     msifs_present,
     msifs_installed,
     msifs_skipped,
+    msifs_hashmatch
 } msi_file_state;
 
 typedef struct tagMSIFILE
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index ae6be76..deff5f7 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -713,7 +713,8 @@ static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttr
                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
-                                        "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
+                                        "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n"
+                                        "tiberius\t\tMSITESTDIR\t0\t\ttiberius\n";
 
 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
@@ -721,7 +722,8 @@ static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion
                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
-                                  "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
+                                  "gaius\tgaius\tgaius\t500\t\t\t16384\t4\n"
+                                  "tiberius\ttiberius\ttiberius\t500\t\t\t0\t5\n";
 
 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
@@ -729,7 +731,8 @@ static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tV
                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
-                                   "4\t4\t\ttest3.cab\tDISK3\t\n";
+                                   "4\t4\t\ttest3.cab\tDISK3\t\n"
+                                   "5\t5\t\ttest4.cab\tDISK4\t\n";
 
 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
@@ -2295,6 +2298,29 @@ static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
         return RemoveDirectoryA(path);
 }
 
+static BOOL compare_pf_data(const char *filename, const char *data, DWORD size)
+{
+    DWORD read;
+    HANDLE handle;
+    BOOL ret = FALSE;
+    char *buffer, path[MAX_PATH];
+
+    lstrcpyA(path, PROG_FILES_DIR);
+    lstrcatA(path, "\\");
+    lstrcatA(path, filename);
+
+    handle = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    buffer = HeapAlloc(GetProcessHeap(), 0, size);
+    if (buffer)
+    {
+        ReadFile(handle, buffer, size, &read, NULL);
+        if (read == size && !memcmp(data, buffer, size)) ret = TRUE;
+        HeapFree(GetProcessHeap(), 0, buffer);
+    }
+    CloseHandle(handle);
+    return ret;
+}
+
 static void delete_test_files(void)
 {
     DeleteFileA("msitest.msi");
@@ -4068,15 +4094,18 @@ static void test_missingcab(void)
     CreateDirectoryA("msitest", NULL);
     create_file("msitest\\augustus", 500);
     create_file("maximus", 500);
+    create_file("tiberius", 500);
 
     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
 
     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
+    create_cab_file("test4.cab", MEDIA_SIZE, "tiberius\0");
 
     create_pf("msitest", FALSE);
     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
+    create_pf_data("msitest\\tiberius", "abcdefgh", TRUE);
 
     r = MsiInstallProductA(msifile, NULL);
     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
@@ -4093,11 +4122,14 @@ static void test_missingcab(void)
       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
     }
     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
+    ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n");
+    ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
-    ok(delete_pf("msitest", FALSE), "File not installed\n");
+    ok(delete_pf("msitest", FALSE), "Directory not created\n");
 
     create_pf("msitest", FALSE);
     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
+    create_pf_data("msitest\\tiberius", "abcdefgh", TRUE);
     create_pf("msitest\\gaius", TRUE);
 
     r = MsiInstallProductA(msifile, "GAIUS=1");
@@ -4108,16 +4140,19 @@ static void test_missingcab(void)
         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
     }
     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
+    ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n");
+    ok(delete_pf("msitest\\tiberius", TRUE), "File removed\n");
     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
-    ok(delete_pf("msitest", FALSE), "File not installed\n");
+    ok(delete_pf("msitest", FALSE), "Directory not created\n");
 
 error:
-    delete_pf("msitest\\caesar", TRUE);
     delete_pf("msitest", FALSE);
     DeleteFile("msitest\\augustus");
     RemoveDirectory("msitest");
     DeleteFile("maximus");
+    DeleteFile("tiberius");
     DeleteFile("test1.cab");
+    DeleteFile("test4.cab");
     DeleteFile(msifile);
 }
 




More information about the wine-cvs mailing list