winedump: VxD support

Robert Reif reif at earthlink.net
Tue Dec 28 11:28:23 CST 2004


Adds partial VxD support.
-------------- next part --------------
diff -u -N wine.cvs/tools/winedump/le.c wine/tools/winedump/le.c
--- wine.cvs/tools/winedump/le.c	1969-12-31 19:00:00.000000000 -0500
+++ wine/tools/winedump/le.c	2004-12-28 11:52:38.000000000 -0500
@@ -0,0 +1,358 @@
+/*
+ * Dumping of LE binaries
+ *
+ * Copyright 2004 Robert Reif
+ *
+ * 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 "config.h"
+#include "wine/port.h"
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/winbase16.h"
+#include "winedump.h"
+
+struct o32_obj
+{
+    unsigned long       o32_size;
+    unsigned long       o32_base;
+    unsigned long       o32_flags;
+    unsigned long       o32_pagemap;
+    unsigned long       o32_mapsize;
+    char                o32_name[4];
+};
+
+struct o32_map
+{
+    unsigned short      o32_pagedataoffset;
+    unsigned char       o32_pagesize;
+    unsigned char       o32_pageflags;
+};
+
+struct b32_bundle
+{
+    unsigned char       b32_cnt;
+    unsigned char       b32_type;
+};
+
+struct vxd_descriptor
+{
+    unsigned long       next;
+    unsigned short      sdk_version;
+    unsigned short      device_number;
+    unsigned char       version_major;
+    unsigned char       version_minor;
+    unsigned short      flags;
+    char                name[8];
+    unsigned long       init_order;
+    unsigned long       ctrl_ofs;
+    unsigned long       v86_ctrl_ofs;
+    unsigned long       pm_ctrl_ofs;
+    unsigned long       v86_ctrl_csip;
+    unsigned long       pm_ctrl_csip;
+    unsigned long       rm_ref_data;
+    unsigned long       service_table_ofs;
+    unsigned long       service_table_size;
+    unsigned long       win32_service_table_ofs;
+    unsigned long       prev;
+    unsigned long       size;
+    unsigned long       reserved0;
+    unsigned long       reserved1;
+    unsigned long       reserved2;
+};
+
+static inline WORD get_word( const BYTE *ptr )
+{
+    return ptr[0] | (ptr[1] << 8);
+}
+
+static void dump_le_header( const IMAGE_VXD_HEADER *le )
+{
+    printf( "File header:\n" );
+    printf( "    Magic:                                %04x (%c%c)\n",
+            le->e32_magic, LOBYTE(le->e32_magic), HIBYTE(le->e32_magic));
+    printf( "    Byte order:                           %s\n",
+            le->e32_border == 0 ? "little-indian" : "big-endian");
+    printf( "    Word order:                           %s\n",
+            le->e32_worder ==  0 ? "little-indian" : "big-endian");
+    printf( "    Executable format level:              %ld\n",
+            le->e32_level);
+    printf( "    CPU type:                             %s\n",
+            le->e32_cpu == 0x01 ? "Intel 80286" :
+            le->e32_cpu == 0x02 ? "Intel 80386" :
+            le->e32_cpu == 0x03 ? "Intel 80486" :
+            le->e32_cpu == 0x04 ? "Intel 80586" :
+            le->e32_cpu == 0x20 ? "Intel i860 (N10)" :
+            le->e32_cpu == 0x21 ? "Intel i860 (N11)" :
+            le->e32_cpu == 0x40 ? "MIPS Mark I" :
+            le->e32_cpu == 0x41 ? "MIPS Mark II" :
+            le->e32_cpu == 0x42 ? "MIPS Mark III" :
+            "Unknown");
+    printf( "    Target operating system:              %s\n",
+            le->e32_os == 0x01 ? "OS/2" :
+            le->e32_os == 0x02 ? "Windows" :
+            le->e32_os == 0x03 ? "DOS 4.x" :
+            le->e32_os == 0x04 ? "Windows 386" :
+            "Unknown");
+    printf( "    Module version:                       %ld\n",
+            le->e32_ver);
+    printf( "    Module type flags:                    %08lx\n",
+            le->e32_mflags);
+    if (le->e32_mflags & 0x8000)
+    {
+        if (le->e32_mflags & 0x0004)
+            printf( "        Global initialization\n");
+        else
+            printf( "        Per-Process initialization\n");
+        if (le->e32_mflags & 0x0010)
+            printf( "        No internal fixup\n");
+        if (le->e32_mflags & 0x0020)
+            printf( "        No external fixup\n");
+        if ((le->e32_mflags & 0x0700) == 0x0100)
+            printf( "        Incompatible with PM windowing\n");
+        else if ((le->e32_mflags & 0x0700) == 0x0200)
+            printf( "        Compatible with PM windowing\n");
+        else if ((le->e32_mflags & 0x0700) == 0x0300)
+            printf( "        Uses PM windowing API\n");
+        if (le->e32_mflags & 0x2000)
+            printf( "        Module not loadable\n");
+        if (le->e32_mflags & 0x8000)
+            printf( "        Module is DLL\n");
+    }
+    printf( "    Number of memory pages:               %ld\n",
+            le->e32_mpages);
+    printf( "    Initial object CS number:             %08lx\n",
+            le->e32_startobj);
+    printf( "    Initial EIP:                          %08lx\n",
+            le->e32_eip);
+    printf( "    Initial object SS number:             %08lx\n",
+            le->e32_stackobj);
+    printf( "    Initial ESP:                          %08lx\n",
+            le->e32_esp);
+    printf( "    Memory page size:                     %ld\n",
+            le->e32_pagesize);
+    printf( "    Bytes on last page:                   %ld\n",
+            le->e32_lastpagesize);
+    printf( "    Fix-up section size:                  %ld\n",
+            le->e32_fixupsize);
+    printf( "    Fix-up section checksum:              %08lx\n",
+            le->e32_fixupsum);
+    printf( "    Loader section size:                  %ld\n",
+            le->e32_ldrsize);
+    printf( "    Loader section checksum:              %08lx\n",
+            le->e32_ldrsum);
+    printf( "    Offset of object table:               %08lx\n",
+            le->e32_objtab);
+    printf( "    Object table entries:                 %ld\n",
+            le->e32_objcnt);
+    printf( "    Object page map offset:               %08lx\n",
+            le->e32_objmap);
+    printf( "    Object iterate data map offset:       %08lx\n",
+            le->e32_itermap);
+    printf( "    Resource table offset:                %08lx\n",
+            le->e32_rsrctab);
+    printf( "    Resource table entries:               %ld\n",
+            le->e32_rsrccnt);
+    printf( "    Resident names table offset:          %08lx\n",
+            le->e32_restab);
+    printf( "    Entry table offset:                   %08lx\n",
+            le->e32_enttab);
+    printf( "    Module directives table offset:       %08lx\n",
+            le->e32_dirtab);
+    printf( "    Module directives entries:            %ld\n",
+            le->e32_dircnt);
+    printf( "    Fix-up page table offset:             %08lx\n",
+            le->e32_fpagetab);
+    printf( "    Fix-up record table offset:           %08lx\n",
+            le->e32_frectab);
+    printf( "    Imported modules name table offset:   %08lx\n",
+            le->e32_impmod);
+    printf( "    Imported modules count:               %ld\n",
+            le->e32_impmodcnt);
+    printf( "    Imported procedure name table offset: %08lx\n",
+            le->e32_impproc);
+    printf( "    Per-page checksum table offset:       %08lx\n",
+            le->e32_pagesum);
+    printf( "    Data pages offset from top of table:  %08lx\n",
+            le->e32_datapage);
+    printf( "    Preload page count:                   %08lx\n",
+            le->e32_preload);
+    printf( "    Non-resident names table offset:      %08lx\n",
+            le->e32_nrestab);
+    printf( "    Non-resident names table length:      %ld\n",
+            le->e32_cbnrestab);
+    printf( "    Non-resident names table checksum:    %08lx\n",
+            le->e32_nressum);
+    printf( "    Automatic data object:                %08lx\n",
+            le->e32_autodata);
+    printf( "    Debug information offset:             %08lx\n",
+            le->e32_debuginfo);
+    printf( "    Debug information length:             %ld\n",
+            le->e32_debuglen);
+    printf( "    Preload instance pages number:        %ld\n",
+            le->e32_instpreload);
+    printf( "    Demand instance pages number:         %ld\n",
+            le->e32_instdemand);
+    printf( "    Extra heap allocation:                %ld\n",
+            le->e32_heapsize);
+    printf( "    VxD resource table offset:            %08lx\n",
+            le->e32_winresoff);
+    printf( "    Size of VxD resource table:           %ld\n",
+            le->e32_winreslen);
+    printf( "    VxD identifier:                       %x\n",
+            le->e32_devid);
+    printf( "    VxD DDK version:                      %x\n",
+            le->e32_ddkver);
+}
+
+static void dump_le_objects( const void *base, const IMAGE_VXD_HEADER *le )
+{
+    struct o32_obj *pobj;
+    int i;
+
+    printf("\nObject table:\n");
+    pobj = (struct o32_obj *)((const unsigned char *)le + le->e32_objtab);
+    for (i = 0; i < le->e32_objcnt; i++)
+    {
+        int j;
+        struct o32_map *pmap=0;
+
+        printf("    Obj. Rel.Base Codesize Flags    Tableidx Tablesize Name\n");
+        printf("    %04X %08lx %08lx %08lx %08lx %08lx  ", i + 1,
+               pobj->o32_base, pobj->o32_size, pobj->o32_flags,
+               pobj->o32_pagemap, pobj->o32_mapsize);
+        for (j = 0; j < 4; j++)
+        {
+           if  (isprint(pobj->o32_name[j]))
+                printf("%c", pobj->o32_name[j]);
+           else
+                printf(".");
+        }
+        printf("\n");
+
+        if(pobj->o32_flags & 0x0001)
+            printf("\tReadable\n");
+        if(pobj->o32_flags & 0x0002)
+            printf("\tWriteable\n");
+        if(pobj->o32_flags & 0x0004)
+            printf("\tExecutable\n");
+        if(pobj->o32_flags & 0x0008)
+            printf("\tResource\n");
+        if(pobj->o32_flags & 0x0010)
+            printf("\tDiscardable\n");
+        if(pobj->o32_flags & 0x0020)
+            printf("\tShared\n");
+        if(pobj->o32_flags & 0x0040)
+            printf("\tPreloaded\n");
+        if(pobj->o32_flags & 0x0080)
+            printf("\tInvalid\n");
+        if(pobj->o32_flags & 0x2000)
+            printf("\tUse 32\n");
+
+        printf("    Page tables:\n");
+        printf("        Tableidx Offset Flags\n");
+        pmap = (struct o32_map *)((const unsigned char *)le + le->e32_objmap);
+        pmap = &(pmap[pobj->o32_pagemap - 1]);
+        for (j = 0; j < pobj->o32_mapsize; j++)
+        {
+            printf("        %08x %06x %02x\n",
+                   pobj->o32_pagemap + j,
+                   (pmap->o32_pagedataoffset << 8) + pmap->o32_pagesize,
+                   (int)pmap->o32_pageflags);
+            pmap++;
+        }
+        pobj++;
+    }
+}
+
+static void dump_le_names( const void *base, const IMAGE_VXD_HEADER *le )
+{
+    const char *pstr = (const char *)le + le->e32_restab;
+
+    printf( "\nResident name table:\n" );
+    while (*pstr)
+    {
+        printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr,
+                pstr + 1 );
+        pstr += *pstr + 1 + sizeof(WORD);
+    }
+    if (le->e32_cbnrestab)
+    {
+        printf( "\nNon-resident name table:\n" );
+        pstr = (char *)base + le->e32_nrestab;
+        while (*pstr)
+        {
+            printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr,
+                    pstr + 1 );
+            pstr += *pstr + 1 + sizeof(WORD);
+        }
+    }
+}
+
+static void dump_le_resources( const void *base, const IMAGE_VXD_HEADER *le )
+{
+    printf( "\nResources:\n" );
+    printf( "    Not Implemented\n" );
+}
+
+static void dump_le_modules( const void *base, const IMAGE_VXD_HEADER *le )
+{
+    printf( "\nImported modulename table:\n" );
+    printf( "    Not Implemented\n" );
+}
+
+static void dump_le_entries( const void *base, const IMAGE_VXD_HEADER *le )
+{
+    printf( "\nEntry table:\n" );
+    printf( "    Not Implemented\n" );
+}
+
+static void dump_le_fixups( const void *base, const IMAGE_VXD_HEADER *le )
+{
+    printf( "\nFixup table:\n" );
+    printf( "    Not Implemented\n" );
+}
+
+static void dump_le_VxD( const void *base, const IMAGE_VXD_HEADER *le )
+{
+    printf( "\nVxD descriptor:\n" );
+    printf( "    Not Implemented\n" );
+}
+
+void le_dump( const void *exe, size_t exe_size )
+{
+    const IMAGE_DOS_HEADER *dos = exe;
+    const IMAGE_VXD_HEADER *le;
+
+    le = (const IMAGE_VXD_HEADER*)((const char *)dos + dos->e_lfanew);
+
+    dump_le_header( le );
+    dump_le_objects( exe, le );
+    dump_le_resources( exe, le );
+    dump_le_names( exe, le );
+    dump_le_entries( exe, le );
+    dump_le_modules( exe, le );
+    dump_le_fixups( exe, le );
+    dump_le_VxD( exe, le );
+}
diff -u -N wine.cvs/tools/winedump/Makefile.in wine/tools/winedump/Makefile.in
--- wine.cvs/tools/winedump/Makefile.in	2004-07-28 07:29:04.000000000 -0400
+++ wine/tools/winedump/Makefile.in	2004-12-28 10:31:40.000000000 -0500
@@ -10,6 +10,7 @@
 
 C_SRCS = \
 	debug.c \
+	le.c \
 	main.c  \
 	misc.c  \
 	msmangle.c  \
diff -u -N wine.cvs/tools/winedump/pe.c wine/tools/winedump/pe.c
--- wine.cvs/tools/winedump/pe.c	2004-12-28 12:22:03.000000000 -0500
+++ wine/tools/winedump/pe.c	2004-12-23 13:47:14.000000000 -0500
@@ -54,7 +54,7 @@
 unsigned long		PE_total_len;
 IMAGE_NT_HEADERS*	PE_nt_headers;
 
-enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_NE};
+enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_NE, SIG_LE};
 
 static inline unsigned int strlenW( const WCHAR *str )
 {
@@ -954,6 +954,12 @@
         return;
     }
 
+    if (sig == SIG_LE)
+    {
+        le_dump( PE_base, PE_total_len );
+        return;
+    }
+
     if (globals.do_dumpheader)
     {
 	dump_pe_header();
@@ -1018,6 +1024,10 @@
                 {
                     sig = SIG_NE;
                 }
+		else if (*(WORD *)pdw == IMAGE_VXD_SIGNATURE)
+		{
+                    sig = SIG_LE;
+		}
 		else
 		{
 		    printf("No PE Signature found\n");
@@ -1078,6 +1088,7 @@
 	    ret = 0; break;
 	case SIG_PE:
 	case SIG_NE:
+	case SIG_LE:
 	    printf("Contents of \"%s\": %ld bytes\n\n", name, PE_total_len);
 	    (*fn)(effective_sig);
 	    break;


More information about the wine-patches mailing list