|
|
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "windefs.h"
#include "restok.h"
#include "exentres.h"
#include "resread.h"
#include "checksum.h"
#define SAME 0 //... Used in string compares
#define MAXLEVELS 3 //... Max # of levels in resource directory
typedef struct tagResSectData { ULONG ulVirtualAddress; //... Virtual address of section .rsrc
ULONG ulSizeOfResources; //... Size of resources in section .rsrc
ULONG ulVirtualSize; //... Virtual Size of resources in .rsrc
ULONG ulVirtualAddressX; //... Virtual address of section .rsrc1
ULONG ulSizeOfResourcesX; //... Size of resources in section .rsrc1
ULONG ulVirtualSizeX; //... Virtual Size of resources in .rsrc1
} RESSECTDATA, *PRESSECTDATA;
WORD gwFilter = 0;
int InsertResourcesInExe( FILE *, HANDLE); LONG GetFileResources( FILE *, FILE *, ULONG); ULONG MoveFilePos( FILE *, ULONG); ULONG MyWrite( FILE *, PUCHAR, ULONG); ULONG MyRead( FILE *, PUCHAR, ULONG); WCHAR *GetDirNameU( WCHAR *, PIMAGE_RESOURCE_DIR_STRING_U); ULONG ReadResources( FILE *, ULONG, ULONG, PUCHAR); DWORD AddToLangIDList( DWORD);
ULONG ProcessDirectory( FILE *, USHORT, PRESSECTDATA, PIMAGE_RESOURCE_DIRECTORY, PIMAGE_RESOURCE_DIRECTORY);
ULONG ProcessDirEntry( FILE *, USHORT, PRESSECTDATA, PIMAGE_RESOURCE_DIRECTORY, PIMAGE_RESOURCE_DIRECTORY_ENTRY);
ULONG ProcessSubDir( FILE *, USHORT, PRESSECTDATA, PIMAGE_RESOURCE_DIRECTORY, PIMAGE_RESOURCE_DIRECTORY_ENTRY);
ULONG ProcessNamedEntry( FILE *, PRESSECTDATA, PIMAGE_RESOURCE_DIRECTORY, PIMAGE_RESOURCE_DIRECTORY_ENTRY);
ULONG ProcessIdEntry( FILE *, PRESSECTDATA, PIMAGE_RESOURCE_DIRECTORY, PIMAGE_RESOURCE_DIRECTORY_ENTRY);
ULONG ProcessDataEntry( FILE *, PRESSECTDATA, PIMAGE_RESOURCE_DIRECTORY, PIMAGE_RESOURCE_DATA_ENTRY);
int FindNewExeHdr( FILE *, ULONG *);
IMAGE_DOS_HEADER ExeDosHdr;//... Exe's DOS header
IMAGE_NT_HEADERS NTHdrs; //... Exe's NT headers
struct tagLevelData //... Holds ID or name for each directory level
{ //... level [0] is for resource type
ULONG dwID; //... level [1] is for resource name
WCHAR wszName[128]; //... level [2] is for resource language
} LevelData[ MAXLEVELS] = { 0L, TEXT(""), 0L, TEXT(""), 0L, TEXT("")};
BOOL fGetResLangIDs = FALSE;
extern BOOL fInThirdPartyEditer;//.. Are we in a 3rd-party resource editor?
extern MSTRDATA gMstr; //... Data from Master Project file (MPJ)
extern PROJDATA gProj; //... Data from Language Project file (PRJ)
extern UCHAR szDHW[];
PLANGLIST pLangIDList = NULL;
//..........................................................................
void FreeLangIDList( void) { PLANGLIST pID = NULL;
while ( pLangIDList ) { pID = pLangIDList->pNext; RLFREE( pLangIDList); pLangIDList = pID; } }
//..........................................................................
ULONG GetListOfResLangIDs( char *szExeName) { ULONG ulRC = SUCCESS; ULONG ulOffset = 0; static RESHEADER ResHeader; // Structure contain Resource Header info.
if ( IsExe( szExeName) ) { //.. open the original exe file
FILE *fpExe = FOPEN( szExeName, "rb");
if ( fpExe != NULL ) { //... Get list of languages in exe file
ulRC = (ULONG)FindNewExeHdr( fpExe, &ulOffset);
if ( ulRC == SUCCESS ) { fGetResLangIDs = TRUE;
ulRC = (ULONG)GetFileResources( fpExe, NULL, ulOffset);
fGetResLangIDs = FALSE; } FCLOSE( fpExe); } else { ulRC = ERROR_OPEN_FAILED; } } else if ( IsWin32Res( szExeName) ) { FILE *fpRes = FOPEN( szExeName, "rb");
if ( fpRes != NULL ) { LONG lEndOffset = 0L;
//... How large is the res file?
fseek( fpRes, 0L, SEEK_END); lEndOffset = ftell( fpRes);
rewind( fpRes); //... Get list of languages in .RES file
while ( ulRC == SUCCESS && ! feof( fpRes) ) { LONG lCurrOffset = 0L;
lCurrOffset = (LONG)ftell( fpRes);
if ( (lCurrOffset + (LONG)sizeof( RESHEADER)) >= lEndOffset ) { break; }
if ( GetResHeader( fpRes, &ResHeader, NULL) == -1 ) { ulRC = 1L; break; } //... Is this the dummy, res32-identifying, res?
if ( ResHeader.lSize == 0L ) { continue; } ulRC = AddToLangIDList( (DWORD)ResHeader.wLanguageId);
SkipBytes( fpRes, (DWORD *)&ResHeader.lSize); ClearResHeader( ResHeader);
DWordUpFilePointer( fpRes, MYREAD, ftell( fpRes), NULL);
} // END while ( ! feof( InResFile)
FCLOSE( fpRes); } else { ulRC = ERROR_OPEN_FAILED; } }
if ( ulRC != SUCCESS ) { FreeLangIDList(); } return ( ulRC); }
//..........................................................................
int ExtractResFromExe32A(
char *szExeName, char *szResName, WORD wFilter) { FILE *fpExe = NULL; //... Handle of input .EXE file
FILE *fpRes = NULL; //... Handle of output .RES file
ULONG ulRC = 0; ULONG ulOffset = 0; int nRC = SUCCESS;
gwFilter = wFilter;
//.. open the original exe file
fpExe = FOPEN( szExeName, "rb");
if ( fpExe == NULL ) { return ( ERROR_OPEN_FAILED); } nRC = FindNewExeHdr( fpExe, &ulOffset);
if ( nRC != SUCCESS ) { FCLOSE( fpExe); return ( nRC); } fpRes = FOPEN( (CHAR *)szResName, "wb");
if ( fpRes != NULL ) { //... First, write the dummy 32bit identifier
PutByte( fpRes, 0x00, NULL); PutByte( fpRes, 0x00, NULL); PutByte( fpRes, 0x00, NULL); PutByte( fpRes, 0x00, NULL); PutByte( fpRes, 0x20, NULL); PutByte( fpRes, 0x00, NULL); PutByte( fpRes, 0x00, NULL); PutByte( fpRes, 0x00, NULL);
PutWord( fpRes, 0xffff, NULL); PutWord( fpRes, 0x00, NULL); PutWord( fpRes, 0xffff, NULL); PutWord( fpRes, 0x00, NULL);
PutdWord( fpRes, 0L, NULL); PutdWord( fpRes, 0L, NULL);
PutdWord( fpRes, 0L, NULL); PutdWord( fpRes, 0L, NULL);
ulRC = (ULONG)GetFileResources( fpExe, fpRes, ulOffset);
FCLOSE( fpRes); } else { ulRC = GetLastError(); } FCLOSE( fpExe); return ( ulRC); }
//..........................................................................
int BuildExeFromRes32A(
char * szOutExe, //... Output EXE file's name
char * szRes, //... File of replacement resources
char * szInExe ) //... Intput EXE file's name
{ HANDLE hExeFile = NULL; FILE *fpRes = NULL; DWORD dwRC = 0; WORD wRC = 0;
//... Copy Input exe to out put exe
if ( CopyFileA( szInExe, szOutExe, FALSE) == FALSE ) { QuitA( IDS_COPYFILE_FAILED, szInExe, szOutExe); }
if ( (fpRes = FOPEN( szRes, "rb")) == NULL ) { return -2; }
SetLastError(0);
//if Source file was set attributes READ-ONLY, CopyFile sets temp file also.
//And BeginUpdateResourceA returns ERROR.
SetFileAttributesA(szOutExe, FILE_ATTRIBUTE_NORMAL);
hExeFile = BeginUpdateResourceA( szOutExe, TRUE);
dwRC = GetLastError();
if ( ! hExeFile ) { FCLOSE( fpRes); return ( -3); }
wRC = (WORD)InsertResourcesInExe( fpRes, hExeFile);
FCLOSE( fpRes);
if ( wRC != 1 ) { return ( wRC); }
SetLastError(0); // needed only to see if EndUpdateResource
// sets last error value.
dwRC = EndUpdateResource( hExeFile, FALSE);
if ( dwRC == FALSE ) { return ( -4); } MapFileAndFixCheckSumA( szOutExe); //... This func always calls QuitT or returns 0
return (1); }
//..........................................................................
int FindNewExeHdr( FILE *fpExe, ULONG *ulOffset) { ULONG ulRC = 0;
//... read the old format EXE header
ulRC = MyRead( fpExe, (void *)&ExeDosHdr, sizeof( ExeDosHdr));
if ( ulRC != 0L && ulRC != sizeof( ExeDosHdr) ) { return ( ERROR_READ_FAULT); }
//... make sure its really an EXE file
if ( ExeDosHdr.e_magic != IMAGE_DOS_SIGNATURE ) { return ( ERROR_INVALID_EXE_SIGNATURE); }
//... make sure theres a new EXE header
//... floating around somewhere
if ( ! (*ulOffset = ExeDosHdr.e_lfanew) ) { return ( ERROR_BAD_EXE_FORMAT); } return ( SUCCESS); }
//..........................................................................
int InsertResourcesInExe(
FILE *fpRes, HANDLE hExeFile ) { PVOID pResData = NULL; LONG lEndOffset = 0L; BOOL bUpdRC = FALSE; LANGID wLangID = 0; int nResCnt = 0; int nResOut = 0; static RESHEADER ResHeader;
//... How big is the .RES file?
fseek( fpRes, 0L, SEEK_END); lEndOffset = ftell( fpRes);
rewind( fpRes);
//... Update all resources, found in the .RES,
//... to the .EXE
while ( ! feof( fpRes) ) { DWordUpFilePointer( fpRes, MYREAD, ftell( fpRes), NULL); RLFREE( pResData);
if ( ftell( fpRes) >= lEndOffset ) { return (1); } ZeroMemory( &ResHeader, sizeof( ResHeader));
// Read in the resource header
if ( ( GetResHeader( fpRes, &ResHeader, (DWORD *) NULL) == -1 ) ) { return ( -1); }
if ( ResHeader.lSize > 0L ) { wLangID = ResHeader.wLanguageId;
// Allocate Memory to hold resource data
pResData = (PVOID)FALLOC( ResHeader.lSize);
// Read it into the buffer
if ( ResReadBytes( fpRes, pResData, (size_t)ResHeader.lSize, NULL ) == FALSE ) { RLFREE( pResData); return (-1); }
nResCnt++; // Increment # resources read
DWordUpFilePointer( fpRes, MYREAD, ftell( fpRes), NULL); } else { continue; }
// now write the data
if ( ResHeader.bTypeFlag == IDFLAG ) { if ( ResHeader.bNameFlag == IDFLAG ) { SetLastError(0);
bUpdRC = UpdateResource( hExeFile, MAKEINTRESOURCE( ResHeader.wTypeID), MAKEINTRESOURCE( ResHeader.wNameID), wLangID, pResData, ResHeader.lSize);
if ( ! bUpdRC ) { RLFREE( pResData); return (-1); } } else { SetLastError(0);
bUpdRC = UpdateResource( hExeFile, MAKEINTRESOURCE( ResHeader.wTypeID), ResHeader.pszName, wLangID, pResData, ResHeader.lSize);
if ( ! bUpdRC ) { RLFREE( pResData); return (-1); } } } else { if (ResHeader.bNameFlag == IDFLAG) { SetLastError(0);//BUGUG
bUpdRC = UpdateResource( hExeFile, ResHeader.pszType, MAKEINTRESOURCE( ResHeader.wNameID), wLangID, pResData, ResHeader.lSize);
if ( ! bUpdRC ) { RLFREE( pResData); return (-1); } } else { SetLastError(0);
bUpdRC = UpdateResource( hExeFile, ResHeader.pszType, ResHeader.pszName, wLangID, pResData, ResHeader.lSize);
if ( ! bUpdRC ) { RLFREE( pResData); return (-1); } } } ClearResHeader( ResHeader); RLFREE( pResData); } //... END WHILE ( ! feof...
return (1); }
//............................................................
LONG GetFileResources(
FILE *fpExe, FILE *fpRes, ULONG ulHdrOffset) { ULONG ulOffsetToResources; ULONG ulOffsetToResourcesX; ULONG ulRead; ULONG ulToRead; ULONG ulRC = SUCCESS; PUCHAR pResources = NULL; //... Ptr to start of resource directory table
PIMAGE_SECTION_HEADER pSectTbl = NULL; PIMAGE_SECTION_HEADER pSectTblLast = NULL; PIMAGE_SECTION_HEADER pSect = NULL; PIMAGE_SECTION_HEADER pResSect = NULL; PIMAGE_SECTION_HEADER pResSectX = NULL; static RESSECTDATA ResSectData;
//... Read the NT image headers into memory
ulRC = MoveFilePos( fpExe, ulHdrOffset);
if ( ulRC != 0L ) { return ( -1L); } ulRead = MyRead( fpExe, (PUCHAR)&NTHdrs, sizeof( IMAGE_NT_HEADERS));
if ( ulRead != 0L && ulRead != sizeof( IMAGE_NT_HEADERS) ) { return ( -1L); } //... Check for valid exe
if ( *(PUSHORT)&NTHdrs.Signature != IMAGE_NT_SIGNATURE ) { return ( ERROR_INVALID_EXE_SIGNATURE); }
if ((NTHdrs.FileHeader.Characteristics&IMAGE_FILE_EXECUTABLE_IMAGE) == 0 && (NTHdrs.FileHeader.Characteristics&IMAGE_FILE_DLL) == 0) { return ( ERROR_EXE_MARKED_INVALID); } //... Where is resource section in file
//... and how big is it?
//... First, read section table
ulToRead = NTHdrs.FileHeader.NumberOfSections * sizeof( IMAGE_SECTION_HEADER); pSectTbl = (PIMAGE_SECTION_HEADER)FALLOC( ulToRead);
memset( (PVOID)pSectTbl, 0, ulToRead);
ulHdrOffset += sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + NTHdrs.FileHeader.SizeOfOptionalHeader; MoveFilePos( fpExe, ulHdrOffset); ulRead = MyRead( fpExe, (PUCHAR)pSectTbl, ulToRead);
if ( ulRead != 0L && ulRead != ulToRead ) { SetLastError(ERROR_BAD_FORMAT); RLFREE( pSectTbl); return ( -1L); } pSectTblLast = pSectTbl + NTHdrs.FileHeader.NumberOfSections;
for ( pSect = pSectTbl; pSect < pSectTblLast; ++pSect ) { if ( lstrcmpA( (CHAR *)pSect->Name, ".rsrc") == SAME && pResSect==NULL ) { pResSect = pSect; } else if ( lstrcmpA( (CHAR *)pSect->Name, ".rsrc1") == SAME && pResSectX==NULL ) { pResSectX = pSect; } }
if ( pResSect == NULL ) { RLFREE( pSectTbl); QuitA( IDS_NO_RES_SECTION, gMstr.szSrc, NULL); }
ulOffsetToResources = pResSect->PointerToRawData; ulOffsetToResourcesX = pResSectX ? pResSectX->PointerToRawData : 0L;
ResSectData.ulVirtualAddress = pResSect->VirtualAddress; ResSectData.ulSizeOfResources = pResSect->SizeOfRawData; ResSectData.ulVirtualSize = pResSect->Misc.VirtualSize; ResSectData.ulVirtualAddressX = pResSectX ? pResSectX->VirtualAddress : 0L; ResSectData.ulSizeOfResourcesX = pResSectX ? pResSectX->SizeOfRawData : 0L; ResSectData.ulVirtualSizeX = pResSectX ? pResSectX->Misc.VirtualSize : 0L;
//... Read resource section into memory
pResources = (PUCHAR)FALLOC((ulToRead = (max(ResSectData.ulVirtualSize, ResSectData.ulSizeOfResources) + max(ResSectData.ulVirtualSizeX, ResSectData.ulSizeOfResourcesX)))); memset( (PVOID)pResources, 0, ulToRead);
ulRC = ReadResources( fpExe, ulOffsetToResources, ResSectData.ulSizeOfResources, pResources);
if ( ulRC != 0L ) { RLFREE( pSectTbl); RLFREE( pResources); return ( ulRC); } else if ( ResSectData.ulSizeOfResourcesX > 0L ) { ulRC = ReadResources( fpExe, ulOffsetToResourcesX, ResSectData.ulSizeOfResourcesX, &pResources[ ResSectData.ulVirtualSize]); if ( ulRC != 0L ) { RLFREE( pSectTbl); RLFREE( pResources); return ( ulRC); } } //... Now process the resource table
ulRC = ProcessDirectory( fpRes, 0, &ResSectData, (PIMAGE_RESOURCE_DIRECTORY)pResources, (PIMAGE_RESOURCE_DIRECTORY)pResources);
RLFREE( pSectTbl); RLFREE( pResources);
return ( (LONG)ulRC); }
//......................................................................
ULONG ProcessDirectory(
FILE *fpRes, USHORT usLevel, PRESSECTDATA pResSectData, PIMAGE_RESOURCE_DIRECTORY pResStart, PIMAGE_RESOURCE_DIRECTORY pResDir) { ULONG ulRC = SUCCESS; PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry; PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirStart; PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEnd;
pResDirStart = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((PBYTE)pResDir + sizeof( IMAGE_RESOURCE_DIRECTORY));
pResDirEnd = pResDirStart + pResDir->NumberOfNamedEntries + pResDir->NumberOfIdEntries;
for ( pResDirEntry = pResDirStart, ulRC = 0L; pResDirEntry < pResDirEnd && ulRC == 0L; ++pResDirEntry ) { ulRC = ProcessDirEntry( fpRes, usLevel, pResSectData, pResStart, pResDirEntry); } return ( ulRC); }
//......................................................................
ULONG ProcessDirEntry(
FILE *fpRes, USHORT usLevel, PRESSECTDATA pResSectData, PIMAGE_RESOURCE_DIRECTORY pResStart, PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry) { ULONG ulRC = SUCCESS;
if ( pResDirEntry->Name & IMAGE_RESOURCE_NAME_IS_STRING ) { GetDirNameU( LevelData[ usLevel].wszName, (PIMAGE_RESOURCE_DIR_STRING_U)((PBYTE)pResStart + (pResDirEntry->Name & (~IMAGE_RESOURCE_NAME_IS_STRING)))); LevelData[ usLevel].dwID = IMAGE_RESOURCE_NAME_IS_STRING; } else { LevelData[ usLevel].wszName[0] = TEXT('\0'); LevelData[ usLevel].dwID = pResDirEntry->Name; }
if ( pResDirEntry->OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY ) { ulRC = ProcessSubDir( fpRes, usLevel, pResSectData, pResStart, pResDirEntry); } else if ( pResDirEntry->Name & IMAGE_RESOURCE_NAME_IS_STRING ) { ulRC = ProcessNamedEntry( fpRes, pResSectData, pResStart, pResDirEntry); } else { ulRC = ProcessIdEntry( fpRes, pResSectData, pResStart, pResDirEntry); } return ( ulRC); }
//......................................................................
ULONG ProcessSubDir(
FILE *fpRes, USHORT usLevel, PRESSECTDATA pResSectData, PIMAGE_RESOURCE_DIRECTORY pResStart, PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry) { PIMAGE_RESOURCE_DIRECTORY pResDir;
pResDir = (PIMAGE_RESOURCE_DIRECTORY)((PBYTE)pResStart + (pResDirEntry->OffsetToData & (~IMAGE_RESOURCE_DATA_IS_DIRECTORY)));
return ( ++usLevel < MAXLEVELS ? ProcessDirectory( fpRes, usLevel, pResSectData, pResStart, pResDir) : -1L); }
//......................................................................
ULONG ProcessIdEntry(
FILE *fpRes, PRESSECTDATA pResSectData, PIMAGE_RESOURCE_DIRECTORY pResStart, PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry) { return ( ProcessDataEntry( fpRes, pResSectData, pResStart, (PIMAGE_RESOURCE_DATA_ENTRY)((PBYTE)pResStart + pResDirEntry->OffsetToData))); }
//......................................................................
ULONG ProcessNamedEntry(
FILE *fpRes, PRESSECTDATA pResSectData, PIMAGE_RESOURCE_DIRECTORY pResStart, PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry) { return ( ProcessDataEntry( fpRes, pResSectData, pResStart, (PIMAGE_RESOURCE_DATA_ENTRY)((PBYTE)pResStart + pResDirEntry->OffsetToData))); }
//......................................................................
ULONG ProcessDataEntry(
FILE *fpRes, PRESSECTDATA pResSectData, PIMAGE_RESOURCE_DIRECTORY pResStart, PIMAGE_RESOURCE_DATA_ENTRY pResData) { ULONG ulOffset; ULONG ulCopied; DWORD dwHdrSize = 0L; fpos_t HdrSizePos;
if ( fGetResLangIDs ) { //... Are we just looking for LANG IDs?
return ( AddToLangIDList( (WORD)(LevelData[2].dwID))); }
if ( gwFilter != 0 ) { //... Filtering turned on?
//... Yes, is this a resource we want?
if ( LevelData[0].dwID == IMAGE_RESOURCE_NAME_IS_STRING || LevelData[0].dwID != (DWORD)gwFilter ) { return ( 0L); //... Not a resource we want
} }
//... Are we in the dialog editor?
if ( fInThirdPartyEditer ) { //... Is the language we want?
if ( LevelData[2].dwID != gMstr.wLanguageID ) { return ( 0L); //... Not the language we want
} }
ulOffset = pResData->OffsetToData - pResSectData->ulVirtualAddress;
if ( ulOffset >= pResSectData->ulVirtualSize ) { if ( pResSectData->ulVirtualSizeX > 0L ) { ulOffset = pResData->OffsetToData + pResSectData->ulVirtualSize - pResSectData->ulVirtualAddressX;
if ( ulOffset >= pResSectData->ulVirtualSize + pResSectData->ulSizeOfResourcesX ) { return ( (ULONG)-1L); } } else { return ( (ULONG)-1L); } } //... write out the resource header info
//... First, write the resource's size
PutdWord( fpRes, pResData->Size, &dwHdrSize);
//... Remember where to write real hdr size and
//... write out bogus hdr size, fix up later
fgetpos( fpRes, &HdrSizePos); PutdWord( fpRes, 0, &dwHdrSize);
//... Write resource type
if ( LevelData[0].dwID == IMAGE_RESOURCE_NAME_IS_STRING ) { PutString( fpRes, (TCHAR *)LevelData[0].wszName, &dwHdrSize); } else { PutWord( fpRes, IDFLAG, &dwHdrSize); PutWord( fpRes, LOWORD( LevelData[0].dwID), &dwHdrSize); }
//... Write resource name
//... dbl-null-terminated if string
if ( LevelData[1].dwID == IMAGE_RESOURCE_NAME_IS_STRING ) { PutString( fpRes, (TCHAR *)LevelData[1].wszName, &dwHdrSize); } else { PutWord( fpRes, IDFLAG, &dwHdrSize); PutWord( fpRes, LOWORD( LevelData[1].dwID), &dwHdrSize); }
DWordUpFilePointer( fpRes, MYWRITE, ftell( fpRes), &dwHdrSize);
//... More Win32 header stuff
PutdWord( fpRes, 0, &dwHdrSize); //... Data version
PutWord( fpRes, 0x1030, &dwHdrSize); //... MemoryFlags (WORD)
//... language is always a number (WORD)
PutWord( fpRes, LOWORD( LevelData[2].dwID), &dwHdrSize);
//... More Win32 header stuff
PutdWord( fpRes, 0, &dwHdrSize); //... Version
PutdWord( fpRes, 0, &dwHdrSize); //... Characteristics
//... Now, fix up the resource header size
UpdateResSize( fpRes, &HdrSizePos, dwHdrSize);
//... Copy the resource data to the res file
ulCopied = MyWrite( fpRes, (PUCHAR)pResStart + ulOffset, pResData->Size);
if ( ulCopied != 0L && ulCopied != pResData->Size ) { return ( (ULONG)-1); } DWordUpFilePointer( fpRes, MYWRITE, ftell( fpRes), NULL); return ( 0L); }
//......................................................................
/*
* Utility routines */
ULONG ReadResources(
FILE *fpExe, ULONG ulOffsetToResources, ULONG ulSizeOfResources, PUCHAR pResources) { ULONG ulRC = SUCCESS; ULONG ulRead;
ulRC = MoveFilePos( fpExe, ulOffsetToResources);
if ( ulRC != 0L ) { return ( (ULONG)-1L); } ulRead = MyRead( fpExe, pResources, ulSizeOfResources);
if ( ulRead != 0L && ulRead != ulSizeOfResources ) { return ( (ULONG)-1L); } return ( 0L); }
//......................................................................
WCHAR * GetDirNameU(
WCHAR *pszDest, PIMAGE_RESOURCE_DIR_STRING_U pDirStr) { CopyMemory( pszDest, pDirStr->NameString, MEMSIZE( pDirStr->Length)); pszDest[ pDirStr->Length] = L'\0'; return ( pszDest); }
//......................................................................
ULONG MoveFilePos( FILE *fp, ULONG pos) { return ( fseek( fp, pos, SEEK_SET)); }
//......................................................................
ULONG MyWrite( FILE *fp, UCHAR *p, ULONG ulToWrite) { size_t cWritten;
cWritten = fwrite( p, 1, (size_t)ulToWrite, fp);
return ( (ULONG)(cWritten == ulToWrite ? 0L : cWritten)); }
//......................................................................
ULONG MyRead( FILE *fp, UCHAR*p, ULONG ulRequested ) { size_t cRead;
cRead = fread( p, 1, (size_t)ulRequested, fp);
return ( (ULONG)(cRead == ulRequested ? 0L : cRead)); }
//......................................................................
DWORD AddToLangIDList( DWORD dwLangID) { WORD wLangID = (WORD)dwLangID;
if ( pLangIDList ) { PLANGLIST pID;
for ( pID = pLangIDList; pID; pID = pID->pNext ) { if ( pID->wLang == wLangID ) { break; //... LANGID already in list
} else if ( pID->pNext == NULL ) { pID->pNext = (PLANGLIST)FALLOC( sizeof( LANGLIST)); pID = pID->pNext; pID->pNext = NULL; pID->wLang = wLangID; //... LANGID now added to list
} } } else { pLangIDList = (PLANGLIST)FALLOC( sizeof( LANGLIST)); pLangIDList->pNext = NULL; pLangIDList->wLang = wLangID; } return ( SUCCESS); }
|