/*
 *	                      Class Monikers
 *
 *           Copyright 1999  Noomen Hamza
 *           Copyright 2005-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 <assert.h>
#include <stdarg.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wine/debug.h"
#include "ole2.h"
#include "wine/unicode.h"
#include "moniker.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

#define CHARS_IN_GUID 39

/* ClassMoniker data structure */
typedef struct ClassMoniker
{
    IMoniker IMoniker_iface;
    IROTData IROTData_iface;
    LONG ref;
    CLSID clsid; /* clsid identified by this moniker */
    IUnknown *pMarshal; /* custom marshaler */
} ClassMoniker;

static inline ClassMoniker *impl_from_IMoniker(IMoniker *iface)
{
    return CONTAINING_RECORD(iface, ClassMoniker, IMoniker_iface);
}

static inline ClassMoniker *impl_from_IROTData(IROTData *iface)
{
    return CONTAINING_RECORD(iface, ClassMoniker, IROTData_iface);
}

/*******************************************************************************
 *        ClassMoniker_QueryInterface
 *******************************************************************************/
static HRESULT WINAPI ClassMoniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
    ClassMoniker *This = impl_from_IMoniker(iface);

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

    /* Perform a sanity check on the parameters.*/
    if (!ppvObject)
        return E_POINTER;

    /* Initialize the return parameter */
    *ppvObject = 0;

    /* Compare the riid with the interface IDs implemented by this object.*/
    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IPersist, riid) ||
        IsEqualIID(&IID_IPersistStream, riid) ||
        IsEqualIID(&IID_IMoniker, riid))
    {
        *ppvObject = iface;
    }
    else if (IsEqualIID(&IID_IROTData, riid))
        *ppvObject = &This->IROTData_iface;
    else if (IsEqualIID(&IID_IMarshal, riid))
    {
        HRESULT hr = S_OK;
        if (!This->pMarshal)
            hr = MonikerMarshal_Create(iface, &This->pMarshal);
        if (hr != S_OK)
            return hr;
        return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
    }

    /* Check that we obtained an interface.*/
    if (!*ppvObject)
        return E_NOINTERFACE;

    /* Query Interface always increases the reference count by one when it is successful */
    IMoniker_AddRef(iface);

    return S_OK;
}

/******************************************************************************
 *        ClassMoniker_AddRef
 ******************************************************************************/
static ULONG WINAPI ClassMoniker_AddRef(IMoniker* iface)
{
    ClassMoniker *This = impl_from_IMoniker(iface);

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

    return InterlockedIncrement(&This->ref);
}

/******************************************************************************
 *        ClassMoniker_Destroy (local function)
 *******************************************************************************/
static HRESULT ClassMoniker_Destroy(ClassMoniker* This)
{
    TRACE("(%p)\n",This);

    if (This->pMarshal) IUnknown_Release(This->pMarshal);

    HeapFree(GetProcessHeap(),0,This);

    return S_OK;
}

/******************************************************************************
 *        ClassMoniker_Release
 ******************************************************************************/
static ULONG WINAPI ClassMoniker_Release(IMoniker* iface)
{
    ClassMoniker *This = impl_from_IMoniker(iface);
    ULONG ref;

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

    ref = InterlockedDecrement(&This->ref);

    /* destroy the object if there's no more reference on it */
    if (ref == 0) ClassMoniker_Destroy(This);

    return ref;
}

/******************************************************************************
 *        ClassMoniker_GetClassID
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetClassID(IMoniker* iface,CLSID *pClassID)
{
    TRACE("(%p,%p),stub!\n",iface,pClassID);

    if (pClassID==NULL)
        return E_POINTER;

    *pClassID = CLSID_ClassMoniker;

    return S_OK;
}

/******************************************************************************
 *        ClassMoniker_IsDirty
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsDirty(IMoniker* iface)
{
    /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
       method in the OLE-provided moniker interfaces always return S_FALSE because
       their internal state never changes. */

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

    return S_FALSE;
}

/******************************************************************************
 *        ClassMoniker_Load
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_Load(IMoniker* iface,IStream* pStm)
{
    ClassMoniker *This = impl_from_IMoniker(iface);
    HRESULT hr;
    DWORD zero;

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

    hr = IStream_Read(pStm, &This->clsid, sizeof(This->clsid), NULL);
    if (hr != S_OK) return STG_E_READFAULT;

    hr = IStream_Read(pStm, &zero, sizeof(zero), NULL);
    if ((hr != S_OK) || (zero != 0)) return STG_E_READFAULT;

    return S_OK;
}

/******************************************************************************
 *        ClassMoniker_Save
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
{
    ClassMoniker *This = impl_from_IMoniker(iface);
    HRESULT hr;
    DWORD zero = 0;

    TRACE("(%p, %s)\n", pStm, fClearDirty ? "TRUE" : "FALSE");

    hr = IStream_Write(pStm, &This->clsid, sizeof(This->clsid), NULL);
    if (FAILED(hr)) return hr;

    return IStream_Write(pStm, &zero, sizeof(zero), NULL);
}

/******************************************************************************
 *        ClassMoniker_GetSizeMax
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetSizeMax(IMoniker* iface,
                                          ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{
    TRACE("(%p)\n", pcbSize);

    pcbSize->QuadPart = sizeof(CLSID) + sizeof(DWORD);

    return S_OK;
}

/******************************************************************************
 *                  ClassMoniker_BindToObject
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_BindToObject(IMoniker* iface,
                                            IBindCtx* pbc,
                                            IMoniker* pmkToLeft,
                                            REFIID riid,
                                            VOID** ppvResult)
{
    ClassMoniker *This = impl_from_IMoniker(iface);
    BIND_OPTS2 bindopts;
    IClassActivator *pActivator;
    HRESULT hr;

    TRACE("(%p,%p,%p,%p)\n", pbc, pmkToLeft, riid, ppvResult);

    bindopts.cbStruct = sizeof(bindopts);
    IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts);

    if (!pmkToLeft)
        return CoGetClassObject(&This->clsid, bindopts.dwClassContext, NULL,
                                riid, ppvResult);
    else
    {
        hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator,
                                   (void **)&pActivator);
        if (FAILED(hr)) return hr;

        hr = IClassActivator_GetClassObject(pActivator, &This->clsid,
                                            bindopts.dwClassContext,
                                            bindopts.locale, riid, ppvResult);

        IClassActivator_Release(pActivator);

        return hr;
    }
}

/******************************************************************************
 *        ClassMoniker_BindToStorage
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_BindToStorage(IMoniker* iface,
                                             IBindCtx* pbc,
                                             IMoniker* pmkToLeft,
                                             REFIID riid,
                                             VOID** ppvResult)
{
    TRACE("(%p,%p,%p,%p)\n",pbc, pmkToLeft, riid, ppvResult);
    return ClassMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult);
}

/******************************************************************************
 *        ClassMoniker_Reduce
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_Reduce(IMoniker* iface,
                                      IBindCtx* pbc,
                                      DWORD dwReduceHowFar,
                                      IMoniker** ppmkToLeft,
                                      IMoniker** ppmkReduced)
{
    TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);

    if (!ppmkReduced)
        return E_POINTER;

    ClassMoniker_AddRef(iface);

    *ppmkReduced = iface;

    return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
 *        ClassMoniker_ComposeWith
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_ComposeWith(IMoniker* iface,
                                           IMoniker* pmkRight,
                                           BOOL fOnlyIfNotGeneric,
                                           IMoniker** ppmkComposite)
{
    HRESULT res=S_OK;
    DWORD mkSys,mkSys2;
    IEnumMoniker* penumMk=0;
    IMoniker *pmostLeftMk=0;
    IMoniker* tempMkComposite=0;

    TRACE("(%p,%d,%p)\n", pmkRight, fOnlyIfNotGeneric, ppmkComposite);

    if ((ppmkComposite==NULL)||(pmkRight==NULL))
	return E_POINTER;

    *ppmkComposite=0;

    IMoniker_IsSystemMoniker(pmkRight,&mkSys);

    /* If pmkRight is an anti-moniker, the returned moniker is NULL */
    if(mkSys==MKSYS_ANTIMONIKER)
        return res;

    else
        /* if pmkRight is a composite whose leftmost component is an anti-moniker,           */
        /* the returned moniker is the composite after the leftmost anti-moniker is removed. */

         if(mkSys==MKSYS_GENERICCOMPOSITE){

            res=IMoniker_Enum(pmkRight,TRUE,&penumMk);

            if (FAILED(res))
                return res;

            res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);

            IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);

            if(mkSys2==MKSYS_ANTIMONIKER){

                IMoniker_Release(pmostLeftMk);

                tempMkComposite=iface;
                IMoniker_AddRef(iface);

                while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){

                    res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);

                    IMoniker_Release(tempMkComposite);
                    IMoniker_Release(pmostLeftMk);

                    tempMkComposite=*ppmkComposite;
                    IMoniker_AddRef(tempMkComposite);
                }
                return res;
            }
            else
                return CreateGenericComposite(iface,pmkRight,ppmkComposite);
         }
         /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
          composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
          a NULL moniker and a return value of MK_E_NEEDGENERIC */
          else
            if (!fOnlyIfNotGeneric)
                return CreateGenericComposite(iface,pmkRight,ppmkComposite);

            else
                return MK_E_NEEDGENERIC;
}

/******************************************************************************
 *        ClassMoniker_Enum
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
    TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);

    if (ppenumMoniker == NULL)
        return E_POINTER;

    *ppenumMoniker = NULL;

    return S_OK;
}

/******************************************************************************
 *        ClassMoniker_IsEqual
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{

    CLSID clsid;
    LPOLESTR dispName1,dispName2;
    IBindCtx* bind;
    HRESULT res = S_FALSE;

    TRACE("(%p,%p)\n",iface,pmkOtherMoniker);

    if (!pmkOtherMoniker) return S_FALSE;


    /* check if both are ClassMoniker */
    if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
    if(!IsEqualCLSID(&clsid,&CLSID_ClassMoniker)) return S_FALSE;

    /* check if both displaynames are the same */
    if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
        if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
	    if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
                if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;
                CoTaskMemFree(dispName2);
            }
            CoTaskMemFree(dispName1);
	}
    }
    return res;
}

/******************************************************************************
 *        ClassMoniker_Hash
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_Hash(IMoniker* iface,DWORD* pdwHash)
{
    ClassMoniker *This = impl_from_IMoniker(iface);

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

    *pdwHash = This->clsid.Data1;

    return S_OK;
}

/******************************************************************************
 *        ClassMoniker_IsRunning
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsRunning(IMoniker* iface,
                                         IBindCtx* pbc,
                                         IMoniker* pmkToLeft,
                                         IMoniker* pmkNewlyRunning)
{
    TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pmkNewlyRunning);

    /* as in native */
    return E_NOTIMPL;
}

/******************************************************************************
 *        ClassMoniker_GetTimeOfLastChange
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetTimeOfLastChange(IMoniker* iface,
                                                   IBindCtx* pbc,
                                                   IMoniker* pmkToLeft,
                                                   FILETIME* pItemTime)
{
    TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pItemTime);

    return MK_E_UNAVAILABLE;
}

/******************************************************************************
 *        ClassMoniker_Inverse
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_Inverse(IMoniker* iface,IMoniker** ppmk)
{
    TRACE("(%p)\n",ppmk);

    if (!ppmk)
        return E_POINTER;

    return CreateAntiMoniker(ppmk);
}

/******************************************************************************
 *        ClassMoniker_CommonPrefixWith
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
    DWORD mkSys;
    
    TRACE("(%p, %p)\n", pmkOther, ppmkPrefix);

    *ppmkPrefix = NULL;

    IMoniker_IsSystemMoniker(pmkOther, &mkSys);

    /* If the other moniker is an class moniker that is equal to this moniker, this method sets *ppmkPrefix */
    /* to this moniker and returns MK_S_US */

    if (mkSys == MKSYS_CLASSMONIKER)
    {
        if (IMoniker_IsEqual(iface, pmkOther) == S_OK)
        {
            *ppmkPrefix = iface;

            IMoniker_AddRef(iface);

            return MK_S_US;
        }
        else
            return MK_E_NOPREFIX;
    }
    else
        /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
        /* the case where the other moniker is a generic composite. */
        return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix);
}

/******************************************************************************
 *        ClassMoniker_RelativePathTo
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
    TRACE("(%p, %p)\n",pmOther,ppmkRelPath);

    if (!ppmkRelPath)
        return E_POINTER;

    *ppmkRelPath = NULL;

    return MK_E_NOTBINDABLE;
}

/******************************************************************************
 *        ClassMoniker_GetDisplayName
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetDisplayName(IMoniker* iface,
                                              IBindCtx* pbc,
                                              IMoniker* pmkToLeft,
                                              LPOLESTR *ppszDisplayName)
{
    ClassMoniker *This = impl_from_IMoniker(iface);
    static const WCHAR wszClsidPrefix[] = {'c','l','s','i','d',':',0};

    TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, ppszDisplayName);

    if (!ppszDisplayName)
        return E_POINTER;

    if (pmkToLeft)
        return E_INVALIDARG;

    *ppszDisplayName = CoTaskMemAlloc(sizeof(wszClsidPrefix) + (CHARS_IN_GUID-2) * sizeof(WCHAR));

    StringFromGUID2(&This->clsid, *ppszDisplayName+sizeof(wszClsidPrefix)/sizeof(WCHAR)-2, CHARS_IN_GUID);

    /* note: this overwrites the opening curly bracket of the CLSID string generated above */
    memcpy(*ppszDisplayName, wszClsidPrefix, sizeof(wszClsidPrefix)-sizeof(WCHAR));

    /* note: this overwrites the closing curly bracket of the CLSID string generated above */
    (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-2] = ':';
    (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-1] = '\0';

    TRACE("string is %s\n", debugstr_w(*ppszDisplayName));
    return S_OK;
}

/******************************************************************************
 *        ClassMoniker_ParseDisplayName
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_ParseDisplayName(IMoniker* iface,
                                                IBindCtx* pbc,
                                                IMoniker* pmkToLeft,
                                                LPOLESTR pszDisplayName,
                                                ULONG* pchEaten,
                                                IMoniker** ppmkOut)
{
    FIXME("(%p, %p, %s, %p, %p)\n", pbc, pmkToLeft, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
    return E_NOTIMPL;
}

/******************************************************************************
 *        ClassMoniker_IsSystemMoniker
 ******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
    TRACE("(%p,%p)\n",iface,pwdMksys);

    if (!pwdMksys)
        return E_POINTER;

    *pwdMksys = MKSYS_CLASSMONIKER;

    return S_OK;
}

/*******************************************************************************
 *        ClassMonikerIROTData_QueryInterface
 *******************************************************************************/
static HRESULT WINAPI ClassMonikerROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
{

    ClassMoniker *This = impl_from_IROTData(iface);

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

    return ClassMoniker_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
}

/***********************************************************************
 *        ClassMonikerIROTData_AddRef
 */
static ULONG WINAPI ClassMonikerROTData_AddRef(IROTData *iface)
{
    ClassMoniker *This = impl_from_IROTData(iface);

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

    return ClassMoniker_AddRef(&This->IMoniker_iface);
}

/***********************************************************************
 *        ClassMonikerIROTData_Release
 */
static ULONG WINAPI ClassMonikerROTData_Release(IROTData* iface)
{
    ClassMoniker *This = impl_from_IROTData(iface);

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

    return ClassMoniker_Release(&This->IMoniker_iface);
}

/******************************************************************************
 *        ClassMonikerIROTData_GetComparisonData
 ******************************************************************************/
static HRESULT WINAPI ClassMonikerROTData_GetComparisonData(IROTData* iface,
                                                         BYTE* pbData,
                                                         ULONG cbMax,
                                                         ULONG* pcbData)
{
    ClassMoniker *This = impl_from_IROTData(iface);

    TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);

    *pcbData = 2*sizeof(CLSID);
    if (cbMax < *pcbData)
        return E_OUTOFMEMORY;

    /* write CLSID of the moniker */
    memcpy(pbData, &CLSID_ClassMoniker, sizeof(CLSID));
    /* write CLSID the moniker represents */
    memcpy(pbData+sizeof(CLSID), &This->clsid, sizeof(CLSID));

    return S_OK;
}

/********************************************************************************/
/* Virtual function table for the ClassMoniker class which  include IPersist,*/
/* IPersistStream and IMoniker functions.                                       */
static const IMonikerVtbl ClassMonikerVtbl =
{
    ClassMoniker_QueryInterface,
    ClassMoniker_AddRef,
    ClassMoniker_Release,
    ClassMoniker_GetClassID,
    ClassMoniker_IsDirty,
    ClassMoniker_Load,
    ClassMoniker_Save,
    ClassMoniker_GetSizeMax,
    ClassMoniker_BindToObject,
    ClassMoniker_BindToStorage,
    ClassMoniker_Reduce,
    ClassMoniker_ComposeWith,
    ClassMoniker_Enum,
    ClassMoniker_IsEqual,
    ClassMoniker_Hash,
    ClassMoniker_IsRunning,
    ClassMoniker_GetTimeOfLastChange,
    ClassMoniker_Inverse,
    ClassMoniker_CommonPrefixWith,
    ClassMoniker_RelativePathTo,
    ClassMoniker_GetDisplayName,
    ClassMoniker_ParseDisplayName,
    ClassMoniker_IsSystemMoniker
};

/********************************************************************************/
/* Virtual function table for the IROTData class.                               */
static const IROTDataVtbl ROTDataVtbl =
{
    ClassMonikerROTData_QueryInterface,
    ClassMonikerROTData_AddRef,
    ClassMonikerROTData_Release,
    ClassMonikerROTData_GetComparisonData
};

/******************************************************************************
 *         ClassMoniker_Construct (local function)
 *******************************************************************************/
static HRESULT ClassMoniker_Construct(ClassMoniker* This, REFCLSID rclsid)
{
    TRACE("(%p,%s)\n",This,debugstr_guid(rclsid));

    /* Initialize the virtual function table. */
    This->IMoniker_iface.lpVtbl = &ClassMonikerVtbl;
    This->IROTData_iface.lpVtbl = &ROTDataVtbl;
    This->ref           = 0;
    This->clsid         = *rclsid;
    This->pMarshal      = NULL;

    return S_OK;
}

/******************************************************************************
 *        CreateClassMoniker	[OLE32.@]
 ******************************************************************************/
HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker **ppmk)
{
    ClassMoniker* newClassMoniker;
    HRESULT       hr;

    TRACE("(%s,%p)\n", debugstr_guid(rclsid), ppmk);

    newClassMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassMoniker));

    if (!newClassMoniker)
        return STG_E_INSUFFICIENTMEMORY;

    hr = ClassMoniker_Construct(newClassMoniker, rclsid);

    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, newClassMoniker);
        return hr;
    }

    return ClassMoniker_QueryInterface(&newClassMoniker->IMoniker_iface, &IID_IMoniker,
                                       (void**)ppmk);
}

HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten,
                                           IMoniker **ppmk)
{
    HRESULT hr;
    LPCWSTR s = strchrW(szDisplayName, ':');
    LPCWSTR end;
    CLSID clsid;
    BYTE table[256];
    int i;

    if (!s)
        return MK_E_SYNTAX;

    s++;

    for (end = s; *end && (*end != ':'); end++)
        ;

    TRACE("parsing %s\n", debugstr_wn(s, end - s));

    /* validate the CLSID string */
    if (s[0] == '{')
    {
        if ((end - s != 38) || (s[37] != '}'))
            return MK_E_SYNTAX;
        s++;
    }
    else
    {
        if (end - s != 36)
            return MK_E_SYNTAX;
    }

    for (i=0; i<36; i++)
    {
        if ((i == 8)||(i == 13)||(i == 18)||(i == 23))
        {
            if (s[i] != '-')
                return MK_E_SYNTAX;
            continue;
        }
        if (!(((s[i] >= '0') && (s[i] <= '9'))  ||
              ((s[i] >= 'a') && (s[i] <= 'f'))  ||
              ((s[i] >= 'A') && (s[i] <= 'F'))))
            return MK_E_SYNTAX;
    }

    /* quick lookup table */
    memset(table, 0, 256);

    for (i = 0; i < 10; i++)
        table['0' + i] = i;
    for (i = 0; i < 6; i++)
    {
        table['A' + i] = i+10;
        table['a' + i] = i+10;
    }

    /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */

    clsid.Data1 = (table[s[0]] << 28 | table[s[1]] << 24 | table[s[2]] << 20 | table[s[3]] << 16 |
                   table[s[4]] << 12 | table[s[5]] << 8  | table[s[6]] << 4  | table[s[7]]);
    clsid.Data2 = table[s[9]] << 12  | table[s[10]] << 8 | table[s[11]] << 4 | table[s[12]];
    clsid.Data3 = table[s[14]] << 12 | table[s[15]] << 8 | table[s[16]] << 4 | table[s[17]];

    /* these are just sequential bytes */
    clsid.Data4[0] = table[s[19]] << 4 | table[s[20]];
    clsid.Data4[1] = table[s[21]] << 4 | table[s[22]];
    clsid.Data4[2] = table[s[24]] << 4 | table[s[25]];
    clsid.Data4[3] = table[s[26]] << 4 | table[s[27]];
    clsid.Data4[4] = table[s[28]] << 4 | table[s[29]];
    clsid.Data4[5] = table[s[30]] << 4 | table[s[31]];
    clsid.Data4[6] = table[s[32]] << 4 | table[s[33]];
    clsid.Data4[7] = table[s[34]] << 4 | table[s[35]];

    hr = CreateClassMoniker(&clsid, ppmk);
    if (SUCCEEDED(hr))
        *pchEaten = (*end == ':' ? end + 1 : end) - szDisplayName;
    return hr;
}

static HRESULT WINAPI ClassMonikerCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
    {
        *ppv = iface;
        IClassFactory_AddRef(iface);
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI ClassMonikerCF_AddRef(LPCLASSFACTORY iface)
{
    return 2; /* non-heap based object */
}

static ULONG WINAPI ClassMonikerCF_Release(LPCLASSFACTORY iface)
{
    return 1; /* non-heap based object */
}

static HRESULT WINAPI ClassMonikerCF_CreateInstance(LPCLASSFACTORY iface,
    LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
    HRESULT hr;
    IMoniker *pmk;

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

    *ppv = NULL;

    if (pUnk)
        return CLASS_E_NOAGGREGATION;

    hr = CreateClassMoniker(&CLSID_NULL, &pmk);
    if (FAILED(hr)) return hr;

    hr = IMoniker_QueryInterface(pmk, riid, ppv);
    IMoniker_Release(pmk);

    return hr;
}

static HRESULT WINAPI ClassMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
    FIXME("(%d), stub!\n",fLock);
    return S_OK;
}

static const IClassFactoryVtbl ClassMonikerCFVtbl =
{
    ClassMonikerCF_QueryInterface,
    ClassMonikerCF_AddRef,
    ClassMonikerCF_Release,
    ClassMonikerCF_CreateInstance,
    ClassMonikerCF_LockServer
};
static const IClassFactoryVtbl *ClassMonikerCF = &ClassMonikerCFVtbl;

HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
    return IClassFactory_QueryInterface((IClassFactory *)&ClassMonikerCF, riid, ppv);
}
