/*
 *	Monikers
 *
 *	Copyright 1998	Marcus Meissner
 *      Copyright 1999  Noomen Hamza
 *      Copyright 2005  Robert Shearman (for CodeWeavers)
 *      Copyright 2007  Robert Shearman
 *
 * 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 "config.h"
#include "wine/port.h"

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

#define COBJMACROS

#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wtypes.h"
#include "ole2.h"

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

#include "compobj_private.h"
#include "moniker.h"
#include "irot.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

/* see MSDN docs for IROTData::GetComparisonData, which states what this
 * constant is
 */
#define MAX_COMPARISON_DATA 2048

static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr)
{
    return I_RpcExceptionFilter(eptr->ExceptionRecord->ExceptionCode);
}

/* define the structure of the running object table elements */
struct rot_entry
{
    struct list        entry;
    InterfaceData* object; /* marshaled running object*/
    MonikerComparisonData* moniker_data; /* moniker comparison data that identifies this object */
    DWORD              cookie; /* cookie identifying this object */
    FILETIME           last_modified;
    IrotContextHandle  ctxt_handle;
};

/* define the RunningObjectTableImpl structure */
typedef struct RunningObjectTableImpl
{
    IRunningObjectTable IRunningObjectTable_iface;
    LONG ref;

    struct list rot; /* list of ROT entries */
    CRITICAL_SECTION lock;
} RunningObjectTableImpl;

static RunningObjectTableImpl* runningObjectTableInstance = NULL;
static IrotHandle irot_handle;

/* define the EnumMonikerImpl structure */
typedef struct EnumMonikerImpl
{
    IEnumMoniker IEnumMoniker_iface;
    LONG ref;

    InterfaceList *moniker_list;
    ULONG pos;
} EnumMonikerImpl;

static inline RunningObjectTableImpl *impl_from_IRunningObjectTable(IRunningObjectTable *iface)
{
    return CONTAINING_RECORD(iface, RunningObjectTableImpl, IRunningObjectTable_iface);
}

static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
{
    return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface);
}

/* IEnumMoniker Local functions*/
static HRESULT EnumMonikerImpl_CreateEnumROTMoniker(InterfaceList *moniker_list,
    ULONG pos, IEnumMoniker **ppenumMoniker);

static IrotHandle get_irot_handle(void)
{
    if (!irot_handle)
    {
        RPC_STATUS status;
        RPC_WSTR binding;
        IrotHandle new_handle;
        unsigned short ncacn_np[] = IROT_PROTSEQ;
        unsigned short endpoint[] = IROT_ENDPOINT;
        status = RpcStringBindingComposeW(NULL, ncacn_np, NULL, endpoint, NULL, &binding);
        if (status == RPC_S_OK)
        {
            status = RpcBindingFromStringBindingW(binding, &new_handle);
            RpcStringFreeW(&binding);
        }
        if (status != RPC_S_OK)
            return NULL;
        if (InterlockedCompareExchangePointer(&irot_handle, new_handle, NULL))
            /* another thread beat us to it */
            RpcBindingFree(&new_handle);
    }
    return irot_handle;
}

static BOOL start_rpcss(void)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    WCHAR cmd[MAX_PATH];
    static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0};
    BOOL rslt;
    void *redir;

    TRACE("\n");

    ZeroMemory(&si, sizeof(STARTUPINFOA));
    si.cb = sizeof(STARTUPINFOA);
    GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) );
    strcatW( cmd, rpcss );

    Wow64DisableWow64FsRedirection( &redir );
    rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
    Wow64RevertWow64FsRedirection( redir );

    if (rslt)
    {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        Sleep(100);
    }

    return rslt;
}

static HRESULT create_stream_on_mip_ro(const InterfaceData *mip, IStream **stream)
{
    HGLOBAL hglobal = GlobalAlloc(0, mip->ulCntData);
    void *pv = GlobalLock(hglobal);
    memcpy(pv, mip->abData, mip->ulCntData);
    GlobalUnlock(hglobal);
    return CreateStreamOnHGlobal(hglobal, TRUE, stream);
}

static void rot_entry_delete(struct rot_entry *rot_entry)
{
    if (rot_entry->cookie)
    {
        InterfaceData *object = NULL;
        InterfaceData *moniker = NULL;
        __TRY
        {
            IrotRevoke(get_irot_handle(), rot_entry->cookie,
                       &rot_entry->ctxt_handle, &object, &moniker);
        }
        __EXCEPT(rpc_filter)
        {
        }
        __ENDTRY
        MIDL_user_free(object);
        if (moniker)
        {
            IStream *stream;
            HRESULT hr;
            hr = create_stream_on_mip_ro(moniker, &stream);
            if (hr == S_OK)
            {
                CoReleaseMarshalData(stream);
                IUnknown_Release(stream);
            }
        }
        MIDL_user_free(moniker);
    }
    if (rot_entry->object)
    {
        IStream *stream;
        HRESULT hr;
        hr = create_stream_on_mip_ro(rot_entry->object, &stream);
        if (hr == S_OK)
        {
            CoReleaseMarshalData(stream);
            IUnknown_Release(stream);
        }
    }
    HeapFree(GetProcessHeap(), 0, rot_entry->object);
    HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data);
    HeapFree(GetProcessHeap(), 0, rot_entry);
}

