/*
 * Implementation of hyperlinking (hlink.dll)
 *
 * Copyright 2005 Aric Stewart for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "hlink_private.h"

#include "shellapi.h"
#include "hlguids.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(hlink);

#define HLINK_SAVE_MAGIC    0x00000002
#define HLINK_SAVE_MONIKER_PRESENT      0x01
#define HLINK_SAVE_MONIKER_IS_ABSOLUTE  0x02
#define HLINK_SAVE_LOCATION_PRESENT     0x08
#define HLINK_SAVE_FRIENDLY_PRESENT     0x10
/* 0x20, 0x40 unknown */
#define HLINK_SAVE_TARGET_FRAME_PRESENT 0x80
/* known flags */
#define HLINK_SAVE_ALL (HLINK_SAVE_TARGET_FRAME_PRESENT|HLINK_SAVE_FRIENDLY_PRESENT|HLINK_SAVE_LOCATION_PRESENT|0x04|HLINK_SAVE_MONIKER_IS_ABSOLUTE|HLINK_SAVE_MONIKER_PRESENT)

static const IHlinkVtbl              hlvt;
static const IPersistStreamVtbl      psvt;
static const IDataObjectVtbl         dovt;

typedef struct
{
    const IHlinkVtbl    *lpVtbl;
    LONG                ref;

    const IPersistStreamVtbl    *lpPSVtbl;
    const IDataObjectVtbl       *lpDOVtbl;

    LPWSTR              FriendlyName;
    LPWSTR              Location;
    LPWSTR              TargetFrameName;
    IMoniker            *Moniker;
    IHlinkSite          *Site;
    DWORD               SiteData;
    BOOL                absolute;
} HlinkImpl;


static inline HlinkImpl* HlinkImpl_from_IPersistStream( IPersistStream* iface)
{
    return (HlinkImpl*) ((CHAR*)iface - FIELD_OFFSET(HlinkImpl, lpPSVtbl));
}

static inline HlinkImpl* HlinkImpl_from_IDataObject( IDataObject* iface)
{
    return (HlinkImpl*) ((CHAR*)iface - FIELD_OFFSET(HlinkImpl, lpDOVtbl));
}

static inline void __GetMoniker(HlinkImpl* This, IMoniker** moniker)
{
    *moniker = NULL;
    if (This->Moniker)
    {
        *moniker = This->Moniker;
        if (*moniker)
            IMoniker_AddRef(*moniker);
    }
    else if (This->Site)
    {
        IHlinkSite_GetMoniker(This->Site, This->SiteData,
                OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, moniker);
    }
}

HRESULT WINAPI HLink_Constructor(IUnknown *pUnkOuter, REFIID riid,
        LPVOID *ppv)
{
    HlinkImpl * hl;

    TRACE("unkOut=%p riid=%s\n", pUnkOuter, debugstr_guid(riid));
    *ppv = NULL;

    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    hl = heap_alloc_zero(sizeof(HlinkImpl));
    if (!hl)
        return E_OUTOFMEMORY;

    hl->ref = 1;
    hl->lpVtbl = &hlvt;
    hl->lpPSVtbl = &psvt;
    hl->lpDOVtbl = &dovt;

    *ppv = hl;
    return S_OK;
}

static HRESULT WINAPI IHlink_fnQueryInterface(IHlink* iface, REFIID riid,
        LPVOID *ppvObj)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppvObj);

    *ppvObj = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || (IsEqualIID(riid, &IID_IHlink)))
        *ppvObj = This;
    else if (IsEqualIID(riid, &IID_IPersistStream))
        *ppvObj = &(This->lpPSVtbl);
    else if (IsEqualIID(riid, &IID_IDataObject))
        *ppvObj = &(This->lpDOVtbl);

    if (*ppvObj)
    {
        IUnknown_AddRef((IUnknown*)(*ppvObj));
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI IHlink_fnAddRef (IHlink* iface)
{
    HlinkImpl  *This = (HlinkImpl*)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(count=%u)\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IHlink_fnRelease (IHlink* iface)
{
    HlinkImpl  *This = (HlinkImpl*)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(count=%u)\n", This, refCount + 1);
    if (refCount)
        return refCount;

    TRACE("-- destroying IHlink (%p)\n", This);
    heap_free(This->FriendlyName);
    heap_free(This->TargetFrameName);
    heap_free(This->Location);
    if (This->Moniker)
        IMoniker_Release(This->Moniker);
    if (This->Site)
        IHlinkSite_Release(This->Site);
    heap_free(This);
    return 0;
}

static HRESULT WINAPI IHlink_fnSetHlinkSite( IHlink* iface,
        IHlinkSite* pihlSite, DWORD dwSiteData)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p)->(%p %i)\n", This, pihlSite, dwSiteData);

    if (This->Site)
        IHlinkSite_Release(This->Site);

    This->Site = pihlSite;
    if (This->Site)
        IHlinkSite_AddRef(This->Site);

    This->SiteData = dwSiteData;

    return S_OK;
}

static HRESULT WINAPI IHlink_fnGetHlinkSite( IHlink* iface,
        IHlinkSite** ppihlSite, DWORD *pdwSiteData)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p)->(%p %p)\n", This, ppihlSite, pdwSiteData);

    *ppihlSite = This->Site;
    *pdwSiteData = This->SiteData;

    if (This->Site)
        IHlinkSite_AddRef(This->Site);

    return S_OK;
}

static HRESULT WINAPI IHlink_fnSetMonikerReference( IHlink* iface,
        DWORD rfHLSETF, IMoniker *pmkTarget, LPCWSTR pwzLocation)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p)->(%i %p %s)\n", This, rfHLSETF, pmkTarget,
            debugstr_w(pwzLocation));

    if(rfHLSETF == 0)
        return E_INVALIDARG;
    if(!(rfHLSETF & (HLINKSETF_TARGET | HLINKSETF_LOCATION)))
        return rfHLSETF;

    if(rfHLSETF & HLINKSETF_TARGET){
        if (This->Moniker)
            IMoniker_Release(This->Moniker);

        This->Moniker = pmkTarget;
        if (This->Moniker)
        {
            LPOLESTR display_name;
            IMoniker_AddRef(This->Moniker);
            IMoniker_GetDisplayName(This->Moniker, NULL, NULL, &display_name);
            This->absolute = display_name && strchrW(display_name, ':');
            CoTaskMemFree(display_name);
        }
    }

    if(rfHLSETF & HLINKSETF_LOCATION){
        heap_free(This->Location);
        This->Location = hlink_strdupW( pwzLocation );
    }

    return S_OK;
}

static HRESULT WINAPI IHlink_fnSetStringReference(IHlink* iface,
        DWORD grfHLSETF, LPCWSTR pwzTarget, LPCWSTR pwzLocation)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p)->(%i %s %s)\n", This, grfHLSETF, debugstr_w(pwzTarget),
            debugstr_w(pwzLocation));

    if(grfHLSETF > (HLINKSETF_TARGET | HLINKSETF_LOCATION) &&
            grfHLSETF < -(HLINKSETF_TARGET | HLINKSETF_LOCATION))
        return grfHLSETF;

    if (grfHLSETF & HLINKSETF_TARGET)
    {
        if (This->Moniker)
        {
            IMoniker_Release(This->Moniker);
            This->Moniker = NULL;
        }
        if (pwzTarget && *pwzTarget)
        {
            IMoniker *pMon;
            IBindCtx *pbc = NULL;
            ULONG eaten;
            HRESULT r;

            r = CreateBindCtx(0, &pbc);
            if (FAILED(r))
                return E_OUTOFMEMORY;

            r = MkParseDisplayName(pbc, pwzTarget, &eaten, &pMon);
            IBindCtx_Release(pbc);

            if (FAILED(r))
            {
                LPCWSTR p = strchrW(pwzTarget, ':');
                if (p && (p - pwzTarget > 1))
                    r = CreateURLMoniker(NULL, pwzTarget, &pMon);
                else
                    r = CreateFileMoniker(pwzTarget, &pMon);
                if (FAILED(r))
                {
                    ERR("couldn't create moniker for %s, failed with error 0x%08x\n",
                        debugstr_w(pwzTarget), r);
                    return r;
                }
            }

            IHlink_SetMonikerReference(iface, HLINKSETF_TARGET, pMon, NULL);
            IMoniker_Release(pMon);
        }
    }

    if (grfHLSETF & HLINKSETF_LOCATION)
    {
        heap_free(This->Location);
        This->Location = NULL;
        if (pwzLocation && *pwzLocation)
            This->Location = hlink_strdupW( pwzLocation );
    }

    return S_OK;
}

static HRESULT WINAPI IHlink_fnGetMonikerReference(IHlink* iface,
        DWORD dwWhichRef, IMoniker **ppimkTarget, LPWSTR *ppwzLocation)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppimkTarget,
            ppwzLocation);

    if(ppimkTarget)
        __GetMoniker(This, ppimkTarget);

    if (ppwzLocation)
        IHlink_GetStringReference(iface, dwWhichRef, NULL, ppwzLocation);

    return S_OK;
}

static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface,
        DWORD dwWhichRef, LPWSTR *ppwzTarget, LPWSTR *ppwzLocation)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppwzTarget, ppwzLocation);

    /* note: undocumented behavior with dwWhichRef == -1 */
    if(dwWhichRef != -1 && dwWhichRef & ~(HLINKGETREF_DEFAULT | HLINKGETREF_ABSOLUTE | HLINKGETREF_RELATIVE))
    {
        if(ppwzTarget)
            *ppwzTarget = NULL;
        if(ppwzLocation)
            *ppwzLocation = NULL;
        return E_INVALIDARG;
    }

    if(dwWhichRef != HLINKGETREF_DEFAULT)
        FIXME("unhandled flags: 0x%x\n", dwWhichRef);

    if (ppwzTarget)
    {
        IMoniker* mon;
        __GetMoniker(This, &mon);
        if (mon)
        {
            IBindCtx *pbc;

            CreateBindCtx( 0, &pbc);
            IMoniker_GetDisplayName(mon, pbc, NULL, ppwzTarget);
            IBindCtx_Release(pbc);
            IMoniker_Release(mon);
        }
        else
            *ppwzTarget = NULL;
    }
    if (ppwzLocation)
        *ppwzLocation = hlink_co_strdupW( This->Location );

    TRACE("(Target: %s Location: %s)\n",
            (ppwzTarget)?debugstr_w(*ppwzTarget):"<NULL>",
            (ppwzLocation)?debugstr_w(*ppwzLocation):"<NULL>");

    return S_OK;
}

static HRESULT WINAPI IHlink_fnSetFriendlyName (IHlink *iface,
        LPCWSTR pwzFriendlyName)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p) -> (%s)\n", This, debugstr_w(pwzFriendlyName));

    heap_free(This->FriendlyName);
    This->FriendlyName = hlink_strdupW( pwzFriendlyName );

    return S_OK;
}

static HRESULT WINAPI IHlink_fnGetFriendlyName (IHlink* iface,
        DWORD grfHLFNAMEF, LPWSTR* ppwzFriendlyName)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p) -> (%i %p)\n", This, grfHLFNAMEF, ppwzFriendlyName);

    /* FIXME: Only using explicitly set and cached friendly names */

    if (This->FriendlyName)
        *ppwzFriendlyName = hlink_co_strdupW( This->FriendlyName );
    else
    {
        IMoniker *moniker;
        __GetMoniker(This, &moniker);
        if (moniker)
        {
            IBindCtx *bcxt;
            CreateBindCtx(0, &bcxt);

            IMoniker_GetDisplayName(moniker, bcxt, NULL, ppwzFriendlyName);
            IBindCtx_Release(bcxt);
            IMoniker_Release(moniker);
        }
        else
            *ppwzFriendlyName = NULL;
    }

    return S_OK;
}

static HRESULT WINAPI IHlink_fnSetTargetFrameName(IHlink* iface,
        LPCWSTR pwzTargetFramename)
{
    HlinkImpl  *This = (HlinkImpl*)iface;
    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzTargetFramename));

    heap_free(This->TargetFrameName);
    This->TargetFrameName = hlink_strdupW( pwzTargetFramename );

    return S_OK;
}

static HRESULT WINAPI IHlink_fnGetTargetFrameName(IHlink* iface,
        LPWSTR *ppwzTargetFrameName)
{
    HlinkImpl  *This = (HlinkImpl*)iface;

    TRACE("(%p)->(%p)\n", This, ppwzTargetFrameName);
    *ppwzTargetFrameName = hlink_co_strdupW( This->TargetFrameName );

    return S_OK;
}

static HRESULT WINAPI IHlink_fnGetMiscStatus(IHlink* iface, DWORD* pdwStatus)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc,
        IBindStatusCallback *pbsc, IHlinkBrowseContext *phbc)
{
    HlinkImpl  *This = (HlinkImpl*)iface;
    IMoniker *mon = NULL;

    FIXME("Semi-Stub:(%p)->(%i %p %p %p)\n", This, grfHLNF, pbc, pbsc, phbc);

    if (This->Site)
        IHlinkSite_ReadyToNavigate(This->Site, This->SiteData, 0);

    __GetMoniker(This, &mon);
    TRACE("Moniker %p\n", mon);

    if (mon)
    {
        IBindCtx *bcxt;
        IHlinkTarget *target = NULL;
        HRESULT r = S_OK;

        CreateBindCtx(0, &bcxt);

        RegisterBindStatusCallback(bcxt, pbsc, NULL, 0);

        r = IMoniker_BindToObject(mon, bcxt, NULL, &IID_IHlinkTarget,
                (LPVOID*)&target);
        TRACE("IHlinkTarget returned 0x%x\n", r);
        if (r == S_OK)
        {
            IHlinkTarget_SetBrowseContext(target, phbc);
            IHlinkTarget_Navigate(target, grfHLNF, This->Location);
            IHlinkTarget_Release(target);
        }
        else
        {
            static const WCHAR szOpen[] = {'o','p','e','n',0};
            LPWSTR target = NULL;

            r = IHlink_GetStringReference(iface, HLINKGETREF_DEFAULT, &target, NULL);
            if (SUCCEEDED(r) && target)
            {
                ShellExecuteW(NULL, szOpen, target, NULL, NULL, SW_SHOW);
                CoTaskMemFree(target);
            }
        }

        RevokeBindStatusCallback(bcxt, pbsc);

        IBindCtx_Release(bcxt);
        IMoniker_Release(mon);
    }

    if (This->Site)
        IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, 0, NULL);

    TRACE("Finished Navigation\n");
    return S_OK;
}

static HRESULT WINAPI IHlink_fnSetAdditonalParams(IHlink* iface,
        LPCWSTR pwzAdditionalParams)
{
    TRACE("Not implemented in native IHlink\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IHlink_fnGetAdditionalParams(IHlink* iface,
        LPWSTR* ppwzAdditionalParams)
{
    TRACE("Not implemented in native IHlink\n");
    return E_NOTIMPL;
}

static const IHlinkVtbl hlvt =
{
    IHlink_fnQueryInterface,
    IHlink_fnAddRef,
    IHlink_fnRelease,
    IHlink_fnSetHlinkSite,
    IHlink_fnGetHlinkSite,
    IHlink_fnSetMonikerReference,
    IHlink_fnGetMonikerReference,
    IHlink_fnSetStringReference,
    IHlink_fnGetStringReference,
    IHlink_fnSetFriendlyName,
    IHlink_fnGetFriendlyName,
    IHlink_fnSetTargetFrameName,
    IHlink_fnGetTargetFrameName,
    IHlink_fnGetMiscStatus,
    IHlink_fnNavigate,
    IHlink_fnSetAdditonalParams,
    IHlink_fnGetAdditionalParams
};

static HRESULT WINAPI IDataObject_fnQueryInterface(IDataObject* iface,
        REFIID riid, LPVOID *ppvObj)
{
    HlinkImpl *This = HlinkImpl_from_IDataObject(iface);
    TRACE("%p\n", This);
    return IHlink_QueryInterface((IHlink*)This, riid, ppvObj);
}

static ULONG WINAPI IDataObject_fnAddRef (IDataObject* iface)
{
    HlinkImpl *This = HlinkImpl_from_IDataObject(iface);
    TRACE("%p\n", This);
    return IHlink_AddRef((IHlink*)This);
}

static ULONG WINAPI IDataObject_fnRelease (IDataObject* iface)
{
    HlinkImpl *This = HlinkImpl_from_IDataObject(iface);
    TRACE("%p\n", This);
    return IHlink_Release((IHlink*)This);
}

static HRESULT WINAPI IDataObject_fnGetData(IDataObject* iface,
        FORMATETC* pformatetcIn, STGMEDIUM* pmedium)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnGetDataHere(IDataObject* iface,
        FORMATETC* pformatetc, STGMEDIUM* pmedium)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnQueryGetData(IDataObject* iface,
        FORMATETC* pformatetc)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnGetConicalFormatEtc(IDataObject* iface,
        FORMATETC* pformatetcIn, FORMATETC* pformatetcOut)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnSetData(IDataObject* iface,
        FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnEnumFormatEtc(IDataObject* iface,
        DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnDAdvise(IDataObject* iface,
        FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink,
        DWORD* pdwConnection)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnDUnadvise(IDataObject* iface,
        DWORD dwConnection)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI IDataObject_fnEnumDAdvise(IDataObject* iface,
        IEnumSTATDATA** ppenumAdvise)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const IDataObjectVtbl dovt =
{
    IDataObject_fnQueryInterface,
    IDataObject_fnAddRef,
    IDataObject_fnRelease,
    IDataObject_fnGetData,
    IDataObject_fnGetDataHere,
    IDataObject_fnQueryGetData,
    IDataObject_fnGetConicalFormatEtc,
    IDataObject_fnSetData,
    IDataObject_fnEnumFormatEtc,
    IDataObject_fnDAdvise,
    IDataObject_fnDUnadvise,
    IDataObject_fnEnumDAdvise
};

static HRESULT WINAPI IPersistStream_fnQueryInterface(IPersistStream* iface,
        REFIID riid, LPVOID *ppvObj)
{
    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
    TRACE("(%p)\n", This);
    return IHlink_QueryInterface((IHlink*)This, riid, ppvObj);
}

static ULONG WINAPI IPersistStream_fnAddRef (IPersistStream* iface)
{
    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
    TRACE("(%p)\n", This);
    return IHlink_AddRef((IHlink*)This);
}

static ULONG WINAPI IPersistStream_fnRelease (IPersistStream* iface)
{
    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
    TRACE("(%p)\n", This);
    return IHlink_Release((IHlink*)This);
}

static HRESULT WINAPI IPersistStream_fnGetClassID(IPersistStream* iface,
        CLSID* pClassID)
{
    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
    TRACE("(%p)\n", This);
    *pClassID = CLSID_StdHlink;
    return S_OK;
}

static HRESULT WINAPI IPersistStream_fnIsDirty(IPersistStream* iface)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT write_hlink_string(IStream *pStm, LPCWSTR str)
{
    DWORD len;
    HRESULT hr;

    TRACE("(%p, %s)\n", pStm, debugstr_w(str));

    len = strlenW(str) + 1;

    hr = IStream_Write(pStm, &len, sizeof(len), NULL);
    if (FAILED(hr)) return hr;

    hr = IStream_Write(pStm, str, len * sizeof(WCHAR), NULL);
    if (FAILED(hr)) return hr;

    return S_OK;
}

static inline ULONG size_hlink_string(LPCWSTR str)
{
    return sizeof(DWORD) + (strlenW(str) + 1) * sizeof(WCHAR);
}

static HRESULT read_hlink_string(IStream *pStm, LPWSTR *out_str)
{
    LPWSTR str;
    DWORD len;
    ULONG read;
    HRESULT hr;

    hr = IStream_Read(pStm, &len, sizeof(len), &read);
    if (FAILED(hr)) return hr;
    if (read != sizeof(len)) return STG_E_READFAULT;

    TRACE("read len %d\n", len);

    str = heap_alloc(len * sizeof(WCHAR));
    if (!str) return E_OUTOFMEMORY;

    hr = IStream_Read(pStm, str, len * sizeof(WCHAR), &read);
    if (FAILED(hr))
    {
        heap_free(str);
        return hr;
    }
    if (read != len * sizeof(WCHAR))
    {
        heap_free(str);
        return STG_E_READFAULT;
    }
    TRACE("read string %s\n", debugstr_w(str));

    *out_str = str;
    return S_OK;
}

static HRESULT WINAPI IPersistStream_fnLoad(IPersistStream* iface,
        IStream* pStm)
{
    HRESULT r;
    DWORD hdr[2];
    DWORD read;
    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);

    r = IStream_Read(pStm, hdr, sizeof(hdr), &read);
    if (read != sizeof(hdr) || (hdr[0] != HLINK_SAVE_MAGIC))
    {
        r = E_FAIL;
        goto end;
    }
    if (hdr[1] & ~HLINK_SAVE_ALL)
        FIXME("unknown flag(s) 0x%x\n", hdr[1] & ~HLINK_SAVE_ALL);

    if (hdr[1] & HLINK_SAVE_TARGET_FRAME_PRESENT)
    {
        TRACE("loading target frame name\n");
        r = read_hlink_string(pStm, &This->TargetFrameName);
        if (FAILED(r)) goto end;
    }

    if (hdr[1] & HLINK_SAVE_FRIENDLY_PRESENT)
    {
        TRACE("loading target friendly name\n");
        if (!(hdr[1] & 0x4))
            FIXME("0x4 flag not present with friendly name flag - not sure what this means\n");
        r = read_hlink_string(pStm, &This->FriendlyName);
        if (FAILED(r)) goto end;
    }

    if (hdr[1] & HLINK_SAVE_MONIKER_PRESENT)
    {
        TRACE("loading moniker\n");
        r = OleLoadFromStream(pStm, &IID_IMoniker, (LPVOID*)&(This->Moniker));
        if (FAILED(r))
            goto end;
        This->absolute = hdr[1] & HLINK_SAVE_MONIKER_IS_ABSOLUTE ? TRUE : FALSE;
    }

    if (hdr[1] & HLINK_SAVE_LOCATION_PRESENT)
    {
        TRACE("loading location\n");
        r = read_hlink_string(pStm, &This->Location);
        if (FAILED(r)) goto end;
    }

end:
    TRACE("Load Result 0x%x (%p)\n", r, This->Moniker);

    return r;
}

static HRESULT WINAPI IPersistStream_fnSave(IPersistStream* iface,
        IStream* pStm, BOOL fClearDirty)
{
    HRESULT r = E_FAIL;
    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
    DWORD hdr[2];
    IMoniker *moniker;

    TRACE("(%p) Moniker(%p)\n", This, This->Moniker);

    __GetMoniker(This, &moniker);

    hdr[0] = HLINK_SAVE_MAGIC;
    hdr[1] = 0;

    if (moniker)
        hdr[1] |= HLINK_SAVE_MONIKER_PRESENT;
    if (This->absolute)
        hdr[1] |= HLINK_SAVE_MONIKER_IS_ABSOLUTE;
    if (This->Location)
        hdr[1] |= HLINK_SAVE_LOCATION_PRESENT;
    if (This->FriendlyName)
        hdr[1] |= HLINK_SAVE_FRIENDLY_PRESENT | 4 /* FIXME */;
    if (This->TargetFrameName)
        hdr[1] |= HLINK_SAVE_TARGET_FRAME_PRESENT;

    IStream_Write(pStm, hdr, sizeof(hdr), NULL);

    if (This->TargetFrameName)
    {
        r = write_hlink_string(pStm, This->TargetFrameName);
        if (FAILED(r)) goto end;
    }

    if (This->FriendlyName)
    {
        r = write_hlink_string(pStm, This->FriendlyName);
        if (FAILED(r)) goto end;
    }

    if (moniker)
    {
        IPersistStream* monstream;

        monstream = NULL;
        IMoniker_QueryInterface(moniker, &IID_IPersistStream,
                (LPVOID*)&monstream);
        if (monstream)
        {
            r = OleSaveToStream(monstream, pStm);
            IPersistStream_Release(monstream);
        }
        if (FAILED(r)) goto end;
    }

    if (This->Location)
    {
        r = write_hlink_string(pStm, This->Location);
        if (FAILED(r)) goto end;
    }

end:
    if (moniker) IMoniker_Release(moniker);
    TRACE("Save Result 0x%x\n", r);

    return r;
}

static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface,
        ULARGE_INTEGER* pcbSize)
{
    HRESULT r = E_FAIL;
    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
    IMoniker *moniker;

    TRACE("(%p) Moniker(%p)\n", This, This->Moniker);

    pcbSize->QuadPart = sizeof(DWORD)*2;

    if (This->TargetFrameName)
        pcbSize->QuadPart += size_hlink_string(This->TargetFrameName);

    if (This->FriendlyName)
        pcbSize->QuadPart += size_hlink_string(This->FriendlyName);

    __GetMoniker(This, &moniker);
    if (moniker)
    {
        IPersistStream* monstream = NULL;
        IMoniker_QueryInterface(moniker, &IID_IPersistStream,
                (LPVOID*)&monstream);
        if (monstream)
        {
            ULARGE_INTEGER mon_size;
            r = IPersistStream_GetSizeMax(monstream, &mon_size);
            pcbSize->QuadPart += mon_size.QuadPart;
            IPersistStream_Release(monstream);
        }
        IMoniker_Release(moniker);
    }

    if (This->Location)
        pcbSize->QuadPart += size_hlink_string(This->Location);

    return r;
}

static const IPersistStreamVtbl psvt =
{
    IPersistStream_fnQueryInterface,
    IPersistStream_fnAddRef,
    IPersistStream_fnRelease,
    IPersistStream_fnGetClassID,
    IPersistStream_fnIsDirty,
    IPersistStream_fnLoad,
    IPersistStream_fnSave,
    IPersistStream_fnGetSizeMax,
};
