From 2a6d007c655bcd3736082a8a1a1539ca464593d1 Mon Sep 17 00:00:00 2001
From: Mike McCormack <mike@codeweavers.com>
Date: Mon, 28 Nov 2005 10:37:08 +0100
Subject: [PATCH] If a source directory doesn't exist, use the install root
 instead.

---
 dlls/msi/helpers.c | 109 +++++++++++++++++++++++++++++----------------
 1 file changed, 70 insertions(+), 39 deletions(-)

diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c
index a2bfb0d7d67..2b2ba06155d 100644
--- a/dlls/msi/helpers.c
+++ b/dlls/msi/helpers.c
@@ -210,6 +210,24 @@ MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir )
     return NULL;
 }
 
+static LPWSTR get_source_root( MSIPACKAGE *package )
+{
+    LPWSTR path, p;
+
+    path = msi_dup_property( package, cszSourceDir );
+    if (path)
+        return path;
+
+    path = msi_dup_property( package, cszDatabase );
+    if (path)
+    {
+        p = strrchrW(path,'\\');
+        if (p)
+            *(p+1) = 0;
+    }
+    return path;
+}
+
 LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 
                       BOOL set_prop, MSIFOLDER **folder)
 {
@@ -221,42 +239,28 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
     if (!name)
         return NULL;
 
-    /* source directories appear to always be at the root */
-    if (source)
-    {
-        path = msi_dup_property( package, cszSourceDir );
-        if (!path)
-        {
-            path = msi_dup_property( package, cszDatabase );
-            if (path)
-            {
-                p = strrchrW(path,'\\');
-                if (p)
-                    *(p+1) = 0;
-            }
-        }
-        if (folder)
-            *folder = get_loaded_folder( package, name );
-        return path;
-    }
-
     /* special resolving for Target and Source root dir */
     if (strcmpW(name,cszTargetDir)==0 || strcmpW(name,cszSourceDir)==0)
     {
-        LPWSTR check_path;
-        check_path = msi_dup_property( package, cszTargetDir );
-        if (!check_path)
+        if (!source)
         {
-            check_path = msi_dup_property( package, cszRootDrive );
-            if (set_prop)
-                MSI_SetPropertyW(package,cszTargetDir,check_path);
-        }
+            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);
-        if (strcmpiW(path,check_path)!=0)
-            MSI_SetPropertyW(package,cszTargetDir,path);
-        msi_free(check_path);
+            /* correct misbuilt target dir */
+            path = build_directory_name(2, check_path, NULL);
+            if (strcmpiW(path,check_path)!=0)
+                MSI_SetPropertyW(package,cszTargetDir,path);
+            msi_free(check_path);
+        }
+        else
+            path = get_source_root( package );
         if (folder)
             *folder = get_loaded_folder( package, name );
         return path;
@@ -269,13 +273,19 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
     if (folder)
         *folder = f;
 
-    if (f->ResolvedTarget)
+    if (!source && f->ResolvedTarget)
     {
         path = strdupW( f->ResolvedTarget );
         TRACE("   already resolved to %s\n",debugstr_w(path));
         return path;
     }
-    else if (f->Property)
+    else if (source && f->ResolvedSource)
+    {
+        path = strdupW( f->ResolvedSource );
+        TRACE("   (source)already resolved to %s\n",debugstr_w(path));
+        return path;
+    }
+    else if (!source && f->Property)
     {
         path = build_directory_name( 2, f->Property, NULL );
                     
@@ -292,13 +302,34 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
         TRACE(" ! Parent is %s\n", debugstr_w(parent));
 
         p = resolve_folder(package, parent, source, set_prop, NULL);
-        TRACE("   TargetDefault = %s\n", debugstr_w(f->TargetDefault));
+        if (!source)
+        {
+            TRACE("   TargetDefault = %s\n", debugstr_w(f->TargetDefault));
 
-        path = build_directory_name( 3, p, f->TargetDefault, NULL );
-        f->ResolvedTarget = strdupW( path );
-        TRACE("   resolved into %s\n",debugstr_w(path));
-        if (set_prop)
-            MSI_SetPropertyW(package,name,path);
+            path = build_directory_name( 3, p, f->TargetDefault, NULL );
+            f->ResolvedTarget = strdupW( path );
+            TRACE("target -> %s\n", debugstr_w(path));
+            if (set_prop)
+                MSI_SetPropertyW(package,name,path);
+        }
+        else 
+        {
+            if (f->SourceDefault && f->SourceDefault[0]!='.')
+                path = build_directory_name( 3, p, f->SourceDefault, NULL );
+            else
+                path = strdupW(p);
+            TRACE("source -> %s\n", debugstr_w(path));
+
+            /* if the directory doesn't exist, use the root */
+            if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
+            {
+                msi_free( path );
+                path = get_source_root( package );
+                TRACE("defaulting to %s\n", debugstr_w(path));
+            }
+            else
+                f->ResolvedSource = strdupW( path );
+        }
         msi_free(p);
     }
     return path;