/* moniker_data must be freed with HeapFree when no longer in use */
static HRESULT get_moniker_comparison_data(IMoniker *pMoniker, MonikerComparisonData **moniker_data)
{
    HRESULT hr;
    IROTData *pROTData = NULL;
    hr = IMoniker_QueryInterface(pMoniker, &IID_IROTData, (void *)&pROTData);
    if (SUCCEEDED(hr))
    {
        ULONG size = MAX_COMPARISON_DATA;
        *moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[size]));
        if (!*moniker_data)
        {
            IROTData_Release(pROTData);
            return E_OUTOFMEMORY;
        }
        hr = IROTData_GetComparisonData(pROTData, (*moniker_data)->abData, size, &size);
        IROTData_Release(pROTData);
        if (hr != S_OK)
        {
            ERR("Failed to copy comparison data into buffer, hr = 0x%08x\n", hr);
            HeapFree(GetProcessHeap(), 0, *moniker_data);
            return hr;
        }
        (*moniker_data)->ulCntData = size;
    }
    else
    {
        IBindCtx *pbc;
        LPOLESTR pszDisplayName;
        CLSID clsid;
        int len;

        TRACE("generating comparison data from display name\n");

        hr = CreateBindCtx(0, &pbc);
        if (FAILED(hr))
            return hr;
        hr = IMoniker_GetDisplayName(pMoniker, pbc, NULL, &pszDisplayName);
        IBindCtx_Release(pbc);
        if (FAILED(hr))
            return hr;
        hr = IMoniker_GetClassID(pMoniker, &clsid);
        if (FAILED(hr))
        {
            CoTaskMemFree(pszDisplayName);
            return hr;
        }

        len = strlenW(pszDisplayName);
        *moniker_data = HeapAlloc(GetProcessHeap(), 0,
            FIELD_OFFSET(MonikerComparisonData, abData[sizeof(CLSID) + (len+1)*sizeof(WCHAR)]));
        if (!*moniker_data)
        {
            CoTaskMemFree(pszDisplayName);
            return E_OUTOFMEMORY;
        }
        (*moniker_data)->ulCntData = sizeof(CLSID) + (len+1)*sizeof(WCHAR);

        memcpy(&(*moniker_data)->abData[0], &clsid, sizeof(clsid));
        memcpy(&(*moniker_data)->abData[sizeof(clsid)], pszDisplayName, (len+1)*sizeof(WCHAR));
        CoTaskMemFree(pszDisplayName);
    }
    return S_OK;
}

static HRESULT reduce_moniker(IMoniker *pmk, IBindCtx *pbc, IMoniker **pmkReduced)
{
    IBindCtx *pbcNew = NULL;
    HRESULT hr;
    if (!pbc)
    {
        hr = CreateBindCtx(0, &pbcNew);
        if (FAILED(hr))
            return hr;
        pbc = pbcNew;
    }
    hr = IMoniker_Reduce(pmk, pbc, MKRREDUCE_ALL, NULL, pmkReduced);
    if (FAILED(hr))
        ERR("reducing moniker failed with error 0x%08x\n", hr);
    if (pbcNew) IBindCtx_Release(pbcNew);
    return hr;
}

/***********************************************************************
 *        RunningObjectTable_QueryInterface
 */
static HRESULT WINAPI
RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,
                                      REFIID riid,void** ppvObject)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);

    TRACE("(%p,%p,%p)\n",This,riid,ppvObject);

    /* validate arguments */

    if (ppvObject==0)
        return E_INVALIDARG;

    *ppvObject = 0;

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IRunningObjectTable, riid))
        *ppvObject = This;

    if ((*ppvObject)==0)
        return E_NOINTERFACE;

    IRunningObjectTable_AddRef(iface);

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_AddRef
 */
static ULONG WINAPI
RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);

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

    return InterlockedIncrement(&This->ref);
}

/***********************************************************************
 *        RunningObjectTable_Destroy
 */
static HRESULT
RunningObjectTableImpl_Destroy(void)
{
    struct list *cursor, *cursor2;
    IrotHandle old_handle;

    TRACE("()\n");

    if (runningObjectTableInstance==NULL)
        return E_INVALIDARG;

    /* free the ROT table memory */
    LIST_FOR_EACH_SAFE(cursor, cursor2, &runningObjectTableInstance->rot)
    {
        struct rot_entry *rot_entry = LIST_ENTRY(cursor, struct rot_entry, entry);
        list_remove(&rot_entry->entry);
        rot_entry_delete(rot_entry);
    }

    DEBUG_CLEAR_CRITSEC_NAME(&runningObjectTableInstance->lock);
    DeleteCriticalSection(&runningObjectTableInstance->lock);

    /* free the ROT structure memory */
    HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
    runningObjectTableInstance = NULL;

    old_handle = irot_handle;
    irot_handle = NULL;
    if (old_handle)
        RpcBindingFree(&old_handle);

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_Release
 */
static ULONG WINAPI
RunningObjectTableImpl_Release(IRunningObjectTable* iface)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    ULONG ref;

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

    ref = InterlockedDecrement(&This->ref);

    /* uninitialize ROT structure if there's no more references to it */
    if (ref == 0)
    {
        struct list *cursor, *cursor2;
        LIST_FOR_EACH_SAFE(cursor, cursor2, &This->rot)
        {
            struct rot_entry *rot_entry = LIST_ENTRY(cursor, struct rot_entry, entry);
            list_remove(&rot_entry->entry);
            rot_entry_delete(rot_entry);
        }
        /*  RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
         *  when RunningObjectTableImpl_UnInitialize function is called
         */
    }

    return ref;
}

/***********************************************************************
 *        RunningObjectTable_Register
 *
 * PARAMS
 * grfFlags       [in] Registration options 
 * punkObject     [in] the object being registered
 * pmkObjectName  [in] the moniker of the object being registered
 * pdwRegister    [out] the value identifying the registration
 */
