📄 ndr_stubless.c
字号:
else { NdrFreeBuffer(&stubMsg); client_free_handle(&stubMsg, pProcHeader, pHandleFormat, hBinding); } 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 esi ; Restore registers pop edi pop ebp 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 Mac OS 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 architectureLONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size){ FIXME("Not implemented for your architecture\n"); return 0;}#endifstatic DWORD calc_arg_size(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat){ DWORD size; switch(*pFormat) { case RPC_FC_STRUCT: size = *(const WORD*)(pFormat + 2); break; case RPC_FC_CARRAY: size = *(const WORD*)(pFormat + 2); ComputeConformance(pStubMsg, NULL, pFormat + 4, 0); size *= pStubMsg->MaxCount; break; case RPC_FC_SMFARRAY: size = *(const WORD*)(pFormat + 2); break; case RPC_FC_LGFARRAY: size = *(const DWORD*)(pFormat + 2); break; default: FIXME("Unhandled type %02x\n", *pFormat); /* fallthrough */ case RPC_FC_RP: size = sizeof(void *); break; } return size;}/* FIXME: need to free some stuff in here too */LONG WINAPI NdrStubCall2( struct IRpcStubBuffer * pThis, struct IRpcChannelBuffer * pChannel, PRPC_MESSAGE pRpcMsg, DWORD * 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 */ INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; /* cache of extension flags from NDR_PROC_HEADER_EXTS */ INTERPRETER_OPT_FLAGS2 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; /* location to put retval into */ LONG_PTR *retval_ptr = NULL; 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%x\n", pStubDesc->Version); RpcRaiseException(RPC_X_WRONG_STUB_VERSION); } /* create the full pointer translation tables, if requested */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER); if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) { const NDR_PROC_HEADER_RPC *pProcHeader = (const 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) { const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = (const NDR_PROC_PARTIAL_OIF_HEADER *)&pFormat[current_offset]; Oif_flags = pOIFHeader->Oi2Flags; number_of_params = pOIFHeader->number_of_params; current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); } TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); if (Oif_flags.HasExtensions) { const NDR_PROC_HEADER_EXTS *pExtensions = (const NDR_PROC_HEADER_EXTS *)&pFormat[current_offset]; ext_flags = pExtensions->Flags2; current_offset += pExtensions->Size; } if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrStubInitialize(pRpcMsg, &stubMsg, pStubDesc, pChannel); else NdrServerInitializeNew(pRpcMsg, &stubMsg, pStubDesc); /* store the RPC flags away */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) pRpcMsg->RpcFlags = ((const 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.HasPipes) { FIXME("pipes not supported yet\n"); RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ /* init pipes package */ /* NdrPipesInitialize(...) */ } if (ext_flags.HasNewCorrDesc) { /* 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(), HEAP_ZERO_MEMORY, stack_size); stubMsg.StackTop = args; /* used by conformance of top-level objects */ /* 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_FREE; phase++) { TRACE("phase = %d\n", phase); switch (phase) { case STUBLESS_CALLSERVER: /* call the server function */ if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum]) pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg); else { SERVER_ROUTINE func; LONG_PTR retval; if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) { SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject; func = vtbl[pRpcMsg->ProcNum]; } else func = pServerInfo->DispatchTable[pRpcMsg->ProcNum]; /* FIXME: what happens with return values that don't fit into a single register on x86? */ retval = call_server_func(func, args, stack_size); if (retval_ptr) { TRACE("stub implementation returned 0x%lx\n", retval); *retval_ptr = retval; } else TRACE("void stub implementation\n"); } stubMsg.Buffer = NULL; stubMsg.BufferLength = 0; break; case STUBLESS_GETBUFFER: if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrStubGetBuffer(pThis, pChannel, &stubMsg); else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -