oleaut32/tests: Add some tests for marshalling pointers.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
71f2839e52
commit
5c8329d3fd
|
@ -370,6 +370,8 @@ static ItestDualVtbl TestDualVtbl = {
|
|||
static ItestDual TestDual = { &TestDualVtbl };
|
||||
static ItestDual TestDualDisp = { &TestDualVtbl };
|
||||
|
||||
static int testmode;
|
||||
|
||||
typedef struct Widget
|
||||
{
|
||||
IWidget IWidget_iface;
|
||||
|
@ -956,6 +958,59 @@ static HRESULT WINAPI Widget_basetypes_out(IWidget *iface, signed char *c, short
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Widget_int_ptr(IWidget *iface, int *in, int *out, int *in_out)
|
||||
{
|
||||
ok(*in == 123, "Got [in] %d.\n", *in);
|
||||
if (testmode == 0) /* Invoke() */
|
||||
ok(*out == 456, "Got [out] %d.\n", *out);
|
||||
else if (testmode == 1)
|
||||
ok(!*out, "Got [out] %d.\n", *out);
|
||||
ok(*in_out == 789, "Got [in, out] %d.\n", *in_out);
|
||||
|
||||
*in = 987;
|
||||
*out = 654;
|
||||
*in_out = 321;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Widget_int_ptr_ptr(IWidget *iface, int **in, int **out, int **in_out)
|
||||
{
|
||||
todo_wine_if(testmode == 2)
|
||||
ok(!*out, "Got [out] %p.\n", *out);
|
||||
if (testmode == 0)
|
||||
{
|
||||
ok(!*in, "Got [in] %p.\n", *in);
|
||||
ok(!*in_out, "Got [in, out] %p.\n", *in_out);
|
||||
}
|
||||
else if (testmode == 1)
|
||||
{
|
||||
ok(!*in, "Got [in] %p.\n", *in);
|
||||
ok(!*in_out, "Got [in, out] %p.\n", *in_out);
|
||||
|
||||
*out = CoTaskMemAlloc(sizeof(int));
|
||||
**out = 654;
|
||||
*in_out = CoTaskMemAlloc(sizeof(int));
|
||||
**in_out = 321;
|
||||
}
|
||||
else if (testmode == 2)
|
||||
{
|
||||
ok(**in == 123, "Got [in] %d.\n", **in);
|
||||
ok(**in_out == 789, "Got [in, out] %d.\n", **in_out);
|
||||
|
||||
*out = CoTaskMemAlloc(sizeof(int));
|
||||
**out = 654;
|
||||
**in_out = 321;
|
||||
}
|
||||
else if (testmode == 3)
|
||||
{
|
||||
ok(**in_out == 789, "Got [in, out] %d.\n", **in_out);
|
||||
*in_out = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const struct IWidgetVtbl Widget_VTable =
|
||||
{
|
||||
Widget_QueryInterface,
|
||||
|
@ -999,6 +1054,8 @@ static const struct IWidgetVtbl Widget_VTable =
|
|||
Widget_Coclass,
|
||||
Widget_basetypes_in,
|
||||
Widget_basetypes_out,
|
||||
Widget_int_ptr,
|
||||
Widget_int_ptr_ptr,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI StaticWidget_QueryInterface(IStaticWidget *iface, REFIID riid, void **ppvObject)
|
||||
|
@ -1396,6 +1453,126 @@ static void test_marshal_basetypes(IWidget *widget, IDispatch *disp)
|
|||
ok(st == STATE_UNWIDGETIFIED, "Got state %u.\n", st);
|
||||
}
|
||||
|
||||
static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
|
||||
{
|
||||
VARIANTARG arg[3];
|
||||
DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
|
||||
int in, out, in_out, *in_ptr, *out_ptr, *in_out_ptr;
|
||||
HRESULT hr;
|
||||
|
||||
testmode = 0;
|
||||
|
||||
in = 123;
|
||||
out = 456;
|
||||
in_out = 789;
|
||||
V_VT(&arg[2]) = VT_BYREF|VT_I4; V_I4REF(&arg[2]) = ∈
|
||||
V_VT(&arg[1]) = VT_BYREF|VT_I4; V_I4REF(&arg[1]) = &out;
|
||||
V_VT(&arg[0]) = VT_BYREF|VT_I4; V_I4REF(&arg[0]) = &in_out;
|
||||
hr = IDispatch_Invoke(disp, DISPID_TM_INT_PTR, &IID_NULL, LOCALE_NEUTRAL,
|
||||
DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(in == 987, "Got [in] %d.\n", in);
|
||||
ok(out == 654, "Got [out] %d.\n", out);
|
||||
ok(in_out == 321, "Got [in, out] %d.\n", in_out);
|
||||
|
||||
testmode = 1;
|
||||
|
||||
in = 123;
|
||||
out = 456;
|
||||
in_out = 789;
|
||||
hr = IWidget_int_ptr(widget, &in, &out, &in_out);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(in == 123, "Got [in] %d.\n", in);
|
||||
ok(out == 654, "Got [out] %d.\n", out);
|
||||
ok(in_out == 321, "Got [in, out] %d.\n", in_out);
|
||||
|
||||
if (0) {
|
||||
out = in_out = -1;
|
||||
hr = IWidget_int_ptr(widget, NULL, &out, &in_out);
|
||||
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
|
||||
ok(!out, "[out] parameter should have been cleared.\n");
|
||||
ok(in_out == -1, "[in, out] parameter should not have been cleared.\n");
|
||||
|
||||
in = in_out = -1;
|
||||
hr = IWidget_int_ptr(widget, &in, NULL, &in_out);
|
||||
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
|
||||
ok(in == -1, "[in] parameter should not have been cleared.\n");
|
||||
ok(in_out == -1, "[in, out] parameter should not have been cleared.\n");
|
||||
|
||||
in = out = -1;
|
||||
hr = IWidget_int_ptr(widget, &in, &out, NULL);
|
||||
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
|
||||
ok(in == -1, "[in] parameter should not have been cleared.\n");
|
||||
ok(!out, "[out] parameter should have been cleared.\n");
|
||||
}
|
||||
|
||||
/* We can't test Invoke() with double pointers, as it is not possible to fit
|
||||
* more than one level of indirection into a VARIANTARG. */
|
||||
|
||||
testmode = 0;
|
||||
in_ptr = out_ptr = in_out_ptr = NULL;
|
||||
hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
|
||||
ok(hr == S_OK, "Got hr %#x\n", hr);
|
||||
ok(!in_ptr, "Got [in] %p.\n", in_ptr);
|
||||
ok(!out_ptr, "Got [out] %p.\n", out_ptr);
|
||||
ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
|
||||
|
||||
if (0) {
|
||||
testmode = 1;
|
||||
hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
|
||||
ok(hr == S_OK, "Got hr %#x\n", hr);
|
||||
ok(*out_ptr == 654, "Got [out] %d.\n", *out_ptr);
|
||||
ok(*in_out_ptr == 321, "Got [in, out] %d.\n", *in_out_ptr);
|
||||
CoTaskMemFree(out_ptr);
|
||||
CoTaskMemFree(in_out_ptr);
|
||||
|
||||
testmode = 2;
|
||||
in = 123;
|
||||
out = 456;
|
||||
in_out = 789;
|
||||
in_ptr = ∈
|
||||
out_ptr = &out;
|
||||
in_out_ptr = &in_out;
|
||||
hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(out_ptr != &out, "[out] ptr should have changed.\n");
|
||||
ok(in_out_ptr == &in_out, "[in, out] ptr should not have changed.\n");
|
||||
ok(*out_ptr == 654, "Got [out] %d.\n", *out_ptr);
|
||||
ok(*in_out_ptr == 321, "Got [in, out] %d.\n", *in_out_ptr);
|
||||
}
|
||||
|
||||
testmode = 3;
|
||||
in_ptr = out_ptr = NULL;
|
||||
in_out = 789;
|
||||
in_out_ptr = &in_out;
|
||||
hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
|
||||
|
||||
if (0) {
|
||||
out_ptr = &out;
|
||||
in_out_ptr = &in_out;
|
||||
hr = IWidget_int_ptr_ptr(widget, NULL, &out_ptr, &in_out_ptr);
|
||||
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
|
||||
ok(!out_ptr, "[out] parameter should have been cleared.\n");
|
||||
ok(in_out_ptr == &in_out, "[in, out] parameter should not have been cleared.\n");
|
||||
|
||||
in_ptr = ∈
|
||||
in_out_ptr = &in_out;
|
||||
hr = IWidget_int_ptr_ptr(widget, &in_ptr, NULL, &in_out_ptr);
|
||||
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
|
||||
ok(in_ptr == &in, "[in] parameter should not have been cleared.\n");
|
||||
ok(in_out_ptr == &in_out, "[in, out] parameter should not have been cleared.\n");
|
||||
|
||||
in_ptr = ∈
|
||||
out_ptr = &out;
|
||||
hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, NULL);
|
||||
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
|
||||
ok(in_ptr == &in, "[in] parameter should not have been cleared.\n");
|
||||
ok(!out_ptr, "[out] parameter should have been cleared.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_typelibmarshal(void)
|
||||
{
|
||||
static const WCHAR szCat[] = { 'C','a','t',0 };
|
||||
|
@ -2006,6 +2183,7 @@ todo_wine
|
|||
VariantClear(&varresult);
|
||||
|
||||
test_marshal_basetypes(pWidget, pDispatch);
|
||||
test_marshal_pointer(pWidget, pDispatch);
|
||||
|
||||
IDispatch_Release(pDispatch);
|
||||
IWidget_Release(pWidget);
|
||||
|
|
|
@ -57,6 +57,8 @@ enum IWidget_dispids
|
|||
|
||||
DISPID_TM_BASETYPES_IN,
|
||||
DISPID_TM_BASETYPES_OUT,
|
||||
DISPID_TM_INT_PTR,
|
||||
DISPID_TM_INT_PTR_PTR,
|
||||
};
|
||||
|
||||
static const int DISPID_TM_NEG_RESTRICTED = -26;
|
||||
|
@ -242,6 +244,12 @@ library TestTypelib
|
|||
HRESULT basetypes_out([out] signed char *c, [out] short *s, [out] int *i, [out] hyper *h,
|
||||
[out] unsigned char *uc, [out] unsigned short *us, [out] unsigned int *ui,
|
||||
[out] unsigned hyper *uh, [out] float *f, [out] double *d, [out] STATE *st);
|
||||
|
||||
[id(DISPID_TM_INT_PTR)]
|
||||
HRESULT int_ptr([in] int *in, [out] int *out, [in, out] int *in_out);
|
||||
|
||||
[id(DISPID_TM_INT_PTR_PTR)]
|
||||
HRESULT int_ptr_ptr([in] int **in, [out] int **out, [in, out] int **in_out);
|
||||
}
|
||||
|
||||
[
|
||||
|
|
Loading…
Reference in New Issue