MSI: Remove more fixed length buffers, rewrite functions to return malloc'ed memory.

Mike McCormack mike at codeweavers.com
Wed Dec 22 03:27:20 CST 2004


ChangeLog:
* Remove more fixed length buffers, rewrite functions to return 
malloc'ed memory.
-------------- next part --------------
diff -ur dlls/msi.old/action.c dlls/msi/action.c
--- dlls/msi.old/action.c	2004-12-22 18:17:15.000000000 +0900
+++ dlls/msi/action.c	2004-12-22 18:25:34.000000000 +0900
@@ -88,13 +88,13 @@
 
 typedef struct tagMSIFOLDER
 {
-    WCHAR Directory[MAX_PATH];
-    WCHAR TargetDefault[MAX_PATH];
-    WCHAR SourceDefault[MAX_PATH];
-
-    WCHAR ResolvedTarget[MAX_PATH];
-    WCHAR ResolvedSource[MAX_PATH];
-    WCHAR Property[MAX_PATH];   /* initially set property */
+    LPWSTR Directory;
+    LPWSTR TargetDefault;
+    LPWSTR SourceDefault;
+
+    LPWSTR ResolvedTarget;
+    LPWSTR ResolvedSource;
+    LPWSTR Property;   /* initially set property */
     INT   ParentIndex;
     INT   State;
         /* 0 = uninitialized */
@@ -123,7 +123,7 @@
        /* 3 = present do not replace */
        /* 4 = Installed */
     WCHAR   SourcePath[MAX_PATH];
-    WCHAR   TargetPath[MAX_PATH];
+    LPWSTR  TargetPath;
     BOOL    Temporary; 
 }MSIFILE;
 
@@ -165,7 +165,7 @@
                                 const LPWSTR target, const INT type);
 
 static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data);
-static UINT resolve_folder(MSIPACKAGE *package, LPCWSTR name, LPWSTR path, 
+static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
                            BOOL source, BOOL set_prop, MSIFOLDER **folder);
 
 static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
@@ -274,6 +274,26 @@
     return ret;
 }
 
+static LPWSTR PACKAGE_GetProperty(MSIPACKAGE *package, LPCWSTR prop)
+{
+    DWORD sz = 0;
+    LPWSTR str;
+    UINT r;
+
+    r = MSI_GetPropertyW(package, prop, NULL, &sz);
+    if (r != ERROR_SUCCESS)
+        return NULL;
+    sz++;
+    str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
+    r = MSI_GetPropertyW(package, prop, str, &sz);
+    if (r != ERROR_SUCCESS)
+    {
+        HeapFree(GetProcessHeap(),0,str);
+        str = NULL;
+    }
+    return str;
+}
+
 inline static int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )
 {
     int rc = -1;
@@ -354,7 +374,9 @@
     memset(&package->files[index],0,sizeof(MSIFILE));
 
     package->files[index].File = PACKAGE_dupstrW(name);
-    strcpyW(package->files[index].TargetPath, path);
+    if (package->files[index].TargetPath)
+        HeapFree(GetProcessHeap(),0,package->files[index].TargetPath);
+    package->files[index].TargetPath = PACKAGE_dupstrW(path);
     package->files[index].Temporary = TRUE;
 
     TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));  
@@ -625,23 +647,23 @@
 
     if (szPackagePath)   
     {
-        LPWSTR p;
-        WCHAR check[MAX_PATH];
-        WCHAR pth[MAX_PATH];
-        DWORD size;
+        LPWSTR p, check, path;
  
-        strcpyW(pth,szPackagePath);
-        p = strrchrW(pth,'\\');    
+        path = PACKAGE_dupstrW(szPackagePath);
+        p = strrchrW(path,'\\');    
         if (p)
         {
             p++;
             *p=0;
         }
 
-        size = MAX_PATH;
-        if (MSI_GetPropertyW(package,cszSourceDir,check,&size) 
-            != ERROR_SUCCESS )
-            MSI_SetPropertyW(package, cszSourceDir, pth);
+        check = PACKAGE_GetProperty(package, cszSourceDir);
+        if (check)
+        {
+            MSI_SetPropertyW(package, cszSourceDir, path);
+            HeapFree(GetProcessHeap(), 0, check);
+        }
+        HeapFree(GetProcessHeap(), 0, path);
     }
 
     if (szCommandLine)
@@ -1412,29 +1434,27 @@
 static UINT HANDLE_CustomType34(MSIPACKAGE *package, const LPWSTR source, 
                                 const LPWSTR target, const INT type)
 {
-    WCHAR filename[MAX_PATH*2];
+    LPWSTR filename, deformated;
     STARTUPINFOW si;
     PROCESS_INFORMATION info;
     BOOL rc;
-    WCHAR *deformated;
 
     memset(&si,0,sizeof(STARTUPINFOW));
 
-    rc = resolve_folder(package, source, filename, FALSE, FALSE, NULL);
-    if (rc != ERROR_SUCCESS)
-        return rc;
+    filename = resolve_folder(package, source, FALSE, FALSE, NULL);
+    if (!filename)
+        return ERROR_FUNCTION_FAILED;
 
     SetCurrentDirectoryW(filename);
+    HeapFree(GetProcessHeap(),0,filename);
 
     deformat_string(package,target,&deformated);
-    strcpyW(filename,deformated);
 
-    HeapFree(GetProcessHeap(),0,deformated);
+    TRACE("executing exe %s \n",debugstr_w(deformated));
 
-    TRACE("executing exe %s \n",debugstr_w(filename));
-
-    rc = CreateProcessW(NULL, filename, NULL, NULL, FALSE, 0, NULL,
+    rc = CreateProcessW(NULL, deformated, NULL, NULL, FALSE, 0, NULL,
                   c_collen, &si, &info);
+    HeapFree(GetProcessHeap(),0,deformated);
 
     if ( !rc )
     {
@@ -1531,7 +1551,7 @@
     while (1)
     {
         WCHAR dir[0x100];
-        WCHAR full_path[MAX_PATH];
+        LPWSTR full_path;
         DWORD sz;
         MSIRECORD *row = NULL, *uirow;
 
@@ -1553,9 +1573,8 @@
         }
 
         sz = MAX_PATH;
-        rc = resolve_folder(package,dir,full_path,FALSE,FALSE,&folder);
-
-        if (rc != ERROR_SUCCESS)
+        full_path = resolve_folder(package,dir,FALSE,FALSE,&folder);
+        if (!full_path)
         {
             ERR("Unable to resolve folder id %s\n",debugstr_w(dir));
             msiobj_release(&row->hdr);
@@ -1576,6 +1595,7 @@
         folder->State = 3;
 
         msiobj_release(&row->hdr);
+        HeapFree(GetProcessHeap(),0,full_path);
     }
     MSI_ViewClose(view);
     msiobj_release(&view->hdr);
@@ -1910,17 +1930,12 @@
 
 {
     WCHAR Query[1024] = 
-{'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','D','i','r','e','c',
-'t','o','r','y',' ','w','h','e','r','e',' ','`','D','i','r','e','c','t',
-'o','r','y','`',' ','=',' ','`',0};
-    static const WCHAR end[]={'`',0};
+        {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','D','i','r','e','c',
+         't','o','r','y',' ','w','h','e','r','e',' ','`','D','i','r','e','c','t',
+         'o','r','y','`',' ','=',' ','`','%','s','`',0};
     UINT rc;
     MSIQUERY * view;
-    WCHAR targetbuffer[0x100];
-    WCHAR *srcdir = NULL;
-    WCHAR *targetdir = NULL;
-    WCHAR parent[0x100];
-    DWORD sz=0x100;
+    LPWSTR targetdir, parent, srcdir;
     MSIRECORD * row = 0;
     INT index = -1;
     DWORD i;
@@ -1938,10 +1953,8 @@
 
     TRACE("Working to load %s\n",debugstr_w(dir));
 
-    index = package->loaded_folders; 
-
-    package->loaded_folders++;
-    if (package->loaded_folders== 1)
+    index = package->loaded_folders++;
+    if (package->loaded_folders==1)
         package->folders = HeapAlloc(GetProcessHeap(),0,
                                         sizeof(MSIFOLDER));
     else
@@ -1951,13 +1964,9 @@
 
     memset(&package->folders[index],0,sizeof(MSIFOLDER));
 
-    strcpyW(package->folders[index].Directory,dir);
-
-    strcatW(Query,dir);
-    strcatW(Query,end);
-
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    package->folders[index].Directory = PACKAGE_dupstrW(dir);
 
+    rc = ACTION_OpenQuery(package->db, &view, Query, dir);
     if (rc != ERROR_SUCCESS)
         return -1;
 
@@ -1977,9 +1986,7 @@
         return -1;
     }
 
-    sz=0x100;
-    MSI_RecordGetStringW(row,3,targetbuffer,&sz);
-    targetdir=targetbuffer;
+    targetdir = load_dynamic_stringW(row,3);
 
     /* split src and target dir */
     if (strchrW(targetdir,':'))
@@ -2012,38 +2019,34 @@
     if (srcdir && srcdir[0] == '.' && srcdir[1] == 0)
         srcdir = NULL;
 
-     if (targetdir)
-        strcpyW(package->folders[index].TargetDefault,targetdir);
-
-     if (srcdir)
-        strcpyW(package->folders[index].SourceDefault,srcdir);
-     else if (targetdir)
-        strcpyW(package->folders[index].SourceDefault,targetdir);
-
-    if (MSI_RecordIsNull(row,2))
-        parent[0]=0;
-    else
+    if (targetdir)
     {
-            sz=0x100;
-            MSI_RecordGetStringW(row,2,parent,&sz);
+        TRACE("   TargetDefault = %s\n",debugstr_w(targetdir));
+        HeapFree(GetProcessHeap(), 0, package->folders[index].TargetDefault);
+        package->folders[index].TargetDefault = PACKAGE_dupstrW(targetdir);
     }
 
-    if (parent[0]) 
+    if (srcdir)
+       package->folders[index].SourceDefault = PACKAGE_dupstrW(srcdir);
+    else if (targetdir)
+        package->folders[index].SourceDefault = PACKAGE_dupstrW(targetdir);
+    HeapFree(GetProcessHeap(), 0, targetdir);
+
+    parent = load_dynamic_stringW(row,2);
+    if (parent) 
     {
         i = load_folder(package,parent);
         package->folders[index].ParentIndex = i;
         TRACE("Parent is index %i... %s %s\n",
                     package->folders[index].ParentIndex,
-    debugstr_w(package->folders[package->folders[index].ParentIndex].Directory),
+        debugstr_w(package->folders[package->folders[index].ParentIndex].Directory),
                     debugstr_w(parent));
     }
     else
         package->folders[index].ParentIndex = -2;
+    HeapFree(GetProcessHeap(), 0, parent);
 
-    sz = MAX_PATH;
-    rc = MSI_GetPropertyW(package, dir, package->folders[index].Property, &sz);
-    if (rc != ERROR_SUCCESS)
-        package->folders[index].Property[0]=0;
+    package->folders[index].Property = PACKAGE_GetProperty(package, dir);
 
     msiobj_release(&row->hdr);
     MSI_ViewClose(view);
@@ -2052,57 +2055,97 @@
     return index;
 }
 
-static UINT resolve_folder(MSIPACKAGE *package, LPCWSTR name, LPWSTR path, 
+/*
+ *  build_directory_name()
+ *
+ *  This function is to save messing round with directory names
+ *  It handles adding backslashes between path segments, 
+ *   and can add \ at the end of the directory name if told to.
+ *
+ *  It takes a variable number of arguments.
+ *  It always allocates a new string for the result, so make sure
+ *   to free the return value when finished with it.
+ *
+ *  The first arg is the number of path segments that follow.
+ *  The arguments following count are a list of path segments.
+ *  A path segment may be NULL.
+ *
+ *  Path segments will be added with a \ seperating them.
+ *  A \ will not be added after the last segment, however if the
+ *    last segment is NULL, then the last character will be a \
+ * 
+ */
+static LPWSTR build_directory_name(DWORD count, ...)
+{
+    DWORD sz = 1, i;
+    LPWSTR dir;
+    va_list va;
+
+    va_start(va,count);
+    for(i=0; i<count; i++)
+    {
+        LPCWSTR str = va_arg(va,LPCWSTR);
+        if (str)
+            sz += strlenW(str) + 1;
+    }
+    va_end(va);
+
+    dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
+    dir[0]=0;
+
+    va_start(va,count);
+    for(i=0; i<count; i++)
+    {
+        LPCWSTR str = va_arg(va,LPCWSTR);
+        if (!str)
+            continue;
+        strcatW(dir, str);
+        if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
+            strcatW(dir, cszbs);
+    }
+    return dir;
+}
+
+static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
                            BOOL source, BOOL set_prop, MSIFOLDER **folder)
 {
     DWORD i;
-    UINT rc = ERROR_SUCCESS;
-    DWORD sz;
+    LPWSTR p, path = NULL;
 
     TRACE("Working to resolve %s\n",debugstr_w(name));
 
-    if (!path)
-        return rc;
-
     /* special resolving for Target and Source root dir */
     if (strcmpW(name,cszTargetDir)==0 || strcmpW(name,cszSourceDir)==0)
     {
         if (!source)
         {
-            sz = MAX_PATH;
-            rc = MSI_GetPropertyW(package,cszTargetDir,path,&sz);
-            if (rc != ERROR_SUCCESS)
+            path = PACKAGE_GetProperty(package,cszTargetDir);
+            if (!path)
             {
-                sz = MAX_PATH;
-                rc = MSI_GetPropertyW(package,cszRootDrive,path,&sz);
+                path = PACKAGE_GetProperty(package,cszRootDrive);
                 if (set_prop)
                     MSI_SetPropertyW(package,cszTargetDir,path);
             }
             if (folder)
                 *folder = &(package->folders[0]);
-            return rc;
+            return path;
         }
         else
         {
-            sz = MAX_PATH;
-            rc = MSI_GetPropertyW(package,cszSourceDir,path,&sz);
-            if (rc != ERROR_SUCCESS)
+            path = PACKAGE_GetProperty(package,cszSourceDir);
+            if (!path)
             {
-                sz = MAX_PATH;
-                rc = MSI_GetPropertyW(package,cszDatabase,path,&sz);
-                if (rc == ERROR_SUCCESS)
+                path = PACKAGE_GetProperty(package,cszDatabase);
+                if (path)
                 {
-                    LPWSTR ptr = strrchrW(path,'\\');
-                    if (ptr)
-                    {
-                        ptr++;
-                        *ptr = 0;
-                    }
+                    p = strrchrW(path,'\\');
+                    if (p)
+                        *p++ = 0;
                 }
             }
             if (folder)
                 *folder = &(package->folders[0]);
-            return rc;
+            return path;
         }
     }
 
@@ -2113,67 +2156,55 @@
     }
 
     if (i >= package->loaded_folders)
-        return ERROR_FUNCTION_FAILED;
+        return NULL;
 
     if (folder)
         *folder = &(package->folders[i]);
 
-    if (!source && package->folders[i].ResolvedTarget[0])
+    if (!source && package->folders[i].ResolvedTarget)
     {
-        strcpyW(path,package->folders[i].ResolvedTarget);
+        path = PACKAGE_dupstrW(package->folders[i].ResolvedTarget);
         TRACE("   already resolved to %s\n",debugstr_w(path));
-        return ERROR_SUCCESS;
+        return path;
     }
-    else if (source && package->folders[i].ResolvedSource[0])
+    else if (source && package->folders[i].ResolvedSource)
     {
-        strcpyW(path,package->folders[i].ResolvedSource);
-        return ERROR_SUCCESS;
+        path = PACKAGE_dupstrW(package->folders[i].ResolvedSource);
+        return path;
     }
-    else if (!source && package->folders[i].Property[0])
+    else if (!source && package->folders[i].Property)
     {
-        strcpyW(path,package->folders[i].Property);
+        path = PACKAGE_dupstrW(package->folders[i].Property);
         TRACE("   internally set to %s\n",debugstr_w(path));
         if (set_prop)
             MSI_SetPropertyW(package,name,path);
-        return ERROR_SUCCESS;
+        return path;
     }
 
     if (package->folders[i].ParentIndex >= 0)
     {
-        int len;
-        TRACE(" ! Parent is %s\n", debugstr_w(package->folders[
-                   package->folders[i].ParentIndex].Directory));
-        resolve_folder(package, package->folders[
-                       package->folders[i].ParentIndex].Directory, path,source,
-                       set_prop, NULL);
-
-        len = strlenW(path);
-        if (len && path[len-1] != '\\')
-            strcatW(path, cszbs);
+        LPWSTR parent = package->folders[package->folders[i].ParentIndex].Directory;
 
+        TRACE(" ! Parent is %s\n", debugstr_w(parent));
+
+        p = resolve_folder(package, parent, source, set_prop, NULL);
         if (!source)
         {
-            if (package->folders[i].TargetDefault[0])
-            {
-                strcatW(path,package->folders[i].TargetDefault);
-                strcatW(path,cszbs);
-            }
-            strcpyW(package->folders[i].ResolvedTarget,path);
+            TRACE("   TargetDefault = %s\n",debugstr_w(package->folders[i].TargetDefault));
+            path = build_directory_name(3, p, package->folders[i].TargetDefault, NULL);
+            package->folders[i].ResolvedTarget = PACKAGE_dupstrW(path);
             TRACE("   resolved into %s\n",debugstr_w(path));
             if (set_prop)
                 MSI_SetPropertyW(package,name,path);
         }
         else 
         {
-            if (package->folders[i].SourceDefault[0])
-            {
-                strcatW(path,package->folders[i].SourceDefault);
-                strcatW(path,cszbs);
-            }
-            strcpyW(package->folders[i].ResolvedSource,path);
+            path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);
+            package->folders[i].ResolvedSource = PACKAGE_dupstrW(path);
         }
+        HeapFree(GetProcessHeap(),0,p);
     }
-    return rc;
+    return path;
 }
 
 /* 
@@ -2213,7 +2244,7 @@
         while (1)
         {
             WCHAR name[0x100];
-            WCHAR path[MAX_PATH];
+            LPWSTR path;
             MSIRECORD * row = 0;
             DWORD sz;
 
@@ -2230,8 +2261,9 @@
             /* This helper function now does ALL the work */
             TRACE("Dir %s ...\n",debugstr_w(name));
             load_folder(package,name);
