diff --git a/tools/winedump/Makefile.in b/tools/winedump/Makefile.in index b55ac72f6d4..43e200ab6ed 100644 --- a/tools/winedump/Makefile.in +++ b/tools/winedump/Makefile.in @@ -17,6 +17,7 @@ C_SRCS = \ msc.c \ msmangle.c \ ne.c \ + nls.c \ output.c \ pdb.c \ pe.c \ diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c index 85bc6815d1f..4e46687a355 100644 --- a/tools/winedump/dump.c +++ b/tools/winedump/dump.c @@ -40,8 +40,8 @@ #include "winbase.h" #include "winedump.h" -static void* dump_base; -static unsigned long dump_total_len; +void *dump_base = NULL; +unsigned long dump_total_len = 0; void dump_data( const unsigned char *ptr, unsigned int size, const char *prefix ) { @@ -239,6 +239,7 @@ dumpers[] = {SIG_EMF, get_kind_emf, emf_dump}, {SIG_FNT, get_kind_fnt, fnt_dump}, {SIG_TLB, get_kind_tlb, tlb_dump}, + {SIG_NLS, get_kind_nls, nls_dump}, {SIG_UNKNOWN, NULL, NULL} /* sentinel */ }; diff --git a/tools/winedump/nls.c b/tools/winedump/nls.c new file mode 100644 index 00000000000..a114b770865 --- /dev/null +++ b/tools/winedump/nls.c @@ -0,0 +1,97 @@ +/* + * Dump a NLS file + * + * Copyright 2020 Alexandre Julliard + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include + +#include "windef.h" +#include "winedump.h" + +static const void *read_data( unsigned int *pos, unsigned int size ) +{ + const void *ret = PRD( *pos, size ); + *pos += size; + return ret; +} + +static unsigned short casemap( const unsigned short *table, unsigned int len, unsigned short ch ) +{ + unsigned int off = table[ch >> 8] + ((ch >> 4) & 0x0f); + if (off >= len) return 0; + off = table[off] + (ch & 0x0f); + if (off >= len) return 0; + return ch + table[off]; +} + +static void dump_casemap(void) +{ + int i, ch; + unsigned int pos = 0, upper_len, lower_len; + const unsigned short *header, *upper, *lower; + + if (!(header = read_data( &pos, 2 * sizeof(*header) ))) return; + upper_len = header[1]; + if (!(upper = read_data( &pos, upper_len * sizeof(*upper) ))) + { + printf( "Invalid len %04x\n", header[1] ); + return; + } + lower_len = dump_total_len / sizeof(*lower) - 2 - upper_len; + if (!(lower = read_data( &pos, lower_len * sizeof(*lower) ))) return; + + printf( "Magic: %04x\n", header[0] ); + printf( "Upper-case table:\n" ); + for (i = 0; i < 0x10000; i++) + { + if (!(i % 16)) printf( "\n%04x:", i ); + ch = casemap( upper, upper_len, i ); + if (ch == i) printf( " ...." ); + else printf( " %04x", ch ); + } + printf( "\n\nLower-case table:\n" ); + for (i = 0; i < 0x10000; i++) + { + if (!(i % 16)) printf( "\n%04x:", i ); + ch = casemap( lower, lower_len, i ); + if (ch == i) printf( " ...." ); + else printf( " %04x", ch ); + } + printf( "\n\n" ); +} + +void nls_dump(void) +{ + const char *name = strrchr( globals.input_name, '/' ); + if (name) name++; + else name = globals.input_name; + if (!strcasecmp( name, "l_intl.nls" )) return dump_casemap(); + fprintf( stderr, "Unrecognized file name '%s'\n", globals.input_name ); +} + +enum FileSig get_kind_nls(void) +{ + if (strlen( globals.input_name ) < 5) return SIG_UNKNOWN; + if (strcasecmp( globals.input_name + strlen(globals.input_name) - 4, ".nls" )) return SIG_UNKNOWN; + return SIG_NLS; +} diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index c165872b439..c2671539009 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -137,6 +137,8 @@ typedef struct __globals } _globals; extern _globals globals; +extern void *dump_base; +extern unsigned long dump_total_len; /* Names to use for output DLL */ #define OUTPUT_DLL_NAME \ @@ -214,7 +216,7 @@ const char *get_machine_str(int mach); /* file dumping functions */ enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_PDB, SIG_NE, SIG_LE, SIG_MDMP, SIG_COFFLIB, SIG_LNK, - SIG_EMF, SIG_FNT, SIG_TLB}; + SIG_EMF, SIG_FNT, SIG_TLB, SIG_NLS}; const void* PRD(unsigned long prd, unsigned long len); unsigned long Offset(const void* ptr); @@ -254,6 +256,8 @@ enum FileSig get_kind_fnt(void); void fnt_dump( void ); enum FileSig get_kind_tlb(void); void tlb_dump(void); +enum FileSig get_kind_nls(void); +void nls_dump(void); BOOL codeview_dump_symbols(const void* root, unsigned long size); BOOL codeview_dump_types_from_offsets(const void* table, const DWORD* offsets, unsigned num_types);