From 50e9c0145ddade1b40373b6635145842fed139e9 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 17 Feb 2005 11:51:23 +0000 Subject: [PATCH] Add dumping of lnk files. --- tools/winedump/Makefile.in | 1 + tools/winedump/lnk.c | 313 +++++++++++++++++++++++++++++++++++++ tools/winedump/main.c | 17 ++ tools/winedump/winedump.h | 5 +- 4 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 tools/winedump/lnk.c diff --git a/tools/winedump/Makefile.in b/tools/winedump/Makefile.in index 1ccda875c55..1f82fd77e73 100644 --- a/tools/winedump/Makefile.in +++ b/tools/winedump/Makefile.in @@ -12,6 +12,7 @@ C_SRCS = \ debug.c \ emf.c \ le.c \ + lnk.c \ main.c \ misc.c \ msmangle.c \ diff --git a/tools/winedump/lnk.c b/tools/winedump/lnk.c new file mode 100644 index 00000000000..7a555286434 --- /dev/null +++ b/tools/winedump/lnk.c @@ -0,0 +1,313 @@ +/* + * Dump a shortcut (lnk) file + * + * Copyright 2005 Mike McCormack + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "windef.h" +#include "winbase.h" + +#include "pshpack1.h" + +#define SCF_PIDL 1 +#define SCF_LOCATION 2 +#define SCF_DESCRIPTION 4 +#define SCF_RELATIVE 8 +#define SCF_WORKDIR 0x10 +#define SCF_ARGS 0x20 +#define SCF_CUSTOMICON 0x40 +#define SCF_UNICODE 0x80 +#define SCF_PRODUCT 0x800 +#define SCF_COMPONENT 0x1000 + +typedef struct _LINK_HEADER +{ + DWORD dwSize; /* 0x00 size of the header - 0x4c */ + GUID MagicGuid; /* 0x04 is CLSID_ShellLink */ + DWORD dwFlags; /* 0x14 describes elements following */ + DWORD dwFileAttr; /* 0x18 attributes of the target file */ + FILETIME Time1; /* 0x1c */ + FILETIME Time2; /* 0x24 */ + FILETIME Time3; /* 0x2c */ + DWORD dwFileLength; /* 0x34 File length */ + DWORD nIcon; /* 0x38 icon number */ + DWORD fStartup; /* 0x3c startup type */ + DWORD wHotKey; /* 0x40 hotkey */ + DWORD Unknown5; /* 0x44 */ + DWORD Unknown6; /* 0x48 */ +} LINK_HEADER, * PLINK_HEADER; + +typedef struct tagLINK_ADVERTISEINFO +{ + DWORD size; + DWORD magic; + CHAR bufA[MAX_PATH]; + WCHAR bufW[MAX_PATH]; +} LINK_ADVERTISEINFO; + +typedef struct _LOCATION_INFO +{ + DWORD dwTotalSize; + DWORD dwHeaderSize; + DWORD dwFlags; + DWORD dwVolTableOfs; + DWORD dwLocalPathOfs; + DWORD dwNetworkVolTableOfs; + DWORD dwFinalPathOfs; +} LOCATION_INFO; + +typedef struct lnk_string_tag { + unsigned short size; + union { + unsigned short w[1]; + unsigned char a[1]; + } str; +} lnk_string; + +#include "poppack.h" + +static void guid_to_string(LPGUID guid, char *str) +{ + sprintf(str, "{%08lx-%04x-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}", + guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); +} + +/* the size is a short integer */ +static void* load_pidl(int fd) +{ + int r; + unsigned char *data; + unsigned short size = 0; + + r = read( fd, &size, sizeof size ); + if (r != sizeof size) + return NULL; + if (sizesize = size; + if (unicode) + data->str.w[size] = 0; + else + data->str.a[size] = 0; + r = read(fd, &data->str, bytesize); + if (r != bytesize) + { + free(data); + return NULL; + } + return data; +} + + +static int dump_pidl(int fd) +{ + void *pidl; + + pidl = load_pidl(fd); + if (!pidl) + return -1; + + printf("PIDL\n"); + printf("----\n\n"); + + free(pidl); + + return 0; +} + +static void print_unicode_string(unsigned short *str) +{ + while(*str) + { + printf("%c", *str); + str++; + } + printf("\n"); +} + +static int dump_string(int fd, char *what, int unicode) +{ + lnk_string *data; + + data = load_string(fd, unicode); + if (!data) + return -1; + printf("%s : ", what); + if (unicode) + print_unicode_string(data->str.w); + else + printf("%s",data->str.a); + printf("\n"); + free(data); + return 0; +} + +static int dump_location(int fd) +{ + LOCATION_INFO *loc; + + loc = load_long_section(fd); + if (!loc) + return -1; + + printf("Location\n"); + printf("--------\n\n"); + printf("Total size = %ld\n", loc->dwTotalSize); + printf("Header size = %ld\n", loc->dwHeaderSize); + printf("Flags = %08lx\n", loc->dwFlags); + printf("Volume ofs = %08lx\n", loc->dwVolTableOfs); + printf("LocalPath ofs = %08lx\n", loc->dwLocalPathOfs); + printf("Net Path ofs = %08lx\n", loc->dwNetworkVolTableOfs); + printf("Final Path = %08lx\n", loc->dwFinalPathOfs); + printf("\n"); + + free(loc); + + return 0; +} + +static int dump_advertise_info(int fd, char *type) +{ + LINK_ADVERTISEINFO *avt; + + avt = load_long_section(fd); + if (!avt) + return -1; + + printf("Advertise Info\n"); + printf("--------------\n\n"); + printf("magic = %lx\n", avt->magic); + printf("%s = %s\n", type, avt->bufA); + printf("\n"); + + return 0; +} + +static int dump_lnk_fd(int fd) +{ + LINK_HEADER *hdr; + char guid[40]; + + hdr = load_long_section( fd ); + if (!hdr) + return -1; + + guid_to_string(&hdr->MagicGuid, guid); + + printf("Header\n"); + printf("------\n\n"); + printf("Size: %04lx\n", hdr->dwSize); + printf("GUID: %s\n", guid); + printf("Flags: %04lx\n", hdr->dwFlags); + printf("Length: %04lx\n", hdr->dwFileLength); + printf("\n"); + + if (hdr->dwFlags & SCF_PIDL) + dump_pidl(fd); + if (hdr->dwFlags & SCF_LOCATION) + dump_location(fd); + if (hdr->dwFlags & SCF_DESCRIPTION) + dump_string(fd, "Description", hdr->dwFlags & SCF_UNICODE); + if (hdr->dwFlags & SCF_RELATIVE) + dump_string(fd, "Relative path", hdr->dwFlags & SCF_UNICODE); + if (hdr->dwFlags & SCF_WORKDIR) + dump_string(fd, "Working directory", hdr->dwFlags & SCF_UNICODE); + if (hdr->dwFlags & SCF_ARGS) + dump_string(fd, "Arguments", hdr->dwFlags & SCF_UNICODE); + if (hdr->dwFlags & SCF_CUSTOMICON) + dump_string(fd, "Icon path", hdr->dwFlags & SCF_UNICODE); + if (hdr->dwFlags & SCF_PRODUCT) + dump_advertise_info(fd, "product"); + if (hdr->dwFlags & SCF_COMPONENT) + dump_advertise_info(fd, "component"); + + return 0; +} + +int dump_lnk(const char *emf) +{ + int fd; + + fd = open(emf,O_RDONLY); + if (fd<0) + return -1; + dump_lnk_fd(fd); + close(fd); + return 0; +} diff --git a/tools/winedump/main.c b/tools/winedump/main.c index ed6d2b4e111..7a7a1285870 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -86,6 +86,13 @@ static void do_dumpemf(void) } +static void do_dumplnk(void) +{ + if (globals.mode != NONE) fatal("Only one mode can be specified\n"); + globals.mode = LNK; +} + + static void do_code (void) { globals.do_code = 1; @@ -221,6 +228,7 @@ static const struct option option_table[] = { {"-j", DUMP, 1, do_dumpsect, "-j sect_name Dumps only the content of section sect_name (import, export, debug, resource, tls)"}, {"-x", DUMP, 0, do_dumpall, "-x Dumps everything"}, {"emf", EMF, 0, do_dumpemf, "emf Dumps an Enhanced Meta File"}, + {"lnk", LNK, 0, do_dumplnk, "lnk Dumps a shortcut (.lnk) file"}, {NULL, NONE, 0, NULL, NULL} }; @@ -249,6 +257,10 @@ void do_usage (void) for (opt = option_table; opt->name; opt++) if (opt->mode == EMF) printf ("\t %s\n", opt->usage); + printf ("\tWhen used in lnk mode\n"); + for (opt = option_table; opt->name; opt++) + if (opt->mode == LNK) + printf ("\t %s\n", opt->usage); puts ("\n"); exit (1); @@ -486,6 +498,11 @@ int main (int argc, char *argv[]) fatal("No file name has been given\n"); dump_emf(globals.input_name); break; + case LNK: + if (globals.input_name == NULL) + fatal("No file name has been given\n"); + dump_lnk(globals.input_name); + break; } return 0; diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index d8039f7968a..ca5b2ce8efc 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -72,7 +72,7 @@ #define SYM_THISCALL 0x4 #define SYM_DATA 0x8 /* Data, not a function */ -typedef enum {NONE, DMGL, SPEC, DUMP, EMF} Mode; +typedef enum {NONE, DMGL, SPEC, DUMP, EMF, LNK} Mode; /* Structure holding a parsed symbol */ typedef struct __parsed_symbol @@ -156,6 +156,9 @@ extern _globals globals; /* EMF functions */ int dump_emf (const char *emf); +/* LNK functions */ +int dump_lnk (const char *lnk); + /* Image functions */ void dump_file(const char* name);