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
24 #include <sys/types.h>
35 #define SCF_LOCATION 2
36 #define SCF_DESCRIPTION 4
37 #define SCF_RELATIVE 8
38 #define SCF_WORKDIR 0x10
40 #define SCF_CUSTOMICON 0x40
41 #define SCF_UNICODE 0x80
42 #define SCF_PRODUCT 0x800
43 #define SCF_COMPONENT 0x1000
45 typedef struct _LINK_HEADER
47 DWORD dwSize; /* 0x00 size of the header - 0x4c */
48 GUID MagicGuid; /* 0x04 is CLSID_ShellLink */
49 DWORD dwFlags; /* 0x14 describes elements following */
50 DWORD dwFileAttr; /* 0x18 attributes of the target file */
51 FILETIME Time1; /* 0x1c */
52 FILETIME Time2; /* 0x24 */
53 FILETIME Time3; /* 0x2c */
54 DWORD dwFileLength; /* 0x34 File length */
55 DWORD nIcon; /* 0x38 icon number */
56 DWORD fStartup; /* 0x3c startup type */
57 DWORD wHotKey; /* 0x40 hotkey */
58 DWORD Unknown5; /* 0x44 */
59 DWORD Unknown6; /* 0x48 */
60 } LINK_HEADER, * PLINK_HEADER;
62 typedef struct tagLINK_ADVERTISEINFO
70 typedef struct _LOCATION_INFO
77 DWORD dwNetworkVolTableOfs;
81 typedef struct lnk_string_tag {
91 static void guid_to_string(LPGUID guid, char *str)
93 sprintf(str, "{%08lx-%04x-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}",
94 guid->Data1, guid->Data2, guid->Data3,
95 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
96 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
99 /* the size is a short integer */
100 static void* load_pidl(int fd)
104 unsigned short size = 0;
106 r = read( fd, &size, sizeof size );
107 if (r != sizeof size)
109 if (size<sizeof size)
112 data = malloc(size + sizeof size);
113 memcpy(data, &size, sizeof size);
114 r = read( fd, data + sizeof size, size );
123 /* size is an integer */
124 static void* load_long_section(int fd)
129 r = read( fd, &size, sizeof size );
130 if (r != sizeof size)
132 if (size<sizeof size)
136 memcpy(data, &size, sizeof size);
137 r = read( fd, data + sizeof size, size - sizeof size);
138 if (r != (size - sizeof size))
146 /* the size is a character count in a short integer */
147 static lnk_string* load_string(int fd, int unicode)
151 unsigned short size = 0, bytesize;
153 r = read( fd, &size, sizeof size );
154 if (r != sizeof size)
156 if (size < sizeof size)
161 bytesize *= sizeof(WCHAR);
162 data = malloc(sizeof *data + bytesize);
165 data->str.w[size] = 0;
167 data->str.a[size] = 0;
168 r = read(fd, &data->str, bytesize);
178 static int dump_pidl(int fd)
182 pidl = load_pidl(fd);
194 static void print_unicode_string(unsigned short *str)
204 static int dump_string(int fd, char *what, int unicode)
208 data = load_string(fd, unicode);
211 printf("%s : ", what);
213 print_unicode_string(data->str.w);
215 printf("%s",data->str.a);
221 static int dump_location(int fd)
225 loc = load_long_section(fd);
229 printf("Location\n");
230 printf("--------\n\n");
231 printf("Total size = %ld\n", loc->dwTotalSize);
232 printf("Header size = %ld\n", loc->dwHeaderSize);
233 printf("Flags = %08lx\n", loc->dwFlags);
234 printf("Volume ofs = %08lx\n", loc->dwVolTableOfs);
235 printf("LocalPath ofs = %08lx\n", loc->dwLocalPathOfs);
236 printf("Net Path ofs = %08lx\n", loc->dwNetworkVolTableOfs);
237 printf("Final Path = %08lx\n", loc->dwFinalPathOfs);
245 static int dump_advertise_info(int fd, char *type)
247 LINK_ADVERTISEINFO *avt;
249 avt = load_long_section(fd);
253 printf("Advertise Info\n");
254 printf("--------------\n\n");
255 printf("magic = %lx\n", avt->magic);
256 printf("%s = %s\n", type, avt->bufA);
262 static int dump_lnk_fd(int fd)
267 hdr = load_long_section( fd );
271 guid_to_string(&hdr->MagicGuid, guid);
274 printf("------\n\n");
275 printf("Size: %04lx\n", hdr->dwSize);
276 printf("GUID: %s\n", guid);
277 printf("Flags: %04lx\n", hdr->dwFlags);
278 printf("Length: %04lx\n", hdr->dwFileLength);
281 if (hdr->dwFlags & SCF_PIDL)
283 if (hdr->dwFlags & SCF_LOCATION)
285 if (hdr->dwFlags & SCF_DESCRIPTION)
286 dump_string(fd, "Description", hdr->dwFlags & SCF_UNICODE);
287 if (hdr->dwFlags & SCF_RELATIVE)
288 dump_string(fd, "Relative path", hdr->dwFlags & SCF_UNICODE);
289 if (hdr->dwFlags & SCF_WORKDIR)
290 dump_string(fd, "Working directory", hdr->dwFlags & SCF_UNICODE);
291 if (hdr->dwFlags & SCF_ARGS)
292 dump_string(fd, "Arguments", hdr->dwFlags & SCF_UNICODE);
293 if (hdr->dwFlags & SCF_CUSTOMICON)
294 dump_string(fd, "Icon path", hdr->dwFlags & SCF_UNICODE);
295 if (hdr->dwFlags & SCF_PRODUCT)
296 dump_advertise_info(fd, "product");
297 if (hdr->dwFlags & SCF_COMPONENT)
298 dump_advertise_info(fd, "component");
303 int dump_lnk(const char *emf)
307 fd = open(emf,O_RDONLY);