#include #include #include #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); }