Commit 3d5b606d authored by Erich E. Hoover's avatar Erich E. Hoover Committed by Alexandre Julliard

msidb: Add stub tool for manipulating MSI databases.

The "Windows SDK Components for Windows Installer Developers" has a command line tool called msidb that is incredibly useful for creating, editing, and exporting MSI installer databases, think of it as winemsibuilder on steroids. This patch series implements much of the functionality of the msidb tool, maintains compatible CLI flags, and the underlying MSI functionality necessary to support these features. Jacek expressed an interest in having these patches resurrected for use by the Gecko build scripts and Austin's VS builds of Valgrind. With this patch series all the existing winemsibuilder functionality is available, plus the ability to drop streams, export the _SummaryInformation table, and export binary streams (Binary/Icon tables). A big feature of the implementation is that it allows you to edit existing installer databases, rather than just creating new ones. Signed-off-by: 's avatarErich E. Hoover <erich.e.hoover@gmail.com> Signed-off-by: 's avatarHans Leidekker <hans@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 2f149571
...@@ -1715,6 +1715,7 @@ enable_ipconfig ...@@ -1715,6 +1715,7 @@ enable_ipconfig
enable_lodctr enable_lodctr
enable_mofcomp enable_mofcomp
enable_mshta enable_mshta
enable_msidb
enable_msiexec enable_msiexec
enable_msinfo32 enable_msinfo32
enable_net enable_net
...@@ -20292,6 +20293,7 @@ wine_fn_config_makefile programs/ipconfig enable_ipconfig ...@@ -20292,6 +20293,7 @@ wine_fn_config_makefile programs/ipconfig enable_ipconfig
wine_fn_config_makefile programs/lodctr enable_lodctr wine_fn_config_makefile programs/lodctr enable_lodctr
wine_fn_config_makefile programs/mofcomp enable_mofcomp wine_fn_config_makefile programs/mofcomp enable_mofcomp
wine_fn_config_makefile programs/mshta enable_mshta wine_fn_config_makefile programs/mshta enable_mshta
wine_fn_config_makefile programs/msidb enable_msidb
wine_fn_config_makefile programs/msiexec enable_msiexec wine_fn_config_makefile programs/msiexec enable_msiexec
wine_fn_config_makefile programs/msinfo32 enable_msinfo32 wine_fn_config_makefile programs/msinfo32 enable_msinfo32
wine_fn_config_makefile programs/net enable_net wine_fn_config_makefile programs/net enable_net
...@@ -20443,6 +20445,7 @@ else ...@@ -20443,6 +20445,7 @@ else
fonts \ fonts \
loader/l_intl.nls \ loader/l_intl.nls \
loader/wine.inf \ loader/wine.inf \
programs/msidb/msidb \
programs/msiexec/msiexec \ programs/msiexec/msiexec \
programs/notepad/notepad \ programs/notepad/notepad \
programs/regedit/regedit \ programs/regedit/regedit \
......
...@@ -3938,6 +3938,7 @@ WINE_CONFIG_MAKEFILE(programs/ipconfig) ...@@ -3938,6 +3938,7 @@ WINE_CONFIG_MAKEFILE(programs/ipconfig)
WINE_CONFIG_MAKEFILE(programs/lodctr) WINE_CONFIG_MAKEFILE(programs/lodctr)
WINE_CONFIG_MAKEFILE(programs/mofcomp) WINE_CONFIG_MAKEFILE(programs/mofcomp)
WINE_CONFIG_MAKEFILE(programs/mshta) WINE_CONFIG_MAKEFILE(programs/mshta)
WINE_CONFIG_MAKEFILE(programs/msidb)
WINE_CONFIG_MAKEFILE(programs/msiexec) WINE_CONFIG_MAKEFILE(programs/msiexec)
WINE_CONFIG_MAKEFILE(programs/msinfo32) WINE_CONFIG_MAKEFILE(programs/msinfo32)
WINE_CONFIG_MAKEFILE(programs/net) WINE_CONFIG_MAKEFILE(programs/net)
...@@ -4106,6 +4107,7 @@ else ...@@ -4106,6 +4107,7 @@ else
fonts \ fonts \
loader/l_intl.nls \ loader/l_intl.nls \
loader/wine.inf \ loader/wine.inf \
programs/msidb/msidb \
programs/msiexec/msiexec \ programs/msiexec/msiexec \
programs/notepad/notepad \ programs/notepad/notepad \
programs/regedit/regedit \ programs/regedit/regedit \
......
MODULE = msidb.exe
APPMODE = -mconsole -municode
IMPORTS = msi
C_SRCS = main.c
/*
* msidb - command line tool for assembling MSI packages
*
* Copyright 2015 Erich E. Hoover
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define WIN32_LEAN_AND_MEAN
#include <stdlib.h>
#include <windows.h>
#include <msi.h>
#include <msiquery.h>
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(msidb);
struct msidb_state
{
WCHAR *database_file;
WCHAR *table_folder;
MSIHANDLE database_handle;
BOOL create_database;
};
static void show_usage( void )
{
WINE_MESSAGE(
"Usage: msidb [OPTION]...[OPTION]...\n"
"Options:\n"
" -? Show this usage message and exit.\n"
" -c Create database file (instead of opening existing file).\n"
" -d package.msi Path to the database file.\n"
" -f folder Folder in which to open/save the tables.\n"
);
}
static int valid_state( struct msidb_state *state )
{
if (state->database_file == NULL)
{
FIXME( "GUI operation is not currently supported.\n" );
return 0;
}
if (state->table_folder == NULL)
{
ERR( "No table folder specified (-f option).\n" );
show_usage();
return 0;
}
return 1;
}
static int process_argument( struct msidb_state *state, int i, int argc, WCHAR *argv[] )
{
/* msidb accepts either "-" or "/" style flags */
if (strlenW(argv[i]) != 2 || (argv[i][0] != '-' && argv[i][0] != '/'))
{
WINE_FIXME( "Table names are not currently supported.\n" );
show_usage();
exit( 1 );
}
switch( argv[i][1] )
{
case '?':
show_usage();
exit( 0 );
case 'c':
state->create_database = TRUE;
return 1;
case 'd':
if (i + 1 >= argc) return 0;
state->database_file = argv[i + 1];
return 2;
case 'f':
if (i + 1 >= argc) return 0;
state->table_folder = argv[i + 1];
return 2;
default:
break;
}
show_usage();
exit( 1 );
}
static int open_database( struct msidb_state *state )
{
LPCWSTR db_mode = state->create_database ? MSIDBOPEN_CREATE : MSIDBOPEN_TRANSACT;
UINT ret;
ret = MsiOpenDatabaseW( state->database_file, db_mode, &state->database_handle );
if (ret != ERROR_SUCCESS)
{
ERR( "Failed to open database '%s', error %d\n", wine_dbgstr_w(state->database_file), ret );
return 0;
}
return 1;
}
static void close_database( struct msidb_state *state )
{
UINT ret;
ret = MsiDatabaseCommit( state->database_handle );
if (ret != ERROR_SUCCESS)
{
ERR( "Failed to commit changes to database.\n" );
return;
}
ret = MsiCloseHandle( state->database_handle );
if (ret != ERROR_SUCCESS)
{
WARN( "Failed to close database handle.\n" );
return;
}
}
int wmain( int argc, WCHAR *argv[] )
{
struct msidb_state state;
int i, n = 1;
memset( &state, 0x0, sizeof(state) );
/* process and validate all the command line flags */
for (i = 1; n && i < argc; i += n)
n = process_argument( &state, i, argc, argv );
if (!valid_state( &state ))
return 1;
/* perform the requested operations */
if (!open_database( &state ))
{
ERR( "Failed to open database '%s'.\n", wine_dbgstr_w(state.database_file) );
return 1;
}
close_database( &state );
return 0;
}
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