/*
 * UrlMon
 *
 * Copyright 1999 Ulrich Czekalla for Corel Corporation
 * Copyright 2002 Huw D M Davies for CodeWeavers
 * Copyright 2005 Jacek Caban 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 "urlmon_main.h"

#include "winreg.h"
#include "shlwapi.h"
#include "hlink.h"
#include "shellapi.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(urlmon);

typedef struct {
    IMoniker      IMoniker_iface;
    IUriContainer IUriContainer_iface;

    LONG ref;

    IUri *uri;
    BSTR URLName;
} URLMoniker;

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

static HRESULT WINAPI URLMoniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
{
    URLMoniker *This = impl_from_IMoniker(iface);

    if(!ppv)
	return E_INVALIDARG;

    if(IsEqualIID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = iface;
    }else if(IsEqualIID(&IID_IPersist, riid)) {
        TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
        *ppv = iface;
    }else if(IsEqualIID(&IID_IPersistStream,riid)) {
        TRACE("(%p)->(IID_IPersistStream %p)\n", This, ppv);
        *ppv = iface;
    }else if(IsEqualIID(&IID_IMoniker, riid)) {
        TRACE("(%p)->(IID_IMoniker %p)\n", This, ppv);
        *ppv = iface;
    }else if(IsEqualIID(&IID_IAsyncMoniker, riid)) {
        TRACE("(%p)->(IID_IAsyncMoniker %p)\n", This, ppv);
        *ppv = iface;
    }else if(IsEqualIID(&IID_IUriContainer, riid)) {
        TRACE("(%p)->(IID_IUriContainer %p)\n", This, ppv);
        *ppv = &This->IUriContainer_iface;
    }else {
        WARN("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI URLMoniker_AddRef(IMoniker *iface)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%u\n",This, refCount);

    return refCount;
}

static ULONG WINAPI URLMoniker_Release(IMoniker *iface)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%u\n",This, refCount);

    if (!refCount) {
        if(This->uri)
            IUri_Release(This->uri);
        SysFreeString(This->URLName);
        heap_free(This);

        URLMON_UnlockModule();
    }

    return refCount;
}

static HRESULT WINAPI URLMoniker_GetClassID(IMoniker *iface, CLSID *pClassID)
{
    URLMoniker *This = impl_from_IMoniker(iface);

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

    if(!pClassID)
        return E_POINTER;

    /* Windows always returns CLSID_StdURLMoniker */
    *pClassID = CLSID_StdURLMoniker;
    return S_OK;
}

static HRESULT WINAPI URLMoniker_IsDirty(IMoniker *iface)
{
    URLMoniker *This = impl_from_IMoniker(iface);

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

    /* 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. */
    return S_FALSE;
}

static HRESULT WINAPI URLMoniker_Load(IMoniker* iface,IStream* pStm)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    WCHAR *new_uri_str;
    IUri *new_uri;
    BSTR new_url;
    ULONG size;
    ULONG got;
    HRESULT hres;

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

    if(!pStm)
        return E_INVALIDARG;

    /*
     * NOTE
     *  Writes a ULONG containing length of unicode string, followed
     *  by that many unicode characters
     */
    hres = IStream_Read(pStm, &size, sizeof(ULONG), &got);
    if(FAILED(hres))
        return hres;
    if(got != sizeof(ULONG))
        return E_FAIL;

    new_uri_str = heap_alloc(size+sizeof(WCHAR));
    if(!new_uri_str)
        return E_OUTOFMEMORY;

    hres = IStream_Read(pStm, new_uri_str, size, NULL);
    new_uri_str[size/sizeof(WCHAR)] = 0;
    if(SUCCEEDED(hres))
        hres = CreateUri(new_uri_str, 0, 0, &new_uri);
    heap_free(new_uri_str);
    if(FAILED(hres))
        return hres;

    hres = IUri_GetDisplayUri(new_uri, &new_url);
    if(FAILED(hres)) {
        IUri_Release(new_uri);
        return hres;
    }

    SysFreeString(This->URLName);
    if(This->uri)
        IUri_Release(This->uri);

    This->uri = new_uri;
    This->URLName = new_url;
    return S_OK;
}

static HRESULT WINAPI URLMoniker_Save(IMoniker *iface, IStream* pStm, BOOL fClearDirty)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    HRESULT res;
    ULONG size;

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

    if(!pStm)
        return E_INVALIDARG;

    size = (SysStringLen(This->URLName) + 1)*sizeof(WCHAR);
    res=IStream_Write(pStm,&size,sizeof(ULONG),NULL);
    if(SUCCEEDED(res))
        res=IStream_Write(pStm,This->URLName,size,NULL);

    return res;

}

static HRESULT WINAPI URLMoniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER *pcbSize)
{
    URLMoniker *This = impl_from_IMoniker(iface);

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

    if(!pcbSize)
        return E_INVALIDARG;

    pcbSize->QuadPart = sizeof(ULONG) + ((SysStringLen(This->URLName)+1) * sizeof(WCHAR));
    return S_OK;
}

static HRESULT WINAPI URLMoniker_BindToObject(IMoniker *iface, IBindCtx* pbc, IMoniker *pmkToLeft,
        REFIID riid, void **ppv)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    IRunningObjectTable *obj_tbl;
    HRESULT hres;

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

    hres = IBindCtx_GetRunningObjectTable(pbc, &obj_tbl);
    if(SUCCEEDED(hres)) {
        FIXME("use running object table\n");
        IRunningObjectTable_Release(obj_tbl);
    }

    if(!This->uri) {
        *ppv = NULL;
        return MK_E_SYNTAX;
    }

    return bind_to_object(&This->IMoniker_iface, This->uri, pbc, riid, ppv);
}

static HRESULT WINAPI URLMoniker_BindToStorage(IMoniker* iface, IBindCtx* pbc,
        IMoniker* pmkToLeft, REFIID riid, void **ppvObject)
{
    URLMoniker *This = impl_from_IMoniker(iface);

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

    if(ppvObject) *ppvObject = NULL;

    if(!pbc || !ppvObject) return E_INVALIDARG;

    if(pmkToLeft)
        FIXME("Unsupported pmkToLeft\n");

    if(!This->uri)
        return MK_E_SYNTAX;

    return bind_to_storage(This->uri, pbc, riid, ppvObject);
}

static HRESULT WINAPI URLMoniker_Reduce(IMoniker *iface, IBindCtx *pbc,
        DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
{
    URLMoniker *This = impl_from_IMoniker(iface);

    TRACE("(%p,%p,%d,%p,%p)\n", This, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced);

    if(!ppmkReduced)
        return E_INVALIDARG;

    IMoniker_AddRef(iface);
    *ppmkReduced = iface;
    return MK_S_REDUCED_TO_SELF;
}

static HRESULT WINAPI URLMoniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
        BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    FIXME("(%p)->(%p,%d,%p): stub\n",This,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
    return E_NOTIMPL;
}

static HRESULT WINAPI URLMoniker_Enum(IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker)
{
    URLMoniker *This = impl_from_IMoniker(iface);

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

    if(!ppenumMoniker)
        return E_INVALIDARG;

    /* Does not support sub-monikers */
    *ppenumMoniker = NULL;
    return S_OK;
}

static HRESULT WINAPI URLMoniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    CLSID clsid;
    LPOLESTR urlPath;
    IBindCtx* bind;
    HRESULT res;

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

    if(pmkOtherMoniker==NULL)
        return E_INVALIDARG;

    IMoniker_GetClassID(pmkOtherMoniker,&clsid);

    if(!IsEqualCLSID(&clsid,&CLSID_StdURLMoniker))
        return S_FALSE;

    res = CreateBindCtx(0,&bind);
    if(FAILED(res))
        return res;

    res = S_FALSE;
    if(SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&urlPath))) {
        int result = lstrcmpiW(urlPath, This->URLName);
        CoTaskMemFree(urlPath);
        if(result == 0)
            res = S_OK;
    }
    IBindCtx_Release(bind);
    return res;
}


static HRESULT WINAPI URLMoniker_Hash(IMoniker *iface, DWORD *pdwHash)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    int  h = 0,i,skip,len;
    int  off = 0;
    LPOLESTR val;

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

    if(!pdwHash)
        return E_INVALIDARG;

    val = This->URLName;
    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;
}

static HRESULT WINAPI URLMoniker_IsRunning(IMoniker* iface, IBindCtx* pbc,
        IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    FIXME("(%p)->(%p,%p,%p): stub\n",This,pbc,pmkToLeft,pmkNewlyRunning);
    return E_NOTIMPL;
}

static HRESULT WINAPI URLMoniker_GetTimeOfLastChange(IMoniker *iface,
        IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    FIXME("(%p)->(%p,%p,%p): stub\n", This, pbc, pmkToLeft, pFileTime);
    return E_NOTIMPL;
}

static HRESULT WINAPI URLMoniker_Inverse(IMoniker *iface, IMoniker **ppmk)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    TRACE("(%p,%p)\n",This,ppmk);
    return MK_E_NOINVERSE;
}

static HRESULT WINAPI URLMoniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkPrefix)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    FIXME("(%p)->(%p,%p): stub\n",This,pmkOther,ppmkPrefix);
    return E_NOTIMPL;
}

static HRESULT WINAPI URLMoniker_RelativePathTo(IMoniker *iface, IMoniker *pmOther, IMoniker **ppmkRelPath)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    FIXME("(%p)->(%p,%p): stub\n",This,pmOther,ppmkRelPath);
    return E_NOTIMPL;
}

static HRESULT WINAPI URLMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
        LPOLESTR *ppszDisplayName)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    int len;
    
    TRACE("(%p,%p,%p,%p)\n", This, pbc, pmkToLeft, ppszDisplayName);
    
    if(!ppszDisplayName)
        return E_INVALIDARG;

    if(!This->URLName)
        return E_OUTOFMEMORY;

    /* FIXME: If this is a partial URL, try and get a URL moniker from SZ_URLCONTEXT in the bind context,
        then look at pmkToLeft to try and complete the URL
    */
    len = SysStringLen(This->URLName)+1;
    *ppszDisplayName = CoTaskMemAlloc(len*sizeof(WCHAR));
    if(!*ppszDisplayName)
        return E_OUTOFMEMORY;
    lstrcpyW(*ppszDisplayName, This->URLName);
    return S_OK;
}

static HRESULT WINAPI URLMoniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
        LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    FIXME("(%p)->(%p,%p,%p,%p,%p): stub\n",This,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
    return E_NOTIMPL;
}

static HRESULT WINAPI URLMoniker_IsSystemMoniker(IMoniker *iface, DWORD *pwdMksys)
{
    URLMoniker *This = impl_from_IMoniker(iface);

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

    if(!pwdMksys)
        return E_INVALIDARG;

    *pwdMksys = MKSYS_URLMONIKER;
    return S_OK;
}

static const IMonikerVtbl URLMonikerVtbl =
{
    URLMoniker_QueryInterface,
    URLMoniker_AddRef,
    URLMoniker_Release,
    URLMoniker_GetClassID,
    URLMoniker_IsDirty,
    URLMoniker_Load,
    URLMoniker_Save,
    URLMoniker_GetSizeMax,
    URLMoniker_BindToObject,
    URLMoniker_BindToStorage,
    URLMoniker_Reduce,
    URLMoniker_ComposeWith,
    URLMoniker_Enum,
    URLMoniker_IsEqual,
    URLMoniker_Hash,
    URLMoniker_IsRunning,
    URLMoniker_GetTimeOfLastChange,
    URLMoniker_Inverse,
    URLMoniker_CommonPrefixWith,
    URLMoniker_RelativePathTo,
    URLMoniker_GetDisplayName,
    URLMoniker_ParseDisplayName,
    URLMoniker_IsSystemMoniker
};

static inline URLMoniker *impl_from_IUriContainer(IUriContainer *iface)
{
    return CONTAINING_RECORD(iface, URLMoniker, IUriContainer_iface);
}

static HRESULT WINAPI UriContainer_QueryInterface(IUriContainer *iface, REFIID riid, void **ppv)
{
    URLMoniker *This = impl_from_IUriContainer(iface);
    return IMoniker_QueryInterface(&This->IMoniker_iface, riid, ppv);
}

static ULONG WINAPI UriContainer_AddRef(IUriContainer *iface)
{
    URLMoniker *This = impl_from_IUriContainer(iface);
    return IMoniker_AddRef(&This->IMoniker_iface);
}

static ULONG WINAPI UriContainer_Release(IUriContainer *iface)
{
    URLMoniker *This = impl_from_IUriContainer(iface);
    return IMoniker_Release(&This->IMoniker_iface);
}

static HRESULT WINAPI UriContainer_GetIUri(IUriContainer *iface, IUri **ppIUri)
{
    URLMoniker *This = impl_from_IUriContainer(iface);

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

    if(!This->uri) {
        *ppIUri = NULL;
        return S_FALSE;
    }

    IUri_AddRef(This->uri);
    *ppIUri = This->uri;
    return S_OK;
}

static const IUriContainerVtbl UriContainerVtbl = {
    UriContainer_QueryInterface,
    UriContainer_AddRef,
    UriContainer_Release,
    UriContainer_GetIUri
};

static HRESULT create_moniker(IUri *uri, URLMoniker **ret)
{
    URLMoniker *mon;
    HRESULT hres;

    mon = heap_alloc(sizeof(*mon));
    if(!mon)
        return E_OUTOFMEMORY;

    mon->IMoniker_iface.lpVtbl = &URLMonikerVtbl;
    mon->IUriContainer_iface.lpVtbl = &UriContainerVtbl;
    mon->ref = 1;

    if(uri) {
        /* FIXME: try to avoid it */
        hres = IUri_GetDisplayUri(uri, &mon->URLName);
        if(FAILED(hres)) {
            heap_free(mon);
            return hres;
        }

        IUri_AddRef(uri);
        mon->uri = uri;
    }else {
        mon->URLName = NULL;
        mon->uri = NULL;
    }

    URLMON_LockModule();
    *ret = mon;
    return S_OK;
}

HRESULT StdURLMoniker_Construct(IUnknown *outer, void **ppv)
{
    URLMoniker *mon;
    HRESULT hres;

    TRACE("(%p %p)\n", outer, ppv);

    hres = create_moniker(NULL, &mon);
    if(FAILED(hres))
        return hres;

    *ppv = &mon->IMoniker_iface;
    return S_OK;
}

static const DWORD create_flags_map[3] = {
    Uri_CREATE_FILE_USE_DOS_PATH,  /* URL_MK_LEGACY */
    0,                             /* URL_MK_UNIFORM */
    Uri_CREATE_NO_CANONICALIZE     /* URL_MK_NO_CANONICALIZE */
};

static const DWORD combine_flags_map[3] = {
    URL_FILE_USE_PATHURL,  /* URL_MK_LEGACY */
    0,                     /* URL_MK_UNIFORM */
    URL_DONT_SIMPLIFY      /* URL_MK_NO_CANONICALIZE */
};

/***********************************************************************
 *           CreateURLMonikerEx (URLMON.@)
 *
 * Create a url moniker.
 *
 * PARAMS
 *    pmkContext [I] Context
 *    szURL      [I] Url to create the moniker for
 *    ppmk       [O] Destination for created moniker.
 *    dwFlags    [I] Flags.
 *
 * RETURNS
 *    Success: S_OK. ppmk contains the created IMoniker object.
 *    Failure: MK_E_SYNTAX if szURL is not a valid url, or
 *             E_OUTOFMEMORY if memory allocation fails.
 */
HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk, DWORD dwFlags)
{
    IUri *uri, *base_uri = NULL;
    URLMoniker *obj;
    HRESULT hres;

    TRACE("(%p, %s, %p, %08x)\n", pmkContext, debugstr_w(szURL), ppmk, dwFlags);

    if (ppmk)
        *ppmk = NULL;

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

    if(dwFlags >= sizeof(create_flags_map)/sizeof(*create_flags_map)) {
        FIXME("Unsupported flags %x\n", dwFlags);
        return E_INVALIDARG;
    }

    if(pmkContext) {
        IUriContainer *uri_container;

        hres = IMoniker_QueryInterface(pmkContext, &IID_IUriContainer, (void**)&uri_container);
        if(SUCCEEDED(hres)) {
            hres = IUriContainer_GetIUri(uri_container, &base_uri);
            IUriContainer_Release(uri_container);
            if(FAILED(hres))
                return hres;
        }
    }

    if(base_uri) {
        hres = CoInternetCombineUrlEx(base_uri, szURL, combine_flags_map[dwFlags], &uri, 0);
        IUri_Release(base_uri);
    }else {
        hres = CreateUri(szURL, Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|create_flags_map[dwFlags], 0, &uri);
    }
    if(FAILED(hres))
        return hres;

    hres = create_moniker(uri, &obj);
    IUri_Release(uri);
    if(FAILED(hres))
	return hres;

    *ppmk = &obj->IMoniker_iface;
    return S_OK;
}

/***********************************************************************
 *           CreateURLMonikerEx2 (URLMON.@)
 */
HRESULT WINAPI CreateURLMonikerEx2(IMoniker *pmkContext, IUri *pUri, IMoniker **ppmk, DWORD dwFlags)
{
    IUri *context_uri = NULL, *uri;
    IUriContainer *uri_container;
    URLMoniker *ret;
    HRESULT hres;

    TRACE("(%p %p %p %x)\n", pmkContext, pUri, ppmk, dwFlags);

    if (ppmk)
        *ppmk = NULL;

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

    if(dwFlags >= sizeof(create_flags_map)/sizeof(*create_flags_map)) {
        FIXME("Unsupported flags %x\n", dwFlags);
        return E_INVALIDARG;
    }

    if(pmkContext) {
        hres = IMoniker_QueryInterface(pmkContext, &IID_IUriContainer, (void**)&uri_container);
        if(SUCCEEDED(hres)) {
            hres = IUriContainer_GetIUri(uri_container, &context_uri);
            if(FAILED(hres))
                context_uri = NULL;
            IUriContainer_Release(uri_container);
        }
    }

    if(context_uri) {
        hres = CoInternetCombineIUri(context_uri, pUri, combine_flags_map[dwFlags], &uri, 0);
        IUri_Release(context_uri);
        if(FAILED(hres))
            return hres;
    }else {
        uri = pUri;
        IUri_AddRef(uri);
    }

    hres = create_moniker(uri, &ret);
    IUri_Release(uri);
    if(FAILED(hres))
        return hres;

    *ppmk = &ret->IMoniker_iface;
    return S_OK;
}

/**********************************************************************
 *           CreateURLMoniker (URLMON.@)
 *
 * Create a url moniker.
 *
 * PARAMS
 *    pmkContext [I] Context
 *    szURL      [I] Url to create the moniker for
 *    ppmk       [O] Destination for created moniker.
 *
 * RETURNS
 *    Success: S_OK. ppmk contains the created IMoniker object.
 *    Failure: MK_E_SYNTAX if szURL is not a valid url, or
 *             E_OUTOFMEMORY if memory allocation fails.
 */
HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk)
{
    return CreateURLMonikerEx(pmkContext, szURL, ppmk, URL_MK_LEGACY);
}

/***********************************************************************
 *           IsAsyncMoniker (URLMON.@)
 */
HRESULT WINAPI IsAsyncMoniker(IMoniker *pmk)
{
    IUnknown *am;
    
    TRACE("(%p)\n", pmk);
    if(!pmk)
        return E_INVALIDARG;
    if(SUCCEEDED(IMoniker_QueryInterface(pmk, &IID_IAsyncMoniker, (void**)&am))) {
        IUnknown_Release(am);
        return S_OK;
    }
    return S_FALSE;
}

/***********************************************************************
 *           BindAsyncMoniker (URLMON.@)
 *
 * Bind a bind status callback to an asynchronous URL Moniker.
 *
 * PARAMS
 *  pmk           [I] Moniker object to bind status callback to
 *  grfOpt        [I] Options, seems not used
 *  pbsc          [I] Status callback to bind
 *  iidResult     [I] Interface to return
 *  ppvResult     [O] Resulting asynchronous moniker object
 *
 * RETURNS
 *    Success: S_OK.
 *    Failure: E_INVALIDARG, if any argument is invalid, or
 *             E_OUTOFMEMORY if memory allocation fails.
 */
HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback *pbsc, REFIID iidResult, LPVOID *ppvResult)
{
    LPBC pbc = NULL;
    HRESULT hr = E_INVALIDARG;

    TRACE("(%p %08x %p %s %p)\n", pmk, grfOpt, pbsc, debugstr_guid(iidResult), ppvResult);

    if (pmk && ppvResult)
    {
        *ppvResult = NULL;

        hr = CreateAsyncBindCtx(0, pbsc, NULL, &pbc);
        if (hr == NOERROR)
        {
            hr = IMoniker_BindToObject(pmk, pbc, NULL, iidResult, ppvResult);
            IBindCtx_Release(pbc);
        }
    }
    return hr;
}

/***********************************************************************
 *           MkParseDisplayNameEx (URLMON.@)
 */
HRESULT WINAPI MkParseDisplayNameEx(IBindCtx *pbc, LPCWSTR szDisplayName, ULONG *pchEaten, LPMONIKER *ppmk)
{
    TRACE("(%p %s %p %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk);

    if (!pbc || !szDisplayName || !*szDisplayName || !pchEaten || !ppmk)
        return E_INVALIDARG;

    if(is_registered_protocol(szDisplayName)) {
        HRESULT hres;

        hres = CreateURLMoniker(NULL, szDisplayName, ppmk);
        if(SUCCEEDED(hres)) {
            *pchEaten = strlenW(szDisplayName);
            return hres;
        }
    }

    return MkParseDisplayName(pbc, szDisplayName, pchEaten, ppmk);
}


/***********************************************************************
 *           URLDownloadToCacheFileA (URLMON.@)
 */
HRESULT WINAPI URLDownloadToCacheFileA(LPUNKNOWN lpUnkCaller, LPCSTR szURL, LPSTR szFileName,
        DWORD dwBufLength, DWORD dwReserved, LPBINDSTATUSCALLBACK pBSC)
{
    LPWSTR url = NULL, file_name = NULL;
    int len;
    HRESULT hres;

    TRACE("(%p %s %p %d %d %p)\n", lpUnkCaller, debugstr_a(szURL), szFileName,
            dwBufLength, dwReserved, pBSC);

    if(szURL) {
        len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
        url = heap_alloc(len*sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, szURL, -1, url, len);
    }

    if(szFileName)
        file_name = heap_alloc(dwBufLength*sizeof(WCHAR));

    hres = URLDownloadToCacheFileW(lpUnkCaller, url, file_name, dwBufLength*sizeof(WCHAR),
            dwReserved, pBSC);

    if(SUCCEEDED(hres) && file_name)
        WideCharToMultiByte(CP_ACP, 0, file_name, -1, szFileName, dwBufLength, NULL, NULL);

    heap_free(url);
    heap_free(file_name);

    return hres;
}

/***********************************************************************
 *           URLDownloadToCacheFileW (URLMON.@)
 */
HRESULT WINAPI URLDownloadToCacheFileW(LPUNKNOWN lpUnkCaller, LPCWSTR szURL, LPWSTR szFileName,
                DWORD dwBufLength, DWORD dwReserved, LPBINDSTATUSCALLBACK pBSC)
{
    WCHAR cache_path[MAX_PATH + 1];
    FILETIME expire, modified;
    HRESULT hr;
    LPWSTR ext;

    static WCHAR header[] = {
        'H','T','T','P','/','1','.','0',' ','2','0','0',' ',
        'O','K','\\','r','\\','n','\\','r','\\','n',0
    };

    TRACE("(%p, %s, %p, %d, %d, %p)\n", lpUnkCaller, debugstr_w(szURL),
          szFileName, dwBufLength, dwReserved, pBSC);

    if (!szURL || !szFileName)
        return E_INVALIDARG;

    ext = PathFindExtensionW(szURL);

    if (!CreateUrlCacheEntryW(szURL, 0, ext, cache_path, 0))
        return E_FAIL;

    hr = URLDownloadToFileW(lpUnkCaller, szURL, cache_path, 0, pBSC);
    if (FAILED(hr))
        return hr;

    expire.dwHighDateTime = 0;
    expire.dwLowDateTime = 0;
    modified.dwHighDateTime = 0;
    modified.dwLowDateTime = 0;

    if (!CommitUrlCacheEntryW(szURL, cache_path, expire, modified, NORMAL_CACHE_ENTRY,
                              header, sizeof(header), NULL, NULL))
        return E_FAIL;

    if (strlenW(cache_path) > dwBufLength)
        return E_OUTOFMEMORY;

    lstrcpyW(szFileName, cache_path);

    return S_OK;
}

/***********************************************************************
 *           HlinkSimpleNavigateToMoniker (URLMON.@)
 */
HRESULT WINAPI HlinkSimpleNavigateToMoniker(IMoniker *pmkTarget,
    LPCWSTR szLocation, LPCWSTR szTargetFrameName, IUnknown *pUnk,
    IBindCtx *pbc, IBindStatusCallback *pbsc, DWORD grfHLNF, DWORD dwReserved)
{
    LPWSTR target;
    HRESULT hres;

    TRACE("\n");

    hres = IMoniker_GetDisplayName(pmkTarget, pbc, 0, &target);
    if(hres == S_OK)
        hres = HlinkSimpleNavigateToString( target, szLocation, szTargetFrameName,
                                            pUnk, pbc, pbsc, grfHLNF, dwReserved );
    CoTaskMemFree(target);

    return hres;
}

/***********************************************************************
 *           HlinkSimpleNavigateToString (URLMON.@)
 */
HRESULT WINAPI HlinkSimpleNavigateToString( LPCWSTR szTarget,
    LPCWSTR szLocation, LPCWSTR szTargetFrameName, IUnknown *pUnk,
    IBindCtx *pbc, IBindStatusCallback *pbsc, DWORD grfHLNF, DWORD dwReserved)
{
    FIXME("%s %s %s %p %p %p %u %u partial stub\n", debugstr_w( szTarget ), debugstr_w( szLocation ),
          debugstr_w( szTargetFrameName ), pUnk, pbc, pbsc, grfHLNF, dwReserved);

    /* undocumented: 0 means HLNF_OPENINNEWWINDOW*/
    if (!grfHLNF) grfHLNF = HLNF_OPENINNEWWINDOW;

    if (grfHLNF == HLNF_OPENINNEWWINDOW)
    {
        SHELLEXECUTEINFOW sei;
        static const WCHAR openW[] = { 'o', 'p', 'e', 'n', 0 };

        memset(&sei, 0, sizeof(sei));
        sei.cbSize = sizeof(sei);
        sei.lpVerb = openW;
        sei.nShow = SW_SHOWNORMAL;
        sei.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NO_CONSOLE;
        sei.lpFile = szTarget;

        if (ShellExecuteExW(&sei)) return S_OK;
    }

    return E_NOTIMPL;
}

/***********************************************************************
 *           HlinkNavigateString (URLMON.@)
 */
HRESULT WINAPI HlinkNavigateString( IUnknown *pUnk, LPCWSTR szTarget )
{
    TRACE("%p %s\n", pUnk, debugstr_w( szTarget ) );
    return HlinkSimpleNavigateToString( 
               szTarget, NULL, NULL, pUnk, NULL, NULL, 0, 0 );
}

/***********************************************************************
 *           GetSoftwareUpdateInfo (URLMON.@)
 */
HRESULT WINAPI GetSoftwareUpdateInfo( LPCWSTR szDistUnit, LPSOFTDISTINFO psdi )
{
    FIXME("%s %p\n", debugstr_w(szDistUnit), psdi );
    return E_FAIL;
}
