Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencstub.c
Go to the documentation of this file.
00001 /* 00002 * COM stub (CStdStubBuffer) implementation 00003 * 00004 * Copyright 2001 Ove Kåven, TransGaming Technologies 00005 * Copyright 2009 Alexandre Julliard 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include "config.h" 00023 #include "wine/port.h" 00024 00025 #include <stdarg.h> 00026 00027 #define COBJMACROS 00028 00029 #include "windef.h" 00030 #include "winbase.h" 00031 #include "winerror.h" 00032 #include "excpt.h" 00033 00034 #include "objbase.h" 00035 #include "rpcproxy.h" 00036 00037 #include "wine/debug.h" 00038 #include "wine/exception.h" 00039 00040 #include "cpsf.h" 00041 00042 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00043 00044 #define STUB_HEADER(This) (((const CInterfaceStubHeader*)((This)->lpVtbl))[-1]) 00045 00046 static LONG WINAPI stub_filter(EXCEPTION_POINTERS *eptr) 00047 { 00048 if (eptr->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) 00049 return EXCEPTION_CONTINUE_SEARCH; 00050 return EXCEPTION_EXECUTE_HANDLER; 00051 } 00052 00053 typedef struct 00054 { 00055 IUnknownVtbl *base_obj; 00056 IRpcStubBuffer *base_stub; 00057 CStdStubBuffer stub_buffer; 00058 } cstdstubbuffer_delegating_t; 00059 00060 static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer *iface ) 00061 { 00062 return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer)); 00063 } 00064 00065 HRESULT CStdStubBuffer_Construct(REFIID riid, 00066 LPUNKNOWN pUnkServer, 00067 PCInterfaceName name, 00068 CInterfaceStubVtbl *vtbl, 00069 LPPSFACTORYBUFFER pPSFactory, 00070 LPRPCSTUBBUFFER *ppStub) 00071 { 00072 CStdStubBuffer *This; 00073 IUnknown *pvServer; 00074 HRESULT r; 00075 TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); 00076 TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); 00077 TRACE("vtbl=%p\n", &vtbl->Vtbl); 00078 00079 if (!IsEqualGUID(vtbl->header.piid, riid)) { 00080 ERR("IID mismatch during stub creation\n"); 00081 return RPC_E_UNEXPECTED; 00082 } 00083 00084 r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); 00085 if(FAILED(r)) 00086 return r; 00087 00088 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdStubBuffer)); 00089 if (!This) { 00090 IUnknown_Release(pvServer); 00091 return E_OUTOFMEMORY; 00092 } 00093 00094 This->lpVtbl = &vtbl->Vtbl; 00095 This->RefCount = 1; 00096 This->pvServerObject = pvServer; 00097 This->pPSFactory = pPSFactory; 00098 *ppStub = (LPRPCSTUBBUFFER)This; 00099 00100 IPSFactoryBuffer_AddRef(pPSFactory); 00101 return S_OK; 00102 } 00103 00104 static CRITICAL_SECTION delegating_vtbl_section; 00105 static CRITICAL_SECTION_DEBUG critsect_debug = 00106 { 00107 0, 0, &delegating_vtbl_section, 00108 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, 00109 0, 0, { (DWORD_PTR)(__FILE__ ": delegating_vtbl_section") } 00110 }; 00111 static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0, 0 }; 00112 00113 typedef struct 00114 { 00115 DWORD ref; 00116 DWORD size; 00117 IUnknownVtbl vtbl; 00118 /* remaining entries in vtbl */ 00119 } ref_counted_vtbl; 00120 00121 static ref_counted_vtbl *current_vtbl; 00122 00123 00124 static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv) 00125 { 00126 *ppv = pUnk; 00127 return S_OK; 00128 } 00129 00130 static ULONG WINAPI delegating_AddRef(IUnknown *pUnk) 00131 { 00132 return 1; 00133 } 00134 00135 static ULONG WINAPI delegating_Release(IUnknown *pUnk) 00136 { 00137 return 1; 00138 } 00139 00140 /* The idea here is to replace the first param on the stack 00141 ie. This (which will point to cstdstubbuffer_delegating_t) 00142 with This->stub_buffer.pvServerObject and then jump to the 00143 relevant offset in This->stub_buffer.pvServerObject's vtbl. 00144 */ 00145 #ifdef __i386__ 00146 00147 #include "pshpack1.h" 00148 typedef struct { 00149 BYTE mov1[4]; /* mov 0x4(%esp),%eax 8b 44 24 04 */ 00150 BYTE mov2[3]; /* mov 0x10(%eax),%eax 8b 40 10 */ 00151 BYTE mov3[4]; /* mov %eax,0x4(%esp) 89 44 24 04 */ 00152 BYTE mov4[2]; /* mov (%eax),%eax 8b 00 */ 00153 BYTE mov5[2]; /* jmp *offset(%eax) ff a0 offset */ 00154 DWORD offset; 00155 BYTE pad[1]; /* nop 90 */ 00156 } vtbl_method_t; 00157 #include "poppack.h" 00158 00159 static const BYTE opcodes[20] = { 0x8b, 0x44, 0x24, 0x04, 0x8b, 0x40, 0x10, 0x89, 0x44, 0x24, 0x04, 00160 0x8b, 0x00, 0xff, 0xa0, 0, 0, 0, 0, 0x90 }; 00161 00162 #elif defined(__x86_64__) 00163 00164 #include "pshpack1.h" 00165 typedef struct 00166 { 00167 BYTE mov1[4]; /* movq 0x20(%rcx),%rcx 48 8b 49 20 */ 00168 BYTE mov2[3]; /* movq (%rcx),%rax 48 8b 01 */ 00169 BYTE jmp[2]; /* jmp *offset(%rax) ff a0 offset */ 00170 DWORD offset; 00171 BYTE pad[3]; /* lea 0x0(%rsi),%rsi 48 8d 36 */ 00172 } vtbl_method_t; 00173 #include "poppack.h" 00174 00175 static const BYTE opcodes[16] = { 0x48, 0x8b, 0x49, 0x20, 0x48, 0x8b, 0x01, 00176 0xff, 0xa0, 0, 0, 0, 0, 0x48, 0x8d, 0x36 }; 00177 #else 00178 00179 #warning You must implement delegated proxies/stubs for your CPU 00180 typedef struct 00181 { 00182 DWORD offset; 00183 } vtbl_method_t; 00184 static const BYTE opcodes[1]; 00185 00186 #endif 00187 00188 #define BLOCK_SIZE 1024 00189 #define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ 00190 00191 static const vtbl_method_t *method_blocks[MAX_BLOCKS]; 00192 00193 static const vtbl_method_t *allocate_block( unsigned int num ) 00194 { 00195 unsigned int i; 00196 vtbl_method_t *prev, *block; 00197 00198 block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), 00199 MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); 00200 if (!block) return NULL; 00201 00202 for (i = 0; i < BLOCK_SIZE; i++) 00203 { 00204 memcpy( &block[i], opcodes, sizeof(opcodes) ); 00205 block[i].offset = (BLOCK_SIZE * num + i + 3) * sizeof(void *); 00206 } 00207 VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL ); 00208 prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); 00209 if (prev) /* someone beat us to it */ 00210 { 00211 VirtualFree( block, 0, MEM_RELEASE ); 00212 block = prev; 00213 } 00214 return block; 00215 } 00216 00217 static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) 00218 { 00219 const void **entry = (const void **)(vtbl + 1); 00220 DWORD i, j; 00221 00222 if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) 00223 { 00224 FIXME( "%u methods not supported\n", num ); 00225 return FALSE; 00226 } 00227 vtbl->QueryInterface = delegating_QueryInterface; 00228 vtbl->AddRef = delegating_AddRef; 00229 vtbl->Release = delegating_Release; 00230 for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) 00231 { 00232 const vtbl_method_t *block = method_blocks[i]; 00233 if (!block && !(block = allocate_block( i ))) return FALSE; 00234 for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++) *entry++ = &block[j]; 00235 } 00236 return TRUE; 00237 } 00238 00239 BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) 00240 { 00241 const void **entry = (const void **)(vtbl + 1); 00242 DWORD i, j; 00243 00244 if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) 00245 { 00246 FIXME( "%u methods not supported\n", num ); 00247 return FALSE; 00248 } 00249 vtbl->QueryInterface = IUnknown_QueryInterface_Proxy; 00250 vtbl->AddRef = IUnknown_AddRef_Proxy; 00251 vtbl->Release = IUnknown_Release_Proxy; 00252 for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) 00253 { 00254 const vtbl_method_t *block = method_blocks[i]; 00255 if (!block && !(block = allocate_block( i ))) return FALSE; 00256 for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) 00257 if (!*entry) *entry = &block[j]; 00258 } 00259 return TRUE; 00260 } 00261 00262 static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods) 00263 { 00264 IUnknownVtbl *ret; 00265 00266 if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */ 00267 00268 EnterCriticalSection(&delegating_vtbl_section); 00269 00270 if(!current_vtbl || num_methods > current_vtbl->size) 00271 { 00272 ref_counted_vtbl *table = HeapAlloc(GetProcessHeap(), 0, 00273 FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); 00274 if (!table) 00275 { 00276 LeaveCriticalSection(&delegating_vtbl_section); 00277 return NULL; 00278 } 00279 00280 table->ref = 0; 00281 table->size = num_methods; 00282 fill_delegated_stub_table(&table->vtbl, num_methods); 00283 00284 if (current_vtbl && current_vtbl->ref == 0) 00285 { 00286 TRACE("freeing old table\n"); 00287 HeapFree(GetProcessHeap(), 0, current_vtbl); 00288 } 00289 current_vtbl = table; 00290 } 00291 00292 current_vtbl->ref++; 00293 ret = ¤t_vtbl->vtbl; 00294 LeaveCriticalSection(&delegating_vtbl_section); 00295 return ret; 00296 } 00297 00298 static void release_delegating_vtbl(IUnknownVtbl *vtbl) 00299 { 00300 ref_counted_vtbl *table = (ref_counted_vtbl*)((DWORD *)vtbl - 1); 00301 00302 EnterCriticalSection(&delegating_vtbl_section); 00303 table->ref--; 00304 TRACE("ref now %d\n", table->ref); 00305 if(table->ref == 0 && table != current_vtbl) 00306 { 00307 TRACE("... and we're not current so free'ing\n"); 00308 HeapFree(GetProcessHeap(), 0, table); 00309 } 00310 LeaveCriticalSection(&delegating_vtbl_section); 00311 } 00312 00313 HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, 00314 LPUNKNOWN pUnkServer, 00315 PCInterfaceName name, 00316 CInterfaceStubVtbl *vtbl, 00317 REFIID delegating_iid, 00318 LPPSFACTORYBUFFER pPSFactory, 00319 LPRPCSTUBBUFFER *ppStub) 00320 { 00321 cstdstubbuffer_delegating_t *This; 00322 IUnknown *pvServer; 00323 HRESULT r; 00324 00325 TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); 00326 TRACE("iid=%s delegating to %s\n", debugstr_guid(vtbl->header.piid), debugstr_guid(delegating_iid)); 00327 TRACE("vtbl=%p\n", &vtbl->Vtbl); 00328 00329 if (!IsEqualGUID(vtbl->header.piid, riid)) 00330 { 00331 ERR("IID mismatch during stub creation\n"); 00332 return RPC_E_UNEXPECTED; 00333 } 00334 00335 r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); 00336 if(FAILED(r)) return r; 00337 00338 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); 00339 if (!This) 00340 { 00341 IUnknown_Release(pvServer); 00342 return E_OUTOFMEMORY; 00343 } 00344 00345 This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount ); 00346 r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub); 00347 if(FAILED(r)) 00348 { 00349 release_delegating_vtbl(This->base_obj); 00350 HeapFree(GetProcessHeap(), 0, This); 00351 IUnknown_Release(pvServer); 00352 return r; 00353 } 00354 00355 This->stub_buffer.lpVtbl = &vtbl->Vtbl; 00356 This->stub_buffer.RefCount = 1; 00357 This->stub_buffer.pvServerObject = pvServer; 00358 This->stub_buffer.pPSFactory = pPSFactory; 00359 *ppStub = (LPRPCSTUBBUFFER)&This->stub_buffer; 00360 00361 IPSFactoryBuffer_AddRef(pPSFactory); 00362 return S_OK; 00363 } 00364 00365 HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface, 00366 REFIID riid, 00367 LPVOID *obj) 00368 { 00369 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00370 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); 00371 00372 if (IsEqualIID(&IID_IUnknown, riid) || 00373 IsEqualIID(&IID_IRpcStubBuffer, riid)) 00374 { 00375 IUnknown_AddRef(iface); 00376 *obj = iface; 00377 return S_OK; 00378 } 00379 *obj = NULL; 00380 return E_NOINTERFACE; 00381 } 00382 00383 ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface) 00384 { 00385 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00386 TRACE("(%p)->AddRef()\n",This); 00387 return InterlockedIncrement(&This->RefCount); 00388 } 00389 00390 ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface, 00391 LPPSFACTORYBUFFER pPSF) 00392 { 00393 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00394 ULONG refs; 00395 00396 TRACE("(%p)->Release()\n",This); 00397 00398 refs = InterlockedDecrement(&This->RefCount); 00399 if (!refs) 00400 { 00401 /* test_Release shows that native doesn't call Disconnect here. 00402 We'll leave it in for the time being. */ 00403 IRpcStubBuffer_Disconnect(iface); 00404 00405 IPSFactoryBuffer_Release(pPSF); 00406 HeapFree(GetProcessHeap(),0,This); 00407 } 00408 return refs; 00409 } 00410 00411 ULONG WINAPI NdrCStdStubBuffer2_Release(LPRPCSTUBBUFFER iface, 00412 LPPSFACTORYBUFFER pPSF) 00413 { 00414 cstdstubbuffer_delegating_t *This = impl_from_delegating( iface ); 00415 ULONG refs; 00416 00417 TRACE("(%p)->Release()\n", This); 00418 00419 refs = InterlockedDecrement(&This->stub_buffer.RefCount); 00420 if (!refs) 00421 { 00422 /* Just like NdrCStdStubBuffer_Release, we shouldn't call 00423 Disconnect here */ 00424 IRpcStubBuffer_Disconnect((IRpcStubBuffer *)&This->stub_buffer); 00425 00426 IRpcStubBuffer_Release(This->base_stub); 00427 release_delegating_vtbl(This->base_obj); 00428 00429 IPSFactoryBuffer_Release(pPSF); 00430 HeapFree(GetProcessHeap(), 0, This); 00431 } 00432 00433 return refs; 00434 } 00435 00436 HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface, 00437 LPUNKNOWN lpUnkServer) 00438 { 00439 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00440 HRESULT r; 00441 IUnknown *new = NULL; 00442 00443 TRACE("(%p)->Connect(%p)\n",This,lpUnkServer); 00444 00445 r = IUnknown_QueryInterface(lpUnkServer, STUB_HEADER(This).piid, (void**)&new); 00446 new = InterlockedExchangePointer((void**)&This->pvServerObject, new); 00447 if(new) 00448 IUnknown_Release(new); 00449 return r; 00450 } 00451 00452 void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface) 00453 { 00454 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00455 IUnknown *old; 00456 TRACE("(%p)->Disconnect()\n",This); 00457 00458 old = InterlockedExchangePointer((void**)&This->pvServerObject, NULL); 00459 00460 if(old) 00461 IUnknown_Release(old); 00462 } 00463 00464 HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface, 00465 PRPCOLEMESSAGE pMsg, 00466 LPRPCCHANNELBUFFER pChannel) 00467 { 00468 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00469 DWORD dwPhase = STUB_UNMARSHAL; 00470 HRESULT hr = S_OK; 00471 00472 TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel); 00473 00474 __TRY 00475 { 00476 if (STUB_HEADER(This).pDispatchTable) 00477 STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); 00478 else /* pure interpreted */ 00479 NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); 00480 } 00481 __EXCEPT(stub_filter) 00482 { 00483 DWORD dwExceptionCode = GetExceptionCode(); 00484 WARN("a stub call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode); 00485 if (FAILED(dwExceptionCode)) 00486 hr = dwExceptionCode; 00487 else 00488 hr = HRESULT_FROM_WIN32(dwExceptionCode); 00489 } 00490 __ENDTRY 00491 00492 return hr; 00493 } 00494 00495 LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface, 00496 REFIID riid) 00497 { 00498 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00499 TRACE("(%p)->IsIIDSupported(%s)\n",This,debugstr_guid(riid)); 00500 return IsEqualGUID(STUB_HEADER(This).piid, riid) ? iface : NULL; 00501 } 00502 00503 ULONG WINAPI CStdStubBuffer_CountRefs(LPRPCSTUBBUFFER iface) 00504 { 00505 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00506 TRACE("(%p)->CountRefs()\n",This); 00507 return This->RefCount; 00508 } 00509 00510 HRESULT WINAPI CStdStubBuffer_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, 00511 LPVOID *ppv) 00512 { 00513 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00514 TRACE("(%p)->DebugServerQueryInterface(%p)\n",This,ppv); 00515 return S_OK; 00516 } 00517 00518 void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface, 00519 LPVOID pv) 00520 { 00521 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00522 TRACE("(%p)->DebugServerRelease(%p)\n",This,pv); 00523 } 00524 00525 const IRpcStubBufferVtbl CStdStubBuffer_Vtbl = 00526 { 00527 CStdStubBuffer_QueryInterface, 00528 CStdStubBuffer_AddRef, 00529 NULL, 00530 CStdStubBuffer_Connect, 00531 CStdStubBuffer_Disconnect, 00532 CStdStubBuffer_Invoke, 00533 CStdStubBuffer_IsIIDSupported, 00534 CStdStubBuffer_CountRefs, 00535 CStdStubBuffer_DebugServerQueryInterface, 00536 CStdStubBuffer_DebugServerRelease 00537 }; 00538 00539 static HRESULT WINAPI CStdStubBuffer_Delegating_Connect(LPRPCSTUBBUFFER iface, 00540 LPUNKNOWN lpUnkServer) 00541 { 00542 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 00543 HRESULT r; 00544 TRACE("(%p)->Connect(%p)\n", This, lpUnkServer); 00545 00546 r = CStdStubBuffer_Connect(iface, lpUnkServer); 00547 if(SUCCEEDED(r)) 00548 r = IRpcStubBuffer_Connect(This->base_stub, (IUnknown*)&This->base_obj); 00549 00550 return r; 00551 } 00552 00553 static void WINAPI CStdStubBuffer_Delegating_Disconnect(LPRPCSTUBBUFFER iface) 00554 { 00555 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 00556 TRACE("(%p)->Disconnect()\n", This); 00557 00558 IRpcStubBuffer_Disconnect(This->base_stub); 00559 CStdStubBuffer_Disconnect(iface); 00560 } 00561 00562 static ULONG WINAPI CStdStubBuffer_Delegating_CountRefs(LPRPCSTUBBUFFER iface) 00563 { 00564 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 00565 ULONG ret; 00566 TRACE("(%p)->CountRefs()\n", This); 00567 00568 ret = CStdStubBuffer_CountRefs(iface); 00569 ret += IRpcStubBuffer_CountRefs(This->base_stub); 00570 00571 return ret; 00572 } 00573 00574 const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl = 00575 { 00576 CStdStubBuffer_QueryInterface, 00577 CStdStubBuffer_AddRef, 00578 NULL, 00579 CStdStubBuffer_Delegating_Connect, 00580 CStdStubBuffer_Delegating_Disconnect, 00581 CStdStubBuffer_Invoke, 00582 CStdStubBuffer_IsIIDSupported, 00583 CStdStubBuffer_Delegating_CountRefs, 00584 CStdStubBuffer_DebugServerQueryInterface, 00585 CStdStubBuffer_DebugServerRelease 00586 }; 00587 00588 const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface) 00589 { 00590 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00591 return STUB_HEADER(This).pServerInfo; 00592 } 00593 00594 /************************************************************************ 00595 * NdrStubForwardingFunction [RPCRT4.@] 00596 */ 00597 void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *iface, IRpcChannelBuffer *pChannel, 00598 PRPC_MESSAGE pMsg, DWORD *pdwStubPhase ) 00599 { 00600 /* Note pMsg is passed intact since RPCOLEMESSAGE is basically a RPC_MESSAGE. */ 00601 00602 cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); 00603 HRESULT r = IRpcStubBuffer_Invoke(This->base_stub, (RPCOLEMESSAGE*)pMsg, pChannel); 00604 if(FAILED(r)) RpcRaiseException(r); 00605 return; 00606 } 00607 00608 /*********************************************************************** 00609 * NdrStubInitialize [RPCRT4.@] 00610 */ 00611 void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg, 00612 PMIDL_STUB_MESSAGE pStubMsg, 00613 PMIDL_STUB_DESC pStubDescriptor, 00614 LPRPCCHANNELBUFFER pRpcChannelBuffer) 00615 { 00616 TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer); 00617 NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor); 00618 pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; 00619 IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, 00620 &pStubMsg->dwDestContext, 00621 &pStubMsg->pvDestContext); 00622 } 00623 00624 /*********************************************************************** 00625 * NdrStubGetBuffer [RPCRT4.@] 00626 */ 00627 void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface, 00628 LPRPCCHANNELBUFFER pRpcChannelBuffer, 00629 PMIDL_STUB_MESSAGE pStubMsg) 00630 { 00631 CStdStubBuffer *This = (CStdStubBuffer *)iface; 00632 HRESULT hr; 00633 00634 TRACE("(%p, %p, %p)\n", This, pRpcChannelBuffer, pStubMsg); 00635 00636 pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; 00637 hr = IRpcChannelBuffer_GetBuffer(pRpcChannelBuffer, 00638 (RPCOLEMESSAGE *)pStubMsg->RpcMsg, STUB_HEADER(This).piid); 00639 if (FAILED(hr)) 00640 { 00641 RpcRaiseException(hr); 00642 return; 00643 } 00644 00645 pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer; 00646 } Generated on Sat May 26 2012 04:24:34 for ReactOS by
1.7.6.1
|