char patch[]={
0xf6,0x81,0x27,2,0,0,1,0x75,0x67,0xc7,0x81,0x2c,2,0,0,0,
0,0,0,0x53,0xcd,0x20,3,0,1,0,0x8b,0x5b,4,0x8b,0x83,0xf4,
1,0,0,0x23,0xc0,0x74,0x48,3,0xd8,0x8a,0x46,0x15,0xa8,0x80,0x74,0x3f,
0x83,0xe0,3,0x52,0xba,0x10,8,0,0,0xf7,0xe2,0x5a,3,0xd8,0xf7,3,
0xff,0xff,0xff,0xff,0x74,0x29,0x51,0x56,0x57,0x8b,0xf3,0x8d,0xb9,0x2c,2,0,
0,0xb9,4,2,0,0,0xf3,0xa5,0x81,0xc6,0x30,0x18,0,0,0xb9,4,
2,0,0,0xf3,0xa5,0x5f,0x5e,0x59,0xc6,0x81,0x27,2,0,0,1,0x5b,
0x8b,0x43,0x10,0x89,0x81,0x28,2,0,0,0xb8,0xff,0,0,0,0xc3,0xf7,
0x80,0x2c,2,0,0,0xff,0xff,0xff,0xff,0x74,3,0x38,0xc0,0xc3,0xf6,0x80,
3,2,0,0,0x40,0xc3,0x60,0x8b,6,0xe8,0xd4,1,0,0,0x74,0x79,
0x81,0xc3,0x10,8,0,0,0x81,0xec,0,2,0,0,0x8b,0xfc,0xf7,0x46,
0x18,0xff,1,0,0,0x75,0x37,0x56,0x8b,0x4e,0x18,0x8b,0x76,0x14,0x53,0x51,
0x56,0x8b,0x45,0,0x83,0xf8,0x20,0x72,0x10,0xe8,0x6b,1,0,0,0x8b,0x45,
0,0x31,0x46,0x40,0xe8,0x60,1,0,0,0x5e,0x59,0x5b,0xff,0x45,0,0x81,
0xc6,0,2,0,0,0x81,0xe9,0,2,0,0,0x77,0xd1,0x5e,0x8b,6,
0xf6,0x40,0x6c,2,0x74,0x1d,0x83,0x46,0x1c,8,0x8b,0x4e,0x1c,0x8b,0x41,4,
0x89,0x46,0x14,0x23,0xc0,0x74,0xc,0x8b,1,0x8a,0x4e,0x22,0xd3,0xe0,0x89,0x46,
0x18,0xeb,0xa4,0x81,0xc4,0,2,0,0,0x61,0xf8,0xc7,0x46,4,0,0,
0,0,0xc3,0xd1,0xe9,0x72,0x6c,0x22,0xc9,0x75,0x68,0x60,0xe8,0x3b,1,0,
0,0x74,0x5e,0x81,0xec,0,4,0,0,0x8d,0xbc,0x24,0,2,0,0,
0x53,0x51,0x8b,0x45,0,0x83,0xf8,0x20,0x72,0x24,0x56,0x52,0xe8,0xaf,0,0,
0,0x8b,0x45,0,0x31,0x46,0x40,0xe8,0xa4,0,0,0,0x5a,0xb9,0,1,
0,0,0xf3,0x66,0x6f,0x5e,0x81,0xc6,0,2,0,0,0xeb,8,0xb9,0,
1,0,0,0xf3,0x66,0x6f,0x59,0x5b,0xff,0x45,0,0x81,0xe9,0,1,0,
0,0x77,0xbd,0x81,0xc4,0,4,0,0,0x61,3,0xf1,3,0xf1,0x33,0xc9,
0xc3,0x61,0xf8,0xf3,0x66,0x6f,0xc3,0xd1,0xe9,0x73,4,0xf3,0x66,0x6d,0xc3,0x22,
0xc9,0x75,0xf8,0x60,0x51,0x57,0xf3,0x66,0x6d,0x5e,0x59,0xe8,0xbc,0,0,0,
0x74,0x43,0x81,0xc3,0x10,8,0,0,0x81,0xec,0,2,0,0,0x8b,0xfc,
0x53,0x51,0x56,0x8b,0x45,0,0x83,0xf8,0x20,0x72,0x10,0xe8,0x69,0,0,0,
0x8b,0x45,0,0x31,0x46,0x40,0xe8,0x5e,0,0,0,0x5e,0x59,0x5b,0xff,0x45,
0,0x81,0xc6,0,2,0,0,0x81,0xe9,0,1,0,0,0x77,0xd1,0x81,
0xc4,0,2,0,0,0x61,3,0xf9,3,0xf9,0xb9,0,0,0,0,0xc3,
0xe8,0x86,0,0,0,0xe8,0x13,1,0,0,0xe8,0x43,1,0,0,0x8d,
0xbe,0,0xfe,0xff,0xff,0xe8,0xad,0,0,0,0xe8,0x81,0,0,0,0xe8,
0xae,0,0,0,0xe8,0x62,0,0,0,0xe8,0xc0,0,0,0,0xe8,0x6d,
0,0,0,0xe8,0xd9,0,0,0,0xc3,0xe8,0x94,0,0,0,0xe8,0x5d,
0,0,0,0xe8,0x7f,0,0,0,0xe8,0x3e,0,0,0,0xe8,0xbf,0,
0,0,0xe8,0x49,0,0,0,0xe8,0x92,0,0,0,0xe8,0x11,1,0,
0,0xe8,0xb7,0,0,0,0xe8,0x20,0,0,0,0xc3,0x8b,0x44,0x24,0x2c,
0x8b,0,0x8b,0x40,4,0x8b,0xa8,0xbb,0,0,0,0x81,0xc5,0x28,2,0,
0,0x8d,0x5d,4,0xf7,3,0xff,0xff,0xff,0xff,0xc3,0x56,0x57,0xb9,0,2,
0,0,0xac,0xd7,0xaa,0xe2,0xfb,0x81,0xc3,0,1,0,0,0x5e,0x5f,0xc3,
0x56,0x57,0xb2,2,0x53,0xb9,0,1,0,0,0x87,0xde,0xac,0xd7,0x87,0xde,
0xaa,0xe2,0xf7,0x81,0xc6,0,1,0,0,0x5b,0xfe,0xca,0x75,0xe6,0x81,0xc3,
0,1,0,0,0x5e,0x5f,0xc3,0x56,0x57,0x66,0x8b,0x13,0x66,0xb9,0,2,
0xeb,0x10,0x56,0x57,0x66,0x8b,0x13,0xfd,0xb9,0xff,1,0,0,3,0xf1,3,
0xf9,0x41,0xac,2,0xc2,0x32,0xc6,0x8a,0xd0,0xaa,0xe2,0xf6,0xeb,0x1d,0x56,0x57,
0x66,0x8b,0x13,0xfd,0xb9,0xff,1,0,0,3,0xf1,3,0xf9,0xac,0x32,0xc6,
0x2a,6,0xaa,0xe2,0xf8,0xac,0x32,0xc6,0x2a,0xc2,0xaa,0xfc,0x43,0x43,0x5e,0x5f,
0xc3,0x56,0x57,0x66,0x8b,0x13,0xb9,0xff,1,0,0,0xeb,0xe0,0x56,0xb9,0,
1,0,0,0x66,0xba,0x25,0,0x66,0x8b,0xc2,0x66,3,0xd2,0x66,3,0xd0,
0x66,3,0xd2,0x66,3,0xd2,0x66,3,0xd0,0x66,0xad,0x23,0xc9,0x7b,8,0x66,
0x35,0xa5,0xa5,0x86,0xe0,0xeb,3,0x66,0x33,0xc2,0x66,0x89,0x46,0xfe,0xe2,0xd7,
0x5e,0xc3,0x56,0x81,0xc6,0xfc,1,0,0,0xb9,0x7f,0,0,0,0xfd,0xad,
0x8b,0xd0,0xad,0x2b,0xd0,0x89,0x56,8,0xe2,0xf6,0xfc,0x5e,0x8b,0x45,0,0x29,
6,0xc3,0xb9,0x80,0,0,0,0x8b,0x55,0,0x56,0xad,3,0xd0,0x89,0x56,
0xfc,0xe2,0xf8,0x5e,0xc3,
};

char cr[]="                Encrypted Disk Patch 1.0  Copyright (C) 2006 by Rudolph R. Loew. All Rights Reserved.           ";

unsigned char tab5[]={0x68,0xa9,0,0,0};                    // +1.W  Add 0x1025
unsigned char tab8[]={0x68,0x27,2,0,0};                    // +1.W  Add 0x1025
unsigned char init[]={0xb8,0xff,0,0,0};                    // Call +off[0]
unsigned char dma5[]={0xf6,0x80,0x85,0,0,0,0x40};          // CNN  +off[1] *2 of 3 / *2,4 of 5
unsigned char dma8[]={0xf6,0x80,3,2,0,0,0x40};             // CNN  +off[1] *2 of 3 / *2,4 of 5
unsigned char pdma[]={0xc7,0x46,4,0,0,0,0};                // CNN  +off[4]
unsigned char sgrd[]={0x75,0x4c,0xd1,0xe9,0xf3,0x66,0x6d}; // NNC  +off[3]
unsigned char sgwr[]={0x75,0x45,0xd1,0xe9,0xf3,0x66,0x6f}; // NNC  +off[2]
int fix[]={2,0xb,0x4d,0x6a,0x75,0x81,0x90,0x27d,0};        // Sub 17E
int offs[]={0,0x7f,0x197,0x123,0x96};
unsigned char cnn[]={0xe8,0,0,0,0,0x90,0x90};
unsigned char nnc[]={0x90,0x90,0xe8,0,0,0,0};
#define tabex 0x1025

