/*
 *	handling of SHELL32.DLL OLE-Objects
 *
 *	Copyright 1997	Marcus Meissner
 *	Copyright 1998	Juergen Schmied  <juergen.schmied@metronet.de>
 *
 * 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 "config.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "shellapi.h"
#include "wingdi.h"
#include "winuser.h"
#include "shlobj.h"
#include "shlguid.h"
#include "shldisp.h"
#include "gdiplus.h"
#include "shimgdata.h"
#include "winreg.h"
#include "winerror.h"

#include "undocshell.h"
#include "wine/unicode.h"
#include "shell32_main.h"

#include "wine/debug.h"
#include "shlwapi.h"
#include "debughlp.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

extern INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax);  /* shlwapi.24 */
static HRESULT WINAPI ShellImageDataFactory_Constructor(IUnknown *outer, REFIID riid, void **obj);

/**************************************************************************
 * Default ClassFactory types
 */
typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
static IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst);

/* this table contains all CLSIDs of shell32 objects */
static const struct {
	REFIID			clsid;
	LPFNCREATEINSTANCE	lpfnCI;
} InterfaceTable[] = {

	{&CLSID_ApplicationAssociationRegistration, ApplicationAssociationRegistration_Constructor},
	{&CLSID_ApplicationDestinations, ApplicationDestinations_Constructor},
	{&CLSID_AutoComplete,   IAutoComplete_Constructor},
	{&CLSID_ControlPanel,	IControlPanel_Constructor},
	{&CLSID_DragDropHelper, IDropTargetHelper_Constructor},
	{&CLSID_FolderShortcut, FolderShortcut_Constructor},
	{&CLSID_MyComputer,	ISF_MyComputer_Constructor},
	{&CLSID_MyDocuments,    MyDocuments_Constructor},
	{&CLSID_NetworkPlaces,  ISF_NetworkPlaces_Constructor},
	{&CLSID_Printers,       Printers_Constructor},
	{&CLSID_QueryAssociations, QueryAssociations_Constructor},
	{&CLSID_RecycleBin,     RecycleBin_Constructor},
	{&CLSID_ShellDesktop,	ISF_Desktop_Constructor},
	{&CLSID_ShellFSFolder,	IFSFolder_Constructor},
	{&CLSID_ShellItem,	IShellItem_Constructor},
	{&CLSID_ShellLink,	IShellLink_Constructor},
	{&CLSID_UnixDosFolder,  UnixDosFolder_Constructor},
	{&CLSID_UnixFolder,     UnixFolder_Constructor},
	{&CLSID_ExplorerBrowser,ExplorerBrowser_Constructor},
	{&CLSID_KnownFolderManager, KnownFolderManager_Constructor},
	{&CLSID_Shell,          IShellDispatch_Constructor},
	{&CLSID_DestinationList, CustomDestinationList_Constructor},
	{&CLSID_ShellImageDataFactory, ShellImageDataFactory_Constructor},
	{NULL, NULL}
};

/*************************************************************************
 * SHCoCreateInstance [SHELL32.102]
 *
 * Equivalent to CoCreateInstance. Under Windows 9x this function could sometimes
 * use the shell32 built-in "mini-COM" without the need to load ole32.dll - see
 * SHLoadOLE for details.
 *
 * Under wine if a "LoadWithoutCOM" value is present or the object resides in
 * shell32.dll the function will load the object manually without the help of ole32
 *
 * NOTES
 *     exported by ordinal
 *
 * SEE ALSO
 *     CoCreateInstance, SHLoadOLE
 */
HRESULT WINAPI SHCoCreateInstance(
	LPCWSTR aclsid,
	const CLSID *clsid,
	LPUNKNOWN pUnkOuter,
	REFIID refiid,
	LPVOID *ppv)
{
	DWORD	hres;
	IID	iid;
	const	CLSID * myclsid = clsid;
	WCHAR	sKeyName[MAX_PATH];
	static const WCHAR sCLSID[] = {'C','L','S','I','D','\\','\0'};
	WCHAR	sClassID[60];
	static const WCHAR sInProcServer32[] = {'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2','\0'};
	static const WCHAR sLoadWithoutCOM[] = {'L','o','a','d','W','i','t','h','o','u','t','C','O','M','\0'};
	WCHAR	sDllPath[MAX_PATH];
	HKEY	hKey = 0;
	DWORD	dwSize;
	IClassFactory * pcf = NULL;

	if(!ppv) return E_POINTER;
	*ppv=NULL;

	/* if the clsid is a string, convert it */
	if (!clsid)
	{
	  if (!aclsid) return REGDB_E_CLASSNOTREG;
	  SHCLSIDFromStringW(aclsid, &iid);
	  myclsid = &iid;
	}

	TRACE("(%p,%s,unk:%p,%s,%p)\n",
		aclsid,shdebugstr_guid(myclsid),pUnkOuter,shdebugstr_guid(refiid),ppv);

        if (SUCCEEDED(DllGetClassObject(myclsid, &IID_IClassFactory,(LPVOID*)&pcf)))
        {
            hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv);
            IClassFactory_Release(pcf);
            goto end;
        }

	/* we look up the dll path in the registry */
        SHStringFromGUIDW(myclsid, sClassID, sizeof(sClassID)/sizeof(WCHAR));
	lstrcpyW(sKeyName, sCLSID);
	lstrcatW(sKeyName, sClassID);
	lstrcatW(sKeyName, sInProcServer32);

	if (RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey))
            return E_ACCESSDENIED;

        /* if a special registry key is set, we load a shell extension without help of OLE32 */
        if (!SHQueryValueExW(hKey, sLoadWithoutCOM, 0, 0, 0, 0))
        {
	    /* load an external dll without ole32 */
	    HANDLE hLibrary;
	    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
	    DllGetClassObjectFunc DllGetClassObject;

            dwSize = sizeof(sDllPath);
            SHQueryValueExW(hKey, NULL, 0,0, sDllPath, &dwSize );

	    if ((hLibrary = LoadLibraryExW(sDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
	        ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(sDllPath));
		hres = E_ACCESSDENIED;
	        goto end;
	    } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) {
	        ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(sDllPath));
	        FreeLibrary( hLibrary );
		hres = E_ACCESSDENIED;
	        goto end;
            } else if (FAILED(hres = DllGetClassObject(myclsid, &IID_IClassFactory, (LPVOID*)&pcf))) {
		    TRACE("GetClassObject failed 0x%08x\n", hres);
		    goto end;
	    }

            hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv);
            IClassFactory_Release(pcf);
	} else {

	    /* load an external dll in the usual way */
	    hres = CoCreateInstance(myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv);
	}

end:
        if (hKey) RegCloseKey(hKey);
	if(hres!=S_OK)
	{
	  ERR("failed (0x%08x) to create CLSID:%s IID:%s\n",
              hres, shdebugstr_guid(myclsid), shdebugstr_guid(refiid));
	  ERR("class not found in registry\n");
	}

	TRACE("-- instance: %p\n",*ppv);
	return hres;
}

/*************************************************************************
 * DllGetClassObject     [SHELL32.@]
 * SHDllGetClassObject   [SHELL32.128]
 */
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
{
	IClassFactory * pcf = NULL;
	HRESULT	hres;
	int i;

	TRACE("CLSID:%s,IID:%s\n",shdebugstr_guid(rclsid),shdebugstr_guid(iid));

	if (!ppv) return E_INVALIDARG;
	*ppv = NULL;

	/* search our internal interface table */
	for(i=0;InterfaceTable[i].clsid;i++) {
	    if(IsEqualIID(InterfaceTable[i].clsid, rclsid)) {
	        TRACE("index[%u]\n", i);
	        pcf = IDefClF_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL);
	        break;
	    }
	}

        if (!pcf) {
	    FIXME("failed for CLSID=%s\n", shdebugstr_guid(rclsid));
	    return CLASS_E_CLASSNOTAVAILABLE;
	}

	hres = IClassFactory_QueryInterface(pcf, iid, ppv);
	IClassFactory_Release(pcf);

	TRACE("-- pointer to class factory: %p\n",*ppv);
	return hres;
}

/*************************************************************************
 * SHCLSIDFromString				[SHELL32.147]
 *
 * Under Windows 9x this was an ANSI version of CLSIDFromString. It also allowed
 * to avoid dependency on ole32.dll (see SHLoadOLE for details).
 *
 * Under Windows NT/2000/XP this is equivalent to CLSIDFromString
 *
 * NOTES
 *     exported by ordinal
 *
 * SEE ALSO
 *     CLSIDFromString, SHLoadOLE
 */
DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id)
{
    WCHAR buffer[40];
    TRACE("(%p(%s) %p)\n", clsid, clsid, id);
    if (!MultiByteToWideChar( CP_ACP, 0, clsid, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
        return CO_E_CLASSSTRING;
    return CLSIDFromString( buffer, id );
}
DWORD WINAPI SHCLSIDFromStringW (LPCWSTR clsid, CLSID *id)
{
	TRACE("(%p(%s) %p)\n", clsid, debugstr_w(clsid), id);
	return CLSIDFromString(clsid, id);
}
DWORD WINAPI SHCLSIDFromStringAW (LPCVOID clsid, CLSID *id)
{
	if (SHELL_OsIsUnicode())
	  return SHCLSIDFromStringW (clsid, id);
	return SHCLSIDFromStringA (clsid, id);
}

/*************************************************************************
 *			 SHGetMalloc			[SHELL32.@]
 *
 * Equivalent to CoGetMalloc(MEMCTX_TASK, ...). Under Windows 9x this function
 * could use the shell32 built-in "mini-COM" without the need to load ole32.dll -
 * see SHLoadOLE for details. 
 *
 * PARAMS
 *  lpmal [O] Destination for IMalloc interface.
 *
 * RETURNS
 *  Success: S_OK. lpmal contains the shells IMalloc interface.
 *  Failure. An HRESULT error code.
 *
 * SEE ALSO
 *  CoGetMalloc, SHLoadOLE
 */
HRESULT WINAPI SHGetMalloc(LPMALLOC *lpmal)
{
	TRACE("(%p)\n", lpmal);
	return CoGetMalloc(MEMCTX_TASK, lpmal);
}

/*************************************************************************
 * SHAlloc					[SHELL32.196]
 *
 * Equivalent to CoTaskMemAlloc. Under Windows 9x this function could use
 * the shell32 built-in "mini-COM" without the need to load ole32.dll -
 * see SHLoadOLE for details. 
 *
 * NOTES
 *     exported by ordinal
 *
 * SEE ALSO
 *     CoTaskMemAlloc, SHLoadOLE
 */
LPVOID WINAPI SHAlloc(DWORD len)
{
	LPVOID ret;

	ret = CoTaskMemAlloc(len);
	TRACE("%u bytes at %p\n",len, ret);
	return ret;
}

/*************************************************************************
 * SHFree					[SHELL32.195]
 *
 * Equivalent to CoTaskMemFree. Under Windows 9x this function could use
 * the shell32 built-in "mini-COM" without the need to load ole32.dll -
 * see SHLoadOLE for details. 
 *
 * NOTES
 *     exported by ordinal
 *
 * SEE ALSO
 *     CoTaskMemFree, SHLoadOLE
 */
void WINAPI SHFree(LPVOID pv)
{
	TRACE("%p\n",pv);
	CoTaskMemFree(pv);
}

/*************************************************************************
 * SHGetDesktopFolder			[SHELL32.@]
 */
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
{
	HRESULT	hres;

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

	if(!psf) return E_INVALIDARG;

	*psf = NULL;
	hres = ISF_Desktop_Constructor(NULL, &IID_IShellFolder, (LPVOID*)psf);

	TRACE("-- %p->(%p) 0x%08x\n", psf, *psf, hres);
	return hres;
}
/**************************************************************************
 * Default ClassFactory Implementation
 *
 * SHCreateDefClassObject
 *
 * NOTES
 *  Helper function for dlls without their own classfactory.
 *  A generic classfactory is returned.
 *  When the CreateInstance of the cf is called the callback is executed.
 */

typedef struct
{
    IClassFactory               IClassFactory_iface;
    LONG                        ref;
    CLSID			*rclsid;
    LPFNCREATEINSTANCE		lpfnCI;
    const IID *			riidInst;
    LONG *			pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */
} IDefClFImpl;

static inline IDefClFImpl *impl_from_IClassFactory(IClassFactory *iface)
{
	return CONTAINING_RECORD(iface, IDefClFImpl, IClassFactory_iface);
}

static const IClassFactoryVtbl dclfvt;

/**************************************************************************
 *  IDefClF_fnConstructor
 */

static IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst)
{
	IDefClFImpl* lpclf;

	lpclf = HeapAlloc(GetProcessHeap(),0,sizeof(IDefClFImpl));
	lpclf->ref = 1;
	lpclf->IClassFactory_iface.lpVtbl = &dclfvt;
	lpclf->lpfnCI = lpfnCI;
	lpclf->pcRefDll = pcRefDll;

	if (pcRefDll) InterlockedIncrement(pcRefDll);
	lpclf->riidInst = riidInst;

	TRACE("(%p)%s\n",lpclf, shdebugstr_guid(riidInst));
	return (LPCLASSFACTORY)lpclf;
}
/**************************************************************************
 *  IDefClF_fnQueryInterface
 */
static HRESULT WINAPI IDefClF_fnQueryInterface(
  LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
{
	IDefClFImpl *This = impl_from_IClassFactory(iface);

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

	*ppvObj = NULL;

	if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) {
	  *ppvObj = This;
	  InterlockedIncrement(&This->ref);
	  return S_OK;
	}

	TRACE("-- E_NOINTERFACE\n");
	return E_NOINTERFACE;
}
/******************************************************************************
 * IDefClF_fnAddRef
 */
static ULONG WINAPI IDefClF_fnAddRef(LPCLASSFACTORY iface)
{
	IDefClFImpl *This = impl_from_IClassFactory(iface);
	ULONG refCount = InterlockedIncrement(&This->ref);

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

	return refCount;
}
/******************************************************************************
 * IDefClF_fnRelease
 */
static ULONG WINAPI IDefClF_fnRelease(LPCLASSFACTORY iface)
{
	IDefClFImpl *This = impl_from_IClassFactory(iface);
	ULONG refCount = InterlockedDecrement(&This->ref);

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

	if (!refCount)
	{
	  if (This->pcRefDll) InterlockedDecrement(This->pcRefDll);

	  TRACE("-- destroying IClassFactory(%p)\n",This);
	  HeapFree(GetProcessHeap(),0,This);
	  return 0;
	}
	return refCount;
}
/******************************************************************************
 * IDefClF_fnCreateInstance
 */
static HRESULT WINAPI IDefClF_fnCreateInstance(
  LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
{
	IDefClFImpl *This = impl_from_IClassFactory(iface);

	TRACE("%p->(%p,%s,%p)\n",This,pUnkOuter,shdebugstr_guid(riid),ppvObject);

	*ppvObject = NULL;

	if ( This->riidInst==NULL ||
	     IsEqualCLSID(riid, This->riidInst) ||
	     IsEqualCLSID(riid, &IID_IUnknown) )
	{
	  return This->lpfnCI(pUnkOuter, riid, ppvObject);
	}

	ERR("unknown IID requested %s\n",shdebugstr_guid(riid));
	return E_NOINTERFACE;
}
/******************************************************************************
 * IDefClF_fnLockServer
 */
static HRESULT WINAPI IDefClF_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
{
	IDefClFImpl *This = impl_from_IClassFactory(iface);
	TRACE("%p->(0x%x), not implemented\n",This, fLock);
	return E_NOTIMPL;
}

static const IClassFactoryVtbl dclfvt =
{
    IDefClF_fnQueryInterface,
    IDefClF_fnAddRef,
  IDefClF_fnRelease,
  IDefClF_fnCreateInstance,
  IDefClF_fnLockServer
};

/******************************************************************************
 * SHCreateDefClassObject			[SHELL32.70]
 */
HRESULT WINAPI SHCreateDefClassObject(
	REFIID	riid,
	LPVOID*	ppv,
	LPFNCREATEINSTANCE lpfnCI,	/* [in] create instance callback entry */
	LPDWORD	pcRefDll,		/* [in/out] ref count of the dll */
	REFIID	riidInst)		/* [in] optional interface to the instance */
{
	IClassFactory * pcf;

	TRACE("%s %p %p %p %s\n",
              shdebugstr_guid(riid), ppv, lpfnCI, pcRefDll, shdebugstr_guid(riidInst));

	if (! IsEqualCLSID(riid, &IID_IClassFactory) ) return E_NOINTERFACE;
	if (! (pcf = IDefClF_fnConstructor(lpfnCI, (PLONG)pcRefDll, riidInst))) return E_OUTOFMEMORY;
	*ppv = pcf;
	return S_OK;
}

/*************************************************************************
 *  DragAcceptFiles		[SHELL32.@]
 */
void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
{
	LONG exstyle;

	if( !IsWindow(hWnd) ) return;
	exstyle = GetWindowLongA(hWnd,GWL_EXSTYLE);
	if (b)
	  exstyle |= WS_EX_ACCEPTFILES;
	else
	  exstyle &= ~WS_EX_ACCEPTFILES;
	SetWindowLongA(hWnd,GWL_EXSTYLE,exstyle);
}

/*************************************************************************
 * DragFinish		[SHELL32.@]
 */
void WINAPI DragFinish(HDROP h)
{
	TRACE("\n");
	GlobalFree(h);
}

/*************************************************************************
 * DragQueryPoint		[SHELL32.@]
 */
BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
{
        DROPFILES *lpDropFileStruct;
	BOOL bRet;

	TRACE("\n");

	lpDropFileStruct = GlobalLock(hDrop);

        *p = lpDropFileStruct->pt;
	bRet = lpDropFileStruct->fNC;

	GlobalUnlock(hDrop);
	return bRet;
}

/*************************************************************************
 *  DragQueryFileA		[SHELL32.@]
 *  DragQueryFile 		[SHELL32.@]
 */
UINT WINAPI DragQueryFileA(
	HDROP hDrop,
	UINT lFile,
	LPSTR lpszFile,
	UINT lLength)
{
	LPSTR lpDrop;
	UINT i = 0;
	DROPFILES *lpDropFileStruct = GlobalLock(hDrop);

	TRACE("(%p, %x, %p, %u)\n",	hDrop,lFile,lpszFile,lLength);

	if(!lpDropFileStruct) goto end;

	lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->pFiles;

        if(lpDropFileStruct->fWide) {
            LPWSTR lpszFileW = NULL;

            if(lpszFile && lFile != 0xFFFFFFFF) {
                lpszFileW = HeapAlloc(GetProcessHeap(), 0, lLength*sizeof(WCHAR));
                if(lpszFileW == NULL) {
                    goto end;
                }
            }
            i = DragQueryFileW(hDrop, lFile, lpszFileW, lLength);

            if(lpszFileW) {
                WideCharToMultiByte(CP_ACP, 0, lpszFileW, -1, lpszFile, lLength, 0, NULL);
                HeapFree(GetProcessHeap(), 0, lpszFileW);
            }
            goto end;
        }

	while (i++ < lFile)
	{
	  while (*lpDrop++); /* skip filename */
	  if (!*lpDrop)
	  {
	    i = (lFile == 0xFFFFFFFF) ? i : 0;
	    goto end;
	  }
	}

	i = strlen(lpDrop);
	if (!lpszFile ) goto end;   /* needed buffer size */
	lstrcpynA (lpszFile, lpDrop, lLength);
end:
	GlobalUnlock(hDrop);
	return i;
}

/*************************************************************************
 *  DragQueryFileW		[SHELL32.@]
 */
UINT WINAPI DragQueryFileW(
	HDROP hDrop,
	UINT lFile,
	LPWSTR lpszwFile,
	UINT lLength)
{
	LPWSTR lpwDrop;
	UINT i = 0;
	DROPFILES *lpDropFileStruct = GlobalLock(hDrop);

	TRACE("(%p, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength);

	if(!lpDropFileStruct) goto end;

	lpwDrop = (LPWSTR) ((LPSTR)lpDropFileStruct + lpDropFileStruct->pFiles);

        if(lpDropFileStruct->fWide == FALSE) {
            LPSTR lpszFileA = NULL;

            if(lpszwFile && lFile != 0xFFFFFFFF) {
                lpszFileA = HeapAlloc(GetProcessHeap(), 0, lLength);
                if(lpszFileA == NULL) {
                    goto end;
                }
            }
            i = DragQueryFileA(hDrop, lFile, lpszFileA, lLength);

            if(lpszFileA) {
                MultiByteToWideChar(CP_ACP, 0, lpszFileA, -1, lpszwFile, lLength);
                HeapFree(GetProcessHeap(), 0, lpszFileA);
            }
            goto end;
        }

	i = 0;
	while (i++ < lFile)
	{
	  while (*lpwDrop++); /* skip filename */
	  if (!*lpwDrop)
	  {
	    i = (lFile == 0xFFFFFFFF) ? i : 0;
	    goto end;
	  }
	}

	i = strlenW(lpwDrop);
	if ( !lpszwFile) goto end;   /* needed buffer size */
	lstrcpynW (lpszwFile, lpwDrop, lLength);
end:
	GlobalUnlock(hDrop);
	return i;
}

/*************************************************************************
 *  SHPropStgCreate             [SHELL32.685]
 */
HRESULT WINAPI SHPropStgCreate(IPropertySetStorage *psstg, REFFMTID fmtid,
        const CLSID *pclsid, DWORD grfFlags, DWORD grfMode,
        DWORD dwDisposition, IPropertyStorage **ppstg, UINT *puCodePage)
{
    PROPSPEC prop;
    PROPVARIANT ret;
    HRESULT hres;

    TRACE("%p %s %s %x %x %x %p %p\n", psstg, debugstr_guid(fmtid), debugstr_guid(pclsid),
            grfFlags, grfMode, dwDisposition, ppstg, puCodePage);

    hres = IPropertySetStorage_Open(psstg, fmtid, grfMode, ppstg);

    switch(dwDisposition) {
    case CREATE_ALWAYS:
        if(SUCCEEDED(hres)) {
            IPropertyStorage_Release(*ppstg);
            hres = IPropertySetStorage_Delete(psstg, fmtid);
            if(FAILED(hres))
                return hres;
            hres = E_FAIL;
        }

    case OPEN_ALWAYS:
    case CREATE_NEW:
        if(FAILED(hres))
            hres = IPropertySetStorage_Create(psstg, fmtid, pclsid,
                    grfFlags, grfMode, ppstg);

    case OPEN_EXISTING:
        if(FAILED(hres))
            return hres;

        if(puCodePage) {
            prop.ulKind = PRSPEC_PROPID;
            prop.u.propid = PID_CODEPAGE;
            hres = IPropertyStorage_ReadMultiple(*ppstg, 1, &prop, &ret);
            if(FAILED(hres) || ret.vt!=VT_I2)
                *puCodePage = 0;
            else
                *puCodePage = ret.u.iVal;
        }
    }

    return S_OK;
}

/*************************************************************************
 *  SHPropStgReadMultiple       [SHELL32.688]
 */
HRESULT WINAPI SHPropStgReadMultiple(IPropertyStorage *pps, UINT uCodePage,
        ULONG cpspec, const PROPSPEC *rgpspec, PROPVARIANT *rgvar)
{
    STATPROPSETSTG stat;
    HRESULT hres;

    FIXME("%p %u %u %p %p\n", pps, uCodePage, cpspec, rgpspec, rgvar);

    memset(rgvar, 0, cpspec*sizeof(PROPVARIANT));
    hres = IPropertyStorage_ReadMultiple(pps, cpspec, rgpspec, rgvar);
    if(FAILED(hres))
        return hres;

    if(!uCodePage) {
        PROPSPEC prop;
        PROPVARIANT ret;

        prop.ulKind = PRSPEC_PROPID;
        prop.u.propid = PID_CODEPAGE;
        hres = IPropertyStorage_ReadMultiple(pps, 1, &prop, &ret);
        if(FAILED(hres) || ret.vt!=VT_I2)
            return S_OK;

        uCodePage = ret.u.iVal;
    }

    hres = IPropertyStorage_Stat(pps, &stat);
    if(FAILED(hres))
        return S_OK;

    /* TODO: do something with codepage and stat */
    return S_OK;
}

/*************************************************************************
 *  SHPropStgWriteMultiple      [SHELL32.689]
 */
HRESULT WINAPI SHPropStgWriteMultiple(IPropertyStorage *pps, UINT *uCodePage,
        ULONG cpspec, const PROPSPEC *rgpspec, PROPVARIANT *rgvar, PROPID propidNameFirst)
{
    STATPROPSETSTG stat;
    UINT codepage;
    HRESULT hres;

    FIXME("%p %p %u %p %p %d\n", pps, uCodePage, cpspec, rgpspec, rgvar, propidNameFirst);

    hres = IPropertyStorage_Stat(pps, &stat);
    if(FAILED(hres))
        return hres;

    if(uCodePage && *uCodePage)
        codepage = *uCodePage;
    else {
        PROPSPEC prop;
        PROPVARIANT ret;

        prop.ulKind = PRSPEC_PROPID;
        prop.u.propid = PID_CODEPAGE;
        hres = IPropertyStorage_ReadMultiple(pps, 1, &prop, &ret);
        if(FAILED(hres))
            return hres;
        if(ret.vt!=VT_I2 || !ret.u.iVal)
            return E_FAIL;

        codepage = ret.u.iVal;
        if(uCodePage)
            *uCodePage = codepage;
    }

    /* TODO: do something with codepage and stat */

    hres = IPropertyStorage_WriteMultiple(pps, cpspec, rgpspec, rgvar, propidNameFirst);
    return hres;
}

/*************************************************************************
 *  SHCreateQueryCancelAutoPlayMoniker [SHELL32.@]
 */
HRESULT WINAPI SHCreateQueryCancelAutoPlayMoniker(IMoniker **moniker)
{
    TRACE("%p\n", moniker);

    if (!moniker) return E_INVALIDARG;
    return CreateClassMoniker(&CLSID_QueryCancelAutoPlay, moniker);
}

static HRESULT gpstatus_to_hresult(GpStatus status)
{
    switch (status)
    {
    case Ok:
        return S_OK;
    case InvalidParameter:
        return E_INVALIDARG;
    case OutOfMemory:
        return E_OUTOFMEMORY;
    case NotImplemented:
        return E_NOTIMPL;
    default:
        return E_FAIL;
    }
}

/* IShellImageData */
typedef struct
{
    IShellImageData IShellImageData_iface;
    LONG ref;

    WCHAR *path;
    GpImage *image;
} ShellImageData;

static inline ShellImageData *impl_from_IShellImageData(IShellImageData *iface)
{
    return CONTAINING_RECORD(iface, ShellImageData, IShellImageData_iface);
}

static HRESULT WINAPI ShellImageData_QueryInterface(IShellImageData *iface, REFIID riid, void **obj)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    TRACE("%p, %s, %p\n", This, debugstr_guid(riid), obj);

    if (IsEqualIID(riid, &IID_IShellImageData) || IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = &This->IShellImageData_iface;
        IShellImageData_AddRef(iface);
        return S_OK;
    }

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI ShellImageData_AddRef(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI ShellImageData_Release(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (!ref)
    {
        GdipDisposeImage(This->image);
        HeapFree(GetProcessHeap(), 0, This->path);
        SHFree(This);
    }

    return ref;
}

static HRESULT WINAPI ShellImageData_Decode(IShellImageData *iface, DWORD flags, ULONG cx_desired, ULONG cy_desired)
{
    ShellImageData *This = impl_from_IShellImageData(iface);
    GpImage *image;
    HRESULT hr;

    TRACE("%p, %#x, %u, %u\n", This, flags, cx_desired, cy_desired);

    if (This->image)
        return S_FALSE;

    if (flags & SHIMGDEC_LOADFULL)
        FIXME("LOADFULL flag ignored\n");

    hr = gpstatus_to_hresult(GdipLoadImageFromFile(This->path, &image));
    if (FAILED(hr))
        return hr;

    if (flags & SHIMGDEC_THUMBNAIL)
    {
        hr = gpstatus_to_hresult(GdipGetImageThumbnail(image, cx_desired, cy_desired, &This->image, NULL, NULL));
        GdipDisposeImage(image);
    }
    else
        This->image = image;

    return hr;
}

static HRESULT WINAPI ShellImageData_Draw(IShellImageData *iface, HDC hdc, RECT *dest, RECT *src)
{
    ShellImageData *This = impl_from_IShellImageData(iface);
    GpGraphics *graphics;
    HRESULT hr;

    TRACE("%p, %p, %s, %s\n", This, hdc, wine_dbgstr_rect(dest), wine_dbgstr_rect(src));

    if (!This->image)
        return E_FAIL;

    if (!dest)
        return E_INVALIDARG;

    if (!src)
        return S_OK;

    hr = gpstatus_to_hresult(GdipCreateFromHDC(hdc, &graphics));
    if (FAILED(hr))
        return hr;

    hr = gpstatus_to_hresult(GdipDrawImageRectRectI(graphics, This->image, dest->left, dest->top, dest->right - dest->left,
        dest->bottom - dest->top, src->left, src->top, src->right - src->left, src->bottom - src->top,
        UnitPixel, NULL, NULL, NULL));
    GdipDeleteGraphics(graphics);

    return hr;
}

static HRESULT WINAPI ShellImageData_NextFrame(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_NextPage(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_PrevPage(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_IsTransparent(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_IsAnimated(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_IsVector(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_IsMultipage(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_IsEditable(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_IsPrintable(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_IsDecoded(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetCurrentPage(IShellImageData *iface, ULONG *page)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetPageCount(IShellImageData *iface, ULONG *count)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p: stub\n", This, count);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageDate_SelectPage(IShellImageData *iface, ULONG page)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %u: stub\n", This, page);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetSize(IShellImageData *iface, SIZE *size)
{
    ShellImageData *This = impl_from_IShellImageData(iface);
    REAL cx, cy;
    HRESULT hr;

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

    if (!This->image)
        return E_FAIL;

    hr = gpstatus_to_hresult(GdipGetImageDimension(This->image, &cx, &cy));
    if (SUCCEEDED(hr))
    {
        size->cx = cx;
        size->cy = cy;
    }

    return hr;
}

static HRESULT WINAPI ShellImageData_GetRawDataFormat(IShellImageData *iface, GUID *format)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p: stub\n", This, format);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetPixelFormat(IShellImageData *iface, PixelFormat *format)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p: stub\n", This, format);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetDelay(IShellImageData *iface, DWORD *delay)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p: stub\n", This, delay);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetProperties(IShellImageData *iface, DWORD mode, IPropertySetStorage **props)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %#x, %p: stub\n", This, mode, props);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_Rotate(IShellImageData *iface, DWORD angle)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %u: stub\n", This, angle);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_Scale(IShellImageData *iface, ULONG cx, ULONG cy, InterpolationMode mode)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %u, %u, %#x: stub\n", This, cx, cy, mode);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_DiscardEdit(IShellImageData *iface)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p: stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageDate_SetEncoderParams(IShellImageData *iface, IPropertyBag *params)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p: stub\n", This, params);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_DisplayName(IShellImageData *iface, LPWSTR name, UINT count)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p, %u: stub\n", This, name, count);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetResolution(IShellImageData *iface, ULONG *res_x, ULONG *res_y)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p, %p: stub\n", This, res_x, res_y);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_GetEncoderParams(IShellImageData *iface, GUID *format, EncoderParameters **params)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p, %p: stub\n", This, format, params);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_RegisterAbort(IShellImageData *iface, IShellImageDataAbort *abort,
    IShellImageDataAbort **prev)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p, %p: stub\n", This, abort, prev);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_CloneFrame(IShellImageData *iface, Image **frame)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p: stub\n", This, frame);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageData_ReplaceFrame(IShellImageData *iface, Image *frame)
{
    ShellImageData *This = impl_from_IShellImageData(iface);

    FIXME("%p, %p: stub\n", This, frame);

    return E_NOTIMPL;
}

static const IShellImageDataVtbl ShellImageDataVtbl =
{
    ShellImageData_QueryInterface,
    ShellImageData_AddRef,
    ShellImageData_Release,
    ShellImageData_Decode,
    ShellImageData_Draw,
    ShellImageData_NextFrame,
    ShellImageData_NextPage,
    ShellImageData_PrevPage,
    ShellImageData_IsTransparent,
    ShellImageData_IsAnimated,
    ShellImageData_IsVector,
    ShellImageData_IsMultipage,
    ShellImageData_IsEditable,
    ShellImageData_IsPrintable,
    ShellImageData_IsDecoded,
    ShellImageData_GetCurrentPage,
    ShellImageData_GetPageCount,
    ShellImageDate_SelectPage,
    ShellImageData_GetSize,
    ShellImageData_GetRawDataFormat,
    ShellImageData_GetPixelFormat,
    ShellImageData_GetDelay,
    ShellImageData_GetProperties,
    ShellImageData_Rotate,
    ShellImageData_Scale,
    ShellImageData_DiscardEdit,
    ShellImageDate_SetEncoderParams,
    ShellImageData_DisplayName,
    ShellImageData_GetResolution,
    ShellImageData_GetEncoderParams,
    ShellImageData_RegisterAbort,
    ShellImageData_CloneFrame,
    ShellImageData_ReplaceFrame,
};

static HRESULT create_shellimagedata_from_path(const WCHAR *path, IShellImageData **data)
{
    ShellImageData *This;

    This = SHAlloc(sizeof(*This));

    This->IShellImageData_iface.lpVtbl = &ShellImageDataVtbl;
    This->ref = 1;

    This->path = strdupW(path);
    This->image = NULL;

    *data = &This->IShellImageData_iface;
    return S_OK;
}

/* IShellImageDataFactory */
static HRESULT WINAPI ShellImageDataFactory_QueryInterface(IShellImageDataFactory *iface, REFIID riid, void **obj)
{
    TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), obj);

    if (IsEqualIID(&IID_IShellImageDataFactory, riid) || IsEqualIID(&IID_IUnknown, riid))
    {
        *obj = iface;
    }
    else
    {
        FIXME("not implemented for %s\n", debugstr_guid(riid));
        *obj = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI ShellImageDataFactory_AddRef(IShellImageDataFactory *iface)
{
    TRACE("(%p)\n", iface);

    return 2;
}

static ULONG WINAPI ShellImageDataFactory_Release(IShellImageDataFactory *iface)
{
    TRACE("(%p)\n", iface);

    return 1;
}

static HRESULT WINAPI ShellImageDataFactory_CreateIShellImageData(IShellImageDataFactory *iface, IShellImageData **data)
{
    FIXME("%p, %p: stub\n", iface, data);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageDataFactory_CreateImageFromFile(IShellImageDataFactory *iface, const WCHAR *path,
    IShellImageData **data)
{
    TRACE("%p, %s, %p\n", iface, debugstr_w(path), data);

    return create_shellimagedata_from_path(path, data);
}

static HRESULT WINAPI ShellImageDataFactory_CreateImageFromStream(IShellImageDataFactory *iface, IStream *stream,
    IShellImageData **data)
{
    FIXME("%p, %p, %p: stub\n", iface, stream, data);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellImageDataFactory_GetDataFormatFromPath(IShellImageDataFactory *iface, const WCHAR *path,
    GUID *format)
{
    FIXME("%p, %s, %p: stub\n", iface, debugstr_w(path), format);

    return E_NOTIMPL;
}

static const IShellImageDataFactoryVtbl ShellImageDataFactoryVtbl =
{
    ShellImageDataFactory_QueryInterface,
    ShellImageDataFactory_AddRef,
    ShellImageDataFactory_Release,
    ShellImageDataFactory_CreateIShellImageData,
    ShellImageDataFactory_CreateImageFromFile,
    ShellImageDataFactory_CreateImageFromStream,
    ShellImageDataFactory_GetDataFormatFromPath,
};

static IShellImageDataFactory ShellImageDataFactory = { &ShellImageDataFactoryVtbl };

HRESULT WINAPI ShellImageDataFactory_Constructor(IUnknown *outer, REFIID riid, void **obj)
{
    TRACE("%p %s %p\n", outer, debugstr_guid(riid), obj);

    if (outer)
        return CLASS_E_NOAGGREGATION;

    return IShellImageDataFactory_QueryInterface(&ShellImageDataFactory, riid, obj);
}