static HRESULT WINAPI
RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
               IUnknown *punkObject, IMoniker *pmkObjectName, DWORD *pdwRegister)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    struct rot_entry *rot_entry;
    HRESULT hr = S_OK;
    IStream *pStream = NULL;
    DWORD mshlflags;
    IBindCtx *pbc;
    InterfaceData *moniker = NULL;

    TRACE("(%p,%d,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);

    if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
    {
        ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
        return E_INVALIDARG;
    }

    if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
        return E_INVALIDARG;

    rot_entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rot_entry));
    if (!rot_entry)
        return E_OUTOFMEMORY;

    /* marshal object */
    hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
    if (hr != S_OK)
    {
        rot_entry_delete(rot_entry);
        return hr;
    }
    mshlflags = (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) ? MSHLFLAGS_TABLESTRONG : MSHLFLAGS_TABLEWEAK;
    hr = CoMarshalInterface(pStream, &IID_IUnknown, punkObject, MSHCTX_LOCAL | MSHCTX_NOSHAREDMEM, NULL, mshlflags);
    /* FIXME: a cleaner way would be to create an IStream class that writes
     * directly to an MInterfacePointer */
    if (hr == S_OK)
    {
        HGLOBAL hglobal;
        hr = GetHGlobalFromStream(pStream, &hglobal);
        if (hr == S_OK)
        {
            SIZE_T size = GlobalSize(hglobal);
            const void *pv = GlobalLock(hglobal);
            rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer, abData[size]));
            rot_entry->object->ulCntData = size;
            memcpy(rot_entry->object->abData, pv, size);
            GlobalUnlock(hglobal);
        }
    }
    IStream_Release(pStream);
    if (hr != S_OK)
    {
        rot_entry_delete(rot_entry);
        return hr;
    }

    hr = CreateBindCtx(0, &pbc);
    if (FAILED(hr))
    {
        rot_entry_delete(rot_entry);
        return hr;
    }

    hr = reduce_moniker(pmkObjectName, pbc, &pmkObjectName);
    if (FAILED(hr))
    {
        rot_entry_delete(rot_entry);
        IBindCtx_Release(pbc);
        return hr;
    }

    hr = IMoniker_GetTimeOfLastChange(pmkObjectName, pbc, NULL,
                                      &rot_entry->last_modified);
    IBindCtx_Release(pbc);
    if (FAILED(hr))
    {
        CoFileTimeNow(&rot_entry->last_modified);
        hr = S_OK;
    }

    hr = get_moniker_comparison_data(pmkObjectName,
                                     &rot_entry->moniker_data);
    if (hr != S_OK)
    {
        rot_entry_delete(rot_entry);
        IMoniker_Release(pmkObjectName);
        return hr;
    }

    hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
    if (hr != S_OK)
    {
        rot_entry_delete(rot_entry);
        IMoniker_Release(pmkObjectName);
        return hr;
    }
    /* marshal moniker */
    hr = CoMarshalInterface(pStream, &IID_IMoniker, (IUnknown *)pmkObjectName,
                            MSHCTX_LOCAL | MSHCTX_NOSHAREDMEM, NULL, MSHLFLAGS_TABLESTRONG);
    /* FIXME: a cleaner way would be to create an IStream class that writes
     * directly to an MInterfacePointer */
    if (hr == S_OK)
    {
        HGLOBAL hglobal;
        hr = GetHGlobalFromStream(pStream, &hglobal);
        if (hr == S_OK)
        {
            SIZE_T size = GlobalSize(hglobal);
            const void *pv = GlobalLock(hglobal);
            moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[size]));
            moniker->ulCntData = size;
            memcpy(moniker->abData, pv, size);
            GlobalUnlock(hglobal);
        }
    }
    IStream_Release(pStream);
    IMoniker_Release(pmkObjectName);
    if (hr != S_OK)
    {
        HeapFree(GetProcessHeap(), 0, moniker);
        rot_entry_delete(rot_entry);
        return hr;
    }


    while (TRUE)
    {
        __TRY
        {
            hr = IrotRegister(get_irot_handle(), rot_entry->moniker_data,
                              rot_entry->object, moniker,
                              &rot_entry->last_modified, grfFlags,
                              &rot_entry->cookie, &rot_entry->ctxt_handle);
        }
        __EXCEPT(rpc_filter)
        {
            hr = HRESULT_FROM_WIN32(GetExceptionCode());
        }
        __ENDTRY
        if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
        {
            if (start_rpcss())
                continue;
        }
        break;
    }
    HeapFree(GetProcessHeap(), 0, moniker);
    if (FAILED(hr))
    {
        rot_entry_delete(rot_entry);
        return hr;
    }

    /* gives a registration identifier to the registered object*/
    *pdwRegister = rot_entry->cookie;

    EnterCriticalSection(&This->lock);
    list_add_tail(&This->rot, &rot_entry->entry);
    LeaveCriticalSection(&This->lock);

    return hr;
}

/***********************************************************************
 *        RunningObjectTable_Revoke
 *
 * PARAMS
 *  dwRegister [in] Value identifying registration to be revoked
 */
static HRESULT WINAPI
RunningObjectTableImpl_Revoke( IRunningObjectTable* iface, DWORD dwRegister) 
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    struct rot_entry *rot_entry;

    TRACE("(%p,%d)\n",This,dwRegister);

    EnterCriticalSection(&This->lock);
    LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
    {
        if (rot_entry->cookie == dwRegister)
        {
            list_remove(&rot_entry->entry);
            LeaveCriticalSection(&This->lock);

            rot_entry_delete(rot_entry);
            return S_OK;
        }
    }
    LeaveCriticalSection(&This->lock);

    return E_INVALIDARG;
}

/***********************************************************************
 *        RunningObjectTable_IsRunning
 *
 * PARAMS
 *  pmkObjectName [in]  moniker of the object whose status is desired 
 */
