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