/*
 * NDR -Oi,-Oif,-Oicf Interpreter
 *
 * Copyright 2001 Ove Kåven, TransGaming Technologies
 * Copyright 2003-5 Robert Shearman (for CodeWeavers)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * TODO:
 *  - Pipes
 *  - Some types of binding handles
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"

#include "objbase.h"
#include "rpc.h"
#include "rpcproxy.h"

#include "wine/exception.h"
#include "wine/debug.h"
#include "wine/rpcfc.h"

#include "cpsf.h"
#include "ndr_misc.h"
#include "ndr_stubless.h"

WINE_DEFAULT_DEBUG_CHANNEL(rpc);

#define NDR_TABLE_MASK 127

static inline void call_buffer_sizer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
{
    NDR_BUFFERSIZE m = NdrBufferSizer[pFormat[0] & NDR_TABLE_MASK];
    if (m) m(pStubMsg, pMemory, pFormat);
    else
    {
        FIXME("format type 0x%x not implemented\n", pFormat[0]);
        RpcRaiseException(RPC_X_BAD_STUB_DATA);
    }
}

static inline unsigned char *call_marshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
{
    NDR_MARSHALL m = NdrMarshaller[pFormat[0] & NDR_TABLE_MASK];
    if (m) return m(pStubMsg, pMemory, pFormat);
    else
    {
        FIXME("format type 0x%x not implemented\n", pFormat[0]);
        RpcRaiseException(RPC_X_BAD_STUB_DATA);
        return NULL;
    }
}

static inline unsigned char *call_unmarshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
{
    NDR_UNMARSHALL m = NdrUnmarshaller[pFormat[0] & NDR_TABLE_MASK];
    if (m) return m(pStubMsg, ppMemory, pFormat, fMustAlloc);
    else
    {
        FIXME("format type 0x%x not implemented\n", pFormat[0]);
        RpcRaiseException(RPC_X_BAD_STUB_DATA);
        return NULL;
    }
}

static inline void call_freer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
{
    NDR_FREE m = NdrFreer[pFormat[0] & NDR_TABLE_MASK];
    if (m) m(pStubMsg, pMemory, pFormat);
}

#define STUBLESS_UNMARSHAL  1
#define STUBLESS_INITOUT    2
#define STUBLESS_CALLSERVER 3
#define STUBLESS_CALCSIZE   4
#define STUBLESS_GETBUFFER  5
#define STUBLESS_MARSHAL    6
#define STUBLESS_FREE       7

void WINAPI NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage)
{
#if 0 /* these functions are not defined yet */
    pMessage->pfnAllocate = NdrRpcSmClientAllocate;
    pMessage->pfnFree = NdrRpcSmClientFree;
#endif
}

static void dump_RPC_FC_PROC_PF(PARAM_ATTRIBUTES param_attributes)
{
    if (param_attributes.MustSize) TRACE(" MustSize");
    if (param_attributes.MustFree) TRACE(" MustFree");
    if (param_attributes.IsPipe) TRACE(" IsPipe");
    if (param_attributes.IsIn) TRACE(" IsIn");
    if (param_attributes.IsOut) TRACE(" IsOut");
    if (param_attributes.IsReturn) TRACE(" IsReturn");
    if (param_attributes.IsBasetype) TRACE(" IsBasetype");
    if (param_attributes.IsByValue) TRACE(" IsByValue");
    if (param_attributes.IsSimpleRef) TRACE(" IsSimpleRef");
    if (param_attributes.IsDontCallFreeInst) TRACE(" IsDontCallFreeInst");
    if (param_attributes.SaveForAsyncFinish) TRACE(" SaveForAsyncFinish");
    if (param_attributes.ServerAllocSize) TRACE(" ServerAllocSize = %d", param_attributes.ServerAllocSize * 8);
}

static void dump_INTERPRETER_OPT_FLAGS(INTERPRETER_OPT_FLAGS Oi2Flags)
{
    if (Oi2Flags.ServerMustSize) TRACE(" ServerMustSize");
    if (Oi2Flags.ClientMustSize) TRACE(" ClientMustSize");
    if (Oi2Flags.HasReturn) TRACE(" HasReturn");
    if (Oi2Flags.HasPipes) TRACE(" HasPipes");
    if (Oi2Flags.Unused) TRACE(" Unused");
    if (Oi2Flags.HasAsyncUuid) TRACE(" HasAsyncUuid");
    if (Oi2Flags.HasExtensions) TRACE(" HasExtensions");
    if (Oi2Flags.HasAsyncHandle) TRACE(" HasAsyncHandle");
    TRACE("\n");
}

#define ARG_FROM_OFFSET(args, offset) ((args) + (offset))

static PFORMAT_STRING client_get_handle(
    PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader,
    PFORMAT_STRING pFormat, handle_t *phBinding)
{
    /* binding */
    switch (pProcHeader->handle_type)
    {
    /* explicit binding: parse additional section */
    case RPC_FC_BIND_EXPLICIT:
        switch (*pFormat) /* handle_type */
        {
        case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */
            {
                const NDR_EHD_PRIMITIVE *pDesc = (const NDR_EHD_PRIMITIVE *)pFormat;

                TRACE("Explicit primitive handle @ %d\n", pDesc->offset);

                if (pDesc->flag) /* pointer to binding */
                    *phBinding = **(handle_t **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                else
                    *phBinding = *(handle_t *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                return pFormat + sizeof(NDR_EHD_PRIMITIVE);
            }
        case RPC_FC_BIND_GENERIC: /* explicit generic */
            {
                const NDR_EHD_GENERIC *pDesc = (const NDR_EHD_GENERIC *)pFormat;
                void *pObject = NULL;
                void *pArg;
                const GENERIC_BINDING_ROUTINE_PAIR *pGenPair;

                TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index);

                if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
                    pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                else
                    pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
                pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
                *phBinding = pGenPair->pfnBind(pObject);
                return pFormat + sizeof(NDR_EHD_GENERIC);
            }
        case RPC_FC_BIND_CONTEXT: /* explicit context */
            {
                const NDR_EHD_CONTEXT *pDesc = (const NDR_EHD_CONTEXT *)pFormat;
                NDR_CCONTEXT context_handle;
                TRACE("Explicit bind context\n");
                if (pDesc->flags & HANDLE_PARAM_IS_VIA_PTR)
                {
                    TRACE("\tHANDLE_PARAM_IS_VIA_PTR\n");
                    context_handle = **(NDR_CCONTEXT **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                }
                else
                    context_handle = *(NDR_CCONTEXT *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                if ((pDesc->flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL) &&
                    !context_handle)
                {
                    ERR("null context handle isn't allowed\n");
                    RpcRaiseException(RPC_X_SS_IN_NULL_CONTEXT);
                    return NULL;
                }
                *phBinding = NDRCContextBinding(context_handle);
                /* FIXME: should we store this structure in stubMsg.pContext? */
                return pFormat + sizeof(NDR_EHD_CONTEXT);
            }
        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 */
        FIXME("RPC_FC_BIND_GENERIC\n");
        RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */
        break;
    case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */
        TRACE("Implicit primitive handle\n");
        *phBinding = *pStubMsg->StubDesc->IMPLICIT_HANDLE_INFO.pPrimitiveHandle;
        break;
    case RPC_FC_CALLBACK_HANDLE: /* implicit callback */
        FIXME("RPC_FC_CALLBACK_HANDLE\n");
        break;
    case RPC_FC_AUTO_HANDLE: /* implicit auto handle */
        /* strictly speaking, it isn't necessary to set hBinding here
         * since it isn't actually used (hence the automatic in its name),
         * but then why does MIDL generate a valid entry in the
         * MIDL_STUB_DESC for it? */
        TRACE("Implicit auto handle\n");
        *phBinding = *pStubMsg->StubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle;
        break;
    default:
        ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
        RpcRaiseException(RPC_X_BAD_STUB_DATA);
    }
    return pFormat;
}

static void client_free_handle(
    PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader,
    PFORMAT_STRING pFormat, handle_t hBinding)
{
    /* binding */
    switch (pProcHeader->handle_type)
    {
    /* explicit binding: parse additional section */
    case RPC_FC_BIND_EXPLICIT:
        switch (*pFormat) /* handle_type */
        {
        case RPC_FC_BIND_GENERIC: /* explicit generic */
            {
                const NDR_EHD_GENERIC *pDesc = (const NDR_EHD_GENERIC *)pFormat;
                void *pObject = NULL;
                void *pArg;
                const GENERIC_BINDING_ROUTINE_PAIR *pGenPair;

                TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index);

                if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
                    pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                else
                    pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
                pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
                pGenPair->pfnUnbind(pObject, hBinding);
                break;
            }
        case RPC_FC_BIND_CONTEXT: /* explicit context */
        case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */
            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 */
        FIXME("RPC_FC_BIND_GENERIC\n");
        RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */
        break;
    case RPC_FC_CALLBACK_HANDLE: /* implicit callback */
    case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */
    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);
    }
}

static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
    int phase, unsigned char *args, unsigned short number_of_params,
    unsigned char *pRetVal)
{
    /* current format string offset */
    int current_offset = 0;
    /* current stack offset */
    unsigned short current_stack_offset = 0;
    /* counter */
    unsigned short i;

    for (i = 0; i < number_of_params; i++)
    {
        const NDR_PARAM_OIF_BASETYPE *pParam =
            (const NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset];
        unsigned char * pArg;

        current_stack_offset = pParam->stack_offset;
        pArg = ARG_FROM_OFFSET(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: 0x%x\n", current_stack_offset);
        TRACE("\tmemory addr (before): %p\n", pArg);

        if (pParam->param_attributes.IsBasetype)
        {
            const unsigned char * pTypeFormat =
                &pParam->type_format_char;

            if (pParam->param_attributes.IsSimpleRef)
                pArg = *(unsigned char **)pArg;

            TRACE("\tbase type: 0x%02x\n", *pTypeFormat);

            switch (phase)
            {
            case PROXY_CALCSIZE:
                if (pParam->param_attributes.IsIn)
                    call_buffer_sizer(pStubMsg, pArg, pTypeFormat);
                break;
            case PROXY_MARSHAL:
                if (pParam->param_attributes.IsIn)
                    call_marshaller(pStubMsg, pArg, pTypeFormat);
                break;
            case PROXY_UNMARSHAL:
                if (pParam->param_attributes.IsOut)
                {
                    if (pParam->param_attributes.IsReturn)
                        call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0);
                    else
                        call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
                    TRACE("pRetVal = %p\n", pRetVal);
                }
                break;
            default:
                RpcRaiseException(RPC_S_INTERNAL_ERROR);
            }

            current_offset += sizeof(NDR_PARAM_OIF_BASETYPE);
        }
        else
        {
            const NDR_PARAM_OIF_OTHER *pParamOther =
                (const NDR_PARAM_OIF_OTHER *)&pFormat[current_offset];

            const unsigned char * pTypeFormat =
                &(pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]);

            /* 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(pStubMsg, pArg, pTypeFormat);
                    else
                        call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                }
                break;
            case PROXY_MARSHAL:
                if (pParam->param_attributes.IsIn)
                {
                    if (pParam->param_attributes.IsByValue)
                        call_marshaller(pStubMsg, pArg, pTypeFormat);
                    else
                        call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                }
                break;
            case PROXY_UNMARSHAL:
                if (pParam->param_attributes.IsOut)
                {
                    if (pParam->param_attributes.IsReturn)
                        call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0);
                    else if (pParam->param_attributes.IsByValue)
                        call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
                    else
                        call_unmarshaller(pStubMsg, (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);
    }
}

static unsigned int type_stack_size(unsigned char fc)
{
    switch (fc)
    {
    case RPC_FC_BYTE:
    case RPC_FC_CHAR:
    case RPC_FC_SMALL:
    case RPC_FC_USMALL:
        return sizeof(char);
    case RPC_FC_WCHAR:
    case RPC_FC_SHORT:
    case RPC_FC_USHORT:
        return sizeof(short);
    case RPC_FC_LONG:
    case RPC_FC_ULONG:
    case RPC_FC_ENUM16:
    case RPC_FC_ENUM32:
        return sizeof(int);
    case RPC_FC_FLOAT:
        return sizeof(float);
    case RPC_FC_DOUBLE:
        return sizeof(double);
    case RPC_FC_HYPER:
        return sizeof(ULONGLONG);
    case RPC_FC_ERROR_STATUS_T:
        return sizeof(error_status_t);
    case RPC_FC_IGNORE:
        return sizeof(void *);
    default:
        ERR("invalid base type 0x%x\n", fc);
        RpcRaiseException(RPC_S_INTERNAL_ERROR);
    }
}

void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
    PFORMAT_STRING pFormat, int phase, unsigned char *args,
    unsigned short stack_size,
    unsigned char *pRetVal, BOOL object_proc, BOOL ignore_retval)
{
    /* current format string offset */
    int current_offset = 0;
    /* current stack offset */
    unsigned short current_stack_offset = 0;
    /* counter */
    unsigned short i;

    /* NOTE: V1 style format doesn'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(args, 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 (!ignore_retval &&
                    pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
                {
                    if (pParam->param_direction & RPC_FC_RETURN_PARAM)
                        call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0);
                    else
                        call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
                }
                break;
            default:
                RpcRaiseException(RPC_S_INTERNAL_ERROR);
            }

            current_stack_offset += type_stack_size(*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;
    /* correlation cache */
    ULONG_PTR NdrCorrCache[256];
    __ms_va_list args;

    TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat);

    TRACE("NDR Version: 0x%x\n", pStubDesc->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 */
    __ms_va_start( args, pFormat );
    stubMsg.StackTop = va_arg( args, unsigned char * );
    __ms_va_end( args );

    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 */
        NdrCorrelationInitialize(&stubMsg, NdrCorrCache, sizeof(NdrCorrCache), 0);
    }

    /* 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
     */
    if ((pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) ||
        (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_HAS_COMM_OR_FAULT))
    {
        __TRY
        {
            for (phase = PROXY_CALCSIZE; phase <= PROXY_UNMARSHAL; phase++)
            {
                TRACE("phase = %d\n", phase);
                switch (phase)
                {
                case PROXY_GETBUFFER:
                    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
                    {
                        /* allocate the buffer */
                        NdrProxyGetBuffer(This, &stubMsg);
                    }
                    else
                    {
                        /* allocate the buffer */
                        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:
                    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
                    {
                        /* send the [in] params and receive the [out] and [retval]
                         * params */
                        NdrProxySendReceive(This, &stubMsg);
                    }
                    else
                    {
                        /* send the [in] params and receive the [out] and [retval]
                         * params */
                        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, stubMsg.StackTop,
                            number_of_params, (unsigned char *)&RetVal);
                    else
                        client_do_args_old_format(&stubMsg, pFormat, phase,
                            stubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
                            (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE);
                    break;
                default:
                    ERR("shouldn't reach here. phase %d\n", phase);
                    break;
                }
            }
        }
        __EXCEPT_ALL
        {
            if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
                RetVal = NdrProxyErrorHandler(GetExceptionCode());
            else
            {
                const COMM_FAULT_OFFSETS *comm_fault_offsets = &pStubDesc->CommFaultOffsets[procedure_number];
                ULONG *comm_status;
                ULONG *fault_status;

                TRACE("comm_fault_offsets = {0x%hx, 0x%hx}\n", comm_fault_offsets->CommOffset, comm_fault_offsets->FaultOffset);

                if (comm_fault_offsets->CommOffset == -1)
                    comm_status = (ULONG *)&RetVal;
                else if (comm_fault_offsets->CommOffset >= 0)
                    comm_status = *(ULONG **)ARG_FROM_OFFSET(stubMsg.StackTop, comm_fault_offsets->CommOffset);
                else
                    comm_status = NULL;

                if (comm_fault_offsets->FaultOffset == -1)
                    fault_status = (ULONG *)&RetVal;
                else if (comm_fault_offsets->FaultOffset >= 0)
                    fault_status = *(ULONG **)ARG_FROM_OFFSET(stubMsg.StackTop, comm_fault_offsets->CommOffset);
                else
                    fault_status = NULL;

                NdrMapCommAndFaultStatus(&stubMsg, comm_status, fault_status,
                                         GetExceptionCode());
            }
        }
        __ENDTRY
    }
    else
    {
        /* 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 (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 (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, stubMsg.StackTop,
                        number_of_params, (unsigned char *)&RetVal);
                else
                    client_do_args_old_format(&stubMsg, pFormat, phase,
                        stubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
                        (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE);
                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);
    else
    {
        NdrFreeBuffer(&stubMsg);
        client_free_handle(&stubMsg, pProcHeader, pHandleFormat, hBinding);
    }

    TRACE("RetVal = 0x%lx\n", RetVal);

    return RetVal;
}

/* Calls a function with the specified 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"
    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
    __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
    "movl %esp,%ebp\n\t"
    __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
    "pushl %edi\n\t"            /* Save registers */
    __ASM_CFI(".cfi_rel_offset %edi,-4\n\t")
    "pushl %esi\n\t"
    __ASM_CFI(".cfi_rel_offset %esi,-8\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 */
    __ASM_CFI(".cfi_same_value %esi\n\t")
    "popl %edi\n\t"
    __ASM_CFI(".cfi_same_value %edi\n\t")
    "popl %ebp\n\t"
    __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
    __ASM_CFI(".cfi_same_value %ebp\n\t")
    "ret" )
#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

static 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;
    case RPC_FC_BOGUS_ARRAY:
        pFormat = ComputeConformance(pStubMsg, NULL, pFormat + 4, *(const WORD*)&pFormat[2]);
        TRACE("conformance = %ld\n", pStubMsg->MaxCount);
        pFormat = ComputeVariance(pStubMsg, NULL, pFormat, pStubMsg->MaxCount);
        size = ComplexStructSize(pStubMsg, pFormat);
        size *= pStubMsg->MaxCount;
        break;
    case RPC_FC_C_CSTRING:
    case RPC_FC_C_WSTRING:
        if (*pFormat == RPC_FC_C_CSTRING)
            size = sizeof(CHAR);
        else
            size = sizeof(WCHAR);
        if (pFormat[1] == RPC_FC_STRING_SIZED)
            ComputeConformance(pStubMsg, NULL, pFormat + 2, 0);
        else
            pStubMsg->MaxCount = 0;
        size *= pStubMsg->MaxCount;
        break;
    default:
        FIXME("Unhandled type %02x\n", *pFormat);
        /* fallthrough */
    case RPC_FC_RP:
        size = sizeof(void *);
        break;
    }
    return size;
}

static LONG_PTR *stub_do_args(MIDL_STUB_MESSAGE *pStubMsg,
                              PFORMAT_STRING pFormat, int phase,
                              unsigned char *args,
                              unsigned short number_of_params)
{
    /* counter */
    unsigned short i;
    /* current format string offset */
    int current_offset = 0;
    /* current stack offset */
    unsigned short current_stack_offset = 0;
    /* location to put retval into */
    LONG_PTR *retval_ptr = NULL;

    for (i = 0; i < number_of_params; i++)
    {
        const NDR_PARAM_OIF_BASETYPE *pParam =
        (const NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset];
        unsigned char *pArg;

        current_stack_offset = pParam->stack_offset;
        pArg = 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: 0x%x\n", current_stack_offset);
        TRACE("\tmemory addr (before): %p -> %p\n", pArg, *(unsigned char **)pArg);

        if (pParam->param_attributes.IsBasetype)
        {
            const unsigned char *pTypeFormat =
            &pParam->type_format_char;

            TRACE("\tbase type: 0x%02x\n", *pTypeFormat);

            /* make a note of the address of the return value parameter for later */
            if (pParam->param_attributes.IsReturn)
                retval_ptr = (LONG_PTR *)pArg;

            switch (phase)
            {
                case STUBLESS_MARSHAL:
                    if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
                    {
                        if (pParam->param_attributes.IsSimpleRef)
                            call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                        else
                            call_marshaller(pStubMsg, pArg, pTypeFormat);
                    }
                    break;
                case STUBLESS_FREE:
                    if (pParam->param_attributes.ServerAllocSize)
                        HeapFree(GetProcessHeap(), 0, *(void **)pArg);
                    break;
                case STUBLESS_INITOUT:
                    break;
                case STUBLESS_UNMARSHAL:
                    if (pParam->param_attributes.ServerAllocSize)
                        *(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                                   pParam->param_attributes.ServerAllocSize * 8);

                    if (pParam->param_attributes.IsIn)
                    {
                        if (pParam->param_attributes.IsSimpleRef)
                            call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
                        else
                            call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
                    }
                    break;
                case STUBLESS_CALCSIZE:
                    if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
                    {
                        if (pParam->param_attributes.IsSimpleRef)
                            call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                        else
                            call_buffer_sizer(pStubMsg, pArg, pTypeFormat);
                    }
                    break;
                default:
                    RpcRaiseException(RPC_S_INTERNAL_ERROR);
            }

            current_offset += sizeof(NDR_PARAM_OIF_BASETYPE);
        }
        else
        {
            const NDR_PARAM_OIF_OTHER *pParamOther =
            (const NDR_PARAM_OIF_OTHER *)&pFormat[current_offset];

            const unsigned char * pTypeFormat =
                &(pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]);

            TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);

            switch (phase)
            {
                case STUBLESS_MARSHAL:
                    if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
                    {
                        if (pParam->param_attributes.IsByValue)
                            call_marshaller(pStubMsg, pArg, pTypeFormat);
                        else
                            call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                    }
                    break;
                case STUBLESS_FREE:
                    if (pParam->param_attributes.MustFree)
                    {
                        if (pParam->param_attributes.IsByValue)
                            call_freer(pStubMsg, pArg, pTypeFormat);
                        else
                            call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                    }

                    if (pParam->param_attributes.IsOut &&
                        !pParam->param_attributes.IsIn &&
                        !pParam->param_attributes.IsByValue &&
                        !pParam->param_attributes.ServerAllocSize)
                    {
                        if (*pTypeFormat != RPC_FC_BIND_CONTEXT)
                            pStubMsg->pfnFree(*(void **)pArg);
                    }

                    if (pParam->param_attributes.ServerAllocSize)
                        HeapFree(GetProcessHeap(), 0, *(void **)pArg);
                    break;
                case STUBLESS_INITOUT:
                    if (!pParam->param_attributes.IsIn &&
                             pParam->param_attributes.IsOut &&
                             !pParam->param_attributes.ServerAllocSize &&
                             !pParam->param_attributes.IsByValue)
                    {
                        if (*pTypeFormat == RPC_FC_BIND_CONTEXT)
                        {
                            NDR_SCONTEXT ctxt = NdrContextHandleInitialize(
                                pStubMsg, pTypeFormat);
                            *(void **)pArg = NDRSContextValue(ctxt);
                        }
                        else
                        {
                            DWORD size = calc_arg_size(pStubMsg, pTypeFormat);

                            if(size)
                            {
                                *(void **)pArg = NdrAllocate(pStubMsg, size);
                                memset(*(void **)pArg, 0, size);
                            }
                        }
                    }
                    break;
                case STUBLESS_UNMARSHAL:
                    if (pParam->param_attributes.ServerAllocSize)
                        *(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                                   pParam->param_attributes.ServerAllocSize * 8);

                    if (pParam->param_attributes.IsIn)
                    {
                        if (pParam->param_attributes.IsByValue)
                            call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
                        else
                            call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
                    }
                    break;
                case STUBLESS_CALCSIZE:
                    if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
                    {
                        if (pParam->param_attributes.IsByValue)
                            call_buffer_sizer(pStubMsg, pArg, pTypeFormat);
                        else
                            call_buffer_sizer(pStubMsg, *(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);
    }

    return retval_ptr;
}

static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg,
                                  PFORMAT_STRING pFormat, int phase,
                                  unsigned char *args,
                                  unsigned short stack_size, BOOL object)
{
    /* counter */
    unsigned short i;
    /* current format string offset */
    int current_offset = 0;
    /* current stack offset */
    unsigned short current_stack_offset = 0;
    /* location to put retval into */
    LONG_PTR *retval_ptr = NULL;

    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 ? sizeof(void *) : 0);
        unsigned char *pArg = args + 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);

        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);

            if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
                retval_ptr = (LONG_PTR *)pArg;

            switch (phase)
            {
                case STUBLESS_MARSHAL:
                    if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
                        call_marshaller(pStubMsg, pArg, pTypeFormat);
                    break;
                case STUBLESS_FREE:
                    if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
                        call_freer(pStubMsg, pArg, pTypeFormat);
                    break;
                case STUBLESS_INITOUT:
                    break;
                case STUBLESS_UNMARSHAL:
                    if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
                        call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
                    break;
                case STUBLESS_CALCSIZE:
                    if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
                        call_buffer_sizer(pStubMsg, pArg, pTypeFormat);
                    break;
                default:
                    RpcRaiseException(RPC_S_INTERNAL_ERROR);
            }

            current_stack_offset += type_stack_size(*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);

            if (pParam->param_direction == RPC_FC_RETURN_PARAM)
                retval_ptr = (LONG_PTR *)pArg;

            switch (phase)
            {
                case STUBLESS_MARSHAL:
                    if (pParam->param_direction == RPC_FC_OUT_PARAM ||
                        pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
                        pParam->param_direction == RPC_FC_RETURN_PARAM)
                        call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                    break;
                case STUBLESS_FREE:
                    if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
                        pParam->param_direction == RPC_FC_IN_PARAM)
                        call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                    else if (pParam->param_direction == RPC_FC_OUT_PARAM)
                        pStubMsg->pfnFree(*(void **)pArg);
                    break;
                case STUBLESS_INITOUT:
                    if (pParam->param_direction == RPC_FC_OUT_PARAM)
                    {
                        DWORD size = calc_arg_size(pStubMsg, pTypeFormat);

                        if(size)
                        {
                            *(void **)pArg = NdrAllocate(pStubMsg, size);
                            memset(*(void **)pArg, 0, size);
                        }
                    }
                    break;
                case STUBLESS_UNMARSHAL:
                    if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
                        pParam->param_direction == RPC_FC_IN_PARAM)
                        call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
                    break;
                case STUBLESS_CALCSIZE:
                    if (pParam->param_direction == RPC_FC_OUT_PARAM ||
                        pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
                        pParam->param_direction == RPC_FC_RETURN_PARAM)
                        call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
                    break;
                default:
                    RpcRaiseException(RPC_S_INTERNAL_ERROR);
            }

            current_stack_offset += pParamOther->stack_size * sizeof(INT);
            current_offset += sizeof(NDR_PARAM_OI_OTHER);
        }
    }

    return retval_ptr;
}

