From: "Erich E. Hoover" erich.e.hoover@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@gmail.com Signed-off-by: Hans Leidekker hans@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; }