Erich E. Hoover : msidb: Add support for wildcard (full database) export.
Alexandre Julliard
julliard at winehq.org
Fri Mar 15 15:20:01 CDT 2019
Module: wine
Branch: master
Commit: 63e03de9c7f093a536b48f999768b861aa5a60d9
URL: https://source.winehq.org/git/wine.git/?a=commit;h=63e03de9c7f093a536b48f999768b861aa5a60d9
Author: Erich E. Hoover <erich.e.hoover at gmail.com>
Date: Fri Mar 15 10:04:04 2019 +0100
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 at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
programs/msidb/main.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 80 insertions(+), 2 deletions(-)
diff --git a/programs/msidb/main.c b/programs/msidb/main.c
index 3916e0d..4bd065a 100644
--- a/programs/msidb/main.c
+++ b/programs/msidb/main.c
@@ -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 */
}
More information about the wine-cvs
mailing list