2 * Dump a shortcut (lnk) file
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
41 #define SCF_LOCATION 2
42 #define SCF_DESCRIPTION 4
43 #define SCF_RELATIVE 8
44 #define SCF_WORKDIR 0x10
46 #define SCF_CUSTOMICON 0x40
47 #define SCF_UNICODE 0x80
48 #define SCF_PRODUCT 0x800
49 #define SCF_COMPONENT 0x1000
51 typedef struct _LINK_HEADER
53 DWORD dwSize; /* 0x00 size of the header - 0x4c */
54 GUID MagicGuid; /* 0x04 is CLSID_ShellLink */
55 DWORD dwFlags; /* 0x14 describes elements following */
56 DWORD dwFileAttr; /* 0x18 attributes of the target file */
57 FILETIME Time1; /* 0x1c */
58 FILETIME Time2; /* 0x24 */
59 FILETIME Time3; /* 0x2c */
60 DWORD dwFileLength; /* 0x34 File length */
61 DWORD nIcon; /* 0x38 icon number */
62 DWORD fStartup; /* 0x3c startup type */
63 DWORD wHotKey; /* 0x40 hotkey */
64 DWORD Unknown5; /* 0x44 */
65 DWORD Unknown6; /* 0x48 */
66 } LINK_HEADER, * PLINK_HEADER;
68 typedef struct tagLINK_ADVERTISEINFO
76 typedef struct _LOCATION_INFO
83 DWORD dwNetworkVolTableOfs;
87 typedef struct _LOCAL_VOLUME_INFO
95 typedef struct lnk_string_tag {
105 static void guid_to_string(LPGUID guid, char *str)
107 sprintf(str, "{%08lx-%04x-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}",
108 guid->Data1, guid->Data2, guid->Data3,
109 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
110 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
113 /* the size is a short integer */
114 static void* load_pidl(int fd)
118 unsigned short size = 0;
120 r = read( fd, &size, sizeof size );
121 if (r != sizeof size)
123 if (size<sizeof size)
126 data = malloc(size + sizeof size);
127 memcpy(data, &size, sizeof size);
128 r = read( fd, data + sizeof size, size );
137 /* size is an integer */
138 static void* load_long_section(int fd)
143 r = read( fd, &size, sizeof size );
144 if (r != sizeof size)
146 if (size<sizeof size)
150 memcpy(data, &size, sizeof size);
151 r = read( fd, data + sizeof size, size - sizeof size);
152 if (r != (size - sizeof size))
160 /* the size is a character count in a short integer */
161 static lnk_string* load_string(int fd, int unicode)
165 unsigned short size = 0, bytesize;
167 r = read( fd, &size, sizeof size );
168 if (r != sizeof size)
170 if (size < sizeof size)
175 bytesize *= sizeof(WCHAR);
176 data = malloc(sizeof *data + bytesize);
179 data->str.w[size] = 0;
181 data->str.a[size] = 0;
182 r = read(fd, &data->str, bytesize);
192 static int dump_pidl(int fd)
196 pidl = load_pidl(fd);
208 static void print_unicode_string(unsigned short *str)
218 static int dump_string(int fd, char *what, int unicode)
222 data = load_string(fd, unicode);
225 printf("%s : ", what);
227 print_unicode_string(data->str.w);
229 printf("%s",data->str.a);
235 static int dump_location(int fd)
240 loc = load_long_section(fd);
245 printf("Location\n");
246 printf("--------\n\n");
247 printf("Total size = %ld\n", loc->dwTotalSize);
248 printf("Header size = %ld\n", loc->dwHeaderSize);
249 printf("Flags = %08lx\n", loc->dwFlags);
251 /* dump out information about the volume the link points to */
252 printf("Volume ofs = %08lx ", loc->dwVolTableOfs);
253 if (loc->dwVolTableOfs && (loc->dwVolTableOfs<loc->dwTotalSize))
255 LOCAL_VOLUME_INFO *vol = (LOCAL_VOLUME_INFO *) &p[loc->dwVolTableOfs];
257 printf("size %ld type %ld serial %08lx label %ld ",
258 vol->dwSize, vol->dwType, vol->dwVolSerial, vol->dwVolLabelOfs);
259 if(vol->dwVolLabelOfs)
260 printf("(\"%s\")", &p[vol->dwVolLabelOfs]);
264 /* dump out the path the link points to */
265 printf("LocalPath ofs = %08lx ", loc->dwLocalPathOfs);
266 if( loc->dwLocalPathOfs && (loc->dwLocalPathOfs < loc->dwTotalSize) )
267 printf("(\"%s\")", &p[loc->dwLocalPathOfs]);
270 printf("Net Path ofs = %08lx\n", loc->dwNetworkVolTableOfs);
271 printf("Final Path = %08lx ", loc->dwFinalPathOfs);
272 if( loc->dwFinalPathOfs && (loc->dwFinalPathOfs < loc->dwTotalSize) )
273 printf("(\"%s\")", &p[loc->dwFinalPathOfs]);
282 static int dump_advertise_info(int fd, char *type)
284 LINK_ADVERTISEINFO *avt;
286 avt = load_long_section(fd);
290 printf("Advertise Info\n");
291 printf("--------------\n\n");
292 printf("magic = %lx\n", avt->magic);
293 printf("%s = %s\n", type, avt->bufA);
299 static int dump_lnk_fd(int fd)
304 hdr = load_long_section( fd );
308 guid_to_string(&hdr->MagicGuid, guid);
311 printf("------\n\n");
312 printf("Size: %04lx\n", hdr->dwSize);
313 printf("GUID: %s\n", guid);
315 /* dump out all the flags */
316 printf("Flags: %04lx ( ", hdr->dwFlags);
317 #define FLAG(x) if(hdr->dwFlags & SCF_##x) printf("%s ",#x);
331 printf("Length: %04lx\n", hdr->dwFileLength);
334 if (hdr->dwFlags & SCF_PIDL)
336 if (hdr->dwFlags & SCF_LOCATION)
338 if (hdr->dwFlags & SCF_DESCRIPTION)
339 dump_string(fd, "Description", hdr->dwFlags & SCF_UNICODE);
340 if (hdr->dwFlags & SCF_RELATIVE)
341 dump_string(fd, "Relative path", hdr->dwFlags & SCF_UNICODE);
342 if (hdr->dwFlags & SCF_WORKDIR)
343 dump_string(fd, "Working directory", hdr->dwFlags & SCF_UNICODE);
344 if (hdr->dwFlags & SCF_ARGS)
345 dump_string(fd, "Arguments", hdr->dwFlags & SCF_UNICODE);
346 if (hdr->dwFlags & SCF_CUSTOMICON)
347 dump_string(fd, "Icon path", hdr->dwFlags & SCF_UNICODE);
348 if (hdr->dwFlags & SCF_PRODUCT)
349 dump_advertise_info(fd, "product");
350 if (hdr->dwFlags & SCF_COMPONENT)
351 dump_advertise_info(fd, "component");
356 int dump_lnk(const char *emf)
360 fd = open(emf,O_RDONLY);