1 /* 2 * COM stub (CStdStubBuffer) implementation 3 * 4 * Copyright 2001 Ove Kåven, TransGaming Technologies 5 * Copyright 2009 Alexandre Julliard 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "precomp.h" 23 24 WINE_DEFAULT_DEBUG_CHANNEL(ole); 25 26 #define STUB_HEADER(This) (((const CInterfaceStubHeader*)((This)->lpVtbl))[-1]) 27 28 static LONG WINAPI stub_filter(EXCEPTION_POINTERS *eptr) 29 { 30 if (eptr->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) 31 return EXCEPTION_CONTINUE_SEARCH; 32 return EXCEPTION_EXECUTE_HANDLER; 33 } 34 35 typedef struct 36 { 37 IUnknownVtbl *base_obj; 38 IRpcStubBuffer *base_stub; 39 CStdStubBuffer stub_buffer; 40 } cstdstubbuffer_delegating_t; 41 42 static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer *iface ) 43 { 44 return CONTAINING_RECORD(iface, cstdstubbuffer_delegating_t, stub_buffer); 45 } 46 47 HRESULT CStdStubBuffer_Construct(REFIID riid, 48 LPUNKNOWN pUnkServer, 49 PCInterfaceName name, 50 CInterfaceStubVtbl *vtbl, 51 LPPSFACTORYBUFFER pPSFactory, 52 LPRPCSTUBBUFFER *ppStub) 53 { 54 CStdStubBuffer *This; 55 IUnknown *pvServer; 56 HRESULT r; 57 TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); 58 TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); 59 TRACE("vtbl=%p\n", &vtbl->Vtbl); 60 61 if (!IsEqualGUID(vtbl->header.piid, riid)) { 62 ERR("IID mismatch during stub creation\n"); 63 return RPC_E_UNEXPECTED; 64 } 65 66 r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); 67 if(FAILED(r)) 68 return r; 69 70 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdStubBuffer)); 71 if (!This) { 72 IUnknown_Release(pvServer); 73 return E_OUTOFMEMORY; 74 } 75 76 This->lpVtbl = &vtbl->Vtbl; 77 This->RefCount = 1; 78 This->pvServerObject = pvServer; 79 This->pPSFactory = pPSFactory; 80 *ppStub = (LPRPCSTUBBUFFER)This; 81 82 IPSFactoryBuffer_AddRef(pPSFactory); 83 return S_OK; 84 } 85 86 static CRITICAL_SECTION delegating_vtbl_section; 87 static CRITICAL_SECTION_DEBUG critsect_debug = 88 { 89 0, 0, &delegating_vtbl_section, 90 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, 91 0, 0, { (DWORD_PTR)(__FILE__ ": delegating_vtbl_section") } 92 }; 93 static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0, 0 }; 94 95 typedef struct 96 { 97 DWORD ref; 98 DWORD size; 99 IUnknownVtbl vtbl; 100 /* remaining entries in vtbl */ 101 } ref_counted_vtbl; 102 103 static ref_counted_vtbl *current_vtbl; 104 105 106 static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv) 107 { 108 *ppv = pUnk; 109 return S_OK; 110 } 111 112 static ULONG WINAPI delegating_AddRef(IUnknown *pUnk) 113 { 114 return 1; 115 } 116 117 static ULONG WINAPI delegating_Release(IUnknown *pUnk) 118 { 119 return 1; 120 } 121 122 /* The idea here is to replace the first param on the stack 123 ie. This (which will point to cstdstubbuffer_delegating_t) 124 with This->stub_buffer.pvServerObject and then jump to the 125 relevant offset in This->stub_buffer.pvServerObject's vtbl. 126 */ 127 #ifdef __i386__ 128 129 #include "pshpack1.h" 130 typedef struct { 131 BYTE mov1[4]; /* mov 0x4(%esp),%eax 8b 44 24 04 */ 132 BYTE mov2[3]; /* mov 0x10(%eax),%eax 8b 40 10 */ 133 BYTE mov3[4]; /* mov %eax,0x4(%esp) 89 44 24 04 */ 134 BYTE mov4[2]; /* mov (%eax),%eax 8b 00 */ 135 BYTE mov5[2]; /* jmp *offset(%eax) ff a0 offset */ 136 DWORD offset; 137 BYTE pad[1]; /* nop 90 */ 138 } vtbl_method_t; 139 #include "poppack.h" 140 141 static const BYTE opcodes[20] = { 0x8b, 0x44, 0x24, 0x04, 0x8b, 0x40, 0x10, 0x89, 0x44, 0x24, 0x04, 142 0x8b, 0x00, 0xff, 0xa0, 0, 0, 0, 0, 0x90 }; 143 144 #elif defined(__x86_64__) 145 146 #include "pshpack1.h" 147 typedef struct 148 { 149 BYTE mov1[4]; /* movq 0x20(%rcx),%rcx 48 8b 49 20 */ 150 BYTE mov2[3]; /* movq (%rcx),%rax 48 8b 01 */ 151 BYTE jmp[2]; /* jmp *offset(%rax) ff a0 offset */ 152 DWORD offset; 153 BYTE pad[3]; /* lea 0x0(%rsi),%rsi 48 8d 36 */ 154 } vtbl_method_t; 155 #include "poppack.h" 156 157 static const BYTE opcodes[16] = { 0x48, 0x8b, 0x49, 0x20, 0x48, 0x8b, 0x01, 158 0xff, 0xa0, 0, 0, 0, 0, 0x48, 0x8d, 0x36 }; 159 #elif defined(__arm__) 160 typedef struct 161 { 162 DWORD offset; 163 } vtbl_method_t; 164 static const BYTE opcodes[1]; 165 166 #else 167 168 #warning You must implement delegated proxies/stubs for your CPU 169 typedef struct 170 { 171 DWORD offset; 172 } vtbl_method_t; 173 static const BYTE opcodes[1]; 174 175 #endif 176 177 #define BLOCK_SIZE 1024 178 #define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ 179 180 static const vtbl_method_t *method_blocks[MAX_BLOCKS]; 181 182 static const vtbl_method_t *allocate_block( unsigned int num ) 183 { 184 unsigned int i; 185 vtbl_method_t *prev, *block; 186 DWORD oldprot; 187 188 block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), 189 MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); 190 if (!block) return NULL; 191 192 for (i = 0; i < BLOCK_SIZE; i++) 193 { 194 memcpy( &block[i], opcodes, sizeof(opcodes) ); 195 block[i].offset = (BLOCK_SIZE * num + i + 3) * sizeof(void *); 196 } 197 VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, &oldprot ); 198 prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); 199 if (prev) /* someone beat us to it */ 200 { 201 VirtualFree( block, 0, MEM_RELEASE ); 202 block = prev; 203 } 204 return block; 205 } 206 207 static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) 208 { 209 const void **entry = (const void **)(vtbl + 1); 210 DWORD i, j; 211 212 if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) 213 { 214 FIXME( "%u methods not supported\n", num ); 215 return FALSE; 216 } 217 vtbl->QueryInterface = delegating_QueryInterface; 218 vtbl->AddRef = delegating_AddRef; 219 vtbl->Release = delegating_Release; 220 for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) 221 { 222 const vtbl_method_t *block = method_blocks[i]; 223 if (!block && !(block = allocate_block( i ))) return FALSE; 224 for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++) *entry++ = &block[j]; 225 } 226 return TRUE; 227 } 228 229 BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) 230 { 231 const void **entry = (const void **)(vtbl + 1); 232 DWORD i, j; 233 234 if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) 235 { 236 FIXME( "%u methods not supported\n", num ); 237 return FALSE; 238 } 239 vtbl->QueryInterface = IUnknown_QueryInterface_Proxy; 240 vtbl->AddRef = IUnknown_AddRef_Proxy; 241 vtbl->Release = IUnknown_Release_Proxy; 242 for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) 243 { 244 const vtbl_method_t *block = method_blocks[i]; 245 if (!block && !(block = allocate_block( i ))) return FALSE; 246 for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) 247 if (!*entry) *entry = &block[j]; 248 } 249 return TRUE; 250 } 251 252 static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods) 253 { 254 IUnknownVtbl *ret; 255 256 if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */ 257 258 EnterCriticalSection(&delegating_vtbl_section); 259 260 if(!current_vtbl || num_methods > current_vtbl->size) 261 { 262 ref_counted_vtbl *table = HeapAlloc(GetProcessHeap(), 0, 263 FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); 264 if (!table) 265 { 266 LeaveCriticalSection(&delegating_vtbl_section); 267 return NULL; 268 } 269 270 table->ref = 0; 271 table->size = num_methods; 272 fill_delegated_stub_table(&table->vtbl, num_methods); 273 274 if (current_vtbl && current_vtbl->ref == 0) 275 { 276 TRACE("freeing old table\n"); 277 HeapFree(GetProcessHeap(), 0, current_vtbl); 278 } 279 current_vtbl = table; 280 } 281 282 current_vtbl->ref++; 283 ret = ¤t_vtbl->vtbl; 284 LeaveCriticalSection(&delegating_vtbl_section); 285 return ret; 286 } 287 288 static void release_delegating_vtbl(IUnknownVtbl *vtbl) 289 { 290 ref_counted_vtbl *table = (ref_counted_vtbl*)((DWORD *)vtbl - 1); 291 292 EnterCriticalSection(&delegating_vtbl_section); 293 table->ref--; 294 TRACE("ref now %d\n", table->ref); 295 if(table->ref == 0 && table != current_vtbl) 296 { 297 TRACE("... and we're not current so free'ing\n"); 298 HeapFree(GetProcessHeap(), 0, table); 299 } 300 LeaveCriticalSection(&delegating_vtbl_section); 301 } 302 303 HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, 304 LPUNKNOWN pUnkServer, 305 PCInterfaceName name, 306 CInterfaceStubVtbl *vtbl, 307 REFIID delegating_iid, 308 LPPSFACTORYBUFFER pPSFactory, 309 LPRPCSTUBBUFFER *ppStub) 310 { 311 cstdstubbuffer_delegating_t *This; 312 IUnknown *pvServer; 313 HRESULT r; 314 315 TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); 316 TRACE("iid=%s delegating to %s\n", debugstr_guid(vtbl->header.piid), debugstr_guid(delegating_iid)); 317 TRACE("vtbl=%p\n", &vtbl->Vtbl); 318 319 if (!IsEqualGUID(vtbl->header.piid, riid)) 320 { 321 ERR("IID mismatch during stub creation\n"); 322 return RPC_E_UNEXPECTED; 323 } 324 325 r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); 326 if(FAILED(r)) return r; 327 328 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); 329 if (!This) 330 { 331 IUnknown_Release(pvServer); 332 return E_OUTOFMEMORY; 333 } 334 335 This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount ); 336 r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub); 337 if(FAILED(r)) 338 { 339 release_delegating_vtbl(This->base_obj); 340 HeapFree(GetProcessHeap(), 0, This); 341 IUnknown_Release(pvServer); 342 return r; 343 } 344 345 This->stub_buffer.lpVtbl = &vtbl->Vtbl; 346 This->stub_buffer.RefCount = 1; 347 This->stub_buffer.pvServerObject = pvServer; 348 This->stub_buffer.pPSFactory = pPSFactory; 349 *ppStub = (LPRPCSTUBBUFFER)&This->stub_buffer; 350 351 IPSFactoryBuffer_AddRef(pPSFactory); 352 return S_OK; 353 } 354 355 HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface, 356 REFIID riid, 357 LPVOID *obj) 358 { 359 CStdStubBuffer *This = (CStdStubBuffer *)iface; 360 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); 361 362 if (IsEqualIID(&IID_IUnknown, riid) || 363 IsEqualIID(&IID_IRpcStubBuffer, riid)) 364 { 365 IRpcStubBuffer_AddRef(iface); 366 *obj = iface; 367 return S_OK; 368 } 369 *obj = NULL; 370 return E_NOINTERFACE; 371 } 372 373 ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface) 374 { 375 CStdStubBuffer *This = (CStdStubBuffer *)iface; 376 TRACE("(%p)->AddRef()\n",This); 377 return InterlockedIncrement(&This->RefCount); 378 } 379 380 ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface, 381 LPPSFACTORYBUFFER pPSF) 382 { 383 CStdStubBuffer *This = (CStdStubBuffer *)iface; 384 ULONG refs; 385 386 TRACE("(%p)->Release()\n",This); 387 388 refs = InterlockedDecrement(&This->RefCount); 389 if (!refs) 390 { 391 /* test_Release shows that native doesn't call Disconnect here. 392 We'll leave it in for the time being. */ 393 IRpcStubBuffer_Disconnect(iface); 394 395 IPSFactoryBuffer_Release(pPSF); 396 HeapFree(GetProcessHeap(),0,This); 397 } 398 return refs; 399 } 400 401 ULONG WINAPI NdrCStdStubBuffer2_Release(LPRPCSTUBBUFFER iface, 402 LPPSFACTORYBUFFER pPSF) 403 { 404 cstdstubbuffer_delegating_t *This = impl_from_delegating( iface ); 405 ULONG refs; 406 407 TRACE("(%p)->Release()\n", This); 408 409 refs = InterlockedDecrement(&This->stub_buffer.RefCount); 410 if (!refs) 411 { 412 /* Just like NdrCStdStubBuffer_Release, we shouldn't call 413 Disconnect here */ 414 IRpcStubBuffer_Disconnect((IRpcStubBuffer *)&This->stub_buffer); 415 416 IRpcStubBuffer_Release(This->base_stub); 417 release_delegating_vtbl(This->base_obj); 418 419 IPSFactoryBuffer_Release(pPSF); 420 HeapFree(GetProcessHeap(), 0, This); 421 } 422 423 return refs; 424 } 425 426 HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface, 427 LPUNKNOWN lpUnkServer) 428 { 429 CStdStubBuffer *This = (CStdStubBuffer *)iface; 430 HRESULT r; 431 IUnknown *new = NULL; 432 433 TRACE("(%p)->Connect(%p)\n",This,lpUnkServer); 434 435 r = IUnknown_QueryInterface(lpUnkServer, STUB_HEADER(This).piid, (void**)&new); 436 new = InterlockedExchangePointer((void**)&This->pvServerObject, new); 437 if(new) 438 IUnknown_Release(new); 439 return r; 440 } 441 442 void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface) 443 { 444 CStdStubBuffer *This = (CStdStubBuffer *)iface; 445 IUnknown *old; 446 TRACE("(%p)->Disconnect()\n",This); 447 448 old = InterlockedExchangePointer((void**)&This->pvServerObject, NULL); 449 450 if(old) 451 IUnknown_Release(old); 452 } 453 454 HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface, 455 PRPCOLEMESSAGE pMsg, 456 LPRPCCHANNELBUFFER pChannel) 457 { 458 CStdStubBuffer *This = (CStdStubBuffer *)iface; 459 DWORD dwPhase = STUB_UNMARSHAL; 460 HRESULT hr = S_OK; 461 462 TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel); 463 464 __TRY 465 { 466 if (STUB_HEADER(This).pDispatchTable) 467 STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); 468 else /* pure interpreted */ 469 NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); 470 } 471 __EXCEPT(stub_filter) 472 { 473 DWORD dwExceptionCode = GetExceptionCode(); 474 WARN("a stub call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode); 475 if (FAILED(dwExceptionCode)) 476 hr = dwExceptionCode; 477 else 478 hr = HRESULT_FROM_WIN32(dwExceptionCode); 479 } 480 __ENDTRY 481 482 return hr; 483 } 484 485 LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface, 486 REFIID riid) 487 { 488 CStdStubBuffer *This = (CStdStubBuffer *)iface; 489 TRACE("(%p)->IsIIDSupported(%s)\n",This,debugstr_guid(riid)); 490 return IsEqualGUID(STUB_HEADER(This).piid, riid) ? iface : NULL; 491 } 492 493 ULONG WINAPI CStdStubBuffer_CountRefs(LPRPCSTUBBUFFER iface) 494 { 495 CStdStubBuffer *This = (CStdStubBuffer *)iface; 496 TRACE("(%p)->CountRefs()\n",This); 497 return This->RefCount; 498 } 499 500 HRESULT WINAPI CStdStubBuffer_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, 501 LPVOID *ppv) 502 { 503 CStdStubBuffer *This = (CStdStubBuffer *)iface; 504 TRACE("(%p)->DebugServerQueryInterface(%p)\n",This,ppv); 505 return S_OK; 506 } 507 508 void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface, 509 LPVOID pv) 510 { 511 CStdStubBuffer *This = (CStdStubBuffer *)iface; 512 TRACE("(%p)->DebugServerRelease(%p)\n",This,pv); 513 } 514 515 const IRpcStubBufferVtbl CStdStubBuffer_Vtbl = 516 { 517 CStdStubBuffer_QueryInterface, 518 CStdStubBuffer_AddRef, 519 NULL, 520 CStdStubBuffer_Connect, 521 CStdStubBuffer_Disconnect, 522 CStdStubBuffer_Invoke, 523 CStdStubBuffer_IsIIDSupported, 524 CStdStubBuffer_CountRefs, 525 CStdStubBuffer_DebugServerQueryInterface, 526 CStdStubBuffer_DebugServerRelease 527 }; 528 529 static HRESULT WINAPI CStdStubBuffer_Delegating_Connect(LPRPCSTUBBUFFER iface, 530 LPUNKNOWN lpUnkServer) 531 { 532 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 533 HRESULT r; 534 TRACE("(%p)->Connect(%p)\n", This, lpUnkServer); 535 536 r = CStdStubBuffer_Connect(iface, lpUnkServer); 537 if(SUCCEEDED(r)) 538 r = IRpcStubBuffer_Connect(This->base_stub, (IUnknown*)&This->base_obj); 539 540 return r; 541 } 542 543 static void WINAPI CStdStubBuffer_Delegating_Disconnect(LPRPCSTUBBUFFER iface) 544 { 545 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 546 TRACE("(%p)->Disconnect()\n", This); 547 548 IRpcStubBuffer_Disconnect(This->base_stub); 549 CStdStubBuffer_Disconnect(iface); 550 } 551 552 static ULONG WINAPI CStdStubBuffer_Delegating_CountRefs(LPRPCSTUBBUFFER iface) 553 { 554 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 555 ULONG ret; 556 TRACE("(%p)->CountRefs()\n", This); 557 558 ret = CStdStubBuffer_CountRefs(iface); 559 ret += IRpcStubBuffer_CountRefs(This->base_stub); 560 561 return ret; 562 } 563 564 const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl = 565 { 566 CStdStubBuffer_QueryInterface, 567 CStdStubBuffer_AddRef, 568 NULL, 569 CStdStubBuffer_Delegating_Connect, 570 CStdStubBuffer_Delegating_Disconnect, 571 CStdStubBuffer_Invoke, 572 CStdStubBuffer_IsIIDSupported, 573 CStdStubBuffer_Delegating_CountRefs, 574 CStdStubBuffer_DebugServerQueryInterface, 575 CStdStubBuffer_DebugServerRelease 576 }; 577 578 const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface) 579 { 580 CStdStubBuffer *This = (CStdStubBuffer *)iface; 581 return STUB_HEADER(This).pServerInfo; 582 } 583 584 /************************************************************************ 585 * NdrStubForwardingFunction [RPCRT4.@] 586 */ 587 void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *iface, IRpcChannelBuffer *pChannel, 588 PRPC_MESSAGE pMsg, DWORD *pdwStubPhase ) 589 { 590 /* Note pMsg is passed intact since RPCOLEMESSAGE is basically a RPC_MESSAGE. */ 591 592 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 593 HRESULT r = IRpcStubBuffer_Invoke(This->base_stub, (RPCOLEMESSAGE*)pMsg, pChannel); 594 if(FAILED(r)) RpcRaiseException(r); 595 return; 596 } 597 598 /*********************************************************************** 599 * NdrStubInitialize [RPCRT4.@] 600 */ 601 void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg, 602 PMIDL_STUB_MESSAGE pStubMsg, 603 PMIDL_STUB_DESC pStubDescriptor, 604 LPRPCCHANNELBUFFER pRpcChannelBuffer) 605 { 606 TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer); 607 NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor); 608 pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; 609 IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, 610 &pStubMsg->dwDestContext, 611 &pStubMsg->pvDestContext); 612 } 613 614 /*********************************************************************** 615 * NdrStubGetBuffer [RPCRT4.@] 616 */ 617 void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface, 618 LPRPCCHANNELBUFFER pRpcChannelBuffer, 619 PMIDL_STUB_MESSAGE pStubMsg) 620 { 621 CStdStubBuffer *This = (CStdStubBuffer *)iface; 622 HRESULT hr; 623 624 TRACE("(%p, %p, %p)\n", This, pRpcChannelBuffer, pStubMsg); 625 626 pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; 627 hr = IRpcChannelBuffer_GetBuffer(pRpcChannelBuffer, 628 (RPCOLEMESSAGE *)pStubMsg->RpcMsg, STUB_HEADER(This).piid); 629 if (FAILED(hr)) 630 { 631 RpcRaiseException(hr); 632 return; 633 } 634 635 pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer; 636 } 637