Commit c3adb728 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Add support for importing and exporting the special _ForceCodepage table.

parent 18c55dee
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#define COBJMACROS #define COBJMACROS
#define NONAMELESSUNION #define NONAMELESSUNION
...@@ -888,6 +889,8 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file) ...@@ -888,6 +889,8 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
static const WCHAR suminfo[] = static const WCHAR suminfo[] =
{'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0}; {'_','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) ); 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) ...@@ -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, &types, &num_types );
msi_parse_line( &ptr, &labels, &num_labels ); 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) if (num_columns != num_types)
{ {
r = ERROR_FUNCTION_FAILED; r = ERROR_FUNCTION_FAILED;
...@@ -1087,13 +1097,13 @@ static UINT msi_export_row( MSIRECORD *row, void *arg ) ...@@ -1087,13 +1097,13 @@ static UINT msi_export_row( MSIRECORD *row, void *arg )
return msi_export_record( arg, row, 1 ); 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; DWORD sz;
static const char data[] = "\r\n\r\n0\t_ForceCodepage\r\n"; sprintf( data, fmt, codepage );
FIXME("Read the codepage from the strings table!\n");
sz = lstrlenA(data) + 1; sz = lstrlenA(data) + 1;
if (!WriteFile(handle, data, sz, &sz, NULL)) if (!WriteFile(handle, data, sz, &sz, NULL))
...@@ -1138,7 +1148,8 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, ...@@ -1138,7 +1148,8 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table,
if (!strcmpW( table, forcecodepage )) 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; goto done;
} }
......
...@@ -704,6 +704,8 @@ extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ); ...@@ -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 HRESULT msi_init_string_table( IStorage *stg );
extern string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref ); 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_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 BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name );
extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ); extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table );
......
...@@ -58,15 +58,22 @@ struct string_table ...@@ -58,15 +58,22 @@ struct string_table
UINT *sorted; /* index */ 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 ) static string_table *init_stringtable( int entries, UINT codepage )
{ {
string_table *st; string_table *st;
if (codepage != CP_ACP && !IsValidCodePage(codepage)) if (!validate_codepage( codepage ))
{
ERR("invalid codepage %d\n", codepage);
return NULL; return NULL;
}
st = msi_alloc( sizeof (string_table) ); st = msi_alloc( sizeof (string_table) );
if( !st ) if( !st )
...@@ -671,3 +678,18 @@ err: ...@@ -671,3 +678,18 @@ err:
return ret; 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;
}
...@@ -6968,6 +6968,7 @@ static void test_forcecodepage(void) ...@@ -6968,6 +6968,7 @@ static void test_forcecodepage(void)
UINT r; UINT r;
DeleteFile(msifile); DeleteFile(msifile);
GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
...@@ -7005,7 +7006,24 @@ static void test_forcecodepage(void) ...@@ -7005,7 +7006,24 @@ static void test_forcecodepage(void)
read_file_data("forcecodepage.idt", buffer); read_file_data("forcecodepage.idt", buffer);
ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"), 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); MsiCloseHandle(hdb);
DeleteFileA(msifile); DeleteFileA(msifile);
...@@ -8159,10 +8177,7 @@ static void test_dbmerge(void) ...@@ -8159,10 +8177,7 @@ static void test_dbmerge(void)
GetCurrentDirectoryA(MAX_PATH, buf); GetCurrentDirectoryA(MAX_PATH, buf);
r = MsiDatabaseImportA(hdb, buf, "codepage.idt"); 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`"; query = "DROP TABLE `One`";
r = run_query(hdb, 0, query); r = run_query(hdb, 0, query);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment