Commit 0e29f314 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

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

parent 7dffb518
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "msipriv.h" #include "msipriv.h"
#include "objidl.h" #include "objidl.h"
#include "objbase.h" #include "objbase.h"
#include "msiserver.h"
#include "initguid.h" #include "initguid.h"
...@@ -722,7 +723,19 @@ UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, LPCWSTR szFolder, LPCWSTR szFil ...@@ -722,7 +723,19 @@ UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, LPCWSTR szFolder, LPCWSTR szFil
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return ERROR_INVALID_HANDLE; 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 ); r = MSI_DatabaseImport( db, szFolder, szFilename );
msiobj_release( &db->hdr ); msiobj_release( &db->hdr );
return r; return r;
...@@ -908,7 +921,19 @@ UINT WINAPI MsiDatabaseExportW( MSIHANDLE handle, LPCWSTR szTable, ...@@ -908,7 +921,19 @@ UINT WINAPI MsiDatabaseExportW( MSIHANDLE handle, LPCWSTR szTable,
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return ERROR_INVALID_HANDLE; 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 ); r = MSI_DatabaseExport( db, szTable, szFolder, szFilename );
msiobj_release( &db->hdr ); msiobj_release( &db->hdr );
return r; return r;
...@@ -962,11 +987,137 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle ) ...@@ -962,11 +987,137 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle )
TRACE("%ld\n", handle); TRACE("%ld\n", handle);
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if (!db) if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return MSIDBSTATE_ERROR; return MSIDBSTATE_ERROR;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiGetDatabaseState not allowed during a custom action!\n");
return MSIDBSTATE_READ;
}
if (db->mode != MSIDBOPEN_READONLY ) if (db->mode != MSIDBOPEN_READONLY )
ret = MSIDBSTATE_WRITE; ret = MSIDBSTATE_WRITE;
msiobj_release( &db->hdr ); msiobj_release( &db->hdr );
return ret; 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;
}
...@@ -588,6 +588,7 @@ UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz ); ...@@ -588,6 +588,7 @@ UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz );
extern ITypeLib *get_msi_typelib( LPWSTR *path ); extern ITypeLib *get_msi_typelib( LPWSTR *path );
extern HRESULT create_msi_custom_remote( IUnknown *pOuter, LPVOID *ppObj ); 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_package( IUnknown *pOuter, LPVOID *ppObj );
extern HRESULT create_msi_remote_database( IUnknown *pOuter, LPVOID *ppObj );
extern IUnknown *msi_get_remote(MSIHANDLE handle); extern IUnknown *msi_get_remote(MSIHANDLE handle);
/* handle functions */ /* handle functions */
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "winnls.h" #include "winnls.h"
#include "query.h" #include "query.h"
#include "msiserver.h"
#include "initguid.h" #include "initguid.h"
...@@ -250,8 +251,28 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, ...@@ -250,8 +251,28 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
HRESULT hr;
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE; 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 ); ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
if( ret == ERROR_SUCCESS ) if( ret == ERROR_SUCCESS )
{ {
...@@ -719,8 +740,19 @@ UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb, ...@@ -719,8 +740,19 @@ UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb,
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE; 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 ); r = MSI_DatabaseApplyTransformW( db, szTransformFile, iErrorCond );
msiobj_release( &db->hdr ); msiobj_release( &db->hdr );
return r; return r;
...@@ -770,11 +802,23 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb ) ...@@ -770,11 +802,23 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiDatabaseCommit not allowed during a custom action!\n");
return ERROR_SUCCESS;
}
/* FIXME: lock the database */ /* FIXME: lock the database */
r = MSI_CommitTables( db ); r = MSI_CommitTables( db );
if (r != ERROR_SUCCESS) ERR("Failed to commit tables!\n");
/* FIXME: unlock the database */ /* FIXME: unlock the database */
...@@ -867,8 +911,28 @@ UINT WINAPI MsiDatabaseGetPrimaryKeysW( MSIHANDLE hdb, ...@@ -867,8 +911,28 @@ UINT WINAPI MsiDatabaseGetPrimaryKeysW( MSIHANDLE hdb,
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
HRESULT hr;
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE; 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 ); r = MSI_DatabaseGetPrimaryKeys( db, table, &rec );
if( r == ERROR_SUCCESS ) if( r == ERROR_SUCCESS )
{ {
...@@ -932,8 +996,25 @@ MSICONDITION WINAPI MsiDatabaseIsTablePersistentW( ...@@ -932,8 +996,25 @@ MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(
db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
HRESULT hr;
MSICONDITION condition;
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hDatabase );
if ( !remote_database )
return MSICONDITION_ERROR; 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 ); r = MSI_DatabaseIsTablePersistent( db, szTableName );
msiobj_release( &db->hdr ); msiobj_release( &db->hdr );
......
...@@ -26,12 +26,27 @@ import "oaidl.idl"; ...@@ -26,12 +26,27 @@ import "oaidl.idl";
cpp_quote("#if 0") cpp_quote("#if 0")
typedef unsigned long MSIHANDLE; typedef unsigned long MSIHANDLE;
typedef int INSTALLMESSAGE; typedef int INSTALLMESSAGE;
typedef int MSICONDITION;
typedef int MSIRUNMODE; typedef int MSIRUNMODE;
typedef int INSTALLSTATE; typedef int INSTALLSTATE;
typedef WORD LANGID; typedef WORD LANGID;
cpp_quote("#endif") 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), uuid(902B3592-9D08-4dfd-A593-D07C52546421),
oleautomation, oleautomation,
object object
......
...@@ -856,7 +856,18 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) ...@@ -856,7 +856,18 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
handle = atoiW(&szPackage[1]); handle = atoiW(&szPackage[1]);
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
if ( !remote_database )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database );
WARN("MsiOpenPackage not allowed during a custom action!\n");
return ERROR_FUNCTION_FAILED;
}
} }
else else
{ {
...@@ -1598,7 +1609,27 @@ static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE ...@@ -1598,7 +1609,27 @@ static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE
HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle ) HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle )
{ {
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); 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; return S_OK;
} }
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#define COBJMACROS
#include <stdarg.h> #include <stdarg.h>
#include "windef.h" #include "windef.h"
...@@ -25,6 +27,7 @@ ...@@ -25,6 +27,7 @@
#include "winnls.h" #include "winnls.h"
#include "msi.h" #include "msi.h"
#include "msipriv.h" #include "msipriv.h"
#include "msiserver.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/unicode.h" #include "wine/unicode.h"
...@@ -69,7 +72,21 @@ UINT WINAPI MsiEnableUIPreview( MSIHANDLE hdb, MSIHANDLE* phPreview ) ...@@ -69,7 +72,21 @@ UINT WINAPI MsiEnableUIPreview( MSIHANDLE hdb, MSIHANDLE* phPreview )
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db ) if( !db )
{
IWineMsiRemoteDatabase *remote_database;
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
if ( !remote_database )
return ERROR_INVALID_HANDLE; 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 ); preview = MSI_EnableUIPreview( db );
if( preview ) if( preview )
{ {
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "msidefs.h" #include "msidefs.h"
#include "msipriv.h" #include "msipriv.h"
#include "objidl.h" #include "objidl.h"
#include "msiserver.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi); WINE_DEFAULT_DEBUG_CHANNEL(msi);
...@@ -459,7 +460,28 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase, ...@@ -459,7 +460,28 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
{ {
db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE ); db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
if( !db ) 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 ); si = MSI_GetSummaryInformationW( db->storage, uiUpdateCount );
......
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