Zebediah Figura : msi: Make MsiViewModify() RPC-compatible.

Alexandre Julliard julliard at winehq.org
Fri Apr 20 17:55:41 CDT 2018


Module: wine
Branch: master
Commit: c79fbc241e3c9a62ab50fb0826e33e85e97ae883
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c79fbc241e3c9a62ab50fb0826e33e85e97ae883

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Thu Apr 19 23:44:15 2018 -0500

msi: Make MsiViewModify() RPC-compatible.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msi/msipriv.h      |  1 +
 dlls/msi/msiquery.c     | 49 +++++++++++++++++++++++++++++++++++++++++++------
 dlls/msi/record.c       | 31 +++++++++++++++++++------------
 dlls/msi/tests/custom.c | 29 +++++++++++++++++++++++++++++
 dlls/msi/winemsi.idl    |  3 +++
 5 files changed, 95 insertions(+), 18 deletions(-)

diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index f386f90..aede960 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -833,6 +833,7 @@ extern void dump_record(MSIRECORD *) DECLSPEC_HIDDEN;
 extern UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out) DECLSPEC_HIDDEN;
 extern struct wire_record *marshal_record(MSIHANDLE handle) DECLSPEC_HIDDEN;
 extern void free_remote_record(struct wire_record *rec) DECLSPEC_HIDDEN;
+extern UINT copy_remote_record(const struct wire_record *rec, MSIHANDLE handle) DECLSPEC_HIDDEN;
 
 /* stream internals */
 extern void enum_stream_names( IStorage *stg ) DECLSPEC_HIDDEN;
diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c
index e73701f..e3bcfd8 100644
--- a/dlls/msi/msiquery.c
+++ b/dlls/msi/msiquery.c
@@ -666,17 +666,36 @@ UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode,
 
     TRACE("%d %x %d\n", hView, eModifyMode, hRecord);
 
-    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
-    if( !query )
+    rec = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
+
+    if (!rec)
         return ERROR_INVALID_HANDLE;
 
-    rec = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
+    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+    if (!query)
+    {
+        struct wire_record *wire_refreshed = NULL;
+        MSIHANDLE remote;
+
+        if (!(remote = msi_get_remote(hView)))
+            return ERROR_INVALID_HANDLE;
+
+        r = remote_ViewModify(remote, eModifyMode,
+            (struct wire_record *)&rec->count, &wire_refreshed);
+        if (!r && (eModifyMode == MSIMODIFY_REFRESH || eModifyMode == MSIMODIFY_SEEK))
+        {
+            r = copy_remote_record(wire_refreshed, hRecord);
+            free_remote_record(wire_refreshed);
+        }
+
+        msiobj_release(&rec->hdr);
+        return r;
+    }
+
     r = MSI_ViewModify( query, eModifyMode, rec );
 
     msiobj_release( &query->hdr );
-    if( rec )
-        msiobj_release( &rec->hdr );
-
+    msiobj_release(&rec->hdr);
     return r;
 }
 
@@ -1117,3 +1136,21 @@ UINT __cdecl remote_ViewGetColumnInfo(MSIHANDLE view, MSICOLINFO info, struct wi
     MsiCloseHandle(handle);
     return r;
 }
+
+UINT __cdecl remote_ViewModify(MSIHANDLE view, MSIMODIFY mode,
+    struct wire_record *remote_rec, struct wire_record **remote_refreshed)
+{
+    MSIHANDLE handle = 0;
+    UINT r;
+
+    if ((r = unmarshal_record(remote_rec, &handle)))
+        return r;
+
+    r = MsiViewModify(view, mode, handle);
+    *remote_refreshed = NULL;
+    if (!r && (mode == MSIMODIFY_REFRESH || mode == MSIMODIFY_SEEK))
+        *remote_refreshed = marshal_record(handle);
+
+    MsiCloseHandle(handle);
+    return r;
+}
diff --git a/dlls/msi/record.c b/dlls/msi/record.c
index 91892d7..5804046 100644
--- a/dlls/msi/record.c
+++ b/dlls/msi/record.c
@@ -1055,26 +1055,22 @@ void dump_record(MSIRECORD *rec)
     TRACE("]\n");
 }
 
-UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out)
+UINT copy_remote_record(const struct wire_record *in, MSIHANDLE out)
 {
     MSIRECORD *rec;
     unsigned int i;
     UINT r;
 
-    if (!in)
-    {
-        *out = 0;
-        return ERROR_SUCCESS;
-    }
-
-    rec = MSI_CreateRecord(in->count);
-    if (!rec) return ERROR_OUTOFMEMORY;
+    if (!(rec = msihandle2msiinfo(out, MSIHANDLETYPE_RECORD)))
+        return ERROR_INVALID_HANDLE;
 
     for (i = 0; i <= in->count; i++)
     {
         switch (in->fields[i].type)
         {
         case MSIFIELD_NULL:
+            MSI_FreeField(&rec->fields[i]);
+            rec->fields[i].type = MSIFIELD_NULL;
             break;
         case MSIFIELD_INT:
             r = MSI_RecordSetInteger(rec, i, in->fields[i].u.iVal);
@@ -1097,13 +1093,24 @@ UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out)
         }
     }
 
-    *out = alloc_msihandle(&rec->hdr);
-    if (!*out) return ERROR_OUTOFMEMORY;
-
     msiobj_release(&rec->hdr);
     return ERROR_SUCCESS;
 }
 
+UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out)
+{
+    if (!in)
+    {
+        *out = 0;
+        return ERROR_SUCCESS;
+    }
+
+    *out = MsiCreateRecord(in->count);
+    if (!*out) return ERROR_OUTOFMEMORY;
+
+    return copy_remote_record(in, *out);
+}
+
 struct wire_record *marshal_record(MSIHANDLE handle)
 {
     struct wire_record *ret;
diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c
index d6b186c..79d90f0 100644
--- a/dlls/msi/tests/custom.c
+++ b/dlls/msi/tests/custom.c
@@ -321,6 +321,35 @@ static void test_db(MSIHANDLE hinst)
     ok(hinst, !r, "got %u\n", r);
     ok(hinst, !memcmp(buffer, "duo", 3), "wrong data\n");
 
+    r = MsiViewModify(view, MSIMODIFY_REFRESH, 0);
+    ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r);
+
+    r = MsiRecordSetStringA(rec2, 1, "three");
+    ok(hinst, !r, "got %u\n", r);
+
+    r = MsiRecordSetInteger(rec2, 2, 3);
+    ok(hinst, !r, "got %u\n", r);
+
+    r = MsiRecordSetInteger(rec2, 3, 3);
+    ok(hinst, !r, "got %u\n", r);
+
+    r = MsiViewModify(view, MSIMODIFY_REFRESH, rec2);
+    ok(hinst, !r, "got %d\n", r);
+
+    sz = sizeof(buffer);
+    r = MsiRecordGetStringA(rec2, 1, buffer, &sz);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, sz == strlen(buffer), "got size %u\n", sz);
+    ok(hinst, !strcmp(buffer, "two"), "got '%s'\n", buffer);
+
+    r = MsiRecordGetInteger(rec2, 2);
+    ok(hinst, r == 2, "got %d\n", r);
+
+    sz = sizeof(buffer);
+    r = MsiRecordReadStream(rec2, 3, buffer, &sz);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, !memcmp(buffer, "duo", 3), "wrong data\n");
+
     r = MsiCloseHandle(rec2);
     ok(hinst, !r, "got %u\n", r);
 
diff --git a/dlls/msi/winemsi.idl b/dlls/msi/winemsi.idl
index 628091b..3fbd6d2 100644
--- a/dlls/msi/winemsi.idl
+++ b/dlls/msi/winemsi.idl
@@ -28,6 +28,7 @@ typedef int MSICONDITION;
 typedef int MSIRUNMODE;
 typedef int INSTALLSTATE;
 typedef int MSICOLINFO;
+typedef int MSIMODIFY;
 
 #define MSIFIELD_NULL   0
 #define MSIFIELD_INT    1
@@ -61,6 +62,8 @@ interface IWineMsiRemote
     UINT remote_ViewExecute( [in] MSIHANDLE view, [in, unique] struct wire_record *record );
     UINT remote_ViewFetch( [in] MSIHANDLE view, [out] struct wire_record **record );
     UINT remote_ViewGetColumnInfo( [in] MSIHANDLE view, [in] MSICOLINFO info, [out] struct wire_record **record );
+    UINT remote_ViewModify( [in] MSIHANDLE view, [in] MSIMODIFY mode,
+        [in] struct wire_record *record, [out] struct wire_record **refreshed );
 
     MSICONDITION remote_DatabaseIsTablePersistent( [in] MSIHANDLE db, [in] LPCWSTR table );
     HRESULT remote_DatabaseGetPrimaryKeys( [in] MSIHANDLE db, [in] LPCWSTR table, [out] MSIHANDLE *keys );




More information about the wine-cvs mailing list