static HRESULT WINAPI
RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface, IMoniker *pmkObjectName)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    MonikerComparisonData *moniker_data;
    HRESULT hr;
    const struct rot_entry *rot_entry;

    TRACE("(%p,%p)\n",This,pmkObjectName);

    hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
    if (FAILED(hr))
        return hr;
    hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
    IMoniker_Release(pmkObjectName);
    if (hr != S_OK)
        return hr;

    hr = S_FALSE;
    EnterCriticalSection(&This->lock);
    LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, const struct rot_entry, entry)
    {
        if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
            !memcmp(moniker_data->abData, rot_entry->moniker_data->abData, moniker_data->ulCntData))
        {
            hr = S_OK;
            break;
        }
    }
    LeaveCriticalSection(&This->lock);

    if (hr == S_FALSE)
    {
        while (TRUE)
        {
            __TRY
            {
                hr = IrotIsRunning(get_irot_handle(), moniker_data);
            }
            __EXCEPT(rpc_filter)
            {
                hr = HRESULT_FROM_WIN32(GetExceptionCode());
            }
            __ENDTRY
            if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
            {
                if (start_rpcss())
                    continue;
            }
            break;
        }
    }

    HeapFree(GetProcessHeap(), 0, moniker_data);

    return hr;
}

/***********************************************************************
 *        RunningObjectTable_GetObject
 *
 * PARAMS
 * pmkObjectName [in] Pointer to the moniker on the object 
 * ppunkObject   [out] variable that receives the IUnknown interface pointer
 */
static HRESULT WINAPI
RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
                     IMoniker *pmkObjectName, IUnknown **ppunkObject)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    MonikerComparisonData *moniker_data;
    InterfaceData *object = NULL;
    IrotCookie cookie;
    HRESULT hr;
    struct rot_entry *rot_entry;

    TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);

    if (ppunkObject == NULL)
        return E_POINTER;

    *ppunkObject = NULL;

    hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
    if (FAILED(hr))
        return hr;
    hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
    IMoniker_Release(pmkObjectName);
    if (hr != S_OK)
        return hr;

    EnterCriticalSection(&This->lock);
    LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
    {
        if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
            !memcmp(moniker_data->abData, rot_entry->moniker_data->abData, moniker_data->ulCntData))
        {
            IStream *pStream;
            hr = create_stream_on_mip_ro(rot_entry->object, &pStream);
            if (hr == S_OK)
            {
                hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)ppunkObject);
                IStream_Release(pStream);
            }

            LeaveCriticalSection(&This->lock);
            HeapFree(GetProcessHeap(), 0, moniker_data);

            return hr;
        }
    }
    LeaveCriticalSection(&This->lock);

    TRACE("moniker unavailable locally, calling SCM\n");

    while (TRUE)
    {
        __TRY
        {
            hr = IrotGetObject(get_irot_handle(), moniker_data, &object, &cookie);
        }
        __EXCEPT(rpc_filter)
        {
            hr = HRESULT_FROM_WIN32(GetExceptionCode());
        }
        __ENDTRY
        if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
        {
            if (start_rpcss())
                continue;
        }
        break;
    }

    if (SUCCEEDED(hr))
    {
        IStream *pStream;
        hr = create_stream_on_mip_ro(object, &pStream);
        if (hr == S_OK)
        {
            hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)ppunkObject);
            IStream_Release(pStream);
        }
    }
    else
        WARN("Moniker unavailable, IrotGetObject returned 0x%08x\n", hr);

    HeapFree(GetProcessHeap(), 0, moniker_data);

    return hr;
}

/***********************************************************************
 *        RunningObjectTable_NoteChangeTime
 *
 * PARAMS
 *  dwRegister [in] Value identifying registration being updated
 *  pfiletime  [in] Pointer to structure containing object's last change time
 */
static HRESULT WINAPI
RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
                                      DWORD dwRegister, FILETIME *pfiletime)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    struct rot_entry *rot_entry;
    HRESULT hr = E_INVALIDARG;

    TRACE("(%p,%d,%p)\n",This,dwRegister,pfiletime);

    EnterCriticalSection(&This->lock);
    LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
    {
        if (rot_entry->cookie == dwRegister)
        {
            rot_entry->last_modified = *pfiletime;
            LeaveCriticalSection(&This->lock);

            while (TRUE)
            {
                __TRY
                {
                    hr = IrotNoteChangeTime(get_irot_handle(), dwRegister, pfiletime);
                }
                __EXCEPT(rpc_filter)
                {
                    hr = HRESULT_FROM_WIN32(GetExceptionCode());
                }
                __ENDTRY
                if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
                {
                    if (start_rpcss())
                        continue;
                }
                break;
            }

            goto done;
        }
    }
    LeaveCriticalSection(&This->lock);

done:
    TRACE("-- 0x08%x\n", hr);
    return hr;
}

/***********************************************************************
 *        RunningObjectTable_GetTimeOfLastChange
 *
 * PARAMS
 *  pmkObjectName  [in]  moniker of the object whose status is desired 
 *  pfiletime      [out] structure that receives object's last change time
 */
static HRESULT WINAPI
RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
                            IMoniker *pmkObjectName, FILETIME *pfiletime)
{
    HRESULT hr = MK_E_UNAVAILABLE;
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    MonikerComparisonData *moniker_data;
    const struct rot_entry *rot_entry;

    TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);

    if (pmkObjectName==NULL || pfiletime==NULL)
        return E_INVALIDARG;

    hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
    if (FAILED(hr))
        return hr;
    hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
    IMoniker_Release(pmkObjectName);
    if (hr != S_OK)
        return hr;

    hr = MK_E_UNAVAILABLE;

    EnterCriticalSection(&This->lock);
    LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, const struct rot_entry, entry)
    {
        if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
            !memcmp(moniker_data->abData, rot_entry->moniker_data->abData, moniker_data->ulCntData))
        {
            *pfiletime = rot_entry->last_modified;
            hr = S_OK;
            break;
        }
    }
    LeaveCriticalSection(&This->lock);

    if (hr != S_OK)
    {
        while (TRUE)
        {
            __TRY
            {
                hr = IrotGetTimeOfLastChange(get_irot_handle(), moniker_data, pfiletime);
            }
            __EXCEPT(rpc_filter)
            {
                hr = HRESULT_FROM_WIN32(GetExceptionCode());
            }
            __ENDTRY
            if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
            {
                if (start_rpcss())
                    continue;
            }
            break;
        }
    }

    HeapFree(GetProcessHeap(), 0, moniker_data);

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

