Commit 3fd7a32a authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

rpcrt4: Properly handle complex arrays in the typelib marshaller.

parent 56404595
...@@ -1481,21 +1481,21 @@ static HRESULT WINAPI Widget_variant_array(IWidget *iface, VARIANT in[2], VARIAN ...@@ -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_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_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_VT(&in[1]) == (VT_BYREF|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_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[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(&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_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_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_VT(&in_out[1]) == VT_BSTR, "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(!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[0]) = VT_I1; V_I1(&in[0]) = 7;
V_VT(&in[1]) = VT_I1; V_I1(&in[1]) = 8; 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[0]) = VT_I1; V_I1(&out[0]) = 9;
V_VT(&out[1]) = VT_I1; V_I1(&out[1]) = 10; 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[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_out[1]) = VT_UNKNOWN; V_UNKNOWN(&in_out[1]) = (IUnknown *)create_disp_obj();
return S_OK; return S_OK;
} }
...@@ -2581,9 +2581,11 @@ static void test_marshal_struct(IWidget *widget, IDispatch *disp) ...@@ -2581,9 +2581,11 @@ static void test_marshal_struct(IWidget *widget, IDispatch *disp)
static void test_marshal_array(IWidget *widget, IDispatch *disp) static void test_marshal_array(IWidget *widget, IDispatch *disp)
{ {
VARIANT var_in[2], var_out[2], var_in_out[2]; VARIANT var_in[2], var_out[2], var_in_out[2];
ISomethingFromDispatch *proxy_sfd;
array_t in, out, in_out; array_t in, out, in_out;
MYSTRUCT struct_in[2]; MYSTRUCT struct_in[2];
HRESULT hr; HRESULT hr;
int i = 2;
memcpy(in, test_array1, sizeof(array_t)); memcpy(in, test_array1, sizeof(array_t));
memcpy(out, test_array2, sizeof(array_t)); memcpy(out, test_array2, sizeof(array_t));
...@@ -2594,26 +2596,32 @@ static void test_marshal_array(IWidget *widget, IDispatch *disp) ...@@ -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(&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"); 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[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_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[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_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[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_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); hr = IWidget_variant_array(widget, var_in, var_out, var_in_out);
ok(hr == S_OK, "Got hr %#x.\n", hr); 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_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_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_VT(&var_in[1]) == (VT_BYREF|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_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_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_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_VT(&var_out[1]) == VT_BSTR, "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(!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_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_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_VT(&var_in_out[1]) == VT_UNKNOWN, "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])); 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[0], &test_mystruct1, sizeof(MYSTRUCT));
memcpy(&struct_in[1], &test_mystruct2, sizeof(MYSTRUCT)); memcpy(&struct_in[1], &test_mystruct2, sizeof(MYSTRUCT));
......
...@@ -326,9 +326,13 @@ static unsigned char get_struct_fc(ITypeInfo *typeinfo, TYPEATTR *attr) ...@@ -326,9 +326,13 @@ static unsigned char get_struct_fc(ITypeInfo *typeinfo, TYPEATTR *attr)
static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc) static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc)
{ {
if (get_basetype(typeinfo, desc)) switch (desc->vt)
{
case VT_CY:
return FC_LGFARRAY; 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; ITypeInfo *refinfo;
TYPEATTR *attr; TYPEATTR *attr;
...@@ -351,8 +355,9 @@ static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc) ...@@ -351,8 +355,9 @@ static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc)
return fc; return fc;
} }
else default:
return FC_BOGUS_ARRAY; return get_basetype(typeinfo, desc) ? FC_LGFARRAY : FC_BOGUS_ARRAY;
}
} }
static BOOL type_is_non_iface_pointer(ITypeInfo *typeinfo, TYPEDESC *desc) 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, ...@@ -616,14 +621,11 @@ static size_t write_array_tfs(ITypeInfo *typeinfo, unsigned char *str,
size_t *len, ARRAYDESC *desc) size_t *len, ARRAYDESC *desc)
{ {
unsigned char fc = get_array_fc(typeinfo, &desc->tdescElem); unsigned char fc = get_array_fc(typeinfo, &desc->tdescElem);
ULONG size = type_memsize(typeinfo, &desc->tdescElem);
unsigned char basetype; unsigned char basetype;
size_t ref = 0, off; size_t ref = 0, off;
ULONG size = 1;
USHORT i; USHORT i;
if (fc != FC_LGFARRAY)
FIXME("complex arrays not implemented\n");
if (!(basetype = get_basetype(typeinfo, &desc->tdescElem))) if (!(basetype = get_basetype(typeinfo, &desc->tdescElem)))
ref = write_type_tfs(typeinfo, str, len, &desc->tdescElem, FALSE, FALSE); 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, ...@@ -633,9 +635,20 @@ static size_t write_array_tfs(ITypeInfo *typeinfo, unsigned char *str,
off = *len; off = *len;
WRITE_CHAR(str, *len, FC_LGFARRAY); WRITE_CHAR(str, *len, fc);
WRITE_CHAR(str, *len, 0); 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) if (basetype)
WRITE_CHAR(str, *len, basetype); WRITE_CHAR(str, *len, basetype);
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment