[PATCH 03/10] [WineDump]: dumping internals

Eric Pouech eric.pouech at wanadoo.fr
Wed Nov 29 14:40:12 CST 2006


- now using a uniform scheme for dumping file contents

A+
---

 tools/winedump/dump.c     |  133 ++++++++-------------------------------------
 tools/winedump/lib.c      |   33 ++++++-----
 tools/winedump/minidump.c |   11 ++++
 tools/winedump/pe.c       |   39 +++++++++++++
 tools/winedump/winedump.h |   10 ++-
 5 files changed, 97 insertions(+), 129 deletions(-)

diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c
index 21ff22a..213baf4 100644
--- a/tools/winedump/dump.c
+++ b/tools/winedump/dump.c
@@ -143,96 +143,30 @@ unsigned long Offset(const void* ptr)
     return (const char *)ptr - (const char *)dump_base;
 }
 
-static	void	do_dump( enum FileSig sig )
+static struct dumper
 {
-    if (sig == SIG_NE)
-    {
-        ne_dump();
-        return;
-    }
-
-    if (sig == SIG_LE)
-    {
-        le_dump();
-        return;
-    }
-
-    pe_dump();
+    enum FileSig        kind;
+    enum FileSig        (*get_kind)(void);
+    file_dumper         dumper; /* default dump tool */
 }
-
-static enum FileSig check_headers(void)
+dumpers[] =
 {
-    const char *p;
-    const WORD*		pw;
-    const DWORD*		pdw;
-    const IMAGE_DOS_HEADER*	dh;
-    enum FileSig	sig;
-
-    pw = PRD(0, sizeof(WORD));
-    if (!pw) {printf("Can't get main signature, aborting\n"); return 0;}
-
-    switch (*pw)
-    {
-    case IMAGE_DOS_SIGNATURE:
-	sig = SIG_DOS;
-	dh = PRD(0, sizeof(IMAGE_DOS_HEADER));
-	if (dh)
-	{
-	    /* the signature is the first DWORD */
-	    pdw = PRD(dh->e_lfanew, sizeof(DWORD));
-	    if (pdw)
-	    {
-		if (*pdw == IMAGE_NT_SIGNATURE)
-		{
-		    sig = SIG_PE;
-		}
-                else if (*(const WORD *)pdw == IMAGE_OS2_SIGNATURE)
-                {
-                    sig = SIG_NE;
-                }
-		else if (*(const WORD *)pdw == IMAGE_VXD_SIGNATURE)
-		{
-                    sig = SIG_LE;
-		}
-		else
-		{
-		    printf("No PE Signature found\n");
-		}
-	    }
-	    else
-	    {
-		printf("Can't get the extented signature, aborting\n");
-	    }
-	}
-        return sig;
-
-    case 0x4944: /* "DI" */
-	return SIG_DBG;
-
-    case 0x444D: /* "MD" */
-        pdw = PRD(0, sizeof(DWORD));
-        if (pdw && *pdw == 0x504D444D) /* "MDMP" */
-            return SIG_MDMP;
-        return SIG_UNKNOWN;
-
-    default:
-        break;
-    }
-
-    p = PRD(0, IMAGE_ARCHIVE_START_SIZE);
-    if (p && !strncmp(p, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
-        return SIG_COFFLIB;
-
-    printf("No known main signature (%.2s/%x), aborting\n", (const char *)pw, *pw);
-    return SIG_UNKNOWN;
-}
+    {SIG_DOS,           get_kind_exec,  NULL},
+    {SIG_PE,            get_kind_exec,  pe_dump},
+    {SIG_DBG,           get_kind_dbg,   dbg_dump},
+    {SIG_NE,            get_kind_exec,  ne_dump},
+    {SIG_LE,            get_kind_exec,  le_dump},
+    {SIG_COFFLIB,       get_kind_lib,   lib_dump},
+    {SIG_MDMP,          get_kind_mdmp,  mdmp_dump},
+    {SIG_UNKNOWN,       NULL,           NULL} /* sentinel */
+};
 
 int dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
 {
     int			fd;
-    enum FileSig	effective_sig;
     int			ret = 1;
     struct stat		s;
+    struct dumper*      dpr;
 
     setbuf(stdout, NULL);
 
@@ -250,37 +184,16 @@ #endif
         if ((unsigned long)read( fd, dump_base, dump_total_len ) != dump_total_len) fatal( "Cannot read file" );
     }
 
-    effective_sig = check_headers();
-
-    if (wanted_sig == SIG_UNKNOWN || wanted_sig == effective_sig)
+    for (dpr = dumpers; dpr->kind != SIG_UNKNOWN; dpr++)
     {
-	switch (effective_sig)
-	{
-	case SIG_UNKNOWN: /* shouldn't happen... */
-	    printf("Can't get a recognized file signature, aborting\n");
-	    ret = 0; break;
-	case SIG_PE:
-	case SIG_NE:
-	case SIG_LE:
-	    printf("Contents of \"%s\": %ld bytes\n\n", name, dump_total_len);
-	    (*fn)(effective_sig);
-	    break;
-	case SIG_DBG:
-	    dbg_dump();
-	    break;
-	case SIG_DOS:
-	    ret = 0; break;
-        case SIG_MDMP:
-            mdmp_dump();
-            break;
-
-        case SIG_COFFLIB:
-            printf("Contents of \"%s\": %ld bytes\n\n", name, dump_total_len);
-            lib_dump(dump_base, dump_total_len);
+        if (dpr->get_kind() == dpr->kind &&
+            (wanted_sig == SIG_UNKNOWN || wanted_sig == dpr->kind))
+        {
+            if (fn) fn(); else dpr->dumper();
             break;
-	}
+        }
     }
-    else
+    if (dpr->kind == SIG_UNKNOWN)
     {
 	printf("Can't get a suitable file signature, aborting\n");
 	ret = 0;
@@ -300,5 +213,5 @@ #endif
 
 void	dump_file(const char* name)
 {
-    dump_analysis(name, do_dump, SIG_UNKNOWN);
+    dump_analysis(name, NULL, SIG_UNKNOWN);
 }
diff --git a/tools/winedump/lib.c b/tools/winedump/lib.c
index 56242e8..bd03eb7 100644
--- a/tools/winedump/lib.c
+++ b/tools/winedump/lib.c
@@ -80,29 +80,33 @@ #endif
     }
 }
 
-void lib_dump(const char *lib_base, unsigned long lib_size)
+enum FileSig get_kind_lib(void)
 {
-    long cur_file_pos;
-    IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
+    const char*         arch = PRD(0, IMAGE_ARCHIVE_START_SIZE);
+    if (arch && !strncmp(arch, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
+        return SIG_COFFLIB;
+    return SIG_UNKNOWN;
+}
 
-    if (strncmp(lib_base, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
-    {
-        printf("Not a valid COFF library file");
-        return;
-    }
+void lib_dump(void)
+{
+    long cur_file_pos;
+    const IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
 
-    iamh = (IMAGE_ARCHIVE_MEMBER_HEADER *)(lib_base + IMAGE_ARCHIVE_START_SIZE);
     cur_file_pos = IMAGE_ARCHIVE_START_SIZE;
 
-    while (cur_file_pos < lib_size)
+    for (;;)
     {
-        IMPORT_OBJECT_HEADER *ioh;
+        const IMPORT_OBJECT_HEADER *ioh;
         long size;
 
+        if (!(iamh = PRD(cur_file_pos, sizeof(*iamh)))) break;
+        cur_file_pos += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER);
+
 #if 0 /* left here for debugging purposes, also should be helpful for
        * adding support for new library formats.
        */
-        printf("cur_file_pos %08lx\n", (ULONG_PTR)iamh - (ULONG_PTR)lib_base);
+        printf("cur_file_pos %08lx\n", Offset(iamh));
 
         printf("Name %.16s", iamh->Name);
         if (!strncmp(iamh->Name, IMAGE_ARCHIVE_LINKER_MEMBER, sizeof(iamh->Name)))
@@ -121,7 +125,7 @@ #endif
         /* FIXME: only import library contents with the short format are
          * recognized.
          */
-        ioh = (IMPORT_OBJECT_HEADER *)((char *)iamh + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER));
+        if (!(ioh = PRD(cur_file_pos + sizeof(*iamh), sizeof(*ioh)))) break;
         if (ioh->Sig1 == IMAGE_FILE_MACHINE_UNKNOWN && ioh->Sig2 == IMPORT_OBJECT_HDR_SIG2)
         {
             dump_import_object(ioh);
@@ -130,7 +134,6 @@ #endif
         size = strtoul((const char *)iamh->Size, NULL, 10);
         size = (size + 1) & ~1; /* align to an even address */
 
-        cur_file_pos += size + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER);
-        iamh = (IMAGE_ARCHIVE_MEMBER_HEADER *)((char *)iamh + size + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER));
+        cur_file_pos += size;
     }
 }
diff --git a/tools/winedump/minidump.c b/tools/winedump/minidump.c
index d070c21..04f4a27 100644
--- a/tools/winedump/minidump.c
+++ b/tools/winedump/minidump.c
@@ -59,6 +59,17 @@ static const MINIDUMP_DIRECTORY* get_mdm
     return NULL;
 }
 
+enum FileSig get_kind_mdmp(void)
+{
+    const DWORD*        pdw;
+
+    pdw = PRD(0, sizeof(DWORD));
+    if (!pdw) {printf("Can't get main signature, aborting\n"); return SIG_UNKNOWN;}
+
+    if (*pdw == 0x444D /* "MDMP" */) return SIG_MDMP;
+    return SIG_UNKNOWN;
+}
+
 void mdmp_dump(void)
 {
     const MINIDUMP_HEADER*      hdr = (const MINIDUMP_HEADER*)PRD(0, sizeof(MINIDUMP_HEADER));
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c
index 080fb42..8365432 100644
--- a/tools/winedump/pe.c
+++ b/tools/winedump/pe.c
@@ -784,6 +784,17 @@ static void dump_dir_tls(void)
     printf(" }\n\n");
 }
 
+enum FileSig get_kind_dbg(void)
+{
+    const WORD*                pw;
+
+    pw = PRD(0, sizeof(WORD));
+    if (!pw) {printf("Can't get main signature, aborting\n"); return 0;}
+
+    if (*pw == 0x4944 /* "DI" */) return SIG_DBG;
+    return SIG_UNKNOWN;
+}
+
 void	dbg_dump(void)
 {
     const IMAGE_SEPARATE_DEBUG_HEADER*  separateDebugHead;
@@ -1111,6 +1122,32 @@ static void dump_debug(void)
         dump_stabs(stabs, szstabs, stabstr, szstr);
 }
 
+enum FileSig get_kind_exec(void)
+{
+    const WORD*                pw;
+    const DWORD*               pdw;
+    const IMAGE_DOS_HEADER*    dh;
+
+    pw = PRD(0, sizeof(WORD));
+    if (!pw) {printf("Can't get main signature, aborting\n"); return 0;}
+
+    if (*pw != IMAGE_DOS_SIGNATURE) return SIG_UNKNOWN;
+
+    if ((dh = PRD(0, sizeof(IMAGE_DOS_HEADER))))
+    {
+        /* the signature is the first DWORD */
+        pdw = PRD(dh->e_lfanew, sizeof(DWORD));
+        if (pdw)
+        {
+            if (*pdw == IMAGE_NT_SIGNATURE)                     return SIG_PE;
+            if (*(const WORD *)pdw == IMAGE_OS2_SIGNATURE)      return SIG_NE;
+            if (*(const WORD *)pdw == IMAGE_VXD_SIGNATURE)      return SIG_LE;
+            return SIG_DOS;
+        }
+    }
+    return 0;
+}
+
 void pe_dump(void)
 {
     int	all = (globals.dumpsect != NULL) && strcmp(globals.dumpsect, "ALL") == 0;
@@ -1191,7 +1228,7 @@ static void dll_close (void)
 }
 */
 
-static	void	do_grab_sym( enum FileSig sig )
+static	void	do_grab_sym( void )
 {
     const IMAGE_EXPORT_DIRECTORY*exportDir;
     unsigned			i, j;
diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h
index d4aea07..895e655 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -229,7 +229,7 @@ enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_
 const void*	PRD(unsigned long prd, unsigned long len);
 unsigned long	Offset(const void* ptr);
 
-typedef void (*file_dumper)(enum FileSig sig);
+typedef void (*file_dumper)(void);
 int             dump_analysis(const char*, file_dumper, enum FileSig);
 
 void            dump_data( const unsigned char *ptr, unsigned int size, const char *prefix );
@@ -237,12 +237,16 @@ const char*	get_time_str( unsigned long 
 unsigned int    strlenW( const unsigned short *str );
 void            dump_unicode_str( const unsigned short *str, int len );
 
+enum FileSig    get_kind_exec(void);
+void            pe_dump( void );
 void            ne_dump( void );
 void            le_dump( void );
+enum FileSig    get_kind_mdmp(void);
 void            mdmp_dump( void );
-void            lib_dump( const char *lib_base, unsigned long lib_size );
+enum FileSig    get_kind_lib(void);
+void            lib_dump( void );
+enum FileSig    get_kind_dbg(void);
 void	        dbg_dump( void );
-void            pe_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);



More information about the wine-patches mailing list