+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);
+ 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 };
+