/***********************************************************************
 *        RunningObjectTable_EnumRunning
 *
 * PARAMS
 *  ppenumMoniker  [out]  receives the IEnumMoniker interface pointer 
 */
static HRESULT WINAPI
RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
                                   IEnumMoniker **ppenumMoniker)
{
    RunningObjectTableImpl *This = impl_from_IRunningObjectTable(iface);
    InterfaceList *interface_list = NULL;
    HRESULT hr;

    TRACE("(%p, %p)\n", This, ppenumMoniker);

    *ppenumMoniker = NULL;

    while (TRUE)
    {
        __TRY
        {
            hr = IrotEnumRunning(get_irot_handle(), &interface_list);
        }
        __EXCEPT(rpc_filter)
        {
            hr = HRESULT_FROM_WIN32(GetExceptionCode());
        }
        __ENDTRY
        if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
        {
            if (start_rpcss())
                continue;
        }
        break;
    }

    if (SUCCEEDED(hr))
        hr = EnumMonikerImpl_CreateEnumROTMoniker(interface_list,
                                                  0, ppenumMoniker);

    return hr;
}

/* Virtual function table for the IRunningObjectTable class. */
static const IRunningObjectTableVtbl VT_RunningObjectTableImpl =
{
    RunningObjectTableImpl_QueryInterface,
    RunningObjectTableImpl_AddRef,
    RunningObjectTableImpl_Release,
    RunningObjectTableImpl_Register,
    RunningObjectTableImpl_Revoke,
    RunningObjectTableImpl_IsRunning,
    RunningObjectTableImpl_GetObject,
    RunningObjectTableImpl_NoteChangeTime,
    RunningObjectTableImpl_GetTimeOfLastChange,
    RunningObjectTableImpl_EnumRunning
};

/***********************************************************************
 *        RunningObjectTable_Initialize
 */
HRESULT WINAPI RunningObjectTableImpl_Initialize(void)
{
    TRACE("\n");

    /* create the unique instance of the RunningObjectTableImpl structure */
    runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));

    if (!runningObjectTableInstance)
        return E_OUTOFMEMORY;

    /* initialize the virtual table function */
    runningObjectTableInstance->IRunningObjectTable_iface.lpVtbl = &VT_RunningObjectTableImpl;

    /* the initial reference is set to "1" so that it isn't destroyed after its
     * first use until the process is destroyed, as the running object table is
     * a process-wide cache of a global table */
    runningObjectTableInstance->ref = 1;

    list_init(&runningObjectTableInstance->rot);
    InitializeCriticalSection(&runningObjectTableInstance->lock);
    DEBUG_SET_CRITSEC_NAME(&runningObjectTableInstance->lock, "RunningObjectTableImpl.lock");

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_UnInitialize
 */
HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void)
{
    TRACE("\n");

    if (runningObjectTableInstance==NULL)
        return E_POINTER;

    RunningObjectTableImpl_Release(&runningObjectTableInstance->IRunningObjectTable_iface);

    RunningObjectTableImpl_Destroy();

    return S_OK;
}

/***********************************************************************
 *           GetRunningObjectTable (OLE32.@)
 *
 * Retrieves the global running object table.
 *
 * PARAMS
 *  reserved [I] Reserved. Set to 0.
 *  pprot    [O] Address that receives the pointer to the running object table.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: Any HRESULT code.
 */
HRESULT WINAPI
GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
{
    IID riid=IID_IRunningObjectTable;
    HRESULT res;

    TRACE("()\n");

    if (reserved!=0)
        return E_UNEXPECTED;

    if(runningObjectTableInstance==NULL)
        return CO_E_NOTINITIALIZED;

    res = IRunningObjectTable_QueryInterface(&runningObjectTableInstance->IRunningObjectTable_iface,
                                             &riid,(void**)pprot);

    return res;
}

static HRESULT get_moniker_for_progid_display_name(LPBC pbc,
                                                   LPCOLESTR szDisplayName,
                                                   LPDWORD pchEaten,
                                                   LPMONIKER *ppmk)
{
    CLSID clsid;
    HRESULT hr;
    LPWSTR progid;
    LPCWSTR start = szDisplayName;
    LPCWSTR end;
    int len;
    IMoniker *class_moniker;

    if (*start == '@')
        start++;

    /* find end delimiter */
    for (end = start; *end; end++)
        if (*end == ':')
            break;

    len = end - start;

    /* must start with '@' or have a ':' somewhere and mustn't be one character
     * long (since that looks like an absolute path) */
    if (((start == szDisplayName) && (*end == '\0')) || (len <= 1))
        return MK_E_SYNTAX;

    progid = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
    if (progid)
    {
        memcpy(progid, start, len * sizeof(WCHAR));
        progid[len] = '\0';
    }
    hr = CLSIDFromProgID(progid, &clsid);
    HeapFree(GetProcessHeap(), 0, progid);
    if (FAILED(hr))
        return MK_E_SYNTAX;

    hr = CreateClassMoniker(&clsid, &class_moniker);
    if (SUCCEEDED(hr))
    {
        IParseDisplayName *pdn;
        hr = IMoniker_BindToObject(class_moniker, pbc, NULL,
                                   &IID_IParseDisplayName, (void **)&pdn);
        /* fallback to using IClassFactory to get IParseDisplayName -
         * adsldp.dll depends on this */
        if (FAILED(hr))
        {
            IClassFactory *pcf;
            hr = IMoniker_BindToObject(class_moniker, pbc, NULL,
                                       &IID_IClassFactory, (void **)&pcf);
            if (SUCCEEDED(hr))
            {
                hr = IClassFactory_CreateInstance(pcf, NULL,
                                                  &IID_IParseDisplayName,
                                                  (void **)&pdn);
                IClassFactory_Release(pcf);
            }
        }
        IMoniker_Release(class_moniker);
        if (SUCCEEDED(hr))
        {
            hr = IParseDisplayName_ParseDisplayName(pdn, pbc,
                                                    (LPOLESTR)szDisplayName,
                                                    pchEaten, ppmk);
            IParseDisplayName_Release(pdn);
        }
    }
    return hr;
}

/******************************************************************************
 *              MkParseDisplayName        [OLE32.@]
 */
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
				LPDWORD pchEaten, LPMONIKER *ppmk)
{
    HRESULT hr = MK_E_SYNTAX;
    static const WCHAR wszClsidColon[] = {'c','l','s','i','d',':'};
    IMoniker *moniker;
    DWORD chEaten;

    TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk);

    if (!pbc || !IsValidInterface((LPUNKNOWN) pbc))
        return E_INVALIDARG;

    if (!szDisplayName || !*szDisplayName)
        return E_INVALIDARG;

    if (!pchEaten || !ppmk)
        return E_INVALIDARG;

    *pchEaten = 0;
    *ppmk = NULL;

    if (!strncmpiW(szDisplayName, wszClsidColon, sizeof(wszClsidColon)/sizeof(wszClsidColon[0])))
    {
        hr = ClassMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker);
        if (FAILED(hr) && (hr != MK_E_SYNTAX))
            return hr;
    }
    else
    {
        hr = get_moniker_for_progid_display_name(pbc, szDisplayName, &chEaten, &moniker);
        if (FAILED(hr) && (hr != MK_E_SYNTAX))
            return hr;
    }

    if (FAILED(hr))
    {
        hr = FileMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker);
        if (FAILED(hr) && (hr != MK_E_SYNTAX))
            return hr;
    }

    if (SUCCEEDED(hr))
    {
        while (TRUE)
        {
            IMoniker *next_moniker;
            *pchEaten += chEaten;
            szDisplayName += chEaten;
            if (!*szDisplayName)
            {
                *ppmk = moniker;
                return S_OK;
            }
            chEaten = 0;
            hr = IMoniker_ParseDisplayName(moniker, pbc, NULL,
                                           (LPOLESTR)szDisplayName, &chEaten,
                                           &next_moniker);
            IMoniker_Release(moniker);
            if (FAILED(hr))
            {
                *pchEaten = 0;
                break;
            }
            moniker = next_moniker;
        }
    }

    return hr;
}

/***********************************************************************
 *        GetClassFile (OLE32.@)
 *
 * Retrieves the class ID associated with the given filename.
 *
 * PARAMS
 *  filePathName [I] Filename to retrieve the class ID for.
 *  pclsid       [O] Address that receives the class ID for the file.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: Any HRESULT code.
 */
HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid)
{
    IStorage *pstg=0;
    HRESULT res;
    int nbElm, length, i;
    LONG sizeProgId;
    LPOLESTR *pathDec=0,absFile=0,progId=0;
    LPWSTR extension;
    static const WCHAR bkslashW[] = {'\\',0};
    static const WCHAR dotW[] = {'.',0};

    TRACE("%s, %p\n", debugstr_w(filePathName), pclsid);

    /* if the file contain a storage object the return the CLSID written by IStorage_SetClass method*/
    if((StgIsStorageFile(filePathName))==S_OK){

        res=StgOpenStorage(filePathName,NULL,STGM_READ | STGM_SHARE_DENY_WRITE,NULL,0,&pstg);

        if (SUCCEEDED(res))
            res=ReadClassStg(pstg,pclsid);

        IStorage_Release(pstg);

        return res;
    }
    /* If the file is not a storage object then attempt to match various bits in the file against a
       pattern in the registry. This case is not frequently used, so I present only the pseudocode for
       this case.

     for(i=0;i<nFileTypes;i++)

        for(i=0;j<nPatternsForType;j++){

            PATTERN pat;
            HANDLE  hFile;

            pat=ReadPatternFromRegistry(i,j);
            hFile=CreateFileW(filePathName,,,,,,hFile);
            SetFilePosition(hFile,pat.offset);
            ReadFile(hFile,buf,pat.size,&r,NULL);
            if (memcmp(buf&pat.mask,pat.pattern.pat.size)==0){

                *pclsid=ReadCLSIDFromRegistry(i);
                return S_OK;
            }
        }
     */

    /* if the above strategies fail then search for the extension key in the registry */

    /* get the last element (absolute file) in the path name */
    nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec);
    absFile=pathDec[nbElm-1];

    /* failed if the path represents a directory and not an absolute file name*/
    if (!lstrcmpW(absFile, bkslashW))
        return MK_E_INVALIDEXTENSION;

    /* get the extension of the file */
    extension = NULL;
    length=lstrlenW(absFile);
    for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--)
        /* nothing */;

    if (!extension || !lstrcmpW(extension, dotW))
        return MK_E_INVALIDEXTENSION;

    res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId);

    /* get the progId associated to the extension */
    progId = CoTaskMemAlloc(sizeProgId);
    res = RegQueryValueW(HKEY_CLASSES_ROOT, extension, progId, &sizeProgId);

    if (res==ERROR_SUCCESS)
        /* return the clsid associated to the progId */
        res= CLSIDFromProgID(progId,pclsid);

    for(i=0; pathDec[i]!=NULL;i++)
        CoTaskMemFree(pathDec[i]);
    CoTaskMemFree(pathDec);

    CoTaskMemFree(progId);

    if (res==ERROR_SUCCESS)
        return res;

    return MK_E_INVALIDEXTENSION;
}

/***********************************************************************
 *        EnumMoniker_QueryInterface
 */
static HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
{
    EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);

    TRACE("(%p,%p,%p)\n",This,riid,ppvObject);

    /* validate arguments */
    if (ppvObject == NULL)
        return E_INVALIDARG;

    *ppvObject = NULL;

    if (IsEqualIID(&IID_IUnknown, riid))
        *ppvObject = This;
    else
        if (IsEqualIID(&IID_IEnumMoniker, riid))
            *ppvObject = This;

    if ((*ppvObject)==NULL)
        return E_NOINTERFACE;

    IEnumMoniker_AddRef(iface);

    return S_OK;
}

/***********************************************************************
 *        EnumMoniker_AddRef
 */
static ULONG   WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface)
{
    EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);

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

    return InterlockedIncrement(&This->ref);
}

/***********************************************************************
 *        EnumMoniker_release
 */
static ULONG   WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface)
{
    EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
    ULONG ref;

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

    ref = InterlockedDecrement(&This->ref);

    /* uninitialize rot structure if there's no more reference to it*/
    if (ref == 0)
    {
        ULONG i;

        TRACE("(%p) Deleting\n",This);

        for (i = 0; i < This->moniker_list->size; i++)
            HeapFree(GetProcessHeap(), 0, This->moniker_list->interfaces[i]);
        HeapFree(GetProcessHeap(), 0, This->moniker_list);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}
/***********************************************************************
 *        EnumMoniker_Next
 */
static HRESULT   WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface, ULONG celt, IMoniker** rgelt, ULONG * pceltFetched)
{
    ULONG i;
    EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
    HRESULT hr = S_OK;

    TRACE("(%p) TabCurrentPos %d Tablastindx %d\n", This, This->pos, This->moniker_list->size);

    /* retrieve the requested number of moniker from the current position */
    for(i = 0; (This->pos < This->moniker_list->size) && (i < celt); i++)
    {
        IStream *stream;
        hr = create_stream_on_mip_ro(This->moniker_list->interfaces[This->pos++], &stream);
        if (hr != S_OK) break;
        hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&rgelt[i]);
        IStream_Release(stream);
        if (hr != S_OK) break;
    }

    if (pceltFetched != NULL)
        *pceltFetched= i;

    if (hr != S_OK)
        return hr;

    if (i == celt)
        return S_OK;
    else
        return S_FALSE;

}

/***********************************************************************
 *        EnumMoniker_Skip
 */
static HRESULT   WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface, ULONG celt)
{
    EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);

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

    if  (This->pos + celt >= This->moniker_list->size)
        return S_FALSE;

    This->pos += celt;

    return S_OK;
}

/***********************************************************************
 *        EnumMoniker_Reset
 */
static HRESULT   WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface)
{
    EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);

    This->pos = 0;	/* set back to start of list */

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

    return S_OK;
}

/***********************************************************************
 *        EnumMoniker_Clone
 */
static HRESULT   WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface, IEnumMoniker ** ppenum)
{
    EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
    InterfaceList *moniker_list;
    ULONG i;

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

    *ppenum = NULL;

    moniker_list = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceList, interfaces[This->moniker_list->size]));
    if (!moniker_list)
        return E_OUTOFMEMORY;

    moniker_list->size = This->moniker_list->size;
    for (i = 0; i < This->moniker_list->size; i++)
    {
        SIZE_T size = FIELD_OFFSET(InterfaceData, abData[This->moniker_list->interfaces[i]->ulCntData]);
        moniker_list->interfaces[i] = HeapAlloc(GetProcessHeap(), 0, size);
        if (!moniker_list->interfaces[i])
        {
            ULONG end = i;
            for (i = 0; i < end; i++)
                HeapFree(GetProcessHeap(), 0, moniker_list->interfaces[i]);
            HeapFree(GetProcessHeap(), 0, moniker_list);
            return E_OUTOFMEMORY;
        }
        memcpy(moniker_list->interfaces[i], This->moniker_list->interfaces[i], size);
    }

    /* copy the enum structure */ 
    return EnumMonikerImpl_CreateEnumROTMoniker(moniker_list, This->pos, ppenum);
}

/* Virtual function table for the IEnumMoniker class. */
static const IEnumMonikerVtbl VT_EnumMonikerImpl =
{
    EnumMonikerImpl_QueryInterface,
    EnumMonikerImpl_AddRef,
    EnumMonikerImpl_Release,
    EnumMonikerImpl_Next,
    EnumMonikerImpl_Skip,
    EnumMonikerImpl_Reset,
    EnumMonikerImpl_Clone
};

/***********************************************************************
 *        EnumMonikerImpl_CreateEnumROTMoniker
 *        Used by EnumRunning to create the structure and EnumClone
 *	  to copy the structure
 */
