rpcrt4: Properly handle complex arrays in the typelib marshaller.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-04-01 17:38:25 -05:00 committed by Alexandre Julliard
parent 56404595d5
commit 3fd7a32a01
2 changed files with 53 additions and 32 deletions

View file

@ -1481,21 +1481,21 @@ static HRESULT WINAPI Widget_variant_array(IWidget *iface, VARIANT in[2], VARIAN
{
ok(V_VT(&in[0]) == VT_I4, "Got wrong type %u.\n", V_VT(&in[0]));
ok(V_I4(&in[0]) == 1, "Got wrong value %d.\n", V_I4(&in[0]));
ok(V_VT(&in[1]) == VT_I4, "Got wrong type %u.\n", V_VT(&in[1]));
ok(V_I4(&in[1]) == 2, "Got wrong value %d.\n", V_I4(&in[1]));
ok(V_VT(&in[1]) == (VT_BYREF|VT_I4), "Got wrong type %u.\n", V_VT(&in[1]));
ok(*V_I4REF(&in[1]) == 2, "Got wrong value %d.\n", *V_I4REF(&in[1]));
ok(V_VT(&out[0]) == VT_EMPTY, "Got wrong type %u.\n", V_VT(&out[0]));
ok(V_VT(&out[1]) == VT_EMPTY, "Got wrong type %u.\n", V_VT(&out[1]));
ok(V_VT(&in_out[0]) == VT_I4, "Got wrong type %u.\n", V_VT(&in_out[0]));
ok(V_I4(&in_out[0]) == 5, "Got wrong type %u.\n", V_VT(&in_out[0]));
ok(V_VT(&in_out[1]) == VT_I4, "Got wrong type %u.\n", V_VT(&in_out[1]));
ok(V_I4(&in_out[1]) == 6, "Got wrong type %u.\n", V_VT(&in_out[1]));
ok(V_VT(&in_out[1]) == VT_BSTR, "Got wrong type %u.\n", V_VT(&in_out[1]));
ok(!lstrcmpW(V_BSTR(&in_out[1]), test_bstr1), "Got wrong value %s.\n", wine_dbgstr_w(V_BSTR(&in[1])));
V_VT(&in[0]) = VT_I1; V_I1(&in[0]) = 7;
V_VT(&in[1]) = VT_I1; V_I1(&in[1]) = 8;
V_VT(&out[0]) = VT_I1; V_I1(&out[0]) = 9;
V_VT(&out[1]) = VT_I1; V_I1(&out[1]) = 10;
V_VT(&in_out[0]) = VT_I1; V_I1(&in_out[0]) = 11;
V_VT(&in_out[1]) = VT_I1; V_I1(&in_out[1]) = 12;
V_VT(&in[0]) = VT_I1; V_I1(&in[0]) = 7;
V_VT(&in[1]) = VT_I1; V_I1(&in[1]) = 8;
V_VT(&out[0]) = VT_I1; V_I1(&out[0]) = 9;
V_VT(&out[1]) = VT_BSTR; V_BSTR(&out[1]) = SysAllocString(test_bstr2);
V_VT(&in_out[0]) = VT_I1; V_I1(&in_out[0]) = 11;
V_VT(&in_out[1]) = VT_UNKNOWN; V_UNKNOWN(&in_out[1]) = (IUnknown *)create_disp_obj();
return S_OK;
}
@ -2581,9 +2581,11 @@ static void test_marshal_struct(IWidget *widget, IDispatch *disp)
static void test_marshal_array(IWidget *widget, IDispatch *disp)
{
VARIANT var_in[2], var_out[2], var_in_out[2];
ISomethingFromDispatch *proxy_sfd;
array_t in, out, in_out;
MYSTRUCT struct_in[2];
HRESULT hr;
int i = 2;
memcpy(in, test_array1, sizeof(array_t));
memcpy(out, test_array2, sizeof(array_t));
@ -2594,26 +2596,32 @@ static void test_marshal_array(IWidget *widget, IDispatch *disp)
ok(!memcmp(&out, &test_array5, sizeof(array_t)), "Arrays didn't match.\n");
ok(!memcmp(&in_out, &test_array6, sizeof(array_t)), "Arrays didn't match.\n");
V_VT(&var_in[0]) = VT_I4; V_I4(&var_in[0]) = 1;
V_VT(&var_in[1]) = VT_I4; V_I4(&var_in[1]) = 2;
V_VT(&var_out[0]) = VT_I4; V_I4(&var_out[0]) = 3;
V_VT(&var_out[1]) = VT_I4; V_I4(&var_out[1]) = 4;
V_VT(&var_in_out[0]) = VT_I4; V_I4(&var_in_out[0]) = 5;
V_VT(&var_in_out[1]) = VT_I4; V_I4(&var_in_out[1]) = 6;
V_VT(&var_in[0]) = VT_I4; V_I4(&var_in[0]) = 1;
V_VT(&var_in[1]) = VT_BYREF|VT_I4; V_I4REF(&var_in[1]) = &i;
V_VT(&var_out[0]) = VT_I4; V_I4(&var_out[0]) = 3;
V_VT(&var_out[1]) = VT_I4; V_I4(&var_out[1]) = 4;
V_VT(&var_in_out[0]) = VT_I4; V_I4(&var_in_out[0]) = 5;
V_VT(&var_in_out[1]) = VT_BSTR; V_BSTR(&var_in_out[1]) = SysAllocString(test_bstr1);
hr = IWidget_variant_array(widget, var_in, var_out, var_in_out);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(V_VT(&var_in[0]) == VT_I4, "Got wrong type %u.\n", V_VT(&var_in[0]));
ok(V_I4(&var_in[0]) == 1, "Got wrong value %d.\n", V_I4(&var_in[0]));
ok(V_VT(&var_in[1]) == VT_I4, "Got wrong type %u.\n", V_VT(&var_in[1]));
ok(V_I4(&var_in[1]) == 2, "Got wrong value %d.\n", V_I4(&var_in[1]));
ok(V_VT(&var_in[1]) == (VT_BYREF|VT_I4), "Got wrong type %u.\n", V_VT(&var_in[1]));
ok(V_I4REF(&var_in[1]) == &i, "Got wrong value %p.\n", V_I4REF(&var_in[1]));
ok(i == 2, "Got wrong value %d.\n", i);
ok(V_VT(&var_out[0]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_out[0]));
ok(V_I1(&var_out[0]) == 9, "Got wrong value %u.\n", V_VT(&var_out[0]));
ok(V_VT(&var_out[1]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_out[1]));
ok(V_I1(&var_out[1]) == 10, "Got wrong value %u.\n", V_VT(&var_out[1]));
ok(V_VT(&var_out[1]) == VT_BSTR, "Got wrong type %u.\n", V_VT(&var_out[1]));
ok(!lstrcmpW(V_BSTR(&var_out[1]), test_bstr2), "Got wrong value %s.\n", wine_dbgstr_w(V_BSTR(&var_out[1])));
ok(V_VT(&var_in_out[0]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_in_out[0]));
ok(V_I1(&var_in_out[0]) == 11, "Got wrong value %u.\n", V_VT(&var_in_out[0]));
ok(V_VT(&var_in_out[1]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_in_out[1]));
ok(V_I1(&var_in_out[1]) == 12, "Got wrong value %u.\n", V_VT(&var_in_out[1]));
ok(V_VT(&var_in_out[1]) == VT_UNKNOWN, "Got wrong type %u.\n", V_VT(&var_in_out[1]));
hr = IUnknown_QueryInterface(V_UNKNOWN(&var_in_out[1]), &IID_ISomethingFromDispatch, (void **)&proxy_sfd);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ISomethingFromDispatch_anotherfn(proxy_sfd);
ok(hr == 0x01234567, "Got hr %#x.\n", hr);
ISomethingFromDispatch_Release(proxy_sfd);
release_iface(V_UNKNOWN(&var_in_out[1]));
memcpy(&struct_in[0], &test_mystruct1, sizeof(MYSTRUCT));
memcpy(&struct_in[1], &test_mystruct2, sizeof(MYSTRUCT));

View file

@ -326,9 +326,13 @@ static unsigned char get_struct_fc(ITypeInfo *typeinfo, TYPEATTR *attr)
static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc)
{
if (get_basetype(typeinfo, desc))
switch (desc->vt)
{
case VT_CY:
return FC_LGFARRAY;
else if (desc->vt == VT_USERDEFINED)
case VT_CARRAY:
return get_array_fc(typeinfo, &desc->lpadesc->tdescElem);
case VT_USERDEFINED:
{
ITypeInfo *refinfo;
TYPEATTR *attr;
@ -351,8 +355,9 @@ static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc)
return fc;
}
else
return FC_BOGUS_ARRAY;
default:
return get_basetype(typeinfo, desc) ? FC_LGFARRAY : FC_BOGUS_ARRAY;
}
}
static BOOL type_is_non_iface_pointer(ITypeInfo *typeinfo, TYPEDESC *desc)
@ -616,14 +621,11 @@ static size_t write_array_tfs(ITypeInfo *typeinfo, unsigned char *str,
size_t *len, ARRAYDESC *desc)
{
unsigned char fc = get_array_fc(typeinfo, &desc->tdescElem);
ULONG size = type_memsize(typeinfo, &desc->tdescElem);
unsigned char basetype;
size_t ref = 0, off;
ULONG size = 1;
USHORT i;
if (fc != FC_LGFARRAY)
FIXME("complex arrays not implemented\n");
if (!(basetype = get_basetype(typeinfo, &desc->tdescElem)))
ref = write_type_tfs(typeinfo, str, len, &desc->tdescElem, FALSE, FALSE);
@ -633,9 +635,20 @@ static size_t write_array_tfs(ITypeInfo *typeinfo, unsigned char *str,
off = *len;
WRITE_CHAR(str, *len, FC_LGFARRAY);
WRITE_CHAR(str, *len, fc);
WRITE_CHAR(str, *len, 0);
WRITE_INT (str, *len, size);
if (fc == FC_BOGUS_ARRAY)
{
WRITE_SHORT(str, *len, size);
WRITE_INT(str, *len, 0xffffffff); /* conformance */
WRITE_INT(str, *len, 0xffffffff); /* variance */
}
else
{
size *= type_memsize(typeinfo, &desc->tdescElem);
WRITE_INT(str, *len, size);
}
if (basetype)
WRITE_CHAR(str, *len, basetype);
else