ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cstub.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 = &current_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.