https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aede536c83c5cc95e00b6…
commit aede536c83c5cc95e00b63797bd2271d5ade2cf9
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Sat Mar 12 15:11:55 2022 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Mar 20 19:27:37 2022 +0100
[WINESYNC] msi: Make MsiViewModify() RPC-compatible.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
wine commit id c79fbc241e3c9a62ab50fb0826e33e85e97ae883 by Zebediah Figura
<z.figura12(a)gmail.com>
---
dll/win32/msi/msipriv.h | 1 +
dll/win32/msi/msiquery.c | 49 +++++++++++++++++++++++++++++----
dll/win32/msi/record.c | 31 +++++++++++++--------
dll/win32/msi/winemsi.idl | 3 ++
modules/rostests/winetests/msi/custom.c | 29 +++++++++++++++++++
5 files changed, 95 insertions(+), 18 deletions(-)
diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h
index 936ed4d7241..4a92bd0e943 100644
--- a/dll/win32/msi/msipriv.h
+++ b/dll/win32/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/dll/win32/msi/msiquery.c b/dll/win32/msi/msiquery.c
index e73701f9253..e3bcfd86cc0 100644
--- a/dll/win32/msi/msiquery.c
+++ b/dll/win32/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/dll/win32/msi/record.c b/dll/win32/msi/record.c
index 91892d7377f..58040468993 100644
--- a/dll/win32/msi/record.c
+++ b/dll/win32/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/dll/win32/msi/winemsi.idl b/dll/win32/msi/winemsi.idl
index 628091b9b4c..3fbd6d26a1d 100644
--- a/dll/win32/msi/winemsi.idl
+++ b/dll/win32/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 );
diff --git a/modules/rostests/winetests/msi/custom.c
b/modules/rostests/winetests/msi/custom.c
index d6b186c635a..79d90f04233 100644
--- a/modules/rostests/winetests/msi/custom.c
+++ b/modules/rostests/winetests/msi/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);