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
|
@ -34,10 +34,37 @@
|
||||||
#include "initguid.h"
|
#include "initguid.h"
|
||||||
|
|
||||||
#include "wine/test.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_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);
|
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 */
|
/* functions that are not present on all versions of Windows */
|
||||||
static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
||||||
static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
|
static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
|
||||||
|
@ -281,6 +308,254 @@ static const IClassFactoryVtbl TestClassFactory_Vtbl =
|
||||||
|
|
||||||
static IClassFactory Test_ClassFactory = { &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
|
#define RELEASEMARSHALDATA WM_USER
|
||||||
|
|
||||||
struct host_object_data
|
struct host_object_data
|
||||||
|
@ -290,17 +565,28 @@ struct host_object_data
|
||||||
IUnknown *object;
|
IUnknown *object;
|
||||||
MSHLFLAGS marshal_flags;
|
MSHLFLAGS marshal_flags;
|
||||||
IMessageFilter *filter;
|
IMessageFilter *filter;
|
||||||
|
IUnknown *register_object;
|
||||||
|
CLSID register_clsid;
|
||||||
HANDLE marshal_event;
|
HANDLE marshal_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static IPSFactoryBuffer PSFactoryBuffer;
|
||||||
|
|
||||||
static DWORD CALLBACK host_object_proc(LPVOID p)
|
static DWORD CALLBACK host_object_proc(LPVOID p)
|
||||||
{
|
{
|
||||||
struct host_object_data *data = p;
|
struct host_object_data *data = p;
|
||||||
|
DWORD registration_key;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
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)
|
if (data->filter)
|
||||||
{
|
{
|
||||||
IMessageFilter * prev_filter = NULL;
|
IMessageFilter * prev_filter = NULL;
|
||||||
|
@ -958,6 +1244,77 @@ static void test_marshal_proxy_mta_apartment_shutdown(void)
|
||||||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
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
|
struct ncu_params
|
||||||
{
|
{
|
||||||
LPSTREAM stream;
|
LPSTREAM stream;
|
||||||
|
@ -3966,6 +4323,7 @@ START_TEST(marshal)
|
||||||
with_external_conn = !with_external_conn;
|
with_external_conn = !with_external_conn;
|
||||||
} while (with_external_conn);
|
} while (with_external_conn);
|
||||||
|
|
||||||
|
test_marshal_channel_buffer();
|
||||||
test_hresult_marshaling();
|
test_hresult_marshaling();
|
||||||
test_proxy_used_in_wrong_thread();
|
test_proxy_used_in_wrong_thread();
|
||||||
test_message_filter();
|
test_message_filter();
|
||||||
|
|
Loading…
Reference in New Issue