/* * * Copyright 1997 Marcus Meissner * Copyright 1998 Juergen Schmied * */ #include #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 = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 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 = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 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 = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 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 = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 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 = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 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 };