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

📄 ndr_stubless.c

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