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 @@
*/
#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;
}
......
......@@ -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 );
......
......@@ -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;
}
......@@ -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);
......
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