static HRESULT EnumMonikerImpl_CreateEnumROTMoniker(InterfaceList *moniker_list,
                                                 ULONG current_pos,
                                                 IEnumMoniker **ppenumMoniker)
{
    EnumMonikerImpl* This = NULL;

    if (!ppenumMoniker)
        return E_INVALIDARG;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
    if (!This) return E_OUTOFMEMORY;

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

    /* initialize the virtual table function */
    This->IEnumMoniker_iface.lpVtbl = &VT_EnumMonikerImpl;

    /* the initial reference is set to "1" */
    This->ref = 1;			/* set the ref count to one         */
    This->pos = current_pos;		/* Set the list start posn */
    This->moniker_list = moniker_list;

    *ppenumMoniker =  &This->IEnumMoniker_iface;

    return S_OK;
}


/* Shared implementation of moniker marshaler based on saving and loading of
 * monikers */

typedef struct MonikerMarshal
{
    IUnknown IUnknown_iface;
    IMarshal IMarshal_iface;

    LONG ref;
    IMoniker *moniker;
} MonikerMarshal;

static inline MonikerMarshal *impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, MonikerMarshal, IUnknown_iface);
}

static inline MonikerMarshal *impl_from_IMarshal( IMarshal *iface )
{
    return CONTAINING_RECORD(iface, MonikerMarshal, IMarshal_iface);
}

static HRESULT WINAPI MonikerMarshalInner_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppv)
{
    MonikerMarshal *This = impl_from_IUnknown(iface);
    TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
    *ppv = NULL;
    if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IMarshal, riid))
    {
        *ppv = &This->IMarshal_iface;
        IUnknown_AddRef((IUnknown *)&This->IMarshal_iface);
        return S_OK;
    }
    FIXME("No interface for %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI MonikerMarshalInner_AddRef(IUnknown *iface)
{
    MonikerMarshal *This = impl_from_IUnknown(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI MonikerMarshalInner_Release(IUnknown *iface)
{
    MonikerMarshal *This = impl_from_IUnknown(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    if (!ref) HeapFree(GetProcessHeap(), 0, This);
    return ref;
}

static const IUnknownVtbl VT_MonikerMarshalInner =
{
    MonikerMarshalInner_QueryInterface,
    MonikerMarshalInner_AddRef,
    MonikerMarshalInner_Release
};

static HRESULT WINAPI MonikerMarshal_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
{
    MonikerMarshal *This = impl_from_IMarshal(iface);
    return IMoniker_QueryInterface(This->moniker, riid, ppv);
}

static ULONG WINAPI MonikerMarshal_AddRef(IMarshal *iface)
{
    MonikerMarshal *This = impl_from_IMarshal(iface);
    return IMoniker_AddRef(This->moniker);
}

static ULONG WINAPI MonikerMarshal_Release(IMarshal *iface)
{
    MonikerMarshal *This = impl_from_IMarshal(iface);
    return IMoniker_Release(This->moniker);
}

static HRESULT WINAPI MonikerMarshal_GetUnmarshalClass(
  LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
  void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
    MonikerMarshal *This = impl_from_IMarshal(iface);

    TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
        dwDestContext, pvDestContext, mshlflags, pCid);

    return IMoniker_GetClassID(This->moniker, pCid);
}

static HRESULT WINAPI MonikerMarshal_GetMarshalSizeMax(
  LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
  void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{
    MonikerMarshal *This = impl_from_IMarshal(iface);
    HRESULT hr;
    ULARGE_INTEGER size;

    TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
        dwDestContext, pvDestContext, mshlflags, pSize);

    hr = IMoniker_GetSizeMax(This->moniker, &size);
    if (hr == S_OK)
        *pSize = (DWORD)size.QuadPart;
    return hr;
}

static HRESULT WINAPI MonikerMarshal_MarshalInterface(LPMARSHAL iface, IStream *pStm, 
    REFIID riid, void* pv, DWORD dwDestContext,
    void* pvDestContext, DWORD mshlflags)
{
    MonikerMarshal *This = impl_from_IMarshal(iface);

    TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm, debugstr_guid(riid), pv,
        dwDestContext, pvDestContext, mshlflags);

    return IMoniker_Save(This->moniker, pStm, FALSE);
}

static HRESULT WINAPI MonikerMarshal_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
{
    MonikerMarshal *This = impl_from_IMarshal(iface);
    HRESULT hr;

    TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);

    hr = IMoniker_Load(This->moniker, pStm);
    if (hr == S_OK)
        hr = IMoniker_QueryInterface(This->moniker, riid, ppv);
    return hr;
}

static HRESULT WINAPI MonikerMarshal_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
{
    TRACE("()\n");
    /* can't release a state-based marshal as nothing on server side to
     * release */
    return S_OK;
}

static HRESULT WINAPI MonikerMarshal_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
{
    TRACE("()\n");
    /* can't disconnect a state-based marshal as nothing on server side to
     * disconnect from */
    return S_OK;
}

static const IMarshalVtbl VT_MonikerMarshal =
{
    MonikerMarshal_QueryInterface,
    MonikerMarshal_AddRef,
    MonikerMarshal_Release,
    MonikerMarshal_GetUnmarshalClass,
    MonikerMarshal_GetMarshalSizeMax,
    MonikerMarshal_MarshalInterface,
    MonikerMarshal_UnmarshalInterface,
    MonikerMarshal_ReleaseMarshalData,
    MonikerMarshal_DisconnectObject
};

HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer)
{
    MonikerMarshal *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This) return E_OUTOFMEMORY;

    This->IUnknown_iface.lpVtbl = &VT_MonikerMarshalInner;
    This->IMarshal_iface.lpVtbl = &VT_MonikerMarshal;
    This->ref = 1;
    This->moniker = inner;

    *outer = &This->IUnknown_iface;
    return S_OK;
}

void * __RPC_USER MIDL_user_allocate(SIZE_T size)
{
    return HeapAlloc(GetProcessHeap(), 0, size);
}

void __RPC_USER MIDL_user_free(void *p)
{
    HeapFree(GetProcessHeap(), 0, p);
}