-            resolve_folder(package,name,path,FALSE,TRUE,NULL);
+            path = resolve_folder(package,name,FALSE,TRUE,NULL);
             TRACE("resolves to %s\n",debugstr_w(path));
+            HeapFree( GetProcessHeap(), 0, path);
 
             msiobj_release(&row->hdr);
         }
@@ -2252,15 +2284,11 @@
 
         if (comp)
         {
-            int len;
+            LPWSTR p;
+
             /* calculate target */
-            resolve_folder(package, comp->Directory, file->TargetPath, FALSE,
-                       FALSE, NULL);
-            /* make sure that the path ends in a \ */
-            len = strlenW(file->TargetPath);
-            if (len && file->TargetPath[len-1] != '\\')
-                strcatW(file->TargetPath, cszbs);
-            strcatW(file->TargetPath,file->FileName);
+            p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
+            file->TargetPath = build_directory_name(2, p, file->FileName);
 
             TRACE("file %s resolves to %s\n",
                    debugstr_w(file->File),debugstr_w(file->TargetPath));       
@@ -2681,13 +2709,12 @@
 {
     UINT rc;
     MSIFOLDER *folder;
-    WCHAR install_path[MAX_PATH];
+    LPWSTR install_path;
 
-    rc = resolve_folder(package, package->components[component].Directory,
-                        install_path, FALSE, FALSE, &folder);
-
-    if (rc != ERROR_SUCCESS)
-        return rc; 
+    install_path = resolve_folder(package, package->components[component].Directory,
+                        FALSE, FALSE, &folder);
+    if (!install_path)
+        return ERROR_FUNCTION_FAILED; 
 
     /* create the path */
     if (folder->State == 0)
@@ -2695,6 +2722,7 @@
         create_full_pathW(install_path);
         folder->State = 2;
     }
+    HeapFree(GetProcessHeap(), 0, install_path);
 
     return rc;
 }
@@ -2844,7 +2872,7 @@
         WCHAR file_key[0x100];
         WCHAR file_source[MAX_PATH];
         WCHAR dest_name[0x100];
-        WCHAR dest_path[MAX_PATH];
+        LPWSTR dest_path, dest;
         WCHAR component[0x100];
         INT component_index;
 
@@ -2906,8 +2934,11 @@
 
         if (MSI_RecordIsNull(row,5))
         {
-            strcpyW(dest_path,file_source);
-            *strrchrW(dest_path,'\\')=0;
+            LPWSTR p;
+            dest_path = PACKAGE_dupstrW(file_source);
+            p = strrchrW(dest_path,'\\');
+            if (p)
+                *p=0;
         }
         else
         {
@@ -2915,8 +2946,8 @@
             sz=0x100;
             MSI_RecordGetStringW(row,5,destkey,&sz);
             sz = 0x100;
-            rc = resolve_folder(package, destkey, dest_path,FALSE,FALSE,NULL);
-            if (rc != ERROR_SUCCESS)
+            dest_path = resolve_folder(package, destkey, FALSE,FALSE,NULL);
+            if (!dest_path)
             {
                 ERR("Unable to get destination folder\n");
                 msiobj_release(&row->hdr);
@@ -2924,7 +2955,8 @@
             }
         }
 
