mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
ole32/tests: Add IRpcChannelBuffer and IRpcStubBuffer tests.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3834a6e382
commit
7f83dd11a4
1 changed files with 358 additions and 0 deletions
|
@ -34,10 +34,37 @@
|
|||
#include "initguid.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "wine/heap.h"
|
||||
|
||||
#define DEFINE_EXPECT(func) \
|
||||
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
|
||||
|
||||
#define SET_EXPECT(func) \
|
||||
expect_ ## func = TRUE
|
||||
|
||||
#define CHECK_EXPECT2(func) \
|
||||
do { \
|
||||
ok(expect_ ##func, "unexpected call " #func "\n"); \
|
||||
called_ ## func = TRUE; \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_EXPECT(func) \
|
||||
do { \
|
||||
CHECK_EXPECT2(func); \
|
||||
expect_ ## func = FALSE; \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_CALLED(func) \
|
||||
do { \
|
||||
ok(called_ ## func, "expected " #func "\n"); \
|
||||
expect_ ## func = called_ ## func = FALSE; \
|
||||
}while(0)
|
||||
|
||||
DEFINE_GUID(CLSID_StdGlobalInterfaceTable,0x00000323,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
DEFINE_GUID(CLSID_ManualResetEvent, 0x0000032c,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
|
||||
static const GUID CLSID_WineTestPSFactoryBuffer = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
||||
|
||||
/* functions that are not present on all versions of Windows */
|
||||
static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
||||
static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
|
||||
|
@ -281,6 +308,254 @@ static const IClassFactoryVtbl TestClassFactory_Vtbl =
|
|||
|
||||
static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
|
||||
|
||||
DEFINE_EXPECT(Invoke);
|
||||
DEFINE_EXPECT(CreateStub);
|
||||
DEFINE_EXPECT(CreateProxy);
|
||||
DEFINE_EXPECT(GetWindow);
|
||||
DEFINE_EXPECT(Disconnect);
|
||||
|
||||
static HRESULT WINAPI OleWindow_QueryInterface(IOleWindow *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI OleWindow_AddRef(IOleWindow *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI OleWindow_Release(IOleWindow *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI OleWindow_GetWindow(IOleWindow *iface, HWND *hwnd)
|
||||
{
|
||||
CHECK_EXPECT(GetWindow);
|
||||
*hwnd = (HWND)0xdeadbeef;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IOleWindowVtbl OleWindowVtbl = {
|
||||
OleWindow_QueryInterface,
|
||||
OleWindow_AddRef,
|
||||
OleWindow_Release,
|
||||
OleWindow_GetWindow,
|
||||
/* not needed */
|
||||
};
|
||||
|
||||
static IOleWindow Test_OleWindow = { &OleWindowVtbl };
|
||||
|
||||
static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IOleClientSite))
|
||||
*ppv = iface;
|
||||
else if (IsEqualGUID(riid, &IID_IOleWindow))
|
||||
*ppv = &Test_OleWindow;
|
||||
else
|
||||
{
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const IOleClientSiteVtbl OleClientSiteVtbl = {
|
||||
OleClientSite_QueryInterface,
|
||||
OleClientSite_AddRef,
|
||||
OleClientSite_Release,
|
||||
/* we don't need the rest, we never call it */
|
||||
};
|
||||
|
||||
static IOleClientSite Test_OleClientSite = { &OleClientSiteVtbl };
|
||||
|
||||
typedef struct {
|
||||
IRpcStubBuffer IRpcStubBuffer_iface;
|
||||
LONG ref;
|
||||
IRpcStubBuffer *buffer;
|
||||
} StubBufferWrapper;
|
||||
|
||||
static StubBufferWrapper *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, StubBufferWrapper, IRpcStubBuffer_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStubBuffer_QueryInterface(IRpcStubBuffer *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface);
|
||||
|
||||
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRpcStubBuffer, riid)) {
|
||||
*ppv = &This->IRpcStubBuffer_iface;
|
||||
}else {
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStubBuffer_AddRef(IRpcStubBuffer *iface)
|
||||
{
|
||||
StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStubBuffer_Release(IRpcStubBuffer *iface)
|
||||
{
|
||||
StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
if(!ref) {
|
||||
IRpcStubBuffer_Release(This->buffer);
|
||||
heap_free(This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStubBuffer_Connect(IRpcStubBuffer *iface, IUnknown *pUnkServer)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static void WINAPI RpcStubBuffer_Disconnect(IRpcStubBuffer *iface)
|
||||
{
|
||||
CHECK_EXPECT(Disconnect);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStubBuffer_Invoke(IRpcStubBuffer *iface, RPCOLEMESSAGE *_prpcmsg,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer)
|
||||
{
|
||||
StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface);
|
||||
void *dest_context_data;
|
||||
DWORD dest_context;
|
||||
HRESULT hr;
|
||||
|
||||
CHECK_EXPECT(Invoke);
|
||||
|
||||
hr = IRpcChannelBuffer_GetDestCtx(_pRpcChannelBuffer, &dest_context, &dest_context_data);
|
||||
ok(hr == S_OK, "GetDestCtx failed: %08x\n", hr);
|
||||
todo_wine
|
||||
ok(dest_context == MSHCTX_INPROC, "desc_context = %x\n", dest_context);
|
||||
ok(!dest_context_data, "desc_context_data = %p\n", dest_context_data);
|
||||
|
||||
return IRpcStubBuffer_Invoke(This->buffer, _prpcmsg, _pRpcChannelBuffer);
|
||||
}
|
||||
|
||||
static IRpcStubBuffer *WINAPI RpcStubBuffer_IsIIDSupported(IRpcStubBuffer *iface, REFIID riid)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStubBuffer_CountRefs(IRpcStubBuffer *iface)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStubBuffer_DebugServerQueryInterface(IRpcStubBuffer *iface, void **ppv)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static void WINAPI RpcStubBuffer_DebugServerRelease(IRpcStubBuffer *iface, void *pv)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
}
|
||||
|
||||
static const IRpcStubBufferVtbl RpcStubBufferVtbl = {
|
||||
RpcStubBuffer_QueryInterface,
|
||||
RpcStubBuffer_AddRef,
|
||||
RpcStubBuffer_Release,
|
||||
RpcStubBuffer_Connect,
|
||||
RpcStubBuffer_Disconnect,
|
||||
RpcStubBuffer_Invoke,
|
||||
RpcStubBuffer_IsIIDSupported,
|
||||
RpcStubBuffer_CountRefs,
|
||||
RpcStubBuffer_DebugServerQueryInterface,
|
||||
RpcStubBuffer_DebugServerRelease
|
||||
};
|
||||
|
||||
static IPSFactoryBuffer *ps_factory_buffer;
|
||||
|
||||
static HRESULT WINAPI PSFactoryBuffer_QueryInterface(IPSFactoryBuffer *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPSFactoryBuffer))
|
||||
*ppv = iface;
|
||||
else
|
||||
{
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI PSFactoryBuffer_AddRef(IPSFactoryBuffer *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI PSFactoryBuffer_Release(IPSFactoryBuffer *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PSFactoryBuffer_CreateProxy(IPSFactoryBuffer *iface, IUnknown *outer,
|
||||
REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
|
||||
{
|
||||
CHECK_EXPECT(CreateProxy);
|
||||
return IPSFactoryBuffer_CreateProxy(ps_factory_buffer, outer, riid, ppProxy, ppv);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PSFactoryBuffer_CreateStub(IPSFactoryBuffer *iface, REFIID riid,
|
||||
IUnknown *server, IRpcStubBuffer **ppStub)
|
||||
{
|
||||
StubBufferWrapper *stub;
|
||||
HRESULT hr;
|
||||
|
||||
CHECK_EXPECT(CreateStub);
|
||||
|
||||
ok(server == (IUnknown*)&Test_OleClientSite, "unexpected server %p\n", server);
|
||||
|
||||
stub = heap_alloc(sizeof(*stub));
|
||||
stub->IRpcStubBuffer_iface.lpVtbl = &RpcStubBufferVtbl;
|
||||
stub->ref = 1;
|
||||
|
||||
hr = IPSFactoryBuffer_CreateStub(ps_factory_buffer, riid, server, &stub->buffer);
|
||||
ok(hr == S_OK, "CreateStub failed: %08x\n", hr);
|
||||
|
||||
*ppStub = &stub->IRpcStubBuffer_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
|
||||
{
|
||||
PSFactoryBuffer_QueryInterface,
|
||||
PSFactoryBuffer_AddRef,
|
||||
PSFactoryBuffer_Release,
|
||||
PSFactoryBuffer_CreateProxy,
|
||||
PSFactoryBuffer_CreateStub
|
||||
};
|
||||
|
||||
static IPSFactoryBuffer PSFactoryBuffer = { &PSFactoryBufferVtbl };
|
||||
|
||||
#define RELEASEMARSHALDATA WM_USER
|
||||
|
||||
struct host_object_data
|
||||
|
@ -290,17 +565,28 @@ struct host_object_data
|
|||
IUnknown *object;
|
||||
MSHLFLAGS marshal_flags;
|
||||
IMessageFilter *filter;
|
||||
IUnknown *register_object;
|
||||
CLSID register_clsid;
|
||||
HANDLE marshal_event;
|
||||
};
|
||||
|
||||
static IPSFactoryBuffer PSFactoryBuffer;
|
||||
|
||||
static DWORD CALLBACK host_object_proc(LPVOID p)
|
||||
{
|
||||
struct host_object_data *data = p;
|
||||
DWORD registration_key;
|
||||
HRESULT hr;
|
||||
MSG msg;
|
||||
|
||||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
if(data->register_object) {
|
||||
hr = CoRegisterClassObject(&data->register_clsid, data->register_object,
|
||||
CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®istration_key);
|
||||
ok(hr == S_OK, "CoRegisterClassObject failed: %08x\n", hr);
|
||||
}
|
||||
|
||||
if (data->filter)
|
||||
{
|
||||
IMessageFilter * prev_filter = NULL;
|
||||
|
@ -958,6 +1244,77 @@ static void test_marshal_proxy_mta_apartment_shutdown(void)
|
|||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
}
|
||||
|
||||
static void test_marshal_channel_buffer(void)
|
||||
{
|
||||
DWORD registration_key;
|
||||
IUnknown *proxy = NULL;
|
||||
IOleWindow *ole_window;
|
||||
HWND hwnd;
|
||||
CLSID clsid;
|
||||
DWORD tid;
|
||||
HANDLE thread;
|
||||
HRESULT hr;
|
||||
|
||||
struct host_object_data object_data = { NULL, IID_IOleClientSite, (IUnknown*)&Test_OleClientSite,
|
||||
MSHLFLAGS_NORMAL, NULL, (IUnknown*)&PSFactoryBuffer,
|
||||
CLSID_WineTestPSFactoryBuffer };
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CoGetPSClsid(&IID_IOleWindow, &clsid);
|
||||
ok_ole_success(hr, "CoGetPSClsid");
|
||||
|
||||
hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer,
|
||||
(void **)&ps_factory_buffer);
|
||||
ok_ole_success(hr, "CoGetClassObject");
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object2(&object_data, &thread);
|
||||
|
||||
IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(object_data.stream, &IID_IUnknown, (void **)&proxy);
|
||||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
IStream_Release(object_data.stream);
|
||||
|
||||
hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer,
|
||||
CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®istration_key);
|
||||
ok(hr == S_OK, "CoRegisterClassObject failed: %08x\n", hr);
|
||||
|
||||
hr = CoRegisterPSClsid(&IID_IOleWindow, &CLSID_WineTestPSFactoryBuffer);
|
||||
ok(hr == S_OK, "CoRegisterPSClsid failed: %08x\n", hr);
|
||||
|
||||
SET_EXPECT(CreateStub);
|
||||
SET_EXPECT(CreateProxy);
|
||||
hr = IUnknown_QueryInterface(proxy, &IID_IOleWindow, (void**)&ole_window);
|
||||
ok(hr == S_OK, "Could not get IOleWindow iface: %08x\n", hr);
|
||||
CHECK_CALLED(CreateStub);
|
||||
CHECK_CALLED(CreateProxy);
|
||||
|
||||
SET_EXPECT(Invoke);
|
||||
SET_EXPECT(GetWindow);
|
||||
hr = IOleWindow_GetWindow(ole_window, &hwnd);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "GetWindow failed: %08x\n", hr);
|
||||
todo_wine
|
||||
ok(hwnd == (HWND)0xdeadbeef, "hwnd = %p\n", hwnd);
|
||||
CHECK_CALLED(Invoke);
|
||||
CHECK_CALLED(GetWindow);
|
||||
|
||||
IOleWindow_Release(ole_window);
|
||||
|
||||
SET_EXPECT(Disconnect);
|
||||
IUnknown_Release(proxy);
|
||||
todo_wine
|
||||
CHECK_CALLED(Disconnect);
|
||||
|
||||
hr = CoRevokeClassObject(registration_key);
|
||||
ok(hr == S_OK, "CoRevokeClassObject failed: %08x\n", hr);
|
||||
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
||||
struct ncu_params
|
||||
{
|
||||
LPSTREAM stream;
|
||||
|
@ -3966,6 +4323,7 @@ START_TEST(marshal)
|
|||
with_external_conn = !with_external_conn;
|
||||
} while (with_external_conn);
|
||||
|
||||
test_marshal_channel_buffer();
|
||||
test_hresult_marshaling();
|
||||
test_proxy_used_in_wrong_thread();
|
||||
test_message_filter();
|
||||
|
|
Loading…
Reference in a new issue