MSI: Remove alot of fixed length buffers

Mike McCormack mike at codeweavers.com
Wed Dec 22 03:12:15 CST 2004


OK, flushing out MSI patches as promised.

Mike


ChangeLog:
* Remove alot of fixed length buffers
-------------- next part --------------
Index: dlls/msi/action.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.c,v
retrieving revision 1.41
diff -u -r1.41 action.c
--- dlls/msi/action.c	16 Dec 2004 14:29:25 -0000	1.41
+++ dlls/msi/action.c	22 Dec 2004 10:00:09 -0000
@@ -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;
Index: dlls/msi/msipriv.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/msipriv.h,v
retrieving revision 1.31
diff -u -r1.31 msipriv.h
--- dlls/msi/msipriv.h	28 Nov 2004 14:53:46 -0000	1.31
+++ dlls/msi/msipriv.h	22 Dec 2004 10:00:09 -0000
@@ -194,6 +194,8 @@
     UINT loaded_components;
     struct tagMSIFILE *files;
     UINT loaded_files;
+    LPWSTR ActionFormat;
+    LPWSTR LastAction;
 } MSIPACKAGE;
 
 #define MSIHANDLETYPE_ANY 0
Index: dlls/msi/package.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/package.c,v
retrieving revision 1.20
diff -u -r1.20 package.c
--- dlls/msi/package.c	16 Dec 2004 14:31:59 -0000	1.20
+++ dlls/msi/package.c	22 Dec 2004 10:00:09 -0000
@@ -416,6 +416,8 @@
         package->loaded_folders = 0;
         package->loaded_components= 0;
         package->loaded_files = 0;
+        package->ActionFormat = NULL;
+        package->LastAction = NULL;
 
         /* OK, here is where we do a slew of things to the database to 
          * prep for all that is to come as a package */


More information about the wine-patches mailing list