windows-nt/Source/XPSP1/NT/sdktools/restools/rltools/common/resread.c

1274 lines
33 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
//#include <malloc.h>
#include <tchar.h>
//#include <assert.h>
//#include <sys\types.h>
//#include <sys\stat.h>
#include <fcntl.h>
#ifdef RLDOS
#include "dosdefs.h"
#else //RLDOS
#include <windows.h>
#include "windefs.h"
#endif //RLDOS
#include "resread.h"
#include "restok.h"
#include "custres.h"
#ifdef RLRES32
#include "exentres.h"
#include "reswin16.h"
#else //RLRES32
#include "exe2res.h"
#endif //RLRES32
UCHAR szDHW[ DHWSIZE]; //... Common temporary buffer
char * gszTmpPrefix = "$RLT"; //... Temporary name prefix
BOOL gbMaster = FALSE; //... TRUE if Working in Master project
BOOL gfReplace = TRUE; //... FALSE if appending new language to exe
BOOL gbShowWarnings = FALSE; //... Display warnining messages if TRUE
#ifdef _DEBUG
PMEMLIST pMemList = NULL;
#endif
static BOOL ShouldBeAnExe( CHAR *);
static BOOL NotExistsOrIsEmpty( PCHAR szTargetTokFile);
/**
*
*
* Function: DWORDfpUP
* Move the file pointer to the next 32 bit boundary.
*
*
* Arguments:
* Infile: File pointer to seek
* plSize: Address of Resource size var
*
* Returns:
* Number of padding to next 32 bit boundary, and addjusts resource size var
*
* Errors Codes:
* -1, fseek failed
*
* History:
* 10/11/91 Implemented TerryRu
*
*
**/
DWORD DWORDfpUP(FILE * InFile, DWORD *plSize)
{
DWORD tPos;
DWORD Align;
tPos = (ftell(InFile));
Align = DWORDUP(tPos);
*plSize -= (Align - tPos);
fseek( InFile, Align, SEEK_SET);
return ( Align - tPos);
}
/*
*
* Function GetName,
* Copies a name from the OBJ file into the ObjInfo Structure.
*
*/
void GetName( FILE *infile, TCHAR *szName , DWORD *lSize)
{
WORD i = 0;
do {
#ifdef RLRES16
szName[ i ] = GetByte( infile, lSize);
#else
szName[ i ] = GetWord( infile, lSize);
#endif
} while ( szName[ i++ ] != TEXT('\0') );
}
/*
*
* Function MyAlloc:
* Memory allocation routine with error checking.
*
*/
#ifdef _DEBUG
PBYTE MyAlloc( DWORD dwSize, LPSTR pszFile, WORD wLine)
#else
PBYTE MyAlloc( DWORD dwSize)
#endif
{
PBYTE ptr = NULL;
HGLOBAL hMem = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT,
(size_t)((dwSize > 0) ? dwSize : sizeof( TCHAR)));
if ( hMem == NULL ) {
QuitT( IDS_ENGERR_11, NULL, NULL);
} else {
ptr = GlobalLock( hMem);
}
#ifdef _DEBUG
{
PMEMLIST pTmpMem = (PMEMLIST)GlobalAlloc( GPTR, sizeof( MEMLIST));
pTmpMem->pNext = pMemList;
pMemList = pTmpMem;
lstrcpyA( pMemList->szMemFile, pszFile);
pMemList->wMemLine = wLine;
pMemList->pMem = ptr;
}
#endif // _DEBUG
return ( ptr); // memory allocation okay.
}
//..........................................................................
//ppc cause access violation
void MyFree( void *UNALIGNED*p)
{
if ( p && *p ) {
#ifdef _DEBUG
FreeMemListItem( *p, NULL);
#else
HGLOBAL hMem = GlobalHandle( (HANDLE)*p);
GlobalUnlock( hMem);
GlobalFree( hMem);
#endif // _DEBUG
*p = NULL;
}
}
#ifdef _DEBUG
void FreeMemList( FILE *pfMemFile)
{
while ( pMemList ) {
FreeMemListItem( pMemList->pMem, pfMemFile);
}
}
void FreeMemListItem( void *p, FILE *pfMemFile)
{
if ( pMemList && p ) {
PMEMLIST pThisMem = NULL;
PMEMLIST pNextMem = NULL;
PMEMLIST pPrevMem = NULL;
for ( pThisMem = pMemList; pThisMem; pThisMem = pNextMem ) {
pNextMem = pThisMem->pNext;
if ( pThisMem->pMem == p ) {
HGLOBAL hMem = NULL;
if ( pfMemFile ) {
fprintf( pfMemFile,
"%u\t%s\n",
pThisMem->wMemLine,
pThisMem->szMemFile);
}
hMem = GlobalHandle( p);
GlobalUnlock( hMem);
GlobalFree( hMem);
GlobalFree( pThisMem);
if ( pPrevMem ) {
pPrevMem->pNext = pNextMem;
} else {
pMemList = pNextMem;
}
break;
}
pPrevMem = pThisMem;
}
}
}
#endif // _DEBUG
/*
*
* Function MyReAlloc
*
* Re-allocate memory with error checking.
*
* History:
* 01/21/93 MHotchin Implemented.
*
*/
#ifdef _DEBUG
PBYTE MyReAlloc(
PBYTE pOldMem, //... Current ptr to buffer
DWORD cSize, //... New size for buffer
LPSTR pszFile,
WORD wLine)
#else
PBYTE MyReAlloc(
PBYTE pOldMem, //... Current ptr to buffer
DWORD cSize) //... New size for buffer
#endif // _DEBUG
{
PBYTE ptr = NULL;
HGLOBAL hMem = NULL;
hMem = GlobalHandle( pOldMem);
if ( hMem == NULL ) {
QuitT( IDS_ENGERR_11, NULL, NULL);
}
if ( GlobalUnlock( hMem) || GetLastError() != NO_ERROR ) {
QuitT( IDS_ENGERR_11, NULL, NULL);
}
hMem = GlobalReAlloc( hMem, cSize, GMEM_MOVEABLE | GMEM_ZEROINIT);
if ( hMem == NULL ) {
QuitT( IDS_ENGERR_11, NULL, NULL);
}
ptr = GlobalLock( hMem);
#ifdef _DEBUG
if ( ptr != pOldMem ) {
PMEMLIST pThisMem = NULL;
PMEMLIST pNextMem = NULL;
for ( pThisMem = pMemList; pThisMem; pThisMem = pThisMem->pNext ) {
if ( pThisMem->pMem == pOldMem ) {
pThisMem->pMem = ptr;
break;
}
}
}
#endif // _DEBUG
return ( ptr);
}
/*
*
* Function GetByte:
* Reads a byte from the input file stream, and checks for EOF.
*
*/
BYTE GetByte(FILE *pInFile, DWORD *pdwSize)
{
register int n;
if ( pdwSize ) {
(*pdwSize)--;
}
n = fgetc( pInFile);
if ( n == EOF ) {
if ( feof( pInFile) ) {
exit(-1);
}
}
return ( (BYTE)n);
}
/*
*
* Function UnGetByte:
*
* Returns the character C into the input stream, and updates the Record Length.
*
* Calls:
* ungetc, To return character
* DiffObjExit, If unable to insert the character into the input stream
*
* Caller:
* GetFixUpP,
*
*/
void UnGetByte(FILE *infile, BYTE c, DWORD *lSize)
{
if (lSize) {
(*lSize)++;
}
if (ungetc(c, infile)== EOF) {
exit (-1);
}
// c put back into input stream
}
/*
*
* Function UnGetWord:
*
* Returns the word C into the input stream, and updates the Record Length.
*
* Calls:
*
* Caller:
*
*/
void UnGetWord(FILE *infile, WORD c, DWORD *lSize)
{
long lCurrentOffset;
if (lSize) {
(*lSize) += 2;
}
lCurrentOffset = ftell(infile);
if (fseek(infile, (lCurrentOffset - 2L) , SEEK_SET)) {
exit (-1);
}
}
/*
*
* Function SkipBytes:
* Reads and ignores n bytes from the input stream
*
*/
void SkipBytes(FILE *infile, DWORD *pcBytes)
{
if (fseek(infile, (DWORD) *pcBytes, SEEK_CUR) == -1L) {
exit (-1);
}
*pcBytes=0;
}
/*
* Function GetWord:
* Reads a WORD from the RES file.
*
*/
WORD GetWord(FILE *infile, DWORD *lSize)
{
// Get low order byte
register WORD lobyte;
lobyte = GetByte(infile, lSize);
return (lobyte + (GetByte(infile, lSize) << BYTELN));
}
/*
*
* Function GetDWORD:
* Reads a Double WORD from the OBJ file.
*
*/
DWORD GetdWord(FILE *infile, DWORD *lSize)
{
DWORD dWord = 0;
dWord = (DWORD) GetWord(infile, lSize);
// Get low order word
// now get high order word, shift into upper word and or in low order word
dWord |= ((DWORD) GetWord(infile, lSize) << WORDLN);
return (dWord);
// return complete double word
}
void PutByte(FILE *Outfile, TCHAR b, DWORD *plSize)
{
if (plSize) {
(*plSize) ++;
}
if (fputc(b, Outfile) == EOF) {
exit(-1);
}
}
void PutWord(FILE *OutFile, WORD w, DWORD *plSize)
{
PutByte(OutFile, (BYTE) LOBYTE(w), plSize);
PutByte(OutFile, (BYTE) HIBYTE(w), plSize);
}
void PutdWord (FILE *OutFile, DWORD l, DWORD *plSize)
{
PutWord(OutFile, LOWORD(l), plSize);
PutWord(OutFile, HIWORD(l), plSize);
}
void PutString( FILE *OutFile, TCHAR *szStr , DWORD *plSize)
{
WORD i = 0;
do {
#ifdef RLRES16
PutByte( OutFile , szStr[ i ], plSize);
#else
PutWord( OutFile , szStr[ i ], plSize);
#endif
} while ( szStr[ i++ ] != TEXT('\0') );
}
/**
* Function: MyGetTempFileName
* Generic funciton to create a unique file name,
* using the API GetTempFileName. This
* function is necessary because of the parameters
* differences betweenLWIN16, and WIN32.
*
*
* Arguments:
* BYTE hDriveLetter
* LPCSTR lpszPrefixString
* UINT uUnique
* LPSTR lpszTempFileName
*
* Returns:
* lpszFileNameTempFileName
*
*
* Error Codes:
* 0 - invalid path returned
* 1 - valid path returned
*
* History:
* 3/92, Implemented TerryRu
*/
int MyGetTempFileName(BYTE hDriveLetter,
LPSTR lpszPrefixString,
WORD wUnique,
LPSTR lpszTempFileName)
{
#ifdef RLWIN16
return (GetTempFileName(hDriveLetter,
(LPCSTR)lpszPrefixString,
(UINT)wUnique,
lpszTempFileName));
#else //RLWIN16
#ifdef RLWIN32
UINT uRC;
CHAR szPathName[ MAX_PATH+1];
if (! GetTempPathA((DWORD)sizeof(szPathName), (LPSTR)szPathName)) {
szPathName[0] = '.';
szPathName[1] = '\0';
}
uRC = GetTempFileNameA((LPSTR)szPathName,
lpszPrefixString,
wUnique,
lpszTempFileName);
return ((int)uRC);
#else //RLWIN32
return (tmpnam(lpszTempFileName) == NULL ? 0 : 1);
#endif // RLWIN32
#endif // RLWIN16
}
/**
* Function GenerateImageFile:
* builds a resource from the token and rdf files
*
* History:
* 2/92, implemented SteveBl
* 7/92, modified to always use a temporary file SteveBl
*/
int GenerateImageFile(
CHAR * szTargetImage,
CHAR * szSrcImage,
CHAR * szTOK,
CHAR * szRDFs,
WORD wFilter)
{
CHAR szTmpInRes[ MAXFILENAME];
CHAR szTmpOutRes[ MAXFILENAME];
CHAR szTmpTargetImage[ MAXFILENAME];
BOOL bTargetExe = FALSE;
BOOL bSrcExe = FALSE;
int nExeType = NOTEXE;
int rc;
FILE *fIn = NULL;
FILE *fOut = NULL;
if ( IsRes( szTOK) ) {
// The given szTOK file is really a localized resource file,
// place these resources into outputimage file
MyGetTempFileName( 0, "TMP", 0, szTmpTargetImage);
if ( IsWin32Res( szTOK) ) {
rc = BuildExeFromRes32A( szTmpTargetImage, szTOK, szSrcImage);
} else {
rc = BuildExeFromRes16A( szTmpTargetImage, szTOK, szSrcImage);
}
if ( rc != 1 ) {
remove( szTmpTargetImage);
QuitT( IDS_ENGERR_16, (LPTSTR)IDS_NOBLDEXERES, NULL);
}
if ( ! CopyFileA( szTmpTargetImage, szTargetImage, FALSE) ) {
remove( szTmpTargetImage);
QuitA( IDS_COPYFILE_FAILED, szTmpTargetImage, szTargetImage);
}
remove( szTmpTargetImage);
return ( rc);
}
// We're going to now do this EVERY time. Even if the target doesn't
// exist. This will enable us to always work, even if we get two different
// paths that resolve to the same file.
MyGetTempFileName(0, "TMP", 0, szTmpTargetImage);
rc = IsExe( szSrcImage);
if ( rc == NTEXE || rc == WIN16EXE ) {
//... resources contained in image file
nExeType = rc;
MyGetTempFileName( 0, "RES", 0, szTmpInRes);
if ( nExeType == NTEXE ) {
ExtractResFromExe32A( szSrcImage, szTmpInRes, wFilter);
} else {
ExtractResFromExe16A( szSrcImage, szTmpInRes, wFilter);
}
bSrcExe = TRUE;
} else if ( rc == -1 ) {
QuitA( IDS_ENGERR_01, "original source", szSrcImage);
} else if ( rc == NOTEXE ) {
if ( ShouldBeAnExe( szSrcImage) ) {
QuitA( IDS_ENGERR_18, szSrcImage, NULL);
}
} else {
QuitA( IDS_ENGERR_18, szSrcImage, NULL);
}
if ( IsRes( szTargetImage) ) {
bTargetExe = FALSE;
} else {
bTargetExe = TRUE;
}
// check for valid input files
if ( bSrcExe == TRUE && bTargetExe == FALSE ) {
if ( nExeType == NTEXE ) {
GenerateRESfromRESandTOKandRDFs( szTargetImage,
szTmpInRes,
szTOK,
szRDFs,
FALSE);
return 1;
} else {
return -1; //... Can not generate a win16 .RES (yet)
}
}
if ( bSrcExe == FALSE && bTargetExe == TRUE ) {
// can not go from res to exe
return -1;
}
// okay we have valid file inputs, generate image file
if ( bSrcExe ) {
// create name for temporary localized resource file
MyGetTempFileName(0, "RES", 0, szTmpOutRes);
GenerateRESfromRESandTOKandRDFs( szTmpOutRes,
szTmpInRes,
szTOK,
szRDFs,
FALSE);
// now szTmpOutRes file is a localized resource file,
// place these resources into outputimage file
if ( nExeType == NTEXE ) {
rc = BuildExeFromRes32A( szTmpTargetImage, szTmpOutRes, szSrcImage);
} else {
// rc = BuildExeFromRes16A( szTmpTargetImage, szTmpOutRes, szSrcImage);
remove( szTmpInRes);
remove( szTmpOutRes);
remove( szTmpTargetImage);
QuitT( IDS_ENGERR_16, (LPTSTR)IDS_NOBLDEXERES, NULL);
}
// now clean up temporary files
remove( szTmpInRes);
remove( szTmpOutRes);
if ( rc != 1 ) {
remove( szTmpTargetImage);
QuitT( IDS_ENGERR_16, (LPTSTR)IDS_NOBLDEXERES, NULL);
}
if ( ! CopyFileA( szTmpTargetImage, szTargetImage, FALSE) ) {
remove( szTmpTargetImage);
QuitA( IDS_COPYFILE_FAILED, szTmpTargetImage, szTargetImage);
}
remove( szTmpTargetImage);
// szTargetImage is now generated,
return 1;
}
if ( ! bSrcExe ) {
// image files are resource files
if ( szTmpTargetImage[0] ) {
GenerateRESfromRESandTOKandRDFs( szTmpTargetImage,
szSrcImage,
szTOK,
szRDFs,
FALSE);
}
if ( ! CopyFileA( szTmpTargetImage, szTargetImage, FALSE) ) {
remove( szTmpTargetImage);
QuitA( IDS_COPYFILE_FAILED, szTmpTargetImage, szTargetImage);
}
remove( szTmpTargetImage);
// sztarget Image is now generated,
return 1;
}
return 1;
}
/**
* Function GenerateRESfromRESandTOKandRDFs:
* builds a resource from the token and rdf files
*
* History:
* 2/92, implemented SteveBl
*/
void GenerateRESfromRESandTOKandRDFs(
CHAR * szTargetRES, //... Output exe/res file name
CHAR * szSourceRES, //... Input exe/res file name
CHAR * szTOK, //... Input token file name
CHAR * szRDFs, //... Custom resource definition file name
WORD wFilter)
{
FILE * fTok = NULL;
FILE * fSourceRes = NULL;
FILE * fTargetRes = NULL;
LoadCustResDescriptions( szRDFs);
if ( (fTargetRes = FOPEN( szTargetRES, "wb")) != NULL ) {
if ( (fSourceRes = FOPEN( szSourceRES, "rb")) != NULL ) {
if ( (fTok = FOPEN( szTOK, "rt")) != NULL ) {
ReadWinRes( fSourceRes,
fTargetRes,
fTok,
TRUE, //... Building res/exe file
FALSE, //... Not building token file
wFilter);
FCLOSE( fTok);
FCLOSE( fSourceRes);
FCLOSE( fTargetRes);
ClearResourceDescriptions();
} else {
FCLOSE( fSourceRes);
FCLOSE( fTargetRes);
ClearResourceDescriptions();
QuitA( IDS_ENGERR_01, "token", szTOK);
}
} else {
FCLOSE( fTargetRes);
ClearResourceDescriptions();
QuitA( IDS_ENGERR_20, (LPSTR)IDS_INPUT, szSourceRES);
}
} else {
ClearResourceDescriptions();
QuitA( IDS_ENGERR_20, (LPSTR)IDS_OUTPUT, szSourceRES);
}
}
int GenerateTokFile(
char *szTargetTokFile, //... Target token file, created or updated here
char *szSrcImageFile, //... File from which tokens are to be made
BOOL *pbTokensChanged, //... Set TRUE here if any token changes
WORD wFilter)
{
BOOL bExeFile = FALSE;
int rc = 0;
FILE *fTokFile = NULL;
FILE *fResFile = NULL;
FILE *fTmpTokFile = NULL;
FILE *fCurTokFile = NULL;
FILE *fNewTokFile = NULL;
static char *pchTRes = NULL;
static char *pchTTok = NULL;
static char *pchTMerge = NULL;
*pbTokensChanged = FALSE; //... Assume nothing is changed
rc = IsExe( szSrcImageFile);
if ( rc == NOTEXE ) {
if ( ShouldBeAnExe( szSrcImageFile) ) {
QuitA( IDS_ENGERR_18, szSrcImageFile, NULL);
} else { //... Src file must be a .RES file
bExeFile = FALSE;
pchTRes = szSrcImageFile;
}
} else {
if ( rc == NTEXE || rc == WIN16EXE ) {
//... Resources are stored in a exe file
//... extract resources out of exe file into
//... a temporary file.
pchTRes = _tempnam( "", gszTmpPrefix);
if ( rc == NTEXE ) {
rc = ExtractResFromExe32A( szSrcImageFile,
pchTRes,
wFilter);
} else {
QuitA( IDS_ENGERR_19, szSrcImageFile, "16");
// rc = ExtractResFromExe16A( szSrcImageFile,
// pchTRes,
// wFilter);
}
if ( rc != 0 ) {
return ( 1);
}
bExeFile = TRUE;
} else if ( rc == -1 ) {
QuitA( IDS_ENGERR_01, "source image", szSrcImageFile);
} else {
QuitA( IDS_ENGERR_18, szSrcImageFile, NULL);
}
}
//... now extract tokens out of resource file
//... Open res file
if ( (fResFile = FOPEN( pchTRes, "rb")) == NULL ) {
QuitA( IDS_ENGERR_01,
bExeFile ? "temporary resource" : "resource",
pchTRes);
}
//... Does the token file already exist?
if ( NotExistsOrIsEmpty( szTargetTokFile) ) {
//... No, token file does not exist.
if ( (fTokFile = FOPEN( szTargetTokFile, "wt")) == NULL ) {
FCLOSE( fResFile);
QuitA( IDS_ENGERR_02, szTargetTokFile, NULL);
}
ReadWinRes( fResFile,
NULL,
fTokFile,
FALSE, //... Not building res/exe file
TRUE, //... Building token file
wFilter);
FCLOSE( fResFile);
FCLOSE( fTokFile);
} else {
//... token file exists
//... create a temporary file, and try to
//... merge with existing one
pchTTok = _tempnam( "", gszTmpPrefix);
pchTMerge = _tempnam( "", gszTmpPrefix);
//... open temporary file name
if ( (fTmpTokFile = FOPEN( pchTTok, "wt")) == NULL ) {
FCLOSE( fResFile);
QuitA( IDS_ENGERR_02, pchTTok, NULL);
}
//... write tokens to temporary file
ReadWinRes( fResFile,
NULL,
fTmpTokFile,
FALSE, //... Not building res/exe file
TRUE, //... Building token file
wFilter);
FCLOSE( fResFile);
FCLOSE( fTmpTokFile);
//... now merge temporary file with existing
//... file open temporary token file
if ( (fTmpTokFile = FOPEN( pchTTok, "rt")) == NULL ) {
QuitA( IDS_ENGERR_01, "temporary token", pchTTok);
}
//... open current token file
if ( (fCurTokFile = FOPEN( szTargetTokFile, "rt")) == NULL ) {
FCLOSE( fTmpTokFile);
QuitA( IDS_ENGERR_01, "current token", szTargetTokFile);
}
//... open new tok file name
if ( (fNewTokFile = FOPEN( pchTMerge, "wt")) == NULL ) {
FCLOSE( fTmpTokFile);
FCLOSE( fCurTokFile);
QuitA( IDS_ENGERR_02, pchTMerge, NULL);
}
//... Merge current tokens with temporary tokens
*pbTokensChanged = MergeTokFiles( fNewTokFile,
fCurTokFile,
fTmpTokFile);
FCLOSE( fNewTokFile);
FCLOSE( fTmpTokFile);
FCLOSE( fCurTokFile);
//... bpTokensChanged, only valid if creating
//... master token files so force it to be
//... always true if building proj token files.
if ( gbMaster == FALSE ) {
*pbTokensChanged = TRUE;
}
if ( *pbTokensChanged ) {
if ( ! CopyFileA( pchTMerge, szTargetTokFile, FALSE) ) {
remove( pchTTok);
remove( pchTMerge);
RLFREE( pchTMerge);
QuitA( IDS_COPYFILE_FAILED, pchTMerge, szTargetTokFile);
}
}
remove( pchTTok);
remove( pchTMerge);
RLFREE( pchTTok);
RLFREE( pchTMerge);
}
//... now szTargetTokFile contains latest
//... tokens form szImageFile
//... Clean up if we made a temp .RES file
if ( bExeFile ) {
rc = remove( pchTRes);
RLFREE( pchTRes);
}
return ( 0);
}
BOOL ResReadBytes(
FILE *InFile, //... File to read from
CHAR *pBuf, //... Buffer to write to
size_t dwSize, //... # bytes to read
DWORD *plSize) //... bytes-read counter (or NULL)
{
size_t dwcRead = 0;
dwcRead = fread( pBuf, 1, dwSize, InFile);
if ( dwcRead == dwSize ) {
if ( plSize ) {
*plSize -= dwcRead;
}
return ( TRUE);
}
return ( FALSE);
}
int InsDlgToks( PCHAR szCurToks, PCHAR szDlgToks, WORD wFilter)
{
CHAR szMrgToks[MAXFILENAME];
FILE * fCurToks = NULL;
FILE * fDlgToks = NULL;
FILE * fMrgToks = NULL;
TOKEN Tok1, Tok2;
MyGetTempFileName(0,"TOK",0,szMrgToks);
fMrgToks = FOPEN(szMrgToks, "w");
fCurToks = FOPEN(szCurToks, "r");
fDlgToks = FOPEN(szDlgToks, "r");
if (! (fMrgToks && fCurToks && fDlgToks)) {
return -1;
}
while (!GetToken(fCurToks, &Tok1)) {
if (Tok1.wType != wFilter) {
PutToken(fMrgToks, &Tok1);
RLFREE(Tok1.szText);
continue;
}
Tok2.wType = Tok1.wType;
Tok2.wName = Tok1.wName;
Tok2.wID = Tok1.wID;
Tok2.wFlag = Tok1.wFlag;
Tok2.wLangID = Tok1.wLangID;
Tok2.wReserved = 0 ;
lstrcpy( Tok2.szType, Tok1.szType);
lstrcpy( Tok2.szName, Tok1.szName);
Tok2.szText = NULL;
if (FindToken(fDlgToks, &Tok2, 0)) {
Tok2.wReserved = Tok1.wReserved ;
PutToken(fMrgToks, &Tok2);
RLFREE(Tok2.szText);
} else {
PutToken(fMrgToks, &Tok1);
}
RLFREE(Tok1.szText);
}
FCLOSE (fMrgToks);
FCLOSE (fCurToks);
if ( ! CopyFileA( szMrgToks, szCurToks, FALSE) ) {
remove( szDlgToks);
remove( szMrgToks);
QuitA( IDS_COPYFILE_FAILED, szMrgToks, szCurToks);
}
remove(szMrgToks);
return 1;
}
//+-----------------------------------------------------------------------
//
// MergeTokFiles
//
// Returns: TRUE if a token changed, was added, or was deleted else FALSE
//
// History:
// 7-22-92 stevebl added return value
// 9-8-92 terryru changed order of translation/delta tokens
// 01-25-93 MHotchin Added changes to handle var length token
// text.
//------------------------------------------------------------------------
BOOL MergeTokFiles(
FILE *fNewTokFile, //... Final product of the merge process
FILE *fCurTokFile, //... The soon-to-be-old current token file
FILE *fTmpTokFile) //... The token file generated from the updated .EXE
{
TOKEN Tok1, Tok2;
BOOL bChangesDetected = FALSE; //... Set TRUE if any token changes found
BOOL bChangedText = FALSE; //... TRUE if a token's text has changed
WORD cTokenCount = 0; //... Count of tokens in the new token file
//... Scan through the new token file. For
//... every token in the new token file, find
//... the corresponding token in the current
//... token file. This process will make sure
//... tokens that are no longer in the .EXE
//... will not be in the final token file.
while ( GetToken( fTmpTokFile, &Tok1) == 0 ) {
++cTokenCount; //... Used in checking for deleted tokens
bChangedText = FALSE; //... assume the token did not change
//... Copy pertanent data to use in search
Tok2.wType = Tok1.wType;
Tok2.wName = Tok1.wName;
Tok2.wID = Tok1.wID;
Tok2.wFlag = Tok1.wFlag;
Tok2.wLangID = Tok1.wLangID;
Tok2.wReserved = 0;
Tok2.szText = NULL;
lstrcpy( Tok2.szType, Tok1.szType);
lstrcpy( Tok2.szName, Tok1.szName);
//... Now look for the corresponding token
//If token is Version stamp and szTexts is "Translation",
//it is 1.0 version format. So ignore it.
IGNORETRANSLATION:
if ( FindToken( fCurTokFile, &Tok2, 0) ) {
if ( gbMaster && !(Tok2.wReserved & ST_READONLY) ) {
if ( _tcscmp( (TCHAR *)Tok2.szText, (TCHAR *)Tok1.szText) ) {
//... Token text changed
//If the changes are only align info, translate it to the "unchanged" status.
int l1, r1, t1, b1, l2, r2, t2, b2;
TCHAR a1[20], a2[20];
//Cordinates token?
if ( (Tok1.wType==ID_RT_DIALOG) && (Tok1.wFlag&ISCOR)
//Including align info?
&& _stscanf(Tok1.szText,TEXT("%d %d %d %d %s"),
&l1,&r1,&t1,&b1,a1) == 5
//Not including align info?
&& _stscanf(Tok2.szText,TEXT("%d %d %d %d %s"),
&l2,&r2,&t2,&b2,a2) == 4
//Cordinates are same?
&& l1==l2 && r1==r2 && t1==t2 && b1==b2 ) {
Tok1.wReserved = 0;
} else {
//If token is Version stamp and szTexts is "Translation",
//it is 1.0 version format. So ignore it.
if ( Tok1.wType == ID_RT_VERSION
&& !_tcscmp( Tok2.szText, TEXT("Translation")) ) {
if ( Tok2.szText != NULL ) {
RLFREE( Tok2.szText);
}
Tok2.szText = NULL;
Tok2.wFlag = 1;
goto IGNORETRANSLATION;
}
bChangedText = bChangesDetected = TRUE;
Tok1.wReserved = ST_CHANGED|ST_NEW;
Tok2.wReserved = ST_CHANGED;
}
} else {
Tok1.wReserved = 0;
}
} else {
Tok1.wReserved = Tok2.wReserved;
}
} else {
//... Must be a new token (not in current token file)
//If token is Version stump, and old mtk is 1.0 data file, convert it.
if ( Tok1.wType==ID_RT_VERSION ) {
Tok2.szText = NULL;
Tok2.wFlag = 1;
_tcscpy( Tok2.szName, TEXT("VALUE") );
if ( FindToken( fCurTokFile, &Tok2, 0)
&& ! lstrcmp( Tok1.szText, Tok2.szText) ) {
Tok1.wReserved = Tok2.wReserved;
} else
Tok1.wReserved = ST_TRANSLATED | ST_DIRTY;
} else {
Tok1.wReserved = ST_TRANSLATED | ST_DIRTY;
}
bChangesDetected = TRUE;
}
//... Copy token from new token file to final token
//... file. If a change was detected, then copy the
//... original token (from the "current" token file
//... into the final token file.
PutToken( fNewTokFile, &Tok1);
RLFREE( Tok1.szText);
if ( bChangedText ) {
PutToken( fNewTokFile, &Tok2);
// now delta tokens follow translation tokens
}
if ( Tok2.szText != NULL ) {
RLFREE( Tok2.szText);
}
}
if ( ! bChangesDetected ) {
// We have to test to be sure that no tokens were deleted
// since we know that none changed.
rewind( fCurTokFile);
//... Look for tokens that exist in the current
//... token file that do not exist in the token
//... file created from the updated .EXE.
while ( GetToken( fCurTokFile, &Tok1) == 0 ) {
--cTokenCount;
RLFREE( Tok1.szText);
}
if ( cTokenCount != 0 ) {
bChangesDetected = TRUE;
}
}
return ( bChangesDetected);
}
void MakeNewExt(char *NewName, char *OldName, char *ext)
{
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME]; // dummy vars to hold file name info
char dext[_MAX_EXT];
// Split obj file name into filename and extention
_splitpath(OldName, drive, dir, fname, dext);
// Make new file name with new ext extention
_makepath(NewName, drive, dir, fname, ext);
}
//......................................................................
//...
//... Check to see if the given file name *should* be an EXE
//...
//... Return: TRUE if it should, else FALSE.
static BOOL ShouldBeAnExe( PCHAR szFileName)
{
PCHAR psz;
if ( (psz = strrchr( szFileName, '.')) != NULL ) {
if ( IsRes( szFileName) ) {
return ( FALSE);
} else if ( lstrcmpiA( psz, ".exe") == 0
|| lstrcmpiA( psz, ".dll") == 0
|| lstrcmpiA( psz, ".com") == 0
|| lstrcmpiA( psz, ".scr") == 0
|| lstrcmpiA( psz, ".cpl") == 0 ) {
return ( TRUE);
}
//... Because we think this case of filename
//... would be not executable file rather than res file.
else if ( lstrcmpiA( psz, ".tmp") == 0 ) { //for tmp file created by Dlgedit
return ( FALSE );
} else {
return ( TRUE );
}
}
return ( FALSE);
}
//.........................................................
//...
//... If the named file exists and is not empty, return FALSE, else TRUE.
static BOOL NotExistsOrIsEmpty( PCHAR pszFileName)
{
BOOL fRC = TRUE;
int hFile = -1;
//... Does file not exist?
if ( _access( pszFileName, 0) == 0 ) {
//... No, file exists. Open it.
if ( (hFile = _open( pszFileName, _O_RDONLY)) != -1 ) {
//... Is it Empty?
if ( _filelength( hFile) == 0L ) {
fRC = TRUE; //... Yes, file is empty.
} else {
fRC = FALSE; //... No, file is not empty.
}
_close( hFile);
} else {
QuitA( IDS_ENGERR_01, "non-empty", pszFileName);
}
} else {
fRC = TRUE; //... Yes, file does not exist.
}
return ( fRC);
}