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