750 lines
23 KiB
C++
750 lines
23 KiB
C++
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
Copyright (c) 1993-2000 Microsoft Corporation
|
|||
|
|
|||
|
Module Name :
|
|||
|
|
|||
|
srvcall.c
|
|||
|
|
|||
|
Abstract :
|
|||
|
|
|||
|
This file contains the single call Ndr64 routine for the server side.
|
|||
|
|
|||
|
Author :
|
|||
|
|
|||
|
David Kays dkays October 1993.
|
|||
|
|
|||
|
Revision History :
|
|||
|
|
|||
|
brucemc 11/15/93 Added struct by value support, corrected varargs
|
|||
|
use.
|
|||
|
brucemc 12/20/93 Binding handle support.
|
|||
|
brucemc 12/22/93 Reworked argument accessing method.
|
|||
|
ryszardk 3/12/94 Handle optimization and fixes.
|
|||
|
|
|||
|
---------------------------------------------------------------------*/
|
|||
|
|
|||
|
#include "precomp.hxx"
|
|||
|
|
|||
|
#define CINTERFACE
|
|||
|
#define USE_STUBLESS_PROXY
|
|||
|
|
|||
|
#include "ndrole.h"
|
|||
|
#include "rpcproxy.h"
|
|||
|
|
|||
|
#include "hndl.h"
|
|||
|
#include "interp2.h"
|
|||
|
#include "pipendr.h"
|
|||
|
|
|||
|
#include <stdarg.h>
|
|||
|
|
|||
|
|
|||
|
#pragma code_seg(".ndr64")
|
|||
|
|
|||
|
|
|||
|
long RPC_ENTRY
|
|||
|
Ndr64StubWorker(
|
|||
|
IRpcStubBuffer * pThis,
|
|||
|
IRpcChannelBuffer * pChannel,
|
|||
|
PRPC_MESSAGE pRpcMsg,
|
|||
|
MIDL_SERVER_INFO * pServerInfo,
|
|||
|
const SERVER_ROUTINE * DispatchTable,
|
|||
|
MIDL_SYNTAX_INFO * pSyntaxInfo,
|
|||
|
ulong * pdwStubPhase
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description :
|
|||
|
|
|||
|
Server Interpreter entry point for object RPC procs. Also called by
|
|||
|
Ndr64ServerCall, the entry point for regular RPC procs.
|
|||
|
|
|||
|
Arguments :
|
|||
|
|
|||
|
pThis - Object proc's 'this' pointer, 0 for non-object procs.
|
|||
|
pChannel - Object proc's Channel Buffer, 0 for non-object procs.
|
|||
|
pRpcMsg - The RPC message.
|
|||
|
pdwStubPhase - Used to track the current interpreter's activity.
|
|||
|
|
|||
|
Return :
|
|||
|
|
|||
|
Status of S_OK.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
PMIDL_STUB_DESC pStubDesc;
|
|||
|
ushort ProcNum;
|
|||
|
|
|||
|
long FormatOffset;
|
|||
|
PFORMAT_STRING pFormat;
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
|
|||
|
ulong StackSize;
|
|||
|
|
|||
|
MIDL_STUB_MESSAGE StubMsg;
|
|||
|
|
|||
|
uchar * pArg;
|
|||
|
uchar ** ppArg;
|
|||
|
|
|||
|
NDR64_PROC_FLAGS * pNdr64Flags;
|
|||
|
long NumberParams;
|
|||
|
|
|||
|
BOOL HasExplicitHandle;
|
|||
|
BOOL fBadStubDataException = FALSE;
|
|||
|
long n;
|
|||
|
|
|||
|
boolean NotifyAppInvoked = FALSE;
|
|||
|
long ret;
|
|||
|
NDR_PROC_CONTEXT ProcContext;
|
|||
|
NDR64_PROC_FORMAT * pHeader = NULL;
|
|||
|
NDR64_PARAM_FLAGS * pParamFlags;
|
|||
|
NDR64_BIND_AND_NOTIFY_EXTENSION * pHeaderExts = NULL;
|
|||
|
MIDL_STUB_MESSAGE * pStubMsg = &StubMsg;
|
|||
|
|
|||
|
//
|
|||
|
// In the case of a context handle, the server side manager function has
|
|||
|
// to be called with NDRSContextValue(ctxthandle). But then we may need to
|
|||
|
// marshall the handle, so NDRSContextValue(ctxthandle) is put in the
|
|||
|
// argument buffer and the handle itself is stored in the following array.
|
|||
|
// When marshalling a context handle, we marshall from this array.
|
|||
|
//
|
|||
|
NDR_SCONTEXT CtxtHndl[MAX_CONTEXT_HNDL_NUMBER];
|
|||
|
|
|||
|
ProcNum = (ushort) pRpcMsg->ProcNum;
|
|||
|
|
|||
|
NDR_ASSERT( ! ((ULONG_PTR)pRpcMsg->Buffer & 0x7),
|
|||
|
"marshaling buffer misaligned at server" );
|
|||
|
|
|||
|
|
|||
|
// setup SyntaxInfo of selected transfer syntax.
|
|||
|
NdrServerSetupNDR64TransferSyntax( ProcNum, pSyntaxInfo, &ProcContext );
|
|||
|
StubMsg.pContext = &ProcContext;
|
|||
|
|
|||
|
|
|||
|
pStubDesc = pServerInfo->pStubDesc;
|
|||
|
|
|||
|
pFormat = ProcContext.pProcFormat;
|
|||
|
|
|||
|
pHeader = (NDR64_PROC_FORMAT *) pFormat;
|
|||
|
pNdr64Flags = (NDR64_PROC_FLAGS *) & (pHeader->Flags );
|
|||
|
HasExplicitHandle = !NDR64MAPHANDLETYPE( NDR64GETHANDLETYPE ( pNdr64Flags ) );
|
|||
|
|
|||
|
StackSize = pHeader->StackSize;
|
|||
|
|
|||
|
//
|
|||
|
// Yes, do this here outside of our RpcTryFinally block. If we
|
|||
|
// can't allocate the arg buffer there's nothing more to do, so
|
|||
|
// raise an exception and return control to the RPC runtime.
|
|||
|
//
|
|||
|
// Alloca throws an exception on an error.
|
|||
|
|
|||
|
uchar *pArgBuffer = (uchar*)alloca(StackSize);
|
|||
|
ProcContext.StartofStack = pArgBuffer;
|
|||
|
|
|||
|
//
|
|||
|
// Zero out the arg buffer. We must do this so that parameters
|
|||
|
// are properly zeroed before we start unmarshalling. If we catch
|
|||
|
// an exception before finishing the unmarshalling we can not leave
|
|||
|
// parameters in an unitialized state since we have to do a freeing
|
|||
|
// pass.
|
|||
|
//
|
|||
|
MIDL_memset( pArgBuffer,
|
|||
|
0,
|
|||
|
StackSize );
|
|||
|
|
|||
|
if ( pNdr64Flags->HasOtherExtensions )
|
|||
|
pHeaderExts = (NDR64_BIND_AND_NOTIFY_EXTENSION *) (pFormat + sizeof( NDR64_PROC_FORMAT ) );
|
|||
|
|
|||
|
if ( HasExplicitHandle )
|
|||
|
{
|
|||
|
//
|
|||
|
// For a handle_t parameter we must pass the handle field of
|
|||
|
// the RPC message to the server manager.
|
|||
|
//
|
|||
|
NDR_ASSERT( pHeaderExts, "NULL extension header" );
|
|||
|
if ( pHeaderExts->Binding.HandleType == FC64_BIND_PRIMITIVE )
|
|||
|
{
|
|||
|
pArg = pArgBuffer + pHeaderExts->Binding.StackOffset;
|
|||
|
|
|||
|
if ( NDR64_IS_HANDLE_PTR( pHeaderExts->Binding.Flags ) )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
*((handle_t *)pArg) = pRpcMsg->Handle;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get new interpreter info.
|
|||
|
//
|
|||
|
NumberParams = pHeader->NumberOfParams;
|
|||
|
|
|||
|
NDR64_PARAM_FORMAT* Params =
|
|||
|
(NDR64_PARAM_FORMAT*)ProcContext.Params;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Wrap the unmarshalling, mgr call and marshalling in the try block of
|
|||
|
// a try-finally. Put the free phase in the associated finally block.
|
|||
|
//
|
|||
|
RpcTryFinally
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// If OLE, put pThis in first dword of stack.
|
|||
|
//
|
|||
|
if ( pThis )
|
|||
|
{
|
|||
|
*((void **)pArgBuffer) =
|
|||
|
(void *)((CStdStubBuffer *)pThis)->pvServerObject;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the Stub message.
|
|||
|
//
|
|||
|
if ( ! pChannel )
|
|||
|
{
|
|||
|
if ( ! pNdr64Flags->UsesPipes )
|
|||
|
{
|
|||
|
Ndr64ServerInitialize( pRpcMsg,
|
|||
|
&StubMsg,
|
|||
|
pStubDesc );
|
|||
|
}
|
|||
|
else
|
|||
|
Ndr64ServerInitializePartial( pRpcMsg,
|
|||
|
&StubMsg,
|
|||
|
pStubDesc,
|
|||
|
pHeader->ConstantClientBufferSize );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
NDR_ASSERT( ! pNdr64Flags->UsesPipes, "DCOM pipe is not supported" );
|
|||
|
NdrStubInitialize( pRpcMsg,
|
|||
|
&StubMsg,
|
|||
|
pStubDesc,
|
|||
|
pChannel );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up for context handle management.
|
|||
|
//
|
|||
|
StubMsg.SavedContextHandles = CtxtHndl;
|
|||
|
memset( CtxtHndl, 0, sizeof(CtxtHndl) );
|
|||
|
|
|||
|
|
|||
|
pStubMsg->pCorrMemory = pArgBuffer;
|
|||
|
|
|||
|
if ( pNdr64Flags->UsesFullPtrPackage )
|
|||
|
StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_SERVER );
|
|||
|
|
|||
|
//
|
|||
|
// Set StackTop AFTER the initialize call, since it zeros the field
|
|||
|
// out.
|
|||
|
//
|
|||
|
StubMsg.StackTop = pArgBuffer;
|
|||
|
|
|||
|
if ( pNdr64Flags->UsesPipes )
|
|||
|
NdrpPipesInitialize64( & StubMsg,
|
|||
|
&ProcContext.AllocateContext,
|
|||
|
(PFORMAT_STRING) Params,
|
|||
|
(char*)pArgBuffer,
|
|||
|
NumberParams );
|
|||
|
|
|||
|
//
|
|||
|
// We must make this check AFTER the call to ServerInitialize,
|
|||
|
// since that routine puts the stub descriptor alloc/dealloc routines
|
|||
|
// into the stub message.
|
|||
|
//
|
|||
|
if ( pNdr64Flags->UsesRpcSmPackage )
|
|||
|
NdrRpcSsEnableAllocate( &StubMsg );
|
|||
|
|
|||
|
RpcTryExcept
|
|||
|
{
|
|||
|
|
|||
|
// --------------------------------
|
|||
|
// Unmarshall all of our parameters.
|
|||
|
// --------------------------------
|
|||
|
NDR_ASSERT( ProcContext.StartofStack == pArgBuffer, "startofstack is not set" );
|
|||
|
Ndr64pServerUnMarshal( &StubMsg );
|
|||
|
|
|||
|
if ( pRpcMsg->BufferLength <
|
|||
|
(uint)(StubMsg.Buffer - (uchar *)pRpcMsg->Buffer) )
|
|||
|
{
|
|||
|
RpcRaiseException( RPC_X_BAD_STUB_DATA );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
RpcExcept( NdrServerUnmarshallExceptionFlag(GetExceptionInformation()) )
|
|||
|
{
|
|||
|
// Filter set in rpcndr.h to catch one of the following
|
|||
|
// STATUS_ACCESS_VIOLATION
|
|||
|
// STATUS_DATATYPE_MISALIGNMENT
|
|||
|
// RPC_X_BAD_STUB_DATA
|
|||
|
|
|||
|
NdrpFreeMemoryList( &StubMsg );
|
|||
|
|
|||
|
fBadStubDataException = TRUE;
|
|||
|
if ( RPC_BAD_STUB_DATA_EXCEPTION_FILTER )
|
|||
|
RpcRaiseException( RPC_X_BAD_STUB_DATA );
|
|||
|
else
|
|||
|
RpcRaiseException( RpcExceptionCode() );
|
|||
|
}
|
|||
|
RpcEndExcept
|
|||
|
|
|||
|
//
|
|||
|
// Do [out] initialization.
|
|||
|
//
|
|||
|
Ndr64pServerOutInit( pStubMsg );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Unblock the first pipe; this needs to be after unmarshalling
|
|||
|
// because the buffer may need to be changed to the secondary one.
|
|||
|
// In the out only pipes case this happens immediately.
|
|||
|
//
|
|||
|
|
|||
|
if ( pNdr64Flags->UsesPipes )
|
|||
|
NdrMarkNextActivePipe( ProcContext.pPipeDesc );
|
|||
|
|
|||
|
//
|
|||
|
// OLE interfaces use pdwStubPhase in the exception filter.
|
|||
|
// See CStdStubBuffer_Invoke in rpcproxy.c.
|
|||
|
//
|
|||
|
*pdwStubPhase = STUB_CALL_SERVER;
|
|||
|
|
|||
|
NotifyAppInvoked = TRUE;
|
|||
|
//
|
|||
|
// Check for a thunk. Compiler does all the setup for us.
|
|||
|
//
|
|||
|
if ( pServerInfo->ThunkTable && pServerInfo->ThunkTable[ProcNum] )
|
|||
|
{
|
|||
|
pServerInfo->ThunkTable[ProcNum]( &StubMsg );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Note that this ArgNum is not the number of arguments declared
|
|||
|
// in the function we called, but really the number of
|
|||
|
// REGISTER_TYPEs occupied by the arguments to a function.
|
|||
|
//
|
|||
|
long ArgNum;
|
|||
|
MANAGER_FUNCTION pFunc;
|
|||
|
REGISTER_TYPE returnValue;
|
|||
|
|
|||
|
if ( pRpcMsg->ManagerEpv )
|
|||
|
pFunc = ((MANAGER_FUNCTION *)pRpcMsg->ManagerEpv)[ProcNum];
|
|||
|
else
|
|||
|
pFunc = (MANAGER_FUNCTION) DispatchTable[ProcNum];
|
|||
|
|
|||
|
ArgNum = (long) StackSize / sizeof(REGISTER_TYPE);
|
|||
|
|
|||
|
//
|
|||
|
// The StackSize includes the size of the return. If we want
|
|||
|
// just the number of REGISTER_TYPES, then ArgNum must be reduced
|
|||
|
// by 1 when there is a return value AND the current ArgNum count
|
|||
|
// is greater than 0.
|
|||
|
//
|
|||
|
if ( ArgNum && pNdr64Flags->HasReturn && !pNdr64Flags->HasComplexReturn )
|
|||
|
ArgNum--;
|
|||
|
|
|||
|
returnValue = Invoke( pFunc,
|
|||
|
(REGISTER_TYPE *)pArgBuffer,
|
|||
|
#if defined(_IA64_)
|
|||
|
pHeader->FloatDoubleMask,
|
|||
|
#endif
|
|||
|
ArgNum);
|
|||
|
|
|||
|
if( pNdr64Flags->HasReturn && !pNdr64Flags->HasComplexReturn )
|
|||
|
{
|
|||
|
((REGISTER_TYPE *)pArgBuffer)[ArgNum] = returnValue;
|
|||
|
// Pass the app's return value to OLE channel
|
|||
|
if ( pThis )
|
|||
|
(*pfnDcomChannelSetHResult)( pRpcMsg,
|
|||
|
NULL, // reserved
|
|||
|
(HRESULT) returnValue );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
*pdwStubPhase = STUB_MARSHAL;
|
|||
|
|
|||
|
if ( pNdr64Flags->UsesPipes )
|
|||
|
{
|
|||
|
NdrIsAppDoneWithPipes( ProcContext.pPipeDesc );
|
|||
|
StubMsg.BufferLength += pHeader->ConstantServerBufferSize;
|
|||
|
}
|
|||
|
else
|
|||
|
StubMsg.BufferLength = pHeader->ConstantServerBufferSize;
|
|||
|
|
|||
|
if ( pNdr64Flags->ServerMustSize )
|
|||
|
{
|
|||
|
//
|
|||
|
// Buffer size pass.
|
|||
|
//
|
|||
|
Ndr64pSizing( pStubMsg,
|
|||
|
FALSE ); // IsClient
|
|||
|
}
|
|||
|
|
|||
|
if ( pNdr64Flags->UsesPipes && ProcContext.pPipeDesc->OutPipes )
|
|||
|
{
|
|||
|
NdrGetPartialBuffer( & StubMsg );
|
|||
|
StubMsg.RpcMsg->RpcFlags &= ~RPC_BUFFER_PARTIAL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( ! pChannel )
|
|||
|
{
|
|||
|
Ndr64GetBuffer( &StubMsg,
|
|||
|
StubMsg.BufferLength );
|
|||
|
}
|
|||
|
else
|
|||
|
NdrStubGetBuffer( pThis,
|
|||
|
pChannel,
|
|||
|
&StubMsg );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Marshall pass.
|
|||
|
//
|
|||
|
Ndr64pServerMarshal ( &StubMsg );
|
|||
|
|
|||
|
|
|||
|
if ( pRpcMsg->BufferLength <
|
|||
|
(ulong)(StubMsg.Buffer - (uchar *)pRpcMsg->Buffer) )
|
|||
|
{
|
|||
|
NDR_ASSERT( 0, "Ndr64StubWrok marshal: buffer overflow!" );
|
|||
|
RpcRaiseException( RPC_X_BAD_STUB_DATA );
|
|||
|
}
|
|||
|
|
|||
|
pRpcMsg->BufferLength = (ulong) ( StubMsg.Buffer - (uchar *) pRpcMsg->Buffer );
|
|||
|
|
|||
|
#if defined(DEBUG_WALKIP)
|
|||
|
if ( pChannel )
|
|||
|
{
|
|||
|
Ndr64pReleaseMarshalBuffer(
|
|||
|
StubMsg.RpcMsg,
|
|||
|
ProcContext.pSyntaxInfo,
|
|||
|
StubMsg.RpcMsg->ProcNum,
|
|||
|
StubMsg.StubDesc,
|
|||
|
1, //BUFFER_OUT
|
|||
|
true );
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
RpcFinally
|
|||
|
{
|
|||
|
// clean up context handles if exception is thrown in either marshalling or
|
|||
|
// manager routine.
|
|||
|
|
|||
|
if ( RpcAbnormalTermination() && ! pChannel )
|
|||
|
{
|
|||
|
Ndr64pCleanupServerContextHandles( &StubMsg,
|
|||
|
NumberParams,
|
|||
|
Params,
|
|||
|
pArgBuffer,
|
|||
|
STUB_MARSHAL != *pdwStubPhase);
|
|||
|
}
|
|||
|
|
|||
|
// If we died because of bad stub data, don't free the params here since they
|
|||
|
// were freed using a linked list of memory in the exception handler above.
|
|||
|
|
|||
|
if ( ! fBadStubDataException )
|
|||
|
{
|
|||
|
|
|||
|
Ndr64pFreeParams( &StubMsg,
|
|||
|
NumberParams,
|
|||
|
Params,
|
|||
|
pArgBuffer );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NdrpAllocaDestroy( &ProcContext.AllocateContext );
|
|||
|
|
|||
|
//
|
|||
|
// Deferred frees. Actually, this should only be necessary if you
|
|||
|
// had a pointer to enum16 in a *_is expression.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Free any full pointer resources.
|
|||
|
//
|
|||
|
NdrFullPointerXlatFree( StubMsg.FullPtrXlatTables );
|
|||
|
|
|||
|
//
|
|||
|
// Disable rpcss allocate package if needed.
|
|||
|
//
|
|||
|
if ( pNdr64Flags->UsesRpcSmPackage )
|
|||
|
NdrRpcSsDisableAllocate( &StubMsg );
|
|||
|
|
|||
|
if ( pNdr64Flags->HasNotify )
|
|||
|
{
|
|||
|
NDR_NOTIFY_ROUTINE pfnNotify;
|
|||
|
|
|||
|
// BUGBUG: tests need to be recompiled.
|
|||
|
pfnNotify = StubMsg.StubDesc->NotifyRoutineTable[ pHeaderExts->NotifyIndex ];
|
|||
|
|
|||
|
((NDR_NOTIFY2_ROUTINE)pfnNotify)(NotifyAppInvoked);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
RpcEndFinally
|
|||
|
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
Ndr64pFreeParams(
|
|||
|
MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
long NumberParams,
|
|||
|
NDR64_PARAM_FORMAT * Params,
|
|||
|
uchar * pArgBuffer
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description :
|
|||
|
|
|||
|
Frees the memory associated with function parameters as required.
|
|||
|
|
|||
|
Arguments :
|
|||
|
|
|||
|
pStubMsg - Supplies a pointer to the stub message.
|
|||
|
NumberParams - Supplies the number of parameters for this procedure.
|
|||
|
Params - Supplies a pointer to the parameter list for this function.
|
|||
|
pArgBuffer - Supplies a pointer to the virtual stack.
|
|||
|
pParamFilter - Supplies a filter that is used to determine which functions
|
|||
|
are to be considered. This function should return TRUE if
|
|||
|
the parameter should be considered. If pParamFilter is NULL,
|
|||
|
the default filter is used which is all parameters that have
|
|||
|
MustFree set.
|
|||
|
|
|||
|
Return :
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
for ( long n = 0; n < NumberParams; n++ )
|
|||
|
{
|
|||
|
NDR64_PARAM_FLAGS *pParamFlags =
|
|||
|
( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
|
|||
|
|
|||
|
if ( ! pParamFlags->MustFree )
|
|||
|
continue;
|
|||
|
|
|||
|
uchar *pArg = pArgBuffer + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( ! pParamFlags->IsByValue )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
if ( pArg )
|
|||
|
{
|
|||
|
pStubMsg->fDontCallFreeInst =
|
|||
|
pParamFlags->IsDontCallFreeInst;
|
|||
|
|
|||
|
Ndr64ToplevelTypeFree( pStubMsg,
|
|||
|
pArg,
|
|||
|
Params[n].Type );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We have to check if we need to free any simple ref pointer,
|
|||
|
// since we skipped it's Ndr64PointerFree call. We also have
|
|||
|
// to explicitly free arrays and strings. But make sure it's
|
|||
|
// non-null and not sitting in the buffer.
|
|||
|
//
|
|||
|
if ( pParamFlags->IsSimpleRef ||
|
|||
|
NDR64_IS_ARRAY_OR_STRING(*(PFORMAT_STRING)Params[n].Type) )
|
|||
|
{
|
|||
|
//
|
|||
|
// Don't free [out] params that we're allocated on the
|
|||
|
// interpreter's stack.
|
|||
|
//
|
|||
|
|
|||
|
if ( pParamFlags->UseCache )
|
|||
|
continue;
|
|||
|
|
|||
|
//
|
|||
|
// We have to make sure the array/string is non-null in case we
|
|||
|
// get an exception before finishing our unmarshalling.
|
|||
|
//
|
|||
|
if ( pArg &&
|
|||
|
( (pArg < pStubMsg->BufferStart) ||
|
|||
|
(pArg > pStubMsg->BufferEnd) ) )
|
|||
|
(*pStubMsg->pfnFree)( pArg );
|
|||
|
}
|
|||
|
} // for
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
Ndr64pCleanupServerContextHandles(
|
|||
|
MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
long NumberParams,
|
|||
|
NDR64_PARAM_FORMAT* Params,
|
|||
|
uchar * pArgBuffer,
|
|||
|
BOOL fManagerRoutineException
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description :
|
|||
|
|
|||
|
Cleans up context handles that might have been dropped by the NDR engine between
|
|||
|
the return from the manager routine and the end of marshaling.
|
|||
|
|
|||
|
Arguments :
|
|||
|
|
|||
|
pStubMsg - Supplies a pointer to the stub message.
|
|||
|
NumberParams - Supplies the number of parameters for this procedure.
|
|||
|
Params - Supplies a pointer to the parameter list for this function.
|
|||
|
pArgBuffer - Supplies a pointer to the virtual stack.
|
|||
|
|
|||
|
Return :
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
for ( long n = 0; n < NumberParams; n++ )
|
|||
|
{
|
|||
|
NDR64_PARAM_FLAGS *pParamFlags =
|
|||
|
(NDR64_PARAM_FLAGS *) &( Params[n].Attributes );
|
|||
|
|
|||
|
if ( ! pParamFlags->IsOut || pParamFlags->IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
uchar *pArg = pArgBuffer + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( ! pParamFlags->IsByValue )
|
|||
|
pArg = *((uchar * UNALIGNED *)pArg);
|
|||
|
|
|||
|
NDR64_FORMAT_CHAR FcType = *(PFORMAT_STRING)Params[n].Type;
|
|||
|
|
|||
|
if ( FcType == FC64_BIND_CONTEXT )
|
|||
|
{
|
|||
|
// NDR64_CONTEXT_HANDLE_FORMAT is the same as PNDR_CONTEXT_HANDLE_ARG_DESC.
|
|||
|
|
|||
|
NdrpEmergencyContextCleanup( pStubMsg,
|
|||
|
(PNDR_CONTEXT_HANDLE_ARG_DESC ) Params[n].Type,
|
|||
|
pArg,
|
|||
|
fManagerRoutineException );
|
|||
|
}
|
|||
|
|
|||
|
} // for
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
Ndr64pServerUnMarshal ( MIDL_STUB_MESSAGE * pStubMsg )
|
|||
|
{
|
|||
|
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT * )pStubMsg->pContext;
|
|||
|
|
|||
|
// if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
|
|||
|
// RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
NDR64_PARAM_FORMAT *Params = (NDR64_PARAM_FORMAT *)pContext->Params;
|
|||
|
|
|||
|
CORRELATION_CONTEXT CorrCtxt( pStubMsg, pContext->StartofStack );
|
|||
|
|
|||
|
//
|
|||
|
// ----------------------------------------------------------
|
|||
|
// Unmarshall Pass.
|
|||
|
// ----------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
for ( ulong n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
NDR64_PARAM_FLAGS *pParamFlags =
|
|||
|
( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
|
|||
|
|
|||
|
|
|||
|
if ( ! pParamFlags->IsIn ||
|
|||
|
pParamFlags->IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
if ( pParamFlags->IsPartialIgnore )
|
|||
|
{
|
|||
|
uchar *pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
ALIGN( pStubMsg->Buffer, NDR64_PTR_WIRE_ALIGN );
|
|||
|
*(void**)pArg = *(NDR64_PTR_WIRE_TYPE*)pStubMsg->Buffer ? (void*)1 : (void*)0;
|
|||
|
pStubMsg->Buffer += sizeof(NDR64_PTR_WIRE_TYPE);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
uchar *pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
//
|
|||
|
// This is for returned basetypes and for pointers to
|
|||
|
// basetypes.
|
|||
|
//
|
|||
|
if ( pParamFlags->IsBasetype )
|
|||
|
{
|
|||
|
NDR64_FORMAT_CHAR type = *(PFORMAT_STRING)Params[n].Type;
|
|||
|
|
|||
|
//
|
|||
|
// Check for a pointer to a basetype. Set the arg pointer
|
|||
|
// at the correct buffer location and you're done.
|
|||
|
// Except darn int3264.
|
|||
|
//
|
|||
|
if ( pParamFlags->IsSimpleRef )
|
|||
|
{
|
|||
|
ALIGN( pStubMsg->Buffer, NDR64_SIMPLE_TYPE_BUFALIGN( type ) );
|
|||
|
|
|||
|
*((uchar **)pArg) = pStubMsg->Buffer;
|
|||
|
|
|||
|
pStubMsg->Buffer += NDR64_SIMPLE_TYPE_BUFSIZE( type );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Ndr64SimpleTypeUnmarshall(
|
|||
|
pStubMsg,
|
|||
|
pArg,
|
|||
|
type );
|
|||
|
}
|
|||
|
|
|||
|
continue;
|
|||
|
} // IsBasetype
|
|||
|
|
|||
|
//
|
|||
|
// This is an initialization of [in] and [in,out] ref pointers
|
|||
|
// to pointers. These can not be initialized to point into the
|
|||
|
// rpc buffer and we want to avoid doing a malloc of 4 bytes!
|
|||
|
// 32b: a ref pointer to any pointer, we allocate the pointee pointer.
|
|||
|
//
|
|||
|
if ( pParamFlags->UseCache )
|
|||
|
{
|
|||
|
*((void **)pArg) = NdrpAlloca( &pContext->AllocateContext, 8);
|
|||
|
|
|||
|
// Triple indirection - cool!
|
|||
|
**((void ***)pArg) = 0;
|
|||
|
}
|
|||
|
uchar **ppArg = pParamFlags->IsByValue ? &pArg : (uchar **)pArg;
|
|||
|
|
|||
|
|
|||
|
pStubMsg->ReuseBuffer = pParamFlags->IsForceAllocate;
|
|||
|
|
|||
|
Ndr64TopLevelTypeUnmarshall(pStubMsg,
|
|||
|
ppArg,
|
|||
|
Params[n].Type,
|
|||
|
pParamFlags->IsForceAllocate &&
|
|||
|
!pParamFlags->IsByValue );
|
|||
|
|
|||
|
// force allocate is param attr: reset the flag after each parameter.
|
|||
|
pStubMsg->ReuseBuffer = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( pStubMsg->pCorrInfo )
|
|||
|
Ndr64CorrelationPass( pStubMsg );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#pragma code_seg()
|
|||
|
|