Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/msipriv.h | 4 +--- dlls/msi/msiquery.c | 5 +++-- dlls/msi/record.c | 48 ------------------------------------------------ 3 files changed, 4 insertions(+), 53 deletions(-)
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index b2b3e7c..9bc6413 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -131,7 +131,6 @@ typedef struct tagMSIFIELD union { INT iVal; - INT_PTR pVal; LPWSTR szwVal; IStream *stream; } u; @@ -141,6 +140,7 @@ typedef struct tagMSIFIELD typedef struct tagMSIRECORD { MSIOBJECTHDR hdr; + MSIQUERY *query; UINT count; /* as passed to MsiCreateRecord */ MSIFIELD fields[1]; /* nb. array size is count+1 */ } MSIRECORD; @@ -813,13 +813,11 @@ extern UINT MSI_RecordGetIStream( MSIRECORD *, UINT, IStream **) DECLSPEC_HIDDEN extern const WCHAR *MSI_RecordGetString( const MSIRECORD *, UINT ) DECLSPEC_HIDDEN; extern MSIRECORD *MSI_CreateRecord( UINT ) DECLSPEC_HIDDEN; extern UINT MSI_RecordSetInteger( MSIRECORD *, UINT, int ) DECLSPEC_HIDDEN; -extern UINT MSI_RecordSetIntPtr( MSIRECORD *, UINT, INT_PTR ) DECLSPEC_HIDDEN; extern UINT MSI_RecordSetStringW( MSIRECORD *, UINT, LPCWSTR ) DECLSPEC_HIDDEN; extern BOOL MSI_RecordIsNull( MSIRECORD *, UINT ) DECLSPEC_HIDDEN; extern UINT MSI_RecordGetStringW( MSIRECORD * , UINT, LPWSTR, LPDWORD) DECLSPEC_HIDDEN; extern UINT MSI_RecordGetStringA( MSIRECORD *, UINT, LPSTR, LPDWORD) DECLSPEC_HIDDEN; extern int MSI_RecordGetInteger( MSIRECORD *, UINT ) DECLSPEC_HIDDEN; -extern INT_PTR MSI_RecordGetIntPtr( MSIRECORD *, UINT ) DECLSPEC_HIDDEN; extern UINT MSI_RecordReadStream( MSIRECORD *, UINT, char *, LPDWORD) DECLSPEC_HIDDEN; extern UINT MSI_RecordSetStream(MSIRECORD *, UINT, IStream *) DECLSPEC_HIDDEN; extern UINT MSI_RecordGetFieldCount( const MSIRECORD *rec ) DECLSPEC_HIDDEN; diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c index f8ed4ce..1ba3076 100644 --- a/dlls/msi/msiquery.c +++ b/dlls/msi/msiquery.c @@ -374,7 +374,8 @@ UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec) if (r == ERROR_SUCCESS) { query->row ++; - MSI_RecordSetIntPtr(*prec, 0, (INT_PTR)query); + (*prec)->query = query; + MSI_RecordSetInteger(*prec, 0, 1); }
return r; @@ -608,7 +609,7 @@ UINT MSI_ViewModify( MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec ) if ( !view || !view->ops->modify) return ERROR_FUNCTION_FAILED;
- if ( mode == MSIMODIFY_UPDATE && MSI_RecordGetIntPtr( rec, 0 ) != (INT_PTR)query ) + if ( mode == MSIMODIFY_UPDATE && rec->query != query ) return ERROR_FUNCTION_FAILED;
r = view->ops->modify( view, mode, rec, query->row ); diff --git a/dlls/msi/record.c b/dlls/msi/record.c index de45191..8254b17 100644 --- a/dlls/msi/record.c +++ b/dlls/msi/record.c @@ -46,7 +46,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); #define MSIFIELD_INT 1 #define MSIFIELD_WSTR 3 #define MSIFIELD_STREAM 4 -#define MSIFIELD_INTPTR 5
static void MSI_FreeField( MSIFIELD *field ) { @@ -54,7 +53,6 @@ static void MSI_FreeField( MSIFIELD *field ) { case MSIFIELD_NULL: case MSIFIELD_INT: - case MSIFIELD_INTPTR: break; case MSIFIELD_WSTR: msi_free( field->u.szwVal); @@ -190,9 +188,6 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n, case MSIFIELD_INT: out->u.iVal = in->u.iVal; break; - case MSIFIELD_INTPTR: - out->u.pVal = in->u.pVal; - break; case MSIFIELD_WSTR: if ((str = msi_strdupW( in->u.szwVal, in->len ))) { @@ -216,32 +211,6 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n, return r; }
-INT_PTR MSI_RecordGetIntPtr( MSIRECORD *rec, UINT iField ) -{ - int ret; - - TRACE( "%p %d\n", rec, iField ); - - if( iField > rec->count ) - return MININT_PTR; - - switch( rec->fields[iField].type ) - { - case MSIFIELD_INT: - return rec->fields[iField].u.iVal; - case MSIFIELD_INTPTR: - return rec->fields[iField].u.pVal; - case MSIFIELD_WSTR: - if( string2intW( rec->fields[iField].u.szwVal, &ret ) ) - return ret; - return MININT_PTR; - default: - break; - } - - return MININT_PTR; -} - int MSI_RecordGetInteger( MSIRECORD *rec, UINT iField) { int ret = 0; @@ -255,8 +224,6 @@ int MSI_RecordGetInteger( MSIRECORD *rec, UINT iField) { case MSIFIELD_INT: return rec->fields[iField].u.iVal; - case MSIFIELD_INTPTR: - return rec->fields[iField].u.pVal; case MSIFIELD_WSTR: if( string2intW( rec->fields[iField].u.szwVal, &ret ) ) return ret; @@ -311,20 +278,6 @@ UINT WINAPI MsiRecordClearData( MSIHANDLE handle ) return ERROR_SUCCESS; }
-UINT MSI_RecordSetIntPtr( MSIRECORD *rec, UINT iField, INT_PTR pVal ) -{ - TRACE("%p %u %ld\n", rec, iField, pVal); - - if( iField > rec->count ) - return ERROR_INVALID_PARAMETER; - - MSI_FreeField( &rec->fields[iField] ); - rec->fields[iField].type = MSIFIELD_INTPTR; - rec->fields[iField].u.pVal = pVal; - - return ERROR_SUCCESS; -} - UINT MSI_RecordSetInteger( MSIRECORD *rec, UINT iField, int iVal ) { TRACE("%p %u %d\n", rec, iField, iVal); @@ -1095,7 +1048,6 @@ void dump_record(MSIRECORD *rec) case MSIFIELD_NULL: TRACE("(null)"); break; case MSIFIELD_INT: TRACE("%d", rec->fields[i].u.iVal); break; case MSIFIELD_WSTR: TRACE("%s", debugstr_w(rec->fields[i].u.szwVal)); break; - case MSIFIELD_INTPTR: TRACE("%ld", rec->fields[i].u.pVal); break; case MSIFIELD_STREAM: TRACE("%p", rec->fields[i].u.stream); break; } if (i < rec->count) TRACE(", ");
Instead of passing a remote MSIHANDLE and creating a set of remote_Record*() methods, we marshal the whole record as a wire struct. We do this for two reasons: firstly, because chances are whoever is reading the record is going to want to read the whole thing, so it's much less taxing on IPC to just pass the whole record once; and secondly, because records can be created on the client side or returned from the server side, and we don't want to have to write a lot of extra code to deal with both possibilities.
The wire_record struct is designed so that we can simply pass the relevant part of an MSIRECORD to the server.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/msipriv.h | 2 ++ dlls/msi/package.c | 41 +++++++++++++++++++---------------------- dlls/msi/record.c | 43 +++++++++++++++++++++++++++++++++++++++++++ dlls/msi/winemsi.idl | 22 +++++++++++++++++++++- 4 files changed, 85 insertions(+), 23 deletions(-)
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 9bc6413..3675042 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -39,6 +39,7 @@ #include "wine/debug.h"
#include "msiserver.h" +#include "winemsi.h"
static const BOOL is_64bit = sizeof(void *) > sizeof(int); BOOL is_wow64 DECLSPEC_HIDDEN; @@ -830,6 +831,7 @@ extern BOOL MSI_RecordsAreFieldsEqual(MSIRECORD *a, MSIRECORD *b, UINT field) DE extern UINT msi_record_set_string(MSIRECORD *, UINT, const WCHAR *, int) DECLSPEC_HIDDEN; extern const WCHAR *msi_record_get_string(const MSIRECORD *, UINT, int *) DECLSPEC_HIDDEN; extern void dump_record(MSIRECORD *) DECLSPEC_HIDDEN; +extern UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out) DECLSPEC_HIDDEN;
/* stream internals */ extern void enum_stream_names( IStorage *stg ) DECLSPEC_HIDDEN; diff --git a/dlls/msi/package.c b/dlls/msi/package.c index b154423..a02eb91 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -2053,39 +2053,27 @@ INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType, MsiRecordGetInteger(hRecord, 1) != 2) return -1;
+ record = msihandle2msiinfo(hRecord, MSIHANDLETYPE_RECORD); + if (!record) + return ERROR_INVALID_HANDLE; + package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); if( !package ) { MSIHANDLE remote; - HRESULT hr;
if (!(remote = msi_get_remote(hInstall))) return ERROR_INVALID_HANDLE;
- hr = remote_ProcessMessage(remote, eMessageType, hRecord); + ret = remote_ProcessMessage(remote, eMessageType, (struct wire_record *)&record->count);
- if (FAILED(hr)) - { - if (HRESULT_FACILITY(hr) == FACILITY_WIN32) - return HRESULT_CODE(hr); - - return ERROR_FUNCTION_FAILED; - } - - return ERROR_SUCCESS; + msiobj_release(&record->hdr); + return ret; }
- record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD ); - if( !record ) - goto out; - ret = MSI_ProcessMessage( package, eMessageType, record );
-out: msiobj_release( &package->hdr ); - if( record ) - msiobj_release( &record->hdr ); - return ret; }
@@ -2481,10 +2469,19 @@ UINT __cdecl remote_SetProperty(MSIHANDLE hinst, LPCWSTR property, LPCWSTR value return MsiSetPropertyW(hinst, property, value); }
-HRESULT __cdecl remote_ProcessMessage(MSIHANDLE hinst, INSTALLMESSAGE message, MSIHANDLE record) +int __cdecl remote_ProcessMessage(MSIHANDLE hinst, INSTALLMESSAGE message, struct wire_record *remote_rec) { - UINT r = MsiProcessMessage(hinst, message, record); - return HRESULT_FROM_WIN32(r); + MSIHANDLE rec; + int ret; + UINT r; + + if ((r = unmarshal_record(remote_rec, &rec))) + return r; + + ret = MsiProcessMessage(hinst, message, rec); + + MsiCloseHandle(rec); + return ret; }
HRESULT __cdecl remote_DoAction(MSIHANDLE hinst, BSTR action) diff --git a/dlls/msi/record.c b/dlls/msi/record.c index 8254b17..7b53d86 100644 --- a/dlls/msi/record.c +++ b/dlls/msi/record.c @@ -1054,3 +1054,46 @@ void dump_record(MSIRECORD *rec) } TRACE("]\n"); } + +UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out) +{ + MSIRECORD *rec; + unsigned int i; + UINT r; + + rec = MSI_CreateRecord(in->count); + if (!rec) return ERROR_OUTOFMEMORY; + + for (i = 0; i <= in->count; i++) + { + switch (in->fields[i].type) + { + case MSIFIELD_NULL: + break; + case MSIFIELD_INT: + r = MSI_RecordSetInteger(rec, i, in->fields[i].u.iVal); + break; + case MSIFIELD_WSTR: + r = MSI_RecordSetStringW(rec, i, in->fields[i].u.szwVal); + break; + case MSIFIELD_STREAM: + r = MSI_RecordSetIStream(rec, i, in->fields[i].u.stream); + break; + default: + ERR("invalid field type %d\n", in->fields[i].type); + break; + } + + if (r) + { + msiobj_release(&rec->hdr); + return r; + } + } + + *out = alloc_msihandle(&rec->hdr); + if (!*out) return ERROR_OUTOFMEMORY; + + msiobj_release(&rec->hdr); + return ERROR_SUCCESS; +} diff --git a/dlls/msi/winemsi.idl b/dlls/msi/winemsi.idl index 7ea2e3c..d97db4c 100644 --- a/dlls/msi/winemsi.idl +++ b/dlls/msi/winemsi.idl @@ -28,9 +28,29 @@ typedef int MSICONDITION; typedef int MSIRUNMODE; typedef int INSTALLSTATE;
+#define MSIFIELD_NULL 0 +#define MSIFIELD_INT 1 +#define MSIFIELD_WSTR 3 +#define MSIFIELD_STREAM 4 cpp_quote("#endif") cpp_quote("#include "msiquery.h"")
+struct wire_field { + unsigned int type; + [switch_is(type)] union { + [case(MSIFIELD_NULL)] ; + [case(MSIFIELD_INT)] int iVal; + [case(MSIFIELD_WSTR), string] LPWSTR szwVal; + [case(MSIFIELD_STREAM)] IStream *stream; + } u; + int len; +}; + +struct wire_record { + unsigned int count; + [size_is(count+1)] struct wire_field fields[]; +}; + [ uuid(56D58B64-8780-4c22-A8BC-8B0B29E4A9F8) ] @@ -44,7 +64,7 @@ interface IWineMsiRemote HRESULT remote_GetActiveDatabase( [in] MSIHANDLE hinst, [out] MSIHANDLE *handle ); UINT remote_GetProperty( [in] MSIHANDLE hinst, [in, string] LPCWSTR property, [out, string] LPWSTR *value, [out] DWORD *size ); UINT remote_SetProperty( [in] MSIHANDLE hinst, [in, string, unique] LPCWSTR property, [in, string, unique] LPCWSTR value ); - HRESULT remote_ProcessMessage( [in] MSIHANDLE hinst, [in] INSTALLMESSAGE message, [in] MSIHANDLE record ); + int remote_ProcessMessage( [in] MSIHANDLE hinst, [in] INSTALLMESSAGE message, [in] struct wire_record *record ); HRESULT remote_DoAction( [in] MSIHANDLE hinst, [in] BSTR action ); HRESULT remote_Sequence( [in] MSIHANDLE hinst, [in] BSTR table, [in] int sequence ); HRESULT remote_GetTargetPath( [in] MSIHANDLE hinst, [in] BSTR folder, [out, size_is(*size)] BSTR value, [in, out] DWORD *size );
Signed-off-by: Hans Leidekker hans@codeweavers.com