source: trunk/src/shell32/shelllink.c@ 5087

Last change on this file since 5087 was 4561, checked in by sandervl, 25 years ago

merged with latest Wine (11-05-2000)

File size: 38.1 KB
Line 
1/* $Id: shelllink.c,v 1.2 2000-11-06 10:20:56 sandervl Exp $ */
2/*
3 *
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied
6 *
7 */
8#ifdef __WIN32OS2__
9#define ICOM_CINTERFACE 1
10#include <odin.h>
11#endif
12
13#include <string.h>
14#include <sys/stat.h>
15#include <stdio.h>
16#ifndef __WIN32OS2__
17#include <unistd.h>
18#endif
19#include <errno.h>
20#ifndef __WIN32OS2__
21#include <sys/wait.h>
22#endif
23
24#include "debugtools.h"
25#include "winerror.h"
26#include "winbase.h"
27#include "winnls.h"
28
29#include "shlobj.h"
30#include "wine/winestring.h"
31#include "wine/undocshell.h"
32#ifndef __WIN32OS2__
33#include "bitmaps/wine.xpm"
34#endif
35
36#include "heap.h"
37#include "pidl.h"
38#include "shell32_main.h"
39#include "shlguid.h"
40#include "file.h"
41#include "options.h"
42
43DEFAULT_DEBUG_CHANNEL(shell);
44
45/* link file formats */
46
47#include "pshpack1.h"
48
49/* flag1: lnk elements: simple link has 0x0B */
50#define WORKDIR 0x10
51#define ARGUMENT 0x20
52#define ICON 0x40
53#define UNC 0x80
54
55/* fStartup */
56#define NORMAL 0x01
57#define MAXIMIZED 0x03
58#define MINIMIZED 0x07
59
60typedef struct _LINK_HEADER
61{ DWORD MagicStr; /* 0x00 'L','\0','\0','\0' */
62 GUID MagicGuid; /* 0x04 is CLSID_ShellLink */
63 DWORD Flag1; /* 0x14 describes elements following */
64 DWORD Flag2; /* 0x18 */
65 FILETIME Time1; /* 0x1c */
66 FILETIME Time2; /* 0x24 */
67 FILETIME Time3; /* 0x2c */
68 DWORD Unknown1; /* 0x34 */
69 DWORD Unknown2; /* 0x38 icon number */
70 DWORD fStartup; /* 0x3c startup type */
71 DWORD wHotKey; /* 0x40 hotkey */
72 DWORD Unknown5; /* 0x44 */
73 DWORD Unknown6; /* 0x48 */
74 USHORT PidlSize; /* 0x4c */
75 ITEMIDLIST Pidl; /* 0x4e */
76} LINK_HEADER, * PLINK_HEADER;
77
78#define LINK_HEADER_SIZE (sizeof(LINK_HEADER)-sizeof(ITEMIDLIST))
79
80typedef struct
81{
82 BYTE bWidth;
83 BYTE bHeight;
84 BYTE bColorCount;
85 BYTE bReserved;
86 WORD wPlanes;
87 WORD wBitCount;
88 DWORD dwBytesInRes;
89 WORD nID;
90} GRPICONDIRENTRY;
91
92typedef struct
93{
94 WORD idReserved;
95 WORD idType;
96 WORD idCount;
97 GRPICONDIRENTRY idEntries[1];
98} GRPICONDIR;
99
100typedef struct
101{
102 BYTE bWidth;
103 BYTE bHeight;
104 BYTE bColorCount;
105 BYTE bReserved;
106 WORD wPlanes;
107 WORD wBitCount;
108 DWORD dwBytesInRes;
109 DWORD dwImageOffset;
110} ICONDIRENTRY;
111
112typedef struct
113{
114 WORD idReserved;
115 WORD idType;
116 WORD idCount;
117} ICONDIR;
118
119
120#include "poppack.h"
121
122
123static ICOM_VTABLE(IShellLinkA) slvt;
124static ICOM_VTABLE(IShellLinkW) slvtw;
125static ICOM_VTABLE(IPersistFile) pfvt;
126static ICOM_VTABLE(IPersistStream) psvt;
127
128/* IShellLink Implementation */
129
130typedef struct
131{
132 ICOM_VFIELD(IShellLinkA);
133 DWORD ref;
134
135 ICOM_VTABLE(IShellLinkW)* lpvtblw;
136 ICOM_VTABLE(IPersistFile)* lpvtblPersistFile;
137 ICOM_VTABLE(IPersistStream)* lpvtblPersistStream;
138
139 /* internal stream of the IPersistFile interface */
140 IStream* lpFileStream;
141
142 /* data structures according to the informations in the lnk */
143 LPSTR sPath;
144 LPITEMIDLIST pPidl;
145 WORD wHotKey;
146 SYSTEMTIME time1;
147 SYSTEMTIME time2;
148 SYSTEMTIME time3;
149
150 LPSTR sIcoPath;
151 INT iIcoNdx;
152 LPSTR sArgs;
153 LPSTR sWorkDir;
154 LPSTR sDescription;
155} IShellLinkImpl;
156
157#define _IShellLinkW_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblw)))
158#define _ICOM_THIS_From_IShellLinkW(class, name) class* This = (class*)(((char*)name)-_IShellLinkW_Offset);
159
160#define _IPersistFile_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistFile)))
161#define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((char*)name)-_IPersistFile_Offset);
162
163#define _IPersistStream_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistStream)))
164#define _ICOM_THIS_From_IPersistStream(class, name) class* This = (class*)(((char*)name)-_IPersistStream_Offset);
165#define _IPersistStream_From_ICOM_THIS(class, name) class* StreamThis = (class*)(((char*)name)+_IPersistStream_Offset);
166
167/**************************************************************************
168 * IPersistFile_QueryInterface
169 */
170static HRESULT WINAPI IPersistFile_fnQueryInterface(
171 IPersistFile* iface,
172 REFIID riid,
173 LPVOID *ppvObj)
174{
175 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
176
177 TRACE("(%p)\n",This);
178
179 return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObj);
180}
181
182/******************************************************************************
183 * IPersistFile_AddRef
184 */
185static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile* iface)
186{
187 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
188
189 TRACE("(%p)->(count=%lu)\n",This,This->ref);
190
191 return IShellLinkA_AddRef((IShellLinkA*)This);
192}
193/******************************************************************************
194 * IPersistFile_Release
195 */
196static ULONG WINAPI IPersistFile_fnRelease(IPersistFile* iface)
197{
198 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
199
200 TRACE("(%p)->(count=%lu)\n",This,This->ref);
201
202 return IShellLinkA_Release((IShellLinkA*)This);
203}
204
205static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile* iface, CLSID *pClassID)
206{
207 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
208 FIXME("(%p)\n",This);
209 return NOERROR;
210}
211static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile* iface)
212{
213 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
214 FIXME("(%p)\n",This);
215 return NOERROR;
216}
217static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode)
218{
219 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
220 _IPersistStream_From_ICOM_THIS(IPersistStream, This)
221
222 LPSTR sFile = HEAP_strdupWtoA ( GetProcessHeap(), 0, pszFileName);
223 HRESULT hRet = E_FAIL;
224
225 TRACE("(%p, %s)\n",This, sFile);
226
227
228 if (This->lpFileStream)
229 IStream_Release(This->lpFileStream);
230
231 if SUCCEEDED(CreateStreamOnFile(sFile, &(This->lpFileStream)))
232 {
233 if SUCCEEDED (IPersistStream_Load(StreamThis, This->lpFileStream))
234 {
235 return NOERROR;
236 }
237 }
238
239 return hRet;
240}
241
242
243#ifndef __WIN32OS2__
244/* Icon extraction routines
245 *
246 * FIXME: should use PrivateExtractIcons and friends
247 * FIXME: should not use stdio
248 */
249
250static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName)
251{
252 FILE *fXPMFile;
253 int nHeight;
254 int nXORWidthBytes;
255 int nANDWidthBytes;
256 BOOL b8BitColors;
257 int nColors;
258 BYTE *pXOR;
259 BYTE *pAND;
260 BOOL aColorUsed[256] = {0};
261 int nColorsUsed = 0;
262 int i,j;
263
264 if (!((pIcon->bmiHeader.biBitCount == 4) || (pIcon->bmiHeader.biBitCount == 8)))
265 return 0;
266
267 if (!(fXPMFile = fopen(szXPMFileName, "w")))
268 return 0;
269
270 nHeight = pIcon->bmiHeader.biHeight / 2;
271 nXORWidthBytes = 4 * ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount / 32)
272 + ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount % 32) > 0));
273 nANDWidthBytes = 4 * ((pIcon->bmiHeader.biWidth / 32)
274 + ((pIcon->bmiHeader.biWidth % 32) > 0));
275 b8BitColors = pIcon->bmiHeader.biBitCount == 8;
276 nColors = pIcon->bmiHeader.biClrUsed ? pIcon->bmiHeader.biClrUsed
277 : 1 << pIcon->bmiHeader.biBitCount;
278 pXOR = (BYTE*) pIcon + sizeof (BITMAPINFOHEADER) + (nColors * sizeof (RGBQUAD));
279 pAND = pXOR + nHeight * nXORWidthBytes;
280
281#define MASK(x,y) (pAND[(x) / 8 + (nHeight - (y) - 1) * nANDWidthBytes] & (1 << (7 - (x) % 8)))
282#define COLOR(x,y) (b8BitColors ? pXOR[(x) + (nHeight - (y) - 1) * nXORWidthBytes] : (x) % 2 ? pXOR[(x) / 2 + (nHeight - (y) - 1) * nXORWidthBytes] & 0xF : (pXOR[(x) / 2 + (nHeight - (y) - 1) * nXORWidthBytes] & 0xF0) >> 4)
283
284 for (i = 0; i < nHeight; i++)
285 for (j = 0; j < pIcon->bmiHeader.biWidth; j++)
286 if (!aColorUsed[COLOR(j,i)] && !MASK(j,i))
287 {
288 aColorUsed[COLOR(j,i)] = TRUE;
289 nColorsUsed++;
290 }
291
292 if (fprintf(fXPMFile, "/* XPM */\nstatic char *icon[] = {\n") <= 0)
293 goto error;
294 if (fprintf(fXPMFile, "\"%d %d %d %d\",\n",
295 (int) pIcon->bmiHeader.biWidth, nHeight, nColorsUsed + 1, 2) <=0)
296 goto error;
297
298 for (i = 0; i < nColors; i++)
299 if (aColorUsed[i])
300 if (fprintf(fXPMFile, "\"%.2X c #%.2X%.2X%.2X\",\n", i, pIcon->bmiColors[i].rgbRed,
301 pIcon->bmiColors[i].rgbGreen, pIcon->bmiColors[i].rgbBlue) <= 0)
302 goto error;
303 if (fprintf(fXPMFile, "\" c None\"") <= 0)
304 goto error;
305
306 for (i = 0; i < nHeight; i++)
307 {
308 if (fprintf(fXPMFile, ",\n\"") <= 0)
309 goto error;
310 for (j = 0; j < pIcon->bmiHeader.biWidth; j++)
311 {
312 if MASK(j,i)
313 {
314 if (fprintf(fXPMFile, " ") <= 0)
315 goto error;
316 }
317 else
318 if (fprintf(fXPMFile, "%.2X", COLOR(j,i)) <= 0)
319 goto error;
320 }
321 if (fprintf(fXPMFile, "\"") <= 0)
322 goto error;
323 }
324 if (fprintf(fXPMFile, "};\n") <= 0)
325 goto error;
326
327#undef MASK
328#undef COLOR
329
330 fclose(fXPMFile);
331 return 1;
332
333 error:
334 fclose(fXPMFile);
335 unlink( szXPMFileName );
336 return 0;
337}
338
339static BOOL CALLBACK EnumResNameProc(HANDLE hModule, const char *lpszType, char *lpszName, LONG lParam)
340{
341 *(HRSRC *) lParam = FindResourceA(hModule, lpszName, RT_GROUP_ICONA);
342 return FALSE;
343}
344
345static int ExtractFromEXEDLL(const char *szFileName, int nIndex, const char *szXPMFileName)
346{
347 HMODULE hModule;
348 HRSRC hResInfo;
349 char *lpName = NULL;
350 HGLOBAL hResData;
351 GRPICONDIR *pIconDir;
352 BITMAPINFO *pIcon;
353 int nMax = 0;
354 int i;
355
356 if (!(hModule = LoadLibraryExA(szFileName, 0, LOAD_LIBRARY_AS_DATAFILE)))
357 goto error1;
358
359 if (nIndex)
360 hResInfo = FindResourceA(hModule, MAKEINTRESOURCEA(nIndex), RT_GROUP_ICONA);
361 else
362 if (EnumResourceNamesA(hModule, RT_GROUP_ICONA, &EnumResNameProc, (LONG) &hResInfo))
363 goto error2;
364
365 if (!hResInfo)
366 goto error2;
367
368 if (!(hResData = LoadResource(hModule, hResInfo)))
369 goto error2;
370 if (!(pIconDir = LockResource(hResData)))
371 goto error3;
372
373 for (i = 0; i < pIconDir->idCount; i++)
374 if ((pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth) > nMax)
375 {
376 lpName = MAKEINTRESOURCEA(pIconDir->idEntries[i].nID);
377 nMax = pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth;
378 }
379
380 FreeResource(hResData);
381
382 if (!(hResInfo = FindResourceA(hModule, lpName, RT_ICONA)))
383 goto error2;
384 if (!(hResData = LoadResource(hModule, hResInfo)))
385 goto error2;
386 if (!(pIcon = LockResource(hResData)))
387 goto error3;
388
389 if(!SaveIconResAsXPM(pIcon, szXPMFileName))
390 goto error3;
391
392 FreeResource(hResData);
393 FreeLibrary(hModule);
394
395 return 1;
396
397 error3:
398 FreeResource(hResData);
399 error2:
400 FreeLibrary(hModule);
401 error1:
402 return 0;
403}
404
405static int ExtractFromICO(const char *szFileName, const char *szXPMFileName)
406{
407 FILE *fICOFile;
408 ICONDIR iconDir;
409 ICONDIRENTRY *pIconDirEntry;
410 int nMax = 0;
411 int nIndex = 0;
412 void *pIcon;
413 int i;
414
415 if (!(fICOFile = fopen(szFileName, "r")))
416 goto error1;
417
418 if (fread(&iconDir, sizeof (ICONDIR), 1, fICOFile) != 1)
419 goto error2;
420 if ((iconDir.idReserved != 0) || (iconDir.idType != 1))
421 goto error2;
422
423 if ((pIconDirEntry = malloc(iconDir.idCount * sizeof (ICONDIRENTRY))) == NULL)
424 goto error2;
425 if (fread(pIconDirEntry, sizeof (ICONDIRENTRY), iconDir.idCount, fICOFile) != iconDir.idCount)
426 goto error3;
427
428 for (i = 0; i < iconDir.idCount; i++)
429 if ((pIconDirEntry[i].bHeight * pIconDirEntry[i].bWidth) > nMax)
430 {
431 nIndex = i;
432 nMax = pIconDirEntry[i].bHeight * pIconDirEntry[i].bWidth;
433 }
434 if ((pIcon = malloc(pIconDirEntry[nIndex].dwBytesInRes)) == NULL)
435 goto error3;
436 if (fseek(fICOFile, pIconDirEntry[nIndex].dwImageOffset, SEEK_SET))
437 goto error4;
438 if (fread(pIcon, pIconDirEntry[nIndex].dwBytesInRes, 1, fICOFile) != 1)
439 goto error4;
440
441 if(!SaveIconResAsXPM(pIcon, szXPMFileName))
442 goto error4;
443
444 free(pIcon);
445 free(pIconDirEntry);
446 fclose(fICOFile);
447
448 return 1;
449
450 error4:
451 free(pIcon);
452 error3:
453 free(pIconDirEntry);
454 error2:
455 fclose(fICOFile);
456 error1:
457 return 0;
458}
459
460/* get the Unix file name for a given path, allocating the string */
461inline static char *get_unix_file_name( const char *dos )
462{
463 DOS_FULL_NAME path;
464
465 if (!DOSFS_GetFullName( dos, FALSE, &path )) return NULL;
466 return HEAP_strdupA( GetProcessHeap(), 0, path.long_name );
467}
468
469static BOOL create_default_icon( const char *filename )
470{
471 FILE *fXPM;
472 int i;
473
474 if (!(fXPM = fopen(filename, "w"))) return FALSE;
475 fprintf(fXPM, "/* XPM */\nstatic char * icon[] = {");
476 for (i = 0; i < sizeof(wine_xpm)/sizeof(wine_xpm[0]); i++)
477 fprintf( fXPM, "\n\"%s\",", wine_xpm[i]);
478 fprintf( fXPM, "};\n" );
479 fclose( fXPM );
480 return TRUE;
481}
482
483/* extract an icon from an exe or icon file; helper for IPersistFile_fnSave */
484static char *extract_icon( const char *path, int index )
485{
486 char *filename = HEAP_strdupA( GetProcessHeap(), 0, tmpnam(NULL) );
487 if (ExtractFromEXEDLL( path, index, filename )) return filename;
488 if (ExtractFromICO( path, filename )) return filename;
489 if (create_default_icon( filename )) return filename;
490 HeapFree( GetProcessHeap(), 0, filename );
491 return NULL;
492}
493#endif //#ifndef __WIN32OS2__
494
495
496static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFileName, BOOL fRemember)
497{
498 HRESULT ret = NOERROR;
499 int pid, status;
500 char buffer[MAX_PATH], buff2[MAX_PATH];
501 char *filename, *link_name, *p;
502 char *shell_link_app = NULL;
503 char *icon_name = NULL;
504 char *path_name = NULL;
505 char *work_dir = NULL;
506 BOOL bDesktop;
507
508 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
509
510 TRACE("(%p)->(%s)\n",This,debugstr_w(pszFileName));
511
512 if (!pszFileName || !This->sPath)
513 return ERROR_UNKNOWN;
514
515 /* check for .exe extension */
516 if (!(p = strrchr( This->sPath, '.' ))) return NOERROR;
517 if (strchr( p, '\\' ) || strchr( p, '/' )) return NOERROR;
518 if (strcasecmp( p, ".exe" )) return NOERROR;
519
520 /* check if ShellLinker configured */
521#ifdef __WIN32OS2__
522 return NOERROR;
523#else
524 PROFILE_GetWineIniString( "wine", "ShellLinker", "", buffer, sizeof(buffer) );
525 if (!*buffer) return NOERROR;
526 shell_link_app = HEAP_strdupA( GetProcessHeap(), 0, buffer );
527
528 if (!WideCharToMultiByte( CP_ACP, 0, pszFileName, -1, buffer, sizeof(buffer), NULL, NULL))
529 return ERROR_UNKNOWN;
530 GetFullPathNameA( buffer, sizeof(buff2), buff2, NULL );
531 filename = HEAP_strdupA( GetProcessHeap(), 0, buff2 );
532
533 if (SHGetSpecialFolderPathA( 0, buffer, CSIDL_STARTUP, FALSE ))
534 {
535 /* ignore startup for now */
536 if (!strncasecmp( filename, buffer, strlen(buffer) )) goto done;
537 }
538 if (SHGetSpecialFolderPathA( 0, buffer, CSIDL_DESKTOPDIRECTORY, FALSE ))
539 {
540 if (!strncasecmp( filename, buffer, strlen(buffer) ))
541 {
542 link_name = filename + strlen(buffer);
543 bDesktop = TRUE;
544 goto found;
545 }
546 }
547 if (SHGetSpecialFolderPathA( 0, buffer, CSIDL_STARTMENU, FALSE ))
548 {
549 if (!strncasecmp( filename, buffer, strlen(buffer) ))
550 {
551 link_name = filename + strlen(buffer);
552 bDesktop = FALSE;
553 goto found;
554 }
555 }
556 goto done;
557
558 found:
559 /* make link name a Unix name */
560 for (p = link_name; *p; p++) if (*p == '\\') *p = '/';
561 /* strip leading slashes */
562 while (*link_name == '/') link_name++;
563 /* remove extension */
564 if ((p = strrchr( link_name, '.' ))) *p = 0;
565
566 /* convert app path name */
567 path_name = get_unix_file_name( This->sPath );
568
569 /* convert app working dir */
570 if (This->sWorkDir) work_dir = get_unix_file_name( This->sWorkDir );
571
572 /* extract the icon */
573 if (!(icon_name = extract_icon( This->sIcoPath ? This->sIcoPath : This->sPath,
574 This->iIcoNdx ))) goto done;
575
576 TRACE("linker app='%s' link='%s' mode=%s path='%s' args='%s' icon='%s' workdir='%s' descr='%s'\n",
577 shell_link_app, link_name, bDesktop ? "desktop" : "menu", path_name,
578 This->sArgs ? This->sArgs : "", icon_name, work_dir ? work_dir : "",
579 This->sDescription ? This->sDescription : "" );
580
581 if ((pid = fork()) == -1) goto done;
582 if (!pid)
583 {
584 int pos = 0;
585 char *argv[20];
586 argv[pos++] = shell_link_app;
587 argv[pos++] = "--link";
588 argv[pos++] = link_name;
589 argv[pos++] = "--path";
590 argv[pos++] = path_name;
591 argv[pos++] = bDesktop ? "--desktop" : "--menu";
592 if (This->sArgs)
593 {
594 argv[pos++] = "--args";
595 argv[pos++] = This->sArgs;
596 }
597 if (icon_name)
598 {
599 argv[pos++] = "--icon";
600 argv[pos++] = icon_name;
601 }
602 if (This->sWorkDir)
603 {
604 argv[pos++] = "--workdir";
605 argv[pos++] = This->sWorkDir;
606 }
607 if (This->sDescription)
608 {
609 argv[pos++] = "--descr";
610 argv[pos++] = This->sDescription;
611 }
612 argv[pos] = NULL;
613 execvp( shell_link_app, argv );
614 _exit(1);
615 }
616
617 while (waitpid( pid, &status, 0 ) == -1)
618 {
619 if (errno != EINTR)
620 {
621 ret = ERROR_UNKNOWN;
622 goto done;
623 }
624 }
625 if (status) ret = E_ACCESSDENIED;
626
627 done:
628 if (icon_name) unlink( icon_name );
629 HeapFree( GetProcessHeap(), 0, shell_link_app );
630 HeapFree( GetProcessHeap(), 0, filename );
631 HeapFree( GetProcessHeap(), 0, icon_name );
632 HeapFree( GetProcessHeap(), 0, path_name );
633 HeapFree( GetProcessHeap(), 0, work_dir );
634 return ret;
635#endif //__WIN32OS2__
636}
637
638static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLESTR pszFileName)
639{
640 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
641 FIXME("(%p)->(%s)\n",This,debugstr_w(pszFileName));
642 return NOERROR;
643}
644static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *ppszFileName)
645{
646 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
647 FIXME("(%p)\n",This);
648 return NOERROR;
649}
650
651static ICOM_VTABLE(IPersistFile) pfvt =
652{
653 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
654 IPersistFile_fnQueryInterface,
655 IPersistFile_fnAddRef,
656 IPersistFile_fnRelease,
657 IPersistFile_fnGetClassID,
658 IPersistFile_fnIsDirty,
659 IPersistFile_fnLoad,
660 IPersistFile_fnSave,
661 IPersistFile_fnSaveCompleted,
662 IPersistFile_fnGetCurFile
663};
664
665/************************************************************************
666 * IPersistStream_QueryInterface
667 */
668static HRESULT WINAPI IPersistStream_fnQueryInterface(
669 IPersistStream* iface,
670 REFIID riid,
671 VOID** ppvoid)
672{
673 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
674
675 TRACE("(%p)\n",This);
676
677 return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvoid);
678}
679
680/************************************************************************
681 * IPersistStream_Release
682 */
683static ULONG WINAPI IPersistStream_fnRelease(
684 IPersistStream* iface)
685{
686 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
687
688 TRACE("(%p)\n",This);
689
690 return IShellLinkA_Release((IShellLinkA*)This);
691}
692
693/************************************************************************
694 * IPersistStream_AddRef
695 */
696static ULONG WINAPI IPersistStream_fnAddRef(
697 IPersistStream* iface)
698{
699 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
700
701 TRACE("(%p)\n",This);
702
703 return IShellLinkA_AddRef((IShellLinkA*)This);
704}
705
706/************************************************************************
707 * IPersistStream_GetClassID
708 *
709 */
710static HRESULT WINAPI IPersistStream_fnGetClassID(
711 IPersistStream* iface,
712 CLSID* pClassID)
713{
714 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
715
716 TRACE("(%p)\n", This);
717
718 if (pClassID==0)
719 return E_POINTER;
720
721/* memcpy(pClassID, &CLSID_???, sizeof(CLSID_???)); */
722
723 return S_OK;
724}
725
726/************************************************************************
727 * IPersistStream_IsDirty (IPersistStream)
728 */
729static HRESULT WINAPI IPersistStream_fnIsDirty(
730 IPersistStream* iface)
731{
732 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
733
734 TRACE("(%p)\n", This);
735
736 return S_OK;
737}
738/************************************************************************
739 * IPersistStream_Load (IPersistStream)
740 */
741
742static HRESULT WINAPI IPersistStream_fnLoad(
743 IPersistStream* iface,
744 IStream* pLoadStream)
745{
746 PLINK_HEADER lpLinkHeader = HeapAlloc(GetProcessHeap(), 0, LINK_HEADER_SIZE);
747 ULONG dwBytesRead;
748 DWORD ret = E_FAIL;
749 char sTemp[MAX_PATH];
750
751 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
752
753 TRACE("(%p)(%p)\n", This, pLoadStream);
754
755 if ( ! pLoadStream)
756 {
757 return STG_E_INVALIDPOINTER;
758 }
759
760 IStream_AddRef (pLoadStream);
761 if(lpLinkHeader)
762 {
763 if (SUCCEEDED(IStream_Read(pLoadStream, lpLinkHeader, LINK_HEADER_SIZE, &dwBytesRead)))
764 {
765 if ((lpLinkHeader->MagicStr == 0x0000004CL) && IsEqualIID(&lpLinkHeader->MagicGuid, &CLSID_ShellLink))
766 {
767 lpLinkHeader = HeapReAlloc(GetProcessHeap(), 0, lpLinkHeader, LINK_HEADER_SIZE+lpLinkHeader->PidlSize);
768 if (lpLinkHeader)
769 {
770 if (SUCCEEDED(IStream_Read(pLoadStream, &(lpLinkHeader->Pidl), lpLinkHeader->PidlSize, &dwBytesRead)))
771 {
772 if (pcheck (&lpLinkHeader->Pidl))
773 {
774 This->pPidl = ILClone (&lpLinkHeader->Pidl);
775
776 SHGetPathFromIDListA(&lpLinkHeader->Pidl, sTemp);
777 This->sPath = HEAP_strdupA ( GetProcessHeap(), 0, sTemp);
778 }
779 This->wHotKey = lpLinkHeader->wHotKey;
780 FileTimeToSystemTime (&lpLinkHeader->Time1, &This->time1);
781 FileTimeToSystemTime (&lpLinkHeader->Time2, &This->time2);
782 FileTimeToSystemTime (&lpLinkHeader->Time3, &This->time3);
783#if 1
784 GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time1, NULL, sTemp, 256);
785 TRACE("-- time1: %s\n", sTemp);
786 GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time2, NULL, sTemp, 256);
787 TRACE("-- time1: %s\n", sTemp);
788 GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time3, NULL, sTemp, 256);
789 TRACE("-- time1: %s\n", sTemp);
790 pdump (This->pPidl);
791#endif
792 ret = S_OK;
793 }
794 }
795 }
796 else
797 {
798 WARN("stream contains no link!\n");
799 }
800 }
801 }
802
803 IStream_Release (pLoadStream);
804
805 pdump(This->pPidl);
806
807 HeapFree(GetProcessHeap(), 0, lpLinkHeader);
808
809 return ret;
810}
811
812/************************************************************************
813 * IPersistStream_Save (IPersistStream)
814 */
815static HRESULT WINAPI IPersistStream_fnSave(
816 IPersistStream* iface,
817 IStream* pOutStream,
818 BOOL fClearDirty)
819{
820 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
821
822 TRACE("(%p) %p %x\n", This, pOutStream, fClearDirty);
823
824 return E_NOTIMPL;
825}
826
827/************************************************************************
828 * IPersistStream_GetSizeMax (IPersistStream)
829 */
830static HRESULT WINAPI IPersistStream_fnGetSizeMax(
831 IPersistStream* iface,
832 ULARGE_INTEGER* pcbSize)
833{
834 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
835
836 TRACE("(%p)\n", This);
837
838 return E_NOTIMPL;
839}
840
841static ICOM_VTABLE(IPersistStream) psvt =
842{
843 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
844 IPersistStream_fnQueryInterface,
845 IPersistStream_fnAddRef,
846 IPersistStream_fnRelease,
847 IPersistStream_fnGetClassID,
848 IPersistStream_fnIsDirty,
849 IPersistStream_fnLoad,
850 IPersistStream_fnSave,
851 IPersistStream_fnGetSizeMax
852};
853
854/**************************************************************************
855 * IShellLink_Constructor
856 */
857IShellLinkA * IShellLink_Constructor(BOOL bUnicode)
858{ IShellLinkImpl * sl;
859
860 sl = (IShellLinkImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellLinkImpl));
861 sl->ref = 1;
862 ICOM_VTBL(sl) = &slvt;
863 sl->lpvtblw = &slvtw;
864 sl->lpvtblPersistFile = &pfvt;
865 sl->lpvtblPersistStream = &psvt;
866
867 TRACE("(%p)->()\n",sl);
868 shell32_ObjCount++;
869 return bUnicode ? (IShellLinkA *) &(sl->lpvtblw) : (IShellLinkA *)sl;
870}
871
872/**************************************************************************
873 * IShellLinkA_QueryInterface
874 */
875static HRESULT WINAPI IShellLinkA_fnQueryInterface( IShellLinkA * iface, REFIID riid, LPVOID *ppvObj)
876{
877 ICOM_THIS(IShellLinkImpl, iface);
878
879 TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
880
881 *ppvObj = NULL;
882
883 if(IsEqualIID(riid, &IID_IUnknown) ||
884 IsEqualIID(riid, &IID_IShellLinkA))
885 {
886 *ppvObj = This;
887 }
888 else if(IsEqualIID(riid, &IID_IShellLinkW))
889 {
890 *ppvObj = (IShellLinkW *)&(This->lpvtblw);
891 }
892 else if(IsEqualIID(riid, &IID_IPersistFile))
893 {
894 *ppvObj = (IPersistFile *)&(This->lpvtblPersistFile);
895 }
896 else if(IsEqualIID(riid, &IID_IPersistStream))
897 {
898 *ppvObj = (IPersistStream *)&(This->lpvtblPersistStream);
899 }
900
901 if(*ppvObj)
902 {
903 IUnknown_AddRef((IUnknown*)(*ppvObj));
904 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
905 return S_OK;
906 }
907 TRACE("-- Interface: E_NOINTERFACE\n");
908 return E_NOINTERFACE;
909}
910/******************************************************************************
911 * IShellLinkA_AddRef
912 */
913static ULONG WINAPI IShellLinkA_fnAddRef(IShellLinkA * iface)
914{
915 ICOM_THIS(IShellLinkImpl, iface);
916
917 TRACE("(%p)->(count=%lu)\n",This,This->ref);
918
919 shell32_ObjCount++;
920 return ++(This->ref);
921}
922/******************************************************************************
923 * IShellLinkA_Release
924 */
925static ULONG WINAPI IShellLinkA_fnRelease(IShellLinkA * iface)
926{
927 ICOM_THIS(IShellLinkImpl, iface);
928
929 TRACE("(%p)->(count=%lu)\n",This,This->ref);
930
931 shell32_ObjCount--;
932 if (!--(This->ref))
933 { TRACE("-- destroying IShellLink(%p)\n",This);
934
935 if (This->sIcoPath)
936 HeapFree(GetProcessHeap(), 0, This->sIcoPath);
937
938 if (This->sArgs)
939 HeapFree(GetProcessHeap(), 0, This->sArgs);
940
941 if (This->sWorkDir)
942 HeapFree(GetProcessHeap(), 0, This->sWorkDir);
943
944 if (This->sDescription)
945 HeapFree(GetProcessHeap(), 0, This->sDescription);
946
947 if (This->sPath)
948 HeapFree(GetProcessHeap(),0,This->sPath);
949
950 if (This->pPidl)
951 SHFree(This->pPidl);
952
953 if (This->lpFileStream)
954 IStream_Release(This->lpFileStream);
955
956 This->iIcoNdx = 0;
957
958 HeapFree(GetProcessHeap(),0,This);
959 return 0;
960 }
961 return This->ref;
962}
963
964static HRESULT WINAPI IShellLinkA_fnGetPath(IShellLinkA * iface, LPSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
965{
966 ICOM_THIS(IShellLinkImpl, iface);
967
968 TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)(%s)\n",This, pszFile, cchMaxPath, pfd, fFlags, debugstr_a(This->sPath));
969
970 if (This->sPath)
971 lstrcpynA(pszFile,This->sPath, cchMaxPath);
972 else
973 return E_FAIL;
974
975 return NOERROR;
976}
977static HRESULT WINAPI IShellLinkA_fnGetIDList(IShellLinkA * iface, LPITEMIDLIST * ppidl)
978{
979 ICOM_THIS(IShellLinkImpl, iface);
980
981 TRACE("(%p)->(ppidl=%p)\n",This, ppidl);
982
983 *ppidl = ILClone(This->pPidl);
984 return NOERROR;
985}
986static HRESULT WINAPI IShellLinkA_fnSetIDList(IShellLinkA * iface, LPCITEMIDLIST pidl)
987{
988 ICOM_THIS(IShellLinkImpl, iface);
989
990 TRACE("(%p)->(pidl=%p)\n",This, pidl);
991
992 if (This->pPidl)
993 SHFree(This->pPidl);
994 This->pPidl = ILClone (pidl);
995 return NOERROR;
996}
997static HRESULT WINAPI IShellLinkA_fnGetDescription(IShellLinkA * iface, LPSTR pszName,INT cchMaxName)
998{
999 ICOM_THIS(IShellLinkImpl, iface);
1000
1001 FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
1002 lstrcpynA(pszName,"Description, FIXME",cchMaxName);
1003 return NOERROR;
1004}
1005static HRESULT WINAPI IShellLinkA_fnSetDescription(IShellLinkA * iface, LPCSTR pszName)
1006{
1007 ICOM_THIS(IShellLinkImpl, iface);
1008
1009 TRACE("(%p)->(pName=%s)\n", This, pszName);
1010
1011 if (This->sDescription)
1012 HeapFree(GetProcessHeap(), 0, This->sDescription);
1013 if (!(This->sDescription = HEAP_strdupA(GetProcessHeap(), 0, pszName)))
1014 return E_OUTOFMEMORY;
1015
1016 return NOERROR;
1017}
1018static HRESULT WINAPI IShellLinkA_fnGetWorkingDirectory(IShellLinkA * iface, LPSTR pszDir,INT cchMaxPath)
1019{
1020 ICOM_THIS(IShellLinkImpl, iface);
1021
1022 FIXME("(%p)->()\n",This);
1023 lstrcpynA(pszDir,"c:\\", cchMaxPath);
1024 return NOERROR;
1025}
1026static HRESULT WINAPI IShellLinkA_fnSetWorkingDirectory(IShellLinkA * iface, LPCSTR pszDir)
1027{
1028 ICOM_THIS(IShellLinkImpl, iface);
1029
1030 TRACE("(%p)->(dir=%s)\n",This, pszDir);
1031
1032 if (This->sWorkDir)
1033 HeapFree(GetProcessHeap(), 0, This->sWorkDir);
1034 if (!(This->sWorkDir = HEAP_strdupA(GetProcessHeap(), 0, pszDir)))
1035 return E_OUTOFMEMORY;
1036
1037 return NOERROR;
1038}
1039static HRESULT WINAPI IShellLinkA_fnGetArguments(IShellLinkA * iface, LPSTR pszArgs,INT cchMaxPath)
1040{
1041 ICOM_THIS(IShellLinkImpl, iface);
1042
1043 FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
1044 lstrcpynA(pszArgs, "", cchMaxPath);
1045 return NOERROR;
1046}
1047static HRESULT WINAPI IShellLinkA_fnSetArguments(IShellLinkA * iface, LPCSTR pszArgs)
1048{
1049 ICOM_THIS(IShellLinkImpl, iface);
1050
1051 TRACE("(%p)->(args=%s)\n",This, pszArgs);
1052
1053 if (This->sArgs)
1054 HeapFree(GetProcessHeap(), 0, This->sArgs);
1055 if (!(This->sArgs = HEAP_strdupA(GetProcessHeap(), 0, pszArgs)))
1056 return E_OUTOFMEMORY;
1057
1058 return NOERROR;
1059}
1060static HRESULT WINAPI IShellLinkA_fnGetHotkey(IShellLinkA * iface, WORD *pwHotkey)
1061{
1062 ICOM_THIS(IShellLinkImpl, iface);
1063
1064 TRACE("(%p)->(%p)(0x%08x)\n",This, pwHotkey, This->wHotKey);
1065
1066 *pwHotkey = This->wHotKey;
1067
1068 return NOERROR;
1069}
1070static HRESULT WINAPI IShellLinkA_fnSetHotkey(IShellLinkA * iface, WORD wHotkey)
1071{
1072 ICOM_THIS(IShellLinkImpl, iface);
1073
1074 TRACE("(%p)->(hotkey=%x)\n",This, wHotkey);
1075
1076 This->wHotKey = wHotkey;
1077
1078 return NOERROR;
1079}
1080static HRESULT WINAPI IShellLinkA_fnGetShowCmd(IShellLinkA * iface, INT *piShowCmd)
1081{
1082 ICOM_THIS(IShellLinkImpl, iface);
1083
1084 FIXME("(%p)->(%p)\n",This, piShowCmd);
1085 *piShowCmd=0;
1086 return NOERROR;
1087}
1088static HRESULT WINAPI IShellLinkA_fnSetShowCmd(IShellLinkA * iface, INT iShowCmd)
1089{
1090 ICOM_THIS(IShellLinkImpl, iface);
1091
1092 FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
1093 return NOERROR;
1094}
1095static HRESULT WINAPI IShellLinkA_fnGetIconLocation(IShellLinkA * iface, LPSTR pszIconPath,INT cchIconPath,INT *piIcon)
1096{
1097 ICOM_THIS(IShellLinkImpl, iface);
1098
1099 FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
1100 lstrcpynA(pszIconPath,"shell32.dll",cchIconPath);
1101 *piIcon=1;
1102 return NOERROR;
1103}
1104static HRESULT WINAPI IShellLinkA_fnSetIconLocation(IShellLinkA * iface, LPCSTR pszIconPath,INT iIcon)
1105{
1106 ICOM_THIS(IShellLinkImpl, iface);
1107
1108 TRACE("(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
1109
1110 if (This->sIcoPath)
1111 HeapFree(GetProcessHeap(), 0, This->sIcoPath);
1112 if (!(This->sIcoPath = HEAP_strdupA(GetProcessHeap(), 0, pszIconPath)))
1113 return E_OUTOFMEMORY;
1114 This->iIcoNdx = iIcon;
1115
1116 return NOERROR;
1117}
1118static HRESULT WINAPI IShellLinkA_fnSetRelativePath(IShellLinkA * iface, LPCSTR pszPathRel, DWORD dwReserved)
1119{
1120 ICOM_THIS(IShellLinkImpl, iface);
1121
1122 FIXME("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
1123 return NOERROR;
1124}
1125static HRESULT WINAPI IShellLinkA_fnResolve(IShellLinkA * iface, HWND hwnd, DWORD fFlags)
1126{
1127 ICOM_THIS(IShellLinkImpl, iface);
1128
1129 FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
1130 return NOERROR;
1131}
1132static HRESULT WINAPI IShellLinkA_fnSetPath(IShellLinkA * iface, LPCSTR pszFile)
1133{
1134 ICOM_THIS(IShellLinkImpl, iface);
1135
1136 TRACE("(%p)->(path=%s)\n",This, pszFile);
1137
1138 if (This->sPath)
1139 HeapFree(GetProcessHeap(), 0, This->sPath);
1140 if (!(This->sPath = HEAP_strdupA(GetProcessHeap(), 0, pszFile)))
1141 return E_OUTOFMEMORY;
1142
1143 return NOERROR;
1144}
1145
1146/**************************************************************************
1147* IShellLink Implementation
1148*/
1149
1150static ICOM_VTABLE(IShellLinkA) slvt =
1151{
1152 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1153 IShellLinkA_fnQueryInterface,
1154 IShellLinkA_fnAddRef,
1155 IShellLinkA_fnRelease,
1156 IShellLinkA_fnGetPath,
1157 IShellLinkA_fnGetIDList,
1158 IShellLinkA_fnSetIDList,
1159 IShellLinkA_fnGetDescription,
1160 IShellLinkA_fnSetDescription,
1161 IShellLinkA_fnGetWorkingDirectory,
1162 IShellLinkA_fnSetWorkingDirectory,
1163 IShellLinkA_fnGetArguments,
1164 IShellLinkA_fnSetArguments,
1165 IShellLinkA_fnGetHotkey,
1166 IShellLinkA_fnSetHotkey,
1167 IShellLinkA_fnGetShowCmd,
1168 IShellLinkA_fnSetShowCmd,
1169 IShellLinkA_fnGetIconLocation,
1170 IShellLinkA_fnSetIconLocation,
1171 IShellLinkA_fnSetRelativePath,
1172 IShellLinkA_fnResolve,
1173 IShellLinkA_fnSetPath
1174};
1175
1176
1177/**************************************************************************
1178 * IShellLinkW_fnQueryInterface
1179 */
1180static HRESULT WINAPI IShellLinkW_fnQueryInterface(
1181 IShellLinkW * iface, REFIID riid, LPVOID *ppvObj)
1182{
1183 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1184
1185 return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObj);
1186}
1187
1188/******************************************************************************
1189 * IShellLinkW_fnAddRef
1190 */
1191static ULONG WINAPI IShellLinkW_fnAddRef(IShellLinkW * iface)
1192{
1193 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1194
1195 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1196
1197 return IShellLinkA_AddRef((IShellLinkA*)This);
1198}
1199/******************************************************************************
1200 * IShellLinkW_fnRelease
1201 */
1202
1203static ULONG WINAPI IShellLinkW_fnRelease(IShellLinkW * iface)
1204{
1205 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1206
1207 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1208
1209 return IShellLinkA_Release((IShellLinkA*)This);
1210}
1211
1212static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
1213{
1214 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1215
1216 FIXME("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
1217 lstrcpynAtoW(pszFile,"c:\\foo.bar", cchMaxPath);
1218 return NOERROR;
1219}
1220
1221static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST * ppidl)
1222{
1223 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1224
1225 FIXME("(%p)->(ppidl=%p)\n",This, ppidl);
1226 *ppidl = _ILCreateDesktop();
1227 return NOERROR;
1228}
1229
1230static HRESULT WINAPI IShellLinkW_fnSetIDList(IShellLinkW * iface, LPCITEMIDLIST pidl)
1231{
1232 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1233
1234 FIXME("(%p)->(pidl=%p)\n",This, pidl);
1235 return NOERROR;
1236}
1237
1238static HRESULT WINAPI IShellLinkW_fnGetDescription(IShellLinkW * iface, LPWSTR pszName,INT cchMaxName)
1239{
1240 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1241
1242 FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
1243 lstrcpynAtoW(pszName,"Description, FIXME",cchMaxName);
1244 return NOERROR;
1245}
1246
1247static HRESULT WINAPI IShellLinkW_fnSetDescription(IShellLinkW * iface, LPCWSTR pszName)
1248{
1249 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1250
1251 TRACE("(%p)->(desc=%s)\n",This, debugstr_w(pszName));
1252
1253 if (This->sDescription)
1254 HeapFree(GetProcessHeap(), 0, This->sDescription);
1255 if (!(This->sDescription = HEAP_strdupWtoA(GetProcessHeap(), 0, pszName)))
1256 return E_OUTOFMEMORY;
1257
1258 return NOERROR;
1259}
1260
1261static HRESULT WINAPI IShellLinkW_fnGetWorkingDirectory(IShellLinkW * iface, LPWSTR pszDir,INT cchMaxPath)
1262{
1263 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1264
1265 FIXME("(%p)->()\n",This);
1266 lstrcpynAtoW(pszDir,"c:\\", cchMaxPath);
1267 return NOERROR;
1268}
1269
1270static HRESULT WINAPI IShellLinkW_fnSetWorkingDirectory(IShellLinkW * iface, LPCWSTR pszDir)
1271{
1272 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1273
1274 TRACE("(%p)->(dir=%s)\n",This, debugstr_w(pszDir));
1275
1276 if (This->sWorkDir)
1277 HeapFree(GetProcessHeap(), 0, This->sWorkDir);
1278 if (!(This->sWorkDir = HEAP_strdupWtoA(GetProcessHeap(), 0, pszDir)))
1279 return E_OUTOFMEMORY;
1280
1281 return NOERROR;
1282}
1283
1284static HRESULT WINAPI IShellLinkW_fnGetArguments(IShellLinkW * iface, LPWSTR pszArgs,INT cchMaxPath)
1285{
1286 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1287
1288 FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
1289 lstrcpynAtoW(pszArgs, "", cchMaxPath);
1290 return NOERROR;
1291}
1292
1293static HRESULT WINAPI IShellLinkW_fnSetArguments(IShellLinkW * iface, LPCWSTR pszArgs)
1294{
1295 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1296
1297 TRACE("(%p)->(args=%s)\n",This, debugstr_w(pszArgs));
1298
1299 if (This->sArgs)
1300 HeapFree(GetProcessHeap(), 0, This->sArgs);
1301 if (!(This->sArgs = HEAP_strdupWtoA(GetProcessHeap(), 0, pszArgs)))
1302 return E_OUTOFMEMORY;
1303
1304 return NOERROR;
1305}
1306
1307static HRESULT WINAPI IShellLinkW_fnGetHotkey(IShellLinkW * iface, WORD *pwHotkey)
1308{
1309 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1310
1311 FIXME("(%p)->(%p)\n",This, pwHotkey);
1312 *pwHotkey=0x0;
1313 return NOERROR;
1314}
1315
1316static HRESULT WINAPI IShellLinkW_fnSetHotkey(IShellLinkW * iface, WORD wHotkey)
1317{
1318 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1319
1320 FIXME("(%p)->(hotkey=%x)\n",This, wHotkey);
1321 return NOERROR;
1322}
1323
1324static HRESULT WINAPI IShellLinkW_fnGetShowCmd(IShellLinkW * iface, INT *piShowCmd)
1325{
1326 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1327
1328 FIXME("(%p)->(%p)\n",This, piShowCmd);
1329 *piShowCmd=0;
1330 return NOERROR;
1331}
1332
1333static HRESULT WINAPI IShellLinkW_fnSetShowCmd(IShellLinkW * iface, INT iShowCmd)
1334{
1335 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1336
1337 FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
1338 return NOERROR;
1339}
1340
1341static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR pszIconPath,INT cchIconPath,INT *piIcon)
1342{
1343 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1344
1345 FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
1346 lstrcpynAtoW(pszIconPath,"shell32.dll",cchIconPath);
1347 *piIcon=1;
1348 return NOERROR;
1349}
1350
1351static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
1352{
1353 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1354
1355 TRACE("(%p)->(path=%s iicon=%u)\n",This, debugstr_w(pszIconPath), iIcon);
1356
1357 if (This->sIcoPath)
1358 HeapFree(GetProcessHeap(), 0, This->sIcoPath);
1359 if (!(This->sIcoPath = HEAP_strdupWtoA(GetProcessHeap(), 0, pszIconPath)))
1360 return E_OUTOFMEMORY;
1361 This->iIcoNdx = iIcon;
1362
1363 return NOERROR;
1364}
1365
1366static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR pszPathRel, DWORD dwReserved)
1367{
1368 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1369
1370 FIXME("(%p)->(path=%s %lx)\n",This, debugstr_w(pszPathRel), dwReserved);
1371 return NOERROR;
1372}
1373
1374static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags)
1375{
1376 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1377
1378 FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
1379 return NOERROR;
1380}
1381
1382static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
1383{
1384 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1385
1386 TRACE("(%p)->(path=%s)\n",This, debugstr_w(pszFile));
1387
1388 if (This->sPath)
1389 HeapFree(GetProcessHeap(), 0, This->sPath);
1390 if (!(This->sPath = HEAP_strdupWtoA(GetProcessHeap(), 0, pszFile)))
1391 return E_OUTOFMEMORY;
1392
1393 return NOERROR;
1394}
1395
1396/**************************************************************************
1397* IShellLinkW Implementation
1398*/
1399
1400static ICOM_VTABLE(IShellLinkW) slvtw =
1401{
1402 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1403 IShellLinkW_fnQueryInterface,
1404 IShellLinkW_fnAddRef,
1405 IShellLinkW_fnRelease,
1406 IShellLinkW_fnGetPath,
1407 IShellLinkW_fnGetIDList,
1408 IShellLinkW_fnSetIDList,
1409 IShellLinkW_fnGetDescription,
1410 IShellLinkW_fnSetDescription,
1411 IShellLinkW_fnGetWorkingDirectory,
1412 IShellLinkW_fnSetWorkingDirectory,
1413 IShellLinkW_fnGetArguments,
1414 IShellLinkW_fnSetArguments,
1415 IShellLinkW_fnGetHotkey,
1416 IShellLinkW_fnSetHotkey,
1417 IShellLinkW_fnGetShowCmd,
1418 IShellLinkW_fnSetShowCmd,
1419 IShellLinkW_fnGetIconLocation,
1420 IShellLinkW_fnSetIconLocation,
1421 IShellLinkW_fnSetRelativePath,
1422 IShellLinkW_fnResolve,
1423 IShellLinkW_fnSetPath
1424};
1425
Note: See TracBrowser for help on using the repository browser.