[PATCH 04/10] [WineDump]: lnk dumping
Eric Pouech
eric.pouech at wanadoo.fr
Wed Nov 29 14:40:16 CST 2006
- now using same scheme for dumping lnk files as the
executables (through the PRD macro and a full mapped image)
A+
---
tools/winedump/dump.c | 1
tools/winedump/lnk.c | 196 +++++++++++++---------------------------
tools/winedump/main.c | 19 ----
tools/winedump/winedump.h | 9 +-
tools/winedump/winedump.man.in | 9 +-
5 files changed, 76 insertions(+), 158 deletions(-)
diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c
index 213baf4..ba002fa 100644
--- a/tools/winedump/dump.c
+++ b/tools/winedump/dump.c
@@ -158,6 +158,7 @@ dumpers[] =
{SIG_LE, get_kind_exec, le_dump},
{SIG_COFFLIB, get_kind_lib, lib_dump},
{SIG_MDMP, get_kind_mdmp, mdmp_dump},
+ {SIG_LNK, get_kind_lnk, lnk_dump},
{SIG_UNKNOWN, NULL, NULL} /* sentinel */
};
diff --git a/tools/winedump/lnk.c b/tools/winedump/lnk.c
index 78b2c45..3692c91 100644
--- a/tools/winedump/lnk.c
+++ b/tools/winedump/lnk.c
@@ -93,7 +93,8 @@ typedef struct _LOCAL_VOLUME_INFO
DWORD dwVolLabelOfs;
} LOCAL_VOLUME_INFO;
-typedef struct lnk_string_tag {
+typedef struct lnk_string_tag
+{
unsigned short size;
union {
unsigned short w[1];
@@ -103,7 +104,9 @@ typedef struct lnk_string_tag {
#include "poppack.h"
-static void guid_to_string(LPGUID guid, char *str)
+static unsigned offset;
+
+static void guid_to_string(const GUID* guid, char *str)
{
sprintf(str, "{%08x-%04x-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid->Data1, guid->Data2, guid->Data3,
@@ -111,91 +114,35 @@ static void guid_to_string(LPGUID guid,
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
}
-/* the size is a short integer */
-static void* load_pidl(int fd)
+static const void* fetch_block(void)
{
- int r;
- unsigned char *data;
- unsigned short size = 0;
-
- r = read( fd, &size, sizeof size );
- if (r != sizeof size)
- return NULL;
- if (size<sizeof size)
- return NULL;
-
- data = malloc(size + sizeof size);
- memcpy(data, &size, sizeof size);
- r = read( fd, data + sizeof size, size );
- if (r != size)
- {
- free(data);
- return NULL;
- }
- return (void*)data;
-}
+ const unsigned* u;
+ const void* ret;
-/* size is an integer */
-static void* load_long_section(int fd)
-{
- int r, size = 0;
- unsigned char *data;
-
- r = read( fd, &size, sizeof size );
- if (r != sizeof size)
- return NULL;
- if (size<sizeof size)
- return NULL;
-
- data = malloc(size);
- memcpy(data, &size, sizeof size);
- r = read( fd, data + sizeof size, size - sizeof size);
- if (r != (size - sizeof size))
- {
- free(data);
- return NULL;
- }
- return (void*)data;
+ if (!(u = PRD(offset, sizeof(*u)))) return 0;
+ if ((ret = PRD(offset, *u))) offset += *u;
+ return ret;
}
-/* the size is a character count in a short integer */
-static lnk_string* load_string(int fd, int unicode)
+static const lnk_string* fetch_string(int unicode)
{
- int r;
- lnk_string *data;
- unsigned short size = 0, bytesize;
-
- r = read( fd, &size, sizeof size );
- if (r != sizeof size)
- return NULL;
- if ( size == 0 )
- return NULL;
-
- bytesize = size;
- if (unicode)
- bytesize *= sizeof(WCHAR);
- data = malloc(sizeof *data + bytesize);
- data->size = 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;
+ const unsigned short* s;
+ unsigned short len;
+ const void* ret;
+
+ if (!(s = PRD(offset, sizeof(*s)))) return 0;
+ len = *s * (unicode ? sizeof(WCHAR) : sizeof(char));
+ if ((ret = PRD(offset, sizeof(*s) + len))) offset += sizeof(*s) + len;
+ return ret;
}
-static int dump_pidl(int fd)
+static int dump_pidl(void)
{
- lnk_string *pidl;
+ const lnk_string *pidl;
int i, n = 0, sz = 0;
- pidl = load_pidl(fd);
+ pidl = fetch_string(FALSE);
if (!pidl)
return -1;
@@ -222,47 +169,37 @@ static int dump_pidl(int fd)
}
printf("\n");
- free(pidl);
-
return 0;
}
-static void print_unicode_string(const unsigned short *str)
+static int dump_string(const char *what, int unicode)
{
- while(*str)
- {
- printf("%c", *str);
- str++;
- }
- printf("\n");
-}
-
-static int dump_string(int fd, const char *what, int unicode)
-{
- lnk_string *data;
+ const lnk_string *data;
+ unsigned sz;
- data = load_string(fd, unicode);
+ data = fetch_string(unicode);
if (!data)
return -1;
printf("%s : ", what);
+ sz = data->size;
if (unicode)
- print_unicode_string(data->str.w);
+ while (sz) printf("%c", data->str.w[data->size - sz--]);
else
- printf("%s",data->str.a);
+ while (sz) printf("%c", data->str.a[data->size - sz--]);
printf("\n");
- free(data);
+
return 0;
}
-static int dump_location(int fd)
+static int dump_location(void)
{
- LOCATION_INFO *loc;
- char *p;
+ const LOCATION_INFO *loc;
+ const char *p;
- loc = load_long_section(fd);
+ loc = fetch_block();
if (!loc)
return -1;
- p = (char*)loc;
+ p = (const char*)loc;
printf("Location\n");
printf("--------\n\n");
@@ -296,8 +233,6 @@ static int dump_location(int fd)
printf("\n");
printf("\n");
- free(loc);
-
return 0;
}
@@ -338,11 +273,11 @@ static int base85_to_guid( const char *s
return 1;
}
-static int dump_advertise_info(int fd, const char *type)
+static int dump_advertise_info(const char *type)
{
- LINK_ADVERTISEINFO *avt;
+ const LINK_ADVERTISEINFO *avt;
- avt = load_long_section(fd);
+ avt = fetch_block();
if (!avt)
return -1;
@@ -389,14 +324,26 @@ static int dump_advertise_info(int fd, c
return 0;
}
-static int dump_lnk_fd(int fd)
+static const GUID CLSID_ShellLink = {0x00021401L, 0, 0, {0xC0,0,0,0,0,0,0,0x46}};
+
+enum FileSig get_kind_lnk(void)
+{
+ const LINK_HEADER* hdr;
+
+ hdr = PRD(0, sizeof(*hdr));
+ if (hdr && hdr->dwSize == sizeof(LINK_HEADER) &&
+ !memcmp(&hdr->MagicGuid, &CLSID_ShellLink, sizeof(GUID)))
+ return SIG_LNK;
+ return SIG_UNKNOWN;
+}
+
+void lnk_dump(void)
{
- LINK_HEADER *hdr;
+ const LINK_HEADER* hdr;
char guid[40];
- hdr = load_long_section( fd );
- if (!hdr)
- return -1;
+ offset = 0;
+ hdr = fetch_block();
guid_to_string(&hdr->MagicGuid, guid);
@@ -433,35 +380,22 @@ #undef FLAG
printf("\n");
if (hdr->dwFlags & SCF_PIDL)
- dump_pidl(fd);
+ dump_pidl();
if (hdr->dwFlags & SCF_LOCATION)
- dump_location(fd);
+ dump_location();
if (hdr->dwFlags & SCF_DESCRIPTION)
- dump_string(fd, "Description", hdr->dwFlags & SCF_UNICODE);
+ dump_string("Description", hdr->dwFlags & SCF_UNICODE);
if (hdr->dwFlags & SCF_RELATIVE)
- dump_string(fd, "Relative path", hdr->dwFlags & SCF_UNICODE);
+ dump_string("Relative path", hdr->dwFlags & SCF_UNICODE);
if (hdr->dwFlags & SCF_WORKDIR)
- dump_string(fd, "Working directory", hdr->dwFlags & SCF_UNICODE);
+ dump_string("Working directory", hdr->dwFlags & SCF_UNICODE);
if (hdr->dwFlags & SCF_ARGS)
- dump_string(fd, "Arguments", hdr->dwFlags & SCF_UNICODE);
+ dump_string("Arguments", hdr->dwFlags & SCF_UNICODE);
if (hdr->dwFlags & SCF_CUSTOMICON)
- dump_string(fd, "Icon path", hdr->dwFlags & SCF_UNICODE);
+ dump_string("Icon path", hdr->dwFlags & SCF_UNICODE);
if (hdr->dwFlags & SCF_PRODUCT)
- dump_advertise_info(fd, "product");
+ dump_advertise_info("product");
if (hdr->dwFlags & SCF_COMPONENT)
- dump_advertise_info(fd, "msi string");
-
- return 0;
+ dump_advertise_info("msi string");
}
-int dump_lnk(const char *lnk)
-{
- int fd;
-
- fd = open(lnk,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 f71c49a..22c3210 100644
--- a/tools/winedump/main.c
+++ b/tools/winedump/main.c
@@ -87,13 +87,6 @@ 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;
@@ -237,14 +230,13 @@ static const struct my_option option_tab
{"-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}
};
void do_usage (void)
{
const struct my_option *opt;
- printf ("Usage: winedump [-h | sym <sym> | spec <dll> | dump <file> | emf <emf> | lnk <lnk>]\n");
+ printf ("Usage: winedump [-h | sym <sym> | spec <dll> | dump <file> | emf <emf>]\n");
printf ("Mode options (can be put as the mode (sym/spec/dump...) is declared):\n");
printf ("\tWhen used in --help mode\n");
for (opt = option_table; opt->name; opt++)
@@ -266,10 +258,6 @@ 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 ("");
exit (1);
@@ -506,11 +494,6 @@ #endif
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 895e655..37d9056 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -72,7 +72,7 @@ #define SYM_STDCALL 0x2
#define SYM_THISCALL 0x4
#define SYM_DATA 0x8 /* Data, not a function */
-typedef enum {NONE, DMGL, SPEC, DUMP, EMF, LNK} Mode;
+typedef enum {NONE, DMGL, SPEC, DUMP, EMF} Mode;
/* Structure holding a parsed symbol */
typedef struct __parsed_symbol
@@ -159,9 +159,6 @@ #define CALLING_CONVENTION (globals.do_c
/* EMF functions */
int dump_emf (const char *emf);
-/* LNK functions */
-int dump_lnk (const char *lnk);
-
/* Image functions */
void dump_file(const char* name);
@@ -224,7 +221,7 @@ char *str_toupper (char *str);
const char *get_machine_str(int mach);
/* file dumping functions */
-enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_NE, SIG_LE, SIG_MDMP, SIG_COFFLIB};
+enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_NE, SIG_LE, SIG_MDMP, SIG_COFFLIB, SIG_LNK};
const void* PRD(unsigned long prd, unsigned long len);
unsigned long Offset(const void* ptr);
@@ -247,6 +244,8 @@ enum FileSig get_kind_lib(void);
void lib_dump( void );
enum FileSig get_kind_dbg(void);
void dbg_dump( void );
+enum FileSig get_kind_lnk(void);
+void lnk_dump( void );
void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr);
void dump_codeview(unsigned long ptr, unsigned long len);
diff --git a/tools/winedump/winedump.man.in b/tools/winedump/winedump.man.in
index f4fa04d..0a2ca24 100644
--- a/tools/winedump/winedump.man.in
+++ b/tools/winedump/winedump.man.in
@@ -8,7 +8,7 @@ winedump \- A Wine DLL tool
|
.BI "spec " "<dll> "
|
-.BI "dump " "<dll>"
+.BI "dump " "<file>"
.RI "] [" "mode_options" ]
.SH DESCRIPTION
.B winedump
@@ -46,7 +46,7 @@ program determines the mode winedump wil
Help mode.
Basic usage help is printed.
.IP \fBdump\fR
-To dump the contents of a PE file.
+To dump the contents of a file.
.IP \fBspec\fR
For generating .spec files and stub DLLs.
.IP \fBsym\fR
@@ -61,8 +61,9 @@ No options are used.
The program prints the help info and than exits.
.PP
.B Dump mode:
-.IP \fI<dll>\fR
-Dumps the content of the dll named \fI<dll>\fR.
+.IP \fI<file>\fR
+Dumps the content of the file named \fI<file>\fR. Various file
+formats are supported (PE, NE, LE, Minidumps, .lnk).
.IP \fB-C\fR
Turns on symbol demangling.
.IP \fB-f\fR
More information about the wine-patches
mailing list