/*
 * NDR data marshalling
 *
 * Copyright 2006 Mike McCormack (for CodeWeavers)
 * Copyright 2006-2007 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
 */

#include "ndr_misc.h"
#include "rpc_assoc.h"
#include "rpcndr.h"

#include "wine/rpcfc.h"

#include "wine/debug.h"
#include "wine/list.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

#define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e

typedef struct ndr_context_handle
{
    ULONG      attributes;
    GUID       uuid;
} ndr_context_handle;

struct context_handle_entry
{
    struct list entry;
    DWORD magic;
    RPC_BINDING_HANDLE handle;
    ndr_context_handle wire_data;
};

static struct list context_handle_list = LIST_INIT(context_handle_list);

static CRITICAL_SECTION ndr_context_cs;
static CRITICAL_SECTION_DEBUG ndr_context_debug =
{
    0, 0, &ndr_context_cs,
    { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
};
static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };

static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
{
    struct context_handle_entry *che = CContext;

    if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
        return NULL;
    return che;
}

static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
{
    struct context_handle_entry *che;
    LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
        if (IsEqualGUID(&che->wire_data.uuid, uuid))
            return che;
    return NULL;
}

RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
{
    struct context_handle_entry *che;
    RPC_BINDING_HANDLE handle = NULL;

    TRACE("%p\n", CContext);

    EnterCriticalSection(&ndr_context_cs);
    che = get_context_entry(CContext);
    if (che)
        handle = che->handle;
    LeaveCriticalSection(&ndr_context_cs);

    if (!handle)
    {
        ERR("invalid handle %p\n", CContext);
        RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
    }
    return handle;
}

void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
{
    struct context_handle_entry *che;

    TRACE("%p %p\n", CContext, pBuff);

    if (CContext)
    {
        EnterCriticalSection(&ndr_context_cs);
        che = get_context_entry(CContext);
        memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
        LeaveCriticalSection(&ndr_context_cs);
    }
    else
    {
        ndr_context_handle *wire_data = pBuff;
        wire_data->attributes = 0;
        wire_data->uuid = GUID_NULL;
    }
}

/***********************************************************************
 *           RpcSmDestroyClientContext [RPCRT4.@]
 */
RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
{
    RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
    struct context_handle_entry *che = NULL;

    TRACE("(%p)\n", ContextHandle);

    EnterCriticalSection(&ndr_context_cs);
    che = get_context_entry(*ContextHandle);
    *ContextHandle = NULL;
    if (che)
    {
        status = RPC_S_OK;
        list_remove(&che->entry);
    }

    LeaveCriticalSection(&ndr_context_cs);

    if (che)
    {
        RpcBindingFree(&che->handle);
        HeapFree(GetProcessHeap(), 0, che);
    }

    return status;
}

/***********************************************************************
 *           RpcSsDestroyClientContext [RPCRT4.@]
 */
void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
{
    RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
    if (status != RPC_S_OK)
        RpcRaiseException(status);
}

/***********************************************************************
 *           RpcSsDontSerializeContext [RPCRT4.@]
 */
 void WINAPI RpcSsDontSerializeContext(void)
{
    FIXME("stub\n");
}

static RPC_STATUS ndr_update_context_handle(NDR_CCONTEXT *CContext,
                                      RPC_BINDING_HANDLE hBinding,
                                      const ndr_context_handle *chi)
{
    struct context_handle_entry *che = NULL;

    /* a null UUID means we should free the context handle */
    if (IsEqualGUID(&chi->uuid, &GUID_NULL))
    {
        if (*CContext)
        {
            che = get_context_entry(*CContext);
            if (!che)
                return RPC_X_SS_CONTEXT_MISMATCH;
            list_remove(&che->entry);
            RpcBindingFree(&che->handle);
            HeapFree(GetProcessHeap(), 0, che);
            che = NULL;
        }
    }
    /* if there's no existing entry matching the GUID, allocate one */
    else if (!(che = context_entry_from_guid(&chi->uuid)))
    {
        che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
        if (!che)
            return RPC_X_NO_MEMORY;
        che->magic = NDR_CONTEXT_HANDLE_MAGIC;
        RpcBindingCopy(hBinding, &che->handle);
        list_add_tail(&context_handle_list, &che->entry);
        che->wire_data = *chi;
    }

    *CContext = che;

    return RPC_S_OK;
}

/***********************************************************************
 *           NDRCContextUnmarshall [RPCRT4.@]
 */
void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
                                  RPC_BINDING_HANDLE hBinding,
                                  void *pBuff, ULONG DataRepresentation)
{
    RPC_STATUS status;

    TRACE("*%p=(%p) %p %p %08x\n",
          CContext, *CContext, hBinding, pBuff, DataRepresentation);

    EnterCriticalSection(&ndr_context_cs);
    status = ndr_update_context_handle(CContext, hBinding, pBuff);
    LeaveCriticalSection(&ndr_context_cs);
    if (status)
        RpcRaiseException(status);
}

