windows-nt/Source/XPSP1/NT/com/rpc/ndr20/stub.cxx

2081 lines
50 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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);
}