📄 ndr_stubless.c
字号:
#else
FIXME("initialize full pointer translation tables\n");
#endif
/* store the RPC flags away */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
pRpcMsg->RpcFlags = ((NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags;
/* use alternate memory allocation routines */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC)
#if 0
NdrRpcSsEnableAllocate(&stubMsg);
#else
FIXME("Set RPCSS memory allocation routines\n");
#endif
if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
{
FIXME("pipes not supported yet\n");
RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
/* init pipes package */
/* NdrPipesInitialize(...) */
}
if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC)
{
/* initialize extra correlation package */
FIXME("new correlation description not implemented\n");
stubMsg.fHasNewCorrDesc = TRUE;
}
/* convert strings, floating point values and endianess into our
* preferred format */
if ((pRpcMsg->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)
NdrConvert(&stubMsg, pFormat);
parameter_start_offset = current_offset;
TRACE("allocating memory for stack of size %x\n", stack_size);
args = HeapAlloc(GetProcessHeap(), 0, stack_size);
ZeroMemory(args, stack_size);
/* add the implicit This pointer as the first arg to the function if we
* are calling an object method */
if (pThis)
*(void **)args = ((CStdStubBuffer *)pThis)->pvServerObject;
/* order of phases:
* 1. STUBLESS_UNMARHSAL - unmarshal [in] params from buffer
* 2. STUBLESS_CALLSERVER - send/receive buffer
* 3. STUBLESS_CALCSIZE - get [out] buffer size
* 4. STUBLESS_GETBUFFER - allocate [out] buffer
* 5. STUBLESS_MARHSAL - marshal [out] params to buffer
*/
for (phase = STUBLESS_UNMARSHAL; phase <= STUBLESS_MARSHAL; phase++)
{
TRACE("phase = %d\n", phase);
switch (phase)
{
case STUBLESS_CALLSERVER:
/* call the server function */
if (pServerInfo->ThunkTable)
{
stubMsg.StackTop = args;
pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg);
/* FIXME: RetVal is stored as the last argument - retrieve it */
}
else if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
{
SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject;
RetVal = call_server_func(vtbl[pRpcMsg->ProcNum], args, stack_size);
}
else
RetVal = call_server_func(pServerInfo->DispatchTable[pRpcMsg->ProcNum], args, stack_size);
TRACE("stub implementation returned %p\n", (void *)RetVal);
stubMsg.Buffer = NULL;
stubMsg.BufferLength = 0;
break;
case STUBLESS_GETBUFFER:
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
NdrStubGetBuffer(pThis, pChannel, &stubMsg);
else
{
RPC_STATUS Status;
pRpcMsg->BufferLength = stubMsg.BufferLength;
/* allocate buffer for [out] and [ret] params */
Status = I_RpcGetBuffer(pRpcMsg);
if (Status)
RpcRaiseException(Status);
stubMsg.BufferStart = pRpcMsg->Buffer;
stubMsg.BufferEnd = stubMsg.BufferStart + stubMsg.BufferLength;
stubMsg.Buffer = stubMsg.BufferStart;
}
break;
case STUBLESS_MARSHAL:
case STUBLESS_UNMARSHAL:
case STUBLESS_CALCSIZE:
current_offset = parameter_start_offset;
current_stack_offset = 0;
/* NOTE: V1 style format does't terminate on the number_of_params
* condition as it doesn't have this attribute. Instead it
* terminates when the stack size given in the header is exceeded.
*/
for (i = 0; i < number_of_params; i++)
{
if (bV2Format) /* new parameter format */
{
const NDR_PARAM_OIF_BASETYPE *pParam =
(NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset];
unsigned char *pArg;
current_stack_offset = pParam->stack_offset;
pArg = (unsigned char *)(args+current_stack_offset);
TRACE("param[%d]: new format\n", i);
TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n");
TRACE("\tstack_offset: %x\n", current_stack_offset);
TRACE("\tmemory addr (before): %p -> %p\n", pArg, *(unsigned char **)pArg);
if (pParam->param_attributes.ServerAllocSize)
FIXME("ServerAllocSize of %d ignored for parameter %d\n",
pParam->param_attributes.ServerAllocSize * 8, i);
if (pParam->param_attributes.IsBasetype)
{
const unsigned char *pTypeFormat =
&pParam->type_format_char;
TRACE("\tbase type: 0x%02x\n", *pTypeFormat);
switch (phase)
{
case STUBLESS_MARSHAL:
if (pParam->param_attributes.IsReturn)
call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{
if (pParam->param_attributes.IsSimpleRef)
call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
else
call_marshaller(&stubMsg, pArg, pTypeFormat);
}
/* FIXME: call call_freer here */
break;
case STUBLESS_UNMARSHAL:
if (pParam->param_attributes.IsIn)
{
if (pParam->param_attributes.IsSimpleRef)
call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
else
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
}
break;
case STUBLESS_CALCSIZE:
if (pParam->param_attributes.IsReturn)
call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{
if (pParam->param_attributes.IsSimpleRef)
call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
else
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
}
break;
default:
RpcRaiseException(RPC_S_INTERNAL_ERROR);
}
current_offset += sizeof(NDR_PARAM_OIF_BASETYPE);
}
else
{
NDR_PARAM_OIF_OTHER * pParamOther =
(NDR_PARAM_OIF_OTHER *)&pFormat[current_offset];
const unsigned char * pTypeFormat =
&(pStubDesc->pFormatTypes[pParamOther->type_offset]);
TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);
switch (phase)
{
case STUBLESS_MARSHAL:
if (pParam->param_attributes.IsReturn)
call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{
if (pParam->param_attributes.IsByValue)
call_marshaller(&stubMsg, pArg, pTypeFormat);
else
{
call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
stubMsg.pfnFree(*(void **)pArg);
}
}
/* FIXME: call call_freer here for IN types */
break;
case STUBLESS_UNMARSHAL:
if (pParam->param_attributes.IsIn)
{
if (pParam->param_attributes.IsByValue)
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
else
call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
}
else if ((pParam->param_attributes.IsOut) &&
!(pParam->param_attributes.IsByValue))
{
*(void **)pArg = NdrAllocate(&stubMsg, sizeof(void *));
**(void ***)pArg = 0;
}
break;
case STUBLESS_CALCSIZE:
if (pParam->param_attributes.IsReturn)
call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{
if (pParam->param_attributes.IsByValue)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
else
call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
}
break;
default:
RpcRaiseException(RPC_S_INTERNAL_ERROR);
}
current_offset += sizeof(NDR_PARAM_OIF_OTHER);
}
TRACE("\tmemory addr (after): %p -> %p\n", pArg, *(unsigned char **)pArg);
}
else /* old parameter format */
{
NDR_PARAM_OI_BASETYPE *pParam =
(NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset];
unsigned char *pArg = (unsigned char *)(args+current_stack_offset);
/* no more parameters; exit loop */
if (current_stack_offset > stack_size)
break;
TRACE("param[%d]: old format\n\tparam_direction: 0x%x\n", i, pParam->param_direction);
if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE ||
pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
{
const unsigned char *pTypeFormat =
&pParam->type_format_char;
TRACE("\tbase type 0x%02x\n", *pTypeFormat);
switch (phase)
{
case STUBLESS_MARSHAL:
if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
{
unsigned char *pRetVal = (unsigned char *)&RetVal;
call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
break;
case STUBLESS_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
break;
case STUBLESS_CALCSIZE:
if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
{
unsigned char * pRetVal = (unsigned char *)&RetVal;
call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
break;
default:
RpcRaiseException(RPC_S_INTERNAL_ERROR);
}
current_stack_offset += call_memory_sizer(&stubMsg, pTypeFormat);
current_offset += sizeof(NDR_PARAM_OI_BASETYPE);
}
else
{
NDR_PARAM_OI_OTHER * pParamOther =
(NDR_PARAM_OI_OTHER *)&pFormat[current_offset];
const unsigned char * pTypeFormat =
&pStubDesc->pFormatTypes[pParamOther->type_offset];
TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);
switch (phase)
{
case STUBLESS_MARSHAL:
if (pParam->param_direction == RPC_FC_RETURN_PARAM)
{
unsigned char *pRetVal = (unsigned char *)&RetVal;
call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
else if (pParam->param_direction == RPC_FC_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM)
call_marshaller(&stubMsg, pArg, pTypeFormat);
break;
case STUBLESS_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_PARAM)
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
break;
case STUBLESS_CALCSIZE:
if (pParam->param_direction == RPC_FC_RETURN_PARAM)
{
unsigned char * pRetVal = (unsigned char *)&RetVal;
call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
else if (pParam->param_direction == RPC_FC_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
break;
default:
RpcRaiseException(RPC_S_INTERNAL_ERROR);
}
current_stack_offset += pParamOther->stack_size * sizeof(INT);
current_offset += sizeof(NDR_PARAM_OI_OTHER);
}
}
}
break;
default:
ERR("shouldn't reach here. phase %d\n", phase);
break;
}
}
pRpcMsg->BufferLength = (unsigned int)(stubMsg.Buffer - (unsigned char *)pRpcMsg->Buffer);
if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC)
{
/* free extra correlation package */
/* NdrCorrelationFree(&stubMsg); */
}
if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
{
/* NdrPipesDone(...) */
}
#if 0
/* free the full pointer translation tables */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables);
#endif
/* free server function stack */
HeapFree(GetProcessHeap(), 0, args);
return S_OK;
}
void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg)
{
DWORD dwPhase;
NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -