Large-scale renaming of all Win32 functions and types to use the
[wine] / dlls / shell32 / shelllink.c
1 /*
2  *
3  *      Copyright 1997  Marcus Meissner
4  *      Copyright 1998  Juergen Schmied
5  *
6  */
7
8 #include <string.h>
9 #include "debug.h"
10 #include "winerror.h"
11
12 #include "wine/obj_base.h"
13 #include "wine/obj_storage.h"
14 #include "wine/obj_shelllink.h"
15
16 #include "heap.h"
17 #include "winnls.h"
18 #include "pidl.h"
19 #include "shell32_main.h"
20 #include "shlguid.h"
21
22 /* link file formats */
23
24 #pragma (1);
25
26 /* lnk elements: simple link has 0x0B */
27 #define WORKDIR         0x10
28 #define ARGUMENT        0x20
29 #define ICON            0x40
30 /* startup type */
31 #define NORMAL          0x01
32 #define MAXIMIZED       0x03
33 #define MINIMIZED       0x07
34
35 typedef struct _LINK_HEADER     
36 {       DWORD   MagicStr;       /* 0x00 'L','\0','\0','\0' */
37         GUID    MagicGuid;      /* 0x04 is CLSID_ShellLink */
38         DWORD   Flag1;          /* 0x14 describes elements following */
39         DWORD   Flag2;          /* 0x18 */
40         FILETIME Time1;         /* 0x1c */
41         FILETIME Time2;         /* 0x24 */
42         FILETIME Time3;         /* 0x2c */
43         DWORD   Unknown1;       /* 0x34 */
44         DWORD   Unknown2;       /* 0x38 icon number */
45         DWORD   Flag3;          /* 0x3c startup type */
46         DWORD   Unknown4;       /* 0x40 hotkey */
47         DWORD   Unknown5;       /* 0x44 */
48         DWORD   Unknown6;       /* 0x48 */
49         USHORT  PidlSize;       /* 0x4c */
50         ITEMIDLIST Pidl;        /* 0x4e */
51 } LINK_HEADER, * PLINK_HEADER;
52
53 #pragma (4);
54
55 /* IPersistFile Implementation */
56 typedef struct
57 {
58         /* IUnknown fields */
59         ICOM_VTABLE(IPersistFile)*      lpvtbl;
60         DWORD           ref;
61         LPSTR           sPath;
62         LPITEMIDLIST    pPidl;
63
64 } IPersistFileImpl;
65
66 static struct ICOM_VTABLE(IPersistFile) pfvt;
67
68
69 /**************************************************************************
70  *        IPersistFile_Constructor
71  */
72 IPersistFileImpl * IPersistFile_Constructor(void) 
73 {
74         IPersistFileImpl* sl;
75
76         sl = (IPersistFileImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IPersistFileImpl));
77         sl->ref = 1;
78         sl->lpvtbl = &pfvt;
79         sl->sPath = NULL;
80         sl->pPidl = NULL;
81                         
82         TRACE(shell,"(%p)->()\n",sl);
83         shell32_ObjCount++;
84         return sl;
85 }
86
87 /**************************************************************************
88  *  IPersistFile_QueryInterface
89  */
90 static HRESULT WINAPI IPersistFile_fnQueryInterface(
91   IPersistFile* iface, REFIID riid, LPVOID *ppvObj)
92 {
93         ICOM_THIS(IPersistFileImpl,iface);
94
95         char    xriid[50];
96         WINE_StringFromCLSID((LPCLSID)riid,xriid);
97         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
98
99         *ppvObj = NULL;
100
101         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
102         { *ppvObj = This; 
103         }
104         else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
105         {    *ppvObj = (LPPERSISTFILE)This;
106         }   
107
108         if(*ppvObj)
109         { IPersistFile_AddRef((IPersistFile*)*ppvObj);      
110           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
111           return S_OK;
112         }
113         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
114         return E_NOINTERFACE;
115 }  
116 /******************************************************************************
117  * IPersistFile_AddRef
118  */
119 static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile* iface)
120 {
121         ICOM_THIS(IPersistFileImpl,iface);
122
123         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
124
125         shell32_ObjCount++;
126         return ++(This->ref);
127 }
128 /******************************************************************************
129  * IPersistFile_Release
130  */
131 static ULONG WINAPI IPersistFile_fnRelease(IPersistFile* iface)
132 {
133         ICOM_THIS(IPersistFileImpl,iface);
134
135         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
136
137         shell32_ObjCount--;
138
139         if (!--(This->ref)) 
140         { TRACE(shell,"-- destroying IPersistFile(%p)\n",This);
141           if (This->sPath)
142             HeapFree(GetProcessHeap(),0,This->sPath);
143           if (This->pPidl)
144             SHFree(This->pPidl);
145           HeapFree(GetProcessHeap(),0,This);
146           return 0;
147         }
148         return This->ref;
149 }
150
151 static HRESULT WINAPI IPersistFile_fnGetClassID(const IPersistFile* iface, CLSID *pClassID)
152 {
153         ICOM_CTHIS(IPersistFile,iface);
154         FIXME(shell,"(%p)\n",This);
155         return NOERROR;
156 }
157 static HRESULT WINAPI IPersistFile_fnIsDirty(const IPersistFile* iface)
158 {
159         ICOM_CTHIS(IPersistFile,iface);
160         FIXME(shell,"(%p)\n",This);
161         return NOERROR;
162 }
163 static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode)
164 {
165         ICOM_THIS(IPersistFileImpl,iface);
166
167         OFSTRUCT        ofs;
168         LPSTR   sFile = HEAP_strdupWtoA ( GetProcessHeap(), 0, pszFileName);
169         HFILE   hFile = OpenFile( sFile, &ofs, OF_READ );
170         HANDLE  hMapping;
171         PLINK_HEADER    pImage;
172         HRESULT         hRet = E_FAIL;
173         CHAR            sTemp[512];
174         
175         TRACE(shell,"(%p)->(%s)\n",This,sFile); 
176
177         HeapFree(GetProcessHeap(),0,sFile);
178
179         if ( !(hMapping = CreateFileMappingA(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL))) 
180         { WARN(shell,"failed to create filemap.\n");
181           goto end_1;
182         }
183
184         if ( !(pImage = (PLINK_HEADER) MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0))) 
185         { WARN(shell,"failed to mmap filemap.\n");
186           goto end_2;   
187         }
188         
189         if (!( (pImage->MagicStr == 0x0000004CL) && IsEqualIID(&pImage->MagicGuid, &CLSID_ShellLink)))
190         { TRACE(shell,"file isn't a lnk\n");
191           goto end_3;
192         }
193         
194         { /* for debugging */
195           SYSTEMTIME time;
196           FileTimeToSystemTime (&pImage->Time1, &time);
197           GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  sTemp, 256);
198           TRACE(shell, "-- time1: %s\n", sTemp);
199
200           FileTimeToSystemTime (&pImage->Time2, &time);
201           GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  sTemp, 256);
202           TRACE(shell, "-- time2: %s\n", sTemp);
203
204           FileTimeToSystemTime (&pImage->Time3, &time);
205           GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  sTemp, 256);
206           TRACE(shell, "-- time3: %s\n", sTemp);
207           pdump (&pImage->Pidl);
208         }
209
210         This->pPidl = ILClone (&pImage->Pidl);
211
212         _ILGetPidlPath(&pImage->Pidl, sTemp, 512);
213         This->sPath = HEAP_strdupA ( GetProcessHeap(), 0, sTemp);
214                 
215         hRet = NOERROR;
216 end_3:  UnmapViewOfFile(pImage);
217 end_2:  CloseHandle(hMapping);
218 end_1:  _lclose( hFile);
219
220         return hRet;
221 }
222
223 static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFileName, BOOL fRemember)
224 {
225         ICOM_THIS(IPersistFileImpl,iface);
226         FIXME(shell,"(%p)->(%s)\n",This,debugstr_w(pszFileName));
227         return NOERROR;
228 }
229 static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLESTR pszFileName)
230 {
231         ICOM_THIS(IPersistFileImpl,iface);
232         FIXME(shell,"(%p)->(%s)\n",This,debugstr_w(pszFileName));
233         return NOERROR;
234 }
235 static HRESULT WINAPI IPersistFile_fnGetCurFile(const IPersistFile* iface, LPOLESTR *ppszFileName)
236 {
237         ICOM_CTHIS(IPersistFileImpl,iface);
238         FIXME(shell,"(%p)\n",This);
239         return NOERROR;
240 }
241   
242 static struct ICOM_VTABLE(IPersistFile) pfvt = 
243 {
244         IPersistFile_fnQueryInterface,
245         IPersistFile_fnAddRef,
246         IPersistFile_fnRelease,
247         IPersistFile_fnGetClassID,
248         IPersistFile_fnIsDirty,
249         IPersistFile_fnLoad,
250         IPersistFile_fnSave,
251         IPersistFile_fnSaveCompleted,
252         IPersistFile_fnGetCurFile
253 };
254
255
256 /**************************************************************************
257 *  IShellLink's IClassFactory implementation
258  */
259 typedef struct
260 {
261     /* IUnknown fields */
262     ICOM_VTABLE(IClassFactory)* lpvtbl;
263     DWORD                       ref;
264 } IClassFactoryImpl;
265
266 static ICOM_VTABLE(IClassFactory) slcfvt;
267
268 /**************************************************************************
269  *  IShellLink_CF_Constructor
270  */
271
272 LPCLASSFACTORY IShellLink_CF_Constructor(void)
273 {
274         IClassFactoryImpl* lpclf;
275
276         lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
277         lpclf->ref = 1;
278         lpclf->lpvtbl = &slcfvt;
279         TRACE(shell,"(%p)->()\n",lpclf);
280         shell32_ObjCount++;
281         return (LPCLASSFACTORY)lpclf;
282 }
283 /**************************************************************************
284  *  IShellLink_CF_QueryInterface
285  */
286 static HRESULT WINAPI IShellLink_CF_QueryInterface(
287   IClassFactory* iface, REFIID riid, LPVOID *ppvObj)
288 {
289         ICOM_THIS(IClassFactoryImpl,iface);
290         char    xriid[50];
291         WINE_StringFromCLSID((LPCLSID)riid,xriid);
292         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
293
294         *ppvObj = NULL;
295
296         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
297         { *ppvObj = (LPUNKNOWN)This; 
298         }
299         else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
300         { *ppvObj = (LPCLASSFACTORY)This;
301         }   
302
303         if(*ppvObj)
304         { IUnknown_AddRef((IUnknown*)*ppvObj);          
305           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
306           return S_OK;
307         }
308         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
309         return E_NOINTERFACE;
310 }  
311 /******************************************************************************
312  * IShellLink_CF_AddRef
313  */
314 static ULONG WINAPI IShellLink_CF_AddRef(IClassFactory* iface)
315 {
316         ICOM_THIS(IClassFactoryImpl,iface);
317         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
318
319         shell32_ObjCount++;
320         return ++(This->ref);
321 }
322 /******************************************************************************
323  * IShellLink_CF_Release
324  */
325 static ULONG WINAPI IShellLink_CF_Release(IClassFactory* iface)
326 {
327         ICOM_THIS(IClassFactoryImpl,iface);
328         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
329
330         shell32_ObjCount--;
331         if (!--(This->ref)) 
332         { TRACE(shell,"-- destroying IClassFactory(%p)\n",This);
333                 HeapFree(GetProcessHeap(),0,This);
334                 return 0;
335         }
336         return This->ref;
337 }
338 /******************************************************************************
339  * IShellLink_CF_CreateInstance
340  */
341 static HRESULT WINAPI IShellLink_CF_CreateInstance(
342   IClassFactory* iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
343 {
344         ICOM_THIS(IClassFactoryImpl,iface);
345         IUnknown *pObj = NULL;
346         HRESULT hres;
347         char    xriid[50];
348
349         WINE_StringFromCLSID((LPCLSID)riid,xriid);
350         TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
351
352         *ppObject = NULL;
353                 
354         if(pUnknown)
355         {       return(CLASS_E_NOAGGREGATION);
356         }
357
358         if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLink))
359         { pObj = (IUnknown *)IShellLink_Constructor();
360         } 
361         else
362         { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
363           return(E_NOINTERFACE);
364         }
365         
366         if (!pObj)
367         { return(E_OUTOFMEMORY);
368         }
369          
370         hres = IUnknown_QueryInterface(pObj,riid, ppObject);
371         IUnknown_Release(pObj);
372         TRACE(shell,"-- Object created: (%p)->%p\n",This,*ppObject);
373
374         return hres;
375 }
376 /******************************************************************************
377  * IShellLink_CF_LockServer
378  */
379 static HRESULT WINAPI IShellLink_CF_LockServer(IClassFactory* iface, BOOL fLock)
380 {
381         ICOM_THIS(IClassFactoryImpl,iface);
382         TRACE(shell,"%p->(0x%x), not implemented\n",This, fLock);
383         return E_NOTIMPL;
384 }
385 static ICOM_VTABLE(IClassFactory) slcfvt = 
386 {
387     IShellLink_CF_QueryInterface,
388     IShellLink_CF_AddRef,
389   IShellLink_CF_Release,
390   IShellLink_CF_CreateInstance,
391   IShellLink_CF_LockServer
392 };
393
394 /**************************************************************************
395  * IShellLink Implementation 
396  */
397
398 typedef struct
399 {
400         ICOM_VTABLE(IShellLink)*        lpvtbl;
401         DWORD                           ref;
402         IPersistFileImpl*               lppf;
403
404 } IShellLinkImpl;
405
406 static ICOM_VTABLE(IShellLink) slvt;
407
408 /**************************************************************************
409  *        IShellLink_Constructor
410  */
411 IShellLink * IShellLink_Constructor(void) 
412 {       IShellLinkImpl * sl;
413
414         sl = (IShellLinkImpl *)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLinkImpl));
415         sl->ref = 1;
416         sl->lpvtbl = &slvt;
417
418         sl->lppf = IPersistFile_Constructor();
419
420         TRACE(shell,"(%p)->()\n",sl);
421         shell32_ObjCount++;
422         return (IShellLink *)sl;
423 }
424
425 /**************************************************************************
426  *  IShellLink::QueryInterface
427  */
428 static HRESULT WINAPI IShellLink_fnQueryInterface( IShellLink * iface, REFIID riid,  LPVOID *ppvObj)
429 {
430         ICOM_THIS(IShellLinkImpl, iface);
431         
432         char    xriid[50];
433         WINE_StringFromCLSID((LPCLSID)riid,xriid);
434         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
435
436         *ppvObj = NULL;
437
438         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
439         { *ppvObj = This; 
440         }
441         else if(IsEqualIID(riid, &IID_IShellLink))  /*IShellLink*/
442         {    *ppvObj = (IShellLink *)This;
443         }   
444         else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
445         {    *ppvObj = (IPersistFile *)This->lppf;
446         }   
447
448         if(*ppvObj)
449         { IShellLink_AddRef((IShellLink*)*ppvObj);      
450           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
451           return S_OK;
452         }
453         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
454         return E_NOINTERFACE;
455 }  
456 /******************************************************************************
457  * IShellLink_AddRef
458  */
459 static ULONG WINAPI IShellLink_fnAddRef(IShellLink * iface)
460 {
461         ICOM_THIS(IShellLinkImpl, iface);
462         
463         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
464
465         shell32_ObjCount++;
466         return ++(This->ref);
467 }
468 /******************************************************************************
469  *      IShellLink_Release
470  */
471 static ULONG WINAPI IShellLink_fnRelease(IShellLink * iface)
472 {
473         ICOM_THIS(IShellLinkImpl, iface);
474         
475         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
476
477         shell32_ObjCount--;
478         if (!--(This->ref)) 
479         { TRACE(shell,"-- destroying IShellLink(%p)\n",This);
480           IPersistFile_Release((IPersistFile*) This->lppf);     /* IPersistFile*/
481           HeapFree(GetProcessHeap(),0,This);
482           return 0;
483         }
484         return This->ref;
485 }
486
487 static HRESULT WINAPI IShellLink_fnGetPath(IShellLink * iface, LPSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
488 {
489         ICOM_THIS(IShellLinkImpl, iface);
490         
491         TRACE(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
492
493         strncpy(pszFile,This->lppf->sPath, cchMaxPath);
494         return NOERROR;
495 }
496 static HRESULT WINAPI IShellLink_fnGetIDList(IShellLink * iface, LPITEMIDLIST * ppidl)
497 {
498         ICOM_THIS(IShellLinkImpl, iface);
499         
500         TRACE(shell,"(%p)->(ppidl=%p)\n",This, ppidl);
501
502         *ppidl = ILClone(This->lppf->pPidl);
503         return NOERROR;
504 }
505 static HRESULT WINAPI IShellLink_fnSetIDList(IShellLink * iface, LPCITEMIDLIST pidl)
506 {
507         ICOM_THIS(IShellLinkImpl, iface);
508         
509         TRACE (shell,"(%p)->(pidl=%p)\n",This, pidl);
510
511         if (This->lppf->pPidl)
512             SHFree(This->lppf->pPidl);
513         This->lppf->pPidl = ILClone (pidl);
514         return NOERROR;
515 }
516 static HRESULT WINAPI IShellLink_fnGetDescription(IShellLink * iface, LPSTR pszName,INT cchMaxName)
517 {
518         ICOM_THIS(IShellLinkImpl, iface);
519         
520         FIXME(shell,"(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
521         strncpy(pszName,"Description, FIXME",cchMaxName);
522         return NOERROR;
523 }
524 static HRESULT WINAPI IShellLink_fnSetDescription(IShellLink * iface, LPCSTR pszName)
525 {
526         ICOM_THIS(IShellLinkImpl, iface);
527         
528         FIXME(shell,"(%p)->(desc=%s)\n",This, pszName);
529         return NOERROR;
530 }
531 static HRESULT WINAPI IShellLink_fnGetWorkingDirectory(IShellLink * iface, LPSTR pszDir,INT cchMaxPath)
532 {
533         ICOM_THIS(IShellLinkImpl, iface);
534         
535         FIXME(shell,"(%p)->()\n",This);
536         strncpy(pszDir,"c:\\", cchMaxPath);
537         return NOERROR;
538 }
539 static HRESULT WINAPI IShellLink_fnSetWorkingDirectory(IShellLink * iface, LPCSTR pszDir)
540 {
541         ICOM_THIS(IShellLinkImpl, iface);
542         
543         FIXME(shell,"(%p)->(dir=%s)\n",This, pszDir);
544         return NOERROR;
545 }
546 static HRESULT WINAPI IShellLink_fnGetArguments(IShellLink * iface, LPSTR pszArgs,INT cchMaxPath)
547 {
548         ICOM_THIS(IShellLinkImpl, iface);
549         
550         FIXME(shell,"(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
551         strncpy(pszArgs, "", cchMaxPath);
552         return NOERROR;
553 }
554 static HRESULT WINAPI IShellLink_fnSetArguments(IShellLink * iface, LPCSTR pszArgs)
555 {
556         ICOM_THIS(IShellLinkImpl, iface);
557         
558         FIXME(shell,"(%p)->(args=%s)\n",This, pszArgs);
559         return NOERROR;
560 }
561 static HRESULT WINAPI IShellLink_fnGetHotkey(IShellLink * iface, WORD *pwHotkey)
562 {
563         ICOM_THIS(IShellLinkImpl, iface);
564         
565         FIXME(shell,"(%p)->(%p)\n",This, pwHotkey);
566         *pwHotkey=0x0;
567         return NOERROR;
568 }
569 static HRESULT WINAPI IShellLink_fnSetHotkey(IShellLink * iface, WORD wHotkey)
570 {
571         ICOM_THIS(IShellLinkImpl, iface);
572         
573         FIXME(shell,"(%p)->(hotkey=%x)\n",This, wHotkey);
574         return NOERROR;
575 }
576 static HRESULT WINAPI IShellLink_fnGetShowCmd(IShellLink * iface, INT *piShowCmd)
577 {
578         ICOM_THIS(IShellLinkImpl, iface);
579         
580         FIXME(shell,"(%p)->(%p)\n",This, piShowCmd);
581         *piShowCmd=0;
582         return NOERROR;
583 }
584 static HRESULT WINAPI IShellLink_fnSetShowCmd(IShellLink * iface, INT iShowCmd)
585 {
586         ICOM_THIS(IShellLinkImpl, iface);
587         
588         FIXME(shell,"(%p)->(showcmd=%x)\n",This, iShowCmd);
589         return NOERROR;
590 }
591 static HRESULT WINAPI IShellLink_fnGetIconLocation(IShellLink * iface, LPSTR pszIconPath,INT cchIconPath,INT *piIcon)
592 {
593         ICOM_THIS(IShellLinkImpl, iface);
594         
595         FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
596         strncpy(pszIconPath,"shell32.dll",cchIconPath);
597         *piIcon=1;
598         return NOERROR;
599 }
600 static HRESULT WINAPI IShellLink_fnSetIconLocation(IShellLink * iface, LPCSTR pszIconPath,INT iIcon)
601 {
602         ICOM_THIS(IShellLinkImpl, iface);
603         
604         FIXME(shell,"(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
605         return NOERROR;
606 }
607 static HRESULT WINAPI IShellLink_fnSetRelativePath(IShellLink * iface, LPCSTR pszPathRel, DWORD dwReserved)
608 {
609         ICOM_THIS(IShellLinkImpl, iface);
610         
611         FIXME(shell,"(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
612         return NOERROR;
613 }
614 static HRESULT WINAPI IShellLink_fnResolve(IShellLink * iface, HWND hwnd, DWORD fFlags)
615 {
616         ICOM_THIS(IShellLinkImpl, iface);
617         
618         FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
619         return NOERROR;
620 }
621 static HRESULT WINAPI IShellLink_fnSetPath(IShellLink * iface, LPCSTR pszFile)
622 {
623         ICOM_THIS(IShellLinkImpl, iface);
624         
625         FIXME(shell,"(%p)->(path=%s)\n",This, pszFile);
626         return NOERROR;
627 }
628
629 /**************************************************************************
630 * IShellLink Implementation
631 */
632
633 static ICOM_VTABLE(IShellLink) slvt = 
634 {       IShellLink_fnQueryInterface,
635         IShellLink_fnAddRef,
636         IShellLink_fnRelease,
637         IShellLink_fnGetPath,
638         IShellLink_fnGetIDList,
639         IShellLink_fnSetIDList,
640         IShellLink_fnGetDescription,
641         IShellLink_fnSetDescription,
642         IShellLink_fnGetWorkingDirectory,
643         IShellLink_fnSetWorkingDirectory,
644         IShellLink_fnGetArguments,
645         IShellLink_fnSetArguments,
646         IShellLink_fnGetHotkey,
647         IShellLink_fnSetHotkey,
648         IShellLink_fnGetShowCmd,
649         IShellLink_fnSetShowCmd,
650         IShellLink_fnGetIconLocation,
651         IShellLink_fnSetIconLocation,
652         IShellLink_fnSetRelativePath,
653         IShellLink_fnResolve,
654         IShellLink_fnSetPath
655 };
656
657 /**************************************************************************
658 *  IShellLink's IClassFactory implementation
659 */
660
661 static ICOM_VTABLE(IClassFactory) slwcfvt;
662
663 /**************************************************************************
664  *  IShellLinkW_CF_Constructor
665  */
666
667 LPCLASSFACTORY IShellLinkW_CF_Constructor(void)
668 {
669         IClassFactoryImpl* lpclf;
670
671         lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
672         lpclf->ref = 1;
673         lpclf->lpvtbl = &slwcfvt;
674         TRACE(shell,"(%p)->()\n",lpclf);
675         shell32_ObjCount++;
676         return (LPCLASSFACTORY)lpclf;
677 }
678 /**************************************************************************
679  *  IShellLinkW_CF_QueryInterface
680  */
681 static HRESULT WINAPI IShellLinkW_CF_QueryInterface(
682   LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
683 {
684         ICOM_THIS(IClassFactoryImpl,iface);
685         char    xriid[50];
686         WINE_StringFromCLSID((LPCLSID)riid,xriid);
687         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
688
689         *ppvObj = NULL;
690
691         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
692         { *ppvObj = (LPUNKNOWN)This; 
693         }
694         else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
695         { *ppvObj = (LPCLASSFACTORY)This;
696         }   
697
698         if(*ppvObj) {
699           IUnknown_AddRef((IUnknown*)*ppvObj);          
700           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
701           return S_OK;
702         }
703         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
704         return E_NOINTERFACE;
705 }  
706 /******************************************************************************
707  * IShellLinkW_CF_AddRef
708  */
709 static ULONG WINAPI IShellLinkW_CF_AddRef(LPCLASSFACTORY iface)
710 {
711         ICOM_THIS(IClassFactoryImpl,iface);
712         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
713
714         shell32_ObjCount++;
715         return ++(This->ref);
716 }
717 /******************************************************************************
718  * IShellLinkW_CF_Release
719  */
720 static ULONG WINAPI IShellLinkW_CF_Release(LPCLASSFACTORY iface)
721 {
722         ICOM_THIS(IClassFactoryImpl,iface);
723         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
724
725         shell32_ObjCount--;
726         if (!--(This->ref)) 
727         { TRACE(shell,"-- destroying IClassFactory(%p)\n",This);
728                 HeapFree(GetProcessHeap(),0,This);
729                 return 0;
730         }
731         return This->ref;
732 }
733 /******************************************************************************
734  * IShellLinkW_CF_CreateInstance
735  */
736 static HRESULT WINAPI IShellLinkW_CF_CreateInstance(
737   LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
738 {
739         ICOM_THIS(IClassFactoryImpl,iface);
740         IUnknown *pObj = NULL;
741         HRESULT hres;
742         char    xriid[50];
743
744         WINE_StringFromCLSID((LPCLSID)riid,xriid);
745         TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
746
747         *ppObject = NULL;
748                 
749         if(pUnknown)
750         { return(CLASS_E_NOAGGREGATION);
751         }
752
753         if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLinkW))
754         { pObj = (IUnknown *)IShellLinkW_Constructor();
755         } 
756         else
757         { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
758           return(E_NOINTERFACE);
759         }
760         
761         if (!pObj)
762         { return(E_OUTOFMEMORY);
763         }
764          
765         hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject);
766         pObj->lpvtbl->fnRelease(pObj);
767         TRACE(shell,"-- Object created: (%p)->%p\n",This,*ppObject);
768
769         return hres;
770 }
771 /******************************************************************************
772  * IShellLinkW_CF_LockServer
773  */
774
775 static HRESULT WINAPI IShellLinkW_CF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
776 {
777         ICOM_THIS(IClassFactoryImpl,iface);
778         TRACE(shell,"%p->(0x%x), not implemented\n",This, fLock);
779         return E_NOTIMPL;
780 }
781
782 static ICOM_VTABLE(IClassFactory) slwcfvt = 
783 {
784     IShellLinkW_CF_QueryInterface,
785     IShellLinkW_CF_AddRef,
786   IShellLinkW_CF_Release,
787   IShellLinkW_CF_CreateInstance,
788   IShellLinkW_CF_LockServer
789 };
790
791
792 /**************************************************************************
793  * IShellLink Implementation 
794  */
795
796 typedef struct 
797 {
798         ICOM_VTABLE(IShellLinkW)*       lpvtbl;
799         DWORD                           ref;
800         IPersistFileImpl*               lppf;
801
802 } IShellLinkWImpl;
803
804 static ICOM_VTABLE(IShellLinkW) slvtw;
805
806 /**************************************************************************
807  *        IShellLinkW_fnConstructor
808  */
809 IShellLinkW * IShellLinkW_Constructor(void) 
810 {       IShellLinkWImpl* sl;
811
812         sl = (IShellLinkWImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLinkWImpl));
813         sl->ref = 1;
814         sl->lpvtbl = &slvtw;
815
816         sl->lppf = IPersistFile_Constructor();
817
818         TRACE(shell,"(%p)->()\n",sl);
819         shell32_ObjCount++;
820         return (IShellLinkW*)sl;
821 }
822
823 /**************************************************************************
824  *  IShellLinkW_fnQueryInterface
825  */
826 static HRESULT WINAPI IShellLinkW_fnQueryInterface(
827   IShellLinkW * iface, REFIID riid, LPVOID *ppvObj)
828 {
829         ICOM_THIS(IShellLinkWImpl, iface);
830         
831         char    xriid[50];
832         WINE_StringFromCLSID((LPCLSID)riid,xriid);
833         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
834
835         *ppvObj = NULL;
836
837         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
838         { *ppvObj = This; 
839         }
840         else if(IsEqualIID(riid, &IID_IShellLinkW))  /*IShellLinkW*/
841         {    *ppvObj = (IShellLinkW *)This;
842         }   
843         else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
844         {    *ppvObj = (IPersistFile *)This->lppf;
845         }   
846
847         if(*ppvObj)
848         { IShellLink_AddRef((IShellLinkW*)*ppvObj);      
849           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
850           return S_OK;
851         }
852
853         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
854
855         return E_NOINTERFACE;
856 }  
857 /******************************************************************************
858  * IShellLinkW_fnAddRef
859  */
860 static ULONG WINAPI IShellLinkW_fnAddRef(IShellLinkW * iface)
861 {
862         ICOM_THIS(IShellLinkWImpl, iface);
863         
864         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
865
866         shell32_ObjCount++;
867         return ++(This->ref);
868 }
869 /******************************************************************************
870  * IShellLinkW_fnRelease
871  */
872
873 static ULONG WINAPI IShellLinkW_fnRelease(IShellLinkW * iface)
874 {
875         ICOM_THIS(IShellLinkWImpl, iface);
876         
877         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
878
879         shell32_ObjCount--;
880         if (!--(This->ref)) 
881         { TRACE(shell,"-- destroying IShellLinkW(%p)\n",This);
882           IPersistFile_Release((IPersistFile*)This->lppf);      /* IPersistFile*/
883           HeapFree(GetProcessHeap(),0,This);
884           return 0;
885         }
886         return This->ref;
887 }
888
889 static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
890 {
891         ICOM_THIS(IShellLinkWImpl, iface);
892         
893         FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
894         lstrcpynAtoW(pszFile,"c:\\foo.bar", cchMaxPath);
895         return NOERROR;
896 }
897
898 static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST * ppidl)
899 {
900         ICOM_THIS(IShellLinkWImpl, iface);
901         
902         FIXME(shell,"(%p)->(ppidl=%p)\n",This, ppidl);
903         *ppidl = _ILCreateDesktop();
904         return NOERROR;
905 }
906
907 static HRESULT WINAPI IShellLinkW_fnSetIDList(IShellLinkW * iface, LPCITEMIDLIST pidl)
908 {
909         ICOM_THIS(IShellLinkWImpl, iface);
910         
911         FIXME(shell,"(%p)->(pidl=%p)\n",This, pidl);
912         return NOERROR;
913 }
914
915 static HRESULT WINAPI IShellLinkW_fnGetDescription(IShellLinkW * iface, LPWSTR pszName,INT cchMaxName)
916 {
917         ICOM_THIS(IShellLinkWImpl, iface);
918         
919         FIXME(shell,"(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
920         lstrcpynAtoW(pszName,"Description, FIXME",cchMaxName);
921         return NOERROR;
922 }
923
924 static HRESULT WINAPI IShellLinkW_fnSetDescription(IShellLinkW * iface, LPCWSTR pszName)
925 {
926         ICOM_THIS(IShellLinkWImpl, iface);
927         
928         FIXME(shell,"(%p)->(desc=%s)\n",This, debugstr_w(pszName));
929         return NOERROR;
930 }
931
932 static HRESULT WINAPI IShellLinkW_fnGetWorkingDirectory(IShellLinkW * iface, LPWSTR pszDir,INT cchMaxPath)
933 {
934         ICOM_THIS(IShellLinkWImpl, iface);
935         
936         FIXME(shell,"(%p)->()\n",This);
937         lstrcpynAtoW(pszDir,"c:\\", cchMaxPath);
938         return NOERROR;
939 }
940
941 static HRESULT WINAPI IShellLinkW_fnSetWorkingDirectory(IShellLinkW * iface, LPCWSTR pszDir)
942 {
943         ICOM_THIS(IShellLinkWImpl, iface);
944         
945         FIXME(shell,"(%p)->(dir=%s)\n",This, debugstr_w(pszDir));
946         return NOERROR;
947 }
948
949 static HRESULT WINAPI IShellLinkW_fnGetArguments(IShellLinkW * iface, LPWSTR pszArgs,INT cchMaxPath)
950 {
951         ICOM_THIS(IShellLinkWImpl, iface);
952         
953         FIXME(shell,"(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
954         lstrcpynAtoW(pszArgs, "", cchMaxPath);
955         return NOERROR;
956 }
957
958 static HRESULT WINAPI IShellLinkW_fnSetArguments(IShellLinkW * iface, LPCWSTR pszArgs)
959 {
960         ICOM_THIS(IShellLinkWImpl, iface);
961         
962         FIXME(shell,"(%p)->(args=%s)\n",This, debugstr_w(pszArgs));
963         return NOERROR;
964 }
965
966 static HRESULT WINAPI IShellLinkW_fnGetHotkey(IShellLinkW * iface, WORD *pwHotkey)
967 {
968         ICOM_THIS(IShellLinkWImpl, iface);
969         
970         FIXME(shell,"(%p)->(%p)\n",This, pwHotkey);
971         *pwHotkey=0x0;
972         return NOERROR;
973 }
974
975 static HRESULT WINAPI IShellLinkW_fnSetHotkey(IShellLinkW * iface, WORD wHotkey)
976 {
977         ICOM_THIS(IShellLinkWImpl, iface);
978         
979         FIXME(shell,"(%p)->(hotkey=%x)\n",This, wHotkey);
980         return NOERROR;
981 }
982
983 static HRESULT WINAPI IShellLinkW_fnGetShowCmd(IShellLinkW * iface, INT *piShowCmd)
984 {
985         ICOM_THIS(IShellLinkWImpl, iface);
986         
987         FIXME(shell,"(%p)->(%p)\n",This, piShowCmd);
988         *piShowCmd=0;
989         return NOERROR;
990 }
991
992 static HRESULT WINAPI IShellLinkW_fnSetShowCmd(IShellLinkW * iface, INT iShowCmd)
993 {
994         ICOM_THIS(IShellLinkWImpl, iface);
995         
996         FIXME(shell,"(%p)->(showcmd=%x)\n",This, iShowCmd);
997         return NOERROR;
998 }
999
1000 static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR pszIconPath,INT cchIconPath,INT *piIcon)
1001 {
1002         ICOM_THIS(IShellLinkWImpl, iface);
1003         
1004         FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
1005         lstrcpynAtoW(pszIconPath,"shell32.dll",cchIconPath);
1006         *piIcon=1;
1007         return NOERROR;
1008 }
1009
1010 static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
1011 {
1012         ICOM_THIS(IShellLinkWImpl, iface);
1013         
1014         FIXME(shell,"(%p)->(path=%s iicon=%u)\n",This, debugstr_w(pszIconPath), iIcon);
1015         return NOERROR;
1016 }
1017
1018 static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR pszPathRel, DWORD dwReserved)
1019 {
1020         ICOM_THIS(IShellLinkWImpl, iface);
1021         
1022         FIXME(shell,"(%p)->(path=%s %lx)\n",This, debugstr_w(pszPathRel), dwReserved);
1023         return NOERROR;
1024 }
1025
1026 static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags)
1027 {
1028         ICOM_THIS(IShellLinkWImpl, iface);
1029         
1030         FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
1031         return NOERROR;
1032 }
1033
1034 static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
1035 {
1036         ICOM_THIS(IShellLinkWImpl, iface);
1037         
1038         FIXME(shell,"(%p)->(path=%s)\n",This, debugstr_w(pszFile));
1039         return NOERROR;
1040 }
1041
1042 /**************************************************************************
1043 * IShellLinkW Implementation
1044 */
1045
1046 static ICOM_VTABLE(IShellLinkW) slvtw = 
1047 {       IShellLinkW_fnQueryInterface,
1048         IShellLinkW_fnAddRef,
1049         IShellLinkW_fnRelease,
1050         IShellLinkW_fnGetPath,
1051         IShellLinkW_fnGetIDList,
1052         IShellLinkW_fnSetIDList,
1053         IShellLinkW_fnGetDescription,
1054         IShellLinkW_fnSetDescription,
1055         IShellLinkW_fnGetWorkingDirectory,
1056         IShellLinkW_fnSetWorkingDirectory,
1057         IShellLinkW_fnGetArguments,
1058         IShellLinkW_fnSetArguments,
1059         IShellLinkW_fnGetHotkey,
1060         IShellLinkW_fnSetHotkey,
1061         IShellLinkW_fnGetShowCmd,
1062         IShellLinkW_fnSetShowCmd,
1063         IShellLinkW_fnGetIconLocation,
1064         IShellLinkW_fnSetIconLocation,
1065         IShellLinkW_fnSetRelativePath,
1066         IShellLinkW_fnResolve,
1067         IShellLinkW_fnSetPath
1068 };
1069