📄 ndr_stubless.c
字号:
/* if a simple ref pointer then we have to do the
* check for the pointer being non-NULL. */
if (pParam->param_attributes.IsSimpleRef)
{
if (!*(unsigned char **)pArg)
RpcRaiseException(RPC_X_NULL_REF_POINTER);
}
TRACE("\tcomplex type: 0x%02x\n", *pTypeFormat);
switch (phase)
{
case PROXY_CALCSIZE:
if (pParam->param_attributes.IsIn)
{
if (pParam->param_attributes.IsByValue)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
else
call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
}
break;
case PROXY_MARSHAL:
if (pParam->param_attributes.IsIn)
{
if (pParam->param_attributes.IsByValue)
call_marshaller(&stubMsg, pArg, pTypeFormat);
else
call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
}
break;
case PROXY_UNMARSHAL:
if (pParam->param_attributes.IsOut)
{
unsigned char *pRetVal = (unsigned char *)&RetVal;
if (pParam->param_attributes.IsReturn)
call_unmarshaller(&stubMsg, &pRetVal, pTypeFormat, 0);
else if (pParam->param_attributes.IsByValue)
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
else
call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
}
break;
default:
RpcRaiseException(RPC_S_INTERNAL_ERROR);
}
current_offset += sizeof(NDR_PARAM_OIF_OTHER);
}
TRACE("\tmemory addr (after): %p\n", pArg);
}
else /* old parameter format */
{
NDR_PARAM_OI_BASETYPE * pParam =
(NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset];
unsigned char * pArg = ARG_FROM_OFFSET(args, current_stack_offset);
/* no more parameters; exit loop */
if (current_stack_offset > stack_size)
break;
TRACE("param[%d]: old format\n", i);
TRACE("\tparam_direction: %x\n", pParam->param_direction);
TRACE("\tstack_offset: 0x%x\n", current_stack_offset);
TRACE("\tmemory addr (before): %p\n", pArg);
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 PROXY_CALCSIZE:
if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
break;
case PROXY_MARSHAL:
if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
call_marshaller(&stubMsg, pArg, pTypeFormat);
break;
case PROXY_UNMARSHAL:
if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
{
if (pParam->param_direction & RPC_FC_RETURN_PARAM)
call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0);
else
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
}
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 PROXY_CALCSIZE:
if (pParam->param_direction == RPC_FC_IN_PARAM ||
pParam->param_direction & RPC_FC_IN_OUT_PARAM)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
break;
case PROXY_MARSHAL:
if (pParam->param_direction == RPC_FC_IN_PARAM ||
pParam->param_direction & RPC_FC_IN_OUT_PARAM)
call_marshaller(&stubMsg, pArg, pTypeFormat);
break;
case PROXY_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_OUT_PARAM)
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
else if (pParam->param_direction == RPC_FC_RETURN_PARAM)
call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0);
break;
default:
RpcRaiseException(RPC_S_INTERNAL_ERROR);
}
current_stack_offset += pParamOther->stack_size * sizeof(INT);
current_offset += sizeof(NDR_PARAM_OI_OTHER);
}
TRACE("\tmemory addr (after): %p\n", pArg);
}
}
break;
default:
ERR("shouldn't reach here. phase %d\n", phase);
break;
}
}
/* FIXME: unbind the binding handle */
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 marshalling buffer */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
NdrProxyFreeBuffer(This, &stubMsg);
else
NdrFreeBuffer(&stubMsg);
TRACE("RetVal = 0x%lx\n", RetVal);
return RetVal;
}
/* calls a function with the specificed arguments, restoring the stack
* properly afterwards as we don't know the calling convention of the
* function */
#if defined __i386__ && defined _MSC_VER
__declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size)
{
__asm
{
push ebp
push edi ; Save registers
push esi
mov ebp, esp
mov eax, [ebp+16] ; Get stack size
sub esp, eax ; Make room in stack for arguments
mov edi, esp
mov ecx, eax
mov esi, [ebp+12]
shr ecx, 2
cld
rep movsd ; Copy dword blocks
call [ebp+8] ; Call function
lea esp, [ebp-8] ; Restore stack
pop ebp ; Restore registers
pop esi
pop edi
ret
}
}
#elif defined __i386__ && defined __GNUC__
LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size);
__ASM_GLOBAL_FUNC(call_server_func,
"pushl %ebp\n\t"
"movl %esp, %ebp\n\t"
"pushl %edi\n\t" /* Save registers */
"pushl %esi\n\t"
"movl 16(%ebp), %eax\n\t" /* Get stack size */
"subl %eax, %esp\n\t" /* Make room in stack for arguments */
"andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for MacOS X */
"movl %esp, %edi\n\t"
"movl %eax, %ecx\n\t"
"movl 12(%ebp), %esi\n\t"
"shrl $2, %ecx\n\t" /* divide by 4 */
"cld\n\t"
"rep; movsl\n\t" /* Copy dword blocks */
"call *8(%ebp)\n\t" /* Call function */
"leal -8(%ebp), %esp\n\t" /* Restore stack */
"popl %esi\n\t" /* Restore registers */
"popl %edi\n\t"
"popl %ebp\n\t"
"ret\n" );
#else
#warning call_server_func not implemented for your architecture
LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size)
{
FIXME("Not implemented for your architecture\n");
return 0;
}
#endif
/* FIXME: need to free some stuff in here too */
long WINAPI NdrStubCall2(
struct IRpcStubBuffer * pThis,
struct IRpcChannelBuffer * pChannel,
PRPC_MESSAGE pRpcMsg,
unsigned long * pdwStubPhase)
{
const MIDL_SERVER_INFO *pServerInfo;
const MIDL_STUB_DESC *pStubDesc;
PFORMAT_STRING pFormat;
MIDL_STUB_MESSAGE stubMsg;
/* pointer to start of stack to pass into stub implementation */
unsigned char * args;
/* size of stack */
unsigned short stack_size;
/* current stack offset */
unsigned short current_stack_offset;
/* number of parameters. optional for client to give it to us */
unsigned char number_of_params = ~0;
/* counter */
unsigned short i;
/* cache of Oif_flags from v2 procedure header */
unsigned char Oif_flags = 0;
/* cache of extension flags from NDR_PROC_EXTENSION */
unsigned char ext_flags = 0;
/* the type of pass we are currently doing */
int phase;
/* header for procedure string */
const NDR_PROC_HEADER *pProcHeader;
/* offset in format string for start of params */
int parameter_start_offset;
/* current format string offset */
int current_offset;
/* -Oif or -Oicf generated format */
BOOL bV2Format = FALSE;
/* the return value (not from this function, but to be put back onto
* the wire */
LONG_PTR RetVal = 0;
TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase);
if (pThis)
pServerInfo = CStdStubBuffer_GetServerInfo(pThis);
else
pServerInfo = ((RPC_SERVER_INTERFACE *)pRpcMsg->RpcInterfaceInformation)->InterpreterInfo;
pStubDesc = pServerInfo->pStubDesc;
pFormat = pServerInfo->ProcString + pServerInfo->FmtStringOffset[pRpcMsg->ProcNum];
pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
/* Later NDR language versions probably won't be backwards compatible */
if (pStubDesc->Version > 0x50002)
{
FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc->Version);
RpcRaiseException(RPC_X_WRONG_STUB_VERSION);
}
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
{
NDR_PROC_HEADER_RPC * pProcHeader = (NDR_PROC_HEADER_RPC *)&pFormat[0];
stack_size = pProcHeader->stack_size;
current_offset = sizeof(NDR_PROC_HEADER_RPC);
}
else
{
stack_size = pProcHeader->stack_size;
current_offset = sizeof(NDR_PROC_HEADER);
}
TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags);
/* binding */
switch (pProcHeader->handle_type)
{
/* explicit binding: parse additional section */
case RPC_FC_BIND_EXPLICIT:
switch (pFormat[current_offset]) /* handle_type */
{
case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */
current_offset += sizeof(NDR_EHD_PRIMITIVE);
break;
case RPC_FC_BIND_GENERIC: /* explicit generic */
current_offset += sizeof(NDR_EHD_GENERIC);
break;
case RPC_FC_BIND_CONTEXT: /* explicit context */
current_offset += sizeof(NDR_EHD_CONTEXT);
break;
default:
ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
break;
case RPC_FC_BIND_GENERIC: /* implicit generic */
case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */
case RPC_FC_CALLBACK_HANDLE: /* implicit callback */
case RPC_FC_AUTO_HANDLE: /* implicit auto handle */
break;
default:
ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
bV2Format = (pStubDesc->Version >= 0x20000);
if (bV2Format)
{
NDR_PROC_PARTIAL_OIF_HEADER * pOIFHeader =
(NDR_PROC_PARTIAL_OIF_HEADER*)&pFormat[current_offset];
Oif_flags = pOIFHeader->Oif_flags;
number_of_params = pOIFHeader->number_of_params;
current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
}
TRACE("Oif_flags = 0x%02x\n", Oif_flags);
if (Oif_flags & RPC_FC_PROC_OI2F_HASEXTS)
{
NDR_PROC_EXTENSION * pExtensions =
(NDR_PROC_EXTENSION *)&pFormat[current_offset];
ext_flags = pExtensions->ext_flags;
current_offset += pExtensions->extension_version;
}
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
NdrStubInitialize(pRpcMsg, &stubMsg, pStubDesc, pChannel);
else
NdrServerInitializeNew(pRpcMsg, &stubMsg, pStubDesc);
/* create the full pointer translation tables, if requested */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
#if 0
stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -