windows-nt/Source/XPSP1/NT/sdktools/restools/resonexe/resonexe.c
2020-09-26 16:20:57 +08:00

383 lines
9.3 KiB
C

/****************************************************************************/
/* */
/* resonexe.C - */
/* */
/* Windows DOS Version 3.2 add resource onto executable */
/* (C) Copyright Microsoft Corporation 1988-1992 */
/* */
/* */
/****************************************************************************/
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include "ntverp.h"
#include "rc.h"
#include "resonexe.h"
#define BUFSIZE 4096
//
// Globals
//
PUCHAR szInFile=NULL;
BOOL fDebug = FALSE;
BOOL fVerbose = FALSE;
BOOL fReplace = FALSE;
BOOL fDelete = FALSE;
int fhBin = -1;
UCHAR szType[256];
UCHAR szName[256];
int idLang;
int idType=0;
int idName=0;
void
usage ( int rc );
void
usage ( int rc )
{
#if DBG
printf("Microsoft (R) Windows RESONEXE Version %s\n", VER_PRODUCTVERSION_STR);
#else
printf("Microsoft (R) Windows RESONEXE Version %s.%d\n", VER_PRODUCTVERSION_STR, VER_PRODUCTBUILD);
#endif /* dbg */
printf("Copyright (C) Microsoft Corp. 1991-1992. All rights reserved.\n\n");
printf( "usage: resonexe [-v] [-r|-x resspec] [-fo outfile] <input file> [<exe file>]\n");
printf( " where input file is an WIN32 .RES file\n");
printf( " -v verbose - print info\n");
printf( " -d debug - print debug info\n");
printf( " -r replace - delete all resource from input file before adding new resources.\n");
printf( " -x delete - delete specified resource from input file.\n");
printf( " resspec is of the form: typeid,nameid,langid\n");
printf( " typeid is a string or decimal number\n");
printf( " nameid is a string or decimal number\n");
printf( " langid is a hexadecimal number\n");
printf( " outfile is the desired output file name.\n");
printf( " outfile defaults to filespec.exe.\n");
printf( " exe file is the exe file to attach resources to.\n");
exit(rc);
}
void
__cdecl main(
IN int argc,
IN char *argv[]
)
/*++
Routine Description:
Determines options
locates and opens input files
reads input files
writes output files
exits
Exit Value:
0 on success
1 if error
--*/
{
int i;
UCHAR *s1;
UCHAR *szOutFile=NULL;
UCHAR *szExeFile=NULL;
long lbytes;
BOOL result;
HANDLE hupd;
if (argc == 1) {
usage(0);
}
for (i=1; i<argc; i++) {
s1 = argv[i];
if (*s1 == '/' || *s1 == '-') {
s1++;
if (!_stricmp(s1, "fo")) {
szOutFile = argv[++i];
}
else if (!_stricmp(s1, "d")) {
fDebug = TRUE;
}
else if (!_stricmp(s1, "v")) {
fVerbose = TRUE;
}
else if (!_stricmp(s1, "r")) {
fReplace = TRUE;
}
else if (!_stricmp(s1, "x")) {
fDelete = TRUE;
if (i+1 == argc)
usage(1);
s1 = argv[++i];
if (sscanf(s1, "%d,%d,%x", &idType, &idName, &idLang) == 3)
continue;
idType = 0;
idName = 0;
if (sscanf(s1, "%d,%[^,],%x", &idType, szName, &idLang) == 3)
continue;
idType = 0;
idName = 0;
if (sscanf(s1, "%[^,],%d,%x", szType, &idName, &idLang) == 3)
continue;
idType = 0;
idName = 0;
if (sscanf(s1, "%[^,],%[^,],%x", szType, szName, &idLang) == 3)
continue;
printf("Unrecognized type,name,lang triplet <%s>\n", s1);
usage(1);
}
else if (!_stricmp(s1, "h")) {
usage(1);
}
else if (!_stricmp(s1, "?")) {
usage(1);
}
else {
usage(1);
}
}
else if (szInFile == NULL) {
szInFile = s1;
}
else {
szExeFile = s1;
}
}
//
// Make sure that we actually got a file
//
if (fDelete) {
if (fReplace) {
printf("usage error: Can't do both Replace and Delete\n");
usage(1);
}
if (!szInFile) {
printf("usage error: Missing exe file spec\n");
usage(1);
}
if (szInFile && !szExeFile) {
szExeFile = szInFile;
if (!szOutFile)
szOutFile = _strdup(szInFile);
szInFile = NULL;
if (idType == 0)
_strupr(szType);
if (idName == 0)
_strupr(szName);
}
}
else if (!szInFile) {
printf("usage error: Must have file spec\n");
usage(1);
}
if (fVerbose || fDebug) {
#if DBG
printf("Microsoft (R) Windows RESONEXE Version %s\n", VER_PRODUCTVERSION_STR);
#else
printf("Microsoft (R) Windows RESONEXE Version %s.%d\n", VER_PRODUCTVERSION_STR, VER_PRODUCTBUILD);
#endif /* dbg */
printf("Copyright (C) Microsoft Corp. 1991-1992. All rights reserved.\n\n");
}
if (szInFile && (fhBin = _open( szInFile, O_RDONLY|O_BINARY )) == -1) {
/*
* try adding a .RES extension.
*/
s1 = MyAlloc(strlen(szInFile) + 4 + 1);
strcpy(s1, szInFile);
szInFile = s1;
strcat(szInFile, ".RES");
if ((fhBin = _open( szInFile, O_RDONLY|O_BINARY )) == -1) {
pehdr();
printf("Cannot open %s for reading.\n", szInFile);
exit(1);
}
#if DBG
printf("Reading %s\n", szInFile);
#endif /* DBG */
}
if (fhBin != -1) {
lbytes = MySeek(fhBin, 0L, SEEK_END);
MySeek(fhBin, 0L, SEEK_SET);
}
if (szExeFile == NULL) {
/*
* Make exefile = infile.exe
*/
szExeFile = MyAlloc(strlen(szInFile) + 4 + 1);
strcpy(szExeFile, szInFile);
s1 = &szExeFile[strlen(szExeFile) - 4];
if (s1 < szExeFile)
s1 = szExeFile;
while (*s1) {
if (*s1 == '.')
break;
s1++;
}
strcpy(s1, ".exe");
}
if (szOutFile == NULL) {
/*
* Make outfile = infile.exe
*/
szOutFile = MyAlloc(strlen(szInFile) + 4 + 1);
strcpy(szOutFile, szInFile);
s1 = &szOutFile[strlen(szOutFile) - 4];
if (s1 < szOutFile)
s1 = szOutFile;
while (*s1) {
if (*s1 == '.')
break;
s1++;
}
strcpy(s1, ".exe");
}
else {
/*
* Make outfile = copyof(exefile)
*/
if (CopyFile(szExeFile, szOutFile, FALSE) == FALSE) {
pehdr();
printf("RW1001: copy of %s to %s failed", szExeFile, szOutFile);
_close(fhBin);
exit(1);
}
SetFileAttributes(szOutFile, FILE_ATTRIBUTE_NORMAL);
}
#if DBG
printf("Writing %s\n", szOutFile);
#endif /* DBG */
hupd = BeginUpdateResourceA(szOutFile, fReplace);
if (hupd == NULL) {
pehdr();
printf("RW1001: unable to load %s\n", szOutFile);
_close(fhBin);
exit(1);
}
if (fDelete) {
result = UpdateResourceA(hupd,
idType!=0?(PCHAR)idType:szType,
idName!=0?(PCHAR)idName:szName,
idLang, NULL, 0);
if (result == 0) {
pehdr();
if (idType) {
if (idName)
printf("RW1004: unable to delete resource %d,%d,%x from %s, status:%d\n", idType, idName, idLang, szExeFile, GetLastError());
else
printf("RW1004: unable to delete resource %d,%s,%x from %s, status:%d\n", idType, szName, idLang, szExeFile, GetLastError());
}
else {
if (idName)
printf("RW1004: unable to delete resource %s,%d,%x from %s, status:%d\n", szType, idName, idLang, szExeFile, GetLastError());
else
printf("RW1004: unable to delete resource %s,%s,%x from %s, status:%d\n", szType, szName, idLang, szExeFile, GetLastError());
}
_close(fhBin);
exit(1);
}
}
else {
result = ReadRes(fhBin, lbytes, hupd);
if (result == 0) {
pehdr();
printf("RW1002: unable to read resources from %s, status:%d\n", szInFile, GetLastError());
_close(fhBin);
exit(1);
}
}
result = EndUpdateResourceW(hupd, FALSE);
if (result == 0) {
pehdr();
printf("RW1003: unable to write resources to %s, status:%d\n", szOutFile, GetLastError());
}
_close( fhBin );
exit(result ? 0 : 1);
}
UCHAR*
MyAlloc(ULONG nbytes )
{
UCHAR *s;
if ((s = (UCHAR*)calloc( 1, nbytes )) != NULL)
return s;
else {
pehdr();
printf( "Memory allocation, needed %u bytes\n", nbytes );
exit(1);
}
}
ULONG
MyRead(int fh, UCHAR*p, ULONG n )
{
USHORT n1;
if ((n1 = _read( fh, p, n )) != n) {
eprintf( "a file read error occured" );
exit(1);
}
else
return 0;
}
LONG
MySeek( int fh, long pos, int cmd )
{
if ((pos = _lseek( fh, pos, cmd )) == -1) {
eprintf( "seek error" );
exit(1);
}
return pos;
}
ULONG
MoveFilePos( int fh, ULONG pos )
{
return MySeek( fh, pos, SEEK_SET );
}
void
eprintf(
UCHAR *s
)
{
pehdr();
printf("%s.\n", s);
}
void
pehdr(
)
{
printf("RESONEXE: error - ");
}