[4/4] msi: Add support for importing and exporting the special _ForceCodepage table.

Hans Leidekker hans at codeweavers.com
Wed Nov 17 03:58:10 CST 2010


Fixes http://bugs.winehq.org/show_bug.cgi?id=25182
---
 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);
-- 
1.7.1






More information about the wine-patches mailing list