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