msidb: Add support for wildcard (full database) export.

msidb allows a full database export with the special "*" database
name.  Note: It does not support true wildcards, just this special
indication that you wish to export all the tables in the database.

Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Erich E. Hoover 2019-03-15 10:04:04 +01:00 committed by Alexandre Julliard
parent 2820738b29
commit 63e03de9c7
1 changed files with 80 additions and 2 deletions

View File

@ -439,7 +439,7 @@ static int import_table( struct msidb_state *state, const WCHAR *table_name )
WCHAR table_path[MAX_PATH];
UINT ret;
snprintfW( table_path, sizeof(table_path)/sizeof(WCHAR), format, table_name );
snprintfW( table_path, ARRAY_SIZE(table_path), format, table_name );
ret = MsiDatabaseImportW( state->database_handle, state->table_folder, table_path );
if (ret != ERROR_SUCCESS)
{
@ -469,7 +469,7 @@ static int export_table( struct msidb_state *state, const WCHAR *table_name )
WCHAR table_path[MAX_PATH];
UINT ret;
snprintfW( table_path, sizeof(table_path)/sizeof(WCHAR), format, table_name );
snprintfW( table_path, ARRAY_SIZE(table_path), format, table_name );
ret = MsiDatabaseExportW( state->database_handle, table_name, state->table_folder, table_path );
if (ret != ERROR_SUCCESS)
{
@ -479,12 +479,90 @@ static int export_table( struct msidb_state *state, const WCHAR *table_name )
return 1;
}
static int export_all_tables( struct msidb_state *state )
{
static const WCHAR summary_information[] =
{'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0};
static const WCHAR query_command[] =
{'S','E','L','E','C','T',' ','N','a','m','e',' ','F','R','O','M',' ','_','T','a','b','l','e','s',0};
MSIHANDLE view = 0;
UINT ret;
ret = MsiDatabaseOpenViewW( state->database_handle, query_command, &view );
if (ret != ERROR_SUCCESS)
{
ERR( "Failed to open _Tables table.\n" );
goto cleanup;
}
ret = MsiViewExecute( view, 0 );
if (ret != ERROR_SUCCESS)
{
ERR( "Failed to query list from _Tables table.\n" );
goto cleanup;
}
while( 1 )
{
MSIHANDLE record = 0;
WCHAR table[256];
DWORD size;
ret = MsiViewFetch( view, &record );
if (ret == ERROR_NO_MORE_ITEMS)
break;
if (ret != ERROR_SUCCESS)
{
ERR( "Failed to query row from _Tables table.\n" );
goto cleanup;
}
size = ARRAY_SIZE(table);
ret = MsiRecordGetStringW( record, 1, table, &size );
if (ret != ERROR_SUCCESS)
{
ERR( "Failed to retrieve name string.\n" );
goto cleanup;
}
if (!export_table( state, table ))
{
ret = ERROR_FUNCTION_FAILED;
goto cleanup;
}
ret = MsiCloseHandle( record );
if (ret != ERROR_SUCCESS)
{
ERR( "Failed to close record handle.\n" );
goto cleanup;
}
}
ret = ERROR_SUCCESS;
/* the _SummaryInformation table is not listed in _Tables */
if (!export_table( state, summary_information ))
{
ret = ERROR_FUNCTION_FAILED;
goto cleanup;
}
cleanup:
if (view && MsiViewClose( view ) != ERROR_SUCCESS)
{
ERR( "Failed to close _Streams table.\n" );
return 0;
}
return (ret == ERROR_SUCCESS);
}
static int export_tables( struct msidb_state *state )
{
const WCHAR wildcard[] = { '*',0 };
struct msidb_listentry *data;
LIST_FOR_EACH_ENTRY( data, &state->table_list, struct msidb_listentry, entry )
{
if (strcmpW( data->name, wildcard ) == 0)
{
if (!export_all_tables( state ))
return 0; /* failed, do not commit changes */
continue;
}
if (!export_table( state, data->name ))
return 0; /* failed, do not commit changes */
}