1 /* 2 * Unit test suite for cstubs 3 * 4 * Copyright 2006 Huw Davies 5 * 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. 10 * 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. 15 * 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 19 */ 20 21 #include <stdarg.h> 22 23 #define PROXY_DELEGATION 24 #define COBJMACROS 25 26 #include "wine/test.h" 27 #include <windef.h> 28 #include <winbase.h> 29 #include <winnt.h> 30 #include <winerror.h> 31 32 #include "initguid.h" 33 #include <ole2.h> 34 #include "rpc.h" 35 #include "rpcdce.h" 36 #include "rpcproxy.h" 37 38 static CStdPSFactoryBuffer PSFactoryBuffer; 39 40 CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer) 41 CSTDSTUBBUFFER2RELEASE(&PSFactoryBuffer) 42 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}}; 47 static CLSID CLSID_psfact = {0x1234567c, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}}; 48 49 static int my_alloc_called; 50 static int my_free_called; 51 52 static void * CALLBACK my_alloc(SIZE_T size) 53 { 54 my_alloc_called++; 55 return NdrOleAllocate(size); 56 } 57 58 static void CALLBACK my_free(void *ptr) 59 { 60 my_free_called++; 61 NdrOleFree(ptr); 62 } 63 64 typedef struct _MIDL_PROC_FORMAT_STRING 65 { 66 short Pad; 67 unsigned char Format[ 2 ]; 68 } MIDL_PROC_FORMAT_STRING; 69 70 typedef struct _MIDL_TYPE_FORMAT_STRING 71 { 72 short Pad; 73 unsigned char Format[ 2 ]; 74 } MIDL_TYPE_FORMAT_STRING; 75 76 77 static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString = 78 { 79 0, 80 { 81 0, 0 82 } 83 }; 84 85 static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString = 86 { 87 0, 88 { 89 0, 0 90 } 91 }; 92 93 static const MIDL_STUB_DESC Object_StubDesc = 94 { 95 NULL, 96 my_alloc, 97 my_free, 98 { 0 }, 99 0, 100 0, 101 0, 102 0, 103 __MIDL_TypeFormatString.Format, 104 1, /* -error bounds_check flag */ 105 0x20000, /* Ndr library version */ 106 0, 107 0x50100a4, /* MIDL Version 5.1.164 */ 108 0, 109 NULL, 110 0, /* notify & notify_flag routine table */ 111 1, /* Flags */ 112 0, /* Reserved3 */ 113 0, /* Reserved4 */ 114 0 /* Reserved5 */ 115 }; 116 117 static HRESULT WINAPI if1_fn1_Proxy(void *This) 118 { 119 return S_OK; 120 } 121 122 static void __RPC_STUB if1_fn1_Stub( 123 IRpcStubBuffer *This, 124 IRpcChannelBuffer *_pRpcChannelBuffer, 125 PRPC_MESSAGE _pRpcMessage, 126 DWORD *_pdwStubPhase) 127 { 128 trace("fn1 stub\n"); 129 } 130 131 static HRESULT WINAPI if1_fn2_Proxy(void *This) 132 { 133 return S_OK; 134 } 135 136 static void __RPC_STUB if1_fn2_Stub( 137 IRpcStubBuffer *This, 138 IRpcChannelBuffer *_pRpcChannelBuffer, 139 PRPC_MESSAGE _pRpcMessage, 140 DWORD *_pdwStubPhase) 141 { 142 trace("fn2 stub\n"); 143 } 144 145 static CINTERFACE_PROXY_VTABLE(5) if1_proxy_vtbl = 146 { 147 { &IID_if1 }, 148 { IUnknown_QueryInterface_Proxy, 149 IUnknown_AddRef_Proxy, 150 IUnknown_Release_Proxy , 151 if1_fn1_Proxy, 152 if1_fn2_Proxy 153 } 154 }; 155 156 157 static const unsigned short if1_FormatStringOffsetTable[] = 158 { 159 0, 160 0 161 }; 162 163 static const MIDL_SERVER_INFO if1_server_info = 164 { 165 &Object_StubDesc, 166 0, 167 __MIDL_ProcFormatString.Format, 168 &if1_FormatStringOffsetTable[-3], 169 0, 170 0, 171 0, 172 0}; 173 174 175 static const PRPC_STUB_FUNCTION if1_table[] = 176 { 177 if1_fn1_Stub, 178 if1_fn2_Stub 179 }; 180 181 static CInterfaceStubVtbl if1_stub_vtbl = 182 { 183 { 184 &IID_if1, 185 &if1_server_info, 186 5, 187 &if1_table[-3] 188 }, 189 { CStdStubBuffer_METHODS } 190 }; 191 192 static CINTERFACE_PROXY_VTABLE(13) if2_proxy_vtbl = 193 { 194 { &IID_if2 }, 195 { IUnknown_QueryInterface_Proxy, 196 IUnknown_AddRef_Proxy, 197 IUnknown_Release_Proxy , 198 0, 199 0, 200 0, 201 0, 202 0, 203 0, 204 0, 205 0, 206 0, 207 0 208 } 209 }; 210 211 static const unsigned short if2_FormatStringOffsetTable[] = 212 { 213 (unsigned short) -1, 214 (unsigned short) -1, 215 (unsigned short) -1, 216 (unsigned short) -1, 217 (unsigned short) -1, 218 (unsigned short) -1, 219 (unsigned short) -1, 220 (unsigned short) -1, 221 (unsigned short) -1, 222 (unsigned short) -1, 223 0 224 }; 225 226 static const MIDL_SERVER_INFO if2_server_info = 227 { 228 &Object_StubDesc, 229 0, 230 __MIDL_ProcFormatString.Format, 231 &if2_FormatStringOffsetTable[-3], 232 0, 233 0, 234 0, 235 0}; 236 237 238 static const PRPC_STUB_FUNCTION if2_table[] = 239 { 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, 249 STUB_FORWARDING_FUNCTION 250 }; 251 252 static CInterfaceStubVtbl if2_stub_vtbl = 253 { 254 { 255 &IID_if2, 256 &if2_server_info, 257 13, 258 &if2_table[-3] 259 }, 260 { CStdStubBuffer_DELEGATING_METHODS } 261 }; 262 263 static CINTERFACE_PROXY_VTABLE(5) if3_proxy_vtbl = 264 { 265 { &IID_if3 }, 266 { IUnknown_QueryInterface_Proxy, 267 IUnknown_AddRef_Proxy, 268 IUnknown_Release_Proxy , 269 if1_fn1_Proxy, 270 0 271 } 272 }; 273 274 275 static const unsigned short if3_FormatStringOffsetTable[] = 276 { 277 0, 278 0 279 }; 280 281 static const MIDL_SERVER_INFO if3_server_info = 282 { 283 &Object_StubDesc, 284 0, 285 __MIDL_ProcFormatString.Format, 286 &if3_FormatStringOffsetTable[-3], 287 0, 288 0, 289 0, 290 0}; 291 292 static CInterfaceStubVtbl if3_stub_vtbl = 293 { 294 { 295 &IID_if3, 296 &if3_server_info, 297 5, 298 &if1_table[-3] 299 }, 300 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 301 }; 302 303 static CINTERFACE_PROXY_VTABLE(7) if4_proxy_vtbl = 304 { 305 { &IID_if4 }, 306 { IUnknown_QueryInterface_Proxy, 307 IUnknown_AddRef_Proxy, 308 IUnknown_Release_Proxy , 309 0, 310 0, 311 0, 312 0 313 } 314 }; 315 316 static const unsigned short if4_FormatStringOffsetTable[] = 317 { 318 (unsigned short) -1, 319 (unsigned short) -1, 320 (unsigned short) -1, 321 (unsigned short) -1, 322 0 323 }; 324 325 static const MIDL_SERVER_INFO if4_server_info = 326 { 327 &Object_StubDesc, 328 0, 329 __MIDL_ProcFormatString.Format, 330 &if4_FormatStringOffsetTable[-3], 331 0, 332 0, 333 0, 334 0}; 335 336 static CInterfaceStubVtbl if4_stub_vtbl = 337 { 338 { 339 &IID_if4, 340 &if4_server_info, 341 7, 342 &if2_table[-3] 343 }, 344 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 345 }; 346 347 static const CInterfaceProxyVtbl *cstub_ProxyVtblList[] = 348 { 349 (const CInterfaceProxyVtbl *) &if1_proxy_vtbl, 350 (const CInterfaceProxyVtbl *) &if2_proxy_vtbl, 351 (const CInterfaceProxyVtbl *) &if3_proxy_vtbl, 352 (const CInterfaceProxyVtbl *) &if4_proxy_vtbl, 353 NULL 354 }; 355 356 static const CInterfaceStubVtbl *cstub_StubVtblList[] = 357 { 358 &if1_stub_vtbl, 359 &if2_stub_vtbl, 360 &if3_stub_vtbl, 361 &if4_stub_vtbl, 362 NULL 363 }; 364 365 static PCInterfaceName const if_name_list[] = 366 { 367 "if1", 368 "if2", 369 "if3", 370 "if4", 371 NULL 372 }; 373 374 static const IID *base_iid_list[] = 375 { 376 NULL, 377 &IID_ITypeLib, 378 NULL, 379 &IID_IDispatch, 380 NULL 381 }; 382 383 #define cstub_CHECK_IID(n) IID_GENERIC_CHECK_IID( cstub, pIID, n) 384 385 static int __stdcall iid_lookup( const IID * pIID, int * pIndex ) 386 { 387 IID_BS_LOOKUP_SETUP 388 389 IID_BS_LOOKUP_INITIAL_TEST( cstub, 4, 4 ) 390 IID_BS_LOOKUP_NEXT_TEST( cstub, 2 ) 391 IID_BS_LOOKUP_NEXT_TEST( cstub, 1 ) 392 IID_BS_LOOKUP_RETURN_RESULT( cstub, 4, *pIndex ) 393 394 } 395 396 397 static BOOL check_address(void *actual, void *expected) 398 { 399 static void *ole32_start = NULL; 400 static void *ole32_end = NULL; 401 static void *combase_start = NULL; 402 static void *combase_end = NULL; 403 404 if (actual == expected) 405 return TRUE; 406 407 /* On Win7, actual can be located inside ole32.dll */ 408 if (ole32_start == NULL || ole32_end == NULL) 409 { 410 PIMAGE_NT_HEADERS nt_headers; 411 ole32_start = (void *) GetModuleHandleA("ole32.dll"); 412 if (ole32_start == NULL) 413 return FALSE; 414 nt_headers = (PIMAGE_NT_HEADERS)((char *) ole32_start + ((PIMAGE_DOS_HEADER) ole32_start)->e_lfanew); 415 ole32_end = (void *)((char *) ole32_start + nt_headers->OptionalHeader.SizeOfImage); 416 } 417 418 if (ole32_start <= actual && actual < ole32_end) 419 return TRUE; 420 421 /* On Win8, actual can be located inside combase.dll */ 422 if (combase_start == NULL || combase_end == NULL) 423 { 424 PIMAGE_NT_HEADERS nt_headers; 425 combase_start = (void *) GetModuleHandleA("combase.dll"); 426 if (combase_start == NULL) 427 return FALSE; 428 nt_headers = (PIMAGE_NT_HEADERS)((char *) combase_start + ((PIMAGE_DOS_HEADER) combase_start)->e_lfanew); 429 combase_end = (void *)((char *) combase_start + nt_headers->OptionalHeader.SizeOfImage); 430 } 431 432 return (combase_start <= actual && actual < combase_end); 433 } 434 435 static const ExtendedProxyFileInfo my_proxy_file_info = 436 { 437 (const PCInterfaceProxyVtblList *) &cstub_ProxyVtblList, 438 (const PCInterfaceStubVtblList *) &cstub_StubVtblList, 439 (const PCInterfaceName *) &if_name_list, 440 (const IID **) &base_iid_list, 441 &iid_lookup, 442 4, 443 1, 444 NULL, 445 0, 446 0, 447 0 448 }; 449 450 static const ProxyFileInfo *proxy_file_list[] = { 451 &my_proxy_file_info, 452 NULL 453 }; 454 455 456 static IPSFactoryBuffer *test_NdrDllGetClassObject(void) 457 { 458 HMODULE rpcrt4 = GetModuleHandleA("rpcrt4.dll"); 459 IPSFactoryBuffer *ppsf = NULL; 460 const PCInterfaceProxyVtblList* proxy_vtbl; 461 const PCInterfaceStubVtblList* stub_vtbl; 462 const CLSID CLSID_Unknown = {0x45678, 0x1234, 0x6666, {0xff, 0x67, 0x45, 0x98, 0x76, 0x12, 0x34, 0x56}}; 463 static const GUID * const interfaces[] = { &IID_if1, &IID_if2, &IID_if3, &IID_if4 }; 464 UINT i; 465 HRESULT r; 466 HMODULE hmod = GetModuleHandleA("rpcrt4.dll"); 467 void *CStd_QueryInterface = GetProcAddress(hmod, "CStdStubBuffer_QueryInterface"); 468 void *CStd_AddRef = GetProcAddress(hmod, "CStdStubBuffer_AddRef"); 469 void *CStd_Release = GetProcAddress(hmod, "NdrCStdStubBuffer_Release"); 470 void *CStd_Connect = GetProcAddress(hmod, "CStdStubBuffer_Connect"); 471 void *CStd_Disconnect = GetProcAddress(hmod, "CStdStubBuffer_Disconnect"); 472 void *CStd_Invoke = GetProcAddress(hmod, "CStdStubBuffer_Invoke"); 473 void *CStd_IsIIDSupported = GetProcAddress(hmod, "CStdStubBuffer_IsIIDSupported"); 474 void *CStd_CountRefs = GetProcAddress(hmod, "CStdStubBuffer_CountRefs"); 475 void *CStd_DebugServerQueryInterface = GetProcAddress(hmod, "CStdStubBuffer_DebugServerQueryInterface"); 476 void *CStd_DebugServerRelease = GetProcAddress(hmod, "CStdStubBuffer_DebugServerRelease"); 477 478 r = NdrDllGetClassObject(&CLSID_Unknown, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list, 479 &CLSID_psfact, &PSFactoryBuffer); 480 ok(r == CLASS_E_CLASSNOTAVAILABLE, "NdrDllGetClassObject with unknown clsid should have returned CLASS_E_CLASSNOTAVAILABLE instead of 0x%x\n", r); 481 ok(ppsf == NULL, "NdrDllGetClassObject should have set ppsf to NULL on failure\n"); 482 483 r = NdrDllGetClassObject(&CLSID_psfact, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list, 484 &CLSID_psfact, &PSFactoryBuffer); 485 486 ok(r == S_OK, "ret %08x\n", r); 487 ok(ppsf != NULL, "ppsf == NULL\n"); 488 489 proxy_vtbl = PSFactoryBuffer.pProxyFileList[0]->pProxyVtblList; 490 stub_vtbl = PSFactoryBuffer.pProxyFileList[0]->pStubVtblList; 491 ok(PSFactoryBuffer.pProxyFileList == proxy_file_list, "pfl not the same\n"); 492 ok(proxy_vtbl == (PCInterfaceProxyVtblList *) &cstub_ProxyVtblList, "proxy vtbllist not the same\n"); 493 ok(stub_vtbl == (PCInterfaceStubVtblList *) &cstub_StubVtblList, "stub vtbllist not the same\n"); 494 495 /* if1 is non-delegating, if2 is delegating, if3 is non-delegating 496 but I've zero'ed the vtbl entries, similarly if4 is delegating 497 with zero'ed vtbl entries */ 498 499 #define VTBL_TEST_NOT_CHANGE_TO(name, i) \ 500 ok(stub_vtbl[i]->Vtbl.name != CStd_##name, #name "vtbl %d updated %p %p\n", \ 501 i, stub_vtbl[i]->Vtbl.name, CStd_##name ) 502 #define VTBL_TEST_CHANGE_TO(name, i) \ 503 ok(check_address(stub_vtbl[i]->Vtbl.name, CStd_##name), #name "vtbl %d not updated %p %p\n", \ 504 i, stub_vtbl[i]->Vtbl.name, CStd_##name ) 505 #define VTBL_TEST_ZERO(name, i) \ 506 ok(stub_vtbl[i]->Vtbl.name == NULL, #name "vtbl %d not null %p\n", \ 507 i, stub_vtbl[i]->Vtbl.name ) 508 509 VTBL_TEST_NOT_CHANGE_TO(QueryInterface, 0); 510 VTBL_TEST_NOT_CHANGE_TO(AddRef, 0); 511 VTBL_TEST_NOT_CHANGE_TO(Release, 0); 512 VTBL_TEST_NOT_CHANGE_TO(Connect, 0); 513 VTBL_TEST_NOT_CHANGE_TO(Disconnect, 0); 514 VTBL_TEST_NOT_CHANGE_TO(Invoke, 0); 515 VTBL_TEST_NOT_CHANGE_TO(IsIIDSupported, 0); 516 VTBL_TEST_NOT_CHANGE_TO(CountRefs, 0); 517 VTBL_TEST_NOT_CHANGE_TO(DebugServerQueryInterface, 0); 518 VTBL_TEST_NOT_CHANGE_TO(DebugServerRelease, 0); 519 520 VTBL_TEST_CHANGE_TO(QueryInterface, 1); 521 VTBL_TEST_CHANGE_TO(AddRef, 1); 522 VTBL_TEST_NOT_CHANGE_TO(Release, 1); 523 VTBL_TEST_NOT_CHANGE_TO(Connect, 1); 524 VTBL_TEST_NOT_CHANGE_TO(Disconnect, 1); 525 VTBL_TEST_CHANGE_TO(Invoke, 1); 526 VTBL_TEST_CHANGE_TO(IsIIDSupported, 1); 527 VTBL_TEST_NOT_CHANGE_TO(CountRefs, 1); 528 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface, 1); 529 VTBL_TEST_CHANGE_TO(DebugServerRelease, 1); 530 531 VTBL_TEST_CHANGE_TO(QueryInterface, 2); 532 VTBL_TEST_CHANGE_TO(AddRef, 2); 533 VTBL_TEST_ZERO(Release, 2); 534 VTBL_TEST_CHANGE_TO(Connect, 2); 535 VTBL_TEST_CHANGE_TO(Disconnect, 2); 536 VTBL_TEST_CHANGE_TO(Invoke, 2); 537 VTBL_TEST_CHANGE_TO(IsIIDSupported, 2); 538 VTBL_TEST_CHANGE_TO(CountRefs, 2); 539 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface, 2); 540 VTBL_TEST_CHANGE_TO(DebugServerRelease, 2); 541 542 VTBL_TEST_CHANGE_TO(QueryInterface, 3); 543 VTBL_TEST_CHANGE_TO(AddRef, 3); 544 VTBL_TEST_ZERO(Release, 3); 545 VTBL_TEST_NOT_CHANGE_TO(Connect, 3); 546 VTBL_TEST_NOT_CHANGE_TO(Disconnect, 3); 547 VTBL_TEST_CHANGE_TO(Invoke, 3); 548 VTBL_TEST_CHANGE_TO(IsIIDSupported, 3); 549 VTBL_TEST_NOT_CHANGE_TO(CountRefs, 3); 550 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface, 3); 551 VTBL_TEST_CHANGE_TO(DebugServerRelease, 3); 552 553 #define VTBL_PROXY_TEST(i,num,ptr) \ 554 ok( check_address(proxy_vtbl[i]->Vtbl[num], (ptr)), "wrong proxy %u func %u %p/%p\n", \ 555 (i), (num), proxy_vtbl[i]->Vtbl[num], (ptr) ) 556 #define VTBL_PROXY_TEST_NOT_ZERO(i,num) \ 557 ok( proxy_vtbl[i]->Vtbl[num] != NULL, "wrong proxy %u func %u is NULL\n", (i), (num)) 558 559 VTBL_PROXY_TEST(0, 0, IUnknown_QueryInterface_Proxy); 560 VTBL_PROXY_TEST(0, 1, IUnknown_AddRef_Proxy); 561 VTBL_PROXY_TEST(0, 2, IUnknown_Release_Proxy); 562 VTBL_PROXY_TEST(0, 3, if1_fn1_Proxy); 563 VTBL_PROXY_TEST(0, 4, if1_fn2_Proxy); 564 565 VTBL_PROXY_TEST(1, 0, GetProcAddress(rpcrt4,"IUnknown_QueryInterface_Proxy")); 566 VTBL_PROXY_TEST(1, 1, GetProcAddress(rpcrt4,"IUnknown_AddRef_Proxy")); 567 VTBL_PROXY_TEST(1, 2, GetProcAddress(rpcrt4,"IUnknown_Release_Proxy")); 568 VTBL_PROXY_TEST_NOT_ZERO(1, 3); 569 VTBL_PROXY_TEST_NOT_ZERO(1, 4); 570 VTBL_PROXY_TEST_NOT_ZERO(1, 5); 571 VTBL_PROXY_TEST_NOT_ZERO(1, 6); 572 VTBL_PROXY_TEST_NOT_ZERO(1, 7); 573 VTBL_PROXY_TEST_NOT_ZERO(1, 8); 574 VTBL_PROXY_TEST_NOT_ZERO(1, 9); 575 VTBL_PROXY_TEST_NOT_ZERO(1, 10); 576 VTBL_PROXY_TEST_NOT_ZERO(1, 11); 577 VTBL_PROXY_TEST_NOT_ZERO(1, 12); 578 579 VTBL_PROXY_TEST(2, 0, IUnknown_QueryInterface_Proxy); 580 VTBL_PROXY_TEST(2, 1, IUnknown_AddRef_Proxy); 581 VTBL_PROXY_TEST(2, 2, IUnknown_Release_Proxy); 582 VTBL_PROXY_TEST(2, 3, if1_fn1_Proxy); 583 todo_wine VTBL_PROXY_TEST_NOT_ZERO(2, 4); 584 585 VTBL_PROXY_TEST(3, 0, GetProcAddress(rpcrt4,"IUnknown_QueryInterface_Proxy")); 586 VTBL_PROXY_TEST(3, 1, GetProcAddress(rpcrt4,"IUnknown_AddRef_Proxy")); 587 VTBL_PROXY_TEST(3, 2, GetProcAddress(rpcrt4,"IUnknown_Release_Proxy")); 588 VTBL_PROXY_TEST_NOT_ZERO(3, 3); 589 VTBL_PROXY_TEST_NOT_ZERO(3, 4); 590 VTBL_PROXY_TEST_NOT_ZERO(3, 5); 591 VTBL_PROXY_TEST_NOT_ZERO(3, 6); 592 593 #undef VTBL_TEST_NOT_CHANGE_TO 594 #undef VTBL_TEST_CHANGE_TO 595 #undef VTBL_TEST_ZERO 596 #undef VTBL_PROXY_TEST 597 #undef VTBL_PROXY_TEST_NOT_ZERO 598 599 for (i = 0; i < sizeof(interfaces)/sizeof(interfaces[0]); i++) 600 ok( proxy_vtbl[i]->header.piid == interfaces[i], 601 "wrong proxy %u iid %p/%p\n", i, proxy_vtbl[i]->header.piid, interfaces[i] ); 602 603 ok(PSFactoryBuffer.RefCount == 1, "ref count %d\n", PSFactoryBuffer.RefCount); 604 IPSFactoryBuffer_Release(ppsf); 605 606 /* One can also search by IID */ 607 r = NdrDllGetClassObject(&IID_if3, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list, 608 &CLSID_psfact, &PSFactoryBuffer); 609 ok(r == S_OK, "ret %08x\n", r); 610 ok(ppsf != NULL, "ppsf == NULL\n"); 611 IPSFactoryBuffer_Release(ppsf); 612 613 r = NdrDllGetClassObject(&IID_if3, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list, 614 NULL, &PSFactoryBuffer); 615 ok(r == S_OK, "ret %08x\n", r); 616 ok(ppsf != NULL, "ppsf == NULL\n"); 617 IPSFactoryBuffer_Release(ppsf); 618 619 /* but only if the PS factory implements it */ 620 r = NdrDllGetClassObject(&IID_IDispatch, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list, 621 &CLSID_psfact, &PSFactoryBuffer); 622 ok(r == CLASS_E_CLASSNOTAVAILABLE, "ret %08x\n", r); 623 624 /* Create it again to return */ 625 r = NdrDllGetClassObject(&CLSID_psfact, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list, 626 &CLSID_psfact, &PSFactoryBuffer); 627 ok(r == S_OK, "ret %08x\n", r); 628 ok(ppsf != NULL, "ppsf == NULL\n"); 629 630 /* Because this PS factory is not loaded as a dll in the normal way, Windows 8 / 10 631 get confused and will crash when one of the proxies for the delegated ifaces is created. 632 Registering the ifaces fixes this (in fact calling CoRegisterPSClsid() with any IID / CLSID is enough). */ 633 634 r = CoRegisterPSClsid(&IID_if1, &CLSID_psfact); 635 ok(r == S_OK, "ret %08x\n", r); 636 r = CoRegisterPSClsid(&IID_if2, &CLSID_psfact); 637 ok(r == S_OK, "ret %08x\n", r); 638 r = CoRegisterPSClsid(&IID_if3, &CLSID_psfact); 639 ok(r == S_OK, "ret %08x\n", r); 640 r = CoRegisterPSClsid(&IID_if4, &CLSID_psfact); 641 ok(r == S_OK, "ret %08x\n", r); 642 643 return ppsf; 644 } 645 646 static int base_buffer_invoke_called; 647 static HRESULT WINAPI base_buffer_Invoke(IRpcStubBuffer *This, RPCOLEMESSAGE *msg, IRpcChannelBuffer *channel) 648 { 649 base_buffer_invoke_called++; 650 ok(msg == (RPCOLEMESSAGE*)0xcafebabe, "msg ptr changed\n"); 651 ok(channel == (IRpcChannelBuffer*)0xdeadbeef, "channel ptr changed\n"); 652 return S_OK; /* returning any failure here results in an exception */ 653 } 654 655 static IRpcStubBufferVtbl base_buffer_vtbl = { 656 (void*)0xcafebab0, 657 (void*)0xcafebab1, 658 (void*)0xcafebab2, 659 (void*)0xcafebab3, 660 (void*)0xcafebab4, 661 base_buffer_Invoke, 662 (void*)0xcafebab6, 663 (void*)0xcafebab7, 664 (void*)0xcafebab8, 665 (void*)0xcafebab9 666 }; 667 668 static void test_NdrStubForwardingFunction(void) 669 { 670 void *This[5]; 671 void *real_this; 672 IRpcChannelBuffer *channel = (IRpcChannelBuffer*)0xdeadbeef; 673 RPC_MESSAGE *msg = (RPC_MESSAGE*)0xcafebabe; 674 DWORD *phase = (DWORD*)0x12345678; 675 IRpcStubBufferVtbl *base_buffer_vtbl_ptr = &base_buffer_vtbl; 676 IRpcStubBuffer *base_stub_buffer = (IRpcStubBuffer*)&base_buffer_vtbl_ptr; 677 678 memset(This, 0xcc, sizeof(This)); 679 This[0] = base_stub_buffer; 680 real_this = &This[1]; 681 682 NdrStubForwardingFunction( real_this, channel, msg, phase ); 683 ok(base_buffer_invoke_called == 1, "base_buffer_invoke called %d times\n", base_buffer_invoke_called); 684 685 } 686 687 static IRpcStubBuffer *create_stub(IPSFactoryBuffer *ppsf, REFIID iid, IUnknown *obj, HRESULT expected_result) 688 { 689 IRpcStubBuffer *pstub = NULL; 690 HRESULT r; 691 692 r = IPSFactoryBuffer_CreateStub(ppsf, iid, obj, &pstub); 693 ok(r == expected_result, "CreateStub returned %08x expected %08x\n", r, expected_result); 694 return pstub; 695 } 696 697 static HRESULT WINAPI create_stub_test_QI(IUnknown *This, REFIID iid, void **ppv) 698 { 699 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n"); 700 *ppv = (void*)0xdeadbeef; 701 return S_OK; 702 } 703 704 static IUnknownVtbl create_stub_test_vtbl = 705 { 706 create_stub_test_QI, 707 NULL, 708 NULL 709 }; 710 711 static HRESULT WINAPI create_stub_test_fail_QI(IUnknown *This, REFIID iid, void **ppv) 712 { 713 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n"); 714 *ppv = NULL; 715 return E_NOINTERFACE; 716 } 717 718 static IUnknownVtbl create_stub_test_fail_vtbl = 719 { 720 create_stub_test_fail_QI, 721 NULL, 722 NULL 723 }; 724 725 struct dummy_unknown 726 { 727 IUnknown IUnknown_iface; 728 LONG ref; 729 }; 730 731 static inline struct dummy_unknown *impl_from_IUnknown(IUnknown *iface) 732 { 733 return CONTAINING_RECORD(iface, struct dummy_unknown, IUnknown_iface); 734 } 735 736 static HRESULT WINAPI dummy_QueryInterface(IUnknown *This, REFIID iid, void **ppv) 737 { 738 *ppv = NULL; 739 return E_NOINTERFACE; 740 } 741 742 static ULONG WINAPI dummy_AddRef(LPUNKNOWN iface) 743 { 744 struct dummy_unknown *this = impl_from_IUnknown(iface); 745 return InterlockedIncrement( &this->ref ); 746 } 747 748 static ULONG WINAPI dummy_Release(LPUNKNOWN iface) 749 { 750 struct dummy_unknown *this = impl_from_IUnknown(iface); 751 return InterlockedDecrement( &this->ref ); 752 } 753 754 static IUnknownVtbl dummy_unknown_vtbl = 755 { 756 dummy_QueryInterface, 757 dummy_AddRef, 758 dummy_Release 759 }; 760 static struct dummy_unknown dummy_unknown = { { &dummy_unknown_vtbl }, 0 }; 761 762 static void create_proxy_test( IPSFactoryBuffer *ppsf, REFIID iid, const void *expected_vtbl ) 763 { 764 IRpcProxyBuffer *proxy = NULL; 765 IUnknown *iface = NULL; 766 HRESULT r; 767 ULONG count; 768 769 r = IPSFactoryBuffer_CreateProxy(ppsf, NULL, iid, &proxy, (void **)&iface); 770 ok( r == S_OK, "IPSFactoryBuffer_CreateProxy failed %x\n", r ); 771 ok( *(void **)iface == expected_vtbl, "wrong iface pointer %p/%p\n", *(void **)iface, expected_vtbl ); 772 count = IUnknown_Release( iface ); 773 ok( count == 1, "wrong refcount %u\n", count ); 774 count = IRpcProxyBuffer_Release( proxy ); 775 ok( count == 0, "wrong refcount %u\n", count ); 776 777 dummy_unknown.ref = 4; 778 r = IPSFactoryBuffer_CreateProxy(ppsf, &dummy_unknown.IUnknown_iface, iid, &proxy, 779 (void **)&iface); 780 ok( r == S_OK, "IPSFactoryBuffer_CreateProxy failed %x\n", r ); 781 ok( dummy_unknown.ref == 5, "wrong refcount %u\n", dummy_unknown.ref ); 782 ok( *(void **)iface == expected_vtbl, "wrong iface pointer %p/%p\n", *(void **)iface, expected_vtbl ); 783 count = IUnknown_Release( iface ); 784 ok( count == 4, "wrong refcount %u\n", count ); 785 ok( dummy_unknown.ref == 4, "wrong refcount %u\n", dummy_unknown.ref ); 786 count = IRpcProxyBuffer_Release( proxy ); 787 ok( count == 0, "wrong refcount %u\n", count ); 788 ok( dummy_unknown.ref == 4, "wrong refcount %u\n", dummy_unknown.ref ); 789 } 790 791 static void test_CreateProxy( IPSFactoryBuffer *ppsf ) 792 { 793 create_proxy_test( ppsf, &IID_if1, if1_proxy_vtbl.Vtbl ); 794 create_proxy_test( ppsf, &IID_if2, if2_proxy_vtbl.Vtbl ); 795 create_proxy_test( ppsf, &IID_if3, if3_proxy_vtbl.Vtbl ); 796 create_proxy_test( ppsf, &IID_if4, if4_proxy_vtbl.Vtbl ); 797 } 798 799 static void test_CreateStub(IPSFactoryBuffer *ppsf) 800 { 801 IUnknownVtbl *vtbl = &create_stub_test_vtbl; 802 IUnknown *obj = (IUnknown*)&vtbl; 803 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK); 804 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub; 805 const CInterfaceStubHeader *header = &CONTAINING_RECORD(cstd_stub->lpVtbl, const CInterfaceStubVtbl, Vtbl)->header; 806 807 ok(IsEqualIID(header->piid, &IID_if1), "header iid differs\n"); 808 ok(cstd_stub->RefCount == 1, "ref count %d\n", cstd_stub->RefCount); 809 /* 0xdeadbeef returned from create_stub_test_QI */ 810 ok(cstd_stub->pvServerObject == (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub->pvServerObject); 811 ok(cstd_stub->pPSFactory != NULL, "pPSFactory was NULL\n"); 812 cstd_stub->pvServerObject = NULL; 813 IRpcStubBuffer_Release(pstub); 814 815 vtbl = &create_stub_test_fail_vtbl; 816 pstub = create_stub(ppsf, &IID_if1, obj, E_NOINTERFACE); 817 ok(pstub == S_OK, "create_stub failed: %u\n", GetLastError()); 818 819 } 820 821 static HRESULT WINAPI connect_test_orig_QI(IUnknown *This, REFIID iid, void **ppv) 822 { 823 ok(IsEqualIID(iid, &IID_if1) || 824 IsEqualIID(iid, &IID_if2), "incorrect iid\n"); 825 *ppv = (void*)This; 826 return S_OK; 827 } 828 829 static int connect_test_orig_release_called; 830 static ULONG WINAPI connect_test_orig_release(IUnknown *This) 831 { 832 connect_test_orig_release_called++; 833 return 0; 834 } 835 836 static IUnknownVtbl connect_test_orig_vtbl = 837 { 838 connect_test_orig_QI, 839 NULL, 840 connect_test_orig_release 841 }; 842 843 static HRESULT WINAPI connect_test_new_QI(IUnknown *This, REFIID iid, void **ppv) 844 { 845 ok(IsEqualIID(iid, &IID_if1) || 846 IsEqualIID(iid, &IID_if2), "incorrect iid\n"); 847 *ppv = (void*)0xcafebabe; 848 return S_OK; 849 } 850 851 static IUnknownVtbl connect_test_new_vtbl = 852 { 853 connect_test_new_QI, 854 NULL, 855 NULL 856 }; 857 858 static HRESULT WINAPI connect_test_new_fail_QI(IUnknown *This, REFIID iid, void **ppv) 859 { 860 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n"); 861 *ppv = (void*)0xdeadbeef; 862 return E_NOINTERFACE; 863 } 864 865 static IUnknownVtbl connect_test_new_fail_vtbl = 866 { 867 connect_test_new_fail_QI, 868 NULL, 869 NULL 870 }; 871 872 static int connect_test_base_Connect_called; 873 static HRESULT WINAPI connect_test_base_Connect(IRpcStubBuffer *pstub, IUnknown *obj) 874 { 875 connect_test_base_Connect_called++; 876 ok(*(void**)obj == (void*)0xbeefcafe, "unexpected obj %p\n", obj); 877 return S_OK; 878 } 879 880 static IRpcStubBufferVtbl connect_test_base_stub_buffer_vtbl = 881 { 882 (void*)0xcafebab0, 883 (void*)0xcafebab1, 884 (void*)0xcafebab2, 885 connect_test_base_Connect, 886 (void*)0xcafebab4, 887 (void*)0xcafebab5, 888 (void*)0xcafebab6, 889 (void*)0xcafebab7, 890 (void*)0xcafebab8, 891 (void*)0xcafebab9 892 }; 893 894 static void test_Connect(IPSFactoryBuffer *ppsf) 895 { 896 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl; 897 IUnknownVtbl *new_vtbl = &connect_test_new_vtbl; 898 IUnknownVtbl *new_fail_vtbl = &connect_test_new_fail_vtbl; 899 IUnknown *obj = (IUnknown*)&orig_vtbl; 900 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK); 901 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub; 902 IRpcStubBufferVtbl *base_stub_buf_vtbl = &connect_test_base_stub_buffer_vtbl; 903 HRESULT r; 904 905 obj = (IUnknown*)&new_vtbl; 906 r = IRpcStubBuffer_Connect(pstub, obj); 907 ok(r == S_OK, "r %08x\n", r); 908 ok(connect_test_orig_release_called == 1, "release called %d\n", connect_test_orig_release_called); 909 ok(cstd_stub->pvServerObject == (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub->pvServerObject); 910 911 cstd_stub->pvServerObject = (IUnknown*)&orig_vtbl; 912 obj = (IUnknown*)&new_fail_vtbl; 913 r = IRpcStubBuffer_Connect(pstub, obj); 914 ok(r == E_NOINTERFACE, "r %08x\n", r); 915 ok(cstd_stub->pvServerObject == (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub->pvServerObject); 916 ok(connect_test_orig_release_called == 2, "release called %d\n", connect_test_orig_release_called); 917 918 /* Now use a delegated stub. 919 920 We know from the NdrStubForwardFunction test that 921 (void**)pstub-1 is the base interface stub buffer. This shows 922 that (void**)pstub-2 contains the address of a vtable that gets 923 passed to the base interface's Connect method. Note that 924 (void**)pstub-2 itself gets passed to Connect and not 925 *((void**)pstub-2), so it should contain the vtable ptr and not 926 an interface ptr. */ 927 928 obj = (IUnknown*)&orig_vtbl; 929 pstub = create_stub(ppsf, &IID_if2, obj, S_OK); 930 *((void**)pstub-1) = &base_stub_buf_vtbl; 931 *((void**)pstub-2) = (void*)0xbeefcafe; 932 933 obj = (IUnknown*)&new_vtbl; 934 r = IRpcStubBuffer_Connect(pstub, obj); 935 ok(r == S_OK, "r %08x\n", r); 936 ok(connect_test_base_Connect_called == 1, "connect_test_bsae_Connect called %d times\n", 937 connect_test_base_Connect_called); 938 ok(connect_test_orig_release_called == 3, "release called %d\n", connect_test_orig_release_called); 939 cstd_stub = (CStdStubBuffer*)pstub; 940 ok(cstd_stub->pvServerObject == (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub->pvServerObject); 941 } 942 943 static void test_Disconnect(IPSFactoryBuffer *ppsf) 944 { 945 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl; 946 IUnknown *obj = (IUnknown*)&orig_vtbl; 947 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK); 948 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub; 949 950 connect_test_orig_release_called = 0; 951 IRpcStubBuffer_Disconnect(pstub); 952 ok(connect_test_orig_release_called == 1, "release called %d\n", connect_test_orig_release_called); 953 ok(cstd_stub->pvServerObject == NULL, "pvServerObject %p\n", cstd_stub->pvServerObject); 954 IRpcStubBuffer_Release(pstub); 955 } 956 957 958 static int release_test_psfacbuf_release_called; 959 static ULONG WINAPI release_test_pretend_psfacbuf_release(IUnknown *pUnk) 960 { 961 release_test_psfacbuf_release_called++; 962 return 1; 963 } 964 965 static IUnknownVtbl release_test_pretend_psfacbuf_vtbl = 966 { 967 NULL, 968 NULL, 969 release_test_pretend_psfacbuf_release 970 }; 971 972 static void test_Release(IPSFactoryBuffer *ppsf) 973 { 974 LONG facbuf_refs; 975 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl; 976 IUnknown *obj = (IUnknown*)&orig_vtbl; 977 IUnknownVtbl *pretend_psfacbuf_vtbl = &release_test_pretend_psfacbuf_vtbl; 978 IUnknown *pretend_psfacbuf = (IUnknown *)&pretend_psfacbuf_vtbl; 979 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK); 980 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub; 981 982 facbuf_refs = PSFactoryBuffer.RefCount; 983 984 /* This shows that NdrCStdStubBuffer_Release doesn't call Disconnect */ 985 ok(cstd_stub->RefCount == 1, "ref count %d\n", cstd_stub->RefCount); 986 connect_test_orig_release_called = 0; 987 IRpcStubBuffer_Release(pstub); 988 todo_wine { 989 ok(connect_test_orig_release_called == 0, "release called %d\n", connect_test_orig_release_called); 990 } 991 ok(PSFactoryBuffer.RefCount == facbuf_refs - 1, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs); 992 993 /* This shows that NdrCStdStubBuffer_Release calls Release on its 2nd arg, rather than on This->pPSFactory 994 (which are usually the same and indeed it's odd that _Release requires this 2nd arg). */ 995 pstub = create_stub(ppsf, &IID_if1, obj, S_OK); 996 ok(PSFactoryBuffer.RefCount == facbuf_refs, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs); 997 NdrCStdStubBuffer_Release(pstub, (IPSFactoryBuffer*)pretend_psfacbuf); 998 ok(release_test_psfacbuf_release_called == 1, "pretend_psfacbuf_release called %d\n", release_test_psfacbuf_release_called); 999 ok(PSFactoryBuffer.RefCount == facbuf_refs, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs); 1000 } 1001 1002 static HRESULT WINAPI delegating_invoke_test_QI(ITypeLib *pUnk, REFIID iid, void** ppv) 1003 { 1004 1005 *ppv = pUnk; 1006 return S_OK; 1007 } 1008 1009 static ULONG WINAPI delegating_invoke_test_addref(ITypeLib *pUnk) 1010 { 1011 return 1; 1012 } 1013 1014 static ULONG WINAPI delegating_invoke_test_release(ITypeLib *pUnk) 1015 { 1016 return 1; 1017 } 1018 1019 static UINT WINAPI delegating_invoke_test_get_type_info_count(ITypeLib *pUnk) 1020 { 1021 return 0xabcdef; 1022 } 1023 1024 static ITypeLibVtbl delegating_invoke_test_obj_vtbl = 1025 { 1026 delegating_invoke_test_QI, 1027 delegating_invoke_test_addref, 1028 delegating_invoke_test_release, 1029 delegating_invoke_test_get_type_info_count, 1030 NULL, 1031 NULL, 1032 NULL, 1033 NULL, 1034 NULL, 1035 NULL, 1036 NULL, 1037 NULL, 1038 NULL 1039 }; 1040 1041 static HRESULT WINAPI delegating_invoke_chan_query_interface(IRpcChannelBuffer *pchan, 1042 REFIID iid, 1043 void **ppv) 1044 { 1045 ok(0, "call to QueryInterface not expected\n"); 1046 return E_NOINTERFACE; 1047 } 1048 1049 static ULONG WINAPI delegating_invoke_chan_add_ref(IRpcChannelBuffer *pchan) 1050 { 1051 return 2; 1052 } 1053 1054 static ULONG WINAPI delegating_invoke_chan_release(IRpcChannelBuffer *pchan) 1055 { 1056 return 1; 1057 } 1058 1059 static HRESULT WINAPI delegating_invoke_chan_get_buffer(IRpcChannelBuffer *pchan, 1060 RPCOLEMESSAGE *msg, 1061 REFIID iid) 1062 { 1063 msg->Buffer = HeapAlloc(GetProcessHeap(), 0, msg->cbBuffer); 1064 return S_OK; 1065 } 1066 1067 static HRESULT WINAPI delegating_invoke_chan_send_receive(IRpcChannelBuffer *pchan, 1068 RPCOLEMESSAGE *pMessage, 1069 ULONG *pStatus) 1070 { 1071 ok(0, "call to SendReceive not expected\n"); 1072 return E_NOTIMPL; 1073 } 1074 1075 static HRESULT WINAPI delegating_invoke_chan_free_buffer(IRpcChannelBuffer *pchan, 1076 RPCOLEMESSAGE *pMessage) 1077 { 1078 ok(0, "call to FreeBuffer not expected\n"); 1079 return E_NOTIMPL; 1080 } 1081 1082 static HRESULT WINAPI delegating_invoke_chan_get_dest_ctx(IRpcChannelBuffer *pchan, 1083 DWORD *pdwDestContext, 1084 void **ppvDestContext) 1085 { 1086 *pdwDestContext = MSHCTX_LOCAL; 1087 *ppvDestContext = NULL; 1088 return S_OK; 1089 } 1090 1091 static HRESULT WINAPI delegating_invoke_chan_is_connected(IRpcChannelBuffer *pchan) 1092 { 1093 ok(0, "call to IsConnected not expected\n"); 1094 return E_NOTIMPL; 1095 } 1096 1097 static IRpcChannelBufferVtbl delegating_invoke_test_rpc_chan_vtbl = 1098 { 1099 delegating_invoke_chan_query_interface, 1100 delegating_invoke_chan_add_ref, 1101 delegating_invoke_chan_release, 1102 delegating_invoke_chan_get_buffer, 1103 delegating_invoke_chan_send_receive, 1104 delegating_invoke_chan_free_buffer, 1105 delegating_invoke_chan_get_dest_ctx, 1106 delegating_invoke_chan_is_connected 1107 }; 1108 1109 static void test_delegating_Invoke(IPSFactoryBuffer *ppsf) 1110 { 1111 ITypeLibVtbl *obj_vtbl = &delegating_invoke_test_obj_vtbl; 1112 IUnknown *obj = (IUnknown*)&obj_vtbl; 1113 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if2, obj, S_OK); 1114 IRpcChannelBufferVtbl *pchan_vtbl = &delegating_invoke_test_rpc_chan_vtbl; 1115 IRpcChannelBuffer *pchan = (IRpcChannelBuffer *)&pchan_vtbl; 1116 HRESULT r = E_FAIL; 1117 RPCOLEMESSAGE msg; 1118 1119 memset(&msg, 0, sizeof(msg)); 1120 msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION; 1121 msg.iMethod = 3; 1122 r = IRpcStubBuffer_Invoke(pstub, &msg, pchan); 1123 ok(r == S_OK, "ret %08x\n", r); 1124 if(r == S_OK) 1125 { 1126 ok(*(DWORD*)msg.Buffer == 0xabcdef, "buf[0] %08x\n", *(DWORD*)msg.Buffer); 1127 ok(*((DWORD*)msg.Buffer + 1) == S_OK, "buf[1] %08x\n", *((DWORD*)msg.Buffer + 1)); 1128 } 1129 /* free the buffer allocated by delegating_invoke_chan_get_buffer */ 1130 HeapFree(GetProcessHeap(), 0, msg.Buffer); 1131 IRpcStubBuffer_Release(pstub); 1132 } 1133 static const CInterfaceProxyVtbl *cstub_ProxyVtblList2[] = 1134 { 1135 NULL 1136 }; 1137 1138 static const CInterfaceStubVtbl *cstub_StubVtblList2[] = 1139 { 1140 NULL 1141 }; 1142 1143 static PCInterfaceName const if_name_list2[] = 1144 { 1145 NULL 1146 }; 1147 1148 static const IID *base_iid_list2[] = 1149 { 1150 NULL, 1151 }; 1152 1153 static const ExtendedProxyFileInfo my_proxy_file_info2 = 1154 { 1155 (const PCInterfaceProxyVtblList *) &cstub_ProxyVtblList2, 1156 (const PCInterfaceStubVtblList *) &cstub_StubVtblList2, 1157 (const PCInterfaceName *) &if_name_list2, 1158 (const IID **) &base_iid_list2, 1159 &iid_lookup, 1160 0, 1161 1, 1162 NULL, 1163 0, 1164 0, 1165 0 1166 }; 1167 1168 static const ProxyFileInfo *proxy_file_list2[] = { 1169 &my_proxy_file_info2, 1170 NULL 1171 }; 1172 1173 static void test_NdrDllRegisterProxy( void ) 1174 { 1175 HRESULT res; 1176 const ExtendedProxyFileInfo *pf; 1177 HMODULE hmod = GetModuleHandleA(NULL); 1178 1179 1180 res = NdrDllRegisterProxy(NULL, NULL, NULL); 1181 ok(res == E_HANDLE, "Incorrect return code %x\n",res); 1182 pf = NULL; 1183 res = NdrDllRegisterProxy(hmod, &pf, NULL); 1184 ok(res == E_NOINTERFACE, "Incorrect return code %x\n",res); 1185 res = NdrDllRegisterProxy(hmod, proxy_file_list2, NULL); 1186 ok(res == E_NOINTERFACE, "Incorrect return code %x\n",res); 1187 /* This fails on Vista and Windows 7 due to permissions */ 1188 res = NdrDllRegisterProxy(hmod, proxy_file_list, NULL); 1189 ok(res == S_OK || res == E_ACCESSDENIED, "NdrDllRegisterProxy failed %x\n",res); 1190 if (res == S_OK) 1191 { 1192 res = NdrDllUnregisterProxy(hmod,proxy_file_list, NULL); 1193 ok(res == S_OK, "NdrDllUnregisterProxy failed %x\n",res); 1194 } 1195 } 1196 1197 START_TEST( cstub ) 1198 { 1199 IPSFactoryBuffer *ppsf; 1200 1201 OleInitialize(NULL); 1202 1203 ppsf = test_NdrDllGetClassObject(); 1204 test_NdrStubForwardingFunction(); 1205 test_CreateProxy(ppsf); 1206 test_CreateStub(ppsf); 1207 test_Connect(ppsf); 1208 test_Disconnect(ppsf); 1209 test_Release(ppsf); 1210 test_delegating_Invoke(ppsf); 1211 test_NdrDllRegisterProxy(); 1212 1213 OleUninitialize(); 1214 } 1215