[PATCH 3/9] msi: Break out field exporting into a separate routine.

Hans Leidekker hans at codeweavers.com
Fri Mar 15 04:03:58 CDT 2019


From: "Erich E. Hoover" <erich.e.hoover at gmail.com>

msi_export_record is a lot more complicated than necessary, this patch
splits out the field export part of that functionality as
msi_export_field.  This also needs to be separate for exporting binary
stream data (next patch).

v2: Fix memory leak on error path.

Signed-off-by: Erich E. Hoover <erich.e.hoover at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/msi/database.c | 74 +++++++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 29 deletions(-)

diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index 589dce510d..f302610771 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -918,50 +918,66 @@ end:
     return r;
 }
 
-static UINT msi_export_record( HANDLE handle, MSIRECORD *row, UINT start )
+static UINT msi_export_field( HANDLE handle, MSIRECORD *row, UINT field )
 {
-    UINT i, count, len, r = ERROR_SUCCESS;
-    const char *sep;
     char *buffer;
-    DWORD sz;
+    BOOL ret;
+    DWORD sz = 0x100;
+    UINT r;
 
-    len = 0x100;
-    buffer = msi_alloc( len );
-    if ( !buffer )
+    buffer = msi_alloc( sz );
+    if (!buffer)
         return ERROR_OUTOFMEMORY;
 
-    count = MSI_RecordGetFieldCount( row );
-    for ( i=start; i<=count; i++ )
+    r = MSI_RecordGetStringA( row, field, buffer, &sz );
+    if (r == ERROR_MORE_DATA)
     {
-        sz = len;
-        r = MSI_RecordGetStringA( row, i, buffer, &sz );
-        if (r == ERROR_MORE_DATA)
+        char *tmp;
+
+        sz++; /* leave room for NULL terminator */
+        tmp = msi_realloc( buffer, sz );
+        if (!tmp)
         {
-            char *p = msi_realloc( buffer, sz + 1 );
-            if (!p)
-                break;
-            len = sz + 1;
-            buffer = p;
+            msi_free( buffer );
+            return ERROR_OUTOFMEMORY;
         }
-        sz = len;
-        r = MSI_RecordGetStringA( row, i, buffer, &sz );
-        if (r != ERROR_SUCCESS)
-            break;
+        buffer = tmp;
 
-        if (!WriteFile( handle, buffer, sz, &sz, NULL ))
+        r = MSI_RecordGetStringA( row, field, buffer, &sz );
+        if (r != ERROR_SUCCESS)
         {
-            r = ERROR_FUNCTION_FAILED;
-            break;
+            msi_free( buffer );
+            return r;
         }
+    }
+    else if (r != ERROR_SUCCESS)
+    {
+        msi_free( buffer );
+        return r;
+    }
+
+    ret = WriteFile( handle, buffer, sz, &sz, NULL );
+    msi_free( buffer );
+    return ret ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED;
+}
+
+static UINT msi_export_record( HANDLE handle, MSIRECORD *row, UINT start )
+{
+    UINT i, count, r = ERROR_SUCCESS;
+    const char *sep;
+    DWORD sz;
+
+    count = MSI_RecordGetFieldCount( row );
+    for (i = start; i <= count; i++)
+    {
+        r = msi_export_field( handle, row, i );
+        if (r != ERROR_SUCCESS)
+            return r;
 
         sep = (i < count) ? "\t" : "\r\n";
         if (!WriteFile( handle, sep, strlen(sep), &sz, NULL ))
-        {
-            r = ERROR_FUNCTION_FAILED;
-            break;
-        }
+            return ERROR_FUNCTION_FAILED;
     }
-    msi_free( buffer );
     return r;
 }
 
-- 
2.20.1




More information about the wine-devel mailing list