Module: wine Branch: master Commit: c3adb7282040944757957192d608bc4c41bbbfa5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c3adb7282040944757957192d6...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Nov 17 10:58:10 2010 +0100
msi: Add support for importing and exporting the special _ForceCodepage table.
---
dlls/msi/database.c | 21 ++++++++++++++++----- dlls/msi/msipriv.h | 2 ++ dlls/msi/string.c | 30 ++++++++++++++++++++++++++---- dlls/msi/tests/db.c | 25 ++++++++++++++++++++----- 4 files changed, 64 insertions(+), 14 deletions(-)
diff --git a/dlls/msi/database.c b/dlls/msi/database.c index 2bf70c0..886a955 100644 --- a/dlls/msi/database.c +++ b/dlls/msi/database.c @@ -19,6 +19,7 @@ */
#include <stdarg.h> +#include <stdio.h>
#define COBJMACROS #define NONAMELESSUNION @@ -888,6 +889,8 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
static const WCHAR suminfo[] = {'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0}; + static const WCHAR forcecodepage[] = + {'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0};
TRACE("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) );
@@ -910,6 +913,13 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file) msi_parse_line( &ptr, &types, &num_types ); msi_parse_line( &ptr, &labels, &num_labels );
+ if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] && + num_types == 2 && !strcmpW( types[1], forcecodepage )) + { + r = msi_set_string_table_codepage( db->strings, atoiW( types[0] ) ); + goto done; + } + if (num_columns != num_types) { r = ERROR_FUNCTION_FAILED; @@ -1087,13 +1097,13 @@ static UINT msi_export_row( MSIRECORD *row, void *arg ) return msi_export_record( arg, row, 1 ); }
-static UINT msi_export_forcecodepage( HANDLE handle ) +static UINT msi_export_forcecodepage( HANDLE handle, UINT codepage ) { + static const char fmt[] = "\r\n\r\n%u\t_ForceCodepage\r\n"; + char data[sizeof(fmt) + 10]; DWORD sz;
- static const char data[] = "\r\n\r\n0\t_ForceCodepage\r\n"; - - FIXME("Read the codepage from the strings table!\n"); + sprintf( data, fmt, codepage );
sz = lstrlenA(data) + 1; if (!WriteFile(handle, data, sz, &sz, NULL)) @@ -1138,7 +1148,8 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table,
if (!strcmpW( table, forcecodepage )) { - r = msi_export_forcecodepage( handle ); + UINT codepage = msi_get_string_table_codepage( db->strings ); + r = msi_export_forcecodepage( handle, codepage ); goto done; }
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 986097f..bed321e 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -704,6 +704,8 @@ extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ); extern HRESULT msi_init_string_table( IStorage *stg ); extern string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref ); extern UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *bytes_per_strref ); +extern UINT msi_get_string_table_codepage( const string_table *st ); +extern UINT msi_set_string_table_codepage( string_table *st, UINT codepage );
extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ); extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ); diff --git a/dlls/msi/string.c b/dlls/msi/string.c index 0c35fa4..4068033 100644 --- a/dlls/msi/string.c +++ b/dlls/msi/string.c @@ -58,15 +58,22 @@ struct string_table UINT *sorted; /* index */ };
+static BOOL validate_codepage( UINT codepage ) +{ + if (codepage != CP_ACP && !IsValidCodePage( codepage )) + { + WARN("invalid codepage %u\n", codepage); + return FALSE; + } + return TRUE; +} + static string_table *init_stringtable( int entries, UINT codepage ) { string_table *st;
- if (codepage != CP_ACP && !IsValidCodePage(codepage)) - { - ERR("invalid codepage %d\n", codepage); + if (!validate_codepage( codepage )) return NULL; - }
st = msi_alloc( sizeof (string_table) ); if( !st ) @@ -671,3 +678,18 @@ err:
return ret; } + +UINT msi_get_string_table_codepage( const string_table *st ) +{ + return st->codepage; +} + +UINT msi_set_string_table_codepage( string_table *st, UINT codepage ) +{ + if (validate_codepage( codepage )) + { + st->codepage = codepage; + return ERROR_SUCCESS; + } + return ERROR_FUNCTION_FAILED; +} diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 4cd63c4..7ab4ff3 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -6968,6 +6968,7 @@ static void test_forcecodepage(void) UINT r;
DeleteFile(msifile); + GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -7005,7 +7006,24 @@ static void test_forcecodepage(void)
read_file_data("forcecodepage.idt", buffer); ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"), - "Expected "\r\n\r\n0\t_ForceCodepage\r\n", got "%s"", buffer); + "Expected "\r\n\r\n0\t_ForceCodepage\r\n", got "%s"\n", buffer); + + create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); + + r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + read_file_data("forcecodepage.idt", buffer); + ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"), + "Expected "\r\n\r\n850\t_ForceCodepage\r\n", got "%s"\n", buffer); + + create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0); + + r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); + ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_SUCCESS, got %d\n", r);
MsiCloseHandle(hdb); DeleteFileA(msifile); @@ -8159,10 +8177,7 @@ static void test_dbmerge(void)
GetCurrentDirectoryA(MAX_PATH, buf); r = MsiDatabaseImportA(hdb, buf, "codepage.idt"); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
query = "DROP TABLE `One`"; r = run_query(hdb, 0, query);