/***********************************************************************
 *           NDRSContextMarshall [RPCRT4.@]
 */
void WINAPI NDRSContextMarshall(NDR_SCONTEXT SContext,
                               void *pBuff,
                               NDR_RUNDOWN userRunDownIn)
{
    TRACE("(%p %p %p)\n", SContext, pBuff, userRunDownIn);
    NDRSContextMarshall2(I_RpcGetCurrentCallHandle(), SContext, pBuff,
                         userRunDownIn, NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
}

/***********************************************************************
 *           NDRSContextMarshallEx [RPCRT4.@]
 */
void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
                                  NDR_SCONTEXT SContext,
                                  void *pBuff,
                                  NDR_RUNDOWN userRunDownIn)
{
    TRACE("(%p %p %p %p)\n", hBinding, SContext, pBuff, userRunDownIn);
    NDRSContextMarshall2(hBinding, SContext, pBuff, userRunDownIn, NULL,
                         RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
}

/***********************************************************************
 *           NDRSContextMarshall2 [RPCRT4.@]
 */
void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
                                 NDR_SCONTEXT SContext,
                                 void *pBuff,
                                 NDR_RUNDOWN userRunDownIn,
                                 void *CtxGuard, ULONG Flags)
{
    RpcBinding *binding = hBinding;
    RPC_STATUS status;
    ndr_context_handle *ndr = pBuff;

    TRACE("(%p %p %p %p %p %u)\n",
          hBinding, SContext, pBuff, userRunDownIn, CtxGuard, Flags);

    if (!binding->server || !binding->Assoc)
        RpcRaiseException(RPC_S_INVALID_BINDING);

    if (Flags & RPC_CONTEXT_HANDLE_FLAGS)
        FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);

    if (SContext->userContext)
    {
        status = RpcServerAssoc_UpdateContextHandle(binding->Assoc, SContext, CtxGuard, userRunDownIn);
        if (status != RPC_S_OK)
            RpcRaiseException(status);
        ndr->attributes = 0;
        RpcContextHandle_GetUuid(SContext, &ndr->uuid);

        RPCRT4_RemoveThreadContextHandle(SContext);
        RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE);
    }
    else
    {
        if (!RpcContextHandle_IsGuardCorrect(SContext, CtxGuard))
            RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
        memset(ndr, 0, sizeof(*ndr));

        RPCRT4_RemoveThreadContextHandle(SContext);
        /* Note: release the context handle twice in this case to release
         * one ref being kept around for the data and one ref for the
         * unmarshall/marshall sequence */
        if (!RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE))
            return; /* this is to cope with the case of the data not being valid
                     * before and so not having a further reference */
        RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, FALSE);
    }
}

/***********************************************************************
 *           NDRSContextUnmarshall [RPCRT4.@]
 */
NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
                                          ULONG DataRepresentation)
{
    TRACE("(%p %08x)\n", pBuff, DataRepresentation);
    return NDRSContextUnmarshall2(I_RpcGetCurrentCallHandle(), pBuff,
                                  DataRepresentation, NULL,
                                  RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
}

/***********************************************************************
 *           NDRSContextUnmarshallEx [RPCRT4.@]
 */
NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
                                            void *pBuff,
                                            ULONG DataRepresentation)
{
    TRACE("(%p %p %08x)\n", hBinding, pBuff, DataRepresentation);
    return NDRSContextUnmarshall2(hBinding, pBuff, DataRepresentation, NULL,
                                  RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
}

/***********************************************************************
 *           NDRSContextUnmarshall2 [RPCRT4.@]
 */
NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
                                           void *pBuff,
                                           ULONG DataRepresentation,
                                           void *CtxGuard, ULONG Flags)
{
    RpcBinding *binding = hBinding;
    NDR_SCONTEXT SContext;
    RPC_STATUS status;
    const ndr_context_handle *context_ndr = pBuff;

    TRACE("(%p %p %08x %p %u)\n",
          hBinding, pBuff, DataRepresentation, CtxGuard, Flags);

    if (!binding->server || !binding->Assoc)
        RpcRaiseException(RPC_S_INVALID_BINDING);

    if (Flags & RPC_CONTEXT_HANDLE_FLAGS)
        FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);

    if (!pBuff || (!context_ndr->attributes &&
                   UuidIsNil((UUID *)&context_ndr->uuid, &status)))
        status = RpcServerAssoc_AllocateContextHandle(binding->Assoc, CtxGuard,
                                                      &SContext);
    else
    {
        if (context_ndr->attributes)
        {
            ERR("non-null attributes 0x%x\n", context_ndr->attributes);
            status = RPC_X_SS_CONTEXT_MISMATCH;
        }
        else
            status = RpcServerAssoc_FindContextHandle(binding->Assoc,
                                                      &context_ndr->uuid,
                                                      CtxGuard, Flags,
                                                      &SContext);
    }

    if (status != RPC_S_OK)
        RpcRaiseException(status);

    RPCRT4_PushThreadContextHandle(SContext);
    return SContext;
}
