⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndr_stubless.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
#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 + -