|
|
/*++
Microsoft Windows Copyright (c) 1994-2000 Microsoft Corporation. All rights reserved.
Module Name: stub.c
Abstract: Implements the IRpcStubBuffer interface.
Author: ShannonC 12-Oct-1994
Environment: Windows NT and Windows 95. We do not support DOS and Win16.
Revision History:
--*/
#define USE_STUBLESS_PROXY
#define CINTERFACE
#include <ndrp.h>
#include <ndrole.h>
#include <rpcproxy.h>
#include <stddef.h>
#include "ndrtypes.h"
EXTERN_C const IID IID_IPrivStubBuffer = { /* 3e0ac23f-eff6-41f3-b44b-fbfa4544265f */ 0x3e0ac23f, 0xeff6, 0x41f3, {0xb4, 0x4b, 0xfb, 0xfa, 0x45, 0x44, 0x26, 0x5f} };
const IID * RPC_ENTRY NdrpGetStubIID( IRpcStubBuffer *This);
void MakeSureWeHaveNonPipeArgs( PMIDL_STUB_MESSAGE pStubMsg, unsigned long BufferSize );
BOOL NdrpFindInterface( IN const ProxyFileInfo ** pProxyFileList, IN REFIID riid, OUT const ProxyFileInfo ** ppProxyFileInfo, OUT long * pIndex );
extern void ReleaseTemplateForwardVtbl(void ** pVtbl);
//+-------------------------------------------------------------------------
//
// Global data
//
//--------------------------------------------------------------------------
// ICallFactory interface on the StubBuffer objects.
// ICallFactory is an interface on a sync stub only.
// It has been introduced for NT5 beta2.
extern const ICallFactoryVtbl CStdStubBuffer_CallFactoryVtbl = { CStdStubBuffer_CF_QueryInterface, CStdStubBuffer_CF_AddRef, CStdStubBuffer_CF_Release, CStdStubBuffer_CF_CreateCall };
extern const ICallFactoryVtbl CStdStubBuffer2_CallFactoryVtbl = { CStdStubBuffer_CF_QueryInterface, CStdStubBuffer_CF_AddRef, CStdStubBuffer_CF_Release, CStdStubBuffer2_CF_CreateCall };
extern const IReleaseMarshalBuffersVtbl CStdStubBuffer_ReleaseMarshalBuffersVtbl = { CStdStubBuffer_RMB_QueryInterface, CStdStubBuffer_RMB_AddRef, CStdStubBuffer_RMB_Release, CStdStubBuffer_RMB_ReleaseMarshalBuffer};
extern const IReleaseMarshalBuffersVtbl CStdAsyncStubBuffer_ReleaseMarshalBuffersVtbl = { CStdStubBuffer_RMB_QueryInterface, CStdStubBuffer_RMB_AddRef, CStdStubBuffer_RMB_Release, CStdAsyncStubBuffer_RMB_ReleaseMarshalBuffer };
extern const ISynchronizeVtbl CStdAsyncStubBuffer_ISynchronizeVtbl = { CStdAsyncStubBuffer_Synchronize_QueryInterface, CStdAsyncStubBuffer_Synchronize_AddRef, CStdAsyncStubBuffer_Synchronize_Release, CStdAsyncStubBuffer_Synchronize_Wait, CStdAsyncStubBuffer_Synchronize_Signal, CStdAsyncStubBuffer_Synchronize_Reset };
//+-------------------------------------------------------------------------
//
// End of Global data
//
//--------------------------------------------------------------------------
#pragma code_seg(".orpc")
//
// ICallFactory interface on the sync stub object.
//
HRESULT STDMETHODCALLTYPE CStdStubBuffer_CF_QueryInterface( IN ICallFactory *This, IN REFIID riid, OUT void ** ppvObject) /*++
Routine Description: Query for an interface on the interface stub CallFactory pointer.
Arguments: riid - Supplies the IID of the interface being requested. ppvObject - Returns a pointer to the requested interface.
Return Value: S_OK E_NOINTERFACE
Note: The relative position of lpVtbl and pCallFactoryVtbl is the same for CStdStubBuffer, CStdStubBuffer2, CStdAsyncStubBuffer,
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) - (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
return pStubBuffer->lpVtbl->QueryInterface( pStubBuffer, riid, ppvObject ); }
ULONG STDMETHODCALLTYPE CStdStubBuffer_CF_AddRef( IN ICallFactory *This ) /*++
Routine Description: No need to go through punkOuter.
Arguments:
Return Value: S_OK E_NOINTERFACE
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) - (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
return pStubBuffer->lpVtbl->AddRef( pStubBuffer ); }
ULONG STDMETHODCALLTYPE CStdStubBuffer_CF_Release( IN ICallFactory *This ) /*++
Routine Description:
Arguments:
Return Value: S_OK E_NOINTERFACE
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) - (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
return pStubBuffer->lpVtbl->Release( pStubBuffer ); }
HRESULT NdrpCreateNonDelegatedAsyncStub( IN IRpcStubBuffer *This, IN REFIID riid, // async IID
IN IUnknown * punkOuter, // controlling unknown
OUT IRpcStubBuffer ** ppAsyncStub ) { BOOL fFound; long j; // if index
const ProxyFileInfo * pProxyFileInfo;
CStdStubBuffer * pSyncSB = (CStdStubBuffer *)This; CStdAsyncStubBuffer * pAsyncSB;
*ppAsyncStub = 0;
if ( ! pSyncSB->pCallFactoryVtbl || !pSyncSB->pAsyncIID ) return E_NOINTERFACE;
if ( memcmp( &riid, pSyncSB->pAsyncIID, sizeof(IID)) != 0 ) return E_NOINTERFACE;
if ( 0 == pSyncSB->pvServerObject ) return CO_E_OBJNOTCONNECTED;
if ( 0 != punkOuter ) return CLASS_E_NOAGGREGATION;
// same file, so we can use the sync pPSFactory.
fFound = NdrpFindInterface( ((CStdPSFactoryBuffer *)pSyncSB->pPSFactory)->pProxyFileList, riid, &pProxyFileInfo, & j); if ( !fFound ) return E_NOINTERFACE;
pAsyncSB = (CStdAsyncStubBuffer *)(*pfnCoTaskMemAlloc)(sizeof(CStdAsyncStubBuffer));
if( ! pAsyncSB ) return E_OUTOFMEMORY;
memset( pAsyncSB, 0, sizeof(CStdAsyncStubBuffer));
//Initialize the new stub buffer.
pAsyncSB->lpVtbl = &pProxyFileInfo->pStubVtblList[j]->Vtbl; pAsyncSB->RefCount = 1; pAsyncSB->pSynchronizeVtbl = & CStdAsyncStubBuffer_ISynchronizeVtbl;
// Create the stub disconnected from the server call object.
// There will be a separate Connect call later.
// pAsyncSB->pvServerObject = 0;
NdrpAsyncStubMsgConstructor( pAsyncSB );
//Increment the DLL reference count for DllCanUnloadNow.
pSyncSB->pPSFactory->lpVtbl->AddRef( pSyncSB->pPSFactory ); pAsyncSB->pPSFactory = pSyncSB->pPSFactory;
*ppAsyncStub = (IRpcStubBuffer *) & pAsyncSB->lpVtbl;
return S_OK; }
HRESULT NdrpCreateDelegatedAsyncStub( IN IRpcStubBuffer *This, IN REFIID riid, // async IID
IN IUnknown * punkOuter, // controlling unknown
OUT IRpcStubBuffer ** ppAsyncStub ) { HRESULT hr; BOOL fFound; long j; // if index
const ProxyFileInfo * pProxyFileInfo; BOOL fDelegate = FALSE;
CStdStubBuffer2 * pSyncSB = (CStdStubBuffer2 *)This; CStdAsyncStubBuffer * pAsyncSB; ICallFactory * pCallFactory; IRpcStubBuffer * pBaseSyncSB;
*ppAsyncStub = 0;
pSyncSB = (CStdStubBuffer2 *) ((uchar*)This - offsetof(CStdStubBuffer2,lpVtbl)) ;
if ( ! pSyncSB->pCallFactoryVtbl || !pSyncSB->pAsyncIID ) return E_NOINTERFACE;
if ( memcmp( &riid, pSyncSB->pAsyncIID, sizeof(IID)) != 0 ) return E_NOINTERFACE;
if ( 0 == pSyncSB->pvServerObject ) return CO_E_OBJNOTCONNECTED;
if ( 0 != punkOuter ) return CLASS_E_NOAGGREGATION;
// same file, so we can use the sync pPSFactory.
fFound = NdrpFindInterface( ((CStdPSFactoryBuffer *)pSyncSB->pPSFactory)->pProxyFileList, riid, &pProxyFileInfo, & j); if ( !fFound ) return E_NOINTERFACE;
pAsyncSB = (CStdAsyncStubBuffer*)(*pfnCoTaskMemAlloc)(sizeof(CStdAsyncStubBuffer));
if( ! pAsyncSB ) return E_OUTOFMEMORY;
memset( pAsyncSB, 0, sizeof(CStdAsyncStubBuffer));
//Initialize the new stub buffer.
pAsyncSB->lpVtbl = &pProxyFileInfo->pStubVtblList[j]->Vtbl; pAsyncSB->RefCount = 1; pAsyncSB->pSynchronizeVtbl = & CStdAsyncStubBuffer_ISynchronizeVtbl;
// As the Connect connects to real server we don't need that.
// pAsyncSB->lpForwardingVtbl = & ForwardingVtbl;
// Create the stub disconnected from the server call object.
// There will be a separate Connect call later.
// pAsyncSB->pvServerObject = 0;
// Create an async stub for the base interface.
// We don't know if the base is delegated, so we have to use
// the base create call method.
// The base async stub will also be disconnected.
pBaseSyncSB = pSyncSB->pBaseStubBuffer;
hr = pBaseSyncSB->lpVtbl->QueryInterface( pBaseSyncSB, IID_ICallFactory, (void**)& pCallFactory );
if ( SUCCEEDED(hr) ) { // Aggregate the base async stub with the current async stub,
// not with the channel's punkOuter.
// We should not need it, and the base stub is aggregated with
// upper stub mostly for debug tracing.
const IID * pBaseAsyncIID;
pBaseAsyncIID = *(const IID **) ( (uchar*)pBaseSyncSB + offsetof(CStdStubBuffer, pAsyncIID) );
hr = pCallFactory->lpVtbl->CreateCall( pCallFactory, *pBaseAsyncIID, 0, // no need for punkOuter (IUnknown*) & pAsyncSB->lpVtbl,
IID_IUnknown, (IUnknown**)& pAsyncSB->pBaseStubBuffer );
pCallFactory->lpVtbl->Release( pCallFactory ); }
if(SUCCEEDED(hr)) { NdrpAsyncStubMsgConstructor( pAsyncSB );
//Increment the DLL reference count for DllCanUnloadNow.
pSyncSB->pPSFactory->lpVtbl->AddRef( pSyncSB->pPSFactory ); pAsyncSB->pPSFactory = pSyncSB->pPSFactory;
*ppAsyncStub = (IRpcStubBuffer *) & pAsyncSB->lpVtbl; } else { (*pfnCoTaskMemFree)(pAsyncSB); }
return hr; }
HRESULT STDMETHODCALLTYPE CStdStubBuffer_CF_CreateCall( IN ICallFactory *This, IN REFIID riid, IN IUnknown * punkOuter, // controlling unknown
IN REFIID riid2, OUT IUnknown ** ppv ) /*
Creates a call object, i.e. an async stub object.
Note, because the call comes via a CStdStubBuffer, not Buffer2, we know that we need to create only a non-delegated async stub. */ { IRpcStubBuffer * pStubBuffer;
if ( memcmp( &riid2, & IID_IUnknown, sizeof(IID)) != 0 ) return E_INVALIDARG;
pStubBuffer = (IRpcStubBuffer*) (((uchar *)This) - offsetof(CStdStubBuffer, pCallFactoryVtbl) + offsetof(CStdStubBuffer, lpVtbl) );
return NdrpCreateNonDelegatedAsyncStub( pStubBuffer, riid, punkOuter, (IRpcStubBuffer **) ppv ); }
HRESULT STDMETHODCALLTYPE CStdStubBuffer2_CF_CreateCall( IN ICallFactory *This, IN REFIID riid, IN IUnknown * punkOuter, // controlling unknown
IN REFIID riid2, OUT IUnknown ** ppv ) /*
Creates a call object, i.e. an async stub object.
Note, because the call comes via a CStdStubBuffer, not Buffer2, we know that we need to create only a non-delegated async stub. */ { IRpcStubBuffer * pStubBuffer;
if ( memcmp( &riid2, & IID_IUnknown, sizeof(IID)) != 0 ) return E_INVALIDARG;
pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This - offsetof(CStdStubBuffer2, pCallFactoryVtbl) + offsetof(CStdStubBuffer2, lpVtbl) );
return NdrpCreateDelegatedAsyncStub( pStubBuffer, riid, punkOuter, (IRpcStubBuffer **) ppv ); }
HRESULT STDMETHODCALLTYPE CStdStubBuffer_RMB_QueryInterface( IN IReleaseMarshalBuffers *This, IN REFIID riid, OUT void ** ppvObject) /*++
Routine Description: Query for an interface on the interface stub CallFactory pointer.
Arguments: riid - Supplies the IID of the interface being requested. ppvObject - Returns a pointer to the requested interface.
Return Value: S_OK E_NOINTERFACE
Note: The relative position of lpVtbl and pCallFactoryVtbl is the same for CStdStubBuffer, CStdStubBuffer2, CStdAsyncStubBuffer,
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) - (offsetof(CStdStubBuffer, pRMBVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
return pStubBuffer->lpVtbl->QueryInterface( pStubBuffer, riid, ppvObject ); }
ULONG STDMETHODCALLTYPE CStdStubBuffer_RMB_AddRef( IN IReleaseMarshalBuffers *This ) /*++
Routine Description: No need to go through punkOuter.
Arguments:
Return Value: S_OK E_NOINTERFACE
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) - (offsetof(CStdStubBuffer, pRMBVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
return pStubBuffer->lpVtbl->AddRef( pStubBuffer ); }
ULONG STDMETHODCALLTYPE CStdStubBuffer_RMB_Release( IN IReleaseMarshalBuffers *This ) /*++
Routine Description:
Arguments:
Return Value: S_OK E_NOINTERFACE
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) - (offsetof(CStdStubBuffer, pRMBVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
return pStubBuffer->lpVtbl->Release( pStubBuffer ); }
HRESULT STDMETHODCALLTYPE CStdStubBuffer_RMB_ReleaseMarshalBuffer( IN IReleaseMarshalBuffers *pRMB, IN RPCOLEMESSAGE * pMsg, IN DWORD dwIOFlags, IN IUnknown *pChnl) { HRESULT hr; CStdStubBuffer * pStubBuffer = (CStdStubBuffer *) (((uchar *)pRMB) - offsetof(CStdStubBuffer, pRMBVtbl));
hr = NdrpServerReleaseMarshalBuffer(pRMB,(RPC_MESSAGE *)pMsg,dwIOFlags,FALSE); return hr; }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_RMB_ReleaseMarshalBuffer( IN IReleaseMarshalBuffers *pRMB, IN RPCOLEMESSAGE * pMsg, IN DWORD dwIOFlags, IN IUnknown *pChnl) { HRESULT hr; CStdStubBuffer * pStubBuffer = (CStdStubBuffer *) (((uchar *)pRMB) - offsetof(CStdStubBuffer, pRMBVtbl));
hr = NdrpServerReleaseMarshalBuffer(pRMB,(RPC_MESSAGE *)pMsg,dwIOFlags,TRUE); return hr; }
//
// The ISynchronize interface on an async stub object
//
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_Synchronize_QueryInterface( IN ISynchronize *This, IN REFIID riid, OUT void ** ppvObject) /*++
Routine Description: Query for an interface on the interface stub CallFactory pointer.
Arguments: riid - Supplies the IID of the interface being requested. ppvObject - Returns a pointer to the requested interface.
Return Value: S_OK E_NOINTERFACE
Note: Works for delegated and non-delegated async stubs. ISynchronize is public, go through punkOuter. --*/ { IRpcStubBuffer * pStubBuffer;
pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This - offsetof(CStdAsyncStubBuffer,pSynchronizeVtbl) + offsetof(CStdAsyncStubBuffer,lpVtbl) );
return pStubBuffer->lpVtbl->QueryInterface( pStubBuffer, riid, ppvObject ); }
ULONG STDMETHODCALLTYPE CStdAsyncStubBuffer_Synchronize_AddRef( IN ISynchronize *This ) /*++
Routine Description:
Arguments:
Return Value: S_OK E_NOINTERFACE
Note: Works for delegated and non-delegated async stubs.
--*/ { IRpcStubBuffer * pStubBuffer;
pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This - offsetof(CStdAsyncStubBuffer,pSynchronizeVtbl) + offsetof(CStdAsyncStubBuffer,lpVtbl) );
return pStubBuffer->lpVtbl->AddRef( pStubBuffer ); }
ULONG STDMETHODCALLTYPE CStdAsyncStubBuffer_Synchronize_Release( IN ISynchronize *This ) /*++
Routine Description:
Arguments:
Return Value: S_OK E_NOINTERFACE
Note: Works for delegated and non-delegated async stubs.
--*/ { IRpcStubBuffer * pStubBuffer;
pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This - offsetof(CStdAsyncStubBuffer,pSynchronizeVtbl) + offsetof(CStdAsyncStubBuffer,lpVtbl) );
return pStubBuffer->lpVtbl->Release( pStubBuffer ); }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_Synchronize_Wait( IN ISynchronize *This, IN DWORD dwFlags, IN DWORD dwMilisec ) /*++
Routine Description: It should never be called. Arguments: Return Value: Note: Works for delegated and non-delegated async stubs.
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This - (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer, lpVtbl)) );
// It should never be called.
return E_NOTIMPL; }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_Synchronize_Signal( IN ISynchronize *This ) /*++
Routine Description: Query for an interface on the interface stub CallFactory pointer.
Arguments: riid - Supplies the IID of the interface being requested. ppvObject - Returns a pointer to the requested interface.
Return Value: S_OK E_NOINTERFACE
Note: Works for delegated and non-delegated async stubs.
--*/ { CStdAsyncStubBuffer * pAsyncSB; HRESULT hr;
RpcTryExcept { pAsyncSB = (CStdAsyncStubBuffer *) ( (uchar *)This - offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) );
// It causes the Finish call to happen.
hr = NdrpAsyncStubSignal( pAsyncSB ); } RpcExcept( EXCEPTION_EXECUTE_HANDLER) { hr = NdrStubErrorHandler( RpcExceptionCode() ); } RpcEndExcept
return hr; }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_Synchronize_Reset( IN ISynchronize *This ) /*++
Routine Description: This is called by the Server's Call Object as part of its Begin_* method.
Arguments:
Return Value: Always S_OK.
Note: Works for delegated and non-delegated async stubs.
--*/ { IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This - (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer, lpVtbl)) );
// Server's Call object gets S_OK...
return S_OK; }
//
// Implementation of the stub buffer itself.
//
HRESULT STDMETHODCALLTYPE CStdStubBuffer_QueryInterface( IN IRpcStubBuffer *This, IN REFIID riid, OUT void ** ppvObject) /*++
Routine Description: Query for an interface on the interface stub. The interface stub supports the IUnknown and IRpcStubBuffer interfaces.
Arguments: riid - Supplies the IID of the interface being requested. ppvObject - Returns a pointer to the requested interface.
Return Value: S_OK E_NOINTERFACE
Note: The relative position of lpVtbl and pCallFactoryVtbl is the same for CStdStubBuffer, CStdStubBuffer2, This is correct for the stubs supporting async_uuid. --*/ { HRESULT hr;
if ((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) || (memcmp(&riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0)) { This->lpVtbl->AddRef(This); *ppvObject = This; hr = S_OK; } else if ( ((CStdStubBuffer*)This)->pCallFactoryVtbl != 0 && memcmp(&riid, &IID_ICallFactory, sizeof(IID)) == 0 ) { This->lpVtbl->AddRef(This); *ppvObject = ( (uchar *)This + (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) ); hr = S_OK; } else if ( (((CStdStubBuffer*)This)->pRMBVtbl) && (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0)) { This->lpVtbl->AddRef(This); *ppvObject = ( (uchar *)This + offsetof(CStdStubBuffer,pRMBVtbl)) ; hr = S_OK; } else if ( riid == IID_IPrivStubBuffer ) { This->lpVtbl->AddRef(This); *ppvObject = This; hr = S_OK; } else { *ppvObject = 0; hr = E_NOINTERFACE; }
return hr; }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_QueryInterface( IN IRpcStubBuffer *This, IN REFIID riid, OUT void ** ppvObject) /*++
Routine Description: Query for an interface on the interface stub. The interface stub supports the IUnknown and IRpcStubBuffer interfaces.
Arguments: riid - Supplies the IID of the interface being requested. ppvObject - Returns a pointer to the requested interface.
Return Value: S_OK E_NOINTERFACE
Note: The relative position of lpVtbl and pCallFactoryVtbl is the same for CStdAsyncStubBuffer So this works for AsyncStubBuffer2_QueryInterface.
--*/ { HRESULT hr = E_NOINTERFACE;
*ppvObject = 0;
if ((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) || (memcmp(&riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0)) { *ppvObject = This; hr = S_OK; } else if ( memcmp(&riid, &IID_ISynchronize, sizeof(IID)) == 0 ) { // For pSynchronize return &pAsyncSB->pSynchronizeVtbl.
*ppvObject = ( (uchar *)This + (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer,lpVtbl)) );
hr = S_OK; } else if ( (((CStdStubBuffer*)This)->pRMBVtbl) && (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0)) { This->lpVtbl->AddRef(This); *ppvObject = (void *)((CStdStubBuffer*)This)->pRMBVtbl; hr = S_OK; } else if ( riid == IID_IPrivStubBuffer ) { This->lpVtbl->AddRef(This); *ppvObject = This; hr = S_OK; }
if ( SUCCEEDED(hr) ) ((IUnknown*)*ppvObject)->lpVtbl->AddRef( (IUnknown*)*ppvObject );
// This is async stub, the channel would never call a query
// for anything else.
return hr; }
ULONG STDMETHODCALLTYPE CStdStubBuffer_AddRef( IN IRpcStubBuffer *This) /*++
Routine Description: Increment reference count.
Arguments:
Return Value: Reference count.
Note: The relative position of lpVtbl and pCallFactoryVtbl is the same for CStdStubBuffer, CStdStubBuffer2,
--*/ { InterlockedIncrement(&((CStdStubBuffer *)This)->RefCount); return (ULONG) ((CStdStubBuffer *)This)->RefCount; }
ULONG STDMETHODCALLTYPE CStdAsyncStubBuffer_AddRef( IN IRpcStubBuffer *This) /*++
Routine Description: Increment reference count.
Arguments:
Return Value: Reference count.
Note: The relative position of lpVtbl and pCallFactoryVtbl is the same for CStdAsyncStubBuffer,
--*/ { // ok: ISynchronize is not really public
InterlockedIncrement(&((CStdStubBuffer *)This)->RefCount);
return (ULONG) ((CStdStubBuffer *)This)->RefCount; }
//
// This is needed and used only by the synchronous stubs.
//
HRESULT STDMETHODCALLTYPE Forwarding_QueryInterface( IN IUnknown * This, IN REFIID riid, OUT void ** ppv) { *ppv = This; return S_OK; }
ULONG STDMETHODCALLTYPE Forwarding_AddRef( IN IUnknown *This) { return 1; }
ULONG STDMETHODCALLTYPE Forwarding_Release( IN IUnknown *This) { return 1; }
ULONG STDMETHODCALLTYPE NdrCStdStubBuffer_Release( IN IRpcStubBuffer * This, IN IPSFactoryBuffer * pFactory) /*++
Routine Description: Decrement reference count.
Arguments:
Return Value: Reference count.
--*/ { ULONG count;
NDR_ASSERT(((CStdStubBuffer *)This)->RefCount > 0, "Invalid reference count");
count = (ULONG) ((CStdStubBuffer *)This)->RefCount - 1;
if(InterlockedDecrement(&((CStdStubBuffer *)This)->RefCount) == 0) { count = 0;
#if DBG == 1
memset(This, '\0', sizeof(CStdStubBuffer)); #endif
//Free the stub buffer
NdrOleFree(This);
//Decrement the DLL reference count.
((CStdPSFactoryBuffer*)pFactory)->lpVtbl->Release( pFactory ); }
return count; }
ULONG STDMETHODCALLTYPE CStdAsyncStubBuffer_Release( IN IRpcStubBuffer * This ) { CStdAsyncStubBuffer * pAsyncSB; ULONG count;
pAsyncSB = (CStdAsyncStubBuffer*)((uchar*)This - offsetof(CStdAsyncStubBuffer,lpVtbl));
NDR_ASSERT(pAsyncSB->RefCount > 0, "Async stub Invalid reference count");
count = (ULONG) pAsyncSB->RefCount - 1;
if ( InterlockedDecrement( &pAsyncSB->RefCount) == 0) { IPSFactoryBuffer * pFactory = pAsyncSB->pPSFactory;
count = 0;
NdrpAsyncStubMsgDestructor( pAsyncSB );
#if DBG == 1
memset( pAsyncSB, '\33', sizeof(CStdAsyncStubBuffer)); #endif
//Free the stub buffer
NdrOleFree( pAsyncSB );
//Decrement the DLL reference count.
pFactory->lpVtbl->Release( pFactory ); }
return count; }
ULONG STDMETHODCALLTYPE CStdAsyncStubBuffer2_Release( IN IRpcStubBuffer * This ) { // O well, the main desctructor for the delegated async stub.
CStdAsyncStubBuffer * pAsyncSB; ULONG count;
pAsyncSB = (CStdAsyncStubBuffer*)((uchar*)This - offsetof(CStdAsyncStubBuffer,lpVtbl));
NDR_ASSERT(pAsyncSB->RefCount > 0, "Async stub Invalid reference count");
count = (ULONG) pAsyncSB->RefCount - 1;
if ( InterlockedDecrement(&pAsyncSB->RefCount) == 0) { IPSFactoryBuffer * pFactory = pAsyncSB->pPSFactory; IRpcStubBuffer * pBaseStubBuffer = pAsyncSB->pBaseStubBuffer;
count = 0;
if( pBaseStubBuffer != 0) pBaseStubBuffer->lpVtbl->Release( pBaseStubBuffer );
NdrpAsyncStubMsgDestructor( pAsyncSB );
#if DBG == 1
memset( pAsyncSB, '\33', sizeof(CStdAsyncStubBuffer)); #endif
//Free the stub buffer
NdrOleFree( pAsyncSB );
//Decrement the DLL reference count.
pFactory->lpVtbl->Release( pFactory ); }
return count; }
ULONG STDMETHODCALLTYPE NdrCStdStubBuffer2_Release( IN IRpcStubBuffer * This, IN IPSFactoryBuffer * pFactory) /*++
Routine Description: Decrement reference count. This function supports delegation to the stub for the base interface.
Arguments:
Return Value: Reference count.
--*/ { ULONG count; unsigned char *pTemp; CStdStubBuffer2 * pStubBuffer; IRpcStubBuffer *pBaseStubBuffer;
pTemp = (unsigned char *)This; pTemp -= offsetof(CStdStubBuffer2, lpVtbl); pStubBuffer = (CStdStubBuffer2 *) pTemp;
NDR_ASSERT(pStubBuffer->RefCount > 0, "Invalid reference count");
count = (ULONG) pStubBuffer->RefCount - 1;
if(InterlockedDecrement(&pStubBuffer->RefCount) == 0) { count = 0;
pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
if(pBaseStubBuffer != 0) pBaseStubBuffer->lpVtbl->Release(pBaseStubBuffer);
#if DBG == 1
memset(pStubBuffer, '\0', sizeof(CStdStubBuffer2)); #endif
if (pStubBuffer->lpForwardingVtbl) ReleaseTemplateForwardVtbl((void **)pStubBuffer->lpForwardingVtbl); //Free the stub buffer
NdrOleFree(pStubBuffer);
//Decrement the DLL reference count.
((CStdPSFactoryBuffer*)pFactory)->lpVtbl->Release( pFactory ); }
return count; }
HRESULT STDMETHODCALLTYPE CStdStubBuffer_Connect( IN IRpcStubBuffer *This, IN IUnknown * pUnkServer) /*++
Routine Description: Connect the stub buffer to the server object. This is the non-delegated case.
Arguments:
Return Value:
Notes: This works for CStdAsyncBuffer_Connect
--*/ { HRESULT hr; const IID *pIID; IUnknown *punk = 0;
NDR_ASSERT(pUnkServer != 0, "pUnkServer parameter is invalid.");
pIID = NdrpGetStubIID(This); hr = pUnkServer->lpVtbl->QueryInterface(pUnkServer, *pIID, (void**)&punk);
punk = (IUnknown *) InterlockedExchangePointer( (PVOID *) &((CStdStubBuffer *) This)->pvServerObject, (PVOID) punk);
if(punk != 0) { //The stub was already connected. Release the old interface pointer.
punk->lpVtbl->Release(punk); }
return hr; }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_Connect( IN IRpcStubBuffer *This, IN IUnknown * punkServer) /*++
Routine Description: Connect the stub buffer to the server object. This is the non-delegated case.
Arguments: punkServer - this is a pointer to AsyncIFoo already queried by the channel. (when delegation same thing)
Return Value:
Notes: This works the same as for StubBuffer_Connect.
Note that an async stub is always created disconnected. It also always keep a pointer to the real server not to a forwarder object. --*/ { IUnknown *punk = 0;
NDR_ASSERT(punkServer != 0, "pUnkServer parameter is invalid.");
punkServer->lpVtbl->AddRef( punkServer );
punk = (IUnknown *) InterlockedExchangePointer( (PVOID *) &((CStdStubBuffer *) This)->pvServerObject, (PVOID) punkServer);
if( punk != 0 ) { // The stub was already connected. Release the old interface pointer.
punk->lpVtbl->Release(punk); }
return S_OK; }
HRESULT STDMETHODCALLTYPE CStdStubBuffer2_Connect( IN IRpcStubBuffer *This, IN IUnknown * pUnkServer) /*++
Routine Description: Connect the stub buffer to the server object. This is the delegated case.
Arguments:
Return Value:
--*/ { HRESULT hr; unsigned char * pTemp; CStdStubBuffer2 * pStubBuffer; IRpcStubBuffer * pBaseStubBuffer;
hr = CStdStubBuffer_Connect(This, pUnkServer);
if(SUCCEEDED(hr)) { //Connect the stub for the base interface.
pTemp = (unsigned char *)This; pTemp -= offsetof(CStdStubBuffer2, lpVtbl); pStubBuffer = (CStdStubBuffer2 *) pTemp;
pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
if(pBaseStubBuffer != 0) { hr = pBaseStubBuffer->lpVtbl->Connect(pBaseStubBuffer, (IUnknown *) &pStubBuffer->lpForwardingVtbl); } } return hr; }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer2_Connect( IN IRpcStubBuffer *This, IN IUnknown * pUnkServer) /*++
Routine Description: Connect the stub buffer to the server object. This is the delegated case.
Arguments:
Return Value:
Notes: This is different from CStdAsyncBuffer2_Connect as the base is connected to the real server here.
Note that an async stub is always created disconnected. It also always keep a pointer to the real server not to a forwarder object.
--*/ { HRESULT hr; unsigned char * pTemp; CStdStubBuffer2 * pStubBuffer; IRpcStubBuffer * pBaseStubBuffer;
hr = CStdAsyncStubBuffer_Connect(This, pUnkServer);
if(SUCCEEDED(hr)) { //Connect the stub for the base interface.
pTemp = (unsigned char *)This; pTemp -= offsetof(CStdStubBuffer2, lpVtbl); pStubBuffer = (CStdStubBuffer2 *) pTemp;
pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
if(pBaseStubBuffer != 0) { hr = pBaseStubBuffer->lpVtbl->Connect( pBaseStubBuffer, pUnkServer ); } } return hr; }
void STDMETHODCALLTYPE CStdStubBuffer_Disconnect( IN IRpcStubBuffer *This) /*++
Routine Description: Disconnect the stub from the server object.
Arguments:
Return Value: None.
Notes: This works for CStdAsyncBuffer_Disconnect
--*/ { IUnknown * punk;
//Set pvServerObject to zero.
punk = (IUnknown *) InterlockedExchangePointer( (PVOID*) &((CStdStubBuffer *)This)->pvServerObject, 0);
if(punk != 0) { //
// Free the old interface pointer.
//
punk->lpVtbl->Release(punk); } }
void STDMETHODCALLTYPE CStdAsyncStubBuffer_Disconnect( IN IRpcStubBuffer *This) /*++
Routine Description: Disconnect the stub from the server object.
Arguments:
Return Value: None. --*/ { // Same as Buffer_Disconnect
IUnknown * punk;
//Set pvServerObject to zero.
punk = (IUnknown *) InterlockedExchangePointer( (PVOID*) &((CStdStubBuffer *)This)->pvServerObject, 0);
// Free the old interface pointer.
if(punk != 0) punk->lpVtbl->Release(punk); }
void STDMETHODCALLTYPE CStdStubBuffer2_Disconnect( IN IRpcStubBuffer *This) /*++
Routine Description: Disconnect the stub buffer from the server object.
Arguments:
Return Value: None.
--*/ { IUnknown * punk; unsigned char *pTemp; CStdStubBuffer2 * pStubBuffer; IRpcStubBuffer *pBaseStubBuffer;
pTemp = (unsigned char *)This; pTemp -= offsetof(CStdStubBuffer2, lpVtbl); pStubBuffer = (CStdStubBuffer2 *) pTemp;
//Disconnect the stub for the base interface.
pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
if(pBaseStubBuffer != 0) pBaseStubBuffer->lpVtbl->Disconnect(pBaseStubBuffer);
//Set pvServerObject to zero.
punk = (IUnknown *) InterlockedExchangePointer( (PVOID*) &pStubBuffer->pvServerObject, 0);
if(punk != 0) { //
// Free the old interface pointer.
//
punk->lpVtbl->Release(punk); } }
void STDMETHODCALLTYPE CStdAsyncStubBuffer2_Disconnect( IN IRpcStubBuffer *This) /*++
Routine Description: Disconnect the stub buffer from the server object.
Arguments:
Return Value: None.
--*/ { IUnknown * punk; unsigned char *pTemp; CStdStubBuffer2 * pStubBuffer; IRpcStubBuffer *pBaseStubBuffer;
pTemp = (unsigned char *)This; pTemp -= offsetof(CStdStubBuffer2, lpVtbl); pStubBuffer = (CStdStubBuffer2 *) pTemp;
//Disconnect the stub for the base interface.
pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
if(pBaseStubBuffer != 0) pBaseStubBuffer->lpVtbl->Disconnect(pBaseStubBuffer);
//Set pvServerObject to zero.
punk = (IUnknown *) InterlockedExchangePointer( (PVOID*) &pStubBuffer->pvServerObject, 0);
// Free the old interface pointer.
if(punk != 0) punk->lpVtbl->Release(punk); }
HRESULT STDMETHODCALLTYPE CStdStubBuffer_Invoke( IN IRpcStubBuffer * This, IN RPCOLEMESSAGE * prpcmsg, IN IRpcChannelBuffer * pRpcChannelBuffer) /*++
Routine Description: Invoke a stub function via the dispatch table.
Arguments:
Return Value:
--*/ { HRESULT hr = S_OK; unsigned char ** ppTemp; unsigned char * pTemp; CInterfaceStubVtbl *pStubVtbl; unsigned long dwServerPhase = STUB_UNMARSHAL;
//Get a pointer to the stub vtbl.
ppTemp = (unsigned char **) This; pTemp = *ppTemp; pTemp -= sizeof(CInterfaceStubHeader); pStubVtbl = (CInterfaceStubVtbl *) pTemp;
RpcTryExcept
//
//Check if procnum is valid.
//
if((prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount) || (prpcmsg->iMethod < 3)) { RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE); }
// null indicates pure-interpreted
if ( pStubVtbl->header.pDispatchTable != 0) { (*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase); } else { PMIDL_SERVER_INFO pServerInfo; PMIDL_STUB_DESC pStubDesc;
pServerInfo = (PMIDL_SERVER_INFO) pStubVtbl->header.pServerInfo; pStubDesc = pServerInfo->pStubDesc;
#ifdef BUILD_NDR64
if ( pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES ) {
NdrStubCall3(This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase); } else #endif
if ( MIDL_VERSION_3_0_39 <= pServerInfo->pStubDesc->MIDLVersion ) { // Since MIDL 3.0.39 we have a proc flag that indicates
// which interpeter to call. This is because the NDR version
// may be bigger than 1.1 for other reasons.
PFORMAT_STRING pProcFormat; unsigned short ProcOffset;
ProcOffset = pServerInfo->FmtStringOffset[ prpcmsg->iMethod ]; pProcFormat = & pServerInfo->ProcString[ ProcOffset ];
if ( pProcFormat[1] & Oi_OBJ_USE_V2_INTERPRETER ) { NdrStubCall2( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase ); } else { #if defined(__RPC_WIN64__)
RpcRaiseException( RPC_X_WRONG_STUB_VERSION ); #else
NdrStubCall( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase ); #endif
} } else { // Prior to that, the NDR version (on per file basis)
// was the only indication of -Oi2.
if ( pStubDesc->Version <= NDR_VERSION_1_1 ) { #if defined(__RPC_WIN64__)
RpcRaiseException( RPC_X_WRONG_STUB_VERSION ); #else
NdrStubCall( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase ); #endif
} else { NdrStubCall2( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase ); } } } RpcExcept(dwServerPhase == STUB_CALL_SERVER ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER) hr = NdrStubErrorHandler( RpcExceptionCode() ); RpcEndExcept
return hr; }
HRESULT STDMETHODCALLTYPE CStdAsyncStubBuffer_Invoke( IN IRpcStubBuffer * This, IN RPCOLEMESSAGE * prpcmsg, IN IRpcChannelBuffer * pRpcChannelBuffer) /*++
Routine Description: Invoke a stub function via the dispatch table.
Arguments:
Return Value:
--*/ { HRESULT hr = S_OK; unsigned char ** ppTemp; unsigned char * pTemp; CInterfaceStubVtbl *pStubVtbl; unsigned long dwServerPhase = STUB_UNMARSHAL;
//Get a pointer to the stub vtbl.
ppTemp = (unsigned char **) This; pTemp = *ppTemp; pTemp -= sizeof(CInterfaceStubHeader); pStubVtbl = (CInterfaceStubVtbl *) pTemp;
RpcTryExcept { PMIDL_SERVER_INFO pServerInfo;
// Check if procnum is valid.
// Note, this is a sync proc number.
//
if((prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount) || (prpcmsg->iMethod < 3)) { RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE); }
// Async DCOM is supported only in the new interpreter,
// and only since MIDL 5.0.+
pServerInfo = (PMIDL_SERVER_INFO) pStubVtbl->header.pServerInfo;
if ( pServerInfo->pStubDesc->MIDLVersion < MIDL_VERSION_5_0_136 ) RpcRaiseException( RPC_S_INTERNAL_ERROR );
// Non null would indicate an -Os stub or a delegation case.
if ( pStubVtbl->header.pDispatchTable != 0) { (*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase); } else { #if defined(BUILD_NDR64)
if ( pServerInfo->pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES ) { switch ( NdrpGetSyntaxType( ( (PRPC_MESSAGE) prpcmsg )->TransferSyntax ) ) { case XFER_SYNTAX_DCE: NdrDcomAsyncStubCall( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase ); break;
case XFER_SYNTAX_NDR64: Ndr64DcomAsyncStubCall( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase ); break; } } else #endif
NdrDcomAsyncStubCall( This, pRpcChannelBuffer, (PRPC_MESSAGE) prpcmsg, &dwServerPhase ); } } RpcExcept(dwServerPhase == STUB_CALL_SERVER ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER) hr = NdrStubErrorHandler( RpcExceptionCode() ); RpcEndExcept
return hr; }
IRpcStubBuffer * STDMETHODCALLTYPE CStdStubBuffer_IsIIDSupported( IN IRpcStubBuffer *This, IN REFIID riid) /*++
Routine Description: If the stub buffer supports the specified interface, then return an IRpcStubBuffer *. If the interface is not supported, then return zero.
Arguments:
Return Value:
Notes: This works for CStdAsyncStubBuffer,CStdAsyncStubBuffer2.
--*/ { CStdStubBuffer * pCThis = (CStdStubBuffer *) This; const IID * pIID; IRpcStubBuffer * pInterfaceStub = 0;
pIID = NdrpGetStubIID(This);
if(memcmp(&riid, pIID, sizeof(IID)) == 0) { if(pCThis->pvServerObject != 0) { pInterfaceStub = This; pInterfaceStub->lpVtbl->AddRef(pInterfaceStub); } }
return pInterfaceStub; }
ULONG STDMETHODCALLTYPE CStdStubBuffer_CountRefs( IN IRpcStubBuffer *This) /*++
Routine Description: Count the number of references to the server object.
Arguments:
Return Value:
Notes: This works for CStdAsyncStubBuffer.
--*/ { ULONG count = 0;
if(((CStdStubBuffer *)This)->pvServerObject != 0) count++;
return count; }
ULONG STDMETHODCALLTYPE CStdStubBuffer2_CountRefs( IN IRpcStubBuffer *This) /*++
Routine Description: Count the number of references to the server object.
Arguments:
Return Value:
Notes: This works for CStdAsyncStubBuffer2.
--*/ { ULONG count; unsigned char *pTemp; CStdStubBuffer2 * pStubBuffer; IRpcStubBuffer *pBaseStubBuffer;
pTemp = (unsigned char *)This; pTemp -= offsetof(CStdStubBuffer2, lpVtbl); pStubBuffer = (CStdStubBuffer2 *) pTemp;
count = CStdStubBuffer_CountRefs(This);
pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
if(pBaseStubBuffer != 0) count += pBaseStubBuffer->lpVtbl->CountRefs(pBaseStubBuffer);
return count; }
HRESULT STDMETHODCALLTYPE CStdStubBuffer_DebugServerQueryInterface( IN IRpcStubBuffer *This, OUT void **ppv) /*++
Routine Description: Return the interface pointer to the server object.
Arguments:
Return Value:
--*/ { HRESULT hr;
*ppv = ((CStdStubBuffer *)This)->pvServerObject;
if(*ppv != 0) hr = S_OK; else hr = CO_E_OBJNOTCONNECTED;
return hr; }
void STDMETHODCALLTYPE CStdStubBuffer_DebugServerRelease( IN IRpcStubBuffer *This, IN void *pv) /*++
Routine Description: Release a pointer previously obtained via DebugServerQueryInterface. This function does nothing.
Arguments: This pv
Return Value: None.
--*/ { }
const IID * RPC_ENTRY NdrpGetStubIID( IN IRpcStubBuffer *This) /*++
Routine Description: This function returns a pointer to the IID for the interface stub.
Arguments:
Return Value:
--*/ { unsigned char ** ppTemp; unsigned char * pTemp; CInterfaceStubVtbl *pStubVtbl;
//Get a pointer to the stub vtbl.
ppTemp = (unsigned char **) This; pTemp = *ppTemp; pTemp -= sizeof(CInterfaceStubHeader); pStubVtbl = (CInterfaceStubVtbl *) pTemp;
return pStubVtbl->header.piid; }
void RPC_ENTRY NdrStubInitialize( IN PRPC_MESSAGE pRpcMsg, IN PMIDL_STUB_MESSAGE pStubMsg, IN PMIDL_STUB_DESC pStubDescriptor, IN IRpcChannelBuffer * pRpcChannelBuffer ) /*++
Routine Description: This routine is called by the server stub before unmarshalling. It sets up some stub message fields.
Arguments: pRpcMsg pStubMsg pStubDescriptor pRpcChannelBuffer
Return Value: None.
--*/ { NdrServerInitialize( pRpcMsg, pStubMsg, pStubDescriptor);
pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
// This exception should be raised after initializing StubMsg.
if ( pStubDescriptor->Version > NDR_VERSION ) { NDR_ASSERT( 0, "ServerInitializePartial : bad version number" );
RpcRaiseException( RPC_X_WRONG_STUB_VERSION ); }
pRpcChannelBuffer->lpVtbl->GetDestCtx( pRpcChannelBuffer, &pStubMsg->dwDestContext, &pStubMsg->pvDestContext); }
void RPC_ENTRY NdrStubInitializePartial( IN PRPC_MESSAGE pRpcMsg, IN PMIDL_STUB_MESSAGE pStubMsg, IN PMIDL_STUB_DESC pStubDescriptor, IN IRpcChannelBuffer * pRpcChannelBuffer, IN unsigned long RequestedBufferSize ) /*++
Routine Description: This routine is called by the server stub before unmarshalling. It sets up some stub message fields.
Arguments: pRpcMsg pStubMsg pStubDescriptor pRpcChannelBuffer
Return Value: None.
--*/ { NdrServerInitialize( pRpcMsg, pStubMsg, pStubDescriptor);
pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
pRpcChannelBuffer->lpVtbl->GetDestCtx( pRpcChannelBuffer, &pStubMsg->dwDestContext, &pStubMsg->pvDestContext);
MakeSureWeHaveNonPipeArgs( pStubMsg, RequestedBufferSize ); }
void RPC_ENTRY NdrStubGetBuffer( IN IRpcStubBuffer * This, IN IRpcChannelBuffer * pChannel, IN PMIDL_STUB_MESSAGE pStubMsg) /*++
Routine Description: Get a message buffer from the channel
Arguments: This pChannel pStubMsg
Return Value: None. If an error occurs, this functions raises an exception.
--*/ { HRESULT hr; const IID * pIID;
pIID = NdrpGetStubIID(This); pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; pStubMsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION; hr = pChannel->lpVtbl->GetBuffer(pChannel, (RPCOLEMESSAGE *) pStubMsg->RpcMsg, *pIID);
if(FAILED(hr)) { RpcRaiseException(hr); }
pStubMsg->Buffer = (unsigned char *) pStubMsg->RpcMsg->Buffer; pStubMsg->fBufferValid = TRUE; }
HRESULT RPC_ENTRY NdrStubErrorHandler( IN DWORD dwExceptionCode) /*++
Routine Description: Map exceptions into HRESULT failure codes. If we caught an exception from the server object, then propagate the exception to the channel.
Arguments: dwExceptionCode
Return Value: This function returns an HRESULT failure code.
--*/ { HRESULT hr;
if(FAILED((HRESULT) dwExceptionCode)) hr = (HRESULT) dwExceptionCode; else hr = HRESULT_FROM_WIN32(dwExceptionCode);
return hr; }
EXTERN_C void RPC_ENTRY NdrStubInitializeMarshall ( IN PRPC_MESSAGE pRpcMsg, IN PMIDL_STUB_MESSAGE pStubMsg, IN IRpcChannelBuffer * pRpcChannelBuffer ) /*++
Routine Description: This routine is called by the server stub before marshalling. It sets up some stub message fields.
Arguments: pRpcMsg pStubMsg pRpcChannelBuffer
Return Value: None.
--*/ { pStubMsg->BufferLength = 0;
pStubMsg->IgnoreEmbeddedPointers = FALSE;
pStubMsg->fDontCallFreeInst = 0;
pStubMsg->StackTop = 0;
pRpcChannelBuffer->lpVtbl->GetDestCtx( pRpcChannelBuffer, &pStubMsg->dwDestContext, &pStubMsg->pvDestContext); }
void __RPC_STUB NdrStubForwardingFunction( IN IRpcStubBuffer * This, IN IRpcChannelBuffer * pChannel, IN PRPC_MESSAGE pmsg, OUT DWORD * pdwStubPhase) /*++
Routine Description: This function forwards a call to the stub for the base interface.
Arguments: pChannel pmsg pdwStubPhase
Return Value: None.
--*/ { HRESULT hr; unsigned char *pTemp; CStdStubBuffer2 * pStubBuffer; IRpcStubBuffer *pBaseStubBuffer;
pTemp = (unsigned char *)This; pTemp -= offsetof(CStdStubBuffer2, lpVtbl); pStubBuffer = (CStdStubBuffer2 *) pTemp; pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
hr = pBaseStubBuffer->lpVtbl->Invoke(pBaseStubBuffer, (RPCOLEMESSAGE *) pmsg, pChannel); if(FAILED(hr)) RpcRaiseException(hr); }
|