https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2e19edd6a07e2170fe9c60e518e05f04c04c5c59

commit 2e19edd6a07e2170fe9c60e518e05f04c04c5c59
Author:     winesync <[email protected]>
AuthorDate: Sat Mar 12 15:11:49 2022 +0100
Commit:     Mark Jansen <[email protected]>
CommitDate: Sun Mar 20 19:27:35 2022 +0100

    [WINESYNC] msi: Make MsiProcessMessage() RPC-compatible.
    
    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 <[email protected]>
    Signed-off-by: Hans Leidekker <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id bbf0f2da8211da73066fb36a444593ab0e8901f2 by Zebediah Figura 
<[email protected]>
---
 dll/win32/msi/msipriv.h   |  2 ++
 dll/win32/msi/package.c   | 41 +++++++++++++++++++----------------------
 dll/win32/msi/record.c    | 43 +++++++++++++++++++++++++++++++++++++++++++
 dll/win32/msi/winemsi.idl | 22 +++++++++++++++++++++-
 4 files changed, 85 insertions(+), 23 deletions(-)

diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h
index 5c74ef864f0..a0423a60061 100644
--- a/dll/win32/msi/msipriv.h
+++ b/dll/win32/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/dll/win32/msi/package.c b/dll/win32/msi/package.c
index 483f6c4d597..87bd9f99861 100644
--- a/dll/win32/msi/package.c
+++ b/dll/win32/msi/package.c
@@ -2060,39 +2060,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);
-
-        if (FAILED(hr))
-        {
-            if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
-                return HRESULT_CODE(hr);
+        ret = remote_ProcessMessage(remote, eMessageType, (struct wire_record 
*)&record->count);
 
-            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;
 }
 
@@ -2488,10 +2476,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/dll/win32/msi/record.c b/dll/win32/msi/record.c
index 8254b17f096..7b53d86edfe 100644
--- a/dll/win32/msi/record.c
+++ b/dll/win32/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/dll/win32/msi/winemsi.idl b/dll/win32/msi/winemsi.idl
index 7ea2e3cd57f..d97db4c0571 100644
--- a/dll/win32/msi/winemsi.idl
+++ b/dll/win32/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 );

Reply via email to