/*
 * Copyright 2008 Damjan Jovanovic
 *
 * ShellLink's barely documented cousin that handles URLs.
 *
 * 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
 */

/*
 * TODO:
 * Implement the IShellLinkA/W interfaces
 * Handle the SetURL flags
 * Implement any other interfaces? Does any software actually use them?
 *
 * The installer for the Zuma Deluxe Popcap game is good for testing.
 */

#include <stdarg.h>
#include <stdio.h>

#define NONAMELESSUNION
#include "wine/debug.h"
#include "shdocvw.h"
#include "objidl.h"
#include "shobjidl.h"
#include "intshcut.h"
#include "shellapi.h"
#include "winreg.h"
#include "shlwapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);

typedef struct
{
    IUniformResourceLocatorA IUniformResourceLocatorA_iface;
    IUniformResourceLocatorW IUniformResourceLocatorW_iface;
    IPersistFile IPersistFile_iface;
    IPropertySetStorage IPropertySetStorage_iface;

    LONG refCount;

    IPropertySetStorage *property_set_storage;
    WCHAR *url;
    BOOLEAN isDirty;
    LPOLESTR currentFile;
} InternetShortcut;

/* utility functions */

static inline InternetShortcut* impl_from_IUniformResourceLocatorA(IUniformResourceLocatorA *iface)
{
    return CONTAINING_RECORD(iface, InternetShortcut, IUniformResourceLocatorA_iface);
}

static inline InternetShortcut* impl_from_IUniformResourceLocatorW(IUniformResourceLocatorW *iface)
{
    return CONTAINING_RECORD(iface, InternetShortcut, IUniformResourceLocatorW_iface);
}

static inline InternetShortcut* impl_from_IPersistFile(IPersistFile *iface)
{
    return CONTAINING_RECORD(iface, InternetShortcut, IPersistFile_iface);
}

static inline InternetShortcut* impl_from_IPropertySetStorage(IPropertySetStorage *iface)
{
    return (InternetShortcut*)((char*)iface - FIELD_OFFSET(InternetShortcut, IPropertySetStorage_iface));
}

static BOOL run_winemenubuilder( const WCHAR *args )
{
    static const WCHAR menubuilder[] = {'\\','w','i','n','e','m','e','n','u','b','u','i','l','d','e','r','.','e','x','e',0};
    LONG len;
    LPWSTR buffer;
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    BOOL ret;
    WCHAR app[MAX_PATH];
    void *redir;

    GetSystemDirectoryW( app, MAX_PATH - sizeof(menubuilder)/sizeof(WCHAR) );
    strcatW( app, menubuilder );

    len = (strlenW( app ) + strlenW( args ) + 1) * sizeof(WCHAR);
    buffer = heap_alloc( len );
    if( !buffer )
        return FALSE;

    strcpyW( buffer, app );
    strcatW( buffer, args );

    TRACE("starting %s\n",debugstr_w(buffer));

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);

    Wow64DisableWow64FsRedirection( &redir );
    ret = CreateProcessW( app, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
    Wow64RevertWow64FsRedirection( redir );

    heap_free( buffer );

    if (ret)
    {
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }

    return ret;
}

static BOOL StartLinkProcessor( LPCOLESTR szLink )
{
    static const WCHAR szFormat[] = { ' ','-','w',' ','-','u',' ','"','%','s','"',0 };
    LONG len;
    LPWSTR buffer;
    BOOL ret;

    len = sizeof(szFormat) + lstrlenW( szLink ) * sizeof(WCHAR);
    buffer = heap_alloc( len );
    if( !buffer )
        return FALSE;

    wsprintfW( buffer, szFormat, szLink );
    ret = run_winemenubuilder( buffer );
    heap_free( buffer );
    return ret;
}

/* interface functions */

static HRESULT Unknown_QueryInterface(InternetShortcut *This, REFIID riid, PVOID *ppvObject)
{
    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
    *ppvObject = NULL;
    if (IsEqualGUID(&IID_IUnknown, riid))
        *ppvObject = &This->IUniformResourceLocatorA_iface;
    else if (IsEqualGUID(&IID_IUniformResourceLocatorA, riid))
        *ppvObject = &This->IUniformResourceLocatorA_iface;
    else if (IsEqualGUID(&IID_IUniformResourceLocatorW, riid))
        *ppvObject = &This->IUniformResourceLocatorW_iface;
    else if (IsEqualGUID(&IID_IPersistFile, riid))
        *ppvObject = &This->IPersistFile_iface;
    else if (IsEqualGUID(&IID_IPropertySetStorage, riid))
        *ppvObject = &This->IPropertySetStorage_iface;
    else if (IsEqualGUID(&IID_IShellLinkA, riid))
    {
        FIXME("The IShellLinkA interface is not yet supported by InternetShortcut\n");
        return E_NOINTERFACE;
    }
    else if (IsEqualGUID(&IID_IShellLinkW, riid))
    {
        FIXME("The IShellLinkW interface is not yet supported by InternetShortcut\n");
        return E_NOINTERFACE;
    }
    else
    {
        FIXME("Interface with GUID %s not yet implemented by InternetShortcut\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }
    IUnknown_AddRef((IUnknown*)*ppvObject);
    return S_OK;
}

static ULONG Unknown_AddRef(InternetShortcut *This)
{
    TRACE("(%p)\n", This);
    return InterlockedIncrement(&This->refCount);
}

static ULONG Unknown_Release(InternetShortcut *This)
{
    ULONG count;
    TRACE("(%p)\n", This);
    count = InterlockedDecrement(&This->refCount);
    if (count == 0)
    {
        CoTaskMemFree(This->url);
        CoTaskMemFree(This->currentFile);
        IPropertySetStorage_Release(This->property_set_storage);
        heap_free(This);
        SHDOCVW_UnlockModule();
    }
    return count;
}

static HRESULT WINAPI UniformResourceLocatorW_QueryInterface(IUniformResourceLocatorW *url, REFIID riid, PVOID *ppvObject)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
    TRACE("(%p, %s, %p)\n", url, debugstr_guid(riid), ppvObject);
    return Unknown_QueryInterface(This, riid, ppvObject);
}

static ULONG WINAPI UniformResourceLocatorW_AddRef(IUniformResourceLocatorW *url)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
    TRACE("(%p)\n", url);
    return Unknown_AddRef(This);
}

static ULONG WINAPI UniformResourceLocatorW_Release(IUniformResourceLocatorW *url)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
    TRACE("(%p)\n", url);
    return Unknown_Release(This);
}

static HRESULT WINAPI UniformResourceLocatorW_SetUrl(IUniformResourceLocatorW *url, LPCWSTR pcszURL, DWORD dwInFlags)
{
    WCHAR *newURL = NULL;
    InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
    TRACE("(%p, %s, 0x%x)\n", url, debugstr_w(pcszURL), dwInFlags);
    if (dwInFlags != 0)
        FIXME("ignoring unsupported flags 0x%x\n", dwInFlags);
    if (pcszURL != NULL)
    {
        newURL = co_strdupW(pcszURL);
        if (newURL == NULL)
            return E_OUTOFMEMORY;
    }
    CoTaskMemFree(This->url);
    This->url = newURL;
    This->isDirty = TRUE;
    return S_OK;
}

static HRESULT WINAPI UniformResourceLocatorW_GetUrl(IUniformResourceLocatorW *url, LPWSTR *ppszURL)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);

    TRACE("(%p, %p)\n", url, ppszURL);

    if (!This->url) {
        *ppszURL = NULL;
        return S_FALSE;
    }

    *ppszURL = co_strdupW(This->url);
    if (!*ppszURL)
        return E_OUTOFMEMORY;

    return S_OK;
}

static HRESULT WINAPI UniformResourceLocatorW_InvokeCommand(IUniformResourceLocatorW *url, PURLINVOKECOMMANDINFOW pCommandInfo)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
    WCHAR app[64];
    HKEY hkey;
    static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
    SHELLEXECUTEINFOW sei;
    DWORD res, type;
    HRESULT hres;

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

    if (pCommandInfo->dwcbSize < sizeof (URLINVOKECOMMANDINFOW))
        return E_INVALIDARG;

    if (pCommandInfo->dwFlags != IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB)
    {
        FIXME("(%p, %p): non-default verbs not implemented\n", url, pCommandInfo);
        return E_NOTIMPL;
    }

    hres = CoInternetParseUrl(This->url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
    if(FAILED(hres))
        return E_FAIL;

    res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
    if(res != ERROR_SUCCESS)
        return E_FAIL;

    res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || type != REG_SZ)
        return E_FAIL;

    memset(&sei, 0, sizeof(sei));
    sei.cbSize = sizeof(sei);
    sei.lpFile = This->url;
    sei.nShow = SW_SHOW;

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

static HRESULT WINAPI UniformResourceLocatorA_QueryInterface(IUniformResourceLocatorA *url, REFIID riid, PVOID *ppvObject)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
    TRACE("(%p, %s, %p)\n", url, debugstr_guid(riid), ppvObject);
    return Unknown_QueryInterface(This, riid, ppvObject);
}

static ULONG WINAPI UniformResourceLocatorA_AddRef(IUniformResourceLocatorA *url)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
    TRACE("(%p)\n", url);
    return Unknown_AddRef(This);
}

static ULONG WINAPI UniformResourceLocatorA_Release(IUniformResourceLocatorA *url)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
    TRACE("(%p)\n", url);
    return Unknown_Release(This);
}

static HRESULT WINAPI UniformResourceLocatorA_SetUrl(IUniformResourceLocatorA *url, LPCSTR pcszURL, DWORD dwInFlags)
{
    WCHAR *newURL = NULL;
    InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
    TRACE("(%p, %s, 0x%x)\n", url, debugstr_a(pcszURL), dwInFlags);
    if (dwInFlags != 0)
        FIXME("ignoring unsupported flags 0x%x\n", dwInFlags);
    if (pcszURL != NULL)
    {
        newURL = co_strdupAtoW(pcszURL);
        if (newURL == NULL)
            return E_OUTOFMEMORY;
    }
    CoTaskMemFree(This->url);
    This->url = newURL;
    This->isDirty = TRUE;
    return S_OK;
}

static HRESULT WINAPI UniformResourceLocatorA_GetUrl(IUniformResourceLocatorA *url, LPSTR *ppszURL)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);

    TRACE("(%p, %p)\n", url, ppszURL);

    if (!This->url) {
        *ppszURL = NULL;
        return S_FALSE;

    }

    *ppszURL = co_strdupWtoA(This->url);
    if (!*ppszURL)
        return E_OUTOFMEMORY;

    return S_OK;
}

static HRESULT WINAPI UniformResourceLocatorA_InvokeCommand(IUniformResourceLocatorA *url, PURLINVOKECOMMANDINFOA pCommandInfo)
{
    URLINVOKECOMMANDINFOW wideCommandInfo;
    int len;
    WCHAR *wideVerb;
    HRESULT res;
    InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);

    wideCommandInfo.dwcbSize = sizeof wideCommandInfo;
    wideCommandInfo.dwFlags = pCommandInfo->dwFlags;
    wideCommandInfo.hwndParent = pCommandInfo->hwndParent;

    len = MultiByteToWideChar(CP_ACP, 0, pCommandInfo->pcszVerb, -1, NULL, 0);
    wideVerb = heap_alloc(len * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, pCommandInfo->pcszVerb, -1, wideVerb, len);

    wideCommandInfo.pcszVerb = wideVerb;

    res = UniformResourceLocatorW_InvokeCommand(&This->IUniformResourceLocatorW_iface, &wideCommandInfo);
    heap_free(wideVerb);

    return res;
}

static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *pFile, REFIID riid, PVOID *ppvObject)
{
    InternetShortcut *This = impl_from_IPersistFile(pFile);
    TRACE("(%p, %s, %p)\n", pFile, debugstr_guid(riid), ppvObject);
    return Unknown_QueryInterface(This, riid, ppvObject);
}

static ULONG WINAPI PersistFile_AddRef(IPersistFile *pFile)
{
    InternetShortcut *This = impl_from_IPersistFile(pFile);
    TRACE("(%p)\n", pFile);
    return Unknown_AddRef(This);
}

static ULONG WINAPI PersistFile_Release(IPersistFile *pFile)
{
    InternetShortcut *This = impl_from_IPersistFile(pFile);
    TRACE("(%p)\n", pFile);
    return Unknown_Release(This);
}

static HRESULT WINAPI PersistFile_GetClassID(IPersistFile *pFile, CLSID *pClassID)
{
    TRACE("(%p, %p)\n", pFile, pClassID);
    *pClassID = CLSID_InternetShortcut;
    return S_OK;
}

static HRESULT WINAPI PersistFile_IsDirty(IPersistFile *pFile)
{
    InternetShortcut *This = impl_from_IPersistFile(pFile);
    TRACE("(%p)\n", pFile);
    return This->isDirty ? S_OK : S_FALSE;
}

/* A helper function:  Allocate and fill rString.  Return number of bytes read. */
static DWORD get_profile_string(LPCWSTR lpAppName, LPCWSTR lpKeyName,
                                LPCWSTR lpFileName, WCHAR **rString )
{
    DWORD r = 0;
    DWORD len = 128;
    WCHAR *buffer;

    buffer = CoTaskMemAlloc(len * sizeof(*buffer));
    if (buffer != NULL)
    {
        r = GetPrivateProfileStringW(lpAppName, lpKeyName, NULL, buffer, len, lpFileName);
        while (r == len-1)
        {
            WCHAR *realloc_buf;

            len *= 2;
            realloc_buf = CoTaskMemRealloc(buffer, len * sizeof(*buffer));
            if (realloc_buf == NULL)
            {
                CoTaskMemFree(buffer);
                *rString = NULL;
                return 0;
            }
            buffer = realloc_buf;

            r = GetPrivateProfileStringW(lpAppName, lpKeyName, NULL, buffer, len, lpFileName);
        }
    }

    *rString = buffer;
    return r;
}

static HRESULT WINAPI PersistFile_Load(IPersistFile *pFile, LPCOLESTR pszFileName, DWORD dwMode)
{
    WCHAR str_header[] = {'I','n','t','e','r','n','e','t','S','h','o','r','t','c','u','t',0};
    WCHAR str_URL[] = {'U','R','L',0};
    WCHAR str_iconfile[] = {'i','c','o','n','f','i','l','e',0};
    WCHAR str_iconindex[] = {'i','c','o','n','i','n','d','e','x',0};
    WCHAR *filename = NULL;
    HRESULT hr;
    InternetShortcut *This = impl_from_IPersistFile(pFile);
    TRACE("(%p, %s, 0x%x)\n", pFile, debugstr_w(pszFileName), dwMode);
    if (dwMode != 0)
        FIXME("ignoring unimplemented mode 0x%x\n", dwMode);
    filename = co_strdupW(pszFileName);
    if (filename != NULL)
    {
        DWORD r;
        WCHAR *url;

        r = get_profile_string(str_header, str_URL, pszFileName, &url);

        if (url == NULL)
        {
            hr = E_OUTOFMEMORY;
            CoTaskMemFree(filename);
        }
        else if (r == 0)
        {
            hr = E_FAIL;
            CoTaskMemFree(filename);
        }
        else
        {
            hr = S_OK;
            CoTaskMemFree(This->currentFile);
            This->currentFile = filename;
            CoTaskMemFree(This->url);
            This->url = url;
            This->isDirty = FALSE;
        }

        /* Now we're going to read in the iconfile and iconindex.
           If we don't find them, that's not a failure case -- it's possible
           that they just aren't in there. */
        if (SUCCEEDED(hr))
        {
            IPropertyStorage *pPropStg;
            WCHAR *iconfile;
            WCHAR *iconindexstring;
            hr = IPropertySetStorage_Open(This->property_set_storage, &FMTID_Intshcut,
                                          STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
                                          &pPropStg);

            r = get_profile_string(str_header, str_iconfile, pszFileName, &iconfile);
            if (iconfile != NULL)
            {
                PROPSPEC ps;
                PROPVARIANT pv;
                ps.ulKind = PRSPEC_PROPID;
                ps.u.propid = PID_IS_ICONFILE;
                pv.vt = VT_LPWSTR;
                pv.u.pwszVal = iconfile;
                hr = IPropertyStorage_WriteMultiple(pPropStg, 1, &ps, &pv, 0);
                if (FAILED(hr))
                {
                    TRACE("Failed to store the iconfile to our property storage.  hr = 0x%x\n", hr);
                }

                CoTaskMemFree(iconfile);
            }

            r = get_profile_string(str_header, str_iconindex, pszFileName, &iconindexstring);

            if (iconindexstring != NULL)
            {
                int iconindex;
                PROPSPEC ps;
                PROPVARIANT pv;
                char *iconindexastring = co_strdupWtoA(iconindexstring);
                sscanf(iconindexastring, "%d", &iconindex);
                CoTaskMemFree(iconindexastring);
                ps.ulKind = PRSPEC_PROPID;
                ps.u.propid = PID_IS_ICONINDEX;
                pv.vt = VT_I4;
                pv.u.iVal = iconindex;
                hr = IPropertyStorage_WriteMultiple(pPropStg, 1, &ps, &pv, 0);
                if (FAILED(hr))
                {
                    TRACE("Failed to store the iconindex to our property storage.  hr = 0x%x\n", hr);
                }

                CoTaskMemFree(iconindexstring);
            }

            IPropertyStorage_Release(pPropStg);
        }
        else
            hr = E_OUTOFMEMORY;
    }
    else
        hr = E_OUTOFMEMORY;
    return hr;
}

static HRESULT WINAPI PersistFile_Save(IPersistFile *pFile, LPCOLESTR pszFileName, BOOL fRemember)
{
    HRESULT hr = S_OK;
    INT len;
    CHAR *url;
    InternetShortcut *This = impl_from_IPersistFile(pFile);

    TRACE("(%p, %s, %d)\n", pFile, debugstr_w(pszFileName), fRemember);

    if (pszFileName != NULL && fRemember)
    {
        LPOLESTR oldFile = This->currentFile;
        This->currentFile = co_strdupW(pszFileName);
        if (This->currentFile == NULL)
        {
            This->currentFile = oldFile;
            return E_OUTOFMEMORY;
        }
        CoTaskMemFree(oldFile);
    }
    if (This->url == NULL)
        return E_FAIL;

    /* Windows seems to always write:
     *   ASCII "[InternetShortcut]" headers
     *   ASCII names in "name=value" pairs
     *   An ASCII (probably UTF8?) value in "URL=..."
     */
    len = WideCharToMultiByte(CP_UTF8, 0, This->url, -1, NULL, 0, 0, 0);
    url = heap_alloc(len);
    if (url != NULL)
    {
        HANDLE file;
        WideCharToMultiByte(CP_UTF8, 0, This->url, -1, url, len, 0, 0);
        file = CreateFileW(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (file != INVALID_HANDLE_VALUE)
        {
            DWORD bytesWritten;
            char *iconfile;
            char str_header[] = "[InternetShortcut]";
            char str_URL[] = "URL=";
            char str_ICONFILE[] = "ICONFILE=";
            char str_eol[] = "\r\n";
            IPropertyStorage *pPropStgRead;
            PROPSPEC ps[2];
            PROPVARIANT pvread[2];
            ps[0].ulKind = PRSPEC_PROPID;
            ps[0].u.propid = PID_IS_ICONFILE;
            ps[1].ulKind = PRSPEC_PROPID;
            ps[1].u.propid = PID_IS_ICONINDEX;

            WriteFile(file, str_header, lstrlenA(str_header), &bytesWritten, NULL);
            WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);
            WriteFile(file, str_URL, lstrlenA(str_URL), &bytesWritten, NULL);
            WriteFile(file, url, lstrlenA(url), &bytesWritten, NULL);
            WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);

            hr = IPropertySetStorage_Open(This->property_set_storage, &FMTID_Intshcut, STGM_READ|STGM_SHARE_EXCLUSIVE, &pPropStgRead);
            if SUCCEEDED(hr)
            {
                hr = IPropertyStorage_ReadMultiple(pPropStgRead, 2, ps, pvread);
                if (hr == S_FALSE)
                {
                    /* None of the properties are present, that's ok */
                    hr = S_OK;
                    IPropertyStorage_Release(pPropStgRead);
                }
                else if SUCCEEDED(hr)
                {
                    char indexString[50];
                    len = WideCharToMultiByte(CP_UTF8, 0, pvread[0].u.pwszVal, -1, NULL, 0, 0, 0);
                    iconfile = heap_alloc(len);
                    if (iconfile != NULL)
                    {
                        WideCharToMultiByte(CP_UTF8, 0, pvread[0].u.pwszVal, -1, iconfile, len, 0, 0);
                        WriteFile(file, str_ICONFILE, lstrlenA(str_ICONFILE), &bytesWritten, NULL);
                        WriteFile(file, iconfile, lstrlenA(iconfile), &bytesWritten, NULL);
                        WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);
                    }

                    sprintf(indexString, "ICONINDEX=%d", pvread[1].u.iVal);
                    WriteFile(file, indexString, lstrlenA(indexString), &bytesWritten, NULL);
                    WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);

                    IPropertyStorage_Release(pPropStgRead);
                    PropVariantClear(&pvread[0]);
                    PropVariantClear(&pvread[1]);
                }
                else
                {
                    TRACE("Unable to read properties.\n");
                }
            }
            else
            {
               TRACE("Unable to get the IPropertyStorage.\n");
            }

            CloseHandle(file);
            if (pszFileName == NULL || fRemember)
                This->isDirty = FALSE;
            StartLinkProcessor(pszFileName);
        }
        else
            hr = E_FAIL;
        heap_free(url);
    }
    else
        hr = E_OUTOFMEMORY;

    return hr;
}

static HRESULT WINAPI PersistFile_SaveCompleted(IPersistFile *pFile, LPCOLESTR pszFileName)
{
    FIXME("(%p, %p): stub\n", pFile, pszFileName);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistFile_GetCurFile(IPersistFile *pFile, LPOLESTR *ppszFileName)
{
    HRESULT hr = S_OK;
    InternetShortcut *This = impl_from_IPersistFile(pFile);
    TRACE("(%p, %p)\n", pFile, ppszFileName);
    if (This->currentFile == NULL)
        *ppszFileName = NULL;
    else
    {
        *ppszFileName = co_strdupW(This->currentFile);
        if (*ppszFileName == NULL)
            hr = E_OUTOFMEMORY;
    }
    return hr;
}

static HRESULT WINAPI PropertySetStorage_QueryInterface(IPropertySetStorage *iface, REFIID riid, PVOID *ppvObject)
{
    InternetShortcut *This = impl_from_IPropertySetStorage(iface);
    TRACE("(%p)\n", iface);
    return Unknown_QueryInterface(This, riid, ppvObject);
}

static ULONG WINAPI PropertySetStorage_AddRef(IPropertySetStorage *iface)
{
    InternetShortcut *This = impl_from_IPropertySetStorage(iface);
    TRACE("(%p)\n", iface);
    return Unknown_AddRef(This);
}

static ULONG WINAPI PropertySetStorage_Release(IPropertySetStorage *iface)
{
    InternetShortcut *This = impl_from_IPropertySetStorage(iface);
    TRACE("(%p)\n", iface);
    return Unknown_Release(This);
}

static HRESULT WINAPI PropertySetStorage_Create(
        IPropertySetStorage* iface,
        REFFMTID rfmtid,
        const CLSID *pclsid,
        DWORD grfFlags,
        DWORD grfMode,
        IPropertyStorage **ppprstg)
{
    InternetShortcut *This = impl_from_IPropertySetStorage(iface);
    TRACE("(%s, %p, 0x%x, 0x%x, %p)\n", debugstr_guid(rfmtid), pclsid, grfFlags, grfMode, ppprstg);

    return IPropertySetStorage_Create(This->property_set_storage,
                                      rfmtid,
                                      pclsid,
                                      grfFlags,
                                      grfMode,
                                      ppprstg);
}

static HRESULT WINAPI PropertySetStorage_Open(
        IPropertySetStorage* iface,
        REFFMTID rfmtid,
        DWORD grfMode,
        IPropertyStorage **ppprstg)
{
    InternetShortcut *This = impl_from_IPropertySetStorage(iface);
    TRACE("(%s, 0x%x, %p)\n", debugstr_guid(rfmtid), grfMode, ppprstg);

    /* Note:  The |STGM_SHARE_EXCLUSIVE is to cope with a bug in the implementation.  Should be fixed in ole32. */
    return IPropertySetStorage_Open(This->property_set_storage,
                                    rfmtid,
                                    grfMode|STGM_SHARE_EXCLUSIVE,
                                    ppprstg);
}

static HRESULT WINAPI PropertySetStorage_Delete(IPropertySetStorage *iface, REFFMTID rfmtid)
{
    InternetShortcut *This = impl_from_IPropertySetStorage(iface);
    TRACE("(%s)\n", debugstr_guid(rfmtid));


    return IPropertySetStorage_Delete(This->property_set_storage,
                                      rfmtid);
}

static HRESULT WINAPI PropertySetStorage_Enum(IPropertySetStorage *iface, IEnumSTATPROPSETSTG **ppenum)
{
    FIXME("(%p): stub\n", ppenum);
    return E_NOTIMPL;
}

static const IUniformResourceLocatorWVtbl uniformResourceLocatorWVtbl = {
    UniformResourceLocatorW_QueryInterface,
    UniformResourceLocatorW_AddRef,
    UniformResourceLocatorW_Release,
    UniformResourceLocatorW_SetUrl,
    UniformResourceLocatorW_GetUrl,
    UniformResourceLocatorW_InvokeCommand
};

static const IUniformResourceLocatorAVtbl uniformResourceLocatorAVtbl = {
    UniformResourceLocatorA_QueryInterface,
    UniformResourceLocatorA_AddRef,
    UniformResourceLocatorA_Release,
    UniformResourceLocatorA_SetUrl,
    UniformResourceLocatorA_GetUrl,
    UniformResourceLocatorA_InvokeCommand
};

static const IPersistFileVtbl persistFileVtbl = {
    PersistFile_QueryInterface,
    PersistFile_AddRef,
    PersistFile_Release,
    PersistFile_GetClassID,
    PersistFile_IsDirty,
    PersistFile_Load,
    PersistFile_Save,
    PersistFile_SaveCompleted,
    PersistFile_GetCurFile
};

static const IPropertySetStorageVtbl propertySetStorageVtbl = {
    PropertySetStorage_QueryInterface,
    PropertySetStorage_AddRef,
    PropertySetStorage_Release,
    PropertySetStorage_Create,
    PropertySetStorage_Open,
    PropertySetStorage_Delete,
    PropertySetStorage_Enum
};

static InternetShortcut *create_shortcut(void)
{
    InternetShortcut *newshortcut;

    newshortcut = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(InternetShortcut));
    if (newshortcut)
    {
        HRESULT hr;
        IPropertyStorage *dummy;

        newshortcut->IUniformResourceLocatorA_iface.lpVtbl = &uniformResourceLocatorAVtbl;
        newshortcut->IUniformResourceLocatorW_iface.lpVtbl = &uniformResourceLocatorWVtbl;
        newshortcut->IPersistFile_iface.lpVtbl = &persistFileVtbl;
        newshortcut->IPropertySetStorage_iface.lpVtbl = &propertySetStorageVtbl;
        newshortcut->refCount = 0;
        hr = StgCreateStorageEx(NULL, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
                                STGFMT_STORAGE, 0, NULL, NULL, &IID_IPropertySetStorage, (void **) &newshortcut->property_set_storage);
        if FAILED(hr)
        {
            TRACE("Failed to create the storage object needed for the shortcut.\n");
            heap_free(newshortcut);
            return NULL;
        }

        hr = IPropertySetStorage_Create(newshortcut->property_set_storage, &FMTID_Intshcut, NULL, PROPSETFLAG_DEFAULT, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &dummy);
        if FAILED(hr)
        {
            TRACE("Failed to create the property object needed for the shortcut.\n");
            IPropertySetStorage_Release(newshortcut->property_set_storage);
            heap_free(newshortcut);
            return NULL;
        }
        IPropertySetStorage_Release(dummy);
    }

    return newshortcut;
}

HRESULT InternetShortcut_Create(IUnknown *pOuter, REFIID riid, void **ppv)
{
    InternetShortcut *This;
    HRESULT hr;

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

    *ppv = NULL;

    if(pOuter)
        return CLASS_E_NOAGGREGATION;

    This = create_shortcut();
    if (This)
    {
        hr = Unknown_QueryInterface(This, riid, ppv);
        if (SUCCEEDED(hr))
            SHDOCVW_LockModule();
        else
            heap_free(This);
        return hr;
    }
    else
        return E_OUTOFMEMORY;
}


/**********************************************************************
 * OpenURL  (SHDOCVW.@)
 */
void WINAPI OpenURL(HWND hWnd, HINSTANCE hInst, LPCSTR lpcstrUrl, int nShowCmd)
{
    InternetShortcut *shortcut;
    WCHAR* urlfilepath = NULL;
    shortcut = create_shortcut();

    if (shortcut)
    {
        int len;

        len = MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, NULL, 0);
        urlfilepath = heap_alloc(len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, urlfilepath, len);

        if(SUCCEEDED(IPersistFile_Load(&shortcut->IPersistFile_iface, urlfilepath, 0)))
        {
            URLINVOKECOMMANDINFOW ici;

            memset( &ici, 0, sizeof ici );
            ici.dwcbSize = sizeof ici;
            ici.dwFlags = IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB;
            ici.hwndParent = hWnd;

            if(FAILED(UniformResourceLocatorW_InvokeCommand(&shortcut->IUniformResourceLocatorW_iface, (PURLINVOKECOMMANDINFOW) &ici)))
                    TRACE("failed to open URL: %s\n", debugstr_a(lpcstrUrl));
        }

        heap_free(shortcut);
        heap_free(urlfilepath);
    }
}
