msi: update target file paths on MsiSetTargetPath (for TARGETDIR)

Andrey Turkin pancha at mail.nnov.ru
Thu Sep 21 22:12:00 CDT 2006


MsiSetTargetPath can be used to change target path for directory after 
CostFinalize, and all affected file paths must be recalculated. James 
Hawkins sent a patch to make Wine's MSI engine do it for most cases; 
this patch fixes one remaining "corner" case with TARGETDIR, and adds 
test for it.

ChangeLog:

msi: Don't treat TargetDir specifically in resolve_folder
-------------- next part --------------
diff -aur wine-0.9.21/dlls/msi/helpers.c wine-0.9.21-my/dlls/msi/helpers.c
--- wine-0.9.21/dlls/msi/helpers.c	2006-09-13 23:10:25.000000000 +0400
+++ wine-0.9.21-my/dlls/msi/helpers.c	2006-09-22 04:26:42.000000000 +0400
@@ -216,29 +216,13 @@
     if (!name)
         return NULL;
 
-    /* special resolving for Target and Source root dir */
-    if (strcmpW(name,cszTargetDir)==0 || strcmpW(name,cszSourceDir)==0)
+    /* special resolving for Source root dir */
+    if ( strcmpW(name,cszSourceDir)==0)
     {
-        if (!source)
-        {
-            LPWSTR check_path;
-            check_path = msi_dup_property( package, cszTargetDir );
-            if (!check_path)
-            {
-                check_path = msi_dup_property( package, cszRootDrive );
-                if (set_prop)
-                    MSI_SetPropertyW(package,cszTargetDir,check_path);
-            }
-
-            /* correct misbuilt target dir */
-            path = build_directory_name(2, check_path, NULL);
-            clean_spaces_from_path( path );
-            if (strcmpiW(path,check_path)!=0)
-                MSI_SetPropertyW(package,cszTargetDir,path);
-            msi_free(check_path);
-        }
-        else
+        if (source)
             path = get_source_root( package );
+        else
+            path = NULL;
         if (folder)
             *folder = get_loaded_folder( package, name );
         return path;
@@ -251,6 +235,11 @@
     if (folder)
         *folder = f;
 
+    if (strcmpW(name, cszTargetDir)==0 && !f->ResolvedTarget && !f->Property)
+    {
+        f->Property =  msi_dup_property( package, cszRootDrive );
+    }
+
     if (!source && f->ResolvedTarget)
     {
         path = strdupW( f->ResolvedTarget );
diff -aur wine-0.9.21/dlls/msi/tests/package.c wine-0.9.21-my/dlls/msi/tests/package.c
--- wine-0.9.21/dlls/msi/tests/package.c	2006-09-13 23:10:25.000000000 +0400
+++ wine-0.9.21-my/dlls/msi/tests/package.c	2006-09-22 04:20:06.000000000 +0400
@@ -573,9 +573,11 @@
     MsiCloseHandle( rec );
 }
 
+#define ADD_SLASH(x) do { char *t; if (x[0]) {t=x+strlen(x)-1;if(t[0] != '\\' ) {t[1] ='\\';t[2] ='\0';}}} while (0)
+
 static void test_settargetpath(void)
 {
-    char tempdir[MAX_PATH+8], buffer[MAX_PATH];
+    char tempdir[MAX_PATH+8], buffer[MAX_PATH], filebuffer[MAX_PATH];
     DWORD sz;
     MSIHANDLE hpkg;
     UINT r;
@@ -601,7 +603,7 @@
     r = run_query( hdb,
             "INSERT INTO `Component`  "
             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
-            "VALUES( 'WinWorkAround', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'FL_dummycomponent')" );
+            "VALUES( 'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile')" );
     ok( r == S_OK, "cannot add dummy component: %d\n", r );
 
     r = run_query( hdb,
@@ -633,7 +635,7 @@
             "CREATE TABLE `FeatureComponents` ( "
             "`Feature_` CHAR(38) NOT NULL, "
             "`Component_` CHAR(72) NOT NULL "
-            "PRIMARY KEY `Feature_` )" );
+            "PRIMARY KEY `Feature_`,`Component_` )" );
     ok( r == S_OK, "cannot create FeatureComponents table: %d\n", r );
 
     r = run_query( hdb,
@@ -642,6 +644,12 @@
             "VALUES( 'TestFeature', 'TestComp' )" );
     ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
 
+    r = run_query( hdb,
+            "INSERT INTO `FeatureComponents` "
+            "(`Feature_`, `Component_`) "
+            "VALUES( 'TestFeature', 'RootComp' )" );
+    ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
+
     add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
     add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
 
@@ -663,6 +671,12 @@
             "(`File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence`) "
             "VALUES( 'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1 )" );
     ok( r == S_OK, "cannot add file to the File table: %d\n", r );
+    r = run_query( hdb, 
+            "INSERT INTO `File` "
+            "(`File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence`) "
+            "VALUES( 'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1 )" );
+    ok( r == S_OK, "cannot add file to the File table: %d\n", r );
+
 
     hpkg = package_from_db( hdb );
     ok( hpkg, "failed to create package\n");
@@ -690,32 +704,37 @@
 
     sz = sizeof tempdir - 1;
     r = MsiGetTargetPath( hpkg, "TARGETDIR", tempdir, &sz );
-    if ( r == S_OK )
+    ok( r == S_OK, "MsiGetTargePath failed: %d\n", r );
+
+    ADD_SLASH(tempdir);
+    sprintf( filebuffer, "%srootfile.txt", tempdir );
+    query_file_path( hpkg, "[#RootFile]", buffer );
+    ok( 0 == strcmp(buffer, filebuffer), "File paths differ: expected '%s', actual '%s'\n", filebuffer, buffer );
+    
+    if ( GetTempFileName( tempdir, "_wt", 0, buffer ) )
     {
-        if ( GetTempFileName( tempdir, "_wt", 0, buffer ) )
-        {
-            sprintf( tempdir, "%s\\subdir", buffer );
-            r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
-            ok( r == ERROR_SUCCESS, "MsiSetTargetPath on file returned %d\n", r );
+        ADD_SLASH(buffer);
+        sprintf( tempdir, "%ssubdir", buffer );
+        r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
+        ok( r == ERROR_SUCCESS, "MsiSetTargetPath on file returned %d\n", r );
 
-            r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
-            ok( r == ERROR_SUCCESS, "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
+        r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
+        ok( r == ERROR_SUCCESS, "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
 
-            DeleteFile( buffer );
+        DeleteFile( buffer );
 
-            r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
-            ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
+        r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
+        ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
 
-            r = GetFileAttributes( buffer );
-            ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
+        r = GetFileAttributes( buffer );
+        ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
 
-            r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
-            ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
-        } else {
-            trace("GetTempFileName failed, cannot do some tests\n");
-        }
-    } else {
-        trace( "MsiGetTargetPath failed: %d\n", r );
+        sprintf( filebuffer, "%srootfile.txt", buffer );
+        query_file_path( hpkg, "[#RootFile]", buffer );
+        ok( 0 == strcmp(buffer, filebuffer), "File paths differ: expected '%s', actual '%s'\n", filebuffer, buffer );
+
+        r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
+        ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
     }
 
     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two" );


More information about the wine-patches mailing list