summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorMassimiliano Torromeo2011-05-23 09:51:56 +0200
committerMassimiliano Torromeo2011-05-23 09:51:56 +0200
commitae71a9355da4ad59cde066bd24e9d5d63e8312ee (patch)
treec6100ef0ffc74acbd57b6db2416a39c271650bf8
downloadaur-ae71a9355da4ad59cde066bd24e9d5d63e8312ee.tar.gz
first commit
-rw-r--r--.SRCINFO13
-rw-r--r--PKGBUILD15
-rw-r--r--applyppf3_linux.c443
3 files changed, 471 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..d28fea7dde2e
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,13 @@
+pkgbase = applyppf
+ pkgdesc = PPF (Playstation Patch File) v3.0 apply tool
+ pkgver = 3.0
+ pkgrel = 2
+ url = http://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/emulators/applyppf/DESCR
+ arch = i686
+ arch = x86_64
+ license = GPL
+ source = http://ftp.netbsd.org/pub/pkgsrc/distfiles/applyppf3_src.zip
+ sha256sums = 49a1be17e1c87a41a85068d23afad3860ede49e61db90d1d086ead036d63eae2
+
+pkgname = applyppf
+
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..762097e12ddd
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,15 @@
+pkgname=applyppf
+pkgver=3.0
+pkgrel=1
+pkgdesc="PPF (Playstation Patch File) v3.0 apply tool"
+url="http://www.google.com/search?q=applyppf"
+arch=('i686' 'x86_64')
+license=('GPL')
+source=(applyppf3_linux.c)
+
+md5sums=('b959fce3d4b550f89a74380fbc78c116')
+
+build() {
+ gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -o applyppf applyppf3_linux.c
+ install -D -m0755 applyppf $pkgdir/usr/bin/applyppf
+}
diff --git a/applyppf3_linux.c b/applyppf3_linux.c
new file mode 100644
index 000000000000..840ff47d87ce
--- /dev/null
+++ b/applyppf3_linux.c
@@ -0,0 +1,443 @@
+/*
+ * ApplyPPF3.c (Linux Version)
+ * written by Icarus/Paradox
+ *
+ * Big Endian support by Hu Kares.
+ *
+ * Applies PPF1.0, PPF2.0 & PPF3.0 Patches (including PPF3.0 Undo support)
+ * Feel free to use this source in and for your own
+ * programms.
+ *
+ * To compile enter:
+ * gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE applyppf3_linux.c
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(__APPLE__) || defined (MACOSX)
+
+//////////////////////////////////////////////////////////////////////
+// fseeko is already 64 bit for Darwin/MacOS X!
+// fseeko64 undefined for Darwin/MacOS X!
+
+#define fseeko64 fseeko
+
+//////////////////////////////////////////////////////////////////////
+// ftellko is already 64 bit for Darwin/MacOS X!
+// ftello64 undefined for Darwin/MacOS X!
+
+#define ftello64 ftello
+
+//////////////////////////////////////////////////////////////////////
+// "off_t" is already 64 bit for Darwin/MacOS X!
+// "__off64_t" undefined for Darwin/MacOS X!
+
+typedef off_t __off64_t;
+
+#endif /* __APPLE__ || MACOSX */
+
+//////////////////////////////////////////////////////////////////////
+// Macros for little to big Endian conversion.
+
+#ifdef __BIG_ENDIAN__
+
+#define Endian16_Swap(value) (value = (((((unsigned short) value) << 8) & 0xFF00) | \
+ ((((unsigned short) value) >> 8) & 0x00FF)))
+
+#define Endian32_Swap(value) (value = (((((unsigned long) value) << 24) & 0xFF000000) | \
+ ((((unsigned long) value) << 8) & 0x00FF0000) | \
+ ((((unsigned long) value) >> 8) & 0x0000FF00) | \
+ ((((unsigned long) value) >> 24) & 0x000000FF)))
+
+#define Endian64_Swap(value) (value = (((((unsigned long long) value) << 56) & 0xFF00000000000000ULL) | \
+ ((((unsigned long long) value) << 40) & 0x00FF000000000000ULL) | \
+ ((((unsigned long long) value) << 24) & 0x0000FF0000000000ULL) | \
+ ((((unsigned long long) value) << 8) & 0x000000FF00000000ULL) | \
+ ((((unsigned long long) value) >> 8) & 0x00000000FF000000ULL) | \
+ ((((unsigned long long) value) >> 24) & 0x0000000000FF0000ULL) | \
+ ((((unsigned long long) value) >> 40) & 0x000000000000FF00ULL) | \
+ ((((unsigned long long) value) >> 56) & 0x00000000000000FFULL)))
+
+#else
+
+#define Endian16_Swap(value)
+#define Endian32_Swap(value)
+#define Endian64_Swap(value)
+
+#endif /* __BIG_ENDIAN__ */
+
+//////////////////////////////////////////////////////////////////////
+// Used global variables.
+FILE *ppf, *bin;
+char binblock[1024], ppfblock[1024];
+unsigned char ppfmem[512];
+#define APPLY 1
+#define UNDO 2
+
+//////////////////////////////////////////////////////////////////////
+// Used prototypes.
+int PPFVersion(FILE *ppf);
+int OpenFiles(char* file1, char* file2);
+int ShowFileId(FILE *ppf, int ppfver);
+void ApplyPPF1Patch(FILE *ppf, FILE *bin);
+void ApplyPPF2Patch(FILE *ppf, FILE *bin);
+void ApplyPPF3Patch(FILE *ppf, FILE *bin, char mode);
+
+int main(int argc, char **argv){
+ int x;
+ printf("ApplyPPF v3.0 by =Icarus/Paradox= %s\n", __DATE__);
+#ifdef __BIG_ENDIAN__
+ printf("Big Endian support by =Hu Kares=\n\n"); // <Hu Kares> sum credz
+#endif /* __BIG_ENDIAN__ */
+ if(argc!=4){
+ printf("Usage: ApplyPPF <command> <binfile> <patchfile>\n");
+ printf("<Commands>\n");
+ printf(" a : apply PPF1/2/3 patch\n");
+ printf(" u : undo patch (PPF3 only)\n");
+
+ printf("\nExample: ApplyPPF.exe a game.bin patch.ppf\n");
+ return(0);
+ }
+
+ switch(*argv[1]){
+ case 'a' : if(OpenFiles(argv[2], argv[3])) return(0);
+ x=PPFVersion(ppf);
+ if(x){
+ if(x==1){ ApplyPPF1Patch(ppf, bin); break; }
+ if(x==2){ ApplyPPF2Patch(ppf, bin); break; }
+ if(x==3){ ApplyPPF3Patch(ppf, bin, APPLY); break; }
+ } else{ break; }
+ break;
+ case 'u' : if(OpenFiles(argv[2], argv[3])) return(0);
+ x=PPFVersion(ppf);
+ if(x){
+ if(x!=3){
+ printf("Undo function is supported by PPF3.0 only\n");
+ } else {
+ ApplyPPF3Patch(ppf, bin, UNDO);
+ }
+ } else{ break; }
+ break;
+ default :
+ printf("Error: unknown command: \"%s\"\n",argv[1]);
+ return(0);
+ break;
+ }
+
+ fclose(bin);
+ fclose(ppf);
+ return(0);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Applies a PPF1.0 patch.
+void ApplyPPF1Patch(FILE *ppf, FILE *bin){
+ char desc[50];
+ int pos;
+ unsigned int count, seekpos;
+ unsigned char anz;
+
+
+ fseeko64(ppf, 6,SEEK_SET); /* Read Desc.line */
+ fread(&desc, 1, 50, ppf); desc[50]=0;
+ printf("Patchfile is a PPF1.0 patch. Patch Information:\n");
+ printf("Description : %s\n",desc);
+ printf("File_id.diz : no\n");
+
+ printf("Patching... "); fflush(stdout);
+ fseeko64(ppf, 0, SEEK_END);
+ count=ftell(ppf);
+ count-=56;
+ seekpos=56;
+ printf("Patching ... ");
+
+ do{
+ printf("reading...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
+ fseeko64(ppf, seekpos, SEEK_SET);
+ fread(&pos, 1, 4, ppf);
+ Endian32_Swap (pos); // <Hu Kares> little to big endian
+ fread(&anz, 1, 1, ppf);
+ fread(&ppfmem, 1, anz, ppf);
+ fseeko64(bin, pos, SEEK_SET);
+ printf("writing...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
+ fwrite(&ppfmem, 1, anz, bin);
+ seekpos=seekpos+5+anz;
+ count=count-5-anz;
+ } while(count!=0);
+
+ printf("successful.\n");
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Applies a PPF2.0 patch.
+void ApplyPPF2Patch(FILE *ppf, FILE *bin){
+ char desc[50], in;
+ unsigned int binlen, obinlen, count, seekpos;
+ int idlen, pos;
+ unsigned char anz;
+
+
+
+ fseeko64(ppf, 6,SEEK_SET);
+ fread(&desc, 1, 50, ppf); desc[50]=0;
+ printf("Patchfile is a PPF2.0 patch. Patch Information:\n");
+ printf("Description : %s\n",desc);
+ printf("File_id.diz : ");
+ idlen=ShowFileId(ppf, 2);
+ if(!idlen) printf("not available\n");
+
+ fseeko64(ppf, 56, SEEK_SET);
+ fread(&obinlen, 1, 4, ppf);
+ Endian32_Swap (obinlen); // <Hu Kares> little to big endian
+ fseeko64(bin, 0, SEEK_END);
+ binlen=ftell(bin);
+ if(obinlen!=binlen){
+ printf("The size of the bin file isn't correct, continue ? (y/n): "); fflush(stdout);
+ in=getc(stdin);
+ if(in!='y'&&in!='Y'){
+ printf("Aborted...\n");
+ return;
+ }
+ }
+
+ fflush(stdin);
+ fseeko64(ppf, 60, SEEK_SET);
+ fread(&ppfblock, 1, 1024, ppf);
+ fseeko64(bin, 0x9320, SEEK_SET);
+ fread(&binblock, 1, 1024, bin);
+ in=memcmp(ppfblock, binblock, 1024);
+ if(in!=0){
+ printf("Binblock/Patchvalidation failed. continue ? (y/n): "); fflush(stdout);
+
+#if defined(__APPLE__) || defined (MACOSX)
+
+ if(obinlen!=binlen) { // <Hu Kares> required, since fflush doesn't flush '\n'!
+ in=getc(stdin);
+ }
+
+#endif /* __APPLE__ || MACOSX */
+
+ in=getc(stdin);
+ if(in!='y'&&in!='Y'){
+ printf("Aborted...\n");
+ return;
+ }
+ }
+
+ printf("Patching... "); fflush(stdout);
+ fseeko64(ppf, 0, SEEK_END);
+ count=ftell(ppf);
+ seekpos=1084;
+ count-=1084;
+ if(idlen) count-=idlen+38;
+
+ do{
+ printf("reading...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
+ fseeko64(ppf, seekpos, SEEK_SET);
+ fread(&pos, 1, 4, ppf);
+ Endian32_Swap (pos); // <Hu Kares> little to big endian
+ fread(&anz, 1, 1, ppf);
+ fread(&ppfmem, 1, anz, ppf);
+ fseeko64(bin, pos, SEEK_SET);
+ printf("writing...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
+ fwrite(&ppfmem, 1, anz, bin);
+ seekpos=seekpos+5+anz;
+ count=count-5-anz;
+ } while(count!=0);
+
+ printf("successful.\n");
+}
+//////////////////////////////////////////////////////////////////////
+// Applies a PPF3.0 patch.
+void ApplyPPF3Patch(FILE *ppf, FILE *bin, char mode){
+ char desc[50], imagetype=0, in;
+ unsigned char undo=0, blockcheck=0;
+ int idlen;
+ __off64_t offset, count; // <Hu Kares> count has to be 64 bit!
+ unsigned int seekpos;
+ unsigned char anz=0;
+
+
+ fseeko64(ppf, 6,SEEK_SET); /* Read Desc.line */
+ fread(&desc, 1, 50, ppf); desc[50]=0;
+ printf("Patchfile is a PPF3.0 patch. Patch Information:\n");
+ printf("Description : %s\n",desc);
+ printf("File_id.diz : ");
+
+ idlen=ShowFileId(ppf, 3);
+ if(!idlen) printf("not available\n");
+
+ fseeko64(ppf, 56, SEEK_SET);
+ fread(&imagetype, 1, 1, ppf);
+ fseeko64(ppf, 57, SEEK_SET);
+ fread(&blockcheck, 1, 1, ppf);
+ fseeko64(ppf, 58, SEEK_SET);
+ fread(&undo, 1, 1, ppf);
+
+ if(mode==UNDO){
+ if(!undo){
+ printf("Error: no undo data available\n");
+ return;
+ }
+ }
+
+ if(blockcheck){
+ fflush(stdin);
+ fseeko64(ppf, 60, SEEK_SET);
+ fread(&ppfblock, 1, 1024, ppf);
+
+ if(imagetype){
+ fseeko64(bin, 0x80A0, SEEK_SET);
+ } else {
+ fseeko64(bin, 0x9320, SEEK_SET);
+ }
+ fread(&binblock, 1, 1024, bin);
+ in=memcmp(ppfblock, binblock, 1024);
+ if(in!=0){
+ printf("Binblock/Patchvalidation failed. continue ? (y/n): "); fflush(stdout);
+ in=getc(stdin);
+ if(in!='y'&&in!='Y'){
+ printf("Aborted...\n");
+ return;
+ }
+ }
+ }
+
+ fseeko64(ppf, 0, SEEK_END);
+ count=ftello64(ppf); // <Hu Kares> 64 bit!
+ fseeko64(ppf, 0, SEEK_SET);
+
+ if(blockcheck){
+ seekpos=1084;
+ count-=1084;
+ } else {
+ seekpos=60;
+ count-=60;
+ }
+
+ if(idlen) count-=(idlen+18+16+2);
+
+
+ printf("Patching ... ");
+ fseeko64(ppf, seekpos, SEEK_SET);
+ do{
+ printf("reading...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
+ fread(&offset, 1, 8, ppf);
+ Endian64_Swap(offset); // <Hu Kares> little to big endian
+ fread(&anz, 1, 1, ppf);
+
+ if(mode==APPLY){
+ fread(&ppfmem, 1, anz, ppf);
+ if(undo) fseeko64(ppf, anz, SEEK_CUR);
+ }
+ else {
+ if(mode==UNDO){
+ fseeko64(ppf, anz, SEEK_CUR);
+ fread(&ppfmem, 1, anz, ppf);
+ }
+ }
+
+ printf("writing...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
+ fseeko64(bin, offset, SEEK_SET);
+ fwrite(&ppfmem, 1, anz, bin);
+ count-=(anz+9);
+ if(undo) count-=anz;
+
+ } while(count!=0);
+
+ printf("successful.\n");
+
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Shows File_Id.diz of a PPF2.0 / PPF3.0 patch.
+// Input: 2 = PPF2.0
+// Input: 3 = PPF3.0
+// Return 0 = Error/no fileid.
+// Return>0 = Length of fileid.
+int ShowFileId(FILE *ppf, int ppfver){
+ char buffer2[3073];
+ unsigned int idmagic;
+ int lenidx=0, idlen=0, orglen=0;
+
+
+ if(ppfver==2){
+ lenidx=4;
+ } else {
+ lenidx=2;
+ }
+
+ fseeko64(ppf,-(lenidx+4),SEEK_END);
+ fread(&idmagic, 1, 4, ppf);
+ Endian32_Swap (idmagic); // <Hu Kares> little to big endian
+ if(idmagic!='ZID.'){
+ return(0);
+ } else {
+ fseeko64(ppf,-lenidx,SEEK_END);
+ fread(&idlen, 1, lenidx, ppf);
+ Endian32_Swap (idlen); // <Hu Kares> little to big endian
+ orglen = idlen;
+ if (idlen > 3072) { // <Hu Kares> to be secure: avoid segmentation fault!
+ idlen = 3072;
+ }
+ fseeko64(ppf,-(lenidx+16+idlen),SEEK_END);
+ fread(&buffer2, 1, idlen, ppf);
+ buffer2[idlen]=0;
+ printf("available\n%s\n",buffer2);
+ }
+
+ return(orglen);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Check what PPF version we have.
+// Return: 0 - File is no PPF.
+// Return: 1 - File is a PPF1.0
+// Return: 2 - File is a PPF2.0
+// Return: 3 - File is a PPF3.0
+int PPFVersion(FILE *ppf){
+ unsigned int magic;
+
+ fseeko64(ppf,0,SEEK_SET);
+ fread(&magic, 1, 4, ppf);
+ Endian32_Swap (magic); // <Hu Kares> little to big endian
+ switch(magic){
+ case '1FPP' : return(1);
+ case '2FPP' : return(2);
+ case '3FPP' : return(3);
+ default : printf("Error: patchfile is no ppf patch\n"); break;
+ }
+
+ return(0);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Open all needed files.
+// Return: 0 - Successful
+// Return: 1 - Failed.
+int OpenFiles(char* file1, char* file2){
+
+ bin=fopen(file1, "rb+");
+ if(!bin){
+ printf("Error: cannot open file '%s' ",file1);
+ return(1);
+ }
+
+ ppf=fopen(file2, "rb");
+ if(!ppf){
+ printf("Error: cannot open file '%s' ",file2);
+ fclose(bin);
+ return(1);
+ }
+
+ return(0);
+}