From aa9dcb42019e0ebc0913d1a56b150684212099ea Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 22 Jan 2007 23:18:45 +0100 Subject: [PATCH] oleaut32/tests: Add tmarshal test. --- .gitignore | 4 + dlls/oleaut32/tests/Makefile.in | 9 +- dlls/oleaut32/tests/tmarshal.c | 1117 ++++++++++++++++++++++++++++++++ dlls/oleaut32/tests/tmarshal.idl | 159 +++++ dlls/oleaut32/tests/tmarshal.rc | 30 + dlls/oleaut32/tests/tmarshal_dispids.h | 34 + 6 files changed, 1352 insertions(+), 1 deletion(-) create mode 100644 dlls/oleaut32/tests/tmarshal.c create mode 100644 dlls/oleaut32/tests/tmarshal.idl create mode 100644 dlls/oleaut32/tests/tmarshal.rc create mode 100644 dlls/oleaut32/tests/tmarshal_dispids.h diff --git a/.gitignore b/.gitignore index 6f75ba641df..5e59d071edf 100644 --- a/.gitignore +++ b/.gitignore @@ -383,6 +383,10 @@ dlls/oleaut32/oleaut32.res dlls/oleaut32/tests/*.ok dlls/oleaut32/tests/oleaut32_crosstest.exe dlls/oleaut32/tests/testlist.c +dlls/oleaut32/tests/tmarshal.h +dlls/oleaut32/tests/tmarshal.res +dlls/oleaut32/tests/tmarshal.tlb +dlls/oleaut32/tests/tmarshal_i.c dlls/olecli.dll16 dlls/olecli32/libolecli32.def dlls/oledlg/liboledlg.def diff --git a/dlls/oleaut32/tests/Makefile.in b/dlls/oleaut32/tests/Makefile.in index 7510f3b7fcd..31926100198 100644 --- a/dlls/oleaut32/tests/Makefile.in +++ b/dlls/oleaut32/tests/Makefile.in @@ -4,18 +4,25 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ TESTDLL = oleaut32.dll IMPORTS = oleaut32 ole32 shlwapi rpcrt4 user32 gdi32 advapi32 kernel32 -EXTRALIBS = -luuid +EXTRALIBS = -luuid -luser32 CTESTS = \ olefont.c \ olepicture.c \ safearray.c \ + tmarshal.c \ typelib.c \ usrmarshal.c \ varformat.c \ vartest.c \ vartype.c +RC_SRCS = tmarshal.rc + +IDL_I_SRCS = tmarshal.idl +IDL_H_SRCS = tmarshal.idl +IDL_TLB_SRCS = tmarshal.idl + @MAKE_TEST_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c new file mode 100644 index 00000000000..054cb264a8e --- /dev/null +++ b/dlls/oleaut32/tests/tmarshal.c @@ -0,0 +1,1117 @@ +/* + * Copyright (C) 2005-2006 Robert Shearman for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define COBJMACROS + +#include +#include +#include + +#include + +#include "tmarshal.h" +#include "tmarshal_dispids.h" + +#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08lx\n", (unsigned long int)hr) + +/* Debugging functions from wine/libs/wine/debug.c */ + +/* allocate some tmp string space */ +/* FIXME: this is not 100% thread-safe */ +static char *get_tmp_space( int size ) +{ + static char *list[32]; + static long pos; + char *ret; + int idx; + + idx = ++pos % (sizeof(list)/sizeof(list[0])); + if ((ret = realloc( list[idx], size ))) list[idx] = ret; + return ret; +} + +/* default implementation of wine_dbgstr_wn */ +static const char *default_dbgstr_wn( const WCHAR *str, int n ) +{ + char *dst, *res; + + if (!HIWORD(str)) + { + if (!str) return "(null)"; + res = get_tmp_space( 6 ); + sprintf( res, "#%04x", LOWORD(str) ); + return res; + } + if (n == -1) n = lstrlenW(str); + if (n < 0) n = 0; + else if (n > 200) n = 200; + dst = res = get_tmp_space( n * 5 + 7 ); + *dst++ = 'L'; + *dst++ = '"'; + while (n-- > 0) + { + WCHAR c = *str++; + switch (c) + { + case '\n': *dst++ = '\\'; *dst++ = 'n'; break; + case '\r': *dst++ = '\\'; *dst++ = 'r'; break; + case '\t': *dst++ = '\\'; *dst++ = 't'; break; + case '"': *dst++ = '\\'; *dst++ = '"'; break; + case '\\': *dst++ = '\\'; *dst++ = '\\'; break; + default: + if (c >= ' ' && c <= 126) + *dst++ = (char)c; + else + { + *dst++ = '\\'; + sprintf(dst,"%04x",c); + dst+=4; + } + } + } + *dst++ = '"'; + if (*str) + { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst = 0; + return res; +} + +const char *wine_dbgstr_wn( const WCHAR *s, int n ) +{ + return default_dbgstr_wn(s, n); +} + +const char *wine_dbgstr_w( const WCHAR *s ) +{ + return default_dbgstr_wn( s, -1 ); +} + + +#define RELEASEMARSHALDATA WM_USER + +struct host_object_data +{ + IStream *stream; + IID iid; + IUnknown *object; + MSHLFLAGS marshal_flags; + HANDLE marshal_event; + IMessageFilter *filter; +}; + +static DWORD CALLBACK host_object_proc(LPVOID p) +{ + struct host_object_data *data = (struct host_object_data *)p; + HRESULT hr; + MSG msg; + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + if (data->filter) + { + IMessageFilter * prev_filter = NULL; + hr = CoRegisterMessageFilter(data->filter, &prev_filter); + if (prev_filter) IMessageFilter_Release(prev_filter); + ok_ole_success(hr, CoRegisterMessageFilter); + } + + hr = CoMarshalInterface(data->stream, &data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags); + todo_wine + { + ok_ole_success(hr, CoMarshalInterface); + } + + /* force the message queue to be created before signaling parent thread */ + PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + + SetEvent(data->marshal_event); + + while (GetMessage(&msg, NULL, 0, 0)) + { + if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA) + { + trace("releasing marshal data\n"); + CoReleaseMarshalData(data->stream); + SetEvent((HANDLE)msg.lParam); + } + else + DispatchMessage(&msg); + } + + HeapFree(GetProcessHeap(), 0, data); + + CoUninitialize(); + + return hr; +} + +static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, IMessageFilter *filter, HANDLE *thread) +{ + DWORD tid = 0; + HANDLE marshal_event = CreateEvent(NULL, FALSE, FALSE, NULL); + struct host_object_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); + + data->stream = stream; + data->iid = *riid; + data->object = object; + data->marshal_flags = marshal_flags; + data->marshal_event = marshal_event; + data->filter = filter; + + *thread = CreateThread(NULL, 0, host_object_proc, data, 0, &tid); + + /* wait for marshaling to complete before returning */ + WaitForSingleObject(marshal_event, INFINITE); + CloseHandle(marshal_event); + + return tid; +} + +static DWORD start_host_object(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, HANDLE *thread) +{ + return start_host_object2(stream, riid, object, marshal_flags, NULL, thread); +} + +#if 0 /* not used */ +/* asks thread to release the marshal data because it has to be done by the + * same thread that marshaled the interface in the first place. */ +static void release_host_object(DWORD tid) +{ + HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); + PostThreadMessage(tid, RELEASEMARSHALDATA, 0, (LPARAM)event); + WaitForSingleObject(event, INFINITE); + CloseHandle(event); +} +#endif + +static void end_host_object(DWORD tid, HANDLE thread) +{ + BOOL ret = PostThreadMessage(tid, WM_QUIT, 0, 0); + ok(ret, "PostThreadMessage failed with error %d\n", GetLastError()); + /* be careful of races - don't return until hosting thread has terminated */ + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); +} + +typedef struct Widget +{ + const IWidgetVtbl *lpVtbl; + LONG refs; + IUnknown *pDispatchUnknown; +} Widget; + +HRESULT WINAPI Widget_QueryInterface( + IWidget *iface, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) +{ + if (IsEqualIID(riid, &IID_IWidget) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch)) + { + IWidget_AddRef(iface); + *ppvObject = iface; + return S_OK; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } +} + +ULONG WINAPI Widget_AddRef( + IWidget *iface) +{ + Widget *This = (Widget *)iface; + + return InterlockedIncrement(&This->refs); +} + +ULONG WINAPI Widget_Release( + IWidget *iface) +{ + Widget *This = (Widget *)iface; + ULONG refs = InterlockedDecrement(&This->refs); + if (!refs) + { + IUnknown_Release(This->pDispatchUnknown); + memset(This, 0xcc, sizeof(*This)); + HeapFree(GetProcessHeap(), 0, This); + trace("Widget destroyed!\n"); + } + + return refs; +} + +HRESULT WINAPI Widget_GetTypeInfoCount( + IWidget *iface, + /* [out] */ UINT __RPC_FAR *pctinfo) +{ + Widget *This = (Widget *)iface; + IDispatch *pDispatch; + HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch); + if (SUCCEEDED(hr)) + { + hr = IDispatch_GetTypeInfoCount(pDispatch, pctinfo); + IDispatch_Release(pDispatch); + } + return hr; +} + +HRESULT WINAPI Widget_GetTypeInfo( + IWidget __RPC_FAR * iface, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) +{ + Widget *This = (Widget *)iface; + IDispatch *pDispatch; + HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch); + if (SUCCEEDED(hr)) + { + hr = IDispatch_GetTypeInfo(pDispatch, iTInfo, lcid, ppTInfo); + IDispatch_Release(pDispatch); + } + return hr; +} + +HRESULT WINAPI Widget_GetIDsOfNames( + IWidget __RPC_FAR * iface, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID __RPC_FAR *rgDispId) +{ + Widget *This = (Widget *)iface; + IDispatch *pDispatch; + HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch); + if (SUCCEEDED(hr)) + { + hr = IDispatch_GetIDsOfNames(pDispatch, riid, rgszNames, cNames, lcid, rgDispId); + IDispatch_Release(pDispatch); + } + return hr; +} + +HRESULT WINAPI Widget_Invoke( + IWidget __RPC_FAR * iface, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, + /* [out] */ VARIANT __RPC_FAR *pVarResult, + /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, + /* [out] */ UINT __RPC_FAR *puArgErr) +{ + Widget *This = (Widget *)iface; + IDispatch *pDispatch; + HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch); + if (SUCCEEDED(hr)) + { + hr = IDispatch_Invoke(pDispatch, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + IDispatch_Release(pDispatch); + } + return hr; +} + +HRESULT WINAPI Widget_put_Name( + IWidget __RPC_FAR * iface, + /* [in] */ BSTR name) +{ + trace("put_Name(%s)\n", wine_dbgstr_w(name)); + return S_OK; +} + +HRESULT WINAPI Widget_get_Name( + IWidget __RPC_FAR * iface, + /* [out] */ BSTR __RPC_FAR *name) +{ + static const WCHAR szCat[] = { 'C','a','t',0 }; + trace("get_Name()\n"); + *name = SysAllocString(szCat); + return S_OK; +} + +HRESULT WINAPI Widget_DoSomething( + IWidget __RPC_FAR * iface, + /* [in] */ double number, + /* [out] */ BSTR *str1, + /* [defaultvalue][in] */ BSTR str2, + /* [optional][in] */ VARIANT __RPC_FAR *opt) +{ + static const WCHAR szString[] = { 'S','t','r','i','n','g',0 }; + trace("DoSomething()\n"); + + ok(number == 3.141, "number(%f) != 3.141\n", number); + ok(*str2 == '\0', "str2(%s) != \"\"\n", wine_dbgstr_w(str2)); + ok(V_VT(opt) == VT_ERROR, "V_VT(opt) should be VT_ERROR instead of 0x%x\n", V_VT(opt)); + ok(V_ERROR(opt) == DISP_E_PARAMNOTFOUND, "V_ERROR(opt) should be DISP_E_PARAMNOTFOUND instead of 0x%08x\n", V_ERROR(opt)); + *str1 = SysAllocString(szString); + + return S_FALSE; +} + +HRESULT WINAPI Widget_get_State( + IWidget __RPC_FAR * iface, + /* [retval][out] */ STATE __RPC_FAR *state) +{ + trace("get_State() = STATE_WIDGETIFIED\n"); + *state = STATE_WIDGETIFIED; + return S_OK; +} + +HRESULT WINAPI Widget_put_State( + IWidget __RPC_FAR * iface, + /* [in] */ STATE state) +{ + trace("put_State(%d)\n", state); + return S_OK; +} + +HRESULT WINAPI Widget_Map( + IWidget * iface, + BSTR bstrId, + BSTR *sValue) +{ + trace("Map(%s, %p)\n", wine_dbgstr_w(bstrId), sValue); + *sValue = SysAllocString(bstrId); + return S_OK; +} + +HRESULT WINAPI Widget_SetOleColor( + IWidget * iface, + OLE_COLOR val) +{ + trace("SetOleColor(0x%x)\n", val); + return S_OK; +} + +HRESULT WINAPI Widget_GetOleColor( + IWidget * iface, + OLE_COLOR *pVal) +{ + trace("GetOleColor() = 0x8000000f\n"); + *pVal = 0x8000000f; + return S_FALSE; +} + +HRESULT WINAPI Widget_Clone( + IWidget *iface, + IWidget **ppVal) +{ + trace("Clone()\n"); + return Widget_QueryInterface(iface, &IID_IWidget, (void **)ppVal); +} + +HRESULT WINAPI Widget_CloneDispatch( + IWidget *iface, + IDispatch **ppVal) +{ + trace("CloneDispatch()\n"); + return Widget_QueryInterface(iface, &IID_IWidget, (void **)ppVal); +} + +HRESULT WINAPI Widget_CloneCoclass( + IWidget *iface, + ApplicationObject2 **ppVal) +{ + trace("CloneDispatch()\n"); + return S_OK; +} + +HRESULT WINAPI Widget_Value( + IWidget __RPC_FAR * iface, + VARIANT *value, + VARIANT *retval) +{ + trace("Value(%p, %p)\n", value, retval); + ok(V_VT(value) == VT_I2, "V_VT(value) was %d instead of VT_I2\n", V_VT(value)); + ok(V_I2(value) == 1, "V_I2(value) was %d instead of 1\n", V_I2(value)); + V_VT(retval) = VT_I2; + V_I2(retval) = 1234; + return S_OK; +} + +HRESULT WINAPI Widget_Array( + IWidget * iface, + SAFEARRAY * values) +{ + trace("Array(%p)\n", values); + return S_OK; +} + +HRESULT WINAPI Widget_VariantArrayPtr( + IWidget * iface, + SAFEARRAY ** values) +{ + trace("VariantArrayPtr(%p)\n", values); + return S_OK; +} + +void WINAPI Widget_Variant( + IWidget __RPC_FAR * iface, + VARIANT var) +{ + trace("Variant()\n"); + ok(V_VT(&var) == VT_CY, "V_VT(&var) was %d\n", V_VT(&var)); + ok(S(V_CY(&var)).Hi == 0xdababe, "V_CY(&var).Hi was 0x%x\n", S(V_CY(&var)).Hi); + ok(S(V_CY(&var)).Lo == 0xdeadbeef, "V_CY(&var).Lo was 0x%x\n", S(V_CY(&var)).Lo); +} + +HRESULT WINAPI Widget_Error( + IWidget __RPC_FAR * iface) +{ + trace("Error()\n"); + return E_NOTIMPL; +} + +static const struct IWidgetVtbl Widget_VTable = +{ + Widget_QueryInterface, + Widget_AddRef, + Widget_Release, + Widget_GetTypeInfoCount, + Widget_GetTypeInfo, + Widget_GetIDsOfNames, + Widget_Invoke, + Widget_put_Name, + Widget_get_Name, + Widget_DoSomething, + Widget_get_State, + Widget_put_State, + Widget_Map, + Widget_SetOleColor, + Widget_GetOleColor, + Widget_Clone, + Widget_CloneDispatch, + Widget_CloneCoclass, + Widget_Value, + Widget_Array, + Widget_VariantArrayPtr, + Widget_Variant, + Widget_Error +}; + + +typedef struct KindaEnum +{ + const IKindaEnumWidgetVtbl *lpVtbl; + LONG refs; +} KindaEnum; + +static HRESULT register_current_module_typelib(ITypeLib **typelib) +{ + WCHAR path[MAX_PATH]; + HRESULT hr; + + GetModuleFileNameW(NULL, path, MAX_PATH); + + hr = LoadTypeLib(path, typelib); + if (SUCCEEDED(hr)) + hr = RegisterTypeLib(*typelib, path, NULL); + return hr; +} + +static IWidget *Widget_Create(void) +{ + Widget *This = (Widget *)HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + HRESULT hr; + ITypeLib *pTypeLib; + + This->lpVtbl = &Widget_VTable; + This->refs = 1; + + hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &pTypeLib); + ok_ole_success(hr, LoadRegTypeLib); + if (hr == TYPE_E_LIBNOTREGISTERED) + { + hr = register_current_module_typelib(&pTypeLib); + ok_ole_success(hr, register_current_module_typelib); + } + if (SUCCEEDED(hr)) + { + ITypeInfo *pTypeInfo; + hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IWidget, &pTypeInfo); + ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid); + if (SUCCEEDED(hr)) + { + This->pDispatchUnknown = NULL; + hr = CreateStdDispatch((IUnknown *)&This->lpVtbl, This, pTypeInfo, &This->pDispatchUnknown); + ok_ole_success(hr, CreateStdDispatch); + ITypeInfo_Release(pTypeInfo); + } + } + + if (SUCCEEDED(hr)) + return (IWidget *)&This->lpVtbl; + else + { + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } +} + +HRESULT WINAPI KindaEnum_QueryInterface( + IKindaEnumWidget *iface, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) +{ + if (IsEqualIID(riid, &IID_IKindaEnumWidget) || IsEqualIID(riid, &IID_IUnknown)) + { + IKindaEnumWidget_AddRef(iface); + *ppvObject = iface; + return S_OK; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } +} + +ULONG WINAPI KindaEnum_AddRef( + IKindaEnumWidget *iface) +{ + KindaEnum *This = (KindaEnum *)iface; + + return InterlockedIncrement(&This->refs); +} + +ULONG WINAPI KindaEnum_Release( + IKindaEnumWidget *iface) +{ + KindaEnum *This = (KindaEnum *)iface; + ULONG refs = InterlockedDecrement(&This->refs); + if (!refs) + { + memset(This, 0xcc, sizeof(*This)); + HeapFree(GetProcessHeap(), 0, This); + trace("KindaEnumWidget destroyed!\n"); + } + + return refs; +} + +HRESULT WINAPI KindaEnum_Next( + IKindaEnumWidget *iface, + /* [out] */ IWidget __RPC_FAR *__RPC_FAR *widget) +{ + *widget = Widget_Create(); + if (*widget) + return S_OK; + else + return E_OUTOFMEMORY; +} + +HRESULT WINAPI KindaEnum_Count( + IKindaEnumWidget *iface, + /* [out] */ unsigned long __RPC_FAR *count) +{ + return E_NOTIMPL; +} + +HRESULT WINAPI KindaEnum_Reset( + IKindaEnumWidget *iface) +{ + return E_NOTIMPL; +} + +HRESULT WINAPI KindaEnum_Clone( + IKindaEnumWidget *iface, + /* [out] */ IKindaEnumWidget __RPC_FAR *__RPC_FAR *ppenum) +{ + return E_NOTIMPL; +} + +static const IKindaEnumWidgetVtbl KindaEnumWidget_VTable = +{ + KindaEnum_QueryInterface, + KindaEnum_AddRef, + KindaEnum_Release, + KindaEnum_Next, + KindaEnum_Count, + KindaEnum_Reset, + KindaEnum_Clone +}; + +static IKindaEnumWidget *KindaEnumWidget_Create(void) +{ + KindaEnum *This; + HRESULT hr; + ITypeLib *pTypeLib; + + hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &pTypeLib); + ok_ole_success(hr, LoadRegTypeLib); + if (hr == TYPE_E_LIBNOTREGISTERED) + { + hr = register_current_module_typelib(&pTypeLib); + ok_ole_success(hr, register_current_module_typelib); + } + if (SUCCEEDED(hr)) + ITypeLib_Release(pTypeLib); + + This = (KindaEnum *)HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if (!This) return NULL; + This->lpVtbl = &KindaEnumWidget_VTable; + This->refs = 1; + return (IKindaEnumWidget *)This; +} + +static HRESULT WINAPI NonOleAutomation_QueryInterface(INonOleAutomation *iface, REFIID riid, void **ppv) +{ + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_INonOleAutomation)) + { + *(INonOleAutomation **)ppv = iface; + return S_OK; + } + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI NonOleAutomation_AddRef(INonOleAutomation *iface) +{ + return 2; +} + +static ULONG WINAPI NonOleAutomation_Release(INonOleAutomation *iface) +{ + return 1; +} + +static BSTR WINAPI NonOleAutomation_BstrRet(INonOleAutomation *iface) +{ + static const WCHAR wszTestString[] = {'T','h','i','s',' ','i','s',' ','a',' ','t','e','s','t',' ','s','t','r','i','n','g',0}; + return SysAllocString(wszTestString); +} + +static INonOleAutomationVtbl NonOleAutomation_VTable = +{ + NonOleAutomation_QueryInterface, + NonOleAutomation_AddRef, + NonOleAutomation_Release, + NonOleAutomation_BstrRet, +}; + +static INonOleAutomation NonOleAutomation = { &NonOleAutomation_VTable }; + +static ITypeInfo *NonOleAutomation_GetTypeInfo(void) +{ + ITypeLib *pTypeLib; + HRESULT hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &pTypeLib); + if (hr == TYPE_E_LIBNOTREGISTERED) + { + hr = register_current_module_typelib(&pTypeLib); + ok_ole_success(hr, register_current_module_typelib); + } + if (SUCCEEDED(hr)) + { + ITypeInfo *pTypeInfo; + hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_INonOleAutomation, &pTypeInfo); + ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid); + return pTypeInfo; + } + return NULL; +} + +static void test_typelibmarshal(void) +{ + static const WCHAR szCat[] = { 'C','a','t',0 }; + static const WCHAR szTestTest[] = { 'T','e','s','t','T','e','s','t',0 }; + static WCHAR szSuperman[] = { 'S','u','p','e','r','m','a','n',0 }; + HRESULT hr; + IKindaEnumWidget *pKEW = KindaEnumWidget_Create(); + IWidget *pWidget; + IStream *pStream; + IDispatch *pDispatch; + static const LARGE_INTEGER ullZero; + EXCEPINFO excepinfo; + VARIANT varresult; + DISPID dispidNamed = DISPID_PROPERTYPUT; + DISPPARAMS dispparams; + VARIANTARG vararg[4]; + STATE the_state; + HANDLE thread; + DWORD tid; + BSTR bstr; + ITypeInfo *pTypeInfo; + + ok(pKEW != NULL, "Widget creation failed\n"); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); + ok_ole_success(hr, CreateStreamOnHGlobal); + tid = start_host_object(pStream, &IID_IKindaEnumWidget, (IUnknown *)pKEW, MSHLFLAGS_NORMAL, &thread); + + IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(pStream, &IID_IKindaEnumWidget, (void **)&pKEW); + todo_wine + { + ok_ole_success(hr, CoUnmarshalInterface); + } + IStream_Release(pStream); + + hr = IKindaEnumWidget_Next(pKEW, &pWidget); + ok_ole_success(hr, IKindaEnumWidget_Next); + + IKindaEnumWidget_Release(pKEW); + + hr = IWidget_QueryInterface(pWidget, &IID_IDispatch, (void **)&pDispatch); + + /* call put_Name */ + VariantInit(&vararg[0]); + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &dispidNamed; + dispparams.cArgs = 1; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + todo_wine + { + ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK, + "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n", + excepinfo.wCode, excepinfo.scode); + } + VariantClear(&varresult); + + /* call put_Name (direct) */ + bstr = SysAllocString(szSuperman); + hr = IWidget_put_Name(pWidget, bstr); + ok_ole_success(hr, IWidget_put_Name); + SysFreeString(bstr); + + /* call get_Name */ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.cArgs = 0; + dispparams.rgvarg = NULL; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + todo_wine + { + ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK, + "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n", + excepinfo.wCode, excepinfo.scode); + } + trace("Name = %s\n", wine_dbgstr_w(V_BSTR(&varresult))); + VariantClear(&varresult); + + /* call get_Name (direct) */ + bstr = NULL; + hr = IWidget_get_Name(pWidget, &bstr); + ok_ole_success(hr, IWidget_get_Name); + ok(!lstrcmpW(bstr, szCat), "IWidget_get_Name should have returned string \"Cat\" instead of %s\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + + /* call DoSomething */ + VariantInit(&vararg[0]); + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_R8; + V_R8(&vararg[1]) = 3.141; + dispparams.cNamedArgs = 0; + dispparams.cArgs = 2; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n"); + VariantClear(&varresult); + + /* call get_State */ + dispparams.cNamedArgs = 0; + dispparams.cArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = NULL; + hr = IDispatch_Invoke(pDispatch, DISPID_TM_STATE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + ok((V_VT(&varresult) == VT_I4) && (V_I4(&varresult) == STATE_WIDGETIFIED), "Return val mismatch\n"); + + /* call get_State (direct) */ + hr = IWidget_get_State(pWidget, &the_state); + ok_ole_success(hr, IWidget_get_state); + ok(the_state == STATE_WIDGETIFIED, "should have returned WIDGET_WIDGETIFIED instead of %d\n", the_state); + + /* call put_State */ + the_state = STATE_WIDGETIFIED; + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BYREF|VT_I4; + V_I4REF(&vararg[0]) = (int *)&the_state; + dispparams.cNamedArgs = 1; + dispparams.cArgs = 1; + dispparams.rgdispidNamedArgs = &dispidNamed; + dispparams.rgvarg = vararg; + hr = IDispatch_Invoke(pDispatch, DISPID_TM_STATE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + + /* call Map */ + bstr = SysAllocString(szTestTest); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BYREF|VT_BSTR; + V_BSTRREF(&vararg[0]) = &bstr; + dispparams.cNamedArgs = 0; + dispparams.cArgs = 1; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_MAP, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + ok(V_VT(&varresult) == VT_BSTR, "Return value should be of type BSTR instead of %d\n", V_VT(&varresult)); + ok(!lstrcmpW(V_BSTR(&varresult), szTestTest), "Return value should have been \"TestTest\" instead of %s\n", wine_dbgstr_w(V_BSTR(&varresult))); + VariantClear(&varresult); + + /* call SetOleColor with large negative VT_I4 param */ + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I4; + V_I4(&vararg[0]) = 0x80000005; + dispparams.cNamedArgs = 0; + dispparams.cArgs = 1; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = vararg; + hr = IDispatch_Invoke(pDispatch, DISPID_TM_SETOLECOLOR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + + /* call GetOleColor */ + dispparams.cNamedArgs = 0; + dispparams.cArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = NULL; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_GETOLECOLOR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + VariantClear(&varresult); + + /* call Clone */ + dispparams.cNamedArgs = 0; + dispparams.cArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = NULL; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_CLONE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + VariantClear(&varresult); + + /* call CloneDispatch with automatic value getting */ + V_VT(&vararg[0]) = VT_I2; + V_I2(&vararg[0]) = 1; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.cArgs = 1; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_CLONEDISPATCH, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, IDispatch_Invoke); + todo_wine + { + ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK, + "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n", + excepinfo.wCode, excepinfo.scode); + + ok(V_VT(&varresult) == VT_I2, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult)); + ok(V_I2(&varresult) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult)); + } + VariantClear(&varresult); + + /* call Value with a VT_VARIANT|VT_BYREF type */ + V_VT(&vararg[0]) = VT_VARIANT|VT_BYREF; + V_VARIANTREF(&vararg[0]) = &vararg[1]; + V_VT(&vararg[1]) = VT_I2; + V_I2(&vararg[1]) = 1; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.cArgs = 1; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL); + todo_wine + { + ok_ole_success(hr, IDispatch_Invoke); + + ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK, + "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n", + excepinfo.wCode, excepinfo.scode); + + ok(V_VT(&varresult) == VT_I2, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult)); + ok(V_I2(&varresult) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult)); + } + VariantClear(&varresult); + + /* call Variant - exercises variant copying in ITypeInfo::Invoke and + * handling of void return types */ + /* use a big type to ensure that the variant was properly copied into the + * destination function's args */ + V_VT(&vararg[0]) = VT_CY; + S(V_CY(&vararg[0])).Hi = 0xdababe; + S(V_CY(&vararg[0])).Lo = 0xdeadbeef; + dispparams.cNamedArgs = 0; + dispparams.cArgs = 1; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARIANT, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); + ok_ole_success(hr, IDispatch_Invoke); + VariantClear(&varresult); + + /* call Error */ + dispparams.cNamedArgs = 0; + dispparams.cArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = NULL; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_ERROR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, &excepinfo, NULL); + ok(hr == DISP_E_EXCEPTION, "IDispatch_Invoke should have returned DISP_E_EXCEPTION instead of 0x%08x\n", hr); + todo_wine + { + ok(excepinfo.wCode == 0x0 && excepinfo.scode == E_NOTIMPL, + "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n", + excepinfo.wCode, excepinfo.scode); + } + VariantClear(&varresult); + + /* call BstrRet */ + pTypeInfo = NonOleAutomation_GetTypeInfo(); + dispparams.cNamedArgs = 0; + dispparams.cArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = NULL; + VariantInit(&varresult); + hr = ITypeInfo_Invoke(pTypeInfo, &NonOleAutomation, DISPID_NOA_BSTRRET, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok_ole_success(hr, ITypeInfo_Invoke); + todo_wine + { + ok(V_VT(&varresult) == VT_BSTR, "V_VT(&varresult) should be VT_BSTR instead of %d\n", V_VT(&varresult)); + } + ok(V_BSTR(&varresult) != NULL, "V_BSTR(&varresult) should not be NULL\n"); + + VariantClear(&varresult); + ITypeInfo_Release(pTypeInfo); + + /* tests call put_Name without named arg */ + VariantInit(&vararg[0]); + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.cArgs = 1; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL); + todo_wine + { + ok(hr == DISP_E_PARAMNOTFOUND, "IDispatch_Invoke should have returned DISP_E_PARAMNOTFOUND instead of 0x%08x\n", hr); + } + VariantClear(&varresult); + + /* tests param type that cannot be coerced */ + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_UNKNOWN; + V_UNKNOWN(&vararg[0]) = NULL; + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &dispidNamed; + dispparams.cArgs = 1; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch_Invoke should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hr); + VariantClear(&varresult); + + /* tests bad param type */ + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_CLSID; + V_BYREF(&vararg[0]) = NULL; + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &dispidNamed; + dispparams.cArgs = 1; + dispparams.rgvarg = vararg; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_BADVARTYPE, "IDispatch_Invoke should have returned DISP_E_BADVARTYPE instead of 0x%08x\n", hr); + VariantClear(&varresult); + + /* tests too small param count */ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.cArgs = 0; + dispparams.rgvarg = NULL; + VariantInit(&varresult); + hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_BADPARAMCOUNT, "IDispatch_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr); + VariantClear(&varresult); + + /* tests propget function with large param count */ + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = NULL; + V_VT(&vararg[1]) = VT_I4; + V_I4(&vararg[1]) = 1; + dispparams.cNamedArgs = 0; + dispparams.cArgs = 2; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = vararg; + hr = IDispatch_Invoke(pDispatch, DISPID_TM_STATE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL); + todo_wine + { + ok(hr == DISP_E_NOTACOLLECTION, "IDispatch_Invoke should have returned DISP_E_NOTACOLLECTION instead of 0x%08x\n", hr); + } + + IDispatch_Release(pDispatch); + IWidget_Release(pWidget); + + trace("calling end_host_object\n"); + end_host_object(tid, thread); +} + +static void test_DispCallFunc(void) +{ + static const WCHAR szEmpty[] = { 0 }; + VARTYPE rgvt[] = { VT_R8, VT_BSTR, VT_BSTR, VT_VARIANT|VT_BYREF }; + VARIANTARG vararg[4]; + VARIANTARG varref; + VARIANTARG *rgpvarg[4] = { &vararg[0], &vararg[1], &vararg[2], &vararg[3] }; + VARIANTARG varresult; + HRESULT hr; + IWidget *pWidget = Widget_Create(); + V_VT(&vararg[0]) = VT_R8; + V_R8(&vararg[0]) = 3.141; + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szEmpty); + V_VT(&vararg[2]) = VT_BSTR; + V_BSTR(&vararg[2]) = SysAllocString(szEmpty); + V_VT(&vararg[3]) = VT_VARIANT|VT_BYREF; + V_VARIANTREF(&vararg[3]) = &varref; + V_VT(&varref) = VT_ERROR; + V_ERROR(&varref) = DISP_E_PARAMNOTFOUND; + VariantInit(&varresult); + hr = DispCallFunc(pWidget, 36, CC_STDCALL, VT_UI4, 4, rgvt, rgpvarg, &varresult); + ok_ole_success(hr, DispCallFunc); + VariantClear(&varresult); +} + +START_TEST(tmarshal) +{ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + test_typelibmarshal(); + test_DispCallFunc(); + + CoUninitialize(); +} diff --git a/dlls/oleaut32/tests/tmarshal.idl b/dlls/oleaut32/tests/tmarshal.idl new file mode 100644 index 00000000000..c8350bf027c --- /dev/null +++ b/dlls/oleaut32/tests/tmarshal.idl @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2005 Robert Shearman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "tmarshal_dispids.h" +import "ocidl.idl"; + +[ + uuid(d96d8a3e-78b6-4c8d-8f27-059db959be8a), + version(1.0), + helpstring("Test Typelib") +] +library TestTypelib +{ + importlib("stdole2.tlb"); + + typedef enum tagSTATE + { + STATE_UNWIDGETIFIED = 1, + STATE_WIDGETIFIED + } STATE; + + coclass ApplicationObject2; + + [ + odl, + uuid(a1f8cae3-c947-4c5f-b57d-c87b9b5f3586), + oleautomation, + dual + ] + interface IWidget : IDispatch + { + [propput, id(DISPID_TM_NAME)] + HRESULT Name([in] BSTR name); + [propget, id(DISPID_TM_NAME)] + HRESULT Name([out, retval] BSTR *name); + + [id(DISPID_TM_DOSOMETHING)] + HRESULT DoSomething([in] double number, [out] BSTR *str1, [in, defaultvalue("")] BSTR str2, [in, optional] VARIANT *opt); + + [propget, id(DISPID_TM_STATE)] + HRESULT State([out, retval] STATE *state); + [propput, id(DISPID_TM_STATE)] + HRESULT State([in] STATE state); + + [id(DISPID_TM_MAP)] + HRESULT Map([in] BSTR bstrId, [out, retval] BSTR *sValue); + + [id(DISPID_TM_SETOLECOLOR)] + HRESULT SetOleColor([in] OLE_COLOR val); + + [id(DISPID_TM_GETOLECOLOR)] + HRESULT GetOleColor([out, retval] OLE_COLOR *pVal); + + [propget, id(DISPID_TM_CLONE)] + HRESULT Clone([out, retval] IWidget **ppVal); + + [propget, id(DISPID_TM_CLONEDISPATCH)] + HRESULT CloneDispatch([out, retval] IDispatch **ppVal); + + [propget, id(DISPID_TM_CLONECOCLASS)] + HRESULT CloneCoclass([out, retval] ApplicationObject2 **ppVal); + + [id(DISPID_VALUE)] + HRESULT Value([in] VARIANT *value, [out, retval] VARIANT *retval); + + [id(DISPID_TM_ARRAY)] + HRESULT Array([in] SAFEARRAY(BSTR) values); + + [id(DISPID_TM_VARARRAYPTR)] + HRESULT VariantArrayPtr([in] SAFEARRAY(VARIANT) *values); + + [id(DISPID_TM_VARIANT)] + void Variant([in] VARIANT var); + + [id(DISPID_TM_ERROR)] + HRESULT Error(); + } + + [ + odl, + uuid(a028db05-30f0-4b93-b17a-41c72f831d84), + dual, + oleautomation + ] + interface IKindaEnumWidget : IUnknown + { + HRESULT Next( + [out] IWidget **widget); + + HRESULT Count( + [out] unsigned long *count); + + HRESULT Reset(); + + HRESULT Clone( + [out] IKindaEnumWidget **ppenum); + } + + [ + odl, + uuid(a028db06-30f0-4b93-b17a-41c72f831d84), + ] + interface INonOleAutomation : IUnknown + { + [id(DISPID_NOA_BSTRRET)] + BSTR BstrRet(); + } + + + [ + dllname("comm.drv"), + uuid(d377f60b-8639-4261-8ee7-75c8340d2cc9), + ] + module BadModule + { + [ + entry("Foo"), + ] + HRESULT BadModuleFoo(); + }; + + [ + dllname("oleaut32.dll"), + uuid(d377f60c-8639-4261-8ee7-75c8340d2cc9), + ] + module BadEntry + { + [ + entry("Foo"), + ] + HRESULT BadEntryFoo(); + }; + + [ + uuid(bb171948-10ec-407a-9a57-2f85f797ff1a), + appobject, + ] + coclass ApplicationObject2 + { + interface IWidget; + [source] interface IWidget; + }; +}; diff --git a/dlls/oleaut32/tests/tmarshal.rc b/dlls/oleaut32/tests/tmarshal.rc new file mode 100644 index 00000000000..c15e7326e8d --- /dev/null +++ b/dlls/oleaut32/tests/tmarshal.rc @@ -0,0 +1,30 @@ +/* + * Resource file for tmarshaltest + * + * Copyright 2005 Robert Shearman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#include "wine/wine_common_ver.rc" + +1 TYPELIB LOADONCALL DISCARDABLE tmarshal.tlb diff --git a/dlls/oleaut32/tests/tmarshal_dispids.h b/dlls/oleaut32/tests/tmarshal_dispids.h new file mode 100644 index 00000000000..776b7ba1b20 --- /dev/null +++ b/dlls/oleaut32/tests/tmarshal_dispids.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005-2006 Robert Shearman for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define DISPID_TM_NAME 1 +#define DISPID_TM_DOSOMETHING 2 +#define DISPID_TM_STATE 3 +#define DISPID_TM_MAP 4 +#define DISPID_TM_SETOLECOLOR 5 +#define DISPID_TM_GETOLECOLOR 6 +#define DISPID_TM_CLONE 7 +#define DISPID_TM_CLONEDISPATCH 8 +#define DISPID_TM_CLONECOCLASS 9 +#define DISPID_TM_ARRAY 10 +#define DISPID_TM_VARARRAYPTR 11 +#define DISPID_TM_VARIANT 12 +#define DISPID_TM_ERROR 13 + +#define DISPID_NOA_BSTRRET 1 -- 2.11.4.GIT