Changed some treeview related definitions.
[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   LPUNKNOWN 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(LPUNKNOWN 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(LPUNKNOWN 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   {
284     IShellLink_CF_QueryInterface,
285     IShellLink_CF_AddRef,
286     IShellLink_CF_Release
287   },
288   IShellLink_CF_CreateInstance,
289   IShellLink_CF_LockServer
290 };
291
292 /* IShellLink Implementation */
293 static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
294 static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
295 static ULONG WINAPI IShellLink_Release(LPSHELLLINK);
296 static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK, LPSTR,INT32, WIN32_FIND_DATA32A *, DWORD);
297 static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK, LPITEMIDLIST *);
298 static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK, LPCITEMIDLIST);
299 static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK, LPSTR,INT32);
300 static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK, LPCSTR);
301 static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK, LPSTR,INT32);
302 static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK, LPCSTR);
303 static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK, LPSTR,INT32);
304 static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK, LPCSTR);
305 static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK, WORD *);
306 static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK, WORD);
307 static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK, INT32 *);
308 static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK, INT32);
309 static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK, LPSTR,INT32,INT32 *);
310 static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK, LPCSTR,INT32);
311 static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK, LPCSTR, DWORD);
312 static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK, HWND32, DWORD);
313 static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK, LPCSTR);
314
315 /**************************************************************************
316 * IShellLink Implementation
317 */
318
319
320 static struct IShellLink_VTable slvt = 
321 {       IShellLink_QueryInterface,
322         IShellLink_AddRef,
323         IShellLink_Release,
324         IShellLink_GetPath,
325         IShellLink_GetIDList,
326         IShellLink_SetIDList,
327         IShellLink_GetDescription,
328         IShellLink_SetDescription,
329         IShellLink_GetWorkingDirectory,
330         IShellLink_SetWorkingDirectory,
331         IShellLink_GetArguments,
332         IShellLink_SetArguments,
333         IShellLink_GetHotkey,
334         IShellLink_SetHotkey,
335         IShellLink_GetShowCmd,
336         IShellLink_SetShowCmd,
337         IShellLink_GetIconLocation,
338         IShellLink_SetIconLocation,
339         IShellLink_SetRelativePath,
340         IShellLink_Resolve,
341         IShellLink_SetPath
342 };
343
344 /**************************************************************************
345  *        IShellLink_Constructor
346  */
347 LPSHELLLINK IShellLink_Constructor(void) 
348 {       LPSHELLLINK sl;
349
350         sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink));
351         sl->ref = 1;
352         sl->lpvtbl = &slvt;
353
354         sl->lppf = IPersistFile_Constructor();
355
356         TRACE(shell,"(%p)->()\n",sl);
357         shell32_ObjCount++;
358         return sl;
359 }
360
361 /**************************************************************************
362  *  IShellLink::QueryInterface
363  */
364 static HRESULT WINAPI IShellLink_QueryInterface(
365   LPSHELLLINK this, REFIID riid, LPVOID *ppvObj)
366 {       char    xriid[50];
367         WINE_StringFromCLSID((LPCLSID)riid,xriid);
368         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
369
370         *ppvObj = NULL;
371
372         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
373         { *ppvObj = this; 
374         }
375         else if(IsEqualIID(riid, &IID_IShellLink))  /*IShellLink*/
376         {    *ppvObj = (LPSHELLLINK)this;
377         }   
378         else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
379         {    *ppvObj = (LPPERSISTFILE)this->lppf;
380         }   
381
382         if(*ppvObj)
383         { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this);      
384           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
385           return S_OK;
386         }
387         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
388         return E_NOINTERFACE;
389 }  
390 /******************************************************************************
391  * IShellLink_AddRef
392  */
393 static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this)
394 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
395
396         shell32_ObjCount++;
397         return ++(this->ref);
398 }
399 /******************************************************************************
400  *      IShellLink_Release
401  */
402 static ULONG WINAPI IShellLink_Release(LPSHELLLINK this)
403 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
404
405         shell32_ObjCount--;
406         if (!--(this->ref)) 
407         { TRACE(shell,"-- destroying IShellLink(%p)\n",this);
408           IPersistFile_Release(this->lppf);     /* IPersistFile*/
409           HeapFree(GetProcessHeap(),0,this);
410           return 0;
411         }
412         return this->ref;
413 }
414
415 static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK this, LPSTR pszFile,INT32 cchMaxPath, WIN32_FIND_DATA32A *pfd, DWORD fFlags)
416 {       FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",this, pszFile, cchMaxPath, pfd, fFlags);
417         strncpy(pszFile,"c:\\foo.bar", cchMaxPath);
418         return NOERROR;
419 }
420 static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK this, LPITEMIDLIST * ppidl)
421 {       FIXME(shell,"(%p)->(ppidl=%p)\n",this, ppidl);
422         *ppidl = _ILCreateDesktop();
423         return NOERROR;
424 }
425 static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK this, LPCITEMIDLIST pidl)
426 {       FIXME(shell,"(%p)->(pidl=%p)\n",this, pidl);
427         return NOERROR;
428 }
429 static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK this, LPSTR pszName,INT32 cchMaxName)
430 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszName, cchMaxName);
431         strncpy(pszName,"Description, FIXME",cchMaxName);
432         return NOERROR;
433 }
434 static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK this, LPCSTR pszName)
435 {       FIXME(shell,"(%p)->(desc=%s)\n",this, pszName);
436         return NOERROR;
437 }
438 static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK this, LPSTR pszDir,INT32 cchMaxPath)
439 {       FIXME(shell,"(%p)->()\n",this);
440         strncpy(pszDir,"c:\\", cchMaxPath);
441         return NOERROR;
442 }
443 static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK this, LPCSTR pszDir)
444 {       FIXME(shell,"(%p)->(dir=%s)\n",this, pszDir);
445         return NOERROR;
446 }
447 static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK this, LPSTR pszArgs,INT32 cchMaxPath)
448 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszArgs, cchMaxPath);
449         strncpy(pszArgs, "", cchMaxPath);
450         return NOERROR;
451 }
452 static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK this, LPCSTR pszArgs)
453 {       FIXME(shell,"(%p)->(args=%s)\n",this, pszArgs);
454         return NOERROR;
455 }
456 static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK this, WORD *pwHotkey)
457 {       FIXME(shell,"(%p)->(%p)\n",this, pwHotkey);
458         *pwHotkey=0x0;
459         return NOERROR;
460 }
461 static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK this, WORD wHotkey)
462 {       FIXME(shell,"(%p)->(hotkey=%x)\n",this, wHotkey);
463         return NOERROR;
464 }
465 static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK this, INT32 *piShowCmd)
466 {       FIXME(shell,"(%p)->(%p)\n",this, piShowCmd);
467         *piShowCmd=0;
468         return NOERROR;
469 }
470 static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK this, INT32 iShowCmd)
471 {       FIXME(shell,"(%p)->(showcmd=%x)\n",this, iShowCmd);
472         return NOERROR;
473 }
474 static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK this, LPSTR pszIconPath,INT32 cchIconPath,INT32 *piIcon)
475 {       FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",this, pszIconPath, cchIconPath, piIcon);
476         strncpy(pszIconPath,"shell32.dll",cchIconPath);
477         *piIcon=1;
478         return NOERROR;
479 }
480 static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK this, LPCSTR pszIconPath,INT32 iIcon)
481 {       FIXME(shell,"(%p)->(path=%s iicon=%u)\n",this, pszIconPath, iIcon);
482         return NOERROR;
483 }
484 static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK this, LPCSTR pszPathRel, DWORD dwReserved)
485 {       FIXME(shell,"(%p)->(path=%s %lx)\n",this, pszPathRel, dwReserved);
486         return NOERROR;
487 }
488 static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK this, HWND32 hwnd, DWORD fFlags)
489 {       FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",this, hwnd, fFlags);
490         return NOERROR;
491 }
492 static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK this, LPCSTR pszFile)
493 {       FIXME(shell,"(%p)->(path=%s)\n",this, pszFile);
494         return NOERROR;
495 }
496
497 /**************************************************************************
498 *  IShellLink's IClassFactory implementation
499 */
500
501 static ICOM_VTABLE(IClassFactory) slwcfvt;
502
503 /**************************************************************************
504  *  IShellLinkW_CF_Constructor
505  */
506
507 LPCLASSFACTORY IShellLinkW_CF_Constructor(void)
508 {
509         _IClassFactory* lpclf;
510
511         lpclf= (_IClassFactory*)HeapAlloc(GetProcessHeap(),0,sizeof(_IClassFactory));
512         lpclf->ref = 1;
513         lpclf->lpvtbl = &slwcfvt;
514         TRACE(shell,"(%p)->()\n",lpclf);
515         shell32_ObjCount++;
516         return (LPCLASSFACTORY)lpclf;
517 }
518 /**************************************************************************
519  *  IShellLinkW_CF_QueryInterface
520  */
521 static HRESULT WINAPI IShellLinkW_CF_QueryInterface(
522   LPUNKNOWN iface, REFIID riid, LPVOID *ppvObj)
523 {
524         ICOM_THIS(IClassFactory,iface);
525         char    xriid[50];
526         WINE_StringFromCLSID((LPCLSID)riid,xriid);
527         TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
528
529         *ppvObj = NULL;
530
531         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
532         { *ppvObj = (LPUNKNOWN)this; 
533         }
534         else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
535         { *ppvObj = (LPCLASSFACTORY)this;
536         }   
537
538         if(*ppvObj) {
539           IUnknown_AddRef((IUnknown*)*ppvObj);          
540           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
541           return S_OK;
542         }
543         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
544         return E_NOINTERFACE;
545 }  
546 /******************************************************************************
547  * IShellLinkW_CF_AddRef
548  */
549 static ULONG WINAPI IShellLinkW_CF_AddRef(LPUNKNOWN iface)
550 {
551         ICOM_THIS(IClassFactory,iface);
552         TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
553
554         shell32_ObjCount++;
555         return ++(this->ref);
556 }
557 /******************************************************************************
558  * IShellLinkW_CF_Release
559  */
560 static ULONG WINAPI IShellLinkW_CF_Release(LPUNKNOWN iface)
561 {
562         ICOM_THIS(IClassFactory,iface);
563         TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
564
565         shell32_ObjCount--;
566         if (!--(this->ref)) 
567         { TRACE(shell,"-- destroying IClassFactory(%p)\n",this);
568                 HeapFree(GetProcessHeap(),0,this);
569                 return 0;
570         }
571         return this->ref;
572 }
573 /******************************************************************************
574  * IShellLinkW_CF_CreateInstance
575  */
576 static HRESULT WINAPI IShellLinkW_CF_CreateInstance(
577   LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
578 {
579         ICOM_THIS(IClassFactory,iface);
580         IUnknown *pObj = NULL;
581         HRESULT hres;
582         char    xriid[50];
583
584         WINE_StringFromCLSID((LPCLSID)riid,xriid);
585         TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown,xriid,ppObject);
586
587         *ppObject = NULL;
588                 
589         if(pUnknown)
590         { return(CLASS_E_NOAGGREGATION);
591         }
592
593         if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLinkW))
594         { pObj = (IUnknown *)IShellLinkW_Constructor();
595         } 
596         else
597         { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
598           return(E_NOINTERFACE);
599         }
600         
601         if (!pObj)
602         { return(E_OUTOFMEMORY);
603         }
604          
605         hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject);
606         pObj->lpvtbl->fnRelease(pObj);
607         TRACE(shell,"-- Object created: (%p)->%p\n",this,*ppObject);
608
609         return hres;
610 }
611 /******************************************************************************
612  * IShellLinkW_CF_LockServer
613  */
614
615 static HRESULT WINAPI IShellLinkW_CF_LockServer(LPCLASSFACTORY iface, BOOL32 fLock)
616 {
617         ICOM_THIS(IClassFactory,iface);
618         TRACE(shell,"%p->(0x%x), not implemented\n",this, fLock);
619         return E_NOTIMPL;
620 }
621
622 static ICOM_VTABLE(IClassFactory) slwcfvt = 
623 {
624   {
625     IShellLinkW_CF_QueryInterface,
626     IShellLinkW_CF_AddRef,
627     IShellLinkW_CF_Release
628   },
629   IShellLinkW_CF_CreateInstance,
630   IShellLinkW_CF_LockServer
631 };
632
633 /* IShellLinkW Implementation */
634 static HRESULT WINAPI IShellLinkW_QueryInterface(LPSHELLLINKW,REFIID,LPVOID*);
635 static ULONG WINAPI IShellLinkW_AddRef(LPSHELLLINKW);
636 static ULONG WINAPI IShellLinkW_Release(LPSHELLLINKW);
637 static HRESULT WINAPI IShellLinkW_GetPath(LPSHELLLINKW, LPWSTR,INT32, WIN32_FIND_DATA32A *, DWORD);
638 static HRESULT WINAPI IShellLinkW_GetIDList(LPSHELLLINKW, LPITEMIDLIST *);
639 static HRESULT WINAPI IShellLinkW_SetIDList(LPSHELLLINKW, LPCITEMIDLIST);
640 static HRESULT WINAPI IShellLinkW_GetDescription(LPSHELLLINKW, LPWSTR,INT32);
641 static HRESULT WINAPI IShellLinkW_SetDescription(LPSHELLLINKW, LPCWSTR);
642 static HRESULT WINAPI IShellLinkW_GetWorkingDirectory(LPSHELLLINKW, LPWSTR,INT32);
643 static HRESULT WINAPI IShellLinkW_SetWorkingDirectory(LPSHELLLINKW, LPCWSTR);
644 static HRESULT WINAPI IShellLinkW_GetArguments(LPSHELLLINKW, LPWSTR,INT32);
645 static HRESULT WINAPI IShellLinkW_SetArguments(LPSHELLLINKW, LPCWSTR);
646 static HRESULT WINAPI IShellLinkW_GetHotkey(LPSHELLLINKW, WORD *);
647 static HRESULT WINAPI IShellLinkW_SetHotkey(LPSHELLLINKW, WORD);
648 static HRESULT WINAPI IShellLinkW_GetShowCmd(LPSHELLLINKW, INT32 *);
649 static HRESULT WINAPI IShellLinkW_SetShowCmd(LPSHELLLINKW, INT32);
650 static HRESULT WINAPI IShellLinkW_GetIconLocation(LPSHELLLINKW, LPWSTR,INT32,INT32 *);
651 static HRESULT WINAPI IShellLinkW_SetIconLocation(LPSHELLLINKW, LPCWSTR,INT32);
652 static HRESULT WINAPI IShellLinkW_SetRelativePath(LPSHELLLINKW, LPCWSTR, DWORD);
653 static HRESULT WINAPI IShellLinkW_Resolve(LPSHELLLINKW, HWND32, DWORD);
654 static HRESULT WINAPI IShellLinkW_SetPath(LPSHELLLINKW, LPCWSTR);
655
656 /**************************************************************************
657 * IShellLinkW Implementation
658 */
659
660 static struct IShellLinkW_VTable slvtw = 
661 {       IShellLinkW_QueryInterface,
662         IShellLinkW_AddRef,
663         IShellLinkW_Release,
664         IShellLinkW_GetPath,
665         IShellLinkW_GetIDList,
666         IShellLinkW_SetIDList,
667         IShellLinkW_GetDescription,
668         IShellLinkW_SetDescription,
669         IShellLinkW_GetWorkingDirectory,
670         IShellLinkW_SetWorkingDirectory,
671         IShellLinkW_GetArguments,
672         IShellLinkW_SetArguments,
673         IShellLinkW_GetHotkey,
674         IShellLinkW_SetHotkey,
675         IShellLinkW_GetShowCmd,
676         IShellLinkW_SetShowCmd,
677         IShellLinkW_GetIconLocation,
678         IShellLinkW_SetIconLocation,
679         IShellLinkW_SetRelativePath,
680         IShellLinkW_Resolve,
681         IShellLinkW_SetPath
682 };
683
684 /**************************************************************************
685  *        IShellLinkW_Constructor
686  */
687 LPSHELLLINKW IShellLinkW_Constructor(void) 
688 {       LPSHELLLINKW sl;
689
690         sl = (LPSHELLLINKW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLinkW));
691         sl->ref = 1;
692         sl->lpvtbl = &slvtw;
693
694         sl->lppf = IPersistFile_Constructor();
695
696         TRACE(shell,"(%p)->()\n",sl);
697         shell32_ObjCount++;
698         return sl;
699 }
700
701 /**************************************************************************
702  *  IShellLinkW::QueryInterface
703  */
704 static HRESULT WINAPI IShellLinkW_QueryInterface(
705   LPSHELLLINKW this, REFIID riid, LPVOID *ppvObj)
706 {  char    xriid[50];
707    WINE_StringFromCLSID((LPCLSID)riid,xriid);
708    TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
709
710   *ppvObj = NULL;
711
712   if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
713   { *ppvObj = this; 
714   }
715   else if(IsEqualIID(riid, &IID_IShellLinkW))  /*IShellLinkW*/
716   {    *ppvObj = (LPSHELLLINKW)this;
717   }   
718   else if(IsEqualIID(riid, &IID_IPersistFile))  /*IPersistFile*/
719   {    *ppvObj = (LPPERSISTFILE)this->lppf;
720   }   
721
722   if(*ppvObj)
723   { (*(LPSHELLLINKW*)ppvObj)->lpvtbl->fnAddRef(this);      
724     TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
725     return S_OK;
726   }
727     TRACE(shell,"-- Interface: E_NOINTERFACE\n");
728   return E_NOINTERFACE;
729 }  
730 /******************************************************************************
731  * IShellLinkW_AddRef
732  */
733 static ULONG WINAPI IShellLinkW_AddRef(LPSHELLLINKW this)
734 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
735
736         shell32_ObjCount++;
737         return ++(this->ref);
738 }
739 /******************************************************************************
740  * IClassFactory_Release
741  */
742 static ULONG WINAPI IShellLinkW_Release(LPSHELLLINKW this)
743 {       TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
744
745         shell32_ObjCount--;
746         if (!--(this->ref)) 
747         { TRACE(shell,"-- destroying IShellLinkW(%p)\n",this);
748           IPersistFile_Release(this->lppf);     /* IPersistFile*/
749           HeapFree(GetProcessHeap(),0,this);
750           return 0;
751         }
752         return this->ref;
753 }
754
755 static HRESULT WINAPI IShellLinkW_GetPath(LPSHELLLINKW this, LPWSTR pszFile,INT32 cchMaxPath, WIN32_FIND_DATA32A *pfd, DWORD fFlags)
756 {       FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",this, pszFile, cchMaxPath, pfd, fFlags);
757         lstrcpynAtoW(pszFile,"c:\\foo.bar", cchMaxPath);
758         return NOERROR;
759 }
760 static HRESULT WINAPI IShellLinkW_GetIDList(LPSHELLLINKW this, LPITEMIDLIST * ppidl)
761 {       FIXME(shell,"(%p)->(ppidl=%p)\n",this, ppidl);
762         *ppidl = _ILCreateDesktop();
763         return NOERROR;
764 }
765 static HRESULT WINAPI IShellLinkW_SetIDList(LPSHELLLINKW this, LPCITEMIDLIST pidl)
766 {       FIXME(shell,"(%p)->(pidl=%p)\n",this, pidl);
767         return NOERROR;
768 }
769 static HRESULT WINAPI IShellLinkW_GetDescription(LPSHELLLINKW this, LPWSTR pszName,INT32 cchMaxName)
770 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszName, cchMaxName);
771         lstrcpynAtoW(pszName,"Description, FIXME",cchMaxName);
772         return NOERROR;
773 }
774 static HRESULT WINAPI IShellLinkW_SetDescription(LPSHELLLINKW this, LPCWSTR pszName)
775 {       FIXME(shell,"(%p)->(desc=%s)\n",this, debugstr_w(pszName));
776         return NOERROR;
777 }
778 static HRESULT WINAPI IShellLinkW_GetWorkingDirectory(LPSHELLLINKW this, LPWSTR pszDir,INT32 cchMaxPath)
779 {       FIXME(shell,"(%p)->()\n",this);
780         lstrcpynAtoW(pszDir,"c:\\", cchMaxPath);
781         return NOERROR;
782 }
783 static HRESULT WINAPI IShellLinkW_SetWorkingDirectory(LPSHELLLINKW this, LPCWSTR pszDir)
784 {       FIXME(shell,"(%p)->(dir=%s)\n",this, debugstr_w(pszDir));
785         return NOERROR;
786 }
787 static HRESULT WINAPI IShellLinkW_GetArguments(LPSHELLLINKW this, LPWSTR pszArgs,INT32 cchMaxPath)
788 {       FIXME(shell,"(%p)->(%p len=%u)\n",this, pszArgs, cchMaxPath);
789         lstrcpynAtoW(pszArgs, "", cchMaxPath);
790         return NOERROR;
791 }
792 static HRESULT WINAPI IShellLinkW_SetArguments(LPSHELLLINKW this, LPCWSTR pszArgs)
793 {       FIXME(shell,"(%p)->(args=%s)\n",this, debugstr_w(pszArgs));
794         return NOERROR;
795 }
796 static HRESULT WINAPI IShellLinkW_GetHotkey(LPSHELLLINKW this, WORD *pwHotkey)
797 {       FIXME(shell,"(%p)->(%p)\n",this, pwHotkey);
798         *pwHotkey=0x0;
799         return NOERROR;
800 }
801 static HRESULT WINAPI IShellLinkW_SetHotkey(LPSHELLLINKW this, WORD wHotkey)
802 {       FIXME(shell,"(%p)->(hotkey=%x)\n",this, wHotkey);
803         return NOERROR;
804 }
805 static HRESULT WINAPI IShellLinkW_GetShowCmd(LPSHELLLINKW this, INT32 *piShowCmd)
806 {       FIXME(shell,"(%p)->(%p)\n",this, piShowCmd);
807         *piShowCmd=0;
808         return NOERROR;
809 }
810 static HRESULT WINAPI IShellLinkW_SetShowCmd(LPSHELLLINKW this, INT32 iShowCmd)
811 {       FIXME(shell,"(%p)->(showcmd=%x)\n",this, iShowCmd);
812         return NOERROR;
813 }
814 static HRESULT WINAPI IShellLinkW_GetIconLocation(LPSHELLLINKW this, LPWSTR pszIconPath,INT32 cchIconPath,INT32 *piIcon)
815 {       FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",this, pszIconPath, cchIconPath, piIcon);
816         lstrcpynAtoW(pszIconPath,"shell32.dll",cchIconPath);
817         *piIcon=1;
818         return NOERROR;
819 }
820 static HRESULT WINAPI IShellLinkW_SetIconLocation(LPSHELLLINKW this, LPCWSTR pszIconPath,INT32 iIcon)
821 {       FIXME(shell,"(%p)->(path=%s iicon=%u)\n",this, debugstr_w(pszIconPath), iIcon);
822         return NOERROR;
823 }
824 static HRESULT WINAPI IShellLinkW_SetRelativePath(LPSHELLLINKW this, LPCWSTR pszPathRel, DWORD dwReserved)
825 {       FIXME(shell,"(%p)->(path=%s %lx)\n",this, debugstr_w(pszPathRel), dwReserved);
826         return NOERROR;
827 }
828 static HRESULT WINAPI IShellLinkW_Resolve(LPSHELLLINKW this, HWND32 hwnd, DWORD fFlags)
829 {       FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",this, hwnd, fFlags);
830         return NOERROR;
831 }
832 static HRESULT WINAPI IShellLinkW_SetPath(LPSHELLLINKW this, LPCWSTR pszFile)
833 {       FIXME(shell,"(%p)->(path=%s)\n",this, debugstr_w(pszFile));
834         return NOERROR;
835 }
836