winewayland.drv: Update desktop window size on display changes.
[wine.git] / dlls / rpcrt4 / cstub.c
blob0f5bd0eda9fff5ac47968d01bcabb60de9a936f0
1 /*
2 * COM stub (CStdStubBuffer) implementation
4 * Copyright 2001 Ove Kåven, TransGaming Technologies
5 * Copyright 2009 Alexandre Julliard
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.
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.
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
22 #include <stdarg.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "excpt.h"
31 #include "objbase.h"
32 #include "rpcproxy.h"
34 #include "wine/debug.h"
35 #include "wine/exception.h"
37 #include "cpsf.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ole);
41 static LONG WINAPI stub_filter(EXCEPTION_POINTERS *eptr)
43 if (eptr->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
44 return EXCEPTION_CONTINUE_SEARCH;
45 return EXCEPTION_EXECUTE_HANDLER;
48 static CStdStubBuffer *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface)
50 return CONTAINING_RECORD(&iface->lpVtbl, CStdStubBuffer, lpVtbl);
53 static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer *iface )
55 return CONTAINING_RECORD(impl_from_IRpcStubBuffer(iface), cstdstubbuffer_delegating_t, stub_buffer);
58 static const CInterfaceStubHeader *get_stub_header(const CStdStubBuffer *stub)
60 const CInterfaceStubVtbl *vtbl = CONTAINING_RECORD(stub->lpVtbl, CInterfaceStubVtbl, Vtbl);
62 return &vtbl->header;
65 HRESULT CStdStubBuffer_Construct(REFIID riid,
66 LPUNKNOWN pUnkServer,
67 PCInterfaceName name,
68 CInterfaceStubVtbl *vtbl,
69 LPPSFACTORYBUFFER pPSFactory,
70 LPRPCSTUBBUFFER *ppStub)
72 CStdStubBuffer *This;
73 IUnknown *pvServer;
74 HRESULT r;
75 TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name);
76 TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid));
77 TRACE("vtbl=%p\n", &vtbl->Vtbl);
79 if (!IsEqualGUID(vtbl->header.piid, riid)) {
80 ERR("IID mismatch during stub creation\n");
81 return RPC_E_UNEXPECTED;
84 r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer);
85 if(FAILED(r))
86 return r;
88 This = calloc(1, sizeof(CStdStubBuffer));
89 if (!This) {
90 IUnknown_Release(pvServer);
91 return E_OUTOFMEMORY;
94 This->lpVtbl = &vtbl->Vtbl;
95 This->RefCount = 1;
96 This->pvServerObject = pvServer;
97 This->pPSFactory = pPSFactory;
98 *ppStub = (LPRPCSTUBBUFFER)This;
100 IPSFactoryBuffer_AddRef(pPSFactory);
101 return S_OK;
104 static CRITICAL_SECTION delegating_vtbl_section;
105 static CRITICAL_SECTION_DEBUG critsect_debug =
107 0, 0, &delegating_vtbl_section,
108 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
109 0, 0, { (DWORD_PTR)(__FILE__ ": delegating_vtbl_section") }
111 static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0, 0 };
113 struct delegating_vtbl
115 DWORD ref;
116 DWORD size;
117 IUnknownVtbl vtbl;
118 const void *methods[];
121 static struct delegating_vtbl *current_vtbl;
124 static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv)
126 *ppv = pUnk;
127 return S_OK;
130 static ULONG WINAPI delegating_AddRef(IUnknown *pUnk)
132 return 1;
135 static ULONG WINAPI delegating_Release(IUnknown *pUnk)
137 return 1;
140 /* The idea here is to replace the first param on the stack
141 ie. This (which will point to cstdstubbuffer_delegating_t)
142 with This->stub_buffer.pvServerObject and then jump to the
143 relevant offset in This->stub_buffer.pvServerObject's vtbl.
145 #ifdef __i386__
147 #include "pshpack1.h"
148 typedef struct {
149 BYTE mov1[4]; /* mov 0x4(%esp),%eax 8b 44 24 04 */
150 BYTE mov2[3]; /* mov 0x10(%eax),%eax 8b 40 10 */
151 BYTE mov3[4]; /* mov %eax,0x4(%esp) 89 44 24 04 */
152 BYTE mov4[2]; /* mov (%eax),%eax 8b 00 */
153 BYTE mov5[2]; /* jmp *offset(%eax) ff a0 offset */
154 DWORD offset;
155 BYTE pad[1]; /* nop 90 */
156 } vtbl_method_t;
157 #include "poppack.h"
159 static const BYTE opcodes[20] = { 0x8b, 0x44, 0x24, 0x04, 0x8b, 0x40, 0x10, 0x89, 0x44, 0x24, 0x04,
160 0x8b, 0x00, 0xff, 0xa0, 0, 0, 0, 0, 0x90 };
162 #elif defined(__x86_64__)
164 #include "pshpack1.h"
165 typedef struct
167 BYTE mov1[4]; /* movq 0x20(%rcx),%rcx 48 8b 49 20 */
168 BYTE mov2[3]; /* movq (%rcx),%rax 48 8b 01 */
169 BYTE jmp[2]; /* jmp *offset(%rax) ff a0 offset */
170 DWORD offset;
171 BYTE pad[3]; /* lea 0x0(%rsi),%rsi 48 8d 36 */
172 } vtbl_method_t;
173 #include "poppack.h"
175 static const BYTE opcodes[16] = { 0x48, 0x8b, 0x49, 0x20, 0x48, 0x8b, 0x01,
176 0xff, 0xa0, 0, 0, 0, 0, 0x48, 0x8d, 0x36 };
177 #elif defined(__arm__)
179 static const DWORD opcodes[] =
181 0xe52d4004, /* push {r4} */
182 0xe5900010, /* ldr r0, [r0, #16] */
183 0xe5904000, /* ldr r4, [r0] */
184 0xe59fc008, /* ldr ip, [pc, #8] */
185 0xe08cc004, /* add ip, ip, r4 */
186 0xe49d4004, /* pop {r4} */
187 0xe59cf000 /* ldr pc, [ip] */
190 typedef struct
192 DWORD opcodes[ARRAY_SIZE(opcodes)];
193 DWORD offset;
194 } vtbl_method_t;
196 #elif defined(__aarch64__)
198 static const DWORD opcodes[] =
200 0xf9401000, /* ldr x0, [x0,#32] */
201 0xf9400010, /* ldr x16, [x0] */
202 0x18000071, /* ldr w17, offset */
203 0xf8716a10, /* ldr x16, [x16,x17] */
204 0xd61f0200 /* br x16 */
207 typedef struct
209 DWORD opcodes[ARRAY_SIZE(opcodes)];
210 DWORD offset;
211 } vtbl_method_t;
213 #else
215 #warning You must implement delegated proxies/stubs for your CPU
216 typedef struct
218 DWORD offset;
219 } vtbl_method_t;
220 static const BYTE opcodes[1];
222 #endif
224 #define BLOCK_SIZE 1024
225 #define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */
227 static const vtbl_method_t *method_blocks[MAX_BLOCKS];
229 static const vtbl_method_t *allocate_block( unsigned int num )
231 unsigned int i;
232 vtbl_method_t *prev, *block;
233 DWORD oldprot;
235 block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block),
236 MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
237 if (!block) return NULL;
239 for (i = 0; i < BLOCK_SIZE; i++)
241 memcpy( &block[i], opcodes, sizeof(opcodes) );
242 block[i].offset = (BLOCK_SIZE * num + i + 3) * sizeof(void *);
244 VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, &oldprot );
245 prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL );
246 if (prev) /* someone beat us to it */
248 VirtualFree( block, 0, MEM_RELEASE );
249 block = prev;
251 return block;
254 static BOOL init_delegating_vtbl(struct delegating_vtbl *table, DWORD num)
256 DWORD i, j;
258 table->ref = 0;
259 table->size = num;
261 if (num - 3 > BLOCK_SIZE * MAX_BLOCKS)
263 FIXME( "%lu methods not supported\n", num );
264 return FALSE;
266 table->vtbl.QueryInterface = delegating_QueryInterface;
267 table->vtbl.AddRef = delegating_AddRef;
268 table->vtbl.Release = delegating_Release;
269 for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++)
271 const vtbl_method_t *block = method_blocks[i];
272 if (!block && !(block = allocate_block( i ))) return FALSE;
273 for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++)
274 table->methods[j] = &block[j];
276 return TRUE;
279 BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num)
281 const void **entry = (const void **)(vtbl + 1);
282 DWORD i, j;
284 if (num - 3 > BLOCK_SIZE * MAX_BLOCKS)
286 FIXME( "%lu methods not supported\n", num );
287 return FALSE;
289 vtbl->QueryInterface = IUnknown_QueryInterface_Proxy;
290 vtbl->AddRef = IUnknown_AddRef_Proxy;
291 vtbl->Release = IUnknown_Release_Proxy;
292 for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++)
294 const vtbl_method_t *block = method_blocks[i];
295 if (!block && !(block = allocate_block( i ))) return FALSE;
296 for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++)
297 if (!*entry) *entry = &block[j];
299 return TRUE;
302 IUnknownVtbl *get_delegating_vtbl(DWORD num_methods)
304 IUnknownVtbl *ret;
306 if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */
308 EnterCriticalSection(&delegating_vtbl_section);
310 if(!current_vtbl || num_methods > current_vtbl->size)
312 struct delegating_vtbl *table = malloc(FIELD_OFFSET(struct delegating_vtbl, methods[num_methods]));
313 if (!table)
315 LeaveCriticalSection(&delegating_vtbl_section);
316 return NULL;
319 init_delegating_vtbl(table, num_methods);
321 if (current_vtbl && current_vtbl->ref == 0)
323 TRACE("freeing old table\n");
324 free(current_vtbl);
326 current_vtbl = table;
329 current_vtbl->ref++;
330 ret = &current_vtbl->vtbl;
331 LeaveCriticalSection(&delegating_vtbl_section);
332 return ret;
335 void release_delegating_vtbl(IUnknownVtbl *vtbl)
337 struct delegating_vtbl *table = CONTAINING_RECORD(vtbl, struct delegating_vtbl, vtbl);
339 EnterCriticalSection(&delegating_vtbl_section);
340 table->ref--;
341 TRACE("ref now %ld\n", table->ref);
342 if(table->ref == 0 && table != current_vtbl)
344 TRACE("... and we're not current so free'ing\n");
345 free(table);
347 LeaveCriticalSection(&delegating_vtbl_section);
350 HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid,
351 LPUNKNOWN pUnkServer,
352 PCInterfaceName name,
353 CInterfaceStubVtbl *vtbl,
354 REFIID delegating_iid,
355 LPPSFACTORYBUFFER pPSFactory,
356 LPRPCSTUBBUFFER *ppStub)
358 cstdstubbuffer_delegating_t *This;
359 IUnknown *pvServer;
360 HRESULT r;
362 TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name);
363 TRACE("iid=%s delegating to %s\n", debugstr_guid(vtbl->header.piid), debugstr_guid(delegating_iid));
364 TRACE("vtbl=%p\n", &vtbl->Vtbl);
366 if (!IsEqualGUID(vtbl->header.piid, riid))
368 ERR("IID mismatch during stub creation\n");
369 return RPC_E_UNEXPECTED;
372 r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer);
373 if(FAILED(r)) return r;
375 This = calloc(1, sizeof(*This));
376 if (!This)
378 IUnknown_Release(pvServer);
379 return E_OUTOFMEMORY;
382 This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount );
383 r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub);
384 if(FAILED(r))
386 release_delegating_vtbl(This->base_obj);
387 free(This);
388 IUnknown_Release(pvServer);
389 return r;
392 This->stub_buffer.lpVtbl = &vtbl->Vtbl;
393 This->stub_buffer.RefCount = 1;
394 This->stub_buffer.pvServerObject = pvServer;
395 This->stub_buffer.pPSFactory = pPSFactory;
396 *ppStub = (LPRPCSTUBBUFFER)&This->stub_buffer;
398 IPSFactoryBuffer_AddRef(pPSFactory);
399 return S_OK;
402 HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface,
403 REFIID riid,
404 LPVOID *obj)
406 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
407 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
409 if (IsEqualIID(&IID_IUnknown, riid) ||
410 IsEqualIID(&IID_IRpcStubBuffer, riid))
412 IRpcStubBuffer_AddRef(iface);
413 *obj = iface;
414 return S_OK;
416 *obj = NULL;
417 return E_NOINTERFACE;
420 ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface)
422 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
423 TRACE("(%p)->AddRef()\n",This);
424 return InterlockedIncrement(&This->RefCount);
427 ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface,
428 LPPSFACTORYBUFFER pPSF)
430 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
431 ULONG refs;
433 TRACE("(%p)->Release()\n",This);
435 refs = InterlockedDecrement(&This->RefCount);
436 if (!refs)
438 /* test_Release shows that native doesn't call Disconnect here.
439 We'll leave it in for the time being. */
440 IRpcStubBuffer_Disconnect(iface);
442 IPSFactoryBuffer_Release(pPSF);
443 free(This);
445 return refs;
448 ULONG WINAPI NdrCStdStubBuffer2_Release(LPRPCSTUBBUFFER iface,
449 LPPSFACTORYBUFFER pPSF)
451 cstdstubbuffer_delegating_t *This = impl_from_delegating( iface );
452 ULONG refs;
454 TRACE("(%p)->Release()\n", This);
456 refs = InterlockedDecrement(&This->stub_buffer.RefCount);
457 if (!refs)
459 /* Just like NdrCStdStubBuffer_Release, we shouldn't call
460 Disconnect here */
461 IRpcStubBuffer_Disconnect((IRpcStubBuffer *)&This->stub_buffer);
463 IRpcStubBuffer_Release(This->base_stub);
464 release_delegating_vtbl(This->base_obj);
466 IPSFactoryBuffer_Release(pPSF);
467 free(This);
470 return refs;
473 HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface,
474 LPUNKNOWN lpUnkServer)
476 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
477 HRESULT r;
478 IUnknown *new = NULL;
480 TRACE("(%p)->Connect(%p)\n",This,lpUnkServer);
482 r = IUnknown_QueryInterface(lpUnkServer, get_stub_header(This)->piid, (void**)&new);
483 new = InterlockedExchangePointer((void**)&This->pvServerObject, new);
484 if(new)
485 IUnknown_Release(new);
486 return r;
489 void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface)
491 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
492 IUnknown *old;
493 TRACE("(%p)->Disconnect()\n",This);
495 old = InterlockedExchangePointer((void**)&This->pvServerObject, NULL);
497 if(old)
498 IUnknown_Release(old);
501 HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface,
502 PRPCOLEMESSAGE pMsg,
503 LPRPCCHANNELBUFFER pChannel)
505 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
506 const CInterfaceStubHeader *header = get_stub_header(This);
507 DWORD dwPhase = STUB_UNMARSHAL;
508 HRESULT hr = S_OK;
510 TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel);
512 __TRY
514 if (header->pDispatchTable)
515 header->pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase);
516 else /* pure interpreted */
517 NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase);
519 __EXCEPT(stub_filter)
521 DWORD dwExceptionCode = GetExceptionCode();
522 WARN("a stub call failed with exception 0x%08lx (%ld)\n", dwExceptionCode, dwExceptionCode);
523 if (FAILED(dwExceptionCode))
524 hr = dwExceptionCode;
525 else
526 hr = HRESULT_FROM_WIN32(dwExceptionCode);
528 __ENDTRY
530 return hr;
533 LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface,
534 REFIID riid)
536 CStdStubBuffer *stub = impl_from_IRpcStubBuffer(iface);
538 TRACE("(%p)->IsIIDSupported(%s)\n", stub, debugstr_guid(riid));
540 if (IsEqualGUID(get_stub_header(stub)->piid, riid))
541 return iface;
542 return NULL;
545 ULONG WINAPI CStdStubBuffer_CountRefs(LPRPCSTUBBUFFER iface)
547 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
548 TRACE("(%p)->CountRefs()\n",This);
549 return This->RefCount;
552 HRESULT WINAPI CStdStubBuffer_DebugServerQueryInterface(LPRPCSTUBBUFFER iface,
553 LPVOID *ppv)
555 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
556 TRACE("(%p)->DebugServerQueryInterface(%p)\n",This,ppv);
557 return S_OK;
560 void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface,
561 LPVOID pv)
563 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
564 TRACE("(%p)->DebugServerRelease(%p)\n",This,pv);
567 const IRpcStubBufferVtbl CStdStubBuffer_Vtbl =
569 CStdStubBuffer_QueryInterface,
570 CStdStubBuffer_AddRef,
571 NULL,
572 CStdStubBuffer_Connect,
573 CStdStubBuffer_Disconnect,
574 CStdStubBuffer_Invoke,
575 CStdStubBuffer_IsIIDSupported,
576 CStdStubBuffer_CountRefs,
577 CStdStubBuffer_DebugServerQueryInterface,
578 CStdStubBuffer_DebugServerRelease
581 static HRESULT WINAPI CStdStubBuffer_Delegating_Connect(LPRPCSTUBBUFFER iface,
582 LPUNKNOWN lpUnkServer)
584 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
585 HRESULT r;
586 TRACE("(%p)->Connect(%p)\n", This, lpUnkServer);
588 r = CStdStubBuffer_Connect(iface, lpUnkServer);
589 if(SUCCEEDED(r))
590 r = IRpcStubBuffer_Connect(This->base_stub, (IUnknown*)&This->base_obj);
592 return r;
595 static void WINAPI CStdStubBuffer_Delegating_Disconnect(LPRPCSTUBBUFFER iface)
597 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
598 TRACE("(%p)->Disconnect()\n", This);
600 IRpcStubBuffer_Disconnect(This->base_stub);
601 CStdStubBuffer_Disconnect(iface);
604 static ULONG WINAPI CStdStubBuffer_Delegating_CountRefs(LPRPCSTUBBUFFER iface)
606 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
607 ULONG ret;
608 TRACE("(%p)->CountRefs()\n", This);
610 ret = CStdStubBuffer_CountRefs(iface);
611 ret += IRpcStubBuffer_CountRefs(This->base_stub);
613 return ret;
616 const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl =
618 CStdStubBuffer_QueryInterface,
619 CStdStubBuffer_AddRef,
620 NULL,
621 CStdStubBuffer_Delegating_Connect,
622 CStdStubBuffer_Delegating_Disconnect,
623 CStdStubBuffer_Invoke,
624 CStdStubBuffer_IsIIDSupported,
625 CStdStubBuffer_Delegating_CountRefs,
626 CStdStubBuffer_DebugServerQueryInterface,
627 CStdStubBuffer_DebugServerRelease
630 const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface)
632 CStdStubBuffer *stub = impl_from_IRpcStubBuffer(iface);
634 return get_stub_header(stub)->pServerInfo;
637 /************************************************************************
638 * NdrStubForwardingFunction [RPCRT4.@]
640 void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *iface, IRpcChannelBuffer *pChannel,
641 PRPC_MESSAGE pMsg, DWORD *pdwStubPhase )
643 /* Note pMsg is passed intact since RPCOLEMESSAGE is basically a RPC_MESSAGE. */
645 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
646 HRESULT r = IRpcStubBuffer_Invoke(This->base_stub, (RPCOLEMESSAGE*)pMsg, pChannel);
647 if(FAILED(r)) RpcRaiseException(r);
648 return;
651 /***********************************************************************
652 * NdrStubInitialize [RPCRT4.@]
654 void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg,
655 PMIDL_STUB_MESSAGE pStubMsg,
656 PMIDL_STUB_DESC pStubDescriptor,
657 LPRPCCHANNELBUFFER pRpcChannelBuffer)
659 TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer);
660 NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor);
661 pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
662 IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
663 &pStubMsg->dwDestContext,
664 &pStubMsg->pvDestContext);
667 /***********************************************************************
668 * NdrStubGetBuffer [RPCRT4.@]
670 void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface,
671 LPRPCCHANNELBUFFER pRpcChannelBuffer,
672 PMIDL_STUB_MESSAGE pStubMsg)
674 CStdStubBuffer *This = impl_from_IRpcStubBuffer(iface);
675 HRESULT hr;
677 TRACE("(%p, %p, %p)\n", This, pRpcChannelBuffer, pStubMsg);
679 pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
680 hr = IRpcChannelBuffer_GetBuffer(pRpcChannelBuffer,
681 (RPCOLEMESSAGE *)pStubMsg->RpcMsg, get_stub_header(This)->piid);
682 if (FAILED(hr))
684 RpcRaiseException(hr);
685 return;
688 pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer;