/*
 * 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 */
    unsigned long NdrCorrCache[256];

    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 */
#ifdef __i386__
    stubMsg.StackTop = *(unsigned char **)(&pFormat+1);
#else
# warning Stack not retrieved for your CPU architecture
#endif

    pHandleFormat = pFormat;

    /* we only need a handle if this isn't an object method */
    if (!(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT))
    {
        pFormat = client_get_handle(&stubMsg, pProcHeader, pHandleFormat, &hBinding);
        if (!pFormat) return 0;
    }

    bV2Format = (pStubDesc->Version >= 0x20000);

    if (bV2Format)
    {
        const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader =
            (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat;

        Oif_flags = pOIFHeader->Oi2Flags;
        number_of_params = pOIFHeader->number_of_params;

        pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
    }

    TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags);

    if (Oif_flags.HasExtensions)
    {
        const NDR_PROC_HEADER_EXTS *pExtensions =
            (const NDR_PROC_HEADER_EXTS *)pFormat;
        ext_flags = pExtensions->Flags2;
        pFormat += pExtensions->Size;
    }

    stubMsg.BufferLength = 0;

    /* store the RPC flags away */
    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
        rpcMsg.RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags;

    /* use alternate memory allocation routines */
    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC)
        NdrRpcSmSetClientToOsf(&stubMsg);

    if (Oif_flags.HasPipes)
    {
        FIXME("pipes not supported yet\n");
        RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
        /* init pipes package */
        /* NdrPipesInitialize(...) */
    }
    if (ext_flags.HasNewCorrDesc)
    {
        /* initialize extra correlation package */
        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)
    {
        __TRY
        {
            for (phase = PROXY_CALCSIZE; phase <= PROXY_UNMARSHAL; phase++)
            {
                TRACE("phase = %d\n", phase);
                switch (phase)
                {
                case PROXY_GETBUFFER:
                    /* allocate the buffer */
                    NdrProxyGetBuffer(This, &stubMsg);
                    break;
                case PROXY_SENDRECEIVE:
                    /* send the [in] params and receive the [out] and [retval]
                     * params */
                    NdrProxySendReceive(This, &stubMsg);

                    /* 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
        {
            RetVal = NdrProxyErrorHandler(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;
    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)
                    {
                        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)
                    {
                        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_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);

    /* 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
            {
                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 */
    unsigned long 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;

    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 */
#ifdef __i386__
    pStubMsg->StackTop = I_RpcAllocate(async_call_data->stack_size);
    /* FIXME: this may read one more DWORD than is necessary, but it shouldn't hurt */
    memcpy(pStubMsg->StackTop, *(unsigned char **)(&pFormat+1), async_call_data->stack_size);
#else
# warning Stack not retrieved for your CPU architecture
#endif

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