[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