329 lines
7.5 KiB
C
329 lines
7.5 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1991 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
rcdump.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Program to dump the resources from an image file.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Steve Wood (stevewo) 17-Jul-1991
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
void
|
||
|
Usage( void );
|
||
|
|
||
|
void
|
||
|
DumpResources( char *FileName );
|
||
|
|
||
|
|
||
|
BOOL VerboseOutput;
|
||
|
|
||
|
int
|
||
|
__cdecl
|
||
|
main(
|
||
|
int argc,
|
||
|
char *argv[]
|
||
|
)
|
||
|
{
|
||
|
char *s;
|
||
|
int i;
|
||
|
|
||
|
VerboseOutput = FALSE;
|
||
|
if (argc > 1) {
|
||
|
for (i=1; i<argc; i++) {
|
||
|
s = _strupr( argv[i] );
|
||
|
if (*s == '-' || *s == '/') {
|
||
|
while (*++s)
|
||
|
switch( *s ) {
|
||
|
case 'V':
|
||
|
VerboseOutput = TRUE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fprintf( stderr,
|
||
|
"RCDUMP: Invalid switch letter '%c'\n",
|
||
|
*s
|
||
|
);
|
||
|
Usage();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
DumpResources( argv[i] );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
Usage();
|
||
|
}
|
||
|
|
||
|
exit( 0 );
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
Usage( void )
|
||
|
{
|
||
|
fprintf( stderr, "usage: RCDUMP [-v] ImageFileName(s)\n" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
EnumTypesFunc(
|
||
|
HMODULE hModule,
|
||
|
LPSTR lpType,
|
||
|
LPARAM lParam
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
EnumNamesFunc(
|
||
|
HMODULE hModule,
|
||
|
LPCSTR lpType,
|
||
|
LPSTR lpName,
|
||
|
LPARAM lParam
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
EnumLangsFunc(
|
||
|
HMODULE hModule,
|
||
|
LPCSTR lpType,
|
||
|
LPCSTR lpName,
|
||
|
WORD language,
|
||
|
LPARAM lParam
|
||
|
);
|
||
|
|
||
|
|
||
|
void
|
||
|
DumpResources(
|
||
|
char *FileName
|
||
|
)
|
||
|
{
|
||
|
HMODULE hModule;
|
||
|
|
||
|
if (FileName != NULL) {
|
||
|
int i;
|
||
|
i = SetErrorMode(SEM_FAILCRITICALERRORS);
|
||
|
hModule = LoadLibraryEx( FileName, NULL, DONT_RESOLVE_DLL_REFERENCES|LOAD_LIBRARY_AS_DATAFILE );
|
||
|
SetErrorMode(i);
|
||
|
} else {
|
||
|
hModule = NULL;
|
||
|
}
|
||
|
|
||
|
if (FileName != NULL && hModule == NULL) {
|
||
|
printf( "RCDUMP: Unable to load image file %s - rc == %u\n",
|
||
|
FileName,
|
||
|
GetLastError()
|
||
|
);
|
||
|
} else {
|
||
|
printf( "%s contains the following resources:\n",
|
||
|
FileName ? FileName : "RCDUMP"
|
||
|
);
|
||
|
EnumResourceTypes( hModule, EnumTypesFunc, -1L );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
CHAR const *pTypeName[] = {
|
||
|
NULL, // 0
|
||
|
"CURSOR", // 1 RT_CURSOR
|
||
|
"BITMAP", // 2 RT_BITMAP
|
||
|
"ICON", // 3 RT_ICON
|
||
|
"MENU", // 4 RT_MENU
|
||
|
"DIALOG", // 5 RT_DIALOG
|
||
|
"STRING", // 6 RT_STRING
|
||
|
"FONTDIR", // 7 RT_FONTDIR
|
||
|
"FONT", // 8 RT_FONT
|
||
|
"ACCELERATOR", // 9 RT_ACCELERATOR
|
||
|
"RCDATA", // 10 RT_RCDATA
|
||
|
"MESSAGETABLE", // 11 RT_MESSAGETABLE
|
||
|
"GROUP_CURSOR", // 12 RT_GROUP_CURSOR
|
||
|
NULL, // 13 RT_NEWBITMAP -- according to NT
|
||
|
"GROUP_ICON", // 14 RT_GROUP_ICON
|
||
|
NULL, // 15 RT_NAMETABLE
|
||
|
"VERSION", // 16 RT_VERSION
|
||
|
"DIALOGEX", // 17 RT_DIALOGEX ;internal
|
||
|
"DLGINCLUDE", // 18 RT_DLGINCLUDE
|
||
|
"PLUGPLAY", // 19 RT_PLUGPLAY
|
||
|
"VXD", // 20 RT_VXD
|
||
|
"ANICURSOR", // 21 RT_ANICURSOR ;internal
|
||
|
"ANIICON", // 22 RT_ANIICON ;internal
|
||
|
"HTML" // 23 RT_HTML
|
||
|
};
|
||
|
|
||
|
BOOL
|
||
|
EnumTypesFunc(
|
||
|
HMODULE hModule,
|
||
|
LPSTR lpType,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
if (lParam != -1L) {
|
||
|
printf( "RCDUMP: EnumTypesFunc lParam value incorrect (%ld)\n", lParam );
|
||
|
}
|
||
|
|
||
|
printf( "Type: " );
|
||
|
if ((ULONG_PTR)lpType & 0xFFFF0000) {
|
||
|
printf("%s\n", lpType);
|
||
|
}
|
||
|
else {
|
||
|
WORD wType = (WORD) lpType;
|
||
|
|
||
|
if ((wType > sizeof(pTypeName) / sizeof(char *)) || (pTypeName[wType] == NULL))
|
||
|
printf("%u\n", wType);
|
||
|
else
|
||
|
printf("%s\n", pTypeName[wType]);
|
||
|
}
|
||
|
|
||
|
EnumResourceNames( hModule,
|
||
|
lpType,
|
||
|
EnumNamesFunc,
|
||
|
-2L
|
||
|
);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
EnumNamesFunc(
|
||
|
HMODULE hModule,
|
||
|
LPCSTR lpType,
|
||
|
LPSTR lpName,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
if (lParam != -2L) {
|
||
|
printf( "RCDUMP: EnumNamesFunc lParam value incorrect (%ld)\n", lParam );
|
||
|
}
|
||
|
|
||
|
printf( " Name: " );
|
||
|
if ((ULONG_PTR)lpName & 0xFFFF0000) {
|
||
|
printf("%s\n", lpName);
|
||
|
} else {
|
||
|
printf( "%u\n", (USHORT)lpName );
|
||
|
}
|
||
|
|
||
|
EnumResourceLanguages( hModule,
|
||
|
lpType,
|
||
|
lpName,
|
||
|
EnumLangsFunc,
|
||
|
-3L
|
||
|
);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
EnumLangsFunc(
|
||
|
HMODULE hModule,
|
||
|
LPCSTR lpType,
|
||
|
LPCSTR lpName,
|
||
|
WORD language,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
HRSRC hResInfo;
|
||
|
PVOID pv;
|
||
|
HGLOBAL hr;
|
||
|
|
||
|
if (lParam != -3L) {
|
||
|
printf( "RCDUMP: EnumLangsFunc lParam value incorrect (%ld)\n", lParam );
|
||
|
}
|
||
|
|
||
|
printf( " Resource: " );
|
||
|
if ((ULONG_PTR)lpName & 0xFFFF0000) {
|
||
|
printf( "%s . ", lpName );
|
||
|
} else {
|
||
|
printf( "%u . ", (USHORT)lpName );
|
||
|
}
|
||
|
|
||
|
if ((ULONG_PTR)lpType & 0xFFFF0000) {
|
||
|
printf("%s . ", lpType );
|
||
|
}
|
||
|
else {
|
||
|
WORD wType = (WORD) lpType;
|
||
|
|
||
|
if ((wType > sizeof(pTypeName) / sizeof(char *)) || (pTypeName[wType] == NULL))
|
||
|
printf("%u\n", wType);
|
||
|
else
|
||
|
printf("%s\n", pTypeName[wType]);
|
||
|
}
|
||
|
|
||
|
printf( "%08x", language );
|
||
|
hResInfo = FindResourceEx( hModule, lpType, lpName, language );
|
||
|
if (hResInfo == NULL) {
|
||
|
printf( " - FindResourceEx failed, rc == %u\n", GetLastError() );
|
||
|
} else {
|
||
|
hr = LoadResource(hModule, hResInfo);
|
||
|
pv = LockResource(hr);
|
||
|
|
||
|
if (VerboseOutput && pv) {
|
||
|
if (lpType == RT_MESSAGETABLE) {
|
||
|
PMESSAGE_RESOURCE_DATA pmrd;
|
||
|
PMESSAGE_RESOURCE_BLOCK pmrb;
|
||
|
PMESSAGE_RESOURCE_ENTRY pmre;
|
||
|
ULONG i, j;
|
||
|
ULONG cb;
|
||
|
|
||
|
printf("\n");
|
||
|
pmrd = (PMESSAGE_RESOURCE_DATA) pv;
|
||
|
pmrb = &(pmrd->Blocks[0]);
|
||
|
for (i=pmrd->NumberOfBlocks ; i>0 ; i--,pmrb++) {
|
||
|
pmre = (PMESSAGE_RESOURCE_ENTRY)(((char*)pv)+pmrb->OffsetToEntries);
|
||
|
for (j=pmrb->LowId ; j<=pmrb->HighId ; j++) {
|
||
|
if (pmre->Flags & MESSAGE_RESOURCE_UNICODE) {
|
||
|
printf("%d - \"%ws\"\n", j, &(pmre->Text));
|
||
|
} else {
|
||
|
printf("%d - \"%s\"\n", j, &(pmre->Text));
|
||
|
}
|
||
|
pmre = (PMESSAGE_RESOURCE_ENTRY)(((char*)pmre) + pmre->Length);
|
||
|
}
|
||
|
}
|
||
|
} else
|
||
|
if (lpType == RT_STRING) {
|
||
|
int i;
|
||
|
PWCHAR pw;
|
||
|
|
||
|
printf("\n");
|
||
|
pw = (PWCHAR) pv;
|
||
|
for (i=0 ; i<16 ; i++,pw++) {
|
||
|
if (*pw) {
|
||
|
printf("%d - \"%-.*ws\"\n", i+((USHORT)lpName)*16, *pw, pw+1);
|
||
|
pw += *pw;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
printf( " - hResInfo == %p,\n\t\tAddress == %p - Size == %lu\n",
|
||
|
hResInfo, pv, SizeofResource( hModule, hResInfo )
|
||
|
);
|
||
|
}
|
||
|
} else {
|
||
|
printf( " - hResInfo == %p,\n\t\tAddress == %p - Size == %lu\n",
|
||
|
hResInfo,
|
||
|
pv, SizeofResource( hModule, hResInfo )
|
||
|
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|