windows-nt/Source/XPSP1/NT/sdktools/rcdump/rcdump.c

329 lines
7.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}