msi: Make MsiViewFetch() 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:
parent
afb5eede24
commit
39c116fd0c
|
@ -831,6 +831,8 @@ extern UINT msi_record_set_string(MSIRECORD *, UINT, const WCHAR *, int) DECLSPE
|
||||||
extern const WCHAR *msi_record_get_string(const MSIRECORD *, UINT, int *) DECLSPEC_HIDDEN;
|
extern const WCHAR *msi_record_get_string(const MSIRECORD *, UINT, int *) DECLSPEC_HIDDEN;
|
||||||
extern void dump_record(MSIRECORD *) DECLSPEC_HIDDEN;
|
extern void dump_record(MSIRECORD *) DECLSPEC_HIDDEN;
|
||||||
extern UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out) 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;
|
||||||
|
|
||||||
/* stream internals */
|
/* stream internals */
|
||||||
extern void enum_stream_names( IStorage *stg ) DECLSPEC_HIDDEN;
|
extern void enum_stream_names( IStorage *stg ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -389,8 +389,22 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
|
||||||
*record = 0;
|
*record = 0;
|
||||||
|
|
||||||
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
|
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
|
||||||
if( !query )
|
if (!query)
|
||||||
return ERROR_INVALID_HANDLE;
|
{
|
||||||
|
struct wire_record *wire_rec = NULL;
|
||||||
|
MSIHANDLE remote;
|
||||||
|
|
||||||
|
if (!(remote = msi_get_remote(hView)))
|
||||||
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
ret = remote_ViewFetch(remote, &wire_rec);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
ret = unmarshal_record(wire_rec, record);
|
||||||
|
free_remote_record(wire_rec);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
ret = MSI_ViewFetch( query, &rec );
|
ret = MSI_ViewFetch( query, &rec );
|
||||||
if( ret == ERROR_SUCCESS )
|
if( ret == ERROR_SUCCESS )
|
||||||
{
|
{
|
||||||
|
@ -1054,3 +1068,14 @@ UINT __cdecl remote_ViewExecute(MSIHANDLE view, struct wire_record *remote_rec)
|
||||||
MsiCloseHandle(rec);
|
MsiCloseHandle(rec);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT __cdecl remote_ViewFetch(MSIHANDLE view, struct wire_record **rec)
|
||||||
|
{
|
||||||
|
MSIHANDLE handle;
|
||||||
|
UINT r = MsiViewFetch(view, &handle);
|
||||||
|
*rec = NULL;
|
||||||
|
if (!r)
|
||||||
|
*rec = marshal_record(handle);
|
||||||
|
MsiCloseHandle(handle);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
|
@ -1103,3 +1103,58 @@ UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out)
|
||||||
msiobj_release(&rec->hdr);
|
msiobj_release(&rec->hdr);
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wire_record *marshal_record(MSIHANDLE handle)
|
||||||
|
{
|
||||||
|
struct wire_record *ret;
|
||||||
|
unsigned int i, count;
|
||||||
|
MSIRECORD *rec;
|
||||||
|
|
||||||
|
if (!(rec = msihandle2msiinfo(handle, MSIHANDLETYPE_RECORD)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
count = MSI_RecordGetFieldCount(rec);
|
||||||
|
ret = midl_user_allocate(sizeof(*ret) + count * sizeof(ret->fields[0]));
|
||||||
|
ret->count = count;
|
||||||
|
|
||||||
|
for (i = 0; i <= count; i++)
|
||||||
|
{
|
||||||
|
switch (rec->fields[i].type)
|
||||||
|
{
|
||||||
|
case MSIFIELD_NULL:
|
||||||
|
break;
|
||||||
|
case MSIFIELD_INT:
|
||||||
|
ret->fields[i].u.iVal = rec->fields[i].u.iVal;
|
||||||
|
break;
|
||||||
|
case MSIFIELD_WSTR:
|
||||||
|
ret->fields[i].u.szwVal = strdupW(rec->fields[i].u.szwVal);
|
||||||
|
break;
|
||||||
|
case MSIFIELD_STREAM:
|
||||||
|
IStream_AddRef(rec->fields[i].u.stream);
|
||||||
|
ret->fields[i].u.stream = rec->fields[i].u.stream;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERR("invalid field type %d\n", rec->fields[i].type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret->fields[i].type = rec->fields[i].type;
|
||||||
|
}
|
||||||
|
|
||||||
|
msiobj_release(&rec->hdr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_remote_record(struct wire_record *rec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i <= rec->count; i++)
|
||||||
|
{
|
||||||
|
if (rec->fields[i].type == MSIFIELD_WSTR)
|
||||||
|
midl_user_free(rec->fields[i].u.szwVal);
|
||||||
|
else if (rec->fields[i].type == MSIFIELD_STREAM)
|
||||||
|
IStream_Release(rec->fields[i].u.stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
midl_user_free(rec);
|
||||||
|
}
|
||||||
|
|
|
@ -243,7 +243,9 @@ static void test_props(MSIHANDLE hinst)
|
||||||
|
|
||||||
static void test_db(MSIHANDLE hinst)
|
static void test_db(MSIHANDLE hinst)
|
||||||
{
|
{
|
||||||
MSIHANDLE hdb, view, rec;
|
MSIHANDLE hdb, view, rec, rec2;
|
||||||
|
char buffer[10];
|
||||||
|
DWORD sz;
|
||||||
UINT r;
|
UINT r;
|
||||||
|
|
||||||
hdb = MsiGetActiveDatabase(hinst);
|
hdb = MsiGetActiveDatabase(hinst);
|
||||||
|
@ -264,6 +266,56 @@ static void test_db(MSIHANDLE hinst)
|
||||||
r = MsiViewExecute(view, 0);
|
r = MsiViewExecute(view, 0);
|
||||||
ok(hinst, !r, "got %u\n", r);
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
r = MsiViewFetch(view, &rec2);
|
||||||
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
r = MsiRecordGetFieldCount(rec2);
|
||||||
|
ok(hinst, r == 3, "got %u\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, "one"), "got '%s'\n", buffer);
|
||||||
|
|
||||||
|
r = MsiRecordGetInteger(rec2, 2);
|
||||||
|
ok(hinst, r == 1, "got %d\n", r);
|
||||||
|
|
||||||
|
sz = sizeof(buffer);
|
||||||
|
r = MsiRecordReadStream(rec2, 3, buffer, &sz);
|
||||||
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
ok(hinst, !memcmp(buffer, "unus", 4), "wrong data\n");
|
||||||
|
|
||||||
|
r = MsiCloseHandle(rec2);
|
||||||
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
r = MsiViewFetch(view, &rec2);
|
||||||
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
r = MsiRecordGetFieldCount(rec2);
|
||||||
|
ok(hinst, r == 3, "got %u\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);
|
||||||
|
|
||||||
|
r = MsiViewFetch(view, &rec2);
|
||||||
|
ok(hinst, r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
|
||||||
|
ok(hinst, !rec2, "got %u\n", rec2);
|
||||||
|
|
||||||
r = MsiCloseHandle(view);
|
r = MsiCloseHandle(view);
|
||||||
ok(hinst, !r, "got %u\n", r);
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
@ -276,6 +328,19 @@ static void test_db(MSIHANDLE hinst)
|
||||||
r = MsiViewExecute(view, rec);
|
r = MsiViewExecute(view, rec);
|
||||||
ok(hinst, !r, "got %u\n", r);
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
r = MsiViewFetch(view, &rec2);
|
||||||
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
r = MsiRecordGetInteger(rec2, 2);
|
||||||
|
ok(hinst, r == 1, "got %d\n", r);
|
||||||
|
|
||||||
|
r = MsiCloseHandle(rec2);
|
||||||
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
r = MsiViewFetch(view, &rec2);
|
||||||
|
ok(hinst, r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
|
||||||
|
ok(hinst, !rec2, "got %u\n", rec2);
|
||||||
|
|
||||||
r = MsiCloseHandle(rec);
|
r = MsiCloseHandle(rec);
|
||||||
ok(hinst, !r, "got %u\n", r);
|
ok(hinst, !r, "got %u\n", r);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct wire_record {
|
||||||
interface IWineMsiRemote
|
interface IWineMsiRemote
|
||||||
{
|
{
|
||||||
UINT remote_ViewExecute( [in] MSIHANDLE view, [in, unique] struct wire_record *record );
|
UINT remote_ViewExecute( [in] MSIHANDLE view, [in, unique] struct wire_record *record );
|
||||||
|
UINT remote_ViewFetch( [in] MSIHANDLE view, [out] struct wire_record **record );
|
||||||
|
|
||||||
MSICONDITION remote_DatabaseIsTablePersistent( [in] MSIHANDLE db, [in] LPCWSTR table );
|
MSICONDITION remote_DatabaseIsTablePersistent( [in] MSIHANDLE db, [in] LPCWSTR table );
|
||||||
HRESULT remote_DatabaseGetPrimaryKeys( [in] MSIHANDLE db, [in] LPCWSTR table, [out] MSIHANDLE *keys );
|
HRESULT remote_DatabaseGetPrimaryKeys( [in] MSIHANDLE db, [in] LPCWSTR table, [out] MSIHANDLE *keys );
|
||||||
|
|
Loading…
Reference in New Issue