Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

631 lines
14 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
main
Abstract:
framework and utility routines for cvtres
Author:
Sanford A. Staab (sanfords) 23-Apr-1990
Revision History:
01-Oct-1990 mikeke
Added support for conversion of win30 resources
19-May-1990 Steve Wood (stevewo)
Added the target machine switches, along with the debug switch.
23-Apr-1990 sanfords
Created
--*/
#include <windows.h>
#include <share.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cvtres.h"
#include "rc.h"
#include "getmsg.h"
#include "msg.h"
//
// Globals
//
char *szInFile;
char *szOutFile;
USHORT targetMachine = IMAGE_FILE_MACHINE_UNKNOWN;
USHORT targetRelocType;
BOOL fVerbose;
BOOL fWritable = TRUE;
#if DBG
BOOL fDebug;
#endif /* DBG */
void
usage(int rc)
{
printf(get_err(MSG_VERSION), VER_PRODUCTVERSION_STR);
puts(get_err(MSG_COPYRIGHT));
puts("usage: CVTRES [options] ResFile\n"
"\n"
" options:\n"
"\n"
#if DBG
" /DEBUG\n"
#endif /* DBG */
" /MACHINE:{IX86|MIPS|ALPHA|PPC}\n"
" /NOLOGO\n"
" /OUT:filename\n"
" /READONLY\n"
" /VERBOSE\n");
exit(rc);
}
void
_CRTAPI1 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;
char szDrive[_MAX_DRIVE];
char szDir[_MAX_DIR];
char szFname[_MAX_FNAME];
char szExt[_MAX_EXT];
char szInPath[_MAX_PATH];
char szOutPath[_MAX_PATH];
FILE *fh;
FILE *fhOut;
char *s1;
long lbytes;
BOOL result;
BOOL fNoLogo = FALSE;
BOOL fReproducible = FALSE;
DWORD timeDate;
SetErrorFile("cvtres.err", _pgmptr, 1);
if (argc == 1) {
usage(0);
}
for (i = 1; i < argc; i++) {
s1 = argv[i];
if (*s1 == '/' || *s1 == '-') {
s1++;
if (!_strnicmp(s1, "machine:", 8)) {
s1 += 8;
if (!_stricmp(s1, "IX86") || !_stricmp(s1, "X86")) {
targetMachine = IMAGE_FILE_MACHINE_I386;
targetRelocType = IMAGE_REL_I386_DIR32NB;
} else if (!_stricmp(s1, "MIPS")) {
targetMachine = IMAGE_FILE_MACHINE_R4000;
targetRelocType = IMAGE_REL_MIPS_REFWORDNB;
} else if (!_stricmp(s1, "ALPHA")) {
targetMachine = IMAGE_FILE_MACHINE_ALPHA;
targetRelocType = IMAGE_REL_ALPHA_REFLONGNB;
} else if (!_stricmp(s1, "PPC")) {
targetMachine = IMAGE_FILE_MACHINE_POWERPC;
targetRelocType = IMAGE_REL_PPC_ADDR32NB;
} else {
usage(1);
}
} else if (!_stricmp(s1, "nologo")) {
fNoLogo = TRUE;
} else if (!_stricmp(s1, "o")) {
szOutFile = argv[++i];
} else if (!_strnicmp(s1, "out:", 4)) {
szOutFile = s1+4;
} else if (!_stricmp(s1, "readonly") || !_stricmp(s1, "r")) {
fWritable = FALSE;
} else if (!_stricmp(s1, "verbose") || !_stricmp(s1, "v")) {
fVerbose = TRUE;
} else if (!_stricmp(s1, "Brepro")) {
fReproducible = TRUE;
} else if (!_stricmp(s1, "I386")) {
targetMachine = IMAGE_FILE_MACHINE_I386;
targetRelocType = IMAGE_REL_I386_DIR32NB;
} else if (!_stricmp(s1, "IX86")) {
targetMachine = IMAGE_FILE_MACHINE_I386;
targetRelocType = IMAGE_REL_I386_DIR32NB;
} else if (!_stricmp(s1, "MIPS")) {
targetMachine = IMAGE_FILE_MACHINE_R4000;
targetRelocType = IMAGE_REL_MIPS_REFWORDNB;
} else if (!_stricmp(s1, "ALPHA")) {
targetMachine = IMAGE_FILE_MACHINE_ALPHA;
targetRelocType = IMAGE_REL_ALPHA_REFLONGNB;
} else if (!_stricmp(s1, "PPC")) {
targetMachine = IMAGE_FILE_MACHINE_POWERPC;
targetRelocType = IMAGE_REL_PPC_ADDR32NB;
#if DBG
} else if (!_stricmp(s1, "debug") || !_stricmp(s1, "d")) {
fDebug = TRUE;
fVerbose = TRUE;
#endif /* DBG */
} else {
usage(1);
}
} else {
szInFile = s1;
}
}
//
// Make sure that we actually got a file
//
if (!szInFile) {
usage(1);
}
if (!fNoLogo) {
printf(get_err(MSG_VERSION), VER_PRODUCTVERSION_STR);
puts(get_err(MSG_COPYRIGHT));
}
if (targetMachine == IMAGE_FILE_MACHINE_UNKNOWN) {
WarningPrint(WARN_NOMACHINESPECIFIED,
#if defined(_M_IX86)
"IX86");
targetMachine = IMAGE_FILE_MACHINE_I386;
targetRelocType = IMAGE_REL_I386_DIR32NB;
#elif defined(_M_RX000)
"MIPS");
targetMachine = IMAGE_FILE_MACHINE_R4000;
targetRelocType = IMAGE_REL_MIPS_REFWORDNB;
#elif defined(_M_ALPHA)
"ALPHA");
targetMachine = IMAGE_FILE_MACHINE_ALPHA;
targetRelocType = IMAGE_REL_ALPHA_REFLONGNB;
#elif defined(_M_PPC)
"PPC");
targetMachine = IMAGE_FILE_MACHINE_POWERPC;
targetRelocType = IMAGE_REL_PPC_ADDR32NB;
#else
"unknown");
#endif
}
_splitpath(szInFile, szDrive, szDir, szFname, szExt);
if (szExt[0] == '\0') {
// If there is no extension, default to .res
_makepath(szInPath, szDrive, szDir, szFname, ".res");
szInFile = szInPath;
}
if ((fh = _fsopen(szInFile, "rb", _SH_DENYWR)) == NULL) {
ErrorPrint(ERR_CANTREADFILE, szInFile);
exit(1);
}
#if DBG
printf("Reading %s\n", szInFile);
#endif /* DBG */
lbytes = MySeek(fh, 0L, SEEK_END);
MySeek(fh, 0L, SEEK_SET);
if (szOutFile == NULL) {
// Default output file is input file with .obj extension
_makepath(szOutPath, szDrive, szDir, szFname, ".obj");
szOutFile = szOutPath;
}
if ((fhOut = _fsopen(szOutFile, "wb", _SH_DENYRW)) == NULL) {
ErrorPrint(ERR_CANTWRITEFILE, szOutFile);
exit(1);
}
#if DBG
printf("Writing %s\n", szOutFile);
#endif /* DBG */
_tzset();
// timeDate = (ULONG) time(NULL);
timeDate = (ULONG) (fReproducible ? -1 : time(NULL));
result = CvtRes(fh, fhOut, lbytes, fWritable, timeDate);
fclose(fh);
fclose(fhOut);
exit(result ? 0 : 1);
}
PVOID
MyAlloc(UINT nbytes)
{
UCHAR *s;
if ((s = (UCHAR*)calloc( 1, nbytes )) != NULL) {
return s;
}
ErrorPrint(ERR_OUTOFMEMORY, nbytes );
exit(1);
}
PVOID
MyFree( PVOID p )
{
if (p)
free( p );
return NULL;
}
USHORT
MyReadWord(FILE *fh, USHORT*p)
{
UINT n1;
if ((n1 = fread(p, 1, sizeof(USHORT), fh)) != sizeof(USHORT)) {
ErrorPrint( ERR_FILEREADERR);
exit(1);
}
else
return 0;
}
UINT
MyRead(FILE *fh, PVOID p, UINT n )
{
UINT n1;
if ((n1 = fread( p, 1, n, fh)) != n) {
ErrorPrint( ERR_FILEREADERR );
exit(1);
}
else
return 0;
}
LONG
MyTell( FILE *fh )
{
long pos;
if ((pos = ftell( fh )) == -1) {
ErrorPrint(ERR_FILETELLERR );
exit(1);
}
return pos;
}
LONG
MySeek( FILE *fh, long pos, int cmd )
{
if ((pos = fseek( fh, pos, cmd )) == -1) {
ErrorPrint(ERR_FILESEEKERR );
exit(1);
}
return MyTell(fh);
}
ULONG
MoveFilePos( FILE *fh, USHORT pos, int alignment )
{
long newpos;
newpos = (long)pos;
newpos <<= alignment;
return MySeek( fh, newpos, SEEK_SET );
}
UINT
MyWrite( FILE *fh, PVOID p, UINT n )
{
ULONG n1;
if ((n1 = fwrite( p, 1, n, fh )) != n) {
ErrorPrint(ERR_FILEWRITEERR );
exit(1);
}
else
return 0;
}
#undef BUFSIZE
#define BUFSIZE 1024
int
MyCopy( FILE *srcfh, FILE *dstfh, ULONG nbytes )
{
static UCHAR buffer[ BUFSIZE ];
UINT n;
ULONG cb=0L;
while (nbytes) {
if (nbytes <= BUFSIZE)
n = (UINT)nbytes;
else
n = BUFSIZE;
nbytes -= n;
if (!MyRead( srcfh, buffer, n )) {
cb += n;
MyWrite( dstfh, buffer, n );
}
else {
return cb;
}
}
return cb;
}
void
ErrorPrint(
USHORT errnum,
...
)
{
va_list va;
va_start(va, errnum);
printf(get_err(MSG_ERROR), errnum, ' ');
vprintf(get_err(errnum), va);
printf("\n");
va_end(va);
}
void
WarningPrint(
USHORT errnum,
...
)
{
va_list va;
va_start(va, errnum);
printf(get_err(MSG_WARNING), errnum, ' ');
vprintf(get_err(errnum), va);
printf("\n");
va_end(va);
}
#if 0
/***
*splitpath.c - break down path name into components
*
* Copyright (c) 1987-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
* To provide support for accessing the individual components of an
* arbitrary path name
*
*Revision History:
* 06-14-87 DFW initial implementation
* 09-23-87 JCR Removed 'const' from declarations (fixed cl warnings)
* 12-11-87 JCR Added "_LOAD_DS" to declaration
* 11-20-89 GJF Fixed indents, copyright. Added const attribute to
* type of path.
* 03-15-90 GJF Replaced _LOAD_DS with _CALLTYPE1 and added #include
* <cruntime.h>.
* 07-25-90 SBM Removed redundant include (stdio.h), replaced local
* MIN macro with standard min macro
* 10-04-90 GJF New-style function declarator.
* 01-22-91 GJF ANSI naming.
* 11-20-92 KRS Port _MBCS support from 16-bit tree.
* 05-12-93 KRS Add fix for MBCS max path handling.
*
*******************************************************************************/
/***
*_splitpath() - split a path name into its individual components
*
*Purpose:
* to split a path name into its individual components
*
*Entry:
* path - pointer to path name to be parsed
* drive - pointer to buffer for drive component, if any
* dir - pointer to buffer for subdirectory component, if any
* fname - pointer to buffer for file base name component, if any
* ext - pointer to buffer for file name extension component, if any
*
*Exit:
* drive - pointer to drive string. Includes ':' if a drive was given.
* dir - pointer to subdirectory string. Includes leading and trailing
* '/' or '\', if any.
* fname - pointer to file base name
* ext - pointer to file extension, if any. Includes leading '.'.
*
*Exceptions:
*
*******************************************************************************/
void _CRTAPI1 _splitpath (
register const char *path,
char *drive,
char *dir,
char *fname,
char *ext
)
{
register char *p;
char *last_slash = NULL, *dot = NULL;
unsigned len;
UINT uiCodePage = GetACP();
/* we assume that the path argument has the following form, where any
* or all of the components may be missing.
*
* <drive><dir><fname><ext>
*
* and each of the components has the following expected form(s)
*
* drive:
* 0 to _MAX_DRIVE-1 characters, the last of which, if any, is a
* ':'
* dir:
* 0 to _MAX_DIR-1 characters in the form of an absolute path
* (leading '/' or '\') or relative path, the last of which, if
* any, must be a '/' or '\'. E.g -
* absolute path:
* \top\next\last\ ; or
* /top/next/last/
* relative path:
* top\next\last\ ; or
* top/next/last/
* Mixed use of '/' and '\' within a path is also tolerated
* fname:
* 0 to _MAX_FNAME-1 characters not including the '.' character
* ext:
* 0 to _MAX_EXT-1 characters where, if any, the first must be a
* '.'
*
*/
/* extract drive letter and :, if any */
if (*(path + _MAX_DRIVE - 2) == ':') {
if (drive) {
strncpy(drive, path, _MAX_DRIVE - 1);
*(drive + _MAX_DRIVE-1) = '\0';
}
path += _MAX_DRIVE - 1;
}
else if (drive) {
*drive = '\0';
}
/* extract path string, if any. Path now points to the first character
* of the path, if any, or the filename or extension, if no path was
* specified. Scan ahead for the last occurence, if any, of a '/' or
* '\' path separator character. If none is found, there is no path.
* We will also note the last '.' character found, if any, to aid in
* handling the extension.
*/
for (last_slash = NULL, p = (char *)path; *p; p++) {
if (IsDBCSLeadByteEx(uiCodePage, *p))
p++;
else {
if (*p == '/' || *p == '\\')
/* point to one beyond for later copy */
last_slash = p + 1;
else if (*p == '.')
dot = p;
}
}
if (last_slash) {
/* found a path - copy up through last_slash or max. characters
* allowed, whichever is smaller
*/
if (dir) {
len = __min((last_slash - path), (_MAX_DIR - 1));
strncpy(dir, path, len);
*(dir + len) = '\0';
}
path = last_slash;
}
else if (dir) {
/* no path found */
*dir = '\0';
}
/* extract file name and extension, if any. Path now points to the
* first character of the file name, if any, or the extension if no
* file name was given. Dot points to the '.' beginning the extension,
* if any.
*/
if (dot && (dot >= path)) {
/* found the marker for an extension - copy the file name up to
* the '.'.
*/
if (fname) {
len = __min((dot - path), (_MAX_FNAME - 1));
strncpy(fname, path, len);
*(fname + len) = '\0';
}
/* now we can get the extension - remember that p still points
* to the terminating nul character of path.
*/
if (ext) {
len = __min((p - dot), (_MAX_EXT - 1));
strncpy(ext, dot, len);
*(ext + len) = '\0';
}
}
else {
/* found no extension, give empty extension and copy rest of
* string into fname.
*/
if (fname) {
len = __min((p - path), (_MAX_FNAME - 1));
strncpy(fname, path, len);
*(fname + len) = '\0';
}
if (ext) {
*ext = '\0';
}
}
}
#endif