Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/oleaut32/tests/tmarshal.c | 52 ++++++++++++++++++++-------------- dlls/rpcrt4/ndr_typelib.c | 33 ++++++++++++++------- 2 files changed, 53 insertions(+), 32 deletions(-)
diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c index 4f84442baf..ac0969bdfa 100644 --- a/dlls/oleaut32/tests/tmarshal.c +++ b/dlls/oleaut32/tests/tmarshal.c @@ -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)); diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c index 5a4de51dd1..5c48010030 100644 --- a/dlls/rpcrt4/ndr_typelib.c +++ b/dlls/rpcrt4/ndr_typelib.c @@ -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