-        strcatW(dest_path,dest_name);
+        dest = build_directory_name(2, dest_path, dest_name);
+        HeapFree(GetProcessHeap(), 0, dest_path);
            
         TRACE("Duplicating file %s to %s\n",debugstr_w(file_source),
               debugstr_w(dest_path)); 
@@ -3279,14 +3311,11 @@
 
 static UINT ACTION_InstallInitialize(MSIPACKAGE *package)
 {
-    WCHAR level[10000];
+    LPWSTR level;
     INT install_level;
-    DWORD sz;
     DWORD i;
     INT j;
-    DWORD rc;
     LPWSTR override = NULL;
-    static const WCHAR addlocal[]={'A','D','D','L','O','C','A','L',0};
     static const WCHAR all[]={'A','L','L',0};
     static const WCHAR szlevel[] = {
         'I','N','S','T','A','L','L','L','E','V','E','L',0};
@@ -3297,20 +3326,16 @@
 
     TRACE("Checking Install Level\n");
 
-    sz = 10000;
-    if (MSI_GetPropertyW(package,szlevel,level,&sz)==ERROR_SUCCESS)
+    level = PACKAGE_GetProperty(package,szlevel);
+    if (level)
+    {
         install_level = atoiW(level);
+        HeapFree(GetProcessHeap(), 0, level);
+    }
     else
         install_level = 1;
 
-    sz = 0;
-    rc = MSI_GetPropertyW(package,szAddLocal,NULL,&sz);
-    if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
-    {
-        sz++;
-        override = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
-        MSI_GetPropertyW(package, addlocal,override,&sz);
-    }
+    override = PACKAGE_GetProperty(package,szAddLocal);
    
     /*
      * Components FeatureState defaults to FALSE. The idea is we want to 
@@ -3337,7 +3362,7 @@
             |= feature_state;
         }
     } 
-    if (override != NULL)
+    if (override)
         HeapFree(GetProcessHeap(),0,override);
     /* 
      * So basically we ONLY want to install a component if its Enabled AND
@@ -3451,7 +3476,9 @@
 
     if (cmp->KeyPath[0]==0)
     {
-        resolve_folder(package,cmp->Directory,keypath,FALSE,FALSE,NULL);
+        LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL);
+        strcpyW(keypath,p);
+        HeapFree(GetProcessHeap(),0,p);
         return;
     }
     if ((cmp->Attributes & 0x4) || (cmp->Attributes & 0x20))
@@ -3478,33 +3505,31 @@
  */
 static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
 {
-    WCHAR productcode[0x100];
+    LPWSTR productcode;
     WCHAR squished_pc[0x100];
     WCHAR squished_cc[0x100];
-    DWORD sz;
     UINT rc;
     DWORD i;
     HKEY hkey=0,hkey2=0,hkey3=0;
     static const WCHAR szProductCode[]=
-{'P','r','o','d','u','c','t','C','o','d','e',0};
+         {'P','r','o','d','u','c','t','C','o','d','e',0};
     static const WCHAR szInstaller[] = {
-'S','o','f','t','w','a','r','e','\\',
-'M','i','c','r','o','s','o','f','t','\\',
-'W','i','n','d','o','w','s','\\',
-'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
-'I','n','s','t','a','l','l','e','r',0 };
+         'S','o','f','t','w','a','r','e','\\',
+         'M','i','c','r','o','s','o','f','t','\\',
+         'W','i','n','d','o','w','s','\\',
+         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+         'I','n','s','t','a','l','l','e','r',0 };
     static const WCHAR szFeatures[] = {
-'F','e','a','t','u','r','e','s',0 };
+         'F','e','a','t','u','r','e','s',0 };
     static const WCHAR szComponents[] = {
-'C','o','m','p','o','n','e','n','t','s',0 };
+         'C','o','m','p','o','n','e','n','t','s',0 };
 
     if (!package)
         return ERROR_INVALID_HANDLE;
 
     /* writes the Component and Features values to the registry */
-    sz = 0x100;
-    rc = MSI_GetPropertyW(package,szProductCode,productcode,&sz);
-    if (rc != ERROR_SUCCESS)
+    productcode = PACKAGE_GetProperty(package,szProductCode);
+    if (!productcode)
         return ERROR_SUCCESS;
 
     squash_guid(productcode,squished_pc);
@@ -3586,6 +3611,7 @@
         }
     } 
 end:
+    HeapFree(GetProcessHeap(), 0, productcode);
     RegCloseKey(hkey2);
     RegCloseKey(hkey);
     return rc;
@@ -3665,15 +3691,16 @@
         res = LoadTypeLib(package->files[index].TargetPath,&ptLib);
         if (SUCCEEDED(res))
         {
-            WCHAR help[MAX_PATH];
+            LPWSTR help;
             WCHAR helpid[0x100];
 
             sz = 0x100;
             MSI_RecordGetStringW(row,6,helpid,&sz);
 
-            resolve_folder(package,helpid,help,FALSE,FALSE,NULL);
-
+            help = resolve_folder(package,helpid,FALSE,FALSE,NULL);
             res = RegisterTypeLib(ptLib,package->files[index].TargetPath,help);
+            HeapFree(GetProcessHeap(),0,help);
+
             if (!SUCCEEDED(res))
                 ERR("Failed to register type library %s\n",
                      debugstr_w(package->files[index].TargetPath));
@@ -3712,16 +3739,13 @@
     static const WCHAR ExecSeqQuery[] = 
         {'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','p','p','I'
         ,'d',' ','w','h','e','r','e',' ','A','p','p','I','d','=','`','%','s','`',0};
-    WCHAR Query[0x1000];
     HKEY hkey2,hkey3;
     LPWSTR buffer=0;
 
     if (!package)
         return ERROR_INVALID_HANDLE;
 
-    sprintfW(Query,ExecSeqQuery,clsid);
-
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    rc = ACTION_OpenQuery(package->db, &view, ExecSeqQuery, clsid);
     if (rc != ERROR_SUCCESS)
         return rc;
 
@@ -3751,7 +3775,7 @@
         LPWSTR deformated=0;
         UINT size; 
         static const WCHAR szRemoteServerName[] =
-{'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};
+             {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};
         buffer = load_dynamic_stringW(row,2);
         size = deformat_string(package,buffer,&deformated);
         RegSetValueExW(hkey3,szRemoteServerName,0,REG_SZ,(LPVOID)deformated,
@@ -3763,7 +3787,7 @@
     if (!MSI_RecordIsNull(row,3)) 
     {
         static const WCHAR szLocalService[] =
-{'L','o','c','a','l','S','e','r','v','i','c','e',0};
+             {'L','o','c','a','l','S','e','r','v','i','c','e',0};
         UINT size;
         buffer = load_dynamic_stringW(row,3);
         size = (strlenW(buffer)+1) * sizeof(WCHAR);
@@ -3774,7 +3798,7 @@
     if (!MSI_RecordIsNull(row,4)) 
     {
         static const WCHAR szService[] =
-{'S','e','r','v','i','c','e','P','a','r','a','m','e','t','e','r','s',0};
+             {'S','e','r','v','i','c','e','P','a','r','a','m','e','t','e','r','s',0};
         UINT size;
         buffer = load_dynamic_stringW(row,4);
         size = (strlenW(buffer)+1) * sizeof(WCHAR);
@@ -3785,7 +3809,7 @@
     if (!MSI_RecordIsNull(row,5)) 
     {
         static const WCHAR szDLL[] =
-{'D','l','l','S','u','r','r','o','g','a','t','e',0};
+             {'D','l','l','S','u','r','r','o','g','a','t','e',0};
         UINT size;
         buffer = load_dynamic_stringW(row,5);
         size = (strlenW(buffer)+1) * sizeof(WCHAR);
@@ -3796,7 +3820,7 @@
     if (!MSI_RecordIsNull(row,6)) 
     {
         static const WCHAR szActivate[] =
-{'A','c','t','i','v','a','t','e','A','s','S','t','o','r','a','g','e',0};
+             {'A','c','t','i','v','a','t','e','A','s','S','t','o','r','a','g','e',0};
         static const WCHAR szY[] = {'Y',0};
 
         if (MSI_RecordGetInteger(row,6))
@@ -3807,7 +3831,7 @@
     {
         static const WCHAR szRunAs[] = {'R','u','n','A','s',0};
         static const WCHAR szUser[] = 
-{'I','n','t','e','r','a','c','t','i','v','e',' ','U','s','e','r',0};
+             {'I','n','t','e','r','a','c','t','i','v','e',' ','U','s','e','r',0};
 
         if (MSI_RecordGetInteger(row,7))
             RegSetValueExW(hkey3,szRunAs,0,REG_SZ,(LPVOID)szUser,34);
@@ -4022,17 +4046,14 @@
     MSIQUERY * view;
     MSIRECORD * row = 0;
     static const WCHAR Query_t[] = 
-{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','P','r','o','g'
-,'I','d',' ','w','h','e','r','e',' ','P','r','o','g','I','d',' ','=',' ','`'
-,'%','s','`',0};
-    WCHAR Query[0x1000];
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','P','r','o','g'
+        ,'I','d',' ','w','h','e','r','e',' ','P','r','o','g','I','d',' ','=',' ','`'
+        ,'%','s','`',0};
 
     if (!package)
         return ERROR_INVALID_HANDLE;
 
-    sprintfW(Query,Query_t,parent);
-
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    rc = ACTION_OpenQuery(package->db, &view, Query_t, parent);
     if (rc != ERROR_SUCCESS)
         return rc;
 
@@ -4167,24 +4188,21 @@
 static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, 
                             LPWSTR FilePath)
 {
-    WCHAR ProductCode[0x100];
-    WCHAR SystemFolder[MAX_PATH];
-    DWORD sz;
-
+    LPWSTR ProductCode;
+    LPWSTR SystemFolder;
     static const WCHAR szInstaller[] = 
-{'I','n','s','t','a','l','l','e','r','\\',0};
+        {'I','n','s','t','a','l','l','e','r','\\',0};
     static const WCHAR szProductCode[] =
-{'P','r','o','d','u','c','t','C','o','d','e',0};
+        {'P','r','o','d','u','c','t','C','o','d','e',0};
     static const WCHAR szFolder[] =
-{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
+        {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
 
-    sz = 0x100;
-    MSI_GetPropertyW(package,szProductCode,ProductCode,&sz);
-    if (strlenW(ProductCode)==0)
+    ProductCode = PACKAGE_GetProperty(package,szProductCode);
+    if (!ProductCode)
         return ERROR_FUNCTION_FAILED;
 
-    sz = MAX_PATH;
-    MSI_GetPropertyW(package,szFolder,SystemFolder,&sz);
+    SystemFolder = PACKAGE_GetProperty(package,szFolder);
+
     strcatW(SystemFolder,szInstaller); 
     strcatW(SystemFolder,ProductCode);
     create_full_pathW(SystemFolder);
@@ -4192,6 +4210,8 @@
     strcpyW(FilePath,SystemFolder);
     strcatW(FilePath,cszbs);
     strcatW(FilePath,icon_name);
+    HeapFree(GetProcessHeap(),0,SystemFolder);
+    HeapFree(GetProcessHeap(),0,ProductCode);
     return ERROR_SUCCESS;
 }
 
@@ -4231,7 +4251,7 @@
 
     while (1)
     {
-        WCHAR target_file[MAX_PATH];
+        LPWSTR target_file, target_folder;
         WCHAR buffer[0x100];
         DWORD sz;
         DWORD index;
@@ -4285,14 +4305,15 @@
 
         sz = 0x100;
         MSI_RecordGetStringW(row,2,buffer,&sz);
-        resolve_folder(package, buffer,target_file,FALSE,FALSE,NULL);
+        target_folder = resolve_folder(package, buffer,FALSE,FALSE,NULL);
 
         sz = 0x100;
         MSI_RecordGetStringW(row,3,buffer,&sz);
         reduce_to_longfilename(buffer);
-        strcatW(target_file,buffer);
-        if (!strchrW(target_file,'.'))
-            strcatW(target_file,szlnk);
+        if (!strchrW(buffer,'.'))
+            strcatW(buffer,szlnk);
+        target_file = build_directory_name(2, target_folder, buffer);
+        HeapFree(GetProcessHeap(),0,target_folder);
 
         sz = 0x100;
         MSI_RecordGetStringW(row,5,buffer,&sz);
@@ -4352,12 +4373,12 @@
 
         if (!MSI_RecordIsNull(row,12))
         {
-            WCHAR Path[MAX_PATH];
-
+            LPWSTR Path;
             sz = 0x100;
             MSI_RecordGetStringW(row,12,buffer,&sz);
-            resolve_folder(package, buffer, Path, FALSE, FALSE, NULL);
+            Path = resolve_folder(package, buffer, FALSE, FALSE, NULL);
             IShellLinkW_SetWorkingDirectory(sl,Path);
+            HeapFree(GetProcessHeap(), 0, Path);
         }
 
         TRACE("Writing shortcut to %s\n",debugstr_w(target_file));
@@ -4545,22 +4566,22 @@
 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
                                 szPathBuf, DWORD* pcchPathBuf) 
 {
-    WCHAR path[MAX_PATH];
-    UINT rc;
+    LPWSTR path;
+    UINT rc = ERROR_FUNCTION_FAILED;
     MSIPACKAGE *package;
 
     TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
 
     package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
-    if( !package )
+    if (!package)
         return ERROR_INVALID_HANDLE;
-    rc = resolve_folder(package, szFolder, path, FALSE, FALSE, NULL);
+    path = resolve_folder(package, szFolder, FALSE, FALSE, NULL);
     msiobj_release( &package->hdr );
 
-    if (rc == ERROR_SUCCESS && strlenW(path) > *pcchPathBuf)
+    if (path && (strlenW(path) > *pcchPathBuf))
     {
         *pcchPathBuf = strlenW(path)+1;
-        return ERROR_MORE_DATA;
+        rc = ERROR_MORE_DATA;
     }
     else if (rc == ERROR_SUCCESS)
     {
@@ -4568,6 +4589,7 @@
         strcpyW(szPathBuf,path);
         TRACE("Returning Path %s\n",debugstr_w(path));
     }
+    HeapFree(GetProcessHeap(),0,path);
     
     return rc;
 }
@@ -4607,8 +4629,8 @@
 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
                                 szPathBuf, DWORD* pcchPathBuf) 
 {
-    WCHAR path[MAX_PATH];
-    UINT rc;
+    LPWSTR path;
+    UINT rc = ERROR_FUNCTION_FAILED;
     MSIPACKAGE *package;
 
     TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
@@ -4616,10 +4638,10 @@
     package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
     if( !package )
         return ERROR_INVALID_HANDLE;
-    rc = resolve_folder(package, szFolder, path, TRUE, FALSE, NULL);
+    path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
     msiobj_release( &package->hdr );
 
-    if (rc == ERROR_SUCCESS && strlenW(path) > *pcchPathBuf)
+    if (path && strlenW(path) > *pcchPathBuf)
     {
         *pcchPathBuf = strlenW(path)+1;
         return ERROR_MORE_DATA;
@@ -4670,7 +4692,7 @@
                              LPCWSTR szFolderPath)
 {
     DWORD i;
-    WCHAR path[MAX_PATH];
+    LPWSTR path = NULL;
     MSIFOLDER *folder;
 
     TRACE("(%p %s %s)\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
@@ -4684,19 +4706,22 @@
     if (GetFileAttributesW(szFolderPath) == INVALID_FILE_ATTRIBUTES)
         return ERROR_FUNCTION_FAILED;
 
-    resolve_folder(package,szFolder,path,FALSE,FALSE,&folder);
-
-    if (!folder)
+    path = resolve_folder(package,szFolder,FALSE,FALSE,&folder);
+    if (!path)
         return ERROR_INVALID_PARAMETER;
+    HeapFree(GetProcessHeap(),0,path);
 
     strcpyW(folder->Property,szFolderPath);
 
     for (i = 0; i < package->loaded_folders; i++)
-        package->folders[i].ResolvedTarget[0]=0;
+        package->folders[i].ResolvedTarget=NULL;
 
     for (i = 0; i < package->loaded_folders; i++)
-        resolve_folder(package, package->folders[i].Directory, path, FALSE,
+    {
+        path = resolve_folder(package, package->folders[i].Directory, FALSE,
                        TRUE, NULL);
+        HeapFree(GetProcessHeap(),0,path);
+    }
 
     return ERROR_SUCCESS;
 }
diff -ur dlls/msi.old/action.c~ dlls/msi/action.c~
--- dlls/msi.old/action.c~	2004-12-22 18:17:15.000000000 +0900
+++ dlls/msi/action.c~	2004-12-22 18:09:19.000000000 +0900
@@ -88,9 +88,9 @@
 
 typedef struct tagMSIFOLDER
 {
-    WCHAR Directory[96];
-    WCHAR TargetDefault[96];
-    WCHAR SourceDefault[96];
+    WCHAR Directory[MAX_PATH];
+    WCHAR TargetDefault[MAX_PATH];
+    WCHAR SourceDefault[MAX_PATH];
 
     WCHAR ResolvedTarget[MAX_PATH];
     WCHAR ResolvedSource[MAX_PATH];
@@ -107,12 +107,12 @@
 
 typedef struct tagMSIFILE
 {
-    WCHAR File[72];
+    LPWSTR File;
     INT ComponentIndex;
-    WCHAR FileName[MAX_PATH];
+    LPWSTR FileName;
     INT FileSize;
-    WCHAR Version[72];
-    WCHAR Language[20];
+    LPWSTR Version;
+    LPWSTR Language;
     INT Attributes;
     INT Sequence;   
 
@@ -222,12 +222,9 @@
  ********************************************************/
 inline static void reduce_to_longfilename(WCHAR* filename)
 {
-    if (strchrW(filename,'|'))
-    {
-        WCHAR newname[MAX_PATH];
-        strcpyW(newname,strchrW(filename,'|')+1);
-        strcpyW(filename,newname);
-    }
+    LPWSTR p = strchrW(filename,'|');
+    if (p)
+        memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));
 }
 
 inline static char *strdupWtoA( const WCHAR *str )
@@ -269,6 +266,11 @@
     sz ++;
     ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
     rc = MSI_RecordGetStringW(row,index,ret,&sz);
+    if (rc!=ERROR_SUCCESS)
+    {
+        HeapFree(GetProcessHeap(), 0, ret);
+        ret = NULL;
+    }
     return ret;
 }
 
@@ -320,6 +322,15 @@
     return rc;
 }
 
+static LPWSTR PACKAGE_dupstrW(LPCWSTR src)
+{
+    LPWSTR dest;
+    if (!src) return NULL;
+    dest = HeapAlloc(GetProcessHeap(), 0, (strlenW(src)+1)*sizeof(WCHAR));
+    strcpyW(dest, src);
+    return dest;
+}
+
 static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)
 {
     DWORD i;
@@ -342,8 +353,8 @@
 
     memset(&package->files[index],0,sizeof(MSIFILE));
 
-    strcpyW(package->files[index].File,name);
-    strcpyW(package->files[index].TargetPath,path);
+    package->files[index].File = PACKAGE_dupstrW(name);
+    strcpyW(package->files[index].TargetPath, path);
     package->files[index].Temporary = TRUE;
 
     TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));  
@@ -379,6 +390,53 @@
     msiobj_release(&row->hdr);
 }
 
+static UINT ACTION_OpenQuery( MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt, ... )
+{
+    LPWSTR szQuery;
+    LPCWSTR p;
+    UINT sz, rc;
+    va_list va;
+
+    /* figure out how much space we need to allocate */
+    va_start(va, fmt);
+    sz = strlenW(fmt) + 1;
+    p = fmt;
+    while (*p)
+    {
+        p = strchrW(p, '%');
+        if (!p)
+            break;
+        p++;
+        switch (*p)
+        {
+        case 's':  /* a string */
+            sz += strlenW(va_arg(va,LPCWSTR));
+            break;
+        case 'd':
+        case 'i':  /* an integer -2147483648 seems to be longest */
+            sz += 12;
+            break;
+        case '%':  /* a single % - leave it alone */
+            break;
+        default:
+            FIXME("Unhandled character type %c\n",*p);
+        }
+        p++;
+    }
+    va_end(va);
+
+    /* construct the string */
+    szQuery = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
+    va_start(va, fmt);
+    vsnprintfW(szQuery, sz, fmt, va);
+    va_end(va);
+
+    /* perform the query */
+    rc = MSI_DatabaseOpenViewW(db, szQuery, view);
+    HeapFree(GetProcessHeap(), 0, szQuery);
+    return rc;
+}
+
 static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
 {
     static const WCHAR Query_t[] = 
@@ -389,17 +447,14 @@
     UINT rc;
     MSIQUERY * view;
     MSIRECORD * row = 0;
-    static WCHAR *ActionFormat=NULL;
-    static WCHAR LastAction[0x100] = {0};
-    WCHAR Query[1024];
     LPWSTR ptr;
 
-    if (strcmpW(LastAction,action)!=0)
+    if (!package->LastAction || strcmpW(package->LastAction,action))
     {
-        sprintfW(Query,Query_t,action);
-        rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+        rc = ACTION_OpenQuery(package->db, &view, Query_t, action);
         if (rc != ERROR_SUCCESS)
             return;
+
         rc = MSI_ViewExecute(view, 0);
         if (rc != ERROR_SUCCESS)
         {
@@ -421,18 +476,22 @@
             return;
         }
 
-        if (ActionFormat)
-            HeapFree(GetProcessHeap(),0,ActionFormat);
+        /* update the cached actionformat */
+        if (package->ActionFormat)
+            HeapFree(GetProcessHeap(),0,package->ActionFormat);
+        package->ActionFormat = load_dynamic_stringW(row,3);
+
+        if (package->LastAction)
+            HeapFree(GetProcessHeap(),0,package->ActionFormat);
+        package->LastAction = PACKAGE_dupstrW(action);
 
-        ActionFormat = load_dynamic_stringW(row,3);
-        strcpyW(LastAction,action);
         msiobj_release(&row->hdr);
         MSI_ViewClose(view);
         msiobj_release(&view->hdr);
     }
 
     message[0]=0;
-    ptr = ActionFormat;
+    ptr = package->ActionFormat;
     while (*ptr)
     {
         LPWSTR ptr2;
@@ -488,12 +547,10 @@
     MSIQUERY * view;
     MSIRECORD * row = 0;
     WCHAR *ActionText=NULL;
-    WCHAR Query[1024];
 
     GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
 
-    sprintfW(Query,Query_t,action);
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    rc = ACTION_OpenQuery(package->db, &view, Query_t, action);
     if (rc != ERROR_SUCCESS)
         return;
     rc = MSI_ViewExecute(view, 0);
@@ -668,7 +725,6 @@
        'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ',
            '>',' ','%','i',' ','o','r','d','e','r',' ',
        'b','y',' ','S','e','q','u','e','n','c','e',0 };
-    WCHAR Query[1024];
     MSIRECORD * row = 0;
     static const WCHAR IVQuery[] = {
        's','e','l','e','c','t',' ','S','e','q','u','e','n','c','e',' ',
@@ -677,11 +733,11 @@
        'w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',' ',
            '`','I','n','s','t','a','l','l','V','a','l','i','d','a','t','e','`',
        0};
+    INT seq = 0;
 
+    /* get the sequence number */
     if (UIran)
     {
-        INT seq = 0;
-        
         rc = MSI_DatabaseOpenViewW(package->db, IVQuery, &view);
         if (rc != ERROR_SUCCESS)
             return rc;
@@ -703,12 +759,9 @@
         msiobj_release(&row->hdr);
         MSI_ViewClose(view);
         msiobj_release(&view->hdr);
-        sprintfW(Query,ExecSeqQuery,seq);
     }
-    else
-        sprintfW(Query,ExecSeqQuery,0);
-    
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+
+    rc = ACTION_OpenQuery(package->db, &view, ExecSeqQuery, seq);
     if (rc == ERROR_SUCCESS)
     {
         rc = MSI_ViewExecute(view, 0);
@@ -720,7 +773,7 @@
             goto end;
         }
        
-        TRACE("Running the actions \n"); 
+        TRACE("Running the actions\n"); 
 
         while (1)
         {
@@ -960,21 +1013,16 @@
     UINT rc = ERROR_SUCCESS;
     MSIQUERY * view;
     MSIRECORD * row = 0;
-    WCHAR ExecSeqQuery[1024] = 
+    WCHAR ExecSeqQuery[] = 
     {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','C','u','s','t','o'
-,'m','A','c','t','i','o','n',' ','w','h','e','r','e',' ','`','A','c','t','i'
-,'o','n','`',' ','=',' ','`',0};
-    static const WCHAR end[]={'`',0};
+        ,'m','A','c','t','i','o','n',' ','w','h','e','r','e',' ','`','A','c','t','i'
+        ,'o','n','`',' ','=',' ','`','%','s','`',0};
     UINT type;
     LPWSTR source;
     LPWSTR target;
     WCHAR *deformated=NULL;
 
-    strcatW(ExecSeqQuery,action);
-    strcatW(ExecSeqQuery,end);
-
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
-
+    rc = ACTION_OpenQuery(package->db, &view, ExecSeqQuery, action);
     if (rc != ERROR_SUCCESS)
         return rc;
 
@@ -1062,10 +1110,9 @@
         UINT rc;
         MSIQUERY * view;
         MSIRECORD * row = 0;
-        WCHAR Query[1024] =
+        WCHAR fmt[] =
         {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','B','i'
-,'n','a','r','y',' ','w','h','e','r','e',' ','N','a','m','e','=','`',0};
-        static const WCHAR end[]={'`',0};
+,'n','a','r','y',' ','w','h','e','r','e',' ','N','a','m','e','=','`','%','s','`',0};
         HANDLE the_file;
         CHAR buffer[1024];
 
@@ -1078,10 +1125,7 @@
         if (the_file == INVALID_HANDLE_VALUE)
             return ERROR_FUNCTION_FAILED;
 
-        strcatW(Query,source);
-        strcatW(Query,end);
-
-        rc = MSI_DatabaseOpenViewW( package->db, Query, &view);
+        rc = ACTION_OpenQuery(package->db, &view, fmt, source);
         if (rc != ERROR_SUCCESS)
             return rc;
 
@@ -1590,13 +1634,12 @@
     int index = package->loaded_features;
     DWORD sz;
     static const WCHAR Query1[] = {'S','E','L','E','C','T',' ','C','o','m','p',
-'o','n','e','n','t','_',' ','F','R','O','M',' ','F','e','a','t','u','r','e',
-'C','o','m','p','o','n','e','n','t','s',' ','W','H','E','R','E',' ','F','e',
-'a','t','u','r','e','_','=','\'','%','s','\'',0};
+        'o','n','e','n','t','_',' ','F','R','O','M',' ','F','e','a','t','u','r','e',
+        'C','o','m','p','o','n','e','n','t','s',' ','W','H','E','R','E',' ','F','e',
+        'a','t','u','r','e','_','=','\'','%','s','\'',0};
     static const WCHAR Query2[] = {'S','E','L','E','C','T',' ','*',' ','F','R',
-'O','M',' ','C','o','m','p','o','n','e','n','t',' ','W','H','E','R','E',' ','C',
-'o','m','p','o','n','e','n','t','=','\'','%','s','\'',0};
-    WCHAR Query[1024];
+        'O','M',' ','C','o','m','p','o','n','e','n','t',' ','W','H','E','R','E',' ','C',
+        'o','m','p','o','n','e','n','t','=','\'','%','s','\'',0};
     MSIQUERY * view;
     MSIQUERY * view2;
     MSIRECORD * row2;
@@ -1645,8 +1688,7 @@
 
     /* load feature components */
 
-    sprintfW(Query,Query1,package->features[index].Feature);
-    rc = MSI_DatabaseOpenViewW(package->db,Query,&view);
+    rc = ACTION_OpenQuery(package->db, &view, Query1, package->features[index].Feature);
     if (rc != ERROR_SUCCESS)
         return;
     rc = MSI_ViewExecute(view,0);
@@ -1681,9 +1723,7 @@
             package->features[index].ComponentCount ++;
         }
 
-        sprintfW(Query,Query2,buffer);
-   
-        rc = MSI_DatabaseOpenViewW(package->db,Query,&view2);
+        rc = ACTION_OpenQuery(package->db, &view2, Query2, buffer);
         if (rc != ERROR_SUCCESS)
         {
             msiobj_release( &row2->hdr );
@@ -1779,8 +1819,7 @@
 {
     DWORD index = package->loaded_files;
     DWORD i;
-    WCHAR buffer[0x100];
-    DWORD sz;
+    LPWSTR buffer;
 
     /* fill in the data */
 
@@ -1792,12 +1831,9 @@
             package->files , package->loaded_files * sizeof(MSIFILE));
 
     memset(&package->files[index],0,sizeof(MSIFILE));
-
-    sz = 72;       
-    MSI_RecordGetStringW(row,1,package->files[index].File,&sz);
-
-    sz = 0x100;       
-    MSI_RecordGetStringW(row,2,buffer,&sz);
+ 
+    package->files[index].File = load_dynamic_stringW(row, 1);
+    buffer = load_dynamic_stringW(row, 2);
 
     package->files[index].ComponentIndex = -1;
     for (i = 0; i < package->loaded_components; i++)
@@ -1808,25 +1844,16 @@
         }
     if (package->files[index].ComponentIndex == -1)
         ERR("Unfound Component %s\n",debugstr_w(buffer));
+    HeapFree(GetProcessHeap(), 0, buffer);
 
-    sz = MAX_PATH;       
-    MSI_RecordGetStringW(row,3,package->files[index].FileName,&sz);
+    package->files[index].FileName = load_dynamic_stringW(row,3);
 
     reduce_to_longfilename(package->files[index].FileName);
     
     package->files[index].FileSize = MSI_RecordGetInteger(row,4);
-
-    sz = 72;       
-    if (!MSI_RecordIsNull(row,5))
-        MSI_RecordGetStringW(row,5,package->files[index].Version,&sz);
-
-    sz = 20;       
-    if (!MSI_RecordIsNull(row,6))
-        MSI_RecordGetStringW(row,6,package->files[index].Language,&sz);
-
-    if (!MSI_RecordIsNull(row,7))
-        package->files[index].Attributes= MSI_RecordGetInteger(row,7);
-
+    package->files[index].Version = load_dynamic_stringW(row, 5);
+    package->files[index].Language = load_dynamic_stringW(row, 6);
+    package->files[index].Attributes= MSI_RecordGetInteger(row,7);
     package->files[index].Sequence= MSI_RecordGetInteger(row,8);
 
     package->files[index].Temporary = FALSE;
@@ -3037,19 +3064,15 @@
         static const WCHAR szHU[] =
 {'H','K','E','Y','_','U','S','E','R','S','\\',0};
 
-        WCHAR key[0x100];
-        WCHAR name[0x100];
-        LPWSTR value;
         LPSTR value_data = NULL;
         HKEY  root_key, hkey;
         DWORD type,size;
-        WCHAR component[0x100];
+        LPWSTR value, key, name, component;
+        LPCWSTR szRoot;
         INT component_index;
         MSIRECORD * uirow;
-        WCHAR uikey[0x110];
-
+        LPWSTR uikey;
         INT   root;
-        DWORD sz=0x100;
 
         rc = MSI_ViewFetch(view,&row);
         if (rc != ERROR_SUCCESS)
@@ -3058,8 +3081,12 @@
             break;
         }
 
-        sz= 0x100;
-        MSI_RecordGetStringW(row,6,component,&sz);
+        value = NULL;
+        key = NULL;
+        uikey = NULL;
+        name = NULL;
+
+        component = load_dynamic_stringW(row, 6);
         component_index = get_loaded_component(package,component);
 
         if (!package->components[component_index].Enabled ||
@@ -3067,7 +3094,7 @@
         {
             TRACE("Skipping write due to disabled component\n");
             msiobj_release(&row->hdr);
-            continue;
+            goto next;
         }
 
         /* null values have special meanings during uninstalls and such */
@@ -3075,47 +3102,50 @@
         if(MSI_RecordIsNull(row,5))
         {
             msiobj_release(&row->hdr);
-            continue;
+            goto next;
         }
 
         root = MSI_RecordGetInteger(row,2);
-        sz = 0x100;
-        MSI_RecordGetStringW(row,3,key,&sz);
+        key = load_dynamic_stringW(row, 3);
       
-        sz = 0x100; 
-        if (MSI_RecordIsNull(row,4))
-            name[0]=0;
-        else
-            MSI_RecordGetStringW(row,4,name,&sz);
+        name = load_dynamic_stringW(row, 4);
    
         /* get the root key */
         switch (root)
         {
             case 0:  root_key = HKEY_CLASSES_ROOT; 
-                     strcpyW(uikey,szHCR); break;
+                     szRoot = szHCR;
+                     break;
             case 1:  root_key = HKEY_CURRENT_USER;
-                     strcpyW(uikey,szHCU); break;
+                     szRoot = szHCU;
+                     break;
             case 2:  root_key = HKEY_LOCAL_MACHINE;
-                     strcpyW(uikey,szHLM); break;
+                     szRoot = szHLM;
+                     break;
             case 3:  root_key = HKEY_USERS; 
-                     strcpyW(uikey,szHU); break;
+                     szRoot = szHU;
+                     break;
             default:
                  ERR("Unknown root %i\n",root);
                  root_key=NULL;
+                 szRoot = NULL;
                  break;
         }
         if (!root_key)
         {
             msiobj_release(&row->hdr);
-            continue;
+            goto next;
         }
 
+        size = strlenW(key) + strlenW(szRoot) + 1;
+        uikey = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
+        strcpyW(uikey,szRoot);
         strcatW(uikey,key);
         if (RegCreateKeyW( root_key, key, &hkey))
         {
             ERR("Could not create key %s\n",debugstr_w(key));
             msiobj_release(&row->hdr);
-            continue;
+            goto next;
         }
 
         value = load_dynamic_stringW(row,5);
@@ -3145,6 +3175,15 @@
 
         msiobj_release(&row->hdr);
         RegCloseKey(hkey);
+next:
+        if (uikey)
+            HeapFree(GetProcessHeap(),0,uikey);
+        if (key)
+            HeapFree(GetProcessHeap(),0,key);
+        if (name)
+            HeapFree(GetProcessHeap(),0,name);
+        if (component)
+            HeapFree(GetProcessHeap(),0,component);
     }
     MSI_ViewClose(view);
     msiobj_release(&view->hdr);
@@ -3671,8 +3710,8 @@
     MSIQUERY * view;
     MSIRECORD * row = 0;
     static const WCHAR ExecSeqQuery[] = 
-{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','p','p','I'
-,'d',' ','w','h','e','r','e',' ','A','p','p','I','d','=','`','%','s','`',0};
+        {'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','p','p','I'
+        ,'d',' ','w','h','e','r','e',' ','A','p','p','I','d','=','`','%','s','`',0};
     WCHAR Query[0x1000];
     HKEY hkey2,hkey3;
     LPWSTR buffer=0;


More information about the wine-patches mailing list