2 * Unit test suite for cstubs
4 * Copyright 2006 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define PROXY_DELEGATION
26 #include "wine/test.h"
38 static CStdPSFactoryBuffer PSFactoryBuffer
;
40 CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer
)
41 CSTDSTUBBUFFER2RELEASE(&PSFactoryBuffer
)
43 static GUID IID_if1
= {0x12345678, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
44 static GUID IID_if2
= {0x12345679, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
45 static GUID IID_if3
= {0x1234567a, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
46 static GUID IID_if4
= {0x1234567b, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
48 static int my_alloc_called
;
49 static int my_free_called
;
51 static void * CALLBACK
my_alloc(size_t size
)
54 return NdrOleAllocate(size
);
57 static void CALLBACK
my_free(void *ptr
)
63 typedef struct _MIDL_PROC_FORMAT_STRING
66 unsigned char Format
[ 2 ];
67 } MIDL_PROC_FORMAT_STRING
;
69 typedef struct _MIDL_TYPE_FORMAT_STRING
72 unsigned char Format
[ 2 ];
73 } MIDL_TYPE_FORMAT_STRING
;
76 static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString
=
84 static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString
=
92 static const MIDL_STUB_DESC Object_StubDesc
=
102 __MIDL_TypeFormatString
.Format
,
103 1, /* -error bounds_check flag */
104 0x20000, /* Ndr library version */
106 0x50100a4, /* MIDL Version 5.1.164 */
109 0, /* notify & notify_flag routine table */
116 static HRESULT WINAPI
if1_fn1_Proxy(void *This
)
121 static void __RPC_STUB
if1_fn1_Stub(
122 IRpcStubBuffer
*This
,
123 IRpcChannelBuffer
*_pRpcChannelBuffer
,
124 PRPC_MESSAGE _pRpcMessage
,
125 DWORD
*_pdwStubPhase
)
130 static HRESULT WINAPI
if1_fn2_Proxy(void *This
)
135 static void __RPC_STUB
if1_fn2_Stub(
136 IRpcStubBuffer
*This
,
137 IRpcChannelBuffer
*_pRpcChannelBuffer
,
138 PRPC_MESSAGE _pRpcMessage
,
139 DWORD
*_pdwStubPhase
)
144 static CINTERFACE_PROXY_VTABLE(5) if1_proxy_vtbl
=
147 { IUnknown_QueryInterface_Proxy
,
148 IUnknown_AddRef_Proxy
,
149 IUnknown_Release_Proxy
,
156 static const unsigned short if1_FormatStringOffsetTable
[] =
162 static const MIDL_SERVER_INFO if1_server_info
=
166 __MIDL_ProcFormatString
.Format
,
167 &if1_FormatStringOffsetTable
[-3],
174 static const PRPC_STUB_FUNCTION if1_table
[] =
180 static CInterfaceStubVtbl if1_stub_vtbl
=
188 { CStdStubBuffer_METHODS
}
191 static CINTERFACE_PROXY_VTABLE(13) if2_proxy_vtbl
=
194 { IUnknown_QueryInterface_Proxy
,
195 IUnknown_AddRef_Proxy
,
196 IUnknown_Release_Proxy
,
210 static const unsigned short if2_FormatStringOffsetTable
[] =
225 static const MIDL_SERVER_INFO if2_server_info
=
229 __MIDL_ProcFormatString
.Format
,
230 &if2_FormatStringOffsetTable
[-3],
237 static const PRPC_STUB_FUNCTION if2_table
[] =
239 STUB_FORWARDING_FUNCTION
,
240 STUB_FORWARDING_FUNCTION
,
241 STUB_FORWARDING_FUNCTION
,
242 STUB_FORWARDING_FUNCTION
,
243 STUB_FORWARDING_FUNCTION
,
244 STUB_FORWARDING_FUNCTION
,
245 STUB_FORWARDING_FUNCTION
,
246 STUB_FORWARDING_FUNCTION
,
247 STUB_FORWARDING_FUNCTION
,
248 STUB_FORWARDING_FUNCTION
251 static CInterfaceStubVtbl if2_stub_vtbl
=
259 { CStdStubBuffer_DELEGATING_METHODS
}
262 static CINTERFACE_PROXY_VTABLE(4) if3_proxy_vtbl
=
265 { IUnknown_QueryInterface_Proxy
,
266 IUnknown_AddRef_Proxy
,
267 IUnknown_Release_Proxy
,
273 static const unsigned short if3_FormatStringOffsetTable
[] =
279 static const MIDL_SERVER_INFO if3_server_info
=
283 __MIDL_ProcFormatString
.Format
,
284 &if3_FormatStringOffsetTable
[-3],
291 static const PRPC_STUB_FUNCTION if3_table
[] =
296 static CInterfaceStubVtbl if3_stub_vtbl
=
304 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
307 static CINTERFACE_PROXY_VTABLE(7) if4_proxy_vtbl
=
310 { IUnknown_QueryInterface_Proxy
,
311 IUnknown_AddRef_Proxy
,
312 IUnknown_Release_Proxy
,
320 static const unsigned short if4_FormatStringOffsetTable
[] =
329 static const MIDL_SERVER_INFO if4_server_info
=
333 __MIDL_ProcFormatString
.Format
,
334 &if4_FormatStringOffsetTable
[-3],
341 static const PRPC_STUB_FUNCTION if4_table
[] =
343 STUB_FORWARDING_FUNCTION
,
344 STUB_FORWARDING_FUNCTION
,
345 STUB_FORWARDING_FUNCTION
,
346 STUB_FORWARDING_FUNCTION
,
349 static CInterfaceStubVtbl if4_stub_vtbl
=
357 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
360 static const CInterfaceProxyVtbl
*cstub_ProxyVtblList
[] =
362 (const CInterfaceProxyVtbl
*) &if1_proxy_vtbl
,
363 (const CInterfaceProxyVtbl
*) &if2_proxy_vtbl
,
364 (const CInterfaceProxyVtbl
*) &if3_proxy_vtbl
,
365 (const CInterfaceProxyVtbl
*) &if4_proxy_vtbl
,
369 static const CInterfaceStubVtbl
*cstub_StubVtblList
[] =
371 (const CInterfaceStubVtbl
*) &if1_stub_vtbl
,
372 (const CInterfaceStubVtbl
*) &if2_stub_vtbl
,
373 (const CInterfaceStubVtbl
*) &if3_stub_vtbl
,
374 (const CInterfaceStubVtbl
*) &if4_stub_vtbl
,
378 static PCInterfaceName
const if_name_list
[] =
387 static const IID
*base_iid_list
[] =
396 #define cstub_CHECK_IID(n) IID_GENERIC_CHECK_IID( cstub, pIID, n)
398 static int __stdcall
iid_lookup( const IID
* pIID
, int * pIndex
)
402 IID_BS_LOOKUP_INITIAL_TEST( cstub
, 4, 4 )
403 IID_BS_LOOKUP_NEXT_TEST( cstub
, 2 )
404 IID_BS_LOOKUP_NEXT_TEST( cstub
, 1 )
405 IID_BS_LOOKUP_RETURN_RESULT( cstub
, 4, *pIndex
)
410 static const ExtendedProxyFileInfo my_proxy_file_info
=
412 (const PCInterfaceProxyVtblList
*) &cstub_ProxyVtblList
,
413 (const PCInterfaceStubVtblList
*) &cstub_StubVtblList
,
414 (const PCInterfaceName
*) &if_name_list
,
415 (const IID
**) &base_iid_list
,
425 static const ProxyFileInfo
*proxy_file_list
[] = {
431 static IPSFactoryBuffer
*test_NdrDllGetClassObject(void)
433 IPSFactoryBuffer
*ppsf
= NULL
;
434 const CLSID PSDispatch
= {0x20420, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
435 const CLSID CLSID_Unknown
= {0x45678, 0x1234, 0x6666, {0xff, 0x67, 0x45, 0x98, 0x76, 0x12, 0x34, 0x56}};
437 HMODULE hmod
= GetModuleHandleA("rpcrt4.dll");
438 void *CStd_QueryInterface
= GetProcAddress(hmod
, "CStdStubBuffer_QueryInterface");
439 void *CStd_AddRef
= GetProcAddress(hmod
, "CStdStubBuffer_AddRef");
440 void *CStd_Release
= GetProcAddress(hmod
, "NdrCStdStubBuffer_Release");
441 void *CStd_Connect
= GetProcAddress(hmod
, "CStdStubBuffer_Connect");
442 void *CStd_Disconnect
= GetProcAddress(hmod
, "CStdStubBuffer_Disconnect");
443 void *CStd_Invoke
= GetProcAddress(hmod
, "CStdStubBuffer_Invoke");
444 void *CStd_IsIIDSupported
= GetProcAddress(hmod
, "CStdStubBuffer_IsIIDSupported");
445 void *CStd_CountRefs
= GetProcAddress(hmod
, "CStdStubBuffer_CountRefs");
446 void *CStd_DebugServerQueryInterface
= GetProcAddress(hmod
, "CStdStubBuffer_DebugServerQueryInterface");
447 void *CStd_DebugServerRelease
= GetProcAddress(hmod
, "CStdStubBuffer_DebugServerRelease");
449 r
= NdrDllGetClassObject(&PSDispatch
, &IID_IPSFactoryBuffer
, (void**)&ppsf
, proxy_file_list
,
450 &CLSID_Unknown
, &PSFactoryBuffer
);
451 ok(r
== CLASS_E_CLASSNOTAVAILABLE
, "NdrDllGetClassObject with unknown clsid should have returned CLASS_E_CLASSNOTAVAILABLE instead of 0x%x\n", r
);
452 ok(ppsf
== NULL
, "NdrDllGetClassObject should have set ppsf to NULL on failure\n");
454 r
= NdrDllGetClassObject(&PSDispatch
, &IID_IPSFactoryBuffer
, (void**)&ppsf
, proxy_file_list
,
455 &PSDispatch
, &PSFactoryBuffer
);
457 ok(r
== S_OK
, "ret %08x\n", r
);
458 ok(ppsf
!= NULL
, "ppsf == NULL\n");
460 ok(PSFactoryBuffer
.pProxyFileList
== proxy_file_list
, "pfl not the same\n");
461 ok(PSFactoryBuffer
.pProxyFileList
[0]->pStubVtblList
== (PCInterfaceStubVtblList
*) &cstub_StubVtblList
, "stub vtbllist not the same\n");
463 /* if1 is non-delegating, if2 is delegating, if3 is non-delegating
464 but I've zero'ed the vtbl entries, similarly if4 is delegating
465 with zero'ed vtbl entries */
467 #define VTBL_TEST_NOT_CHANGE_TO(name, i) \
468 ok(PSFactoryBuffer.pProxyFileList[0]->pStubVtblList[i]->Vtbl.name != CStd_##name, #name "vtbl %d updated %p %p\n", \
469 i, PSFactoryBuffer.pProxyFileList[0]->pStubVtblList[i]->Vtbl.name, CStd_##name );
470 #define VTBL_TEST_CHANGE_TO(name, i) \
471 ok(PSFactoryBuffer.pProxyFileList[0]->pStubVtblList[i]->Vtbl.name == CStd_##name, #name "vtbl %d not updated %p %p\n", \
472 i, PSFactoryBuffer.pProxyFileList[0]->pStubVtblList[i]->Vtbl.name, CStd_##name );
473 #define VTBL_TEST_ZERO(name, i) \
474 ok(PSFactoryBuffer.pProxyFileList[0]->pStubVtblList[i]->Vtbl.name == NULL, #name "vtbl %d not null %p\n", \
475 i, PSFactoryBuffer.pProxyFileList[0]->pStubVtblList[i]->Vtbl.name );
476 VTBL_TEST_NOT_CHANGE_TO(QueryInterface
, 0);
477 VTBL_TEST_NOT_CHANGE_TO(AddRef
, 0);
478 VTBL_TEST_NOT_CHANGE_TO(Release
, 0);
479 VTBL_TEST_NOT_CHANGE_TO(Connect
, 0);
480 VTBL_TEST_NOT_CHANGE_TO(Disconnect
, 0);
481 VTBL_TEST_NOT_CHANGE_TO(Invoke
, 0);
482 VTBL_TEST_NOT_CHANGE_TO(IsIIDSupported
, 0);
483 VTBL_TEST_NOT_CHANGE_TO(CountRefs
, 0);
484 VTBL_TEST_NOT_CHANGE_TO(DebugServerQueryInterface
, 0);
485 VTBL_TEST_NOT_CHANGE_TO(DebugServerRelease
, 0);
487 VTBL_TEST_CHANGE_TO(QueryInterface
, 1);
488 VTBL_TEST_CHANGE_TO(AddRef
, 1);
489 VTBL_TEST_NOT_CHANGE_TO(Release
, 1);
490 VTBL_TEST_NOT_CHANGE_TO(Connect
, 1);
491 VTBL_TEST_NOT_CHANGE_TO(Disconnect
, 1);
492 VTBL_TEST_CHANGE_TO(Invoke
, 1);
493 VTBL_TEST_CHANGE_TO(IsIIDSupported
, 1);
494 VTBL_TEST_NOT_CHANGE_TO(CountRefs
, 1);
495 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface
, 1);
496 VTBL_TEST_CHANGE_TO(DebugServerRelease
, 1);
498 VTBL_TEST_CHANGE_TO(QueryInterface
, 2);
499 VTBL_TEST_CHANGE_TO(AddRef
, 2);
500 VTBL_TEST_ZERO(Release
, 2);
501 VTBL_TEST_CHANGE_TO(Connect
, 2);
502 VTBL_TEST_CHANGE_TO(Disconnect
, 2);
503 VTBL_TEST_CHANGE_TO(Invoke
, 2);
504 VTBL_TEST_CHANGE_TO(IsIIDSupported
, 2);
505 VTBL_TEST_CHANGE_TO(CountRefs
, 2);
506 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface
, 2);
507 VTBL_TEST_CHANGE_TO(DebugServerRelease
, 2);
509 VTBL_TEST_CHANGE_TO(QueryInterface
, 3);
510 VTBL_TEST_CHANGE_TO(AddRef
, 3);
511 VTBL_TEST_ZERO(Release
, 3);
512 VTBL_TEST_NOT_CHANGE_TO(Connect
, 3);
513 VTBL_TEST_NOT_CHANGE_TO(Disconnect
, 3);
514 VTBL_TEST_CHANGE_TO(Invoke
, 3);
515 VTBL_TEST_CHANGE_TO(IsIIDSupported
, 3);
516 VTBL_TEST_NOT_CHANGE_TO(CountRefs
, 3);
517 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface
, 3);
518 VTBL_TEST_CHANGE_TO(DebugServerRelease
, 3);
522 #undef VTBL_TEST_NOT_CHANGE_TO
523 #undef VTBL_TEST_CHANGE_TO
524 #undef VTBL_TEST_ZERO
526 ok(PSFactoryBuffer
.RefCount
== 1, "ref count %d\n", PSFactoryBuffer
.RefCount
);
527 IPSFactoryBuffer_Release(ppsf
);
529 r
= NdrDllGetClassObject(&IID_if3
, &IID_IPSFactoryBuffer
, (void**)&ppsf
, proxy_file_list
,
530 NULL
, &PSFactoryBuffer
);
531 ok(r
== S_OK
, "ret %08x\n", r
);
532 ok(ppsf
!= NULL
, "ppsf == NULL\n");
537 static int base_buffer_invoke_called
;
538 static HRESULT WINAPI
base_buffer_Invoke(IRpcStubBuffer
*This
, RPCOLEMESSAGE
*msg
, IRpcChannelBuffer
*channel
)
540 base_buffer_invoke_called
++;
541 ok(msg
== (RPCOLEMESSAGE
*)0xcafebabe, "msg ptr changed\n");
542 ok(channel
== (IRpcChannelBuffer
*)0xdeadbeef, "channel ptr changed\n");
543 return S_OK
; /* returning any failure here results in an exception */
546 static IRpcStubBufferVtbl base_buffer_vtbl
= {
559 static void test_NdrStubForwardingFunction(void)
563 IRpcChannelBuffer
*channel
= (IRpcChannelBuffer
*)0xdeadbeef;
564 RPC_MESSAGE
*msg
= (RPC_MESSAGE
*)0xcafebabe;
565 DWORD
*phase
= (DWORD
*)0x12345678;
566 IRpcStubBufferVtbl
*base_buffer_vtbl_ptr
= &base_buffer_vtbl
;
567 IRpcStubBuffer
*base_stub_buffer
= (IRpcStubBuffer
*)&base_buffer_vtbl_ptr
;
569 memset(This
, 0xcc, sizeof(This
));
570 This
[0] = base_stub_buffer
;
571 real_this
= &This
[1];
573 NdrStubForwardingFunction( real_this
, channel
, msg
, phase
);
574 ok(base_buffer_invoke_called
== 1, "base_buffer_invoke called %d times\n", base_buffer_invoke_called
);
578 static IRpcStubBuffer
*create_stub(IPSFactoryBuffer
*ppsf
, REFIID iid
, IUnknown
*obj
, HRESULT expected_result
)
580 IRpcStubBuffer
*pstub
= NULL
;
583 r
= IPSFactoryBuffer_CreateStub(ppsf
, iid
, obj
, &pstub
);
584 ok(r
== expected_result
, "CreateStub returned %08x expected %08x\n", r
, expected_result
);
588 static HRESULT WINAPI
create_stub_test_QI(IUnknown
*This
, REFIID iid
, void **ppv
)
590 ok(IsEqualIID(iid
, &IID_if1
), "incorrect iid\n");
591 *ppv
= (void*)0xdeadbeef;
595 static IUnknownVtbl create_stub_test_vtbl
=
602 static HRESULT WINAPI
create_stub_test_fail_QI(IUnknown
*This
, REFIID iid
, void **ppv
)
604 ok(IsEqualIID(iid
, &IID_if1
), "incorrect iid\n");
606 return E_NOINTERFACE
;
609 static IUnknownVtbl create_stub_test_fail_vtbl
=
611 create_stub_test_fail_QI
,
616 static void test_CreateStub(IPSFactoryBuffer
*ppsf
)
618 IUnknownVtbl
*vtbl
= &create_stub_test_vtbl
;
619 IUnknown
*obj
= (IUnknown
*)&vtbl
;
620 IRpcStubBuffer
*pstub
= create_stub(ppsf
, &IID_if1
, obj
, S_OK
);
621 CStdStubBuffer
*cstd_stub
= (CStdStubBuffer
*)pstub
;
622 const CInterfaceStubHeader
*header
= ((const CInterfaceStubHeader
*)cstd_stub
->lpVtbl
) - 1;
624 ok(IsEqualIID(header
->piid
, &IID_if1
), "header iid differs\n");
625 ok(cstd_stub
->RefCount
== 1, "ref count %d\n", cstd_stub
->RefCount
);
626 /* 0xdeadbeef returned from create_stub_test_QI */
627 ok(cstd_stub
->pvServerObject
== (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub
->pvServerObject
);
628 ok(cstd_stub
->pPSFactory
== ppsf
||
629 broken(cstd_stub
->pPSFactory
== (void *)0x00001000) /* Win9x & NT4 */,
630 "pPSFactory was %p instead of %p\n", cstd_stub
->pPSFactory
, ppsf
);
632 vtbl
= &create_stub_test_fail_vtbl
;
633 pstub
= create_stub(ppsf
, &IID_if1
, obj
, E_NOINTERFACE
);
637 static HRESULT WINAPI
connect_test_orig_QI(IUnknown
*This
, REFIID iid
, void **ppv
)
639 ok(IsEqualIID(iid
, &IID_if1
) ||
640 IsEqualIID(iid
, &IID_if2
), "incorrect iid\n");
645 static int connect_test_orig_release_called
;
646 static ULONG WINAPI
connect_test_orig_release(IUnknown
*This
)
648 connect_test_orig_release_called
++;
652 static IUnknownVtbl connect_test_orig_vtbl
=
654 connect_test_orig_QI
,
656 connect_test_orig_release
659 static HRESULT WINAPI
connect_test_new_QI(IUnknown
*This
, REFIID iid
, void **ppv
)
661 ok(IsEqualIID(iid
, &IID_if1
) ||
662 IsEqualIID(iid
, &IID_if2
), "incorrect iid\n");
663 *ppv
= (void*)0xcafebabe;
667 static IUnknownVtbl connect_test_new_vtbl
=
674 static HRESULT WINAPI
connect_test_new_fail_QI(IUnknown
*This
, REFIID iid
, void **ppv
)
676 ok(IsEqualIID(iid
, &IID_if1
), "incorrect iid\n");
677 *ppv
= (void*)0xdeadbeef;
678 return E_NOINTERFACE
;
681 static IUnknownVtbl connect_test_new_fail_vtbl
=
683 connect_test_new_fail_QI
,
688 static int connect_test_base_Connect_called
;
689 static HRESULT WINAPI
connect_test_base_Connect(IRpcStubBuffer
*pstub
, IUnknown
*obj
)
691 connect_test_base_Connect_called
++;
692 ok(*(void**)obj
== (void*)0xbeefcafe, "unexpected obj %p\n", obj
);
696 static IRpcStubBufferVtbl connect_test_base_stub_buffer_vtbl
=
701 connect_test_base_Connect
,
710 static void test_Connect(IPSFactoryBuffer
*ppsf
)
712 IUnknownVtbl
*orig_vtbl
= &connect_test_orig_vtbl
;
713 IUnknownVtbl
*new_vtbl
= &connect_test_new_vtbl
;
714 IUnknownVtbl
*new_fail_vtbl
= &connect_test_new_fail_vtbl
;
715 IUnknown
*obj
= (IUnknown
*)&orig_vtbl
;
716 IRpcStubBuffer
*pstub
= create_stub(ppsf
, &IID_if1
, obj
, S_OK
);
717 CStdStubBuffer
*cstd_stub
= (CStdStubBuffer
*)pstub
;
718 IRpcStubBufferVtbl
*base_stub_buf_vtbl
= &connect_test_base_stub_buffer_vtbl
;
721 obj
= (IUnknown
*)&new_vtbl
;
722 r
= IRpcStubBuffer_Connect(pstub
, obj
);
723 ok(r
== S_OK
, "r %08x\n", r
);
724 ok(connect_test_orig_release_called
== 1, "release called %d\n", connect_test_orig_release_called
);
725 ok(cstd_stub
->pvServerObject
== (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub
->pvServerObject
);
727 cstd_stub
->pvServerObject
= (IUnknown
*)&orig_vtbl
;
728 obj
= (IUnknown
*)&new_fail_vtbl
;
729 r
= IRpcStubBuffer_Connect(pstub
, obj
);
730 ok(r
== E_NOINTERFACE
, "r %08x\n", r
);
731 ok(cstd_stub
->pvServerObject
== (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub
->pvServerObject
);
732 ok(connect_test_orig_release_called
== 2, "release called %d\n", connect_test_orig_release_called
);
734 /* Now use a delegated stub.
736 We know from the NdrStubForwardFunction test that
737 (void**)pstub-1 is the base interface stub buffer. This shows
738 that (void**)pstub-2 contains the address of a vtable that gets
739 passed to the base interface's Connect method. Note that
740 (void**)pstub-2 itself gets passed to Connect and not
741 *((void**)pstub-2), so it should contain the vtable ptr and not
744 obj
= (IUnknown
*)&orig_vtbl
;
745 pstub
= create_stub(ppsf
, &IID_if2
, obj
, S_OK
);
746 *((void**)pstub
-1) = &base_stub_buf_vtbl
;
747 *((void**)pstub
-2) = (void*)0xbeefcafe;
749 obj
= (IUnknown
*)&new_vtbl
;
750 r
= IRpcStubBuffer_Connect(pstub
, obj
);
751 ok(connect_test_base_Connect_called
== 1, "connect_test_bsae_Connect called %d times\n",
752 connect_test_base_Connect_called
);
753 ok(connect_test_orig_release_called
== 3, "release called %d\n", connect_test_orig_release_called
);
754 cstd_stub
= (CStdStubBuffer
*)pstub
;
755 ok(cstd_stub
->pvServerObject
== (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub
->pvServerObject
);
758 static void test_Disconnect(IPSFactoryBuffer
*ppsf
)
760 IUnknownVtbl
*orig_vtbl
= &connect_test_orig_vtbl
;
761 IUnknown
*obj
= (IUnknown
*)&orig_vtbl
;
762 IRpcStubBuffer
*pstub
= create_stub(ppsf
, &IID_if1
, obj
, S_OK
);
763 CStdStubBuffer
*cstd_stub
= (CStdStubBuffer
*)pstub
;
765 connect_test_orig_release_called
= 0;
766 IRpcStubBuffer_Disconnect(pstub
);
767 ok(connect_test_orig_release_called
== 1, "release called %d\n", connect_test_orig_release_called
);
768 ok(cstd_stub
->pvServerObject
== NULL
, "pvServerObject %p\n", cstd_stub
->pvServerObject
);
772 static int release_test_psfacbuf_release_called
;
773 static ULONG WINAPI
release_test_pretend_psfacbuf_release(IUnknown
*pUnk
)
775 release_test_psfacbuf_release_called
++;
779 static IUnknownVtbl release_test_pretend_psfacbuf_vtbl
=
783 release_test_pretend_psfacbuf_release
786 static void test_Release(IPSFactoryBuffer
*ppsf
)
789 IUnknownVtbl
*orig_vtbl
= &connect_test_orig_vtbl
;
790 IUnknown
*obj
= (IUnknown
*)&orig_vtbl
;
791 IUnknownVtbl
*pretend_psfacbuf_vtbl
= &release_test_pretend_psfacbuf_vtbl
;
792 IUnknown
*pretend_psfacbuf
= (IUnknown
*)&pretend_psfacbuf_vtbl
;
793 IRpcStubBuffer
*pstub
= create_stub(ppsf
, &IID_if1
, obj
, S_OK
);
794 CStdStubBuffer
*cstd_stub
= (CStdStubBuffer
*)pstub
;
796 facbuf_refs
= PSFactoryBuffer
.RefCount
;
798 /* This shows that NdrCStdStubBuffer_Release doesn't call Disconnect */
799 ok(cstd_stub
->RefCount
== 1, "ref count %d\n", cstd_stub
->RefCount
);
800 connect_test_orig_release_called
= 0;
801 IRpcStubBuffer_Release(pstub
);
803 ok(connect_test_orig_release_called
== 0, "release called %d\n", connect_test_orig_release_called
);
805 ok(PSFactoryBuffer
.RefCount
== facbuf_refs
- 1, "factory buffer refs %d orig %d\n", PSFactoryBuffer
.RefCount
, facbuf_refs
);
807 /* This shows that NdrCStdStubBuffer_Release calls Release on its 2nd arg, rather than on This->pPSFactory
808 (which are usually the same and indeed it's odd that _Release requires this 2nd arg). */
809 pstub
= create_stub(ppsf
, &IID_if1
, obj
, S_OK
);
810 ok(PSFactoryBuffer
.RefCount
== facbuf_refs
, "factory buffer refs %d orig %d\n", PSFactoryBuffer
.RefCount
, facbuf_refs
);
811 NdrCStdStubBuffer_Release(pstub
, (IPSFactoryBuffer
*)pretend_psfacbuf
);
812 ok(release_test_psfacbuf_release_called
== 1, "pretend_psfacbuf_release called %d\n", release_test_psfacbuf_release_called
);
813 ok(PSFactoryBuffer
.RefCount
== facbuf_refs
, "factory buffer refs %d orig %d\n", PSFactoryBuffer
.RefCount
, facbuf_refs
);
816 static HRESULT WINAPI
delegating_invoke_test_QI(ITypeLib
*pUnk
, REFIID iid
, void** ppv
)
823 static ULONG WINAPI
delegating_invoke_test_addref(ITypeLib
*pUnk
)
828 static ULONG WINAPI
delegating_invoke_test_release(ITypeLib
*pUnk
)
833 static UINT WINAPI
delegating_invoke_test_get_type_info_count(ITypeLib
*pUnk
)
838 static ITypeLibVtbl delegating_invoke_test_obj_vtbl
=
840 delegating_invoke_test_QI
,
841 delegating_invoke_test_addref
,
842 delegating_invoke_test_release
,
843 delegating_invoke_test_get_type_info_count
,
855 static HRESULT WINAPI
delegating_invoke_chan_query_interface(IRpcChannelBuffer
*pchan
,
859 ok(0, "call to QueryInterface not expected\n");
860 return E_NOINTERFACE
;
863 static ULONG WINAPI
delegating_invoke_chan_add_ref(IRpcChannelBuffer
*pchan
)
868 static ULONG WINAPI
delegating_invoke_chan_release(IRpcChannelBuffer
*pchan
)
873 static HRESULT WINAPI
delegating_invoke_chan_get_buffer(IRpcChannelBuffer
*pchan
,
877 msg
->Buffer
= HeapAlloc(GetProcessHeap(), 0, msg
->cbBuffer
);
881 static HRESULT WINAPI
delegating_invoke_chan_send_receive(IRpcChannelBuffer
*pchan
,
882 RPCOLEMESSAGE
*pMessage
,
885 ok(0, "call to SendReceive not expected\n");
889 static HRESULT WINAPI
delegating_invoke_chan_free_buffer(IRpcChannelBuffer
*pchan
,
890 RPCOLEMESSAGE
*pMessage
)
892 ok(0, "call to FreeBuffer not expected\n");
896 static HRESULT WINAPI
delegating_invoke_chan_get_dest_ctx(IRpcChannelBuffer
*pchan
,
897 DWORD
*pdwDestContext
,
898 void **ppvDestContext
)
900 *pdwDestContext
= MSHCTX_LOCAL
;
901 *ppvDestContext
= NULL
;
905 static HRESULT WINAPI
delegating_invoke_chan_is_connected(IRpcChannelBuffer
*pchan
)
907 ok(0, "call to IsConnected not expected\n");
911 static IRpcChannelBufferVtbl delegating_invoke_test_rpc_chan_vtbl
=
913 delegating_invoke_chan_query_interface
,
914 delegating_invoke_chan_add_ref
,
915 delegating_invoke_chan_release
,
916 delegating_invoke_chan_get_buffer
,
917 delegating_invoke_chan_send_receive
,
918 delegating_invoke_chan_free_buffer
,
919 delegating_invoke_chan_get_dest_ctx
,
920 delegating_invoke_chan_is_connected
923 static void test_delegating_Invoke(IPSFactoryBuffer
*ppsf
)
925 ITypeLibVtbl
*obj_vtbl
= &delegating_invoke_test_obj_vtbl
;
926 IUnknown
*obj
= (IUnknown
*)&obj_vtbl
;
927 IRpcStubBuffer
*pstub
= create_stub(ppsf
, &IID_if2
, obj
, S_OK
);
928 IRpcChannelBufferVtbl
*pchan_vtbl
= &delegating_invoke_test_rpc_chan_vtbl
;
929 IRpcChannelBuffer
*pchan
= (IRpcChannelBuffer
*)&pchan_vtbl
;
933 memset(&msg
, 0, sizeof(msg
));
934 msg
.dataRepresentation
= NDR_LOCAL_DATA_REPRESENTATION
;
936 r
= IRpcStubBuffer_Invoke(pstub
, &msg
, pchan
);
937 ok(r
== S_OK
, "ret %08x\n", r
);
940 ok(*(DWORD
*)msg
.Buffer
== 0xabcdef, "buf[0] %08x\n", *(DWORD
*)msg
.Buffer
);
941 ok(*((DWORD
*)msg
.Buffer
+ 1) == S_OK
, "buf[1] %08x\n", *((DWORD
*)msg
.Buffer
+ 1));
943 /* free the buffer allocated by delegating_invoke_chan_get_buffer */
944 HeapFree(GetProcessHeap(), 0, msg
.Buffer
);
945 IRpcStubBuffer_Release(pstub
);
950 IPSFactoryBuffer
*ppsf
;
954 ppsf
= test_NdrDllGetClassObject();
955 test_NdrStubForwardingFunction();
956 test_CreateStub(ppsf
);
958 test_Disconnect(ppsf
);
960 test_delegating_Invoke(ppsf
);