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

📄 ndr_stubless.c

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