msi: Make MsiViewModify() RPC-compatible.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2018-04-19 23:44:15 -05:00 committed by Alexandre Julliard
parent cea37419f1
commit c79fbc241e
5 changed files with 95 additions and 18 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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 );