- New implementation of SendMessage, ReceiveMessage, ReplyMessage functions
[wine] / dlls / shell32 / shelllink.c
1 /*
2  *
3  *      Copyright 1997  Marcus Meissner
4  *      Copyright 1998  Juergen Schmied
5  *
6  */
7
8 #include <string.h>
9 #include "debug.h"
10 #include "winerror.h"
11
12 #include "objbase.h"
13 #include "wine/obj_base.h"
14 #include "wine/obj_storage.h"
15
16 #include "pidl.h"
17 #include "shell32_main.h"
18 #include "shlguid.h"
19
20 /* IPersistFile Implementation */
21 typedef struct
22 {
23     /* IUnknown fields */
24     ICOM_VTABLE(IPersistFile)* lpvtbl;
25     DWORD                       ref;
26 } IPersistFileImpl;
27
28 static struct ICOM_VTABLE(IPersistFile) pfvt;
29
30
31 /**************************************************************************
32  *        IPersistFile_Constructor
33  */
34 LPPERSISTFILE IPersistFile_Constructor(void) 
35 {
36         IPersistFileImpl* sl;
37
38         sl = (IPersistFileImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IPersistFileImpl));
39         sl->ref = 1;
40         sl->lpvtbl = &pfvt;
41
42         TRACE(shell,"(%p)->()\n",sl);
43         shell32_ObjCount++;
44         return (LPPERSISTFILE)sl;
45 }
46
47 /**************************************************************************
48  *  IPersistFile_QueryInterface
49  */
50 static HRESULT WINAPI IPersistFile_fnQueryInterface(
51   IPersistFile* iface, REFIID riid, LPVOID *ppvObj)
52 {
53         ICOM_THIS(IPersistFileImpl,iface);
54         char    xriid[50];
55         WINE_StringFromCLSID((LPCLSID)riid,xriid);
56         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
57
58         *ppvObj = NULL;
59
60         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
61         { *ppvObj = This; 
62         }
63         else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
64         {    *ppvObj = (LPPERSISTFILE)This;
65         }   
66
67         if(*ppvObj)
68         { IPersistFile_AddRef((IPersistFile*)*ppvObj);      
69           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
70           return S_OK;
71         }
72         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
73         return E_NOINTERFACE;
74 }  
75 /******************************************************************************
76  * IPersistFile_AddRef
77  */
78 static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile* iface)
79 {
80         ICOM_THIS(IPersistFileImpl,iface);
81         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
82
83         shell32_ObjCount++;
84         return ++(This->ref);
85 }
86 /******************************************************************************
87  * IPersistFile_Release
88  */
89 static ULONG WINAPI IPersistFile_fnRelease(IPersistFile* iface)
90 {
91         ICOM_THIS(IPersistFileImpl,iface);
92         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
93
94         shell32_ObjCount--;
95
96         if (!--(This->ref)) 
97         { TRACE(shell,"-- destroying IPersistFile(%p)\n",This);
98           HeapFree(GetProcessHeap(),0,This);
99           return 0;
100         }
101         return This->ref;
102 }
103
104 static HRESULT WINAPI IPersistFile_fnGetClassID(const IPersistFile* iface, CLSID *pClassID)
105 {
106         ICOM_CTHIS(IPersistFile,iface);
107         FIXME(shell,"(%p)\n",This);
108         return NOERROR;
109 }
110 static HRESULT WINAPI IPersistFile_fnIsDirty(const IPersistFile* iface)
111 {
112         ICOM_CTHIS(IPersistFile,iface);
113         FIXME(shell,"(%p)\n",This);
114         return NOERROR;
115 }
116 static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR32 pszFileName, DWORD dwMode)
117 {
118         ICOM_THIS(IPersistFileImpl,iface);
119         FIXME(shell,"(%p)->(%s)\n",This,debugstr_w(pszFileName)); 
120         return E_FAIL;
121 }
122 static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR32 pszFileName, BOOL32 fRemember)
123 {
124         ICOM_THIS(IPersistFileImpl,iface);
125         FIXME(shell,"(%p)->(%s)\n",This,debugstr_w(pszFileName));
126         return NOERROR;
127 }
128 static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLESTR32 pszFileName)
129 {
130         ICOM_THIS(IPersistFileImpl,iface);
131         FIXME(shell,"(%p)->(%s)\n",This,debugstr_w(pszFileName));
132         return NOERROR;
133 }
134 static HRESULT WINAPI IPersistFile_fnGetCurFile(const IPersistFile* iface, LPOLESTR32 *ppszFileName)
135 {
136         ICOM_CTHIS(IPersistFileImpl,iface);
137         FIXME(shell,"(%p)\n",This);
138         return NOERROR;
139 }
140   
141 static struct ICOM_VTABLE(IPersistFile) pfvt = 
142 {
143     IPersistFile_fnQueryInterface,
144     IPersistFile_fnAddRef,
145     IPersistFile_fnRelease,
146     IPersistFile_fnGetClassID,
147     IPersistFile_fnIsDirty,
148     IPersistFile_fnLoad,
149     IPersistFile_fnSave,
150     IPersistFile_fnSaveCompleted,
151     IPersistFile_fnGetCurFile
152 };
153
154
155 /**************************************************************************
156 *  IShellLink's IClassFactory implementation
157  */
158 typedef struct
159 {
160     /* IUnknown fields */
161     ICOM_VTABLE(IClassFactory)* lpvtbl;
162     DWORD                       ref;
163 } IClassFactoryImpl;
164
165 static ICOM_VTABLE(IClassFactory) slcfvt;
166
167 /**************************************************************************
168  *  IShellLink_CF_Constructor
169  */
170
171 LPCLASSFACTORY IShellLink_CF_Constructor(void)
172 {
173         IClassFactoryImpl* lpclf;
174
175         lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
176         lpclf->ref = 1;
177         lpclf->lpvtbl = &slcfvt;
178         TRACE(shell,"(%p)->()\n",lpclf);
179         shell32_ObjCount++;
180         return (LPCLASSFACTORY)lpclf;
181 }
182 /**************************************************************************
183  *  IShellLink_CF_QueryInterface
184  */
185 static HRESULT WINAPI IShellLink_CF_QueryInterface(
186   IClassFactory* iface, REFIID riid, LPVOID *ppvObj)
187 {
188         ICOM_THIS(IClassFactoryImpl,iface);
189         char    xriid[50];
190         WINE_StringFromCLSID((LPCLSID)riid,xriid);
191         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
192
193         *ppvObj = NULL;
194
195         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
196         { *ppvObj = (LPUNKNOWN)This; 
197         }
198         else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
199         { *ppvObj = (LPCLASSFACTORY)This;
200         }   
201
202         if(*ppvObj)
203         { IUnknown_AddRef((IUnknown*)*ppvObj);          
204           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
205           return S_OK;
206         }
207         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
208         return E_NOINTERFACE;
209 }  
210 /******************************************************************************
211  * IShellLink_CF_AddRef
212  */
213 static ULONG WINAPI IShellLink_CF_AddRef(IClassFactory* iface)
214 {
215         ICOM_THIS(IClassFactoryImpl,iface);
216         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
217
218         shell32_ObjCount++;
219         return ++(This->ref);
220 }
221 /******************************************************************************
222  * IShellLink_CF_Release
223  */
224 static ULONG WINAPI IShellLink_CF_Release(IClassFactory* iface)
225 {
226         ICOM_THIS(IClassFactoryImpl,iface);
227         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
228
229         shell32_ObjCount--;
230         if (!--(This->ref)) 
231         { TRACE(shell,"-- destroying IClassFactory(%p)\n",This);
232                 HeapFree(GetProcessHeap(),0,This);
233                 return 0;
234         }
235         return This->ref;
236 }
237 /******************************************************************************
238  * IShellLink_CF_CreateInstance
239  */
240 static HRESULT WINAPI IShellLink_CF_CreateInstance(
241   IClassFactory* iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
242 {
243         ICOM_THIS(IClassFactoryImpl,iface);
244         IUnknown *pObj = NULL;
245         HRESULT hres;
246         char    xriid[50];
247
248         WINE_StringFromCLSID((LPCLSID)riid,xriid);
249         TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
250
251         *ppObject = NULL;
252                 
253         if(pUnknown)
254         {       return(CLASS_E_NOAGGREGATION);
255         }
256
257         if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLink))
258         { pObj = (IUnknown *)IShellLink_Constructor();
259         } 
260         else
261         { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
262           return(E_NOINTERFACE);
263         }
264         
265         if (!pObj)
266         { return(E_OUTOFMEMORY);
267         }
268          
269         hres = IUnknown_QueryInterface(pObj,riid, ppObject);
270         IUnknown_Release(pObj);
271         TRACE(shell,"-- Object created: (%p)->%p\n",This,*ppObject);
272
273         return hres;
274 }
275 /******************************************************************************
276  * IShellLink_CF_LockServer
277  */
278 static HRESULT WINAPI IShellLink_CF_LockServer(IClassFactory* iface, BOOL32 fLock)
279 {
280         ICOM_THIS(IClassFactoryImpl,iface);
281         TRACE(shell,"%p->(0x%x), not implemented\n",This, fLock);
282         return E_NOTIMPL;
283 }
284 static ICOM_VTABLE(IClassFactory) slcfvt = 
285 {
286     IShellLink_CF_QueryInterface,
287     IShellLink_CF_AddRef,
288   IShellLink_CF_Release,
289   IShellLink_CF_CreateInstance,
290   IShellLink_CF_LockServer
291 };
292
293 /* IShellLink Implementation */
294 static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
295 static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
296 static ULONG WINAPI IShellLink_Release(LPSHELLLINK);
297 static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK, LPSTR,INT32, WIN32_FIND_DATA32A *, DWORD);
298 static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK, LPITEMIDLIST *);
299 static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK, LPCITEMIDLIST);
300 static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK, LPSTR,INT32);
301 static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK, LPCSTR);
302 static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK, LPSTR,INT32);
303 static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK, LPCSTR);
304 static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK, LPSTR,INT32);
305 static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK, LPCSTR);
306 static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK, WORD *);
307 static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK, WORD);
308 static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK, INT32 *);
309 static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK, INT32);
310 static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK, LPSTR,INT32,INT32 *);
311 static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK, LPCSTR,INT32);
312 static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK, LPCSTR, DWORD);
313 static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK, HWND32, DWORD);
314 static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK, LPCSTR);
315
316 /**************************************************************************
317 * IShellLink Implementation
318 */
319
320
321 static struct IShellLink_VTable slvt = 
322 {       IShellLink_QueryInterface,
323         IShellLink_AddRef,
324         IShellLink_Release,
325         IShellLink_GetPath,
326         IShellLink_GetIDList,
327         IShellLink_SetIDList,
328         IShellLink_GetDescription,
329         IShellLink_SetDescription,
330         IShellLink_GetWorkingDirectory,
331         IShellLink_SetWorkingDirectory,
332         IShellLink_GetArguments,
333         IShellLink_SetArguments,
334         IShellLink_GetHotkey,
335         IShellLink_SetHotkey,
336         IShellLink_GetShowCmd,
337         IShellLink_SetShowCmd,
338         IShellLink_GetIconLocation,
339         IShellLink_SetIconLocation,
340         IShellLink_SetRelativePath,
341         IShellLink_Resolve,
342         IShellLink_SetPath
343 };
344
345 /**************************************************************************
346  *        IShellLink_Constructor
347  */
348 LPSHELLLINK IShellLink_Constructor(void) 
349 {       LPSHELLLINK sl;
350
351         sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink));
352         sl->ref = 1;
353         sl->lpvtbl = &slvt;
354
355         sl->lppf = IPersistFile_Constructor();
356
357         TRACE(shell,"(%p)->()\n",sl);
358         shell32_ObjCount++;
359         return sl;
360 }
361
362 /**************************************************************************
363  *  IShellLink::QueryInterface
364  */
365 static HRESULT WINAPI IShellLink_QueryInterface(
366   LPSHELLLINK this, REFIID riid, LPVOID *ppvObj)
367 {       char    xriid[50];
368         WINE_StringFromCLSID((LPCLSID)riid,xriid);
369         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
370
371         *ppvObj = NULL;
372
373         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
374         { *ppvObj = this; 
375         }
376         else if(IsEqualIID(riid, &IID_IShellLink))  /*IShellLink*/
377         {    *ppvObj = (LPSHELLLINK)this;
378         }   
379         else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
380         {    *ppvObj = (LPPERSISTFILE)this->lppf;
381         }   
382
383         if(*ppvObj)
384         { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this);      
385           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
386           return S_OK;
387         }
388         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
389         return E_NOINTERFACE;
390 }  
391 /******************************************************************************
392  * IShellLink_AddRef
393  */
394 static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this)
395 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
396
397         shell32_ObjCount++;
398         return ++(this->ref);
399 }
400 /******************************************************************************
401  *      IShellLink_Release
402  */
403 static ULONG WINAPI IShellLink_Release(LPSHELLLINK this)
404 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
405
406         shell32_ObjCount--;
407         if (!--(this->ref)) 
408         { TRACE(shell,"-- destroying IShellLink(%p)\n",this);
409           IPersistFile_Release(this->lppf);     /* IPersistFile*/
410           HeapFree(GetProcessHeap(),0,this);
411           return 0;
412         }
413         return this->ref;
414 }
415
416 static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK this, LPSTR pszFile,INT32 cchMaxPath, WIN32_FIND_DATA32A *pfd, DWORD fFlags)
417 {       FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",this, pszFile, cchMaxPath, pfd, fFlags);
418         strncpy(pszFile,"c:\\foo.bar", cchMaxPath);
419         return NOERROR;
420 }
421 static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK this, LPITEMIDLIST * ppidl)
422 {       FIXME(shell,"(%p)->(ppidl=%p)\n",this, ppidl);
423         *ppidl = _ILCreateDesktop();
424         return NOERROR;
425 }
426 static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK this, LPCITEMIDLIST pidl)
427 {       FIXME(shell,"(%p)->(pidl=%p)\n",this, pidl);
428         return NOERROR;
429 }
430 static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK this, LPSTR pszName,INT32 cchMaxName)
431 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszName, cchMaxName);
432         strncpy(pszName,"Description, FIXME",cchMaxName);
433         return NOERROR;
434 }
435 static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK this, LPCSTR pszName)
436 {       FIXME(shell,"(%p)->(desc=%s)\n",this, pszName);
437         return NOERROR;
438 }
439 static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK this, LPSTR pszDir,INT32 cchMaxPath)
440 {       FIXME(shell,"(%p)->()\n",this);
441         strncpy(pszDir,"c:\\", cchMaxPath);
442         return NOERROR;
443 }
444 static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK this, LPCSTR pszDir)
445 {       FIXME(shell,"(%p)->(dir=%s)\n",this, pszDir);
446         return NOERROR;
447 }
448 static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK this, LPSTR pszArgs,INT32 cchMaxPath)
449 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszArgs, cchMaxPath);
450         strncpy(pszArgs, "", cchMaxPath);
451         return NOERROR;
452 }
453 static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK this, LPCSTR pszArgs)
454 {       FIXME(shell,"(%p)->(args=%s)\n",this, pszArgs);
455         return NOERROR;
456 }
457 static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK this, WORD *pwHotkey)
458 {       FIXME(shell,"(%p)->(%p)\n",this, pwHotkey);
459         *pwHotkey=0x0;
460         return NOERROR;
461 }
462 static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK this, WORD wHotkey)
463 {       FIXME(shell,"(%p)->(hotkey=%x)\n",this, wHotkey);
464         return NOERROR;
465 }
466 static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK this, INT32 *piShowCmd)
467 {       FIXME(shell,"(%p)->(%p)\n",this, piShowCmd);
468         *piShowCmd=0;
469         return NOERROR;
470 }
471 static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK this, INT32 iShowCmd)
472 {       FIXME(shell,"(%p)->(showcmd=%x)\n",this, iShowCmd);
473         return NOERROR;
474 }
475 static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK this, LPSTR pszIconPath,INT32 cchIconPath,INT32 *piIcon)
476 {       FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",this, pszIconPath, cchIconPath, piIcon);
477         strncpy(pszIconPath,"shell32.dll",cchIconPath);
478         *piIcon=1;
479         return NOERROR;
480 }
481 static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK this, LPCSTR pszIconPath,INT32 iIcon)
482 {       FIXME(shell,"(%p)->(path=%s iicon=%u)\n",this, pszIconPath, iIcon);
483         return NOERROR;
484 }
485 static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK this, LPCSTR pszPathRel, DWORD dwReserved)
486 {       FIXME(shell,"(%p)->(path=%s %lx)\n",this, pszPathRel, dwReserved);
487         return NOERROR;
488 }
489 static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK this, HWND32 hwnd, DWORD fFlags)
490 {       FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",this, hwnd, fFlags);
491         return NOERROR;
492 }
493 static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK this, LPCSTR pszFile)
494 {       FIXME(shell,"(%p)->(path=%s)\n",this, pszFile);
495         return NOERROR;
496 }
497
498 /**************************************************************************
499 *  IShellLink's IClassFactory implementation
500 */
501
502 static ICOM_VTABLE(IClassFactory) slwcfvt;
503
504 /**************************************************************************
505  *  IShellLinkW_CF_Constructor
506  */
507
508 LPCLASSFACTORY IShellLinkW_CF_Constructor(void)
509 {
510         IClassFactoryImpl* lpclf;
511
512         lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
513         lpclf->ref = 1;
514         lpclf->lpvtbl = &slwcfvt;
515         TRACE(shell,"(%p)->()\n",lpclf);
516         shell32_ObjCount++;
517         return (LPCLASSFACTORY)lpclf;
518 }
519 /**************************************************************************
520  *  IShellLinkW_CF_QueryInterface
521  */
522 static HRESULT WINAPI IShellLinkW_CF_QueryInterface(
523   LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
524 {
525         ICOM_THIS(IClassFactoryImpl,iface);
526         char    xriid[50];
527         WINE_StringFromCLSID((LPCLSID)riid,xriid);
528         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",This,xriid);
529
530         *ppvObj = NULL;
531
532         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
533         { *ppvObj = (LPUNKNOWN)This; 
534         }
535         else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
536         { *ppvObj = (LPCLASSFACTORY)This;
537         }   
538
539         if(*ppvObj) {
540           IUnknown_AddRef((IUnknown*)*ppvObj);          
541           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
542           return S_OK;
543         }
544         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
545         return E_NOINTERFACE;
546 }  
547 /******************************************************************************
548  * IShellLinkW_CF_AddRef
549  */
550 static ULONG WINAPI IShellLinkW_CF_AddRef(LPCLASSFACTORY iface)
551 {
552         ICOM_THIS(IClassFactoryImpl,iface);
553         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
554
555         shell32_ObjCount++;
556         return ++(This->ref);
557 }
558 /******************************************************************************
559  * IShellLinkW_CF_Release
560  */
561 static ULONG WINAPI IShellLinkW_CF_Release(LPCLASSFACTORY iface)
562 {
563         ICOM_THIS(IClassFactoryImpl,iface);
564         TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
565
566         shell32_ObjCount--;
567         if (!--(This->ref)) 
568         { TRACE(shell,"-- destroying IClassFactory(%p)\n",This);
569                 HeapFree(GetProcessHeap(),0,This);
570                 return 0;
571         }
572         return This->ref;
573 }
574 /******************************************************************************
575  * IShellLinkW_CF_CreateInstance
576  */
577 static HRESULT WINAPI IShellLinkW_CF_CreateInstance(
578   LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
579 {
580         ICOM_THIS(IClassFactoryImpl,iface);
581         IUnknown *pObj = NULL;
582         HRESULT hres;
583         char    xriid[50];
584
585         WINE_StringFromCLSID((LPCLSID)riid,xriid);
586         TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,xriid,ppObject);
587
588         *ppObject = NULL;
589                 
590         if(pUnknown)
591         { return(CLASS_E_NOAGGREGATION);
592         }
593
594         if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLinkW))
595         { pObj = (IUnknown *)IShellLinkW_Constructor();
596         } 
597         else
598         { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
599           return(E_NOINTERFACE);
600         }
601         
602         if (!pObj)
603         { return(E_OUTOFMEMORY);
604         }
605          
606         hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject);
607         pObj->lpvtbl->fnRelease(pObj);
608         TRACE(shell,"-- Object created: (%p)->%p\n",This,*ppObject);
609
610         return hres;
611 }
612 /******************************************************************************
613  * IShellLinkW_CF_LockServer
614  */
615
616 static HRESULT WINAPI IShellLinkW_CF_LockServer(LPCLASSFACTORY iface, BOOL32 fLock)
617 {
618         ICOM_THIS(IClassFactoryImpl,iface);
619         TRACE(shell,"%p->(0x%x), not implemented\n",This, fLock);
620         return E_NOTIMPL;
621 }
622
623 static ICOM_VTABLE(IClassFactory) slwcfvt = 
624 {
625     IShellLinkW_CF_QueryInterface,
626     IShellLinkW_CF_AddRef,
627   IShellLinkW_CF_Release,
628   IShellLinkW_CF_CreateInstance,
629   IShellLinkW_CF_LockServer
630 };
631
632 /* IShellLinkW Implementation */
633 static HRESULT WINAPI IShellLinkW_QueryInterface(LPSHELLLINKW,REFIID,LPVOID*);
634 static ULONG WINAPI IShellLinkW_AddRef(LPSHELLLINKW);
635 static ULONG WINAPI IShellLinkW_Release(LPSHELLLINKW);
636 static HRESULT WINAPI IShellLinkW_GetPath(LPSHELLLINKW, LPWSTR,INT32, WIN32_FIND_DATA32A *, DWORD);
637 static HRESULT WINAPI IShellLinkW_GetIDList(LPSHELLLINKW, LPITEMIDLIST *);
638 static HRESULT WINAPI IShellLinkW_SetIDList(LPSHELLLINKW, LPCITEMIDLIST);
639 static HRESULT WINAPI IShellLinkW_GetDescription(LPSHELLLINKW, LPWSTR,INT32);
640 static HRESULT WINAPI IShellLinkW_SetDescription(LPSHELLLINKW, LPCWSTR);
641 static HRESULT WINAPI IShellLinkW_GetWorkingDirectory(LPSHELLLINKW, LPWSTR,INT32);
642 static HRESULT WINAPI IShellLinkW_SetWorkingDirectory(LPSHELLLINKW, LPCWSTR);
643 static HRESULT WINAPI IShellLinkW_GetArguments(LPSHELLLINKW, LPWSTR,INT32);
644 static HRESULT WINAPI IShellLinkW_SetArguments(LPSHELLLINKW, LPCWSTR);
645 static HRESULT WINAPI IShellLinkW_GetHotkey(LPSHELLLINKW, WORD *);
646 static HRESULT WINAPI IShellLinkW_SetHotkey(LPSHELLLINKW, WORD);
647 static HRESULT WINAPI IShellLinkW_GetShowCmd(LPSHELLLINKW, INT32 *);
648 static HRESULT WINAPI IShellLinkW_SetShowCmd(LPSHELLLINKW, INT32);
649 static HRESULT WINAPI IShellLinkW_GetIconLocation(LPSHELLLINKW, LPWSTR,INT32,INT32 *);
650 static HRESULT WINAPI IShellLinkW_SetIconLocation(LPSHELLLINKW, LPCWSTR,INT32);
651 static HRESULT WINAPI IShellLinkW_SetRelativePath(LPSHELLLINKW, LPCWSTR, DWORD);
652 static HRESULT WINAPI IShellLinkW_Resolve(LPSHELLLINKW, HWND32, DWORD);
653 static HRESULT WINAPI IShellLinkW_SetPath(LPSHELLLINKW, LPCWSTR);
654
655 /**************************************************************************
656 * IShellLinkW Implementation
657 */
658
659 static struct IShellLinkW_VTable slvtw = 
660 {       IShellLinkW_QueryInterface,
661         IShellLinkW_AddRef,
662         IShellLinkW_Release,
663         IShellLinkW_GetPath,
664         IShellLinkW_GetIDList,
665         IShellLinkW_SetIDList,
666         IShellLinkW_GetDescription,
667         IShellLinkW_SetDescription,
668         IShellLinkW_GetWorkingDirectory,
669         IShellLinkW_SetWorkingDirectory,
670         IShellLinkW_GetArguments,
671         IShellLinkW_SetArguments,
672         IShellLinkW_GetHotkey,
673         IShellLinkW_SetHotkey,
674         IShellLinkW_GetShowCmd,
675         IShellLinkW_SetShowCmd,
676         IShellLinkW_GetIconLocation,
677         IShellLinkW_SetIconLocation,
678         IShellLinkW_SetRelativePath,
679         IShellLinkW_Resolve,
680         IShellLinkW_SetPath
681 };
682
683 /**************************************************************************
684  *        IShellLinkW_Constructor
685  */
686 LPSHELLLINKW IShellLinkW_Constructor(void) 
687 {       LPSHELLLINKW sl;
688
689         sl = (LPSHELLLINKW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLinkW));
690         sl->ref = 1;
691         sl->lpvtbl = &slvtw;
692
693         sl->lppf = IPersistFile_Constructor();
694
695         TRACE(shell,"(%p)->()\n",sl);
696         shell32_ObjCount++;
697         return sl;
698 }
699
700 /**************************************************************************
701  *  IShellLinkW_QueryInterface
702  */
703 static HRESULT WINAPI IShellLinkW_QueryInterface(
704   LPSHELLLINKW this, REFIID riid, LPVOID *ppvObj)
705 {  char    xriid[50];
706    WINE_StringFromCLSID((LPCLSID)riid,xriid);
707    TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
708
709   *ppvObj = NULL;
710
711   if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
712   { *ppvObj = this; 
713   }
714   else if(IsEqualIID(riid, &IID_IShellLinkW))  /*IShellLinkW*/
715   {    *ppvObj = (LPSHELLLINKW)this;
716   }   
717   else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
718   {    *ppvObj = (LPPERSISTFILE)this->lppf;
719   }   
720
721   if(*ppvObj)
722   { (*(LPSHELLLINKW*)ppvObj)->lpvtbl->fnAddRef(this);      
723     TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
724     return S_OK;
725   }
726     TRACE(shell,"-- Interface: E_NOINTERFACE\n");
727   return E_NOINTERFACE;
728 }  
729 /******************************************************************************
730  * IShellLinkW_AddRef
731  */
732 static ULONG WINAPI IShellLinkW_AddRef(LPSHELLLINKW this)
733 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
734
735         shell32_ObjCount++;
736         return ++(this->ref);
737 }
738 /******************************************************************************
739  * IClassFactory_Release
740  */
741 static ULONG WINAPI IShellLinkW_Release(LPSHELLLINKW this)
742 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
743
744         shell32_ObjCount--;
745         if (!--(this->ref)) 
746         { TRACE(shell,"-- destroying IShellLinkW(%p)\n",this);
747           IPersistFile_Release(this->lppf);     /* IPersistFile*/
748           HeapFree(GetProcessHeap(),0,this);
749           return 0;
750         }
751         return this->ref;
752 }
753
754 static HRESULT WINAPI IShellLinkW_GetPath(LPSHELLLINKW this, LPWSTR pszFile,INT32 cchMaxPath, WIN32_FIND_DATA32A *pfd, DWORD fFlags)
755 {       FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",this, pszFile, cchMaxPath, pfd, fFlags);
756         lstrcpynAtoW(pszFile,"c:\\foo.bar", cchMaxPath);
757         return NOERROR;
758 }
759 static HRESULT WINAPI IShellLinkW_GetIDList(LPSHELLLINKW this, LPITEMIDLIST * ppidl)
760 {       FIXME(shell,"(%p)->(ppidl=%p)\n",this, ppidl);
761         *ppidl = _ILCreateDesktop();
762         return NOERROR;
763 }
764 static HRESULT WINAPI IShellLinkW_SetIDList(LPSHELLLINKW this, LPCITEMIDLIST pidl)
765 {       FIXME(shell,"(%p)->(pidl=%p)\n",this, pidl);
766         return NOERROR;
767 }
768 static HRESULT WINAPI IShellLinkW_GetDescription(LPSHELLLINKW this, LPWSTR pszName,INT32 cchMaxName)
769 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszName, cchMaxName);
770         lstrcpynAtoW(pszName,"Description, FIXME",cchMaxName);
771         return NOERROR;
772 }
773 static HRESULT WINAPI IShellLinkW_SetDescription(LPSHELLLINKW this, LPCWSTR pszName)
774 {       FIXME(shell,"(%p)->(desc=%s)\n",this, debugstr_w(pszName));
775         return NOERROR;
776 }
777 static HRESULT WINAPI IShellLinkW_GetWorkingDirectory(LPSHELLLINKW this, LPWSTR pszDir,INT32 cchMaxPath)
778 {       FIXME(shell,"(%p)->()\n",this);
779         lstrcpynAtoW(pszDir,"c:\\", cchMaxPath);
780         return NOERROR;
781 }
782 static HRESULT WINAPI IShellLinkW_SetWorkingDirectory(LPSHELLLINKW this, LPCWSTR pszDir)
783 {       FIXME(shell,"(%p)->(dir=%s)\n",this, debugstr_w(pszDir));
784         return NOERROR;
785 }
786 static HRESULT WINAPI IShellLinkW_GetArguments(LPSHELLLINKW this, LPWSTR pszArgs,INT32 cchMaxPath)
787 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszArgs, cchMaxPath);
788         lstrcpynAtoW(pszArgs, "", cchMaxPath);
789         return NOERROR;
790 }
791 static HRESULT WINAPI IShellLinkW_SetArguments(LPSHELLLINKW this, LPCWSTR pszArgs)
792 {       FIXME(shell,"(%p)->(args=%s)\n",this, debugstr_w(pszArgs));
793         return NOERROR;
794 }
795 static HRESULT WINAPI IShellLinkW_GetHotkey(LPSHELLLINKW this, WORD *pwHotkey)
796 {       FIXME(shell,"(%p)->(%p)\n",this, pwHotkey);
797         *pwHotkey=0x0;
798         return NOERROR;
799 }
800 static HRESULT WINAPI IShellLinkW_SetHotkey(LPSHELLLINKW this, WORD wHotkey)
801 {       FIXME(shell,"(%p)->(hotkey=%x)\n",this, wHotkey);
802         return NOERROR;
803 }
804 static HRESULT WINAPI IShellLinkW_GetShowCmd(LPSHELLLINKW this, INT32 *piShowCmd)
805 {       FIXME(shell,"(%p)->(%p)\n",this, piShowCmd);
806         *piShowCmd=0;
807         return NOERROR;
808 }
809 static HRESULT WINAPI IShellLinkW_SetShowCmd(LPSHELLLINKW this, INT32 iShowCmd)
810 {       FIXME(shell,"(%p)->(showcmd=%x)\n",this, iShowCmd);
811         return NOERROR;
812 }
813 static HRESULT WINAPI IShellLinkW_GetIconLocation(LPSHELLLINKW this, LPWSTR pszIconPath,INT32 cchIconPath,INT32 *piIcon)
814 {       FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",this, pszIconPath, cchIconPath, piIcon);
815         lstrcpynAtoW(pszIconPath,"shell32.dll",cchIconPath);
816         *piIcon=1;
817         return NOERROR;
818 }
819 static HRESULT WINAPI IShellLinkW_SetIconLocation(LPSHELLLINKW this, LPCWSTR pszIconPath,INT32 iIcon)
820 {       FIXME(shell,"(%p)->(path=%s iicon=%u)\n",this, debugstr_w(pszIconPath), iIcon);
821         return NOERROR;
822 }
823 static HRESULT WINAPI IShellLinkW_SetRelativePath(LPSHELLLINKW this, LPCWSTR pszPathRel, DWORD dwReserved)
824 {       FIXME(shell,"(%p)->(path=%s %lx)\n",this, debugstr_w(pszPathRel), dwReserved);
825         return NOERROR;
826 }
827 static HRESULT WINAPI IShellLinkW_Resolve(LPSHELLLINKW this, HWND32 hwnd, DWORD fFlags)
828 {       FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",this, hwnd, fFlags);
829         return NOERROR;
830 }
831 static HRESULT WINAPI IShellLinkW_SetPath(LPSHELLLINKW this, LPCWSTR pszFile)
832 {       FIXME(shell,"(%p)->(path=%s)\n",this, debugstr_w(pszFile));
833         return NOERROR;
834 }
835