Finished separation of shell32 and wsock32.
[wine/multimedia.git] / dlls / shell32 / shelllink.c
blob75549b0bc21e1486510009627d43fef0a61ee7f0
1 /*
3 * Copyright 1997 Marcus Meissner
4 * Copyright 1998 Juergen Schmied
6 */
8 #include "config.h"
10 #include <string.h>
11 #include <sys/stat.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #ifdef HAVE_SYS_WAIT_H
16 # include <sys/wait.h>
17 #endif
18 #include "debugtools.h"
19 #include "winerror.h"
20 #include "winbase.h"
21 #include "winnls.h"
22 #include "winreg.h"
24 #include "shlobj.h"
25 #include "wine/undocshell.h"
26 #include "bitmaps/wine.xpm"
28 #include "heap.h"
29 #include "pidl.h"
30 #include "shell32_main.h"
31 #include "shlguid.h"
33 DEFAULT_DEBUG_CHANNEL(shell);
35 /* link file formats */
37 #include "pshpack1.h"
39 /* flag1: lnk elements: simple link has 0x0B */
40 #define WORKDIR 0x10
41 #define ARGUMENT 0x20
42 #define ICON 0x40
43 #define UNC 0x80
45 /* fStartup */
46 #define NORMAL 0x01
47 #define MAXIMIZED 0x03
48 #define MINIMIZED 0x07
50 typedef struct _LINK_HEADER
51 { DWORD MagicStr; /* 0x00 'L','\0','\0','\0' */
52 GUID MagicGuid; /* 0x04 is CLSID_ShellLink */
53 DWORD Flag1; /* 0x14 describes elements following */
54 DWORD Flag2; /* 0x18 */
55 FILETIME Time1; /* 0x1c */
56 FILETIME Time2; /* 0x24 */
57 FILETIME Time3; /* 0x2c */
58 DWORD Unknown1; /* 0x34 */
59 DWORD Unknown2; /* 0x38 icon number */
60 DWORD fStartup; /* 0x3c startup type */
61 DWORD wHotKey; /* 0x40 hotkey */
62 DWORD Unknown5; /* 0x44 */
63 DWORD Unknown6; /* 0x48 */
64 USHORT PidlSize; /* 0x4c */
65 ITEMIDLIST Pidl; /* 0x4e */
66 } LINK_HEADER, * PLINK_HEADER;
68 #define LINK_HEADER_SIZE (sizeof(LINK_HEADER)-sizeof(ITEMIDLIST))
70 typedef struct
72 BYTE bWidth;
73 BYTE bHeight;
74 BYTE bColorCount;
75 BYTE bReserved;
76 WORD wPlanes;
77 WORD wBitCount;
78 DWORD dwBytesInRes;
79 WORD nID;
80 } GRPICONDIRENTRY;
82 typedef struct
84 WORD idReserved;
85 WORD idType;
86 WORD idCount;
87 GRPICONDIRENTRY idEntries[1];
88 } GRPICONDIR;
90 typedef struct
92 BYTE bWidth;
93 BYTE bHeight;
94 BYTE bColorCount;
95 BYTE bReserved;
96 WORD wPlanes;
97 WORD wBitCount;
98 DWORD dwBytesInRes;
99 DWORD dwImageOffset;
100 } ICONDIRENTRY;
102 typedef struct
104 WORD idReserved;
105 WORD idType;
106 WORD idCount;
107 } ICONDIR;
110 #include "poppack.h"
113 static ICOM_VTABLE(IShellLinkA) slvt;
114 static ICOM_VTABLE(IShellLinkW) slvtw;
115 static ICOM_VTABLE(IPersistFile) pfvt;
116 static ICOM_VTABLE(IPersistStream) psvt;
118 /* IShellLink Implementation */
120 typedef struct
122 ICOM_VFIELD(IShellLinkA);
123 DWORD ref;
125 ICOM_VTABLE(IShellLinkW)* lpvtblw;
126 ICOM_VTABLE(IPersistFile)* lpvtblPersistFile;
127 ICOM_VTABLE(IPersistStream)* lpvtblPersistStream;
129 /* internal stream of the IPersistFile interface */
130 IStream* lpFileStream;
132 /* data structures according to the informations in the lnk */
133 LPSTR sPath;
134 LPITEMIDLIST pPidl;
135 WORD wHotKey;
136 SYSTEMTIME time1;
137 SYSTEMTIME time2;
138 SYSTEMTIME time3;
140 LPSTR sIcoPath;
141 INT iIcoNdx;
142 LPSTR sArgs;
143 LPSTR sWorkDir;
144 LPSTR sDescription;
145 } IShellLinkImpl;
147 #define _IShellLinkW_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblw)))
148 #define _ICOM_THIS_From_IShellLinkW(class, name) class* This = (class*)(((char*)name)-_IShellLinkW_Offset);
150 #define _IPersistFile_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistFile)))
151 #define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((char*)name)-_IPersistFile_Offset);
153 #define _IPersistStream_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistStream)))
154 #define _ICOM_THIS_From_IPersistStream(class, name) class* This = (class*)(((char*)name)-_IPersistStream_Offset);
155 #define _IPersistStream_From_ICOM_THIS(class, name) class* StreamThis = (class*)(((char*)name)+_IPersistStream_Offset);
157 /**************************************************************************
158 * IPersistFile_QueryInterface
160 static HRESULT WINAPI IPersistFile_fnQueryInterface(
161 IPersistFile* iface,
162 REFIID riid,
163 LPVOID *ppvObj)
165 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
167 TRACE("(%p)\n",This);
169 return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObj);
172 /******************************************************************************
173 * IPersistFile_AddRef
175 static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile* iface)
177 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
179 TRACE("(%p)->(count=%lu)\n",This,This->ref);
181 return IShellLinkA_AddRef((IShellLinkA*)This);
183 /******************************************************************************
184 * IPersistFile_Release
186 static ULONG WINAPI IPersistFile_fnRelease(IPersistFile* iface)
188 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
190 TRACE("(%p)->(count=%lu)\n",This,This->ref);
192 return IShellLinkA_Release((IShellLinkA*)This);
195 static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile* iface, CLSID *pClassID)
197 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
198 FIXME("(%p)\n",This);
199 return NOERROR;
201 static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile* iface)
203 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
204 FIXME("(%p)\n",This);
205 return NOERROR;
207 static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode)
209 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface)
210 _IPersistStream_From_ICOM_THIS(IPersistStream, This)
212 LPSTR sFile = HEAP_strdupWtoA ( GetProcessHeap(), 0, pszFileName);
213 HRESULT hRet = E_FAIL;
215 TRACE("(%p, %s)\n",This, sFile);
218 if (This->lpFileStream)
219 IStream_Release(This->lpFileStream);
221 if SUCCEEDED(CreateStreamOnFile(sFile, &(This->lpFileStream)))
223 if SUCCEEDED (IPersistStream_Load(StreamThis, This->lpFileStream))
225 return NOERROR;
229 return hRet;
233 /* Icon extraction routines
235 * FIXME: should use PrivateExtractIcons and friends
236 * FIXME: should not use stdio
239 static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName)
241 FILE *fXPMFile;
242 int nHeight;
243 int nXORWidthBytes;
244 int nANDWidthBytes;
245 BOOL b8BitColors;
246 int nColors;
247 BYTE *pXOR;
248 BYTE *pAND;
249 BOOL aColorUsed[256] = {0};
250 int nColorsUsed = 0;
251 int i,j;
253 if (!((pIcon->bmiHeader.biBitCount == 4) || (pIcon->bmiHeader.biBitCount == 8)))
254 return 0;
256 if (!(fXPMFile = fopen(szXPMFileName, "w")))
257 return 0;
259 nHeight = pIcon->bmiHeader.biHeight / 2;
260 nXORWidthBytes = 4 * ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount / 32)
261 + ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount % 32) > 0));
262 nANDWidthBytes = 4 * ((pIcon->bmiHeader.biWidth / 32)
263 + ((pIcon->bmiHeader.biWidth % 32) > 0));
264 b8BitColors = pIcon->bmiHeader.biBitCount == 8;
265 nColors = pIcon->bmiHeader.biClrUsed ? pIcon->bmiHeader.biClrUsed
266 : 1 << pIcon->bmiHeader.biBitCount;
267 pXOR = (BYTE*) pIcon + sizeof (BITMAPINFOHEADER) + (nColors * sizeof (RGBQUAD));
268 pAND = pXOR + nHeight * nXORWidthBytes;
270 #define MASK(x,y) (pAND[(x) / 8 + (nHeight - (y) - 1) * nANDWidthBytes] & (1 << (7 - (x) % 8)))
271 #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)
273 for (i = 0; i < nHeight; i++)
274 for (j = 0; j < pIcon->bmiHeader.biWidth; j++)
275 if (!aColorUsed[COLOR(j,i)] && !MASK(j,i))
277 aColorUsed[COLOR(j,i)] = TRUE;
278 nColorsUsed++;
281 if (fprintf(fXPMFile, "/* XPM */\nstatic char *icon[] = {\n") <= 0)
282 goto error;
283 if (fprintf(fXPMFile, "\"%d %d %d %d\",\n",
284 (int) pIcon->bmiHeader.biWidth, nHeight, nColorsUsed + 1, 2) <=0)
285 goto error;
287 for (i = 0; i < nColors; i++)
288 if (aColorUsed[i])
289 if (fprintf(fXPMFile, "\"%.2X c #%.2X%.2X%.2X\",\n", i, pIcon->bmiColors[i].rgbRed,
290 pIcon->bmiColors[i].rgbGreen, pIcon->bmiColors[i].rgbBlue) <= 0)
291 goto error;
292 if (fprintf(fXPMFile, "\" c None\"") <= 0)
293 goto error;
295 for (i = 0; i < nHeight; i++)
297 if (fprintf(fXPMFile, ",\n\"") <= 0)
298 goto error;
299 for (j = 0; j < pIcon->bmiHeader.biWidth; j++)
301 if MASK(j,i)
303 if (fprintf(fXPMFile, " ") <= 0)
304 goto error;
306 else
307 if (fprintf(fXPMFile, "%.2X", COLOR(j,i)) <= 0)
308 goto error;
310 if (fprintf(fXPMFile, "\"") <= 0)
311 goto error;
313 if (fprintf(fXPMFile, "};\n") <= 0)
314 goto error;
316 #undef MASK
317 #undef COLOR
319 fclose(fXPMFile);
320 return 1;
322 error:
323 fclose(fXPMFile);
324 unlink( szXPMFileName );
325 return 0;
328 static BOOL CALLBACK EnumResNameProc(HANDLE hModule, const char *lpszType, char *lpszName, LONG lParam)
330 *(HRSRC *) lParam = FindResourceA(hModule, lpszName, RT_GROUP_ICONA);
331 return FALSE;
334 static int ExtractFromEXEDLL(const char *szFileName, int nIndex, const char *szXPMFileName)
336 HMODULE hModule;
337 HRSRC hResInfo;
338 char *lpName = NULL;
339 HGLOBAL hResData;
340 GRPICONDIR *pIconDir;
341 BITMAPINFO *pIcon;
342 int nMax = 0;
343 int i;
345 if (!(hModule = LoadLibraryExA(szFileName, 0, LOAD_LIBRARY_AS_DATAFILE)))
346 goto error1;
348 if (nIndex)
349 hResInfo = FindResourceA(hModule, MAKEINTRESOURCEA(nIndex), RT_GROUP_ICONA);
350 else
351 if (EnumResourceNamesA(hModule, RT_GROUP_ICONA, &EnumResNameProc, (LONG) &hResInfo))
352 goto error2;
354 if (!hResInfo)
355 goto error2;
357 if (!(hResData = LoadResource(hModule, hResInfo)))
358 goto error2;
359 if (!(pIconDir = LockResource(hResData)))
360 goto error3;
362 for (i = 0; i < pIconDir->idCount; i++)
363 if ((pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth) > nMax)
365 lpName = MAKEINTRESOURCEA(pIconDir->idEntries[i].nID);
366 nMax = pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth;
369 FreeResource(hResData);
371 if (!(hResInfo = FindResourceA(hModule, lpName, RT_ICONA)))
372 goto error2;
373 if (!(hResData = LoadResource(hModule, hResInfo)))
374 goto error2;
375 if (!(pIcon = LockResource(hResData)))
376 goto error3;
378 if(!SaveIconResAsXPM(pIcon, szXPMFileName))
379 goto error3;
381 FreeResource(hResData);
382 FreeLibrary(hModule);
384 return 1;
386 error3:
387 FreeResource(hResData);
388 error2:
389 FreeLibrary(hModule);
390 error1:
391 return 0;
394 static int ExtractFromICO(const char *szFileName, const char *szXPMFileName)
396 FILE *fICOFile;
397 ICONDIR iconDir;
398 ICONDIRENTRY *pIconDirEntry;
399 int nMax = 0;
400 int nIndex = 0;
401 void *pIcon;
402 int i;
404 if (!(fICOFile = fopen(szFileName, "r")))
405 goto error1;
407 if (fread(&iconDir, sizeof (ICONDIR), 1, fICOFile) != 1)
408 goto error2;
409 if ((iconDir.idReserved != 0) || (iconDir.idType != 1))
410 goto error2;
412 if ((pIconDirEntry = malloc(iconDir.idCount * sizeof (ICONDIRENTRY))) == NULL)
413 goto error2;
414 if (fread(pIconDirEntry, sizeof (ICONDIRENTRY), iconDir.idCount, fICOFile) != iconDir.idCount)
415 goto error3;
417 for (i = 0; i < iconDir.idCount; i++)
418 if ((pIconDirEntry[i].bHeight * pIconDirEntry[i].bWidth) > nMax)
420 nIndex = i;
421 nMax = pIconDirEntry[i].bHeight * pIconDirEntry[i].bWidth;
423 if ((pIcon = malloc(pIconDirEntry[nIndex].dwBytesInRes)) == NULL)
424 goto error3;
425 if (fseek(fICOFile, pIconDirEntry[nIndex].dwImageOffset, SEEK_SET))
426 goto error4;
427 if (fread(pIcon, pIconDirEntry[nIndex].dwBytesInRes, 1, fICOFile) != 1)
428 goto error4;
430 if(!SaveIconResAsXPM(pIcon, szXPMFileName))
431 goto error4;
433 free(pIcon);
434 free(pIconDirEntry);
435 fclose(fICOFile);
437 return 1;
439 error4:
440 free(pIcon);
441 error3:
442 free(pIconDirEntry);
443 error2:
444 fclose(fICOFile);
445 error1:
446 return 0;
449 /* get the Unix file name for a given path, allocating the string */
450 inline static char *get_unix_file_name( const char *dos )
452 char buffer[MAX_PATH];
454 if (!wine_get_unix_file_name( dos, buffer, sizeof(buffer) )) return NULL;
455 return HEAP_strdupA( GetProcessHeap(), 0, buffer );
458 static BOOL create_default_icon( const char *filename )
460 FILE *fXPM;
461 int i;
463 if (!(fXPM = fopen(filename, "w"))) return FALSE;
464 fprintf(fXPM, "/* XPM */\nstatic char * icon[] = {");
465 for (i = 0; i < sizeof(wine_xpm)/sizeof(wine_xpm[0]); i++)
466 fprintf( fXPM, "\n\"%s\",", wine_xpm[i]);
467 fprintf( fXPM, "};\n" );
468 fclose( fXPM );
469 return TRUE;
472 /* extract an icon from an exe or icon file; helper for IPersistFile_fnSave */
473 static char *extract_icon( const char *path, int index )
475 char *filename = HEAP_strdupA( GetProcessHeap(), 0, tmpnam(NULL) );
476 if (ExtractFromEXEDLL( path, index, filename )) return filename;
477 if (ExtractFromICO( path, filename )) return filename;
478 if (create_default_icon( filename )) return filename;
479 HeapFree( GetProcessHeap(), 0, filename );
480 return NULL;
484 static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFileName, BOOL fRemember)
486 HRESULT ret = NOERROR;
487 int pid, status;
488 char buffer[MAX_PATH], buff2[MAX_PATH];
489 char *filename, *link_name, *p;
490 char *shell_link_app = NULL;
491 char *icon_name = NULL;
492 char *path_name = NULL;
493 char *work_dir = NULL;
494 BOOL bDesktop;
495 HKEY hkey;
497 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
499 TRACE("(%p)->(%s)\n",This,debugstr_w(pszFileName));
501 if (!pszFileName || !This->sPath)
502 return ERROR_UNKNOWN;
504 /* check for .exe extension */
505 if (!(p = strrchr( This->sPath, '.' ))) return NOERROR;
506 if (strchr( p, '\\' ) || strchr( p, '/' )) return NOERROR;
507 if (strcasecmp( p, ".exe" )) return NOERROR;
509 /* check if ShellLinker configured */
510 buffer[0] = 0;
511 if (!RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Wine",
512 0, KEY_ALL_ACCESS, &hkey ))
514 DWORD type, count = sizeof(buffer);
515 if (RegQueryValueExA( hkey, "ShellLinker", 0, &type, buffer, &count )) buffer[0] = 0;
516 RegCloseKey( hkey );
518 if (!*buffer) return NOERROR;
519 shell_link_app = HEAP_strdupA( GetProcessHeap(), 0, buffer );
521 if (!WideCharToMultiByte( CP_ACP, 0, pszFileName, -1, buffer, sizeof(buffer), NULL, NULL))
522 return ERROR_UNKNOWN;
523 GetFullPathNameA( buffer, sizeof(buff2), buff2, NULL );
524 filename = HEAP_strdupA( GetProcessHeap(), 0, buff2 );
526 if (SHGetSpecialFolderPathA( 0, buffer, CSIDL_STARTUP, FALSE ))
528 /* ignore startup for now */
529 if (!strncasecmp( filename, buffer, strlen(buffer) )) goto done;
531 if (SHGetSpecialFolderPathA( 0, buffer, CSIDL_DESKTOPDIRECTORY, FALSE ))
533 if (!strncasecmp( filename, buffer, strlen(buffer) ))
535 link_name = filename + strlen(buffer);
536 bDesktop = TRUE;
537 goto found;
540 if (SHGetSpecialFolderPathA( 0, buffer, CSIDL_STARTMENU, FALSE ))
542 if (!strncasecmp( filename, buffer, strlen(buffer) ))
544 link_name = filename + strlen(buffer);
545 bDesktop = FALSE;
546 goto found;
549 goto done;
551 found:
552 /* make link name a Unix name */
553 for (p = link_name; *p; p++) if (*p == '\\') *p = '/';
554 /* strip leading slashes */
555 while (*link_name == '/') link_name++;
556 /* remove extension */
557 if ((p = strrchr( link_name, '.' ))) *p = 0;
559 /* convert app path name */
560 path_name = get_unix_file_name( This->sPath );
562 /* convert app working dir */
563 if (This->sWorkDir) work_dir = get_unix_file_name( This->sWorkDir );
565 /* extract the icon */
566 if (!(icon_name = extract_icon( This->sIcoPath ? This->sIcoPath : This->sPath,
567 This->iIcoNdx ))) goto done;
569 TRACE("linker app='%s' link='%s' mode=%s path='%s' args='%s' icon='%s' workdir='%s' descr='%s'\n",
570 shell_link_app, link_name, bDesktop ? "desktop" : "menu", path_name,
571 This->sArgs ? This->sArgs : "", icon_name, work_dir ? work_dir : "",
572 This->sDescription ? This->sDescription : "" );
574 if ((pid = fork()) == -1) goto done;
575 if (!pid)
577 int pos = 0;
578 char *argv[20];
579 argv[pos++] = shell_link_app;
580 argv[pos++] = "--link";
581 argv[pos++] = link_name;
582 argv[pos++] = "--path";
583 argv[pos++] = path_name;
584 argv[pos++] = bDesktop ? "--desktop" : "--menu";
585 if (This->sArgs)
587 argv[pos++] = "--args";
588 argv[pos++] = This->sArgs;
590 if (icon_name)
592 argv[pos++] = "--icon";
593 argv[pos++] = icon_name;
595 if (This->sWorkDir)
597 argv[pos++] = "--workdir";
598 argv[pos++] = This->sWorkDir;
600 if (This->sDescription)
602 argv[pos++] = "--descr";
603 argv[pos++] = This->sDescription;
605 argv[pos] = NULL;
606 execvp( shell_link_app, argv );
607 _exit(1);
610 while (waitpid( pid, &status, 0 ) == -1)
612 if (errno != EINTR)
614 ret = ERROR_UNKNOWN;
615 goto done;
618 if (status) ret = E_ACCESSDENIED;
620 done:
621 if (icon_name) unlink( icon_name );
622 HeapFree( GetProcessHeap(), 0, shell_link_app );
623 HeapFree( GetProcessHeap(), 0, filename );
624 HeapFree( GetProcessHeap(), 0, icon_name );
625 HeapFree( GetProcessHeap(), 0, path_name );
626 HeapFree( GetProcessHeap(), 0, work_dir );
627 return ret;
630 static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLESTR pszFileName)
632 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
633 FIXME("(%p)->(%s)\n",This,debugstr_w(pszFileName));
634 return NOERROR;
636 static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *ppszFileName)
638 _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
639 FIXME("(%p)\n",This);
640 return NOERROR;
643 static ICOM_VTABLE(IPersistFile) pfvt =
645 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
646 IPersistFile_fnQueryInterface,
647 IPersistFile_fnAddRef,
648 IPersistFile_fnRelease,
649 IPersistFile_fnGetClassID,
650 IPersistFile_fnIsDirty,
651 IPersistFile_fnLoad,
652 IPersistFile_fnSave,
653 IPersistFile_fnSaveCompleted,
654 IPersistFile_fnGetCurFile
657 /************************************************************************
658 * IPersistStream_QueryInterface
660 static HRESULT WINAPI IPersistStream_fnQueryInterface(
661 IPersistStream* iface,
662 REFIID riid,
663 VOID** ppvoid)
665 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
667 TRACE("(%p)\n",This);
669 return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvoid);
672 /************************************************************************
673 * IPersistStream_Release
675 static ULONG WINAPI IPersistStream_fnRelease(
676 IPersistStream* iface)
678 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
680 TRACE("(%p)\n",This);
682 return IShellLinkA_Release((IShellLinkA*)This);
685 /************************************************************************
686 * IPersistStream_AddRef
688 static ULONG WINAPI IPersistStream_fnAddRef(
689 IPersistStream* iface)
691 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
693 TRACE("(%p)\n",This);
695 return IShellLinkA_AddRef((IShellLinkA*)This);
698 /************************************************************************
699 * IPersistStream_GetClassID
702 static HRESULT WINAPI IPersistStream_fnGetClassID(
703 IPersistStream* iface,
704 CLSID* pClassID)
706 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
708 TRACE("(%p)\n", This);
710 if (pClassID==0)
711 return E_POINTER;
713 /* memcpy(pClassID, &CLSID_???, sizeof(CLSID_???)); */
715 return S_OK;
718 /************************************************************************
719 * IPersistStream_IsDirty (IPersistStream)
721 static HRESULT WINAPI IPersistStream_fnIsDirty(
722 IPersistStream* iface)
724 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
726 TRACE("(%p)\n", This);
728 return S_OK;
730 /************************************************************************
731 * IPersistStream_Load (IPersistStream)
734 static HRESULT WINAPI IPersistStream_fnLoad(
735 IPersistStream* iface,
736 IStream* pLoadStream)
738 PLINK_HEADER lpLinkHeader = HeapAlloc(GetProcessHeap(), 0, LINK_HEADER_SIZE);
739 ULONG dwBytesRead;
740 DWORD ret = E_FAIL;
741 char sTemp[MAX_PATH];
743 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
745 TRACE("(%p)(%p)\n", This, pLoadStream);
747 if ( ! pLoadStream)
749 return STG_E_INVALIDPOINTER;
752 IStream_AddRef (pLoadStream);
753 if(lpLinkHeader)
755 if (SUCCEEDED(IStream_Read(pLoadStream, lpLinkHeader, LINK_HEADER_SIZE, &dwBytesRead)))
757 if ((lpLinkHeader->MagicStr == 0x0000004CL) && IsEqualIID(&lpLinkHeader->MagicGuid, &CLSID_ShellLink))
759 lpLinkHeader = HeapReAlloc(GetProcessHeap(), 0, lpLinkHeader, LINK_HEADER_SIZE+lpLinkHeader->PidlSize);
760 if (lpLinkHeader)
762 if (SUCCEEDED(IStream_Read(pLoadStream, &(lpLinkHeader->Pidl), lpLinkHeader->PidlSize, &dwBytesRead)))
764 if (pcheck (&lpLinkHeader->Pidl))
766 This->pPidl = ILClone (&lpLinkHeader->Pidl);
768 SHGetPathFromIDListA(&lpLinkHeader->Pidl, sTemp);
769 This->sPath = HEAP_strdupA ( GetProcessHeap(), 0, sTemp);
771 This->wHotKey = lpLinkHeader->wHotKey;
772 FileTimeToSystemTime (&lpLinkHeader->Time1, &This->time1);
773 FileTimeToSystemTime (&lpLinkHeader->Time2, &This->time2);
774 FileTimeToSystemTime (&lpLinkHeader->Time3, &This->time3);
775 #if 1
776 GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time1, NULL, sTemp, 256);
777 TRACE("-- time1: %s\n", sTemp);
778 GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time2, NULL, sTemp, 256);
779 TRACE("-- time1: %s\n", sTemp);
780 GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time3, NULL, sTemp, 256);
781 TRACE("-- time1: %s\n", sTemp);
782 pdump (This->pPidl);
783 #endif
784 ret = S_OK;
788 else
790 WARN("stream contains no link!\n");
795 IStream_Release (pLoadStream);
797 pdump(This->pPidl);
799 HeapFree(GetProcessHeap(), 0, lpLinkHeader);
801 return ret;
804 /************************************************************************
805 * IPersistStream_Save (IPersistStream)
807 static HRESULT WINAPI IPersistStream_fnSave(
808 IPersistStream* iface,
809 IStream* pOutStream,
810 BOOL fClearDirty)
812 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
814 TRACE("(%p) %p %x\n", This, pOutStream, fClearDirty);
816 return E_NOTIMPL;
819 /************************************************************************
820 * IPersistStream_GetSizeMax (IPersistStream)
822 static HRESULT WINAPI IPersistStream_fnGetSizeMax(
823 IPersistStream* iface,
824 ULARGE_INTEGER* pcbSize)
826 _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
828 TRACE("(%p)\n", This);
830 return E_NOTIMPL;
833 static ICOM_VTABLE(IPersistStream) psvt =
835 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
836 IPersistStream_fnQueryInterface,
837 IPersistStream_fnAddRef,
838 IPersistStream_fnRelease,
839 IPersistStream_fnGetClassID,
840 IPersistStream_fnIsDirty,
841 IPersistStream_fnLoad,
842 IPersistStream_fnSave,
843 IPersistStream_fnGetSizeMax
846 /**************************************************************************
847 * IShellLink_Constructor
849 IShellLinkA * IShellLink_Constructor(BOOL bUnicode)
850 { IShellLinkImpl * sl;
852 sl = (IShellLinkImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellLinkImpl));
853 sl->ref = 1;
854 ICOM_VTBL(sl) = &slvt;
855 sl->lpvtblw = &slvtw;
856 sl->lpvtblPersistFile = &pfvt;
857 sl->lpvtblPersistStream = &psvt;
859 TRACE("(%p)->()\n",sl);
860 shell32_ObjCount++;
861 return bUnicode ? (IShellLinkA *) &(sl->lpvtblw) : (IShellLinkA *)sl;
864 /**************************************************************************
865 * IShellLinkA_QueryInterface
867 static HRESULT WINAPI IShellLinkA_fnQueryInterface( IShellLinkA * iface, REFIID riid, LPVOID *ppvObj)
869 ICOM_THIS(IShellLinkImpl, iface);
871 TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
873 *ppvObj = NULL;
875 if(IsEqualIID(riid, &IID_IUnknown) ||
876 IsEqualIID(riid, &IID_IShellLinkA))
878 *ppvObj = This;
880 else if(IsEqualIID(riid, &IID_IShellLinkW))
882 *ppvObj = (IShellLinkW *)&(This->lpvtblw);
884 else if(IsEqualIID(riid, &IID_IPersistFile))
886 *ppvObj = (IPersistFile *)&(This->lpvtblPersistFile);
888 else if(IsEqualIID(riid, &IID_IPersistStream))
890 *ppvObj = (IPersistStream *)&(This->lpvtblPersistStream);
893 if(*ppvObj)
895 IUnknown_AddRef((IUnknown*)(*ppvObj));
896 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
897 return S_OK;
899 TRACE("-- Interface: E_NOINTERFACE\n");
900 return E_NOINTERFACE;
902 /******************************************************************************
903 * IShellLinkA_AddRef
905 static ULONG WINAPI IShellLinkA_fnAddRef(IShellLinkA * iface)
907 ICOM_THIS(IShellLinkImpl, iface);
909 TRACE("(%p)->(count=%lu)\n",This,This->ref);
911 shell32_ObjCount++;
912 return ++(This->ref);
914 /******************************************************************************
915 * IShellLinkA_Release
917 static ULONG WINAPI IShellLinkA_fnRelease(IShellLinkA * iface)
919 ICOM_THIS(IShellLinkImpl, iface);
921 TRACE("(%p)->(count=%lu)\n",This,This->ref);
923 shell32_ObjCount--;
924 if (!--(This->ref))
925 { TRACE("-- destroying IShellLink(%p)\n",This);
927 if (This->sIcoPath)
928 HeapFree(GetProcessHeap(), 0, This->sIcoPath);
930 if (This->sArgs)
931 HeapFree(GetProcessHeap(), 0, This->sArgs);
933 if (This->sWorkDir)
934 HeapFree(GetProcessHeap(), 0, This->sWorkDir);
936 if (This->sDescription)
937 HeapFree(GetProcessHeap(), 0, This->sDescription);
939 if (This->sPath)
940 HeapFree(GetProcessHeap(),0,This->sPath);
942 if (This->pPidl)
943 SHFree(This->pPidl);
945 if (This->lpFileStream)
946 IStream_Release(This->lpFileStream);
948 This->iIcoNdx = 0;
950 HeapFree(GetProcessHeap(),0,This);
951 return 0;
953 return This->ref;
956 static HRESULT WINAPI IShellLinkA_fnGetPath(IShellLinkA * iface, LPSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
958 ICOM_THIS(IShellLinkImpl, iface);
960 TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)(%s)\n",This, pszFile, cchMaxPath, pfd, fFlags, debugstr_a(This->sPath));
962 if (This->sPath)
963 lstrcpynA(pszFile,This->sPath, cchMaxPath);
964 else
965 return E_FAIL;
967 return NOERROR;
969 static HRESULT WINAPI IShellLinkA_fnGetIDList(IShellLinkA * iface, LPITEMIDLIST * ppidl)
971 ICOM_THIS(IShellLinkImpl, iface);
973 TRACE("(%p)->(ppidl=%p)\n",This, ppidl);
975 *ppidl = ILClone(This->pPidl);
976 return NOERROR;
978 static HRESULT WINAPI IShellLinkA_fnSetIDList(IShellLinkA * iface, LPCITEMIDLIST pidl)
980 ICOM_THIS(IShellLinkImpl, iface);
982 TRACE("(%p)->(pidl=%p)\n",This, pidl);
984 if (This->pPidl)
985 SHFree(This->pPidl);
986 This->pPidl = ILClone (pidl);
987 return NOERROR;
989 static HRESULT WINAPI IShellLinkA_fnGetDescription(IShellLinkA * iface, LPSTR pszName,INT cchMaxName)
991 ICOM_THIS(IShellLinkImpl, iface);
993 FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
994 lstrcpynA(pszName,"Description, FIXME",cchMaxName);
995 return NOERROR;
997 static HRESULT WINAPI IShellLinkA_fnSetDescription(IShellLinkA * iface, LPCSTR pszName)
999 ICOM_THIS(IShellLinkImpl, iface);
1001 TRACE("(%p)->(pName=%s)\n", This, pszName);
1003 if (This->sDescription)
1004 HeapFree(GetProcessHeap(), 0, This->sDescription);
1005 if (!(This->sDescription = HEAP_strdupA(GetProcessHeap(), 0, pszName)))
1006 return E_OUTOFMEMORY;
1008 return NOERROR;
1010 static HRESULT WINAPI IShellLinkA_fnGetWorkingDirectory(IShellLinkA * iface, LPSTR pszDir,INT cchMaxPath)
1012 ICOM_THIS(IShellLinkImpl, iface);
1014 FIXME("(%p)->()\n",This);
1015 lstrcpynA(pszDir,"c:\\", cchMaxPath);
1016 return NOERROR;
1018 static HRESULT WINAPI IShellLinkA_fnSetWorkingDirectory(IShellLinkA * iface, LPCSTR pszDir)
1020 ICOM_THIS(IShellLinkImpl, iface);
1022 TRACE("(%p)->(dir=%s)\n",This, pszDir);
1024 if (This->sWorkDir)
1025 HeapFree(GetProcessHeap(), 0, This->sWorkDir);
1026 if (!(This->sWorkDir = HEAP_strdupA(GetProcessHeap(), 0, pszDir)))
1027 return E_OUTOFMEMORY;
1029 return NOERROR;
1031 static HRESULT WINAPI IShellLinkA_fnGetArguments(IShellLinkA * iface, LPSTR pszArgs,INT cchMaxPath)
1033 ICOM_THIS(IShellLinkImpl, iface);
1035 FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
1036 lstrcpynA(pszArgs, "", cchMaxPath);
1037 return NOERROR;
1039 static HRESULT WINAPI IShellLinkA_fnSetArguments(IShellLinkA * iface, LPCSTR pszArgs)
1041 ICOM_THIS(IShellLinkImpl, iface);
1043 TRACE("(%p)->(args=%s)\n",This, pszArgs);
1045 if (This->sArgs)
1046 HeapFree(GetProcessHeap(), 0, This->sArgs);
1047 if (!(This->sArgs = HEAP_strdupA(GetProcessHeap(), 0, pszArgs)))
1048 return E_OUTOFMEMORY;
1050 return NOERROR;
1052 static HRESULT WINAPI IShellLinkA_fnGetHotkey(IShellLinkA * iface, WORD *pwHotkey)
1054 ICOM_THIS(IShellLinkImpl, iface);
1056 TRACE("(%p)->(%p)(0x%08x)\n",This, pwHotkey, This->wHotKey);
1058 *pwHotkey = This->wHotKey;
1060 return NOERROR;
1062 static HRESULT WINAPI IShellLinkA_fnSetHotkey(IShellLinkA * iface, WORD wHotkey)
1064 ICOM_THIS(IShellLinkImpl, iface);
1066 TRACE("(%p)->(hotkey=%x)\n",This, wHotkey);
1068 This->wHotKey = wHotkey;
1070 return NOERROR;
1072 static HRESULT WINAPI IShellLinkA_fnGetShowCmd(IShellLinkA * iface, INT *piShowCmd)
1074 ICOM_THIS(IShellLinkImpl, iface);
1076 FIXME("(%p)->(%p)\n",This, piShowCmd);
1077 *piShowCmd=0;
1078 return NOERROR;
1080 static HRESULT WINAPI IShellLinkA_fnSetShowCmd(IShellLinkA * iface, INT iShowCmd)
1082 ICOM_THIS(IShellLinkImpl, iface);
1084 FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
1085 return NOERROR;
1087 static HRESULT WINAPI IShellLinkA_fnGetIconLocation(IShellLinkA * iface, LPSTR pszIconPath,INT cchIconPath,INT *piIcon)
1089 ICOM_THIS(IShellLinkImpl, iface);
1091 FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
1092 lstrcpynA(pszIconPath,"shell32.dll",cchIconPath);
1093 *piIcon=1;
1094 return NOERROR;
1096 static HRESULT WINAPI IShellLinkA_fnSetIconLocation(IShellLinkA * iface, LPCSTR pszIconPath,INT iIcon)
1098 ICOM_THIS(IShellLinkImpl, iface);
1100 TRACE("(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
1102 if (This->sIcoPath)
1103 HeapFree(GetProcessHeap(), 0, This->sIcoPath);
1104 if (!(This->sIcoPath = HEAP_strdupA(GetProcessHeap(), 0, pszIconPath)))
1105 return E_OUTOFMEMORY;
1106 This->iIcoNdx = iIcon;
1108 return NOERROR;
1110 static HRESULT WINAPI IShellLinkA_fnSetRelativePath(IShellLinkA * iface, LPCSTR pszPathRel, DWORD dwReserved)
1112 ICOM_THIS(IShellLinkImpl, iface);
1114 FIXME("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
1115 return NOERROR;
1117 static HRESULT WINAPI IShellLinkA_fnResolve(IShellLinkA * iface, HWND hwnd, DWORD fFlags)
1119 ICOM_THIS(IShellLinkImpl, iface);
1121 FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
1122 return NOERROR;
1124 static HRESULT WINAPI IShellLinkA_fnSetPath(IShellLinkA * iface, LPCSTR pszFile)
1126 ICOM_THIS(IShellLinkImpl, iface);
1128 TRACE("(%p)->(path=%s)\n",This, pszFile);
1130 if (This->sPath)
1131 HeapFree(GetProcessHeap(), 0, This->sPath);
1132 if (!(This->sPath = HEAP_strdupA(GetProcessHeap(), 0, pszFile)))
1133 return E_OUTOFMEMORY;
1135 return NOERROR;
1138 /**************************************************************************
1139 * IShellLink Implementation
1142 static ICOM_VTABLE(IShellLinkA) slvt =
1144 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1145 IShellLinkA_fnQueryInterface,
1146 IShellLinkA_fnAddRef,
1147 IShellLinkA_fnRelease,
1148 IShellLinkA_fnGetPath,
1149 IShellLinkA_fnGetIDList,
1150 IShellLinkA_fnSetIDList,
1151 IShellLinkA_fnGetDescription,
1152 IShellLinkA_fnSetDescription,
1153 IShellLinkA_fnGetWorkingDirectory,
1154 IShellLinkA_fnSetWorkingDirectory,
1155 IShellLinkA_fnGetArguments,
1156 IShellLinkA_fnSetArguments,
1157 IShellLinkA_fnGetHotkey,
1158 IShellLinkA_fnSetHotkey,
1159 IShellLinkA_fnGetShowCmd,
1160 IShellLinkA_fnSetShowCmd,
1161 IShellLinkA_fnGetIconLocation,
1162 IShellLinkA_fnSetIconLocation,
1163 IShellLinkA_fnSetRelativePath,
1164 IShellLinkA_fnResolve,
1165 IShellLinkA_fnSetPath
1169 /**************************************************************************
1170 * IShellLinkW_fnQueryInterface
1172 static HRESULT WINAPI IShellLinkW_fnQueryInterface(
1173 IShellLinkW * iface, REFIID riid, LPVOID *ppvObj)
1175 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1177 return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObj);
1180 /******************************************************************************
1181 * IShellLinkW_fnAddRef
1183 static ULONG WINAPI IShellLinkW_fnAddRef(IShellLinkW * iface)
1185 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1187 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1189 return IShellLinkA_AddRef((IShellLinkA*)This);
1191 /******************************************************************************
1192 * IShellLinkW_fnRelease
1195 static ULONG WINAPI IShellLinkW_fnRelease(IShellLinkW * iface)
1197 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1199 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1201 return IShellLinkA_Release((IShellLinkA*)This);
1204 static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags)
1206 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1208 FIXME("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",This, pszFile, cchMaxPath, pfd, fFlags);
1209 MultiByteToWideChar( CP_ACP, 0, "c:\\foo.bar", -1, pszFile, cchMaxPath );
1210 return NOERROR;
1213 static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST * ppidl)
1215 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1217 FIXME("(%p)->(ppidl=%p)\n",This, ppidl);
1218 *ppidl = _ILCreateDesktop();
1219 return NOERROR;
1222 static HRESULT WINAPI IShellLinkW_fnSetIDList(IShellLinkW * iface, LPCITEMIDLIST pidl)
1224 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1226 FIXME("(%p)->(pidl=%p)\n",This, pidl);
1227 return NOERROR;
1230 static HRESULT WINAPI IShellLinkW_fnGetDescription(IShellLinkW * iface, LPWSTR pszName,INT cchMaxName)
1232 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1234 FIXME("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
1235 MultiByteToWideChar( CP_ACP, 0, "Description, FIXME", -1, pszName, cchMaxName );
1236 return NOERROR;
1239 static HRESULT WINAPI IShellLinkW_fnSetDescription(IShellLinkW * iface, LPCWSTR pszName)
1241 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1243 TRACE("(%p)->(desc=%s)\n",This, debugstr_w(pszName));
1245 if (This->sDescription)
1246 HeapFree(GetProcessHeap(), 0, This->sDescription);
1247 if (!(This->sDescription = HEAP_strdupWtoA(GetProcessHeap(), 0, pszName)))
1248 return E_OUTOFMEMORY;
1250 return NOERROR;
1253 static HRESULT WINAPI IShellLinkW_fnGetWorkingDirectory(IShellLinkW * iface, LPWSTR pszDir,INT cchMaxPath)
1255 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1257 FIXME("(%p)->()\n",This);
1258 MultiByteToWideChar( CP_ACP, 0, "c:\\", -1, pszDir, cchMaxPath );
1259 return NOERROR;
1262 static HRESULT WINAPI IShellLinkW_fnSetWorkingDirectory(IShellLinkW * iface, LPCWSTR pszDir)
1264 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1266 TRACE("(%p)->(dir=%s)\n",This, debugstr_w(pszDir));
1268 if (This->sWorkDir)
1269 HeapFree(GetProcessHeap(), 0, This->sWorkDir);
1270 if (!(This->sWorkDir = HEAP_strdupWtoA(GetProcessHeap(), 0, pszDir)))
1271 return E_OUTOFMEMORY;
1273 return NOERROR;
1276 static HRESULT WINAPI IShellLinkW_fnGetArguments(IShellLinkW * iface, LPWSTR pszArgs,INT cchMaxPath)
1278 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1280 FIXME("(%p)->(%p len=%u)\n",This, pszArgs, cchMaxPath);
1281 pszArgs[0] = 0;
1282 return NOERROR;
1285 static HRESULT WINAPI IShellLinkW_fnSetArguments(IShellLinkW * iface, LPCWSTR pszArgs)
1287 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1289 TRACE("(%p)->(args=%s)\n",This, debugstr_w(pszArgs));
1291 if (This->sArgs)
1292 HeapFree(GetProcessHeap(), 0, This->sArgs);
1293 if (!(This->sArgs = HEAP_strdupWtoA(GetProcessHeap(), 0, pszArgs)))
1294 return E_OUTOFMEMORY;
1296 return NOERROR;
1299 static HRESULT WINAPI IShellLinkW_fnGetHotkey(IShellLinkW * iface, WORD *pwHotkey)
1301 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1303 FIXME("(%p)->(%p)\n",This, pwHotkey);
1304 *pwHotkey=0x0;
1305 return NOERROR;
1308 static HRESULT WINAPI IShellLinkW_fnSetHotkey(IShellLinkW * iface, WORD wHotkey)
1310 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1312 FIXME("(%p)->(hotkey=%x)\n",This, wHotkey);
1313 return NOERROR;
1316 static HRESULT WINAPI IShellLinkW_fnGetShowCmd(IShellLinkW * iface, INT *piShowCmd)
1318 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1320 FIXME("(%p)->(%p)\n",This, piShowCmd);
1321 *piShowCmd=0;
1322 return NOERROR;
1325 static HRESULT WINAPI IShellLinkW_fnSetShowCmd(IShellLinkW * iface, INT iShowCmd)
1327 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1329 FIXME("(%p)->(showcmd=%x)\n",This, iShowCmd);
1330 return NOERROR;
1333 static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR pszIconPath,INT cchIconPath,INT *piIcon)
1335 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1337 FIXME("(%p)->(%p len=%u iicon=%p)\n",This, pszIconPath, cchIconPath, piIcon);
1338 MultiByteToWideChar( CP_ACP, 0, "shell32.dll", -1, pszIconPath, cchIconPath );
1339 *piIcon=1;
1340 return NOERROR;
1343 static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
1345 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1347 TRACE("(%p)->(path=%s iicon=%u)\n",This, debugstr_w(pszIconPath), iIcon);
1349 if (This->sIcoPath)
1350 HeapFree(GetProcessHeap(), 0, This->sIcoPath);
1351 if (!(This->sIcoPath = HEAP_strdupWtoA(GetProcessHeap(), 0, pszIconPath)))
1352 return E_OUTOFMEMORY;
1353 This->iIcoNdx = iIcon;
1355 return NOERROR;
1358 static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR pszPathRel, DWORD dwReserved)
1360 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1362 FIXME("(%p)->(path=%s %lx)\n",This, debugstr_w(pszPathRel), dwReserved);
1363 return NOERROR;
1366 static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags)
1368 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1370 FIXME("(%p)->(hwnd=%x flags=%lx)\n",This, hwnd, fFlags);
1371 return NOERROR;
1374 static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
1376 _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
1378 TRACE("(%p)->(path=%s)\n",This, debugstr_w(pszFile));
1380 if (This->sPath)
1381 HeapFree(GetProcessHeap(), 0, This->sPath);
1382 if (!(This->sPath = HEAP_strdupWtoA(GetProcessHeap(), 0, pszFile)))
1383 return E_OUTOFMEMORY;
1385 return NOERROR;
1388 /**************************************************************************
1389 * IShellLinkW Implementation
1392 static ICOM_VTABLE(IShellLinkW) slvtw =
1394 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1395 IShellLinkW_fnQueryInterface,
1396 IShellLinkW_fnAddRef,
1397 IShellLinkW_fnRelease,
1398 IShellLinkW_fnGetPath,
1399 IShellLinkW_fnGetIDList,
1400 IShellLinkW_fnSetIDList,
1401 IShellLinkW_fnGetDescription,
1402 IShellLinkW_fnSetDescription,
1403 IShellLinkW_fnGetWorkingDirectory,
1404 IShellLinkW_fnSetWorkingDirectory,
1405 IShellLinkW_fnGetArguments,
1406 IShellLinkW_fnSetArguments,
1407 IShellLinkW_fnGetHotkey,
1408 IShellLinkW_fnSetHotkey,
1409 IShellLinkW_fnGetShowCmd,
1410 IShellLinkW_fnSetShowCmd,
1411 IShellLinkW_fnGetIconLocation,
1412 IShellLinkW_fnSetIconLocation,
1413 IShellLinkW_fnSetRelativePath,
1414 IShellLinkW_fnResolve,
1415 IShellLinkW_fnSetPath