msi: Return a remote interface to the database in a custom action.

This commit is contained in:
James Hawkins 2007-11-11 18:13:08 -06:00 committed by Alexandre Julliard
parent 7dffb518c0
commit 0e29f314f5
7 changed files with 331 additions and 13 deletions

View file

@ -34,6 +34,7 @@
#include "msipriv.h"
#include "objidl.h"
#include "objbase.h"
#include "msiserver.h"
#include "initguid.h"
@ -722,7 +723,19 @@ UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, LPCWSTR szFolder, LPCWSTR szFil
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiDatabaseImport not allowed during a custom action!\n");
return ERROR_SUCCESS;
}
r = MSI_DatabaseImport( db, szFolder, szFilename );
msiobj_release( &db->hdr );
return r;
@ -908,7 +921,19 @@ UINT WINAPI MsiDatabaseExportW( MSIHANDLE handle, LPCWSTR szTable,
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiDatabaseExport not allowed during a custom action!\n");
return ERROR_SUCCESS;
}
r = MSI_DatabaseExport( db, szTable, szFolder, szFilename );
msiobj_release( &db->hdr );
return r;
@ -962,11 +987,137 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle )
TRACE("%ld\n", handle);
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if (!db)
return MSIDBSTATE_ERROR;
if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return MSIDBSTATE_ERROR;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiGetDatabaseState not allowed during a custom action!\n");
return MSIDBSTATE_READ;
}
if (db->mode != MSIDBOPEN_READONLY )
ret = MSIDBSTATE_WRITE;
msiobj_release( &db->hdr );
return ret;
}
typedef struct _msi_remote_database_impl {
const IWineMsiRemoteDatabaseVtbl *lpVtbl;
MSIHANDLE database;
LONG refs;
} msi_remote_database_impl;
static inline msi_remote_database_impl* mrd_from_IWineMsiRemoteDatabase( IWineMsiRemoteDatabase* iface )
{
return (msi_remote_database_impl *)iface;
}
static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface,
REFIID riid,LPVOID *ppobj)
{
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
IsEqualCLSID( riid, &IID_IWineMsiRemoteDatabase ) )
{
IUnknown_AddRef( iface );
*ppobj = iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI mrd_AddRef( IWineMsiRemoteDatabase *iface )
{
msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface );
return InterlockedIncrement( &This->refs );
}
static ULONG WINAPI mrd_Release( IWineMsiRemoteDatabase *iface )
{
msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface );
ULONG r;
r = InterlockedDecrement( &This->refs );
if (r == 0)
{
MsiCloseHandle( This->database );
msi_free( This );
}
return r;
}
HRESULT WINAPI mrd_IsTablePersistent( IWineMsiRemoteDatabase *iface,
BSTR table, MSICONDITION *persistent )
{
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
*persistent = MsiDatabaseIsTablePersistentW(This->database, (LPWSTR)table);
return S_OK;
}
HRESULT WINAPI mrd_GetPrimaryKeys( IWineMsiRemoteDatabase *iface,
BSTR table, MSIHANDLE *keys )
{
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
UINT r = MsiDatabaseGetPrimaryKeysW(This->database, (LPWSTR)table, keys);
return HRESULT_FROM_WIN32(r);
}
HRESULT WINAPI mrd_GetSummaryInformation( IWineMsiRemoteDatabase *iface,
UINT updatecount, MSIHANDLE *suminfo )
{
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
UINT r = MsiGetSummaryInformationW(This->database, NULL, updatecount, suminfo);
return HRESULT_FROM_WIN32(r);
}
HRESULT WINAPI mrd_OpenView( IWineMsiRemoteDatabase *iface,
BSTR query, MSIHANDLE *view )
{
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
UINT r = MsiDatabaseOpenViewW(This->database, (LPWSTR)query, view);
return HRESULT_FROM_WIN32(r);
}
static HRESULT WINAPI mrd_SetMsiHandle( IWineMsiRemoteDatabase *iface, MSIHANDLE handle )
{
msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface );
This->database = handle;
return S_OK;
}
static const IWineMsiRemoteDatabaseVtbl msi_remote_database_vtbl =
{
mrd_QueryInterface,
mrd_AddRef,
mrd_Release,
mrd_IsTablePersistent,
mrd_GetPrimaryKeys,
mrd_GetSummaryInformation,
mrd_OpenView,
mrd_SetMsiHandle,
};
HRESULT create_msi_remote_database( IUnknown *pOuter, LPVOID *ppObj )
{
msi_remote_database_impl *This;
This = msi_alloc( sizeof *This );
if (!This)
return E_OUTOFMEMORY;
This->lpVtbl = &msi_remote_database_vtbl;
This->database = 0;
This->refs = 1;
*ppObj = This;
return S_OK;
}

View file

@ -588,6 +588,7 @@ UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz );
extern ITypeLib *get_msi_typelib( LPWSTR *path );
extern HRESULT create_msi_custom_remote( IUnknown *pOuter, LPVOID *ppObj );
extern HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj );
extern HRESULT create_msi_remote_database( IUnknown *pOuter, LPVOID *ppObj );
extern IUnknown *msi_get_remote(MSIHANDLE handle);
/* handle functions */

View file

@ -35,6 +35,7 @@
#include "winnls.h"
#include "query.h"
#include "msiserver.h"
#include "initguid.h"
@ -250,7 +251,27 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
HRESULT hr;
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
hr = IWineMsiRemoteDatabase_OpenView( remote_database, (BSTR)szQuery, phView );
IWineMsiRemoteDatabase_Release( remote_database );
if (FAILED(hr))
{
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
return HRESULT_CODE(hr);
return ERROR_FUNCTION_FAILED;
}
return ERROR_SUCCESS;
}
ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
if( ret == ERROR_SUCCESS )
@ -719,7 +740,18 @@ UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb,
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiDatabaseApplyTransform not allowed during a custom action!\n");
return ERROR_SUCCESS;
}
r = MSI_DatabaseApplyTransformW( db, szTransformFile, iErrorCond );
msiobj_release( &db->hdr );
@ -770,11 +802,23 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiDatabaseCommit not allowed during a custom action!\n");
return ERROR_SUCCESS;
}
/* FIXME: lock the database */
r = MSI_CommitTables( db );
if (r != ERROR_SUCCESS) ERR("Failed to commit tables!\n");
/* FIXME: unlock the database */
@ -867,7 +911,27 @@ UINT WINAPI MsiDatabaseGetPrimaryKeysW( MSIHANDLE hdb,
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
HRESULT hr;
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
hr = IWineMsiRemoteDatabase_GetPrimaryKeys( remote_database, (BSTR)table, phRec );
IWineMsiRemoteDatabase_Release( remote_database );
if (FAILED(hr))
{
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
return HRESULT_CODE(hr);
return ERROR_FUNCTION_FAILED;
}
return ERROR_SUCCESS;
}
r = MSI_DatabaseGetPrimaryKeys( db, table, &rec );
if( r == ERROR_SUCCESS )
@ -932,7 +996,24 @@ MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(
db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
if( !db )
return MSICONDITION_ERROR;
{
HRESULT hr;
MSICONDITION condition;
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hDatabase );
if ( !remote_database )
return MSICONDITION_ERROR;
hr = IWineMsiRemoteDatabase_IsTablePersistent( remote_database,
(BSTR)szTableName, &condition );
IWineMsiRemoteDatabase_Release( remote_database );
if (FAILED(hr))
return MSICONDITION_ERROR;
return condition;
}
r = MSI_DatabaseIsTablePersistent( db, szTableName );

View file

@ -26,11 +26,26 @@ import "oaidl.idl";
cpp_quote("#if 0")
typedef unsigned long MSIHANDLE;
typedef int INSTALLMESSAGE;
typedef int MSICONDITION;
typedef int MSIRUNMODE;
typedef int INSTALLSTATE;
typedef WORD LANGID;
cpp_quote("#endif")
[
uuid(7BDE2046-D03B-4ffc-B84C-A098F38CFF0B),
oleautomation,
object
]
interface IWineMsiRemoteDatabase : IUnknown
{
HRESULT IsTablePersistent( [in] BSTR table, [out] MSICONDITION *persistent );
HRESULT GetPrimaryKeys( [in] BSTR table, [out] MSIHANDLE *keys );
HRESULT GetSummaryInformation( [in] UINT updatecount, [out] MSIHANDLE *suminfo );
HRESULT OpenView( [in] BSTR query, [out] MSIHANDLE *view );
HRESULT SetMsiHandle( [in] MSIHANDLE handle );
}
[
uuid(902B3592-9D08-4dfd-A593-D07C52546421),
oleautomation,

View file

@ -856,7 +856,18 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
handle = atoiW(&szPackage[1]);
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiOpenPackage not allowed during a custom action!\n");
return ERROR_FUNCTION_FAILED;
}
}
else
{
@ -1598,7 +1609,27 @@ static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE
HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle )
{
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
*handle = MsiGetActiveDatabase(This->package);
IWineMsiRemoteDatabase *rdb = NULL;
HRESULT hr;
MSIHANDLE hdb;
hr = create_msi_remote_database( NULL, (LPVOID *)&rdb );
if (FAILED(hr) || !rdb)
{
ERR("Failed to create remote database\n");
return hr;
}
hdb = MsiGetActiveDatabase(This->package);
hr = IWineMsiRemoteDatabase_SetMsiHandle( rdb, hdb );
if (FAILED(hr))
{
ERR("Failed to set the database handle\n");
return hr;
}
*handle = alloc_msi_remote_handle( (IUnknown *)rdb );
return S_OK;
}

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include <stdarg.h>
#include "windef.h"
@ -25,6 +27,7 @@
#include "winnls.h"
#include "msi.h"
#include "msipriv.h"
#include "msiserver.h"
#include "wine/debug.h"
#include "wine/unicode.h"
@ -69,7 +72,21 @@ UINT WINAPI MsiEnableUIPreview( MSIHANDLE hdb, MSIHANDLE* phPreview )
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
*phPreview = 0;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiEnableUIPreview not allowed during a custom action!\n");
return ERROR_FUNCTION_FAILED;
}
preview = MSI_EnableUIPreview( db );
if( preview )
{

View file

@ -34,6 +34,7 @@
#include "msidefs.h"
#include "msipriv.h"
#include "objidl.h"
#include "msiserver.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
@ -459,7 +460,28 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
{
db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_PARAMETER;
{
HRESULT hr;
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hDatabase );
if ( !remote_database )
return ERROR_INVALID_HANDLE;
hr = IWineMsiRemoteDatabase_GetSummaryInformation( remote_database,
uiUpdateCount, pHandle );
IWineMsiRemoteDatabase_Release( remote_database );
if (FAILED(hr))
{
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
return HRESULT_CODE(hr);
return ERROR_FUNCTION_FAILED;
}
return ERROR_SUCCESS;
}
}
si = MSI_GetSummaryInformationW( db->storage, uiUpdateCount );