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);
|
|||
|
}
|
|||
|
|
|||
|
|