#define lenv (sizeof(cr)-8)
#define lenvo 12
#define lenvl 20
#define lenvv (lenvl+1)
#define lenvs (lenvl+3)

long rl(int,unsigned char *);
long find(int,int,unsigned char *,unsigned char *);

int fs;

int main(int c,char **v)
{
unsigned char *b,*b1;
long j,k,l,ad2,ad3,off[6];
int e,f,i,upd,ver;
char name[512],back[512];
printf("\nEncrypted Disk Patch 1.0\n\nCopyright (C) 2006 by Rudolph R. Loew, All Rights Reserved.\n\n");
e=20;upd=ver=0;
if (c>1) {
if (strcmp(v[1],"/?")==0) {printf("PATCHENC [-Verify] [PDR_File]\n");return(0);}
if (v[1][0]=='-') {ver=1;c--;v++;}
}
b=(unsigned char *)malloc(32256);
if (b==0) {printf("Not Enough Memory\n");goto quit;}

if (c>1) {strcpy(name,v[1]);goto man;}
f=_open("C:\\MSDOS.SYS",0);
if (f<0) {printf("Cannot Open C:\\MSDOS.SYS\n");goto manual;}
while(j=rl(f,b)) if (j>9) {
if (b[6]=='=') b[6]=0;
if (stricmp(b,"WINDIR")==0) goto fnd1;
}
_close(f);printf("Cannot Locate Windows Directory\n");goto manual;
fnd1: _close(f);strcpy(name,(char *)b+7);
strcat(name,"\\system\\iosubsys\\Esdi_506.pdr");
man: strcpy(back,name);k=f=strlen(name);
f=k;
for (i=0;i<k;i++) if (back[i]=='.') f=i;
strcpy(back+f,".bac");
if (stricmp(name,back)==0) {printf("Name Conflicts With Backup\n");return(20);}
f=_open((char *)name,0);
if (f<0) {printf("%s Not Found or Inaccessible\n",name);goto manual;}
fs=_read(f,b,32000);
if ((fs<0x300) || (fs>31999)) {printf("Invalid File Size\n");goto quit;}
_close(f);
for (i=fs;i<32256;i++) b[i]=0;
if (find(0,lenv,b,cr)) {
if (ver) {printf("Patch Verified\n");e=0;goto quit;}
printf("File Already Patched - Uninstall ? (Y/N) ");_read(0,b,4);
if ((b[0]&0xdf)-'Y') goto quit;
f=_open((char *)back,0);
if (f<0) {printf("Backup File Not Found or Inaccessible\n");return(20);}
_close(f);_dos_setfileattr(name,0);
if (unlink(name)) {printf("Cannot Remove Patch\n");return(20);}
if (rename(back,name)) {printf("Cannot Rename Backup\n");return(20);}
printf("Patch Removed\n");return(0);
}
if (f=find(0,lenvl,b,cr+lenvo)) {
if (b[f+lenvv]<cr[lenvo+lenvv]) goto okupd;
if (b[f+lenvv]>cr[lenvo+lenvv]) goto qupd;
if (b[f+lenvs]<=cr[lenvo+lenvs]) goto okupd;
qupd: printf("Newer Version Found - Downgrade ? (Y/N) ");
qupd1: _read(0,b+32252,4);
if ((b[32252]&0xdf)-'Y') goto quit;
upd=1;
okupd: f=_open((char *)back,0);
if (f<0) {printf("Backup File Not Found or Inaccessible\n");goto quit;}
fs=_read(f,b,32000);
if ((fs<0x300) || (fs>31999)) {printf("Invalid Backup File\n");goto quit;}
_close(f);upd++;
}
off[5]=0;
if ((off[0]=find(0L,5,b,init))==0) goto bad;
if (find(off[0]+1,5,b,init)) goto bad;
if ((off[2]=find(0L,7,b,sgrd))==0) goto bad;
if (find(off[2]+1,7,b,sgrd)) goto bad;
if ((off[3]=find(0L,7,b,sgwr))==0) goto bad;
if (find(off[3]+1,7,b,sgwr)) goto bad;
if (off[3]-off[2]-0xcd) goto bad;
if (j=find(0L,5,b,tab8)) {
if (find(j+1,5,b,tab8)) goto bad;
if ((off[4]=find(0L,7,b,dma8))==0) goto bad;
if ((off[1]=find(off[4]+1,7,b,dma8))==0) goto bad;
if ((k=find(off[1]+1,7,b,dma8))==0) goto bad;
if (off[5]=find(k+1,7,b,dma8)) {
if ((k=find(off[5]+1,7,b,dma8))==0) goto bad;
if (find(k+1,7,b,dma8)) goto bad;
}
}
else {
if ((j=find(0L,5,b,tab5))==0) goto bad;
if (find(j+1,5,b,tab5)) goto bad;
if ((off[4]=find(0L,7,b,dma5))==0) goto bad;
if ((off[1]=find(off[4]+1,7,b,dma5))==0) goto bad;
if ((k=find(off[1]+1,7,b,dma5))==0) goto bad;
if (off[5]=find(k+1,7,b,dma5)) {
if ((k=find(off[5]+1,7,b,dma5))==0) goto bad;
if (find(k+1,7,b,dma5)) goto bad;
}
i=0;
while(fix[i]) *(int *)(patch+fix[i++])-=0x17e;
}
if (off[1]-off[4]-0x32) goto bad;
if ((off[4]=find(0L,7,b,pdma))==0) goto bad;
if (find(off[4]+1,7,b,pdma)) goto bad;
*(int *)(b+j+1)+=tabex;  
j= *(long *)(b+0x3c);
if ((j<0x40) || (j>fs)) goto bad;
k= *(long *)(b+j+0x40);
if ((k<0xc4) || (k>fs)) goto bad;
ad2= *(long *)(b+j+k);
f= *(long *)(b+j+k+0x10);f<<=12;
if (ad2>fs) goto bad;
ad3= *(long *)(b+j+0x80);
if ((ad3<0x15c) || (ad3>fs)) goto bad;
ad2+=(-ad2-ad3-sizeof(patch))&15;k= *(long *)(b+j+k)=ad2+sizeof(patch)+strlen(cr);
if (k>f) {printf("ESDI_506 File Needs To Be Expanded\n");goto quit;}
ad2+=ad3;
*(unsigned long *)(cnn+1)=ad2+offs[0]-off[0]-5;memcpy(b+off[0],cnn,5);
*(unsigned long *)(cnn+1)=ad2+offs[1]-off[1]-5;memcpy(b+off[1],cnn,7);
*(unsigned long *)(nnc+3)=ad2+offs[2]-off[2]-7;memcpy(b+off[2],nnc,7);
*(unsigned long *)(nnc+3)=ad2+offs[3]-off[3]-7;memcpy(b+off[3],nnc,7);
*(unsigned long *)(cnn+1)=ad2+offs[4]-off[4]-5;memcpy(b+off[4],cnn,7);
if (off[5]) {
*(unsigned long *)(cnn+1)=ad2+offs[1]-off[5]-5;memcpy(b+off[5],cnn,7);
}
memcpy(b+ad2,patch,sizeof(patch)+strlen(cr));
if (upd) {
_dos_setfileattr(name,0);
}
else {
unlink(back);
_dos_setfileattr(name,0);
if (rename(name,back)) {printf("Cannot Rename File\n");goto quit;}
}
f=_creat(name,0);
if (f<0) {printf("Cannot Create Patch File\n");goto undo;}
if (_write(f,b,fs)<fs) {
printf("Error Patching File\n");_close(f);unlink(name);
undo: rename(back,name);goto quit;
}
_close(f);_dos_setfileattr(name,7);
switch (upd) {
case 0: printf("Patch Completed\n");break;
case 1: printf("Patch Upgraded\n");break;
case 2: printf("Patch Downgraded\n");
};
return(0);
manual: printf("\nRerun Command Specifying Full Path to ESDI_506.PDR File\n");
goto quit;
bad: printf("Cannot Patch This Version\n");
quit: if (ver) if (e) {printf("Press Enter to Continue or RESET to Reboot \n");_read(0,back,4);}
return(e);
}

long rl(int f,unsigned char *b)
{
int i,j;
i=0;
lp: j=_read(f,b+i,1);
if (j<1) return(0);
if (b[i]<32) {
if (i==0) goto lp;
b[i]=0;return(i);
}
if (i<255) i++;
goto lp;
}

long find(int i,int j,unsigned char *b,unsigned char *s)
{
int k;
for (;i<fs;i++) {
for (k=0;k<j;k++) if (b[i+k]-s[k]) goto diff;
return(i);
diff:;
}
return(0);
}
