📄 ndr_stubless.c
字号:
unsigned short i; /* 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; TRUE; i++) { const NDR_PARAM_OI_BASETYPE *pParam = (const NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; /* note: current_stack_offset starts after the This pointer * if present, so adjust this */ unsigned short current_stack_offset_adjusted = current_stack_offset + (object_proc ? sizeof(void *) : 0); unsigned char * pArg = ARG_FROM_OFFSET(*pStubMsg, current_stack_offset_adjusted); /* no more parameters; exit loop */ if (current_stack_offset_adjusted >= stack_size) break; TRACE("param[%d]: old format\n", i); TRACE("\tparam_direction: 0x%x\n", pParam->param_direction); TRACE("\tstack_offset: 0x%x\n", current_stack_offset_adjusted); 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(pStubMsg, pArg, pTypeFormat); break; case PROXY_MARSHAL: if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) call_marshaller(pStubMsg, 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(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0); else call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); } break; default: RpcRaiseException(RPC_S_INTERNAL_ERROR); } current_stack_offset += call_memory_sizer(pStubMsg, pTypeFormat); current_offset += sizeof(NDR_PARAM_OI_BASETYPE); } else { const NDR_PARAM_OI_OTHER *pParamOther = (const NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; const unsigned char *pTypeFormat = &pStubMsg->StubDesc->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(pStubMsg, *(unsigned char **)pArg, pTypeFormat); break; case PROXY_MARSHAL: if (pParam->param_direction == RPC_FC_IN_PARAM || pParam->param_direction & RPC_FC_IN_OUT_PARAM) call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); break; case PROXY_UNMARSHAL: if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || pParam->param_direction == RPC_FC_OUT_PARAM) call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); else if (pParam->param_direction == RPC_FC_RETURN_PARAM) call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, 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); }}/* the return type should be CLIENT_CALL_RETURN, but this is incompatible * with the way gcc returns structures. "void *" should be the largest type * that MIDL should allow you to return anyway */LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, ...){ /* pointer to start of stack where arguments start */ RPC_MESSAGE rpcMsg; MIDL_STUB_MESSAGE stubMsg; handle_t hBinding = NULL; /* procedure number */ unsigned short procedure_number; /* size of stack */ unsigned short stack_size; /* number of parameters. optional for client to give it to us */ unsigned char number_of_params = ~0; /* 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 = (const NDR_PROC_HEADER *)&pFormat[0]; /* -Oif or -Oicf generated format */ BOOL bV2Format = FALSE; /* the value to return to the client from the remote procedure */ LONG_PTR RetVal = 0; /* the pointer to the object when in OLE mode */ void * This = NULL; PFORMAT_STRING pHandleFormat; TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); /* 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); } 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; procedure_number = pProcHeader->proc_num; pFormat += sizeof(NDR_PROC_HEADER_RPC); } else { stack_size = pProcHeader->stack_size; procedure_number = pProcHeader->proc_num; pFormat += sizeof(NDR_PROC_HEADER); } TRACE("stack size: 0x%x\n", stack_size); TRACE("proc num: %d\n", procedure_number); /* create the full pointer translation tables, if requested */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) { /* object is always the first argument */ This = **(void *const **)(&pFormat+1); NdrProxyInitialize(This, &rpcMsg, &stubMsg, pStubDesc, procedure_number); } else NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDesc, procedure_number); TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); /* needed for conformance of top-level objects */#ifdef __i386__ stubMsg.StackTop = *(unsigned char **)(&pFormat+1);#else# warning Stack not retrieved for your CPU architecture#endif pHandleFormat = pFormat; /* we only need a handle if this isn't an object method */ if (!(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)) { pFormat = client_get_handle(&stubMsg, pProcHeader, pHandleFormat, &hBinding); if (!pFormat) return 0; } bV2Format = (pStubDesc->Version >= 0x20000); if (bV2Format) { const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat; Oif_flags = pOIFHeader->Oi2Flags; number_of_params = pOIFHeader->number_of_params; pFormat += 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; ext_flags = pExtensions->Flags2; pFormat += pExtensions->Size; } stubMsg.BufferLength = 0; /* store the RPC flags away */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) rpcMsg.RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; /* use alternate memory allocation routines */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) NdrRpcSmSetClientToOsf(&stubMsg); 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; } /* order of phases: * 1. PROXY_CALCSIZE - calculate the buffer size * 2. PROXY_GETBUFFER - allocate the buffer * 3. PROXY_MARHSAL - marshal [in] params into the buffer * 4. PROXY_SENDRECEIVE - send/receive buffer * 5. PROXY_UNMARHSAL - unmarshal [out] params from buffer */ for (phase = PROXY_CALCSIZE; phase <= PROXY_UNMARSHAL; phase++) { TRACE("phase = %d\n", phase); switch (phase) { case PROXY_GETBUFFER: /* allocate the buffer */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrProxyGetBuffer(This, &stubMsg); else if (Oif_flags.HasPipes) /* NdrGetPipeBuffer(...) */ FIXME("pipes not supported yet\n"); else { if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)#if 0 NdrNsGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding);#else FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n");#endif else NdrGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding); } break; case PROXY_SENDRECEIVE: /* send the [in] params and receive the [out] and [retval] * params */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrProxySendReceive(This, &stubMsg); else if (Oif_flags.HasPipes) /* NdrPipesSendReceive(...) */ FIXME("pipes not supported yet\n"); else { if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)#if 0 NdrNsSendReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);#else FIXME("using auto handle - call NdrNsSendReceive when it gets implemented\n");#endif else NdrSendReceive(&stubMsg, stubMsg.Buffer); } /* convert strings, floating point values and endianess into our * preferred format */ if ((rpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) NdrConvert(&stubMsg, pFormat); break; case PROXY_CALCSIZE: case PROXY_MARSHAL: case PROXY_UNMARSHAL: if (bV2Format) client_do_args(&stubMsg, pFormat, phase, number_of_params, (unsigned char *)&RetVal); else client_do_args_old_format(&stubMsg, pFormat, phase, stack_size, (unsigned char *)&RetVal, (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)); break; default: ERR("shouldn't reach here. phase %d\n", phase); break; } } if (ext_flags.HasNewCorrDesc) { /* free extra correlation package */ /* NdrCorrelationFree(&stubMsg); */ } if (Oif_flags.HasPipes) { /* NdrPipesDone(...) */ } /* free the full pointer translation tables */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables); /* free marshalling buffer */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrProxyFreeBuffer(This, &stubMsg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -