- Added some missing WINELIB_NAME_AW definitions, types and messages
[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(IShellLinkA)         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(IShellLinkA);
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 IShellLinkA_QueryInterface((IShellLinkA*)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 IShellLinkA_AddRef((IShellLinkA*)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 IShellLinkA_Release((IShellLinkA*)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 IShellLinkA_QueryInterface((IShellLinkA*)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 IShellLinkA_Release((IShellLinkA*)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 IShellLinkA_AddRef((IShellLinkA*)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 IShellLinkA * 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 ? (IShellLinkA *) &(sl->lpvtblw) : (IShellLinkA *)sl;
414 }
415
416 /**************************************************************************
417  *  IShellLinkA_QueryInterface
418  */
419 static HRESULT WINAPI IShellLinkA_fnQueryInterface( IShellLinkA * iface, REFIID riid,  LPVOID *ppvObj)
420 {
421         ICOM_THIS(IShellLinkImpl, iface);
422         
423         TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
424
425         *ppvObj = NULL;
426
427         if(IsEqualIID(riid, &IID_IUnknown) ||
428            IsEqualIID(riid, &IID_IShellLinkA))
429         {
430           *ppvObj = This;
431         }   
432         else if(IsEqualIID(riid, &IID_IShellLinkW))
433         {
434           *ppvObj = (IShellLinkW *)&(This->lpvtblw);
435         }   
436         else if(IsEqualIID(riid, &IID_IPersistFile))
437         {
438           *ppvObj = (IPersistFile *)&(This->lpvtblPersistFile);
439         }
440         else if(IsEqualIID(riid, &IID_IPersistStream))
441         {
442           *ppvObj = (IPersistStream *)&(This->lpvtblPersistStream);
443         }   
444
445         if(*ppvObj)
446         {
447           IUnknown_AddRef((IUnknown*)(*ppvObj));
448           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
449           return S_OK;
450         }
451         TRACE("-- Interface: E_NOINTERFACE\n");
452         return E_NOINTERFACE;
453 }  
454 /******************************************************************************
455  * IShellLinkA_AddRef
456  */
457 static ULONG WINAPI IShellLinkA_fnAddRef(IShellLinkA * iface)
458 {
459         ICOM_THIS(IShellLinkImpl, iface);
460         
461         TRACE("(%p)->(count=%lu)\n",This,This->ref);
462
463         shell32_ObjCount++;
464         return ++(This->ref);
465 }
466 /******************************************************************************
467  *      IShellLinkA_Release
468  */
469 static ULONG WINAPI IShellLinkA_fnRelease(IShellLinkA * iface)
470 {
471         ICOM_THIS(IShellLinkImpl, iface);
472         
473         TRACE("(%p)->(count=%lu)\n",This,This->ref);
474
475         shell32_ObjCount--;
476         if (!--(This->ref)) 
477         { TRACE("-- destroying IShellLink(%p)\n",This);
478
479           if (This->sPath)
480             HeapFree(GetProcessHeap(),0,This->sPath);
481
482           if (This->pPidl)
483             SHFree(This->pPidl);
484
485           if (This->lpFileStream)
486             IStream_Release(This->lpFileStream);
487
488           HeapFree(GetProcessHeap(),0,This);
489           return 0;
490         }
491         return This->ref;
492 }
493
494 static HRESULT WINAPI IShellLinkA_fnGetPath(IShellLinkA * iface, LPSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
495 {
496         ICOM_THIS(IShellLinkImpl, iface);
497         
498         TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)(%s)\n",This, pszFile, cchMaxPath, pfd, fFlags, debugstr_a(This->sPath));
499
500         if (This->sPath)
501           lstrcpynA(pszFile,This->sPath, cchMaxPath);
502         else
503           return E_FAIL;
504
505         return NOERROR;
506 }
507 static HRESULT WINAPI IShellLinkA_fnGetIDList(IShellLinkA * iface, LPITEMIDLIST * ppidl)
508 {
509         ICOM_THIS(IShellLinkImpl, iface);
510         
511         TRACE("(%p)->(ppidl=%p)\n",This, ppidl);
512
513         *ppidl = ILClone(This->pPidl);
514         return NOERROR;
515 }
516 static HRESULT WINAPI IShellLinkA_fnSetIDList(IShellLinkA * iface, LPCITEMIDLIST pidl)
517 {
518         ICOM_THIS(IShellLinkImpl, iface);
519         
520         TRACE("(%p)->(pidl=%p)\n",This, pidl);
521
522         if (This->pPidl)
523             SHFree(This->pPidl);
524         This->pPidl = ILClone (pidl);
525         return NOERROR;
526 }
527 static HRESULT WINAPI IShellLinkA_fnGetDescription(IShellLinkA * iface, LPSTR pszName,INT cchMaxName)
528 {
529         ICOM_THIS(IShellLinkImpl, iface);
530         
531         FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
532         lstrcpynA(pszName,"Description, FIXME",cchMaxName);
533         return NOERROR;
534 }
535 static HRESULT WINAPI IShellLinkA_fnSetDescription(IShellLinkA * iface, LPCSTR pszName)
536 {
537         ICOM_THIS(IShellLinkImpl, iface);
538         
539         FIXME("(%p)->(desc=%s)\n",This, pszName);
540         return NOERROR;
541 }
542 static HRESULT WINAPI IShellLinkA_fnGetWorkingDirectory(IShellLinkA * iface, LPSTR pszDir,INT cchMaxPath)
543 {
544         ICOM_THIS(IShellLinkImpl, iface);
545         
546         FIXME("(%p)->()\n",This);
547         lstrcpynA(pszDir,"c:\\", cchMaxPath);
548         return NOERROR;
549 }
550 static HRESULT WINAPI IShellLinkA_fnSetWorkingDirectory(IShellLinkA * iface, LPCSTR pszDir)
551 {
552         ICOM_THIS(IShellLinkImpl, iface);
553         
554         FIXME("(%p)->(dir=%s)\n",This, pszDir);
555         return NOERROR;
556 }
557 static HRESULT WINAPI IShellLinkA_fnGetArguments(IShellLinkA * iface, LPSTR pszArgs,INT cchMaxPath)
558 {
559         ICOM_THIS(IShellLinkImpl, iface);
560         
561         FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
562         lstrcpynA(pszArgs, "", cchMaxPath);
563         return NOERROR;
564 }
565 static HRESULT WINAPI IShellLinkA_fnSetArguments(IShellLinkA * iface, LPCSTR pszArgs)
566 {
567         ICOM_THIS(IShellLinkImpl, iface);
568         
569         FIXME("(%p)->(args=%s)\n",This, pszArgs);
570
571         return NOERROR;
572 }
573 static HRESULT WINAPI IShellLinkA_fnGetHotkey(IShellLinkA * iface, WORD *pwHotkey)
574 {
575         ICOM_THIS(IShellLinkImpl, iface);
576         
577         TRACE("(%p)->(%p)(0x%08x)\n",This, pwHotkey, This->wHotKey);
578
579         *pwHotkey = This->wHotKey;
580
581         return NOERROR;
582 }
583 static HRESULT WINAPI IShellLinkA_fnSetHotkey(IShellLinkA * iface, WORD wHotkey)
584 {
585         ICOM_THIS(IShellLinkImpl, iface);
586         
587         TRACE("(%p)->(hotkey=%x)\n",This, wHotkey);
588         
589         This->wHotKey = wHotkey;
590
591         return NOERROR;
592 }
593 static HRESULT WINAPI IShellLinkA_fnGetShowCmd(IShellLinkA * iface, INT *piShowCmd)
594 {
595         ICOM_THIS(IShellLinkImpl, iface);
596         
597         FIXME("(%p)->(%p)\n",This, piShowCmd);
598         *piShowCmd=0;
599         return NOERROR;
600 }
601 static HRESULT WINAPI IShellLinkA_fnSetShowCmd(IShellLinkA * iface, INT iShowCmd)
602 {
603         ICOM_THIS(IShellLinkImpl, iface);
604         
605         FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
606         return NOERROR;
607 }
608 static HRESULT WINAPI IShellLinkA_fnGetIconLocation(IShellLinkA * iface, LPSTR pszIconPath,INT cchIconPath,INT *piIcon)
609 {
610         ICOM_THIS(IShellLinkImpl, iface);
611         
612         FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
613         lstrcpynA(pszIconPath,"shell32.dll",cchIconPath);
614         *piIcon=1;
615         return NOERROR;
616 }
617 static HRESULT WINAPI IShellLinkA_fnSetIconLocation(IShellLinkA * iface, LPCSTR pszIconPath,INT iIcon)
618 {
619         ICOM_THIS(IShellLinkImpl, iface);
620         
621         FIXME("(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
622         return NOERROR;
623 }
624 static HRESULT WINAPI IShellLinkA_fnSetRelativePath(IShellLinkA * iface, LPCSTR pszPathRel, DWORD dwReserved)
625 {
626         ICOM_THIS(IShellLinkImpl, iface);
627         
628         FIXME("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
629         return NOERROR;
630 }
631 static HRESULT WINAPI IShellLinkA_fnResolve(IShellLinkA * iface, HWND hwnd, DWORD fFlags)
632 {
633         ICOM_THIS(IShellLinkImpl, iface);
634         
635         FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
636         return NOERROR;
637 }
638 static HRESULT WINAPI IShellLinkA_fnSetPath(IShellLinkA * iface, LPCSTR pszFile)
639 {
640         ICOM_THIS(IShellLinkImpl, iface);
641         
642         FIXME("(%p)->(path=%s)\n",This, pszFile);
643         return NOERROR;
644 }
645
646 /**************************************************************************
647 * IShellLink Implementation
648 */
649
650 static ICOM_VTABLE(IShellLinkA) slvt = 
651 {       
652         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
653         IShellLinkA_fnQueryInterface,
654         IShellLinkA_fnAddRef,
655         IShellLinkA_fnRelease,
656         IShellLinkA_fnGetPath,
657         IShellLinkA_fnGetIDList,
658         IShellLinkA_fnSetIDList,
659         IShellLinkA_fnGetDescription,
660         IShellLinkA_fnSetDescription,
661         IShellLinkA_fnGetWorkingDirectory,
662         IShellLinkA_fnSetWorkingDirectory,
663         IShellLinkA_fnGetArguments,
664         IShellLinkA_fnSetArguments,
665         IShellLinkA_fnGetHotkey,
666         IShellLinkA_fnSetHotkey,
667         IShellLinkA_fnGetShowCmd,
668         IShellLinkA_fnSetShowCmd,
669         IShellLinkA_fnGetIconLocation,
670         IShellLinkA_fnSetIconLocation,
671         IShellLinkA_fnSetRelativePath,
672         IShellLinkA_fnResolve,
673         IShellLinkA_fnSetPath
674 };
675
676
677 /**************************************************************************
678  *  IShellLinkW_fnQueryInterface
679  */
680 static HRESULT WINAPI IShellLinkW_fnQueryInterface(
681   IShellLinkW * iface, REFIID riid, LPVOID *ppvObj)
682 {
683         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
684         
685         return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObj);
686 }
687
688 /******************************************************************************
689  * IShellLinkW_fnAddRef
690  */
691 static ULONG WINAPI IShellLinkW_fnAddRef(IShellLinkW * iface)
692 {
693         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
694         
695         TRACE("(%p)->(count=%lu)\n",This,This->ref);
696
697         return IShellLinkA_AddRef((IShellLinkA*)This);
698 }
699 /******************************************************************************
700  * IShellLinkW_fnRelease
701  */
702
703 static ULONG WINAPI IShellLinkW_fnRelease(IShellLinkW * iface)
704 {
705         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
706         
707         TRACE("(%p)->(count=%lu)\n",This,This->ref);
708
709         return IShellLinkA_Release((IShellLinkA*)This);
710 }
711
712 static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
713 {
714         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
715         
716         FIXME("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
717         lstrcpynAtoW(pszFile,"c:\\foo.bar", cchMaxPath);
718         return NOERROR;
719 }
720
721 static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST * ppidl)
722 {
723         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
724         
725         FIXME("(%p)->(ppidl=%p)\n",This, ppidl);
726         *ppidl = _ILCreateDesktop();
727         return NOERROR;
728 }
729
730 static HRESULT WINAPI IShellLinkW_fnSetIDList(IShellLinkW * iface, LPCITEMIDLIST pidl)
731 {
732         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
733         
734         FIXME("(%p)->(pidl=%p)\n",This, pidl);
735         return NOERROR;
736 }
737
738 static HRESULT WINAPI IShellLinkW_fnGetDescription(IShellLinkW * iface, LPWSTR pszName,INT cchMaxName)
739 {
740         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
741         
742         FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
743         lstrcpynAtoW(pszName,"Description, FIXME",cchMaxName);
744         return NOERROR;
745 }
746
747 static HRESULT WINAPI IShellLinkW_fnSetDescription(IShellLinkW * iface, LPCWSTR pszName)
748 {
749         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
750         
751         FIXME("(%p)->(desc=%s)\n",This, debugstr_w(pszName));
752         return NOERROR;
753 }
754
755 static HRESULT WINAPI IShellLinkW_fnGetWorkingDirectory(IShellLinkW * iface, LPWSTR pszDir,INT cchMaxPath)
756 {
757         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
758         
759         FIXME("(%p)->()\n",This);
760         lstrcpynAtoW(pszDir,"c:\\", cchMaxPath);
761         return NOERROR;
762 }
763
764 static HRESULT WINAPI IShellLinkW_fnSetWorkingDirectory(IShellLinkW * iface, LPCWSTR pszDir)
765 {
766         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
767         
768         FIXME("(%p)->(dir=%s)\n",This, debugstr_w(pszDir));
769         return NOERROR;
770 }
771
772 static HRESULT WINAPI IShellLinkW_fnGetArguments(IShellLinkW * iface, LPWSTR pszArgs,INT cchMaxPath)
773 {
774         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
775         
776         FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
777         lstrcpynAtoW(pszArgs, "", cchMaxPath);
778         return NOERROR;
779 }
780
781 static HRESULT WINAPI IShellLinkW_fnSetArguments(IShellLinkW * iface, LPCWSTR pszArgs)
782 {
783         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
784         
785         FIXME("(%p)->(args=%s)\n",This, debugstr_w(pszArgs));
786         return NOERROR;
787 }
788
789 static HRESULT WINAPI IShellLinkW_fnGetHotkey(IShellLinkW * iface, WORD *pwHotkey)
790 {
791         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
792         
793         FIXME("(%p)->(%p)\n",This, pwHotkey);
794         *pwHotkey=0x0;
795         return NOERROR;
796 }
797
798 static HRESULT WINAPI IShellLinkW_fnSetHotkey(IShellLinkW * iface, WORD wHotkey)
799 {
800         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
801         
802         FIXME("(%p)->(hotkey=%x)\n",This, wHotkey);
803         return NOERROR;
804 }
805
806 static HRESULT WINAPI IShellLinkW_fnGetShowCmd(IShellLinkW * iface, INT *piShowCmd)
807 {
808         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
809         
810         FIXME("(%p)->(%p)\n",This, piShowCmd);
811         *piShowCmd=0;
812         return NOERROR;
813 }
814
815 static HRESULT WINAPI IShellLinkW_fnSetShowCmd(IShellLinkW * iface, INT iShowCmd)
816 {
817         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
818         
819         FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
820         return NOERROR;
821 }
822
823 static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR pszIconPath,INT cchIconPath,INT *piIcon)
824 {
825         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
826         
827         FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
828         lstrcpynAtoW(pszIconPath,"shell32.dll",cchIconPath);
829         *piIcon=1;
830         return NOERROR;
831 }
832
833 static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
834 {
835         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
836         
837         FIXME("(%p)->(path=%s iicon=%u)\n",This, debugstr_w(pszIconPath), iIcon);
838         return NOERROR;
839 }
840
841 static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR pszPathRel, DWORD dwReserved)
842 {
843         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
844         
845         FIXME("(%p)->(path=%s %lx)\n",This, debugstr_w(pszPathRel), dwReserved);
846         return NOERROR;
847 }
848
849 static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags)
850 {
851         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
852         
853         FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
854         return NOERROR;
855 }
856
857 static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
858 {
859         _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
860         
861         FIXME("(%p)->(path=%s)\n",This, debugstr_w(pszFile));
862         return NOERROR;
863 }
864
865 /**************************************************************************
866 * IShellLinkW Implementation
867 */
868
869 static ICOM_VTABLE(IShellLinkW) slvtw = 
870 {       
871         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
872         IShellLinkW_fnQueryInterface,
873         IShellLinkW_fnAddRef,
874         IShellLinkW_fnRelease,
875         IShellLinkW_fnGetPath,
876         IShellLinkW_fnGetIDList,
877         IShellLinkW_fnSetIDList,
878         IShellLinkW_fnGetDescription,
879         IShellLinkW_fnSetDescription,
880         IShellLinkW_fnGetWorkingDirectory,
881         IShellLinkW_fnSetWorkingDirectory,
882         IShellLinkW_fnGetArguments,
883         IShellLinkW_fnSetArguments,
884         IShellLinkW_fnGetHotkey,
885         IShellLinkW_fnSetHotkey,
886         IShellLinkW_fnGetShowCmd,
887         IShellLinkW_fnSetShowCmd,
888         IShellLinkW_fnGetIconLocation,
889         IShellLinkW_fnSetIconLocation,
890         IShellLinkW_fnSetRelativePath,
891         IShellLinkW_fnResolve,
892         IShellLinkW_fnSetPath
893 };
894