[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