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