msi: Return a remote interface to the database in a custom action.
This commit is contained in:
parent
7dffb518c0
commit
0e29f314f5
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue