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