diff options
-rw-r--r-- | include/libmsi.h | 4 | ||||
-rw-r--r-- | libmsi/database.c | 70 | ||||
-rw-r--r-- | tests/testdatabase.c | 33 | ||||
-rw-r--r-- | tests/testdatabase.ok | 3 |
4 files changed, 45 insertions, 65 deletions
diff --git a/include/libmsi.h b/include/libmsi.h index d28106c..c9a2eab 100644 --- a/include/libmsi.h +++ b/include/libmsi.h @@ -207,8 +207,8 @@ unsigned MsiSummaryInfoSetPropertyA(LibmsiObject *, unsigned, unsigned, int, uin unsigned MsiSummaryInfoSetPropertyW(LibmsiObject *, unsigned, unsigned, int, uint64_t*, const WCHAR *); #define MsiSummaryInfoSetProperty WINELIB_NAME_AW(MsiSummaryInfoSetProperty) -unsigned MsiDatabaseExportA(LibmsiObject *, const char *, const char *, const char *); -unsigned MsiDatabaseExportW(LibmsiObject *, const WCHAR *, const WCHAR *, const WCHAR *); +unsigned MsiDatabaseExportA(LibmsiObject *, const char *, int fd); +unsigned MsiDatabaseExportW(LibmsiObject *, const WCHAR *, int fd); #define MsiDatabaseExport WINELIB_NAME_AW(MsiDatabaseExport) unsigned MsiDatabaseImport(LibmsiObject *, const char *, const char *); diff --git a/libmsi/database.c b/libmsi/database.c index f4fb59a..d4e79a9 100644 --- a/libmsi/database.c +++ b/libmsi/database.c @@ -1018,7 +1018,7 @@ unsigned MsiDatabaseImport(LibmsiObject *handle, const char *szFolder, const cha return r; } -static unsigned msi_export_record( HANDLE handle, LibmsiRecord *row, unsigned start ) +static unsigned msi_export_record( int fd, LibmsiRecord *row, unsigned start ) { unsigned i, count, len, r = ERROR_SUCCESS; const char *sep; @@ -1048,14 +1048,15 @@ static unsigned msi_export_record( HANDLE handle, LibmsiRecord *row, unsigned st if (r != ERROR_SUCCESS) break; - if (!WriteFile( handle, buffer, sz, &sz, NULL )) + /* TODO full_write */ + if (write( fd, buffer, sz ) != sz) { r = ERROR_FUNCTION_FAILED; break; } sep = (i < count) ? "\t" : "\r\n"; - if (!WriteFile( handle, sep, strlen(sep), &sz, NULL )) + if (write( fd, sep, strlen(sep) ) != strlen(sep)) { r = ERROR_FUNCTION_FAILED; break; @@ -1067,10 +1068,10 @@ static unsigned msi_export_record( HANDLE handle, LibmsiRecord *row, unsigned st static unsigned msi_export_row( LibmsiRecord *row, void *arg ) { - return msi_export_record( arg, row, 1 ); + return msi_export_record( (intptr_t) arg, row, 1 ); } -static unsigned msi_export_forcecodepage( HANDLE handle, unsigned codepage ) +static unsigned msi_export_forcecodepage( int fd, unsigned codepage ) { static const char fmt[] = "\r\n\r\n%u\t_ForceCodepage\r\n"; char data[sizeof(fmt) + 10]; @@ -1079,14 +1080,14 @@ static unsigned msi_export_forcecodepage( HANDLE handle, unsigned codepage ) sprintf( data, fmt, codepage ); sz = strlen(data) + 1; - if (!WriteFile(handle, data, sz, &sz, NULL)) + if (write( fd, data, sz ) != sz) return ERROR_FUNCTION_FAILED; return ERROR_SUCCESS; } static unsigned MSI_DatabaseExport( LibmsiDatabase *db, const WCHAR *table, - const WCHAR *folder, const WCHAR *file ) + int fd) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','%','s',0 }; @@ -1094,35 +1095,15 @@ static unsigned MSI_DatabaseExport( LibmsiDatabase *db, const WCHAR *table, '_','F','o','r','c','e','C','o','d','e','p','a','g','e',0 }; LibmsiRecord *rec = NULL; LibmsiQuery *view = NULL; - WCHAR *filename; - HANDLE handle; - unsigned len, r; + unsigned r; TRACE("%p %s %s %s\n", db, debugstr_w(table), debugstr_w(folder), debugstr_w(file) ); - if( folder == NULL || file == NULL ) - return ERROR_INVALID_PARAMETER; - - len = strlenW(folder) + strlenW(file) + 2; - filename = msi_alloc(len * sizeof (WCHAR)); - if (!filename) - return ERROR_OUTOFMEMORY; - - strcpyW( filename, folder ); - strcatW( filename, szBackSlash ); - strcatW( filename, file ); - - handle = CreateFileW( filename, GENERIC_READ | GENERIC_WRITE, 0, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - msi_free( filename ); - if (handle == INVALID_HANDLE_VALUE) - return ERROR_FUNCTION_FAILED; - if (!strcmpW( table, forcecodepage )) { unsigned codepage = msi_get_string_table_codepage( db->strings ); - r = msi_export_forcecodepage( handle, codepage ); + r = msi_export_forcecodepage( fd, codepage ); goto done; } @@ -1133,7 +1114,7 @@ static unsigned MSI_DatabaseExport( LibmsiDatabase *db, const WCHAR *table, r = MSI_ViewGetColumnInfo(view, LIBMSI_COL_INFO_NAMES, &rec); if (r == ERROR_SUCCESS) { - msi_export_record( handle, rec, 1 ); + msi_export_record( fd, rec, 1 ); msiobj_release( &rec->hdr ); } @@ -1141,7 +1122,7 @@ static unsigned MSI_DatabaseExport( LibmsiDatabase *db, const WCHAR *table, r = MSI_ViewGetColumnInfo(view, LIBMSI_COL_INFO_TYPES, &rec); if (r == ERROR_SUCCESS) { - msi_export_record( handle, rec, 1 ); + msi_export_record( fd, rec, 1 ); msiobj_release( &rec->hdr ); } @@ -1150,17 +1131,16 @@ static unsigned MSI_DatabaseExport( LibmsiDatabase *db, const WCHAR *table, if (r == ERROR_SUCCESS) { MSI_RecordSetStringW( rec, 0, table ); - msi_export_record( handle, rec, 0 ); + msi_export_record( fd, rec, 0 ); msiobj_release( &rec->hdr ); } /* write out row 4 onwards, the data */ - r = MSI_IterateRecords( view, 0, msi_export_row, handle ); + r = MSI_IterateRecords( view, 0, msi_export_row, (void *)(intptr_t) fd ); msiobj_release( &view->hdr ); } done: - CloseHandle( handle ); return r; } @@ -1180,7 +1160,7 @@ done: * row4 : data <tab> data <tab> data <tab> ... data <cr> <lf> */ unsigned MsiDatabaseExportW( LibmsiObject *handle, const WCHAR *szTable, - const WCHAR *szFolder, const WCHAR *szFilename ) + int fd ) { LibmsiDatabase *db; unsigned r; @@ -1191,13 +1171,13 @@ unsigned MsiDatabaseExportW( LibmsiObject *handle, const WCHAR *szTable, db = msihandle2msiinfo( handle, LIBMSI_OBJECT_TYPE_DATABASE ); if( !db ) return ERROR_INVALID_HANDLE; - r = MSI_DatabaseExport( db, szTable, szFolder, szFilename ); + r = MSI_DatabaseExport( db, szTable, fd ); msiobj_release( &db->hdr ); return r; } unsigned MsiDatabaseExportA( LibmsiObject *handle, const char *szTable, - const char *szFolder, const char *szFilename ) + int fd ) { WCHAR *path = NULL; WCHAR *file = NULL; @@ -1214,21 +1194,7 @@ unsigned MsiDatabaseExportA( LibmsiObject *handle, const char *szTable, goto end; } - if( szFolder ) - { - path = strdupAtoW( szFolder ); - if( !path ) - goto end; - } - - if( szFilename ) - { - file = strdupAtoW( szFilename ); - if( !file ) - goto end; - } - - r = MsiDatabaseExportW( handle, table, path, file ); + r = MsiDatabaseExportW( handle, table, fd ); end: msi_free( table ); diff --git a/tests/testdatabase.c b/tests/testdatabase.c index 7995e8d..7d73933 100644 --- a/tests/testdatabase.c +++ b/tests/testdatabase.c @@ -21,6 +21,8 @@ #define COBJMACROS #include <stdio.h> +#include <fcntl.h> +#include <unistd.h> #include <windows.h> #include <libmsi.h> @@ -1327,7 +1329,7 @@ static void test_msiexport(void) LibmsiObject *hview = 0; unsigned r; const char *query; - char path[MAX_PATH]; + int fd; const char file[] = "phone.txt"; HANDLE handle; char buffer[0x100]; @@ -1369,28 +1371,28 @@ static void test_msiexport(void) r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); - GetCurrentDirectory(MAX_PATH, path); + fd = open(file, O_WRONLY | O_BINARY | O_CREAT, 0644); + ok(fd != -1, "open failed\n"); - r = MsiDatabaseExport(hdb, "phone", path, file); + r = MsiDatabaseExport(hdb, "phone", fd); ok(r == ERROR_SUCCESS, "MsiDatabaseExport failed\n"); - MsiCloseHandle(hdb); + close(fd); - strcat(path, "\\"); - strcat(path, file); + MsiCloseHandle(hdb); /* check the data that was written */ length = 0; memset(buffer, 0, sizeof buffer); - handle = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + handle = CreateFile(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (handle != INVALID_HANDLE_VALUE) { ReadFile(handle, buffer, sizeof buffer, &length, NULL); CloseHandle(handle); - DeleteFile(path); + DeleteFile(file); } else - ok(0, "failed to open file %s\n", path); + ok(0, "failed to open file %s\n", file); ok( length == strlen(expected), "length of data wrong\n"); ok( !strcmp(buffer, expected), "data doesn't match\n"); @@ -7086,6 +7088,7 @@ static void test_forcecodepage(void) const char *query; char buffer[MAX_PATH]; unsigned r; + int fd; DeleteFile(msifile); GetCurrentDirectoryA(MAX_PATH, CURR_DIR); @@ -7121,8 +7124,12 @@ static void test_forcecodepage(void) r = run_query(hdb, 0, query); ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); - r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); + fd = open("forcecodepage.idt", O_WRONLY | O_BINARY | O_CREAT, 0644); + ok(fd != -1, "cannot open file\n"); + + r = MsiDatabaseExport(hdb, "_ForceCodepage", fd); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + close(fd); read_file_data("forcecodepage.idt", buffer); ok(!strcmp(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"), @@ -7133,8 +7140,12 @@ static void test_forcecodepage(void) r = MsiDatabaseImport(hdb, CURR_DIR, "forcecodepage.idt"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); + fd = open("forcecodepage.idt", O_WRONLY | O_BINARY | O_CREAT, 0644); + ok(fd != -1, "cannot open file\n"); + + r = MsiDatabaseExport(hdb, "_ForceCodepage", fd); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + close(fd); read_file_data("forcecodepage.idt", buffer); ok(!strcmp(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"), diff --git a/tests/testdatabase.ok b/tests/testdatabase.ok index d96f81f..134fcc9 100644 --- a/tests/testdatabase.ok +++ b/tests/testdatabase.ok @@ -330,6 +330,7 @@ ok: r == ERROR_SUCCESS ok: r == ERROR_SUCCESS
ok: r == ERROR_SUCCESS
ok: r == ERROR_SUCCESS
+ok: fd != -1
ok: r == ERROR_SUCCESS
ok: length == strlen(expected)
ok: !strcmp(buffer, expected)
@@ -2383,9 +2384,11 @@ ok: r == ERROR_SUCCESS ok: r == ERROR_BAD_QUERY_SYNTAX
ok: r == ERROR_SUCCESS
ok: r == ERROR_BAD_QUERY_SYNTAX
+ok: fd != -1
ok: r == ERROR_SUCCESS
ok: !strcmp(buffer, "\r\n\r\n0\t_ForceCodepage\r\n")
ok: r == ERROR_SUCCESS
+ok: fd != -1
ok: r == ERROR_SUCCESS
ok: !strcmp(buffer, "\r\n\r\n850\t_ForceCodepage\r\n")
ok: r == ERROR_FUNCTION_FAILED
|