Compiler warnings fix.
[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 "debugtools.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 DEFAULT_DEBUG_CHANNEL(shell)
23
24 /* link file formats */
25
26 #include "pshpack1.h"
27
28 /* lnk elements: simple link has 0x0B */
29 #define WORKDIR         0x10
30 #define ARGUMENT        0x20
31 #define ICON            0x40
32
33 /* startup type */
34 #define NORMAL          0x01
35 #define MAXIMIZED       0x03
36 #define MINIMIZED       0x07
37
38 typedef struct _LINK_HEADER     
39 {       DWORD   MagicStr;       /* 0x00 'L','\0','\0','\0' */
40         GUID    MagicGuid;      /* 0x04 is CLSID_ShellLink */
41         DWORD   Flag1;          /* 0x14 describes elements following */
42         DWORD   Flag2;          /* 0x18 */
43         FILETIME Time1;         /* 0x1c */
44         FILETIME Time2;         /* 0x24 */
45         FILETIME Time3;         /* 0x2c */
46         DWORD   Unknown1;       /* 0x34 */
47         DWORD   Unknown2;       /* 0x38 icon number */
48         DWORD   Flag3;          /* 0x3c startup type */
49         DWORD   wHotKey;        /* 0x40 hotkey */
50         DWORD   Unknown5;       /* 0x44 */
51         DWORD   Unknown6;       /* 0x48 */
52         USHORT  PidlSize;       /* 0x4c */
53         ITEMIDLIST Pidl;        /* 0x4e */
54 } LINK_HEADER, * PLINK_HEADER;
55
56 #define LINK_HEADER_SIZE (sizeof(LINK_HEADER)-sizeof(ITEMIDLIST))
57
58 #include "poppack.h"
59
60 static ICOM_VTABLE(IShellLink)          slvt;
61 static ICOM_VTABLE(IShellLinkW)         slvtw;
62 static ICOM_VTABLE(IPersistFile)        pfvt;
63 static ICOM_VTABLE(IPersistStream)      psvt;
64
65 /* IShellLink Implementation */
66
67 typedef struct
68 {
69         ICOM_VTABLE(IShellLink)*        lpvtbl;
70         DWORD                           ref;
71
72         ICOM_VTABLE(IShellLinkW)*       lpvtblw;
73         ICOM_VTABLE(IPersistFile)*      lpvtblPersistFile;
74         ICOM_VTABLE(IPersistStream)*    lpvtblPersistStream;
75         
76         /* internal stream of the IPersistFile interface */
77         IStream*                        lpFileStream;
78         
79         /* data structures according to the informations in the lnk */
80         LPSTR           sPath;
81         LPITEMIDLIST    pPidl;
82         WORD            wHotKey;
83
84 } IShellLinkImpl;
85
86 #define _IShellLinkW_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblw)))
87 #define _ICOM_THIS_From_IShellLinkW(class, name) class* This = (class*)(((char*)name)-_IShellLinkW_Offset);
88
89 #define _IPersistFile_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistFile)))
90 #define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((char*)name)-_IPersistFile_Offset);
91
92 #define _IPersistStream_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistStream)))
93 #define _ICOM_THIS_From_IPersistStream(class, name) class* This = (class*)(((char*)name)-_IPersistStream_Offset);
94 #define _IPersistStream_From_ICOM_THIS(class, name) class* StreamThis = (class*)(((char*)name)+_IPersistStream_Offset);
95
96 /**************************************************************************
97  *  IPersistFile_QueryInterface
98  */
99 static HRESULT WINAPI IPersistFile_fnQueryInterface(
100         IPersistFile* iface,
101         REFIID riid,
102         LPVOID *ppvObj)
103 {
104         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
105
106         TRACE("(%p)\n",This);
107
108         return IShellLink_QueryInterface((IShellLink*)This, riid, ppvObj);
109 }
110
111 /******************************************************************************
112  * IPersistFile_AddRef
113  */
114 static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile* iface)
115 {
116         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
117
118         TRACE("(%p)->(count=%lu)\n",This,This->ref);
119
120         return IShellLink_AddRef((IShellLink*)This);
121 }
122 /******************************************************************************
123  * IPersistFile_Release
124  */
125 static ULONG WINAPI IPersistFile_fnRelease(IPersistFile* iface)
126 {
127         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
128
129         TRACE("(%p)->(count=%lu)\n",This,This->ref);
130
131         return IShellLink_Release((IShellLink*)This);
132 }
133
134 static HRESULT WINAPI IPersistFile_fnGetClassID(const IPersistFile* iface, CLSID *pClassID)
135 {
136         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
137         FIXME("(%p)\n",This);
138         return NOERROR;
139 }
140 static HRESULT WINAPI IPersistFile_fnIsDirty(const IPersistFile* iface)
141 {
142         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
143         FIXME("(%p)\n",This);
144         return NOERROR;
145 }
146 static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode)
147 {
148         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
149         _IPersistStream_From_ICOM_THIS(IPersistStream, This)
150
151         LPSTR           sFile = HEAP_strdupWtoA ( GetProcessHeap(), 0, pszFileName);
152         HRESULT         hRet = E_FAIL;
153
154         TRACE("(%p, %s)\n",This, sFile);
155         
156
157         if (This->lpFileStream)
158           IStream_Release(This->lpFileStream);
159         
160         if SUCCEEDED(CreateStreamOnFile(sFile, &(This->lpFileStream)))
161         {
162           if SUCCEEDED (IPersistStream_Load(StreamThis, This->lpFileStream))
163           {
164             return NOERROR;
165           }
166         }
167         
168         return hRet;
169 }
170
171 static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFileName, BOOL fRemember)
172 {
173         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
174         FIXME("(%p)->(%s)\n",This,debugstr_w(pszFileName));
175         return NOERROR;
176 }
177 static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLESTR pszFileName)
178 {
179         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
180         FIXME("(%p)->(%s)\n",This,debugstr_w(pszFileName));
181         return NOERROR;
182 }
183 static HRESULT WINAPI IPersistFile_fnGetCurFile(const IPersistFile* iface, LPOLESTR *ppszFileName)
184 {
185         _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
186         FIXME("(%p)\n",This);
187         return NOERROR;
188 }
189
190 static ICOM_VTABLE(IPersistFile) pfvt = 
191 {
192         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
193         IPersistFile_fnQueryInterface,
194         IPersistFile_fnAddRef,
195         IPersistFile_fnRelease,
196         IPersistFile_fnGetClassID,
197         IPersistFile_fnIsDirty,
198         IPersistFile_fnLoad,
199         IPersistFile_fnSave,
200         IPersistFile_fnSaveCompleted,
201         IPersistFile_fnGetCurFile
202 };
203
204 /************************************************************************
205  * IPersistStream_QueryInterface
206  */
207 static HRESULT WINAPI IPersistStream_fnQueryInterface(
208         IPersistStream* iface,
209         REFIID     riid,
210         VOID**     ppvoid)
211 {
212         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
213
214         TRACE("(%p)\n",This);
215
216         return IShellLink_QueryInterface((IShellLink*)This, riid, ppvoid);
217 }
218
219 /************************************************************************
220  * IPersistStream_Release
221  */
222 static ULONG WINAPI IPersistStream_fnRelease(
223         IPersistStream* iface)
224 {
225         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
226
227         TRACE("(%p)\n",This);
228
229         return IShellLink_Release((IShellLink*)This);
230 }
231
232 /************************************************************************
233  * IPersistStream_AddRef
234  */
235 static ULONG WINAPI IPersistStream_fnAddRef(
236         IPersistStream* iface)
237 {
238         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
239
240         TRACE("(%p)\n",This);
241
242         return IShellLink_AddRef((IShellLink*)This);
243
244
245 /************************************************************************
246  * IPersistStream_GetClassID
247  *
248  */
249 static HRESULT WINAPI IPersistStream_fnGetClassID(
250         const IPersistStream* iface,
251         CLSID* pClassID)
252 {
253         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
254
255         TRACE("(%p)\n", This);
256
257         if (pClassID==0)
258           return E_POINTER;
259
260 /*      memcpy(pClassID, &CLSID_???, sizeof(CLSID_???)); */
261
262         return S_OK;
263 }
264
265 /************************************************************************
266  * IPersistStream_IsDirty (IPersistStream)
267  */
268 static HRESULT WINAPI IPersistStream_fnIsDirty(
269         IPersistStream*  iface)
270 {
271         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
272
273         TRACE("(%p)\n", This);
274
275         return S_OK;
276 }
277 /************************************************************************
278  * IPersistStream_Load (IPersistStream)
279  */
280
281 static HRESULT WINAPI IPersistStream_fnLoad(
282         IPersistStream*  iface,
283         IStream*         pLoadStream)
284 {
285         PLINK_HEADER lpLinkHeader = HeapAlloc(GetProcessHeap(), 0, LINK_HEADER_SIZE);
286         ULONG   dwBytesRead;
287         DWORD   ret = E_FAIL;
288         char    sTemp[512];
289         
290         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
291
292         TRACE("(%p)(%p)\n", This, pLoadStream);
293
294         if ( ! pLoadStream)
295         {
296           return STG_E_INVALIDPOINTER;
297         }
298         
299         IStream_AddRef (pLoadStream);
300         if(lpLinkHeader)
301         {
302           if (SUCCEEDED(IStream_Read(pLoadStream, lpLinkHeader, LINK_HEADER_SIZE, &dwBytesRead)))
303           {
304             if ((lpLinkHeader->MagicStr == 0x0000004CL) && IsEqualIID(&lpLinkHeader->MagicGuid, &CLSID_ShellLink))
305             {
306               lpLinkHeader = HeapReAlloc(GetProcessHeap(), 0, lpLinkHeader, LINK_HEADER_SIZE+lpLinkHeader->PidlSize);
307               if (lpLinkHeader)
308               {
309                 if (SUCCEEDED(IStream_Read(pLoadStream, &(lpLinkHeader->Pidl), lpLinkHeader->PidlSize, &dwBytesRead)))
310                 {
311                   if (pcheck (&lpLinkHeader->Pidl))
312                   {     
313                     This->pPidl = ILClone (&lpLinkHeader->Pidl);
314
315                     _ILGetPidlPath(&lpLinkHeader->Pidl, sTemp, 512);
316                     This->sPath = HEAP_strdupA ( GetProcessHeap(), 0, sTemp);
317                     This->wHotKey = lpLinkHeader->wHotKey;
318                     ret = S_OK;
319                   }
320                 }
321               }
322             }
323             else
324             { WARN("stream contains no link!\n");
325             }
326           }
327         }
328
329         /* old code for debugging */
330         /*  SYSTEMTIME time;
331           FileTimeToSystemTime (&pImage->Time1, &time);
332           GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  sTemp, 256);
333           TRACE("-- time1: %s\n", sTemp);
334
335           pdump (&pImage->Pidl);
336         */
337
338         IStream_Release (pLoadStream);
339
340         pdump(This->pPidl);
341         
342         HeapFree(GetProcessHeap(), 0, lpLinkHeader);
343
344         return ret;
345 }
346
347 /************************************************************************
348  * IPersistStream_Save (IPersistStream)
349  */
350 static HRESULT WINAPI IPersistStream_fnSave(
351         IPersistStream*  iface,
352         IStream*         pOutStream,
353         BOOL             fClearDirty)
354 {
355         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
356         
357         TRACE("(%p) %p %x\n", This, pOutStream, fClearDirty);
358
359         return E_NOTIMPL;
360 }
361
362 /************************************************************************
363  * IPersistStream_GetSizeMax (IPersistStream)
364  */
365 static HRESULT WINAPI IPersistStream_fnGetSizeMax(
366         IPersistStream*  iface,
367         ULARGE_INTEGER*  pcbSize)
368 {
369         _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
370         
371         TRACE("(%p)\n", This);
372
373         return E_NOTIMPL;
374 }
375
376 static ICOM_VTABLE(IPersistStream) psvt =
377 {
378         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
379         IPersistStream_fnQueryInterface,
380         IPersistStream_fnAddRef,
381         IPersistStream_fnRelease,
382         IPersistStream_fnGetClassID,
383         IPersistStream_fnIsDirty,
384         IPersistStream_fnLoad,
385         IPersistStream_fnSave,
386         IPersistStream_fnGetSizeMax
387 };
388
389 /**************************************************************************
390  *        IShellLink_Constructor
391  */
392 IShellLink * IShellLink_Constructor(BOOL bUnicode) 
393 {       IShellLinkImpl * sl;
394
395         sl = (IShellLinkImpl *)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLinkImpl));
396         sl->ref = 1;
397         sl->lpvtbl = &slvt;
398         sl->lpvtblw = &slvtw;
399         sl->lpvtblPersistFile = &pfvt;
400         sl->lpvtblPersistStream = &psvt;
401         sl->sPath = NULL;
402         sl->pPidl = NULL;
403         sl->lpFileStream = NULL;
404         
405         TRACE("(%p)->()\n",sl);
406         shell32_ObjCount++;
407         return bUnicode ? (IShellLink *) &(sl->lpvtblw) : (IShellLink *)sl;
408 }
409
410 /**************************************************************************
411  *  IShellLink_QueryInterface
412  */
413 static HRESULT WINAPI IShellLink_fnQueryInterface( IShellLink * iface, REFIID riid,  LPVOID *ppvObj)
414 {
415         ICOM_THIS(IShellLinkImpl, iface);
416         
417         char    xriid[50];
418         WINE_StringFromCLSID((LPCLSID)riid,xriid);
419         TRACE("(%p)->(\n\tIID:\t%s)\n",This,xriid);
420
421         *ppvObj = NULL;
422
423         if(IsEqualIID(riid, &IID_IUnknown) ||
424            IsEqualIID(riid, &IID_IShellLink))
425         {
426           *ppvObj = This;
427         }   
428         else if(IsEqualIID(riid, &IID_IShellLinkW))
429         {
430           *ppvObj = (IShellLinkW *)&(This->lpvtblw);
431         }   
432         else if(IsEqualIID(riid, &IID_IPersistFile))
433         {
434           *ppvObj = (IPersistFile *)&(This->lpvtblPersistFile);
435         }
436         else if(IsEqualIID(riid, &IID_IPersistStream))
437         {
438           *ppvObj = (IPersistStream *)&(This->lpvtblPersistStream);
439         }   
440
441         if(*ppvObj)
442         {
443           IUnknown_AddRef((IUnknown*)(*ppvObj));
444           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
445           return S_OK;
446         }
447         TRACE("-- Interface: E_NOINTERFACE\n");
448         return E_NOINTERFACE;
449 }  
450 /******************************************************************************
451  * IShellLink_AddRef
452  */
453 static ULONG WINAPI IShellLink_fnAddRef(IShellLink * iface)
454 {
455         ICOM_THIS(IShellLinkImpl, iface);
456         
457         TRACE("(%p)->(count=%lu)\n",This,This->ref);
458
459         shell32_ObjCount++;
460         return ++(This->ref);
461 }
462 /******************************************************************************
463  *      IShellLink_Release
464  */
465 static ULONG WINAPI IShellLink_fnRelease(IShellLink * iface)
466 {
467         ICOM_THIS(IShellLinkImpl, iface);
468         
469         TRACE("(%p)->(count=%lu)\n",This,This->ref);
470
471         shell32_ObjCount--;
472         if (!--(This->ref)) 
473         { TRACE("-- destroying IShellLink(%p)\n",This);
474
475           if (This->sPath)
476             HeapFree(GetProcessHeap(),0,This->sPath);
477
478           if (This->pPidl)
479             SHFree(This->pPidl);
480
481           if (This->lpFileStream)
482             IStream_Release(This->lpFileStream);
483
484           HeapFree(GetProcessHeap(),0,This);
485           return 0;
486         }
487         return This->ref;
488 }
489
490 static HRESULT WINAPI IShellLink_fnGetPath(IShellLink * iface, LPSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
491 {
492         ICOM_THIS(IShellLinkImpl, iface);
493         
494         TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)(%s)\n",This, pszFile, cchMaxPath, pfd, fFlags, debugstr_a(This->sPath));
495
496         if (This->sPath)
497           strncpy(pszFile,This->sPath, cchMaxPath);
498         else
499           return E_FAIL;
500
501         return NOERROR;
502 }
503 static HRESULT WINAPI IShellLink_fnGetIDList(IShellLink * iface, LPITEMIDLIST * ppidl)
504 {
505         ICOM_THIS(IShellLinkImpl, iface);
506         
507         TRACE("(%p)->(ppidl=%p)\n",This, ppidl);
508
509         *ppidl = ILClone(This->pPidl);
510         return NOERROR;
511 }
512 static HRESULT WINAPI IShellLink_fnSetIDList(IShellLink * iface, LPCITEMIDLIST pidl)
513 {
514         ICOM_THIS(IShellLinkImpl, iface);
515         
516         TRACE("(%p)->(pidl=%p)\n",This, pidl);
517
518         if (This->pPidl)
519             SHFree(This->pPidl);
520         This->pPidl = ILClone (pidl);
521         return NOERROR;
522 }
523 static HRESULT WINAPI IShellLink_fnGetDescription(IShellLink * iface, LPSTR pszName,INT cchMaxName)
524 {
525         ICOM_THIS(IShellLinkImpl, iface);
526         
527         FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
528         strncpy(pszName,"Description, FIXME",cchMaxName);
529         return NOERROR;
530 }
531 static HRESULT WINAPI IShellLink_fnSetDescription(IShellLink * iface, LPCSTR pszName)
532 {
533         ICOM_THIS(IShellLinkImpl, iface);
534         
535         FIXME("(%p)->(desc=%s)\n",This, pszName);
536         return NOERROR;
537 }
538 static HRESULT WINAPI IShellLink_fnGetWorkingDirectory(IShellLink * iface, LPSTR pszDir,INT cchMaxPath)
539 {
540         ICOM_THIS(IShellLinkImpl, iface);
541         
542         FIXME("(%p)->()\n",This);
543         strncpy(pszDir,"c:\\", cchMaxPath);
544         return NOERROR;
545 }
546 static HRESULT WINAPI IShellLink_fnSetWorkingDirectory(IShellLink * iface, LPCSTR pszDir)
547 {
548         ICOM_THIS(IShellLinkImpl, iface);
549         
550         FIXME("(%p)->(dir=%s)\n",This, pszDir);
551         return NOERROR;
552 }
553 static HRESULT WINAPI IShellLink_fnGetArguments(IShellLink * iface, LPSTR pszArgs,INT cchMaxPath)
554 {
555         ICOM_THIS(IShellLinkImpl, iface);
556         
557         FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
558         strncpy(pszArgs, "", cchMaxPath);
559         return NOERROR;
560 }
561 static HRESULT WINAPI IShellLink_fnSetArguments(IShellLink * iface, LPCSTR pszArgs)
562 {
563         ICOM_THIS(IShellLinkImpl, iface);
564         
565         FIXME("(%p)->(args=%s)\n",This, pszArgs);
566
567         return NOERROR;
568 }
569 static HRESULT WINAPI IShellLink_fnGetHotkey(IShellLink * iface, WORD *pwHotkey)
570 {
571         ICOM_THIS(IShellLinkImpl, iface);
572         
573         TRACE("(%p)->(%p)(0x%08x)\n",This, pwHotkey, This->wHotKey);
574
575         *pwHotkey = This->wHotKey;
576
577         return NOERROR;
578 }
579 static HRESULT WINAPI IShellLink_fnSetHotkey(IShellLink * iface, WORD wHotkey)
580 {
581         ICOM_THIS(IShellLinkImpl, iface);
582         
583         TRACE("(%p)->(hotkey=%x)\n",This, wHotkey);
584         
585         This->wHotKey = wHotkey;
586
587         return NOERROR;
588 }
589 static HRESULT WINAPI IShellLink_fnGetShowCmd(IShellLink * iface, INT *piShowCmd)
590 {
591         ICOM_THIS(IShellLinkImpl, iface);
592         
593         FIXME("(%p)->(%p)\n",This, piShowCmd);
594         *piShowCmd=0;
595         return NOERROR;
596 }
597 static HRESULT WINAPI IShellLink_fnSetShowCmd(IShellLink * iface, INT iShowCmd)
598 {
599         ICOM_THIS(IShellLinkImpl, iface);
600         
601         FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
602         return NOERROR;
603 }
604 static HRESULT WINAPI IShellLink_fnGetIconLocation(IShellLink * iface, LPSTR pszIconPath,INT cchIconPath,INT *piIcon)
605 {
606         ICOM_THIS(IShellLinkImpl, iface);
607         
608         FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
609         strncpy(pszIconPath,"shell32.dll",cchIconPath);
610         *piIcon=1;
611         return NOERROR;
612 }
613 static HRESULT WINAPI IShellLink_fnSetIconLocation(IShellLink * iface, LPCSTR pszIconPath,INT iIcon)
614 {
615         ICOM_THIS(IShellLinkImpl, iface);
616         
617         FIXME("(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
618         return NOERROR;
619 }
620 static HRESULT WINAPI IShellLink_fnSetRelativePath(IShellLink * iface, LPCSTR pszPathRel, DWORD dwReserved)
621 {
622         ICOM_THIS(IShellLinkImpl, iface);
623         
624         FIXME("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
625         return NOERROR;
626 }
627 static HRESULT WINAPI IShellLink_fnResolve(IShellLink * iface, HWND hwnd, DWORD fFlags)
628 {
629         ICOM_THIS(IShellLinkImpl, iface);
630         
631         FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
632         return NOERROR;
633 }
634 static HRESULT WINAPI IShellLink_fnSetPath(IShellLink * iface, LPCSTR pszFile)
635 {
636         ICOM_THIS(IShellLinkImpl, iface);
637         
638         FIXME("(%p)->(path=%s)\n",This, pszFile);
639         return NOERROR;
640 }
641
642 /**************************************************************************
643 * IShellLink Implementation
644 */
645
646 static ICOM_VTABLE(IShellLink) slvt = 
647 {       
648         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
649         IShellLink_fnQueryInterface,
650         IShellLink_fnAddRef,
651         IShellLink_fnRelease,
652         IShellLink_fnGetPath,
653         IShellLink_fnGetIDList,
654         IShellLink_fnSetIDList,
655         IShellLink_fnGetDescription,
656         IShellLink_fnSetDescription,
657         IShellLink_fnGetWorkingDirectory,
658         IShellLink_fnSetWorkingDirectory,
659         IShellLink_fnGetArguments,
660         IShellLink_fnSetArguments,
661         IShellLink_fnGetHotkey,
662         IShellLink_fnSetHotkey,
663         IShellLink_fnGetShowCmd,
664         IShellLink_fnSetShowCmd,
665         IShellLink_fnGetIconLocation,
666         IShellLink_fnSetIconLocation,
667         IShellLink_fnSetRelativePath,
668         IShellLink_fnResolve,
669         IShellLink_fnSetPath
670 };
671
672
673 /**************************************************************************
674  *  IShellLinkW_fnQueryInterface
675  */
676 static HRESULT WINAPI IShellLinkW_fnQueryInterface(
677   IShellLinkW * iface, REFIID riid, LPVOID *ppvObj)
678 {
679         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
680         
681         return IShellLink_QueryInterface((IShellLink*)This, riid, ppvObj);
682 }
683
684 /******************************************************************************
685  * IShellLinkW_fnAddRef
686  */
687 static ULONG WINAPI IShellLinkW_fnAddRef(IShellLinkW * iface)
688 {
689         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
690         
691         TRACE("(%p)->(count=%lu)\n",This,This->ref);
692
693         return IShellLink_AddRef((IShellLink*)This);
694 }
695 /******************************************************************************
696  * IShellLinkW_fnRelease
697  */
698
699 static ULONG WINAPI IShellLinkW_fnRelease(IShellLinkW * iface)
700 {
701         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
702         
703         TRACE("(%p)->(count=%lu)\n",This,This->ref);
704
705         return IShellLink_Release((IShellLink*)This);
706 }
707
708 static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
709 {
710         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
711         
712         FIXME("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
713         lstrcpynAtoW(pszFile,"c:\\foo.bar", cchMaxPath);
714         return NOERROR;
715 }
716
717 static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST * ppidl)
718 {
719         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
720         
721         FIXME("(%p)->(ppidl=%p)\n",This, ppidl);
722         *ppidl = _ILCreateDesktop();
723         return NOERROR;
724 }
725
726 static HRESULT WINAPI IShellLinkW_fnSetIDList(IShellLinkW * iface, LPCITEMIDLIST pidl)
727 {
728         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
729         
730         FIXME("(%p)->(pidl=%p)\n",This, pidl);
731         return NOERROR;
732 }
733
734 static HRESULT WINAPI IShellLinkW_fnGetDescription(IShellLinkW * iface, LPWSTR pszName,INT cchMaxName)
735 {
736         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
737         
738         FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
739         lstrcpynAtoW(pszName,"Description, FIXME",cchMaxName);
740         return NOERROR;
741 }
742
743 static HRESULT WINAPI IShellLinkW_fnSetDescription(IShellLinkW * iface, LPCWSTR pszName)
744 {
745         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
746         
747         FIXME("(%p)->(desc=%s)\n",This, debugstr_w(pszName));
748         return NOERROR;
749 }
750
751 static HRESULT WINAPI IShellLinkW_fnGetWorkingDirectory(IShellLinkW * iface, LPWSTR pszDir,INT cchMaxPath)
752 {
753         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
754         
755         FIXME("(%p)->()\n",This);
756         lstrcpynAtoW(pszDir,"c:\\", cchMaxPath);
757         return NOERROR;
758 }
759
760 static HRESULT WINAPI IShellLinkW_fnSetWorkingDirectory(IShellLinkW * iface, LPCWSTR pszDir)
761 {
762         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
763         
764         FIXME("(%p)->(dir=%s)\n",This, debugstr_w(pszDir));
765         return NOERROR;
766 }
767
768 static HRESULT WINAPI IShellLinkW_fnGetArguments(IShellLinkW * iface, LPWSTR pszArgs,INT cchMaxPath)
769 {
770         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
771         
772         FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
773         lstrcpynAtoW(pszArgs, "", cchMaxPath);
774         return NOERROR;
775 }
776
777 static HRESULT WINAPI IShellLinkW_fnSetArguments(IShellLinkW * iface, LPCWSTR pszArgs)
778 {
779         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
780         
781         FIXME("(%p)->(args=%s)\n",This, debugstr_w(pszArgs));
782         return NOERROR;
783 }
784
785 static HRESULT WINAPI IShellLinkW_fnGetHotkey(IShellLinkW * iface, WORD *pwHotkey)
786 {
787         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
788         
789         FIXME("(%p)->(%p)\n",This, pwHotkey);
790         *pwHotkey=0x0;
791         return NOERROR;
792 }
793
794 static HRESULT WINAPI IShellLinkW_fnSetHotkey(IShellLinkW * iface, WORD wHotkey)
795 {
796         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
797         
798         FIXME("(%p)->(hotkey=%x)\n",This, wHotkey);
799         return NOERROR;
800 }
801
802 static HRESULT WINAPI IShellLinkW_fnGetShowCmd(IShellLinkW * iface, INT *piShowCmd)
803 {
804         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
805         
806         FIXME("(%p)->(%p)\n",This, piShowCmd);
807         *piShowCmd=0;
808         return NOERROR;
809 }
810
811 static HRESULT WINAPI IShellLinkW_fnSetShowCmd(IShellLinkW * iface, INT iShowCmd)
812 {
813         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
814         
815         FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
816         return NOERROR;
817 }
818
819 static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR pszIconPath,INT cchIconPath,INT *piIcon)
820 {
821         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
822         
823         FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
824         lstrcpynAtoW(pszIconPath,"shell32.dll",cchIconPath);
825         *piIcon=1;
826         return NOERROR;
827 }
828
829 static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
830 {
831         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
832         
833         FIXME("(%p)->(path=%s iicon=%u)\n",This, debugstr_w(pszIconPath), iIcon);
834         return NOERROR;
835 }
836
837 static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR pszPathRel, DWORD dwReserved)
838 {
839         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
840         
841         FIXME("(%p)->(path=%s %lx)\n",This, debugstr_w(pszPathRel), dwReserved);
842         return NOERROR;
843 }
844
845 static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags)
846 {
847         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
848         
849         FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
850         return NOERROR;
851 }
852
853 static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
854 {
855         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
856         
857         FIXME("(%p)->(path=%s)\n",This, debugstr_w(pszFile));
858         return NOERROR;
859 }
860
861 /**************************************************************************
862 * IShellLinkW Implementation
863 */
864
865 static ICOM_VTABLE(IShellLinkW) slvtw = 
866 {       
867         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
868         IShellLinkW_fnQueryInterface,
869         IShellLinkW_fnAddRef,
870         IShellLinkW_fnRelease,
871         IShellLinkW_fnGetPath,
872         IShellLinkW_fnGetIDList,
873         IShellLinkW_fnSetIDList,
874         IShellLinkW_fnGetDescription,
875         IShellLinkW_fnSetDescription,
876         IShellLinkW_fnGetWorkingDirectory,
877         IShellLinkW_fnSetWorkingDirectory,
878         IShellLinkW_fnGetArguments,
879         IShellLinkW_fnSetArguments,
880         IShellLinkW_fnGetHotkey,
881         IShellLinkW_fnSetHotkey,
882         IShellLinkW_fnGetShowCmd,
883         IShellLinkW_fnSetShowCmd,
884         IShellLinkW_fnGetIconLocation,
885         IShellLinkW_fnSetIconLocation,
886         IShellLinkW_fnSetRelativePath,
887         IShellLinkW_fnResolve,
888         IShellLinkW_fnSetPath
889 };
890