Subversion Repositories filter_foundry

Compare Revisions

No changes between revisions

Regard whitespace Rev 455 → Rev 456

/trunk/3264_mixer/foundry_3264_mixer.cpp
28,102 → 28,147
#include <fstream>
#include <vector>
 
bool update_pe_timestamp(LPCTSTR filename, time_t timestamp) {
size_t peoffset;
FILE* fptr;
typedef struct _PE32 {
uint32_t magic; // 0x50450000
IMAGE_FILE_HEADER fileHeader; // COFF Header without Signature
IMAGE_OPTIONAL_HEADER32 optHeader; // Standard COFF fields, Windows Specific Fields, Data Directories
} PE32;
 
fptr = _wfopen(filename, L"rb+");
if (fptr == NULL) return false;
#ifdef UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif
 
fseek(fptr, 0x3C, SEEK_SET);
fread(&peoffset, sizeof(peoffset), 1, fptr);
int binary_file_string_replace(tstring file_name, const char* asearch, const char* areplace) {
std::ifstream input(file_name, std::ios::binary);
 
fseek(fptr, (long)peoffset + 8, SEEK_SET);
fwrite(&timestamp, sizeof(time_t), 1, fptr);
std::vector<char> buffer((std::istreambuf_iterator<char>(input)), (std::istreambuf_iterator<char>()));
std::vector<char>::iterator itbegin = buffer.begin();
std::vector<char>::iterator itend = buffer.end();
 
fclose(fptr);
if (strlen(asearch) != strlen(areplace)) {
printf("Replace value length greater than original!\n");
return -1;
}
int MAX_BUFFER = strlen(asearch);
 
return true;
char* needed_str = (char*)malloc(MAX_BUFFER);
if (needed_str == 0) return -1;
char* replace_str = (char*)malloc(MAX_BUFFER);
if (replace_str == 0) return -1;
 
memcpy(needed_str, asearch, MAX_BUFFER);
memcpy(replace_str, areplace, MAX_BUFFER);
 
int ifound = 0;
 
for (auto it = itbegin; it < itend; it++) {
if (memcmp(it._Ptr, needed_str, MAX_BUFFER) == 0) {
strncpy(it._Ptr, replace_str, MAX_BUFFER);
it += MAX_BUFFER - 1; // -1 because it++ will be set on the next loop
ifound++;
}
}
 
bool update_pe_stackSizeCommit(LPCTSTR filename, size_t stackReserve, size_t stackCommit) {
size_t peoffset;
FILE* fptr;
if (ifound > 0) {
std::ofstream ofile(file_name, std::ios::out | std::ios::binary);
ofile.write((char*)&buffer[0], buffer.size() * sizeof(char));
ofile.close();
}
 
fptr = _wfopen(filename, L"rb+");
if (fptr == NULL) return false;
return ifound;
}
 
fseek(fptr, 0x3C, SEEK_SET);
fread(&peoffset, sizeof(peoffset), 1, fptr);
int binary_file_string_find(tstring file_name, const char* asearch) {
std::ifstream input(file_name, std::ios::binary);
 
fseek(fptr, (long)peoffset + 12 * 8, SEEK_SET);
fwrite(&stackReserve, sizeof(size_t), 1, fptr);
std::vector<char> buffer((std::istreambuf_iterator<char>(input)), (std::istreambuf_iterator<char>()));
std::vector<char>::iterator itbegin = buffer.begin();
std::vector<char>::iterator itend = buffer.end();
 
fseek(fptr, (long)peoffset + 12 * 8 + 4, SEEK_SET);
fwrite(&stackCommit, sizeof(size_t), 1, fptr);
int MAX_BUFFER = strlen(asearch);
 
fclose(fptr);
char* needed_str = (char*)malloc(MAX_BUFFER);
if (needed_str == 0) return -1;
 
return true;
memcpy(needed_str, asearch, MAX_BUFFER);
 
int ifound = 0;
 
for (auto it = itbegin; it < itend; it++) {
if (memcmp(it._Ptr, needed_str, MAX_BUFFER) == 0) {
it += MAX_BUFFER - 1; // -1 because it++ will be set on the next loop
ifound++;
}
}
 
bool update_pe_heapSizeCommit(LPCTSTR filename, size_t heapReserve, size_t heapCommit) {
return ifound;
}
 
void _set_pe_int32(FILE* fptr, size_t fieldoffset, int32_t val) {
size_t peoffset;
FILE* fptr;
 
fptr = _wfopen(filename, L"rb+");
if (fptr == NULL) return false;
fseek(fptr, 0x3C, SEEK_SET);
fread(&peoffset, sizeof(peoffset), 1, fptr);
 
fseek(fptr, (long)peoffset + fieldoffset, SEEK_SET);
fwrite(&val, sizeof(int32_t), 1, fptr);
}
 
int32_t _get_pe_int32(FILE* fptr, size_t fieldoffset) {
size_t peoffset;
int32_t res;
 
fseek(fptr, 0x3C, SEEK_SET);
fread(&peoffset, sizeof(peoffset), 1, fptr);
 
fseek(fptr, (long)peoffset + 13 * 8, SEEK_SET);
fwrite(&heapReserve, sizeof(size_t), 1, fptr);
fseek(fptr, (long)peoffset + fieldoffset, SEEK_SET);
fread(&res, sizeof(int32_t), 1, fptr);
 
fseek(fptr, (long)peoffset + 13 * 8 + 4, SEEK_SET);
fwrite(&heapCommit, sizeof(size_t), 1, fptr);
return res;
}
 
bool update_pe_timestamp(LPCTSTR filename, __time32_t timestamp) {
FILE* fptr = _wfopen(filename, L"rb+");
if (fptr == NULL) return false;
 
_set_pe_int32(fptr, /*0x0008*/offsetof(PE32, fileHeader.TimeDateStamp), timestamp);
 
fclose(fptr);
 
return true;
}
 
bool openWatcomCosmetics(LPCTSTR filename) {
if (binary_file_string_find(filename, "Open Watcom") > 0) {
FILE* fptr = _wfopen(filename, L"rb+");
if (fptr == NULL) return false;
 
//DOS .EXE header
struct image_dos_header
{
uint16_t e_magic; // Magic number
uint16_t e_cblp; // Bytes on last page of file
uint16_t e_cp; // Pages in file
uint16_t e_crlc; // Relocations
uint16_t e_cparhdr; // Size of header in paragraphs
uint16_t e_minalloc; // Minimum extra paragraphs needed
uint16_t e_maxalloc; // Maximum extra paragraphs needed
uint16_t e_ss; // Initial (relative) SS value
uint16_t e_sp; // Initial SP value
uint16_t e_csum; // Checksum
uint16_t e_ip; // Initial IP value
uint16_t e_cs; // Initial (relative) CS value
uint16_t e_lfarlc; // File address of relocation table
uint16_t e_ovno; // Overlay number
uint16_t e_res[4]; // Reserved words
uint16_t e_oemid; // OEM identifier (for e_oeminfo)
uint16_t e_oeminfo; // OEM information; e_oemid specific
uint16_t e_res2[10]; // Reserved words
int32_t e_lfanew; // File address of new exe header
};
// Min OS Version 1.11 ... But the actual minimal Windows version is Windows NT 3.11
int32_t minOsVersion = _get_pe_int32(fptr, /*0x0040*/offsetof(PE32, optHeader.MajorOperatingSystemVersion));
if (minOsVersion == 0x000B0001) {
_set_pe_int32(fptr, /*0x0040*/offsetof(PE32, optHeader.MajorOperatingSystemVersion), 0x00000003); // Windows 3.0
}
 
struct image_file_header
{
uint16_t Machine;
uint16_t NumberOfSections;
uint32_t TimeDateStamp;
uint32_t PointerToSymbolTable;
uint32_t NumberOfSymbols;
uint16_t SizeOfOptionalHeader;
uint16_t Characteristics;
};
// Stack reserved cannot be changed with linker option "OPTION STACK=1m" (Rejected https://github.com/open-watcom/open-watcom-v2/issues/780)
// It is not required for DLLs, but everybody does it, and I think it is cosmetics to fill these fields, even if not required.
_set_pe_int32(fptr, /*0x0060*/offsetof(PE32, optHeader.SizeOfStackReserve), 0x00100000);
_set_pe_int32(fptr, /*0x0064*/offsetof(PE32, optHeader.SizeOfStackCommit), 0x00001000);
// Heap reserved can be changed with linker option "OPTION HEAP=1m"
_set_pe_int32(fptr, /*0x0068*/offsetof(PE32, optHeader.SizeOfHeapReserve), 0x00100000);
_set_pe_int32(fptr, /*0x006C*/offsetof(PE32, optHeader.SizeOfHeapCommit), 0x00001000);
 
fclose(fptr);
 
// 32 bit (OpenWatcom cosmetics): Export table name "FilterFoundry.dll" => "FilterFoundry.8bf"
// since OpenWatcom cannot link a 8BF file natively.
binary_file_string_replace(filename, "FilterFoundry.dll", "FilterFoundry.8bf");
}
 
return true;
}
 
uint32_t calculate_checksum(LPCTSTR filename) {
//Calculate checksum of image
// Taken from "PE Bliss" Cross-Platform Portable Executable C++ Library
132,7 → 177,7
 
FILE* fptr;
unsigned long long checksum = 0;
struct image_dos_header header;
IMAGE_DOS_HEADER header;
size_t filesize;
unsigned long long top;
unsigned long pe_checksum_pos;
144,7 → 189,7
 
//Read DOS header
fseek(fptr, 0, SEEK_SET);
fread(&header, sizeof(struct image_dos_header), 1, fptr);
fread(&header, sizeof(IMAGE_DOS_HEADER), 1, fptr);
 
//Calculate PE checksum
fseek(fptr, 0, SEEK_SET);
154,7 → 199,7
//"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+
//Calculate real PE headers "CheckSum" field position
//Sum is safe here
pe_checksum_pos = header.e_lfanew + sizeof(struct image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers;
pe_checksum_pos = header.e_lfanew + sizeof(IMAGE_FILE_HEADER) + sizeof(uint32_t) + checksum_pos_in_optional_headers;
 
//Calculate checksum for each byte of file
fseek(fptr, 0L, SEEK_END);
190,7 → 235,6
}
 
bool repair_pe_checksum(LPCTSTR filename) {
size_t peoffset;
FILE* fptr;
 
uint32_t checksum = calculate_checksum(filename);
199,12 → 243,8
fptr = _wfopen(filename, L"rb+");
if (fptr == NULL) return false;
 
fseek(fptr, 0x3C, SEEK_SET);
fread(&peoffset, sizeof(peoffset), 1, fptr);
_set_pe_int32(fptr, /*0x0058*/offsetof(PE32, optHeader.CheckSum), (int32_t)checksum);
 
fseek(fptr, (long)peoffset + 88, SEEK_SET);
fwrite(&checksum, sizeof(uint32_t), 1, fptr);
 
fclose(fptr);
 
return true;
272,51 → 312,7
return bSuccessful;
}
 
#ifdef UNICODE
int binary_file_string_replace(std::wstring file_name, const char* asearch, const char* areplace) {
#else
int binary_file_string_replace(std::string file_name, const char* asearch, const char* areplace) {
#endif
std::ifstream input(file_name, std::ios::binary);
 
std::vector<char> buffer((std::istreambuf_iterator<char>(input)), (std::istreambuf_iterator<char>()));
std::vector<char>::iterator itbegin = buffer.begin();
std::vector<char>::iterator itend = buffer.end();
 
if (strlen(asearch) != strlen(areplace)) {
printf("Replace value length greater than original!\n");
return -1;
}
int MAX_BUFFER = strlen(asearch);
 
char* needed_str = (char*)malloc(MAX_BUFFER);
if (needed_str == 0) return -1;
char* replace_str = (char*)malloc(MAX_BUFFER);
if (replace_str == 0) return -1;
memcpy(needed_str, asearch, MAX_BUFFER);
memcpy(replace_str, areplace, MAX_BUFFER);
 
int ifound = 0;
 
for (auto it = itbegin; it < itend ; it++) {
if (memcmp(it._Ptr, needed_str, MAX_BUFFER) == 0) {
strncpy(it._Ptr, replace_str, MAX_BUFFER);
it += MAX_BUFFER - 1; // -1 because it++ will be set on the next loop
ifound++;
}
}
 
if (ifound > 0) {
std::ofstream ofile(file_name, std::ios::out | std::ios::binary);
ofile.write((char*)&buffer[0], buffer.size() * sizeof(char));
ofile.close();
}
 
return ifound;
}
 
 
int main()
{
LPCTSTR lpTemplateType = L"TPLT";
397,23 → 393,13
removeFromFile(file64tmp, lpTemplateType, lpName64Pipl, wLanguageNeutral);
}
 
// 32 bit (OpenWatcom cosmetics): Export table name "filterfoundry.dll" => "FilterFoundry.8bf"
// since OpenWatcom cannot link a 8BF file natively.
binary_file_string_replace(file32tmp, "filterfoundry.dll", "FilterFoundry.8bf");
binary_file_string_replace(file32out, "filterfoundry.dll", "FilterFoundry.8bf");
// Do some cosmetics to OpenWatcom binaries
openWatcomCosmetics(file32tmp);
openWatcomCosmetics(file32out);
 
// More OpenWatcom cosmetics! https://github.com/open-watcom/open-watcom-v2/issues/780 (Rejected)
// Stack reserved cannot be changed with linker option "OPTION STACK=1m" (Rejected)
// It is not required for DLLs, but everybody does it, and I think it is cosmetics to fill these fields, even if not required.
update_pe_stackSizeCommit(file32tmp, 1024 * 1024, 4096);
update_pe_stackSizeCommit(file32out, 1024 * 1024, 4096);
// Heap reserved can be changed with linker option "OPTION HEAP=1m"
update_pe_heapSizeCommit(file32tmp, 1024 * 1024, 4096);
update_pe_heapSizeCommit(file32out, 1024 * 1024, 4096);
 
// 3. Update timestamp of 32/64 "TMP"
{
if (!update_pe_timestamp(file32tmp, time(0))) {
if (!update_pe_timestamp(file32tmp, (__time32_t)time(0))) {
DeleteFile(file32out);
DeleteFile(file64out);
printf("Error: Update TMP timestamp 32\n");
420,7 → 406,7
return 1;
}
 
if (!update_pe_timestamp(file64tmp, time(0))) {
if (!update_pe_timestamp(file64tmp, (__time32_t)time(0))) {
DeleteFile(file32out);
DeleteFile(file64out);
printf("Error: Update TMP timestamp 64\n");
566,7 → 552,7
 
// 9. Update timestamp of 32/64 "OUT"
{
if (!update_pe_timestamp(file32out, time(0))) {
if (!update_pe_timestamp(file32out, (__time32_t)time(0))) {
DeleteFile(file32out);
DeleteFile(file64out);
printf("Error: Update OUT timestamp 32\n");
573,7 → 559,7
return 1;
}
 
if (!update_pe_timestamp(file64out, time(0))) {
if (!update_pe_timestamp(file64out, (__time32_t)time(0))) {
DeleteFile(file32out);
DeleteFile(file64out);
printf("Error: Update OUT timestamp 64\n");
/trunk/3264_mixer/foundry_3264_mixer.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream