msi: Add support for importing and exporting the special _ForceCodepage table.
This commit is contained in:
parent
18c55dee35
commit
c3adb72820
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue