blob: 1cde64c94536e8cb80ad82add63f823a56ec5e52 [file] [log] [blame]
/*
*
* Copyright 1997 Marcus Meissner
* Copyright 1998 Juergen Schmied
*
*/
#include <string.h>
#include "debug.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "wine/obj_storage.h"
#include "wine/obj_shelllink.h"
#include "heap.h"
#include "winnls.h"
#include "pidl.h"
#include "shell32_main.h"
#include "shlguid.h"
DEFAULT_DEBUG_CHANNEL(shell)
/* link file formats */
#include "pshpack1.h"
/* lnk elements: simple link has 0x0B */
#define WORKDIR 0x10
#define ARGUMENT 0x20
#define ICON 0x40
/* startup type */
#define NORMAL 0x01
#define MAXIMIZED 0x03
#define MINIMIZED 0x07
typedef struct _LINK_HEADER
{ DWORD MagicStr; /* 0x00 'L','\0','\0','\0' */
GUID MagicGuid; /* 0x04 is CLSID_ShellLink */
DWORD Flag1; /* 0x14 describes elements following */
DWORD Flag2; /* 0x18 */
FILETIME Time1; /* 0x1c */
FILETIME Time2; /* 0x24 */
FILETIME Time3; /* 0x2c */
DWORD Unknown1; /* 0x34 */
DWORD Unknown2; /* 0x38 icon number */
DWORD Flag3; /* 0x3c startup type */
DWORD Unknown4; /* 0x40 hotkey */
DWORD Unknown5; /* 0x44 */
DWORD Unknown6; /* 0x48 */
USHORT PidlSize; /* 0x4c */
ITEMIDLIST Pidl; /* 0x4e */
} LINK_HEADER, * PLINK_HEADER;
#include "poppack.h"
/* IPersistFile Implementation */
typedef struct
{
/* IUnknown fields */
ICOM_VTABLE(IPersistFile)* lpvtbl;
DWORD ref;
LPSTR sPath;
LPITEMIDLIST pPidl;
} IPersistFileImpl;
static struct ICOM_VTABLE(IPersistFile) pfvt;
/**************************************************************************
* IPersistFile_Constructor
*/
IPersistFileImpl * IPersistFile_Constructor(void)
{
IPersistFileImpl* sl;
sl = (IPersistFileImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IPersistFileImpl));
sl->ref = 1;
sl->lpvtbl = &pfvt;
sl->sPath = NULL;
sl->pPidl = NULL;
TRACE(shell,"(%p)->()\n",sl);
shell32_ObjCount++;
return sl;
}
/**************************************************************************
* IPersistFile_QueryInterface
*/
static HRESULT WINAPI IPersistFile_fnQueryInterface(
IPersistFile* iface, REFIID riid, LPVOID *ppvObj)
{
ICOM_THIS(IPersistFileImpl,iface);
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
{ *ppvObj = This;
}
else if(IsEqualIID(riid, &IID_IPersistFile)) /*IPersistFile*/
{ *ppvObj = (LPPERSISTFILE)This;
}
if(*ppvObj)
{ IPersistFile_AddRef((IPersistFile*)*ppvObj);
TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
return S_OK;
}
TRACE(shell,"-- Interface: E_NOINTERFACE\n");
return E_NOINTERFACE;
}
/******************************************************************************
* IPersistFile_AddRef
*/
static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile* iface)
{
ICOM_THIS(IPersistFileImpl,iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount++;
return ++(This->ref);
}
/******************************************************************************
* IPersistFile_Release
*/
static ULONG WINAPI IPersistFile_fnRelease(IPersistFile* iface)
{
ICOM_THIS(IPersistFileImpl,iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount--;
if (!--(This->ref))
{ TRACE(shell,"-- destroying IPersistFile(%p)\n",This);
if (This->sPath)
HeapFree(GetProcessHeap(),0,This->sPath);
if (This->pPidl)
SHFree(This->pPidl);
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
static HRESULT WINAPI IPersistFile_fnGetClassID(const IPersistFile* iface, CLSID *pClassID)
{
ICOM_CTHIS(IPersistFile,iface);
FIXME(shell,"(%p)\n",This);
return NOERROR;
}
static HRESULT WINAPI IPersistFile_fnIsDirty(const IPersistFile* iface)
{
ICOM_CTHIS(IPersistFile,iface);
FIXME(shell,"(%p)\n",This);
return NOERROR;
}
static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode)
{
ICOM_THIS(IPersistFileImpl,iface);
OFSTRUCT ofs;
LPSTR sFile = HEAP_strdupWtoA ( GetProcessHeap(), 0, pszFileName);
HFILE hFile = OpenFile( sFile, &ofs, OF_READ );
HANDLE hMapping;
PLINK_HEADER pImage;
HRESULT hRet = E_FAIL;
CHAR sTemp[512];
TRACE(shell,"(%p)->(%s)\n",This,sFile);
HeapFree(GetProcessHeap(),0,sFile);
if ( !(hMapping = CreateFileMappingA(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL)))
{ WARN(shell,"failed to create filemap.\n");
goto end_1;
}
if ( !(pImage = (PLINK_HEADER) MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0)))
{ WARN(shell,"failed to mmap filemap.\n");
goto end_2;
}
if (!( (pImage->MagicStr == 0x0000004CL) && IsEqualIID(&pImage->MagicGuid, &CLSID_ShellLink)))
{ TRACE(shell,"file isn't a lnk\n");
goto end_3;
}
{ /* for debugging */
SYSTEMTIME time;
FileTimeToSystemTime (&pImage->Time1, &time);
GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, sTemp, 256);
TRACE(shell, "-- time1: %s\n", sTemp);
FileTimeToSystemTime (&pImage->Time2, &time);
GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, sTemp, 256);
TRACE(shell, "-- time2: %s\n", sTemp);
FileTimeToSystemTime (&pImage->Time3, &time);
GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, sTemp, 256);
TRACE(shell, "-- time3: %s\n", sTemp);
pdump (&pImage->Pidl);
}
if (!pcheck (&pImage->Pidl))
goto end_3;
This->pPidl = ILClone (&pImage->Pidl);
_ILGetPidlPath(&pImage->Pidl, sTemp, 512);
This->sPath = HEAP_strdupA ( GetProcessHeap(), 0, sTemp);
hRet = NOERROR;
end_3: UnmapViewOfFile(pImage);
end_2: CloseHandle(hMapping);
end_1: _lclose( hFile);
return hRet;
}
static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFileName, BOOL fRemember)
{
ICOM_THIS(IPersistFileImpl,iface);
FIXME(shell,"(%p)->(%s)\n",This,debugstr_w(pszFileName));
return NOERROR;
}
static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLESTR pszFileName)
{
ICOM_THIS(IPersistFileImpl,iface);
FIXME(shell,"(%p)->(%s)\n",This,debugstr_w(pszFileName));
return NOERROR;
}
static HRESULT WINAPI IPersistFile_fnGetCurFile(const IPersistFile* iface, LPOLESTR *ppszFileName)
{
ICOM_CTHIS(IPersistFileImpl,iface);
FIXME(shell,"(%p)\n",This);
return NOERROR;
}
static struct ICOM_VTABLE(IPersistFile) pfvt =
{
IPersistFile_fnQueryInterface,
IPersistFile_fnAddRef,
IPersistFile_fnRelease,
IPersistFile_fnGetClassID,
IPersistFile_fnIsDirty,
IPersistFile_fnLoad,
IPersistFile_fnSave,
IPersistFile_fnSaveCompleted,
IPersistFile_fnGetCurFile
};
/**************************************************************************
* IShellLink's IClassFactory implementation
*/
typedef struct
{
/* IUnknown fields */
ICOM_VTABLE(IClassFactory)* lpvtbl;
DWORD ref;
} IClassFactoryImpl;
static ICOM_VTABLE(IClassFactory) slcfvt;
/**************************************************************************
* IShellLink_CF_Constructor
*/
LPCLASSFACTORY IShellLink_CF_Constructor(void)
{
IClassFactoryImpl* lpclf;
lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
lpclf->ref = 1;
lpclf->lpvtbl = &slcfvt;
TRACE(shell,"(%p)->()\n",lpclf);
shell32_ObjCount++;
return (LPCLASSFACTORY)lpclf;
}
/**************************************************************************
* IShellLink_CF_QueryInterface
*/
static HRESULT WINAPI IShellLink_CF_QueryInterface(
IClassFactory* iface, REFIID riid, LPVOID *ppvObj)
{
ICOM_THIS(IClassFactoryImpl,iface);
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
{ *ppvObj = (LPUNKNOWN)This;
}
else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
{ *ppvObj = (LPCLASSFACTORY)This;
}
if(*ppvObj)
{ IUnknown_AddRef((IUnknown*)*ppvObj);
TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
return S_OK;
}
TRACE(shell,"-- Interface: E_NOINTERFACE\n");
return E_NOINTERFACE;
}
/******************************************************************************
* IShellLink_CF_AddRef
*/
static ULONG WINAPI IShellLink_CF_AddRef(IClassFactory* iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount++;
return ++(This->ref);
}
/******************************************************************************
* IShellLink_CF_Release
*/
static ULONG WINAPI IShellLink_CF_Release(IClassFactory* iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount--;
if (!--(This->ref))
{ TRACE(shell,"-- destroying IClassFactory(%p)\n",This);
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
/******************************************************************************
* IShellLink_CF_CreateInstance
*/
static HRESULT WINAPI IShellLink_CF_CreateInstance(
IClassFactory* iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
{
ICOM_THIS(IClassFactoryImpl,iface);
IUnknown *pObj = NULL;
HRESULT hres;
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
*ppObject = NULL;
if(pUnknown)
{ return(CLASS_E_NOAGGREGATION);
}
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLink))
{ pObj = (IUnknown *)IShellLink_Constructor();
}
else
{ ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
return(E_NOINTERFACE);
}
if (!pObj)
{ return(E_OUTOFMEMORY);
}
hres = IUnknown_QueryInterface(pObj,riid, ppObject);
IUnknown_Release(pObj);
TRACE(shell,"-- Object created: (%p)->%p\n",This,*ppObject);
return hres;
}
/******************************************************************************
* IShellLink_CF_LockServer
*/
static HRESULT WINAPI IShellLink_CF_LockServer(IClassFactory* iface, BOOL fLock)
{
ICOM_THIS(IClassFactoryImpl,iface);
TRACE(shell,"%p->(0x%x), not implemented\n",This, fLock);
return E_NOTIMPL;
}
static ICOM_VTABLE(IClassFactory) slcfvt =
{
IShellLink_CF_QueryInterface,
IShellLink_CF_AddRef,
IShellLink_CF_Release,
IShellLink_CF_CreateInstance,
IShellLink_CF_LockServer
};
/**************************************************************************
* IShellLink Implementation
*/
typedef struct
{
ICOM_VTABLE(IShellLink)* lpvtbl;
DWORD ref;
IPersistFileImpl* lppf;
} IShellLinkImpl;
static ICOM_VTABLE(IShellLink) slvt;
/**************************************************************************
* IShellLink_Constructor
*/
IShellLink * IShellLink_Constructor(void)
{ IShellLinkImpl * sl;
sl = (IShellLinkImpl *)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLinkImpl));
sl->ref = 1;
sl->lpvtbl = &slvt;
sl->lppf = IPersistFile_Constructor();
TRACE(shell,"(%p)->()\n",sl);
shell32_ObjCount++;
return (IShellLink *)sl;
}
/**************************************************************************
* IShellLink::QueryInterface
*/
static HRESULT WINAPI IShellLink_fnQueryInterface( IShellLink * iface, REFIID riid, LPVOID *ppvObj)
{
ICOM_THIS(IShellLinkImpl, iface);
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
{ *ppvObj = This;
}
else if(IsEqualIID(riid, &IID_IShellLink)) /*IShellLink*/
{ *ppvObj = (IShellLink *)This;
}
else if(IsEqualIID(riid, &IID_IPersistFile)) /*IPersistFile*/
{ *ppvObj = (IPersistFile *)This->lppf;
}
if(*ppvObj)
{ IShellLink_AddRef((IShellLink*)*ppvObj);
TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
return S_OK;
}
TRACE(shell,"-- Interface: E_NOINTERFACE\n");
return E_NOINTERFACE;
}
/******************************************************************************
* IShellLink_AddRef
*/
static ULONG WINAPI IShellLink_fnAddRef(IShellLink * iface)
{
ICOM_THIS(IShellLinkImpl, iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount++;
return ++(This->ref);
}
/******************************************************************************
* IShellLink_Release
*/
static ULONG WINAPI IShellLink_fnRelease(IShellLink * iface)
{
ICOM_THIS(IShellLinkImpl, iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount--;
if (!--(This->ref))
{ TRACE(shell,"-- destroying IShellLink(%p)\n",This);
IPersistFile_Release((IPersistFile*) This->lppf); /* IPersistFile*/
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
static HRESULT WINAPI IShellLink_fnGetPath(IShellLink * iface, LPSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
{
ICOM_THIS(IShellLinkImpl, iface);
TRACE(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
strncpy(pszFile,This->lppf->sPath, cchMaxPath);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnGetIDList(IShellLink * iface, LPITEMIDLIST * ppidl)
{
ICOM_THIS(IShellLinkImpl, iface);
TRACE(shell,"(%p)->(ppidl=%p)\n",This, ppidl);
*ppidl = ILClone(This->lppf->pPidl);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetIDList(IShellLink * iface, LPCITEMIDLIST pidl)
{
ICOM_THIS(IShellLinkImpl, iface);
TRACE (shell,"(%p)->(pidl=%p)\n",This, pidl);
if (This->lppf->pPidl)
SHFree(This->lppf->pPidl);
This->lppf->pPidl = ILClone (pidl);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnGetDescription(IShellLink * iface, LPSTR pszName,INT cchMaxName)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
strncpy(pszName,"Description, FIXME",cchMaxName);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetDescription(IShellLink * iface, LPCSTR pszName)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(desc=%s)\n",This, pszName);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnGetWorkingDirectory(IShellLink * iface, LPSTR pszDir,INT cchMaxPath)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->()\n",This);
strncpy(pszDir,"c:\\", cchMaxPath);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetWorkingDirectory(IShellLink * iface, LPCSTR pszDir)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(dir=%s)\n",This, pszDir);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnGetArguments(IShellLink * iface, LPSTR pszArgs,INT cchMaxPath)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
strncpy(pszArgs, "", cchMaxPath);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetArguments(IShellLink * iface, LPCSTR pszArgs)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(args=%s)\n",This, pszArgs);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnGetHotkey(IShellLink * iface, WORD *pwHotkey)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(%p) returning 0\n",This, pwHotkey);
*pwHotkey=0x0;
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetHotkey(IShellLink * iface, WORD wHotkey)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(hotkey=%x)\n",This, wHotkey);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnGetShowCmd(IShellLink * iface, INT *piShowCmd)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(%p)\n",This, piShowCmd);
*piShowCmd=0;
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetShowCmd(IShellLink * iface, INT iShowCmd)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(showcmd=%x)\n",This, iShowCmd);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnGetIconLocation(IShellLink * iface, LPSTR pszIconPath,INT cchIconPath,INT *piIcon)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
strncpy(pszIconPath,"shell32.dll",cchIconPath);
*piIcon=1;
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetIconLocation(IShellLink * iface, LPCSTR pszIconPath,INT iIcon)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetRelativePath(IShellLink * iface, LPCSTR pszPathRel, DWORD dwReserved)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnResolve(IShellLink * iface, HWND hwnd, DWORD fFlags)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
return NOERROR;
}
static HRESULT WINAPI IShellLink_fnSetPath(IShellLink * iface, LPCSTR pszFile)
{
ICOM_THIS(IShellLinkImpl, iface);
FIXME(shell,"(%p)->(path=%s)\n",This, pszFile);
return NOERROR;
}
/**************************************************************************
* IShellLink Implementation
*/
static ICOM_VTABLE(IShellLink) slvt =
{ IShellLink_fnQueryInterface,
IShellLink_fnAddRef,
IShellLink_fnRelease,
IShellLink_fnGetPath,
IShellLink_fnGetIDList,
IShellLink_fnSetIDList,
IShellLink_fnGetDescription,
IShellLink_fnSetDescription,
IShellLink_fnGetWorkingDirectory,
IShellLink_fnSetWorkingDirectory,
IShellLink_fnGetArguments,
IShellLink_fnSetArguments,
IShellLink_fnGetHotkey,
IShellLink_fnSetHotkey,
IShellLink_fnGetShowCmd,
IShellLink_fnSetShowCmd,
IShellLink_fnGetIconLocation,
IShellLink_fnSetIconLocation,
IShellLink_fnSetRelativePath,
IShellLink_fnResolve,
IShellLink_fnSetPath
};
/**************************************************************************
* IShellLink's IClassFactory implementation
*/
static ICOM_VTABLE(IClassFactory) slwcfvt;
/**************************************************************************
* IShellLinkW_CF_Constructor
*/
LPCLASSFACTORY IShellLinkW_CF_Constructor(void)
{
IClassFactoryImpl* lpclf;
lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
lpclf->ref = 1;
lpclf->lpvtbl = &slwcfvt;
TRACE(shell,"(%p)->()\n",lpclf);
shell32_ObjCount++;
return (LPCLASSFACTORY)lpclf;
}
/**************************************************************************
* IShellLinkW_CF_QueryInterface
*/
static HRESULT WINAPI IShellLinkW_CF_QueryInterface(
LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
{
ICOM_THIS(IClassFactoryImpl,iface);
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
{ *ppvObj = (LPUNKNOWN)This;
}
else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
{ *ppvObj = (LPCLASSFACTORY)This;
}
if(*ppvObj) {
IUnknown_AddRef((IUnknown*)*ppvObj);
TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
return S_OK;
}
TRACE(shell,"-- Interface: E_NOINTERFACE\n");
return E_NOINTERFACE;
}
/******************************************************************************
* IShellLinkW_CF_AddRef
*/
static ULONG WINAPI IShellLinkW_CF_AddRef(LPCLASSFACTORY iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount++;
return ++(This->ref);
}
/******************************************************************************
* IShellLinkW_CF_Release
*/
static ULONG WINAPI IShellLinkW_CF_Release(LPCLASSFACTORY iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount--;
if (!--(This->ref))
{ TRACE(shell,"-- destroying IClassFactory(%p)\n",This);
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
/******************************************************************************
* IShellLinkW_CF_CreateInstance
*/
static HRESULT WINAPI IShellLinkW_CF_CreateInstance(
LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
{
ICOM_THIS(IClassFactoryImpl,iface);
IUnknown *pObj = NULL;
HRESULT hres;
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
*ppObject = NULL;
if(pUnknown)
{ return(CLASS_E_NOAGGREGATION);
}
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLinkW))
{ pObj = (IUnknown *)IShellLinkW_Constructor();
}
else
{ ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
return(E_NOINTERFACE);
}
if (!pObj)
{ return(E_OUTOFMEMORY);
}
hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject);
pObj->lpvtbl->fnRelease(pObj);
TRACE(shell,"-- Object created: (%p)->%p\n",This,*ppObject);
return hres;
}
/******************************************************************************
* IShellLinkW_CF_LockServer
*/
static HRESULT WINAPI IShellLinkW_CF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
ICOM_THIS(IClassFactoryImpl,iface);
TRACE(shell,"%p->(0x%x), not implemented\n",This, fLock);
return E_NOTIMPL;
}
static ICOM_VTABLE(IClassFactory) slwcfvt =
{
IShellLinkW_CF_QueryInterface,
IShellLinkW_CF_AddRef,
IShellLinkW_CF_Release,
IShellLinkW_CF_CreateInstance,
IShellLinkW_CF_LockServer
};
/**************************************************************************
* IShellLink Implementation
*/
typedef struct
{
ICOM_VTABLE(IShellLinkW)* lpvtbl;
DWORD ref;
IPersistFileImpl* lppf;
} IShellLinkWImpl;
static ICOM_VTABLE(IShellLinkW) slvtw;
/**************************************************************************
* IShellLinkW_fnConstructor
*/
IShellLinkW * IShellLinkW_Constructor(void)
{ IShellLinkWImpl* sl;
sl = (IShellLinkWImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLinkWImpl));
sl->ref = 1;
sl->lpvtbl = &slvtw;
sl->lppf = IPersistFile_Constructor();
TRACE(shell,"(%p)->()\n",sl);
shell32_ObjCount++;
return (IShellLinkW*)sl;
}
/**************************************************************************
* IShellLinkW_fnQueryInterface
*/
static HRESULT WINAPI IShellLinkW_fnQueryInterface(
IShellLinkW * iface, REFIID riid, LPVOID *ppvObj)
{
ICOM_THIS(IShellLinkWImpl, iface);
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
{ *ppvObj = This;
}
else if(IsEqualIID(riid, &IID_IShellLinkW)) /*IShellLinkW*/
{ *ppvObj = (IShellLinkW *)This;
}
else if(IsEqualIID(riid, &IID_IPersistFile)) /*IPersistFile*/
{ *ppvObj = (IPersistFile *)This->lppf;
}
if(*ppvObj)
{ IShellLink_AddRef((IShellLinkW*)*ppvObj);
TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
return S_OK;
}
TRACE(shell,"-- Interface: E_NOINTERFACE\n");
return E_NOINTERFACE;
}
/******************************************************************************
* IShellLinkW_fnAddRef
*/
static ULONG WINAPI IShellLinkW_fnAddRef(IShellLinkW * iface)
{
ICOM_THIS(IShellLinkWImpl, iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount++;
return ++(This->ref);
}
/******************************************************************************
* IShellLinkW_fnRelease
*/
static ULONG WINAPI IShellLinkW_fnRelease(IShellLinkW * iface)
{
ICOM_THIS(IShellLinkWImpl, iface);
TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
shell32_ObjCount--;
if (!--(This->ref))
{ TRACE(shell,"-- destroying IShellLinkW(%p)\n",This);
IPersistFile_Release((IPersistFile*)This->lppf); /* IPersistFile*/
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
lstrcpynAtoW(pszFile,"c:\\foo.bar", cchMaxPath);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST * ppidl)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(ppidl=%p)\n",This, ppidl);
*ppidl = _ILCreateDesktop();
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetIDList(IShellLinkW * iface, LPCITEMIDLIST pidl)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(pidl=%p)\n",This, pidl);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnGetDescription(IShellLinkW * iface, LPWSTR pszName,INT cchMaxName)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
lstrcpynAtoW(pszName,"Description, FIXME",cchMaxName);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetDescription(IShellLinkW * iface, LPCWSTR pszName)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(desc=%s)\n",This, debugstr_w(pszName));
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnGetWorkingDirectory(IShellLinkW * iface, LPWSTR pszDir,INT cchMaxPath)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->()\n",This);
lstrcpynAtoW(pszDir,"c:\\", cchMaxPath);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetWorkingDirectory(IShellLinkW * iface, LPCWSTR pszDir)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(dir=%s)\n",This, debugstr_w(pszDir));
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnGetArguments(IShellLinkW * iface, LPWSTR pszArgs,INT cchMaxPath)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
lstrcpynAtoW(pszArgs, "", cchMaxPath);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetArguments(IShellLinkW * iface, LPCWSTR pszArgs)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(args=%s)\n",This, debugstr_w(pszArgs));
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnGetHotkey(IShellLinkW * iface, WORD *pwHotkey)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(%p)\n",This, pwHotkey);
*pwHotkey=0x0;
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetHotkey(IShellLinkW * iface, WORD wHotkey)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(hotkey=%x)\n",This, wHotkey);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnGetShowCmd(IShellLinkW * iface, INT *piShowCmd)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(%p)\n",This, piShowCmd);
*piShowCmd=0;
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetShowCmd(IShellLinkW * iface, INT iShowCmd)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(showcmd=%x)\n",This, iShowCmd);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR pszIconPath,INT cchIconPath,INT *piIcon)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
lstrcpynAtoW(pszIconPath,"shell32.dll",cchIconPath);
*piIcon=1;
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(path=%s iicon=%u)\n",This, debugstr_w(pszIconPath), iIcon);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR pszPathRel, DWORD dwReserved)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(path=%s %lx)\n",This, debugstr_w(pszPathRel), dwReserved);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
{
ICOM_THIS(IShellLinkWImpl, iface);
FIXME(shell,"(%p)->(path=%s)\n",This, debugstr_w(pszFile));
return NOERROR;
}
/**************************************************************************
* IShellLinkW Implementation
*/
static ICOM_VTABLE(IShellLinkW) slvtw =
{ IShellLinkW_fnQueryInterface,
IShellLinkW_fnAddRef,
IShellLinkW_fnRelease,
IShellLinkW_fnGetPath,
IShellLinkW_fnGetIDList,
IShellLinkW_fnSetIDList,
IShellLinkW_fnGetDescription,
IShellLinkW_fnSetDescription,
IShellLinkW_fnGetWorkingDirectory,
IShellLinkW_fnSetWorkingDirectory,
IShellLinkW_fnGetArguments,
IShellLinkW_fnSetArguments,
IShellLinkW_fnGetHotkey,
IShellLinkW_fnSetHotkey,
IShellLinkW_fnGetShowCmd,
IShellLinkW_fnSetShowCmd,
IShellLinkW_fnGetIconLocation,
IShellLinkW_fnSetIconLocation,
IShellLinkW_fnSetRelativePath,
IShellLinkW_fnResolve,
IShellLinkW_fnSetPath
};