set svn:eol-style to native
[reactos.git] / reactos / lib / ole32 / itemmoniker.c
index 8358da7..a387619 100644 (file)
-/***************************************************************************************\r
- *                           ItemMonikers implementation\r
- *\r
- *           Copyright 1999  Noomen Hamza\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- ***************************************************************************************/\r
-\r
-#include <assert.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-\r
-#define COBJMACROS\r
-#define NONAMELESSUNION\r
-#define NONAMELESSSTRUCT\r
-\r
-#include "winerror.h"\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "winuser.h"\r
-#include "winnls.h"\r
-#include "wine/debug.h"\r
-#include "ole2.h"\r
-#include "wine/unicode.h"\r
-#include "moniker.h"\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(ole);\r
-\r
-const CLSID CLSID_ItemMoniker = {\r
-  0x304, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}\r
-};\r
-\r
-/* ItemMoniker data structure */\r
-typedef struct ItemMonikerImpl{\r
-\r
-    IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/\r
-\r
-    /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether\r
-     * two monikers are equal. That's whay IROTData interface is implemented by monikers.\r
-     */\r
-    IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/\r
-\r
-    ULONG ref; /* reference counter for this object */\r
-\r
-    LPOLESTR itemName; /* item name identified by this ItemMoniker */\r
-\r
-    LPOLESTR itemDelimiter; /* Delimiter string */\r
-\r
-    IUnknown *pMarshal; /* custom marshaler */\r
-} ItemMonikerImpl;\r
-\r
-/********************************************************************************/\r
-/* ItemMoniker prototype functions :                                            */\r
-\r
-/* IUnknown prototype functions */\r
-static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);\r
-static ULONG   WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);\r
-static ULONG   WINAPI ItemMonikerImpl_Release(IMoniker* iface);\r
-\r
-/* IPersist prototype functions */\r
-static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);\r
-\r
-/* IPersistStream prototype functions */\r
-static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);\r
-static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);\r
-static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);\r
-static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);\r
-\r
-/* IMoniker prototype functions */\r
-static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);\r
-static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);\r
-static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);\r
-static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);\r
-static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);\r
-static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);\r
-static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);\r
-static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);\r
-static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);\r
-static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);\r
-static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);\r
-static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);\r
-static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);\r
-static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);\r
-static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);\r
-\r
-/* Local function used by ItemMoniker implementation */\r
-HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);\r
-HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);\r
-\r
-/********************************************************************************/\r
-/* IROTData prototype functions                                                 */\r
-\r
-/* IUnknown prototype functions */\r
-static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);\r
-static ULONG   WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);\r
-static ULONG   WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);\r
-\r
-/* IROTData prototype function */\r
-static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);\r
-\r
-/********************************************************************************/\r
-/* Virtual function table for the ItemMonikerImpl class which  include IPersist,*/\r
-/* IPersistStream and IMoniker functions.                                       */\r
-static IMonikerVtbl VT_ItemMonikerImpl =\r
-    {\r
-    ItemMonikerImpl_QueryInterface,\r
-    ItemMonikerImpl_AddRef,\r
-    ItemMonikerImpl_Release,\r
-    ItemMonikerImpl_GetClassID,\r
-    ItemMonikerImpl_IsDirty,\r
-    ItemMonikerImpl_Load,\r
-    ItemMonikerImpl_Save,\r
-    ItemMonikerImpl_GetSizeMax,\r
-    ItemMonikerImpl_BindToObject,\r
-    ItemMonikerImpl_BindToStorage,\r
-    ItemMonikerImpl_Reduce,\r
-    ItemMonikerImpl_ComposeWith,\r
-    ItemMonikerImpl_Enum,\r
-    ItemMonikerImpl_IsEqual,\r
-    ItemMonikerImpl_Hash,\r
-    ItemMonikerImpl_IsRunning,\r
-    ItemMonikerImpl_GetTimeOfLastChange,\r
-    ItemMonikerImpl_Inverse,\r
-    ItemMonikerImpl_CommonPrefixWith,\r
-    ItemMonikerImpl_RelativePathTo,\r
-    ItemMonikerImpl_GetDisplayName,\r
-    ItemMonikerImpl_ParseDisplayName,\r
-    ItemMonikerImpl_IsSystemMoniker\r
-};\r
-\r
-/********************************************************************************/\r
-/* Virtual function table for the IROTData class.                               */\r
-static IROTDataVtbl VT_ROTDataImpl =\r
-{\r
-    ItemMonikerROTDataImpl_QueryInterface,\r
-    ItemMonikerROTDataImpl_AddRef,\r
-    ItemMonikerROTDataImpl_Release,\r
-    ItemMonikerROTDataImpl_GetComparisonData\r
-};\r
-\r
-/*******************************************************************************\r
- *        ItemMoniker_QueryInterface\r
- *******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);\r
-\r
-  /* Perform a sanity check on the parameters.*/\r
-    if ( (This==0) || (ppvObject==0) )\r
-       return E_INVALIDARG;\r
-\r
-  /* Initialize the return parameter */\r
-  *ppvObject = 0;\r
-\r
-  /* Compare the riid with the interface IDs implemented by this object.*/\r
-  if (IsEqualIID(&IID_IUnknown, riid) ||\r
-      IsEqualIID(&IID_IPersist, riid) ||\r
-      IsEqualIID(&IID_IPersistStream, riid) ||\r
-      IsEqualIID(&IID_IMoniker, riid)\r
-     )\r
-      *ppvObject = iface;\r
-\r
-    else if (IsEqualIID(&IID_IROTData, riid))\r
-        *ppvObject = (IROTData*)&(This->lpvtbl2);\r
-    else if (IsEqualIID(&IID_IMarshal, riid))\r
-    {\r
-        HRESULT hr = S_OK;\r
-        if (!This->pMarshal)\r
-            hr = MonikerMarshal_Create(iface, &This->pMarshal);\r
-        if (hr != S_OK)\r
-            return hr;\r
-        return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);\r
-    }\r
-\r
-  /* Check that we obtained an interface.*/\r
-    if ((*ppvObject)==0)\r
-        return E_NOINTERFACE;\r
-\r
-   /* Query Interface always increases the reference count by one when it is successful */\r
-  ItemMonikerImpl_AddRef(iface);\r
-\r
-  return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_AddRef\r
- ******************************************************************************/\r
-ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-    TRACE("(%p)\n",This);\r
-\r
-    return InterlockedIncrement(&This->ref);\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Release\r
- ******************************************************************************/\r
-ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-    ULONG ref;\r
-\r
-    TRACE("(%p)\n",This);\r
-\r
-    ref = InterlockedDecrement(&This->ref);\r
-\r
-    /* destroy the object if there's no more reference on it */\r
-    if (ref == 0) ItemMonikerImpl_Destroy(This);\r
-\r
-    return ref;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_GetClassID\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)\r
-{\r
-    TRACE("(%p,%p)\n",iface,pClassID);\r
-\r
-    if (pClassID==NULL)\r
-        return E_POINTER;\r
-\r
-    *pClassID = CLSID_ItemMoniker;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_IsDirty\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)\r
-{\r
-    /* Note that the OLE-provided implementations of the IPersistStream::IsDirty\r
-       method in the OLE-provided moniker interfaces always return S_FALSE because\r
-       their internal state never changes. */\r
-\r
-    TRACE("(%p)\n",iface);\r
-\r
-    return S_FALSE;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Load\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)\r
-{\r
-\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-    HRESULT res;\r
-    DWORD delimiterLength,nameLength,lenW;\r
-    CHAR *itemNameA,*itemDelimiterA;\r
-    ULONG bread;\r
-\r
-    TRACE("\n");\r
-\r
-    /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */\r
-\r
-    /* read item delimiter string length + 1 */\r
-    res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);\r
-    if (bread != sizeof(DWORD))\r
-        return E_FAIL;\r
-\r
-    /* read item delimiter string */\r
-    if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))\r
-        return E_OUTOFMEMORY;\r
-    res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);\r
-    if (bread != delimiterLength)\r
-    {\r
-        HeapFree( GetProcessHeap(), 0, itemDelimiterA );\r
-        return E_FAIL;\r
-    }\r
-\r
-    lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );\r
-    This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));\r
-    if (!This->itemDelimiter)\r
-    {\r
-        HeapFree( GetProcessHeap(), 0, itemDelimiterA );\r
-        return E_OUTOFMEMORY;\r
-    }\r
-    MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );\r
-    HeapFree( GetProcessHeap(), 0, itemDelimiterA );\r
-\r
-    /* read item name string length + 1*/\r
-    res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);\r
-    if (bread != sizeof(DWORD))\r
-        return E_FAIL;\r
-\r
-    /* read item name string */\r
-    if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))\r
-        return E_OUTOFMEMORY;\r
-    res=IStream_Read(pStm,itemNameA,nameLength,&bread);\r
-    if (bread != nameLength)\r
-    {\r
-        HeapFree( GetProcessHeap(), 0, itemNameA );\r
-        return E_FAIL;\r
-    }\r
-\r
-    lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );\r
-    This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));\r
-    if (!This->itemName)\r
-    {\r
-        HeapFree( GetProcessHeap(), 0, itemNameA );\r
-        return E_OUTOFMEMORY;\r
-    }\r
-    MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );\r
-    HeapFree( GetProcessHeap(), 0, itemNameA );\r
-\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Save\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,\r
-                                    IStream* pStm,/* pointer to the stream where the object is to be saved */\r
-                                    BOOL fClearDirty)/* Specifies whether to clear the dirty flag */\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-    HRESULT res;\r
-    CHAR *itemNameA,*itemDelimiterA;\r
-\r
-    /* data written by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */\r
-    /*                                    2) String (type A): item delimiter string ('\0' included)          */\r
-    /*                                    3) DWORD : size of item name string ('\0' included)       */\r
-    /*                                    4) String (type A): item name string ('\0' included)               */\r
-\r
-    DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);\r
-    DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);\r
-    itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);\r
-    itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);\r
-    WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);\r
-    WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);\r
-\r
-    TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE");\r
-\r
-    res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);\r
-    res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);\r
-    res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);\r
-    res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);\r
-\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_GetSizeMax\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,\r
-                                          ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-    DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;\r
-    DWORD nameLength=lstrlenW(This->itemName)+1;\r
-\r
-    TRACE("(%p,%p)\n",iface,pcbSize);\r
-\r
-    if (!pcbSize)\r
-        return E_POINTER;\r
-\r
-    /* for more details see ItemMonikerImpl_Save coments */\r
-\r
-    pcbSize->u.LowPart =  sizeof(DWORD) + /* DWORD which contains delimiter length */\r
-                        delimiterLength*4 + /* item delimiter string */\r
-                        sizeof(DWORD) + /* DWORD which contains item name length */\r
-                        nameLength*4 + /* item name string */\r
-                        18; /* strange, but true */\r
-    pcbSize->u.HighPart=0;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *         ItemMoniker_Construct (local function)\r
- *******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)\r
-{\r
-\r
-    int sizeStr1=lstrlenW(lpszItem), sizeStr2;\r
-    static const OLECHAR emptystr[1];\r
-    LPCOLESTR  delim;\r
-\r
-    TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));\r
-\r
-    /* Initialize the virtual fgunction table. */\r
-    This->lpvtbl1      = &VT_ItemMonikerImpl;\r
-    This->lpvtbl2      = &VT_ROTDataImpl;\r
-    This->ref          = 0;\r
-    This->pMarshal     = NULL;\r
-\r
-    This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));\r
-    if (!This->itemName)\r
-       return E_OUTOFMEMORY;\r
-    lstrcpyW(This->itemName,lpszItem);\r
-\r
-    if (!lpszDelim)\r
-       FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");\r
-\r
-    delim = lpszDelim ? lpszDelim : emptystr;\r
-\r
-    sizeStr2=lstrlenW(delim);\r
-    This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));\r
-    if (!This->itemDelimiter) {\r
-       HeapFree(GetProcessHeap(),0,This->itemName);\r
-       return E_OUTOFMEMORY;\r
-    }\r
-    lstrcpyW(This->itemDelimiter,delim);\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Destroy (local function)\r
- *******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)\r
-{\r
-    TRACE("(%p)\n",This);\r
-\r
-    if (This->pMarshal) IUnknown_Release(This->pMarshal);\r
-    HeapFree(GetProcessHeap(),0,This->itemName);\r
-    HeapFree(GetProcessHeap(),0,This->itemDelimiter);\r
-    HeapFree(GetProcessHeap(),0,This);\r
-\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *                  ItemMoniker_BindToObject\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,\r
-                                            IBindCtx* pbc,\r
-                                            IMoniker* pmkToLeft,\r
-                                            REFIID riid,\r
-                                            VOID** ppvResult)\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-    HRESULT   res;\r
-    IID    refid=IID_IOleItemContainer;\r
-    IOleItemContainer *poic=0;\r
-\r
-    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);\r
-\r
-    if(ppvResult ==NULL)\r
-        return E_POINTER;\r
-\r
-    if(pmkToLeft==NULL)\r
-        return E_INVALIDARG;\r
-\r
-    *ppvResult=0;\r
-\r
-    res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);\r
-\r
-    if (SUCCEEDED(res)){\r
-\r
-        res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);\r
-\r
-        IOleItemContainer_Release(poic);\r
-    }\r
-\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_BindToStorage\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,\r
-                                             IBindCtx* pbc,\r
-                                             IMoniker* pmkToLeft,\r
-                                             REFIID riid,\r
-                                             VOID** ppvResult)\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-    HRESULT   res;\r
-    IOleItemContainer *poic=0;\r
-\r
-    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);\r
-\r
-    *ppvResult=0;\r
-\r
-    if(pmkToLeft==NULL)\r
-        return E_INVALIDARG;\r
-\r
-    res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);\r
-\r
-    if (SUCCEEDED(res)){\r
-\r
-        res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);\r
-\r
-        IOleItemContainer_Release(poic);\r
-    }\r
-\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Reduce\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,\r
-                                      IBindCtx* pbc,\r
-                                      DWORD dwReduceHowFar,\r
-                                      IMoniker** ppmkToLeft,\r
-                                      IMoniker** ppmkReduced)\r
-{\r
-    TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);\r
-\r
-    if (ppmkReduced==NULL)\r
-        return E_POINTER;\r
-\r
-    ItemMonikerImpl_AddRef(iface);\r
-\r
-    *ppmkReduced=iface;\r
-\r
-    return MK_S_REDUCED_TO_SELF;\r
-}\r
-/******************************************************************************\r
- *        ItemMoniker_ComposeWith\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,\r
-                                           IMoniker* pmkRight,\r
-                                           BOOL fOnlyIfNotGeneric,\r
-                                           IMoniker** ppmkComposite)\r
-{\r
-    HRESULT res=S_OK;\r
-    DWORD mkSys,mkSys2;\r
-    IEnumMoniker* penumMk=0;\r
-    IMoniker *pmostLeftMk=0;\r
-    IMoniker* tempMkComposite=0;\r
-\r
-    TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);\r
-\r
-    if ((ppmkComposite==NULL)||(pmkRight==NULL))\r
-       return E_POINTER;\r
-\r
-    *ppmkComposite=0;\r
-\r
-    IMoniker_IsSystemMoniker(pmkRight,&mkSys);\r
-\r
-    /* If pmkRight is an anti-moniker, the returned moniker is NULL */\r
-    if(mkSys==MKSYS_ANTIMONIKER)\r
-        return res;\r
-\r
-    else\r
-        /* if pmkRight is a composite whose leftmost component is an anti-moniker,           */\r
-        /* the returned moniker is the composite after the leftmost anti-moniker is removed. */\r
-\r
-         if(mkSys==MKSYS_GENERICCOMPOSITE){\r
-\r
-            res=IMoniker_Enum(pmkRight,TRUE,&penumMk);\r
-\r
-            if (FAILED(res))\r
-                return res;\r
-\r
-            res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);\r
-\r
-            IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);\r
-\r
-            if(mkSys2==MKSYS_ANTIMONIKER){\r
-\r
-                IMoniker_Release(pmostLeftMk);\r
-\r
-                tempMkComposite=iface;\r
-                IMoniker_AddRef(iface);\r
-\r
-                while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){\r
-\r
-                    res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);\r
-\r
-                    IMoniker_Release(tempMkComposite);\r
-                    IMoniker_Release(pmostLeftMk);\r
-\r
-                    tempMkComposite=*ppmkComposite;\r
-                    IMoniker_AddRef(tempMkComposite);\r
-                }\r
-                return res;\r
-            }\r
-            else\r
-                return CreateGenericComposite(iface,pmkRight,ppmkComposite);\r
-         }\r
-         /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic\r
-          composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns\r
-          a NULL moniker and a return value of MK_E_NEEDGENERIC */\r
-          else\r
-            if (!fOnlyIfNotGeneric)\r
-                return CreateGenericComposite(iface,pmkRight,ppmkComposite);\r
-\r
-            else\r
-                return MK_E_NEEDGENERIC;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Enum\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)\r
-{\r
-    TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);\r
-\r
-    if (ppenumMoniker == NULL)\r
-        return E_POINTER;\r
-\r
-    *ppenumMoniker = NULL;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_IsEqual\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)\r
-{\r
-\r
-    CLSID clsid;\r
-    LPOLESTR dispName1,dispName2;\r
-    IBindCtx* bind;\r
-    HRESULT res = S_FALSE;\r
-\r
-    TRACE("(%p,%p)\n",iface,pmkOtherMoniker);\r
-\r
-    if (!pmkOtherMoniker) return S_FALSE;\r
-\r
-\r
-    /* check if both are ItemMoniker */\r
-    if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;\r
-    if(!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) return S_FALSE;\r
-\r
-    /* check if both displaynames are the same */\r
-    if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {\r
-        if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {\r
-           if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {\r
-                if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;\r
-                CoTaskMemFree(dispName2);\r
-            }\r
-            CoTaskMemFree(dispName1);\r
-       }\r
-    }\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Hash\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-    int  h = 0,i,skip,len;\r
-    int  off = 0;\r
-    LPOLESTR val;\r
-\r
-    if (pdwHash==NULL)\r
-        return E_POINTER;\r
-\r
-    val =  This->itemName;\r
-    len = lstrlenW(val);\r
-\r
-    if (len < 16) {\r
-        for (i = len ; i > 0; i--) {\r
-            h = (h * 37) + val[off++];\r
-        }\r
-    } else {\r
-        /* only sample some characters */\r
-       skip = len / 8;\r
-       for (i = len ; i > 0; i -= skip, off += skip) {\r
-            h = (h * 39) + val[off];\r
-       }\r
-    }\r
-\r
-    *pdwHash=h;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_IsRunning\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,\r
-                                         IBindCtx* pbc,\r
-                                         IMoniker* pmkToLeft,\r
-                                         IMoniker* pmkNewlyRunning)\r
-{\r
-    IRunningObjectTable* rot;\r
-    HRESULT res;\r
-    IOleItemContainer *poic=0;\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);\r
-\r
-    /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */\r
-    /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running.              */\r
-    if (pmkToLeft==NULL)\r
-        if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))\r
-            return S_OK;\r
-        else {\r
-            if (pbc==NULL)\r
-                return E_POINTER;\r
-\r
-            res=IBindCtx_GetRunningObjectTable(pbc,&rot);\r
-\r
-            if (FAILED(res))\r
-                return res;\r
-\r
-            res = IRunningObjectTable_IsRunning(rot,iface);\r
-\r
-            IRunningObjectTable_Release(rot);\r
-        }\r
-    else{\r
-\r
-        /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter,         */\r
-        /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/\r
-        /* passing the string contained within this moniker. */\r
-\r
-        res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);\r
-\r
-        if (SUCCEEDED(res)){\r
-\r
-            res=IOleItemContainer_IsRunning(poic,This->itemName);\r
-\r
-            IOleItemContainer_Release(poic);\r
-        }\r
-    }\r
-\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_GetTimeOfLastChange\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,\r
-                                                   IBindCtx* pbc,\r
-                                                   IMoniker* pmkToLeft,\r
-                                                   FILETIME* pItemTime)\r
-{\r
-    IRunningObjectTable* rot;\r
-    HRESULT res;\r
-    IMoniker *compositeMk;\r
-\r
-    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);\r
-\r
-    if (pItemTime==NULL)\r
-        return E_INVALIDARG;\r
-\r
-    /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */\r
-    if (pmkToLeft==NULL)\r
-\r
-        return MK_E_NOTBINDABLE;\r
-    else {\r
-\r
-        /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access  */\r
-        /* the time of last change. If the object is not in the ROT, the method calls                          */\r
-        /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter.                                            */\r
-\r
-        res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);\r
-\r
-        res=IBindCtx_GetRunningObjectTable(pbc,&rot);\r
-\r
-        if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)\r
-\r
-            res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);\r
-\r
-        IMoniker_Release(compositeMk);\r
-    }\r
-\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_Inverse\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)\r
-{\r
-    TRACE("(%p,%p)\n",iface,ppmk);\r
-\r
-    if (ppmk==NULL)\r
-        return E_POINTER;\r
-\r
-    return CreateAntiMoniker(ppmk);\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_CommonPrefixWith\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)\r
-{\r
-    DWORD mkSys;\r
-    \r
-    TRACE("(%p,%p)\n", pmkOther, ppmkPrefix);\r
-\r
-    IMoniker_IsSystemMoniker(pmkOther,&mkSys);\r
-    /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */\r
-    /* to this moniker and returns MK_S_US */\r
-\r
-    if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){\r
-\r
-        *ppmkPrefix=iface;\r
-\r
-        IMoniker_AddRef(iface);\r
-\r
-        return MK_S_US;\r
-    }\r
-    else\r
-        /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */\r
-        /* the case where the other moniker is a generic composite. */\r
-        return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_RelativePathTo\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)\r
-{\r
-    TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);\r
-\r
-    if (ppmkRelPath==NULL)\r
-        return E_POINTER;\r
-\r
-    *ppmkRelPath=0;\r
-\r
-    return MK_E_NOTBINDABLE;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_GetDisplayName\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,\r
-                                              IBindCtx* pbc,\r
-                                              IMoniker* pmkToLeft,\r
-                                              LPOLESTR *ppszDisplayName)\r
-{\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);\r
-\r
-    if (ppszDisplayName==NULL)\r
-        return E_POINTER;\r
-\r
-    if (pmkToLeft!=NULL){\r
-        return E_INVALIDARG;\r
-    }\r
-\r
-    *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));\r
-\r
-    if (*ppszDisplayName==NULL)\r
-        return E_OUTOFMEMORY;\r
-\r
-    lstrcpyW(*ppszDisplayName,This->itemDelimiter);\r
-    lstrcatW(*ppszDisplayName,This->itemName);\r
-\r
-    TRACE("-- %s\n", debugstr_w(*ppszDisplayName));\r
-\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_ParseDisplayName\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,\r
-                                                IBindCtx* pbc,\r
-                                                IMoniker* pmkToLeft,\r
-                                                LPOLESTR pszDisplayName,\r
-                                                ULONG* pchEaten,\r
-                                                IMoniker** ppmkOut)\r
-{\r
-    IOleItemContainer* poic=0;\r
-    IParseDisplayName* ppdn=0;\r
-    LPOLESTR displayName;\r
-    HRESULT res;\r
-    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
-\r
-    TRACE("%s\n", debugstr_w(pszDisplayName));\r
-\r
-    /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */\r
-    if (pmkToLeft==NULL)\r
-\r
-        return MK_E_SYNTAX;\r
-\r
-    else{\r
-        /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */\r
-        /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */\r
-        /* name to IParseDisplayName::ParseDisplayName */\r
-        res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);\r
-\r
-        if (SUCCEEDED(res)){\r
-\r
-            res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);\r
-\r
-            res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);\r
-\r
-            res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);\r
-\r
-            IOleItemContainer_Release(poic);\r
-            IParseDisplayName_Release(ppdn);\r
-        }\r
-    }\r
-    return res;\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMoniker_IsSystemMoniker\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)\r
-{\r
-    TRACE("(%p,%p)\n",iface,pwdMksys);\r
-\r
-    if (!pwdMksys)\r
-        return E_POINTER;\r
-\r
-    (*pwdMksys)=MKSYS_ITEMMONIKER;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/*******************************************************************************\r
- *        ItemMonikerIROTData_QueryInterface\r
- *******************************************************************************/\r
-HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)\r
-{\r
-\r
-    ICOM_THIS_From_IROTData(IMoniker, iface);\r
-\r
-    TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);\r
-\r
-    return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);\r
-}\r
-\r
-/***********************************************************************\r
- *        ItemMonikerIROTData_AddRef\r
- */\r
-ULONG   WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)\r
-{\r
-    ICOM_THIS_From_IROTData(IMoniker, iface);\r
-\r
-    TRACE("(%p)\n",iface);\r
-\r
-    return ItemMonikerImpl_AddRef(This);\r
-}\r
-\r
-/***********************************************************************\r
- *        ItemMonikerIROTData_Release\r
- */\r
-ULONG   WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)\r
-{\r
-    ICOM_THIS_From_IROTData(IMoniker, iface);\r
-\r
-    TRACE("(%p)\n",iface);\r
-\r
-    return ItemMonikerImpl_Release(This);\r
-}\r
-\r
-/******************************************************************************\r
- *        ItemMonikerIROTData_GetComparaisonData\r
- ******************************************************************************/\r
-HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,\r
-                                                         BYTE* pbData,\r
-                                                         ULONG cbMax,\r
-                                                         ULONG* pcbData)\r
-{\r
-    ICOM_THIS_From_IROTData(IMoniker, iface);\r
-    ItemMonikerImpl *This1 = (ItemMonikerImpl *)This;\r
-    int len = (strlenW(This1->itemName)+1);\r
-    int i;\r
-    LPWSTR pszItemName;\r
-    LPWSTR pszItemDelimiter;\r
-\r
-    TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);\r
-\r
-    *pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);\r
-    if (cbMax < *pcbData)\r
-        return E_OUTOFMEMORY;\r
-\r
-    /* write CLSID */\r
-    memcpy(pbData, &CLSID_ItemMoniker, sizeof(CLSID));\r
-    /* write delimiter */\r
-    pszItemDelimiter = (LPWSTR)(pbData+sizeof(CLSID));\r
-    *pszItemDelimiter = *This1->itemDelimiter;\r
-    /* write name */\r
-    pszItemName = pszItemDelimiter + 1;\r
-    for (i = 0; i < len; i++)\r
-        pszItemName[i] = toupperW(This1->itemName[i]);\r
-\r
-    return S_OK;\r
-}\r
-\r
-/******************************************************************************\r
- *        CreateItemMoniker    [OLE32.@]\r
- ******************************************************************************/\r
-HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR  lpszItem, LPMONIKER * ppmk)\r
-{\r
-    ItemMonikerImpl* newItemMoniker;\r
-    HRESULT        hr;\r
-\r
-    TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk);\r
-\r
-    newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));\r
-\r
-    if (!newItemMoniker)\r
-        return STG_E_INSUFFICIENTMEMORY;\r
-\r
-    hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);\r
-\r
-    if (FAILED(hr)){\r
-\r
-        HeapFree(GetProcessHeap(),0,newItemMoniker);\r
-    return hr;\r
-    }\r
-\r
-    return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);\r
-}\r
-\r
-static HRESULT WINAPI ItemMonikerCF_QueryInterface(LPCLASSFACTORY iface,\r
-                                                  REFIID riid, LPVOID *ppv)\r
-{\r
-    *ppv = NULL;\r
-    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))\r
-    {\r
-        *ppv = iface;\r
-        IUnknown_AddRef(iface);\r
-        return S_OK;\r
-    }\r
-    return E_NOINTERFACE;\r
-}\r
-\r
-static ULONG WINAPI ItemMonikerCF_AddRef(LPCLASSFACTORY iface)\r
-{\r
-    return 2; /* non-heap based object */\r
-}\r
-\r
-static ULONG WINAPI ItemMonikerCF_Release(LPCLASSFACTORY iface)\r
-{\r
-    return 1; /* non-heap based object */\r
-}\r
-\r
-static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface,\r
-    LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)\r
-{\r
-    ItemMonikerImpl* newItemMoniker;\r
-    HRESULT  hr;\r
-    static const WCHAR wszEmpty[] = { 0 };\r
-\r
-    TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);\r
-\r
-    *ppv = NULL;\r
-\r
-    if (pUnk)\r
-        return CLASS_E_NOAGGREGATION;\r
-\r
-    newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));\r
-    if (!newItemMoniker)\r
-        return E_OUTOFMEMORY;\r
-\r
-    hr = ItemMonikerImpl_Construct(newItemMoniker, wszEmpty, wszEmpty);\r
-\r
-    if (SUCCEEDED(hr))\r
-       hr = ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker, riid, ppv);\r
-    if (FAILED(hr))\r
-        HeapFree(GetProcessHeap(),0,newItemMoniker);\r
-\r
-    return hr;\r
-}\r
-\r
-static HRESULT WINAPI ItemMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)\r
-{\r
-    FIXME("(%d), stub!\n",fLock);\r
-    return S_OK;\r
-}\r
-\r
-static const IClassFactoryVtbl ItemMonikerCFVtbl =\r
-{\r
-    ItemMonikerCF_QueryInterface,\r
-    ItemMonikerCF_AddRef,\r
-    ItemMonikerCF_Release,\r
-    ItemMonikerCF_CreateInstance,\r
-    ItemMonikerCF_LockServer\r
-};\r
-static const IClassFactoryVtbl *ItemMonikerCF = &ItemMonikerCFVtbl;\r
-\r
-HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv)\r
-{\r
-    return IClassFactory_QueryInterface((IClassFactory *)&ItemMonikerCF, riid, ppv);\r
-}\r
+/***************************************************************************************
+ *                           ItemMonikers implementation
+ *
+ *           Copyright 1999  Noomen Hamza
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "winnls.h"
+#include "wine/debug.h"
+#include "ole2.h"
+#include "wine/unicode.h"
+#include "moniker.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+const CLSID CLSID_ItemMoniker = {
+  0x304, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
+};
+
+/* ItemMoniker data structure */
+typedef struct ItemMonikerImpl{
+
+    IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
+
+    /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
+     * two monikers are equal. That's whay IROTData interface is implemented by monikers.
+     */
+    IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
+
+    ULONG ref; /* reference counter for this object */
+
+    LPOLESTR itemName; /* item name identified by this ItemMoniker */
+
+    LPOLESTR itemDelimiter; /* Delimiter string */
+
+    IUnknown *pMarshal; /* custom marshaler */
+} ItemMonikerImpl;
+
+/********************************************************************************/
+/* ItemMoniker prototype functions :                                            */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
+static ULONG   WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
+static ULONG   WINAPI ItemMonikerImpl_Release(IMoniker* iface);
+
+/* IPersist prototype functions */
+static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
+
+/* IPersistStream prototype functions */
+static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
+static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
+static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
+static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
+
+/* IMoniker prototype functions */
+static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
+static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
+static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
+static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
+static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
+static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
+static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
+static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
+static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);
+static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
+static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
+static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
+static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
+static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
+static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
+
+/* Local function used by ItemMoniker implementation */
+HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
+HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
+
+/********************************************************************************/
+/* IROTData prototype functions                                                 */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
+static ULONG   WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
+static ULONG   WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
+
+/* IROTData prototype function */
+static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
+
+/********************************************************************************/
+/* Virtual function table for the ItemMonikerImpl class which  include IPersist,*/
+/* IPersistStream and IMoniker functions.                                       */
+static IMonikerVtbl VT_ItemMonikerImpl =
+    {
+    ItemMonikerImpl_QueryInterface,
+    ItemMonikerImpl_AddRef,
+    ItemMonikerImpl_Release,
+    ItemMonikerImpl_GetClassID,
+    ItemMonikerImpl_IsDirty,
+    ItemMonikerImpl_Load,
+    ItemMonikerImpl_Save,
+    ItemMonikerImpl_GetSizeMax,
+    ItemMonikerImpl_BindToObject,
+    ItemMonikerImpl_BindToStorage,
+    ItemMonikerImpl_Reduce,
+    ItemMonikerImpl_ComposeWith,
+    ItemMonikerImpl_Enum,
+    ItemMonikerImpl_IsEqual,
+    ItemMonikerImpl_Hash,
+    ItemMonikerImpl_IsRunning,
+    ItemMonikerImpl_GetTimeOfLastChange,
+    ItemMonikerImpl_Inverse,
+    ItemMonikerImpl_CommonPrefixWith,
+    ItemMonikerImpl_RelativePathTo,
+    ItemMonikerImpl_GetDisplayName,
+    ItemMonikerImpl_ParseDisplayName,
+    ItemMonikerImpl_IsSystemMoniker
+};
+
+/********************************************************************************/
+/* Virtual function table for the IROTData class.                               */
+static IROTDataVtbl VT_ROTDataImpl =
+{
+    ItemMonikerROTDataImpl_QueryInterface,
+    ItemMonikerROTDataImpl_AddRef,
+    ItemMonikerROTDataImpl_Release,
+    ItemMonikerROTDataImpl_GetComparisonData
+};
+
+/*******************************************************************************
+ *        ItemMoniker_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
+
+  /* Perform a sanity check on the parameters.*/
+    if ( (This==0) || (ppvObject==0) )
+       return E_INVALIDARG;
+
+  /* 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 = (IROTData*)&(This->lpvtbl2);
+    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)==0)
+        return E_NOINTERFACE;
+
+   /* Query Interface always increases the reference count by one when it is successful */
+  ItemMonikerImpl_AddRef(iface);
+
+  return S_OK;
+}
+
+/******************************************************************************
+ *        ItemMoniker_AddRef
+ ******************************************************************************/
+ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+    TRACE("(%p)\n",This);
+
+    return InterlockedIncrement(&This->ref);
+}
+
+/******************************************************************************
+ *        ItemMoniker_Release
+ ******************************************************************************/
+ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)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) ItemMonikerImpl_Destroy(This);
+
+    return ref;
+}
+
+/******************************************************************************
+ *        ItemMoniker_GetClassID
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
+{
+    TRACE("(%p,%p)\n",iface,pClassID);
+
+    if (pClassID==NULL)
+        return E_POINTER;
+
+    *pClassID = CLSID_ItemMoniker;
+
+    return S_OK;
+}
+
+/******************************************************************************
+ *        ItemMoniker_IsDirty
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_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;
+}
+
+/******************************************************************************
+ *        ItemMoniker_Load
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
+{
+
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+    HRESULT res;
+    DWORD delimiterLength,nameLength,lenW;
+    CHAR *itemNameA,*itemDelimiterA;
+    ULONG bread;
+
+    TRACE("\n");
+
+    /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
+
+    /* read item delimiter string length + 1 */
+    res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
+    if (bread != sizeof(DWORD))
+        return E_FAIL;
+
+    /* read item delimiter string */
+    if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))
+        return E_OUTOFMEMORY;
+    res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
+    if (bread != delimiterLength)
+    {
+        HeapFree( GetProcessHeap(), 0, itemDelimiterA );
+        return E_FAIL;
+    }
+
+    lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );
+    This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));
+    if (!This->itemDelimiter)
+    {
+        HeapFree( GetProcessHeap(), 0, itemDelimiterA );
+        return E_OUTOFMEMORY;
+    }
+    MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );
+    HeapFree( GetProcessHeap(), 0, itemDelimiterA );
+
+    /* read item name string length + 1*/
+    res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
+    if (bread != sizeof(DWORD))
+        return E_FAIL;
+
+    /* read item name string */
+    if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))
+        return E_OUTOFMEMORY;
+    res=IStream_Read(pStm,itemNameA,nameLength,&bread);
+    if (bread != nameLength)
+    {
+        HeapFree( GetProcessHeap(), 0, itemNameA );
+        return E_FAIL;
+    }
+
+    lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );
+    This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));
+    if (!This->itemName)
+    {
+        HeapFree( GetProcessHeap(), 0, itemNameA );
+        return E_OUTOFMEMORY;
+    }
+    MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );
+    HeapFree( GetProcessHeap(), 0, itemNameA );
+
+    return res;
+}
+
+/******************************************************************************
+ *        ItemMoniker_Save
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
+                                    IStream* pStm,/* pointer to the stream where the object is to be saved */
+                                    BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+    HRESULT res;
+    CHAR *itemNameA,*itemDelimiterA;
+
+    /* data written by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
+    /*                                    2) String (type A): item delimiter string ('\0' included)          */
+    /*                                    3) DWORD : size of item name string ('\0' included)       */
+    /*                                    4) String (type A): item name string ('\0' included)               */
+
+    DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);
+    DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);
+    itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
+    itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
+    WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
+    WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
+
+    TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE");
+
+    res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
+    res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
+    res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
+    res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
+
+    return res;
+}
+
+/******************************************************************************
+ *        ItemMoniker_GetSizeMax
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
+                                          ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+    DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
+    DWORD nameLength=lstrlenW(This->itemName)+1;
+
+    TRACE("(%p,%p)\n",iface,pcbSize);
+
+    if (!pcbSize)
+        return E_POINTER;
+
+    /* for more details see ItemMonikerImpl_Save coments */
+
+    pcbSize->u.LowPart =  sizeof(DWORD) + /* DWORD which contains delimiter length */
+                        delimiterLength*4 + /* item delimiter string */
+                        sizeof(DWORD) + /* DWORD which contains item name length */
+                        nameLength*4 + /* item name string */
+                        18; /* strange, but true */
+    pcbSize->u.HighPart=0;
+
+    return S_OK;
+}
+
+/******************************************************************************
+ *         ItemMoniker_Construct (local function)
+ *******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
+{
+
+    int sizeStr1=lstrlenW(lpszItem), sizeStr2;
+    static const OLECHAR emptystr[1];
+    LPCOLESTR  delim;
+
+    TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));
+
+    /* Initialize the virtual fgunction table. */
+    This->lpvtbl1      = &VT_ItemMonikerImpl;
+    This->lpvtbl2      = &VT_ROTDataImpl;
+    This->ref          = 0;
+    This->pMarshal     = NULL;
+
+    This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
+    if (!This->itemName)
+       return E_OUTOFMEMORY;
+    lstrcpyW(This->itemName,lpszItem);
+
+    if (!lpszDelim)
+       FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
+
+    delim = lpszDelim ? lpszDelim : emptystr;
+
+    sizeStr2=lstrlenW(delim);
+    This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
+    if (!This->itemDelimiter) {
+       HeapFree(GetProcessHeap(),0,This->itemName);
+       return E_OUTOFMEMORY;
+    }
+    lstrcpyW(This->itemDelimiter,delim);
+    return S_OK;
+}
+
+/******************************************************************************
+ *        ItemMoniker_Destroy (local function)
+ *******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
+{
+    TRACE("(%p)\n",This);
+
+    if (This->pMarshal) IUnknown_Release(This->pMarshal);
+    HeapFree(GetProcessHeap(),0,This->itemName);
+    HeapFree(GetProcessHeap(),0,This->itemDelimiter);
+    HeapFree(GetProcessHeap(),0,This);
+
+    return S_OK;
+}
+
+/******************************************************************************
+ *                  ItemMoniker_BindToObject
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
+                                            IBindCtx* pbc,
+                                            IMoniker* pmkToLeft,
+                                            REFIID riid,
+                                            VOID** ppvResult)
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+    HRESULT   res;
+    IID    refid=IID_IOleItemContainer;
+    IOleItemContainer *poic=0;
+
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
+
+    if(ppvResult ==NULL)
+        return E_POINTER;
+
+    if(pmkToLeft==NULL)
+        return E_INVALIDARG;
+
+    *ppvResult=0;
+
+    res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
+
+    if (SUCCEEDED(res)){
+
+        res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
+
+        IOleItemContainer_Release(poic);
+    }
+
+    return res;
+}
+
+/******************************************************************************
+ *        ItemMoniker_BindToStorage
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
+                                             IBindCtx* pbc,
+                                             IMoniker* pmkToLeft,
+                                             REFIID riid,
+                                             VOID** ppvResult)
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+    HRESULT   res;
+    IOleItemContainer *poic=0;
+
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
+
+    *ppvResult=0;
+
+    if(pmkToLeft==NULL)
+        return E_INVALIDARG;
+
+    res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
+
+    if (SUCCEEDED(res)){
+
+        res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
+
+        IOleItemContainer_Release(poic);
+    }
+
+    return res;
+}
+
+/******************************************************************************
+ *        ItemMoniker_Reduce
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
+                                      IBindCtx* pbc,
+                                      DWORD dwReduceHowFar,
+                                      IMoniker** ppmkToLeft,
+                                      IMoniker** ppmkReduced)
+{
+    TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
+
+    if (ppmkReduced==NULL)
+        return E_POINTER;
+
+    ItemMonikerImpl_AddRef(iface);
+
+    *ppmkReduced=iface;
+
+    return MK_S_REDUCED_TO_SELF;
+}
+/******************************************************************************
+ *        ItemMoniker_ComposeWith
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_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,%p,%d,%p)\n",iface,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;
+}
+
+/******************************************************************************
+ *        ItemMoniker_Enum
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_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;
+}
+
+/******************************************************************************
+ *        ItemMoniker_IsEqual
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_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 ItemMoniker */
+    if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
+    if(!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) 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;
+}
+
+/******************************************************************************
+ *        ItemMoniker_Hash
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+    int  h = 0,i,skip,len;
+    int  off = 0;
+    LPOLESTR val;
+
+    if (pdwHash==NULL)
+        return E_POINTER;
+
+    val =  This->itemName;
+    len = lstrlenW(val);
+
+    if (len < 16) {
+        for (i = len ; i > 0; i--) {
+            h = (h * 37) + val[off++];
+        }
+    } else {
+        /* only sample some characters */
+       skip = len / 8;
+       for (i = len ; i > 0; i -= skip, off += skip) {
+            h = (h * 39) + val[off];
+       }
+    }
+
+    *pdwHash=h;
+
+    return S_OK;
+}
+
+/******************************************************************************
+ *        ItemMoniker_IsRunning
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
+                                         IBindCtx* pbc,
+                                         IMoniker* pmkToLeft,
+                                         IMoniker* pmkNewlyRunning)
+{
+    IRunningObjectTable* rot;
+    HRESULT res;
+    IOleItemContainer *poic=0;
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
+
+    /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
+    /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running.              */
+    if (pmkToLeft==NULL)
+        if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
+            return S_OK;
+        else {
+            if (pbc==NULL)
+                return E_POINTER;
+
+            res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+            if (FAILED(res))
+                return res;
+
+            res = IRunningObjectTable_IsRunning(rot,iface);
+
+            IRunningObjectTable_Release(rot);
+        }
+    else{
+
+        /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter,         */
+        /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
+        /* passing the string contained within this moniker. */
+
+        res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
+
+        if (SUCCEEDED(res)){
+
+            res=IOleItemContainer_IsRunning(poic,This->itemName);
+
+            IOleItemContainer_Release(poic);
+        }
+    }
+
+    return res;
+}
+
+/******************************************************************************
+ *        ItemMoniker_GetTimeOfLastChange
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
+                                                   IBindCtx* pbc,
+                                                   IMoniker* pmkToLeft,
+                                                   FILETIME* pItemTime)
+{
+    IRunningObjectTable* rot;
+    HRESULT res;
+    IMoniker *compositeMk;
+
+    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
+
+    if (pItemTime==NULL)
+        return E_INVALIDARG;
+
+    /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
+    if (pmkToLeft==NULL)
+
+        return MK_E_NOTBINDABLE;
+    else {
+
+        /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access  */
+        /* the time of last change. If the object is not in the ROT, the method calls                          */
+        /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter.                                            */
+
+        res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
+
+        res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+        if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
+
+            res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
+
+        IMoniker_Release(compositeMk);
+    }
+
+    return res;
+}
+
+/******************************************************************************
+ *        ItemMoniker_Inverse
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
+{
+    TRACE("(%p,%p)\n",iface,ppmk);
+
+    if (ppmk==NULL)
+        return E_POINTER;
+
+    return CreateAntiMoniker(ppmk);
+}
+
+/******************************************************************************
+ *        ItemMoniker_CommonPrefixWith
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
+{
+    DWORD mkSys;
+    
+    TRACE("(%p,%p)\n", pmkOther, ppmkPrefix);
+
+    IMoniker_IsSystemMoniker(pmkOther,&mkSys);
+    /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
+    /* to this moniker and returns MK_S_US */
+
+    if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
+
+        *ppmkPrefix=iface;
+
+        IMoniker_AddRef(iface);
+
+        return MK_S_US;
+    }
+    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);
+}
+
+/******************************************************************************
+ *        ItemMoniker_RelativePathTo
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
+{
+    TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
+
+    if (ppmkRelPath==NULL)
+        return E_POINTER;
+
+    *ppmkRelPath=0;
+
+    return MK_E_NOTBINDABLE;
+}
+
+/******************************************************************************
+ *        ItemMoniker_GetDisplayName
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
+                                              IBindCtx* pbc,
+                                              IMoniker* pmkToLeft,
+                                              LPOLESTR *ppszDisplayName)
+{
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
+
+    if (ppszDisplayName==NULL)
+        return E_POINTER;
+
+    if (pmkToLeft!=NULL){
+        return E_INVALIDARG;
+    }
+
+    *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
+
+    if (*ppszDisplayName==NULL)
+        return E_OUTOFMEMORY;
+
+    lstrcpyW(*ppszDisplayName,This->itemDelimiter);
+    lstrcatW(*ppszDisplayName,This->itemName);
+
+    TRACE("-- %s\n", debugstr_w(*ppszDisplayName));
+
+    return S_OK;
+}
+
+/******************************************************************************
+ *        ItemMoniker_ParseDisplayName
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
+                                                IBindCtx* pbc,
+                                                IMoniker* pmkToLeft,
+                                                LPOLESTR pszDisplayName,
+                                                ULONG* pchEaten,
+                                                IMoniker** ppmkOut)
+{
+    IOleItemContainer* poic=0;
+    IParseDisplayName* ppdn=0;
+    LPOLESTR displayName;
+    HRESULT res;
+    ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+    TRACE("%s\n", debugstr_w(pszDisplayName));
+
+    /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
+    if (pmkToLeft==NULL)
+
+        return MK_E_SYNTAX;
+
+    else{
+        /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
+        /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */
+        /* name to IParseDisplayName::ParseDisplayName */
+        res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
+
+        if (SUCCEEDED(res)){
+
+            res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
+
+            res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
+
+            res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
+
+            IOleItemContainer_Release(poic);
+            IParseDisplayName_Release(ppdn);
+        }
+    }
+    return res;
+}
+
+/******************************************************************************
+ *        ItemMoniker_IsSystemMoniker
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
+{
+    TRACE("(%p,%p)\n",iface,pwdMksys);
+
+    if (!pwdMksys)
+        return E_POINTER;
+
+    (*pwdMksys)=MKSYS_ITEMMONIKER;
+
+    return S_OK;
+}
+
+/*******************************************************************************
+ *        ItemMonikerIROTData_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
+{
+
+    ICOM_THIS_From_IROTData(IMoniker, iface);
+
+    TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
+
+    return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
+}
+
+/***********************************************************************
+ *        ItemMonikerIROTData_AddRef
+ */
+ULONG   WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
+{
+    ICOM_THIS_From_IROTData(IMoniker, iface);
+
+    TRACE("(%p)\n",iface);
+
+    return ItemMonikerImpl_AddRef(This);
+}
+
+/***********************************************************************
+ *        ItemMonikerIROTData_Release
+ */
+ULONG   WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
+{
+    ICOM_THIS_From_IROTData(IMoniker, iface);
+
+    TRACE("(%p)\n",iface);
+
+    return ItemMonikerImpl_Release(This);
+}
+
+/******************************************************************************
+ *        ItemMonikerIROTData_GetComparaisonData
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
+                                                         BYTE* pbData,
+                                                         ULONG cbMax,
+                                                         ULONG* pcbData)
+{
+    ICOM_THIS_From_IROTData(IMoniker, iface);
+    ItemMonikerImpl *This1 = (ItemMonikerImpl *)This;
+    int len = (strlenW(This1->itemName)+1);
+    int i;
+    LPWSTR pszItemName;
+    LPWSTR pszItemDelimiter;
+
+    TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
+
+    *pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);
+    if (cbMax < *pcbData)
+        return E_OUTOFMEMORY;
+
+    /* write CLSID */
+    memcpy(pbData, &CLSID_ItemMoniker, sizeof(CLSID));
+    /* write delimiter */
+    pszItemDelimiter = (LPWSTR)(pbData+sizeof(CLSID));
+    *pszItemDelimiter = *This1->itemDelimiter;
+    /* write name */
+    pszItemName = pszItemDelimiter + 1;
+    for (i = 0; i < len; i++)
+        pszItemName[i] = toupperW(This1->itemName[i]);
+
+    return S_OK;
+}
+
+/******************************************************************************
+ *        CreateItemMoniker    [OLE32.@]
+ ******************************************************************************/
+HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR  lpszItem, LPMONIKER * ppmk)
+{
+    ItemMonikerImpl* newItemMoniker;
+    HRESULT        hr;
+
+    TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk);
+
+    newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
+
+    if (!newItemMoniker)
+        return STG_E_INSUFFICIENTMEMORY;
+
+    hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
+
+    if (FAILED(hr)){
+
+        HeapFree(GetProcessHeap(),0,newItemMoniker);
+    return hr;
+    }
+
+    return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);
+}
+
+static HRESULT WINAPI ItemMonikerCF_QueryInterface(LPCLASSFACTORY iface,
+                                                  REFIID riid, LPVOID *ppv)
+{
+    *ppv = NULL;
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
+    {
+        *ppv = iface;
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ItemMonikerCF_AddRef(LPCLASSFACTORY iface)
+{
+    return 2; /* non-heap based object */
+}
+
+static ULONG WINAPI ItemMonikerCF_Release(LPCLASSFACTORY iface)
+{
+    return 1; /* non-heap based object */
+}
+
+static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface,
+    LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
+{
+    ItemMonikerImpl* newItemMoniker;
+    HRESULT  hr;
+    static const WCHAR wszEmpty[] = { 0 };
+
+    TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (pUnk)
+        return CLASS_E_NOAGGREGATION;
+
+    newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
+    if (!newItemMoniker)
+        return E_OUTOFMEMORY;
+
+    hr = ItemMonikerImpl_Construct(newItemMoniker, wszEmpty, wszEmpty);
+
+    if (SUCCEEDED(hr))
+       hr = ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker, riid, ppv);
+    if (FAILED(hr))
+        HeapFree(GetProcessHeap(),0,newItemMoniker);
+
+    return hr;
+}
+
+static HRESULT WINAPI ItemMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
+{
+    FIXME("(%d), stub!\n",fLock);
+    return S_OK;
+}
+
+static const IClassFactoryVtbl ItemMonikerCFVtbl =
+{
+    ItemMonikerCF_QueryInterface,
+    ItemMonikerCF_AddRef,
+    ItemMonikerCF_Release,
+    ItemMonikerCF_CreateInstance,
+    ItemMonikerCF_LockServer
+};
+static const IClassFactoryVtbl *ItemMonikerCF = &ItemMonikerCFVtbl;
+
+HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv)
+{
+    return IClassFactory_QueryInterface((IClassFactory *)&ItemMonikerCF, riid, ppv);
+}