initial commit
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
#include "sgu_stdafx.h"
|
||||
#include "sgu_mode_apply_patch.h"
|
||||
#include "sgu_utils.h"
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "bspatch.h"
|
||||
}
|
||||
|
||||
|
||||
static int patchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
|
||||
{
|
||||
FILE* fp = (FILE*)stream->opaque;
|
||||
size_t n = fread(buffer, 1, (size_t)length, fp);
|
||||
if (n != length)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bzPatchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
|
||||
{
|
||||
BZFILE* bz2 = (BZFILE*)stream->opaque;
|
||||
|
||||
int bz2err;
|
||||
int n = BZ2_bzRead(&bz2err, bz2, buffer, length);
|
||||
if (n != length)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool applyPatch(const char* inputFilename, const char* patchFilename, const char* outputFilename)
|
||||
{
|
||||
if (!inputFilename || inputFilename[0] == 0 || !patchFilename || patchFilename[0] == 0)
|
||||
{
|
||||
printf("Error: Input or Patch filename is not specified.\n");
|
||||
return false;
|
||||
}
|
||||
if (!outputFilename || outputFilename[0] == 0)
|
||||
{
|
||||
printf("Error: Output filename is not specified.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* pInputBuffer = nullptr;
|
||||
FILE* patchFile = nullptr;
|
||||
FILE* outputFile = nullptr;
|
||||
uint8_t* pOutputBuffer = nullptr;
|
||||
|
||||
bool result = false;
|
||||
do {
|
||||
// Open the input file
|
||||
int64_t inputFileSize;
|
||||
pInputBuffer = readFileToBuffer(inputFilename, inputFileSize);
|
||||
if (pInputBuffer == nullptr)
|
||||
{
|
||||
printf("Error: Failed to read input file: %s\n", inputFilename);
|
||||
break;
|
||||
}
|
||||
|
||||
// Open the patch file
|
||||
fopen_s(&patchFile, patchFilename, "rb");
|
||||
if (!patchFile)
|
||||
{
|
||||
printf("Error: Could not open patch file %s\n", patchFilename);
|
||||
break;
|
||||
}
|
||||
|
||||
// Open the output file
|
||||
fopen_s(&outputFile, outputFilename, "wb");
|
||||
if (!outputFile)
|
||||
{
|
||||
printf("Error: Could not open output file %s\n", outputFilename);
|
||||
break;
|
||||
}
|
||||
|
||||
//read the patch file header and check for appropriate magic
|
||||
uint8_t header[24];
|
||||
if (fread(header, 1, 24, patchFile) != 24 || memcmp(header, "ENDSLEY/BSDIFF43", 16) != 0)
|
||||
{
|
||||
printf("Error: Corrupt patch file %s\n", patchFilename);
|
||||
break;
|
||||
}
|
||||
|
||||
// Read output file lengths from header
|
||||
int64_t outputFileSize = *(int64_t*)(header + 16);
|
||||
pOutputBuffer = new uint8_t[outputFileSize + 1];
|
||||
if(pOutputBuffer == nullptr)
|
||||
{
|
||||
printf("Error: Failed to allocate memory[%lld] for output buffer\n", outputFileSize+1);
|
||||
break;
|
||||
}
|
||||
|
||||
int bz2err;
|
||||
BZFILE* bzHandle = BZ2_bzReadOpen(&bz2err, patchFile, 0, 0, NULL, 0);
|
||||
if (bzHandle == nullptr)
|
||||
{
|
||||
printf("BZ2_bzReadOpen, bz2err=%d", bz2err);
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply the patch
|
||||
struct bspatch_stream stream;
|
||||
stream.read = bzPatchFileReader;
|
||||
stream.opaque = bzHandle;
|
||||
if (bspatch(pInputBuffer, inputFileSize, pOutputBuffer, outputFileSize, &stream))
|
||||
{
|
||||
printf("Error: Failed to apply patch\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// Clean up the bzip2 reads
|
||||
BZ2_bzReadClose(&bz2err, bzHandle);
|
||||
|
||||
// Write the output buffer to the output file
|
||||
if (outputFileSize != fwrite(pOutputBuffer, 1, outputFileSize, outputFile))
|
||||
{
|
||||
printf("Error: Failed to write output file %s\n", outputFilename);
|
||||
break;
|
||||
}
|
||||
|
||||
result = true;
|
||||
printf("Patch applied successfully. Output file: %s\n", outputFilename);
|
||||
}while (false);
|
||||
|
||||
// Close all files and free buffers
|
||||
freeFileBuffer(pInputBuffer);
|
||||
pInputBuffer = nullptr;
|
||||
|
||||
if (pOutputBuffer != nullptr)
|
||||
{
|
||||
delete[] pOutputBuffer;
|
||||
pOutputBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (patchFile != nullptr)
|
||||
{
|
||||
fclose(patchFile);
|
||||
patchFile = nullptr;
|
||||
}
|
||||
if (outputFile != nullptr)
|
||||
{
|
||||
fclose(outputFile);
|
||||
outputFile = nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user