4 * Copyright 2001,2005 Eric Pouech
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
34 #ifdef HAVE_SYS_STAT_H
35 # include <sys/stat.h>
37 #ifdef HAVE_SYS_MMAN_H
42 #define NONAMELESSUNION
43 #define NONAMELESSSTRUCT
48 static void* dump_base
;
49 static unsigned long dump_total_len
;
51 void dump_data( const unsigned char *ptr
, unsigned int size
, const char *prefix
)
55 printf( "%s%08x: ", prefix
, 0 );
61 for (i
= 0; i
< size
; i
++)
63 printf( "%02x%c", ptr
[i
], (i
% 16 == 7) ? '-' : ' ' );
67 for (j
= 0; j
< 16; j
++)
68 printf( "%c", isprint(ptr
[i
-15+j
]) ? ptr
[i
-15+j
] : '.' );
69 if (i
< size
-1) printf( "\n%s%08x: ", prefix
, i
+ 1 );
74 printf( "%*s ", 3 * (16-(i
%16)), "" );
75 for (j
= 0; j
< i
% 16; j
++)
76 printf( "%c", isprint(ptr
[i
-(i
%16)+j
]) ? ptr
[i
-(i
%16)+j
] : '.' );
81 const char *get_time_str(unsigned long _t
)
83 const time_t t
= (const time_t)_t
;
84 const char *str
= ctime(&t
);
88 if (!str
) /* not valid time */
90 strcpy(buf
, "not valid time");
95 /* FIXME: I don't get the same values from MS' pedump running under Wine...
96 * I wonder if Wine isn't broken wrt to GMT settings...
98 if (len
&& str
[len
-1] == '\n') len
--;
99 if (len
>= sizeof(buf
)) len
= sizeof(buf
) - 1;
100 memcpy( buf
, str
, len
);
105 unsigned int strlenW( const WCHAR
*str
)
107 const WCHAR
*s
= str
;
112 void dump_unicode_str( const WCHAR
*str
, int len
)
114 if (len
== -1) len
= strlenW( str
);
116 while (len
-- > 0 && *str
)
121 case '\n': printf( "\\n" ); break;
122 case '\r': printf( "\\r" ); break;
123 case '\t': printf( "\\t" ); break;
124 case '"': printf( "\\\"" ); break;
125 case '\\': printf( "\\\\" ); break;
127 if (c
>= ' ' && c
<= 126) putchar(c
);
128 else printf( "\\u%04x",c
);
134 char* guid_to_string(const GUID
* guid
, char* str
, size_t sz
)
136 snprintf(str
, sz
, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
137 guid
->Data1
, guid
->Data2
, guid
->Data3
,
138 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
139 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
143 const void* PRD(unsigned long prd
, unsigned long len
)
145 return (prd
+ len
> dump_total_len
) ? NULL
: (const char*)dump_base
+ prd
;
148 unsigned long Offset(const void* ptr
)
150 if (ptr
< dump_base
) {printf("<<<<<ptr below\n");return 0;}
151 if ((const char *)ptr
>= (const char*)dump_base
+ dump_total_len
) {printf("<<<<<ptr above\n");return 0;}
152 return (const char *)ptr
- (const char *)dump_base
;
155 static const struct dumper
158 enum FileSig (*get_kind
)(void);
159 file_dumper dumper
; /* default dump tool */
163 {SIG_DOS
, get_kind_exec
, dos_dump
},
164 {SIG_PE
, get_kind_exec
, pe_dump
},
165 {SIG_DBG
, get_kind_dbg
, dbg_dump
},
166 {SIG_PDB
, get_kind_pdb
, pdb_dump
},
167 {SIG_NE
, get_kind_exec
, ne_dump
},
168 {SIG_LE
, get_kind_exec
, le_dump
},
169 {SIG_COFFLIB
, get_kind_lib
, lib_dump
},
170 {SIG_MDMP
, get_kind_mdmp
, mdmp_dump
},
171 {SIG_LNK
, get_kind_lnk
, lnk_dump
},
172 {SIG_EMF
, get_kind_emf
, emf_dump
},
173 {SIG_UNKNOWN
, NULL
, NULL
} /* sentinel */
176 int dump_analysis(const char *name
, file_dumper fn
, enum FileSig wanted_sig
)
181 const struct dumper
*dpr
;
183 setbuf(stdout
, NULL
);
185 fd
= open(name
, O_RDONLY
| O_BINARY
);
186 if (fd
== -1) fatal("Can't open file");
188 if (fstat(fd
, &s
) < 0) fatal("Can't get size");
189 dump_total_len
= s
.st_size
;
192 if ((dump_base
= mmap(NULL
, dump_total_len
, PROT_READ
, MAP_PRIVATE
, fd
, 0)) == (void *)-1)
195 if (!(dump_base
= malloc( dump_total_len
))) fatal( "Out of memory" );
196 if ((unsigned long)read( fd
, dump_base
, dump_total_len
) != dump_total_len
) fatal( "Cannot read file" );
199 printf("Contents of %s: %ld bytes\n\n", name
, dump_total_len
);
201 for (dpr
= dumpers
; dpr
->kind
!= SIG_UNKNOWN
; dpr
++)
203 if (dpr
->get_kind() == dpr
->kind
&&
204 (wanted_sig
== SIG_UNKNOWN
|| wanted_sig
== dpr
->kind
))
206 if (fn
) fn(); else dpr
->dumper();
210 if (dpr
->kind
== SIG_UNKNOWN
)
212 printf("Can't get a suitable file signature, aborting\n");
216 if (ret
) printf("Done dumping %s\n", name
);
218 if (munmap(dump_base
, dump_total_len
) == -1)
228 void dump_file(const char* name
)
230 dump_analysis(name
, NULL
, SIG_UNKNOWN
);