/***********************************************************************
 *            NdrStubCall2 [RPCRT4.@]
 *
 * Unmarshals [in] parameters, calls either a method in an object or a server
 * function, marshals any [out] parameters and frees any allocated data.
 *
 * NOTES
 *  Used by stubless MIDL-generated code.
 */
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;
    /* 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;
    /* 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];

    TRACE("NDR Version: 0x%x\n", pStubDesc->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;
        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);

    /* create the full pointer translation tables, if requested */
    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
        stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER);

    /* 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;

    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
            {
                RPC_STATUS Status;

                pRpcMsg->BufferLength = stubMsg.BufferLength;
                /* allocate buffer for [out] and [ret] params */
                Status = I_RpcGetBuffer(pRpcMsg); 
                if (Status)
                    RpcRaiseException(Status);
                stubMsg.Buffer = pRpcMsg->Buffer;
            }
            break;
        case STUBLESS_UNMARSHAL:
        case STUBLESS_INITOUT:
        case STUBLESS_CALCSIZE:
        case STUBLESS_MARSHAL:
        case STUBLESS_FREE:
            if (bV2Format)
                retval_ptr = stub_do_args(&stubMsg, &pFormat[parameter_start_offset],
                                          phase, args, number_of_params);
            else
                retval_ptr = stub_do_old_args(&stubMsg, &pFormat[parameter_start_offset],
                                              phase, args, stack_size,
                                              (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT));

            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.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 server function stack */
    HeapFree(GetProcessHeap(), 0, args);

    return S_OK;
}

