2081 lines
50 KiB
C++
2081 lines
50 KiB
C++
/*++
|
||
|
||
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;
|
||
|
||
pAsyncSB = (CStdAsyncStubBuffer *) ( (uchar *)This -
|
||
offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) );
|
||
|
||
// It causes the Finish call to happen.
|
||
hr = NdrpAsyncStubSignal( pAsyncSB );
|
||
|
||
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);
|
||
}
|
||
|
||
|