/***********************************************************************
 *            NdrServerCall2 [RPCRT4.@]
 */
void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg)
{
    DWORD dwPhase;
    NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase);
}

struct async_call_data
{
    MIDL_STUB_MESSAGE *pStubMsg;
    const NDR_PROC_HEADER *pProcHeader;
    PFORMAT_STRING pHandleFormat;
    PFORMAT_STRING pParamFormat;
    RPC_BINDING_HANDLE hBinding;
    /* size of stack */
    unsigned short stack_size;
    /* number of parameters. optional for client to give it to us */
    unsigned char number_of_params;
    /* correlation cache */
    ULONG_PTR NdrCorrCache[256];
};

LONG_PTR WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc,
  PFORMAT_STRING pFormat, ...)
{
    /* pointer to start of stack where arguments start */
    PRPC_MESSAGE pRpcMsg;
    PMIDL_STUB_MESSAGE pStubMsg;
    RPC_ASYNC_STATE *pAsync;
    struct async_call_data *async_call_data;
    /* procedure number */
    unsigned short procedure_number;
    /* 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;
    __ms_va_list args;

    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);
    }

    async_call_data = I_RpcAllocate(sizeof(*async_call_data) + sizeof(MIDL_STUB_MESSAGE) + sizeof(RPC_MESSAGE));
    if (!async_call_data) RpcRaiseException(ERROR_OUTOFMEMORY);
    async_call_data->number_of_params = ~0;
    async_call_data->pProcHeader = pProcHeader;

    async_call_data->pStubMsg = pStubMsg = (PMIDL_STUB_MESSAGE)(async_call_data + 1);
    pRpcMsg = (PRPC_MESSAGE)(pStubMsg + 1);

    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
    {
        const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0];
        async_call_data->stack_size = pProcHeader->stack_size;
        procedure_number = pProcHeader->proc_num;
        pFormat += sizeof(NDR_PROC_HEADER_RPC);
    }
    else
    {
        async_call_data->stack_size = pProcHeader->stack_size;
        procedure_number = pProcHeader->proc_num;
        pFormat += sizeof(NDR_PROC_HEADER);
    }
    TRACE("stack size: 0x%x\n", async_call_data->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)
        pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT);

    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
    {
        ERR("objects not supported\n");
        I_RpcFree(async_call_data);
        RpcRaiseException(RPC_X_BAD_STUB_DATA);
    }

    NdrClientInitializeNew(pRpcMsg, pStubMsg, 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 */
    pStubMsg->StackTop = I_RpcAllocate(async_call_data->stack_size);
    __ms_va_start( args, pFormat );
    memcpy(pStubMsg->StackTop, va_arg( args, unsigned char * ), async_call_data->stack_size);
    __ms_va_end( args );

    pAsync = *(RPC_ASYNC_STATE **)pStubMsg->StackTop;
    pAsync->StubInfo = async_call_data;
    async_call_data->pHandleFormat = pFormat;

    pFormat = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, &async_call_data->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;
        async_call_data->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;
    }

    async_call_data->pParamFormat = pFormat;

    pStubMsg->BufferLength = 0;

    /* 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)
        NdrRpcSmSetClientToOsf(pStubMsg);

    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 */
        NdrCorrelationInitialize(pStubMsg, async_call_data->NdrCorrCache, sizeof(async_call_data->NdrCorrCache), 0);
    }

    /* 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 buffer
     * Then in NdrpCompleteAsyncClientCall:
     * 1. PROXY_SENDRECEIVE - receive buffer
     * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer
     */
    for (phase = PROXY_CALCSIZE; phase <= PROXY_SENDRECEIVE; phase++)
    {
        RPC_STATUS status;
        TRACE("phase = %d\n", phase);
        switch (phase)
        {
        case PROXY_GETBUFFER:
            /* allocate the buffer */
            if (Oif_flags.HasPipes)
                /* NdrGetPipeBuffer(...) */
                FIXME("pipes not supported yet\n");
            else
            {
                if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
#if 0
                    NdrNsGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding);
#else
                    FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n");
#endif
                else
                    NdrGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding);
            }
            pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
            status = I_RpcAsyncSetHandle(pRpcMsg, pAsync);
            if (status != RPC_S_OK)
                RpcRaiseException(status);
            break;
        case PROXY_SENDRECEIVE:
            pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
            /* send the [in] params only */
            if (Oif_flags.HasPipes)
                /* NdrPipesSend(...) */
                FIXME("pipes not supported yet\n");
            else
            {
                if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
#if 0
                    NdrNsSend(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
#else
                    FIXME("using auto handle - call NdrNsSend when it gets implemented\n");
#endif
                else
                {
                    pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
                    status = I_RpcSend(pStubMsg->RpcMsg);
                    if (status != RPC_S_OK)
                        RpcRaiseException(status);
                }
            }

            break;
        case PROXY_CALCSIZE:
        case PROXY_MARSHAL:
            if (bV2Format)
                client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop,
                    async_call_data->number_of_params, NULL);
            else
                client_do_args_old_format(pStubMsg, pFormat, phase,
                    pStubMsg->StackTop, async_call_data->stack_size, NULL,
                    (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE);
            break;
        default:
            ERR("shouldn't reach here. phase %d\n", phase);
            break;
        }
    }

    TRACE("returning 0\n");
    return 0;
}

RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply)
{
    /* pointer to start of stack where arguments start */
    PMIDL_STUB_MESSAGE pStubMsg;
    struct async_call_data *async_call_data;
    /* the type of pass we are currently doing */
    int phase;
    /* header for procedure string */
    const NDR_PROC_HEADER * pProcHeader;
    /* -Oif or -Oicf generated format */
    BOOL bV2Format;
    RPC_STATUS status = RPC_S_OK;

    if (!pAsync->StubInfo)
        return RPC_S_INVALID_ASYNC_HANDLE;

    async_call_data = pAsync->StubInfo;
    pStubMsg = async_call_data->pStubMsg;
    pProcHeader = async_call_data->pProcHeader;

    bV2Format = (pStubMsg->StubDesc->Version >= 0x20000);

    /* 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 buffer
     * Then in NdrpCompleteAsyncClientCall:
     * 1. PROXY_SENDRECEIVE - receive buffer
     * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer
     */
    for (phase = PROXY_SENDRECEIVE; phase <= PROXY_UNMARSHAL; phase++)
    {
        switch (phase)
        {
        case PROXY_SENDRECEIVE:
            pStubMsg->RpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
            /* receive the [out] params */
            if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
#if 0
                NdrNsReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
#else
                FIXME("using auto handle - call NdrNsReceive when it gets implemented\n");
#endif
            else
            {
                status = I_RpcReceive(pStubMsg->RpcMsg);
                if (status != RPC_S_OK)
                    goto cleanup;
                pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
                pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
                pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
                pStubMsg->Buffer = pStubMsg->BufferStart;
            }

            /* convert strings, floating point values and endianess into our
             * preferred format */
#if 0
            if ((pStubMsg->RpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)
                NdrConvert(pStubMsg, pFormat);
#endif

            break;
        case PROXY_UNMARSHAL:
            if (bV2Format)
                client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop,
                    async_call_data->number_of_params, Reply);
            else
                client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase,
                    pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE);
            break;
        default:
            ERR("shouldn't reach here. phase %d\n", phase);
            break;
        }
    }

cleanup:
    if (pStubMsg->fHasNewCorrDesc)
    {
        /* free extra correlation package */
        NdrCorrelationFree(pStubMsg);
    }

    /* free the full pointer translation tables */
    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
        NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);

    /* free marshalling buffer */
    NdrFreeBuffer(pStubMsg);
    client_free_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, async_call_data->hBinding);

    I_RpcFree(pStubMsg->StackTop);
    I_RpcFree(async_call_data);

    TRACE("-- 0x%x\n", status);
    return status;
}

RPCRTAPI LONG RPC_ENTRY NdrAsyncStubCall(struct IRpcStubBuffer* pThis,
    struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg,
    DWORD * pdwStubPhase)
{
    FIXME("unimplemented, expect crash!\n");
    return 0;
}
