#define INCL_DOS #include #include #include #define FALSE 0 #define TRUE !FALSE static char buf[65536]; static char MatchB[] = {0x1E, 0x06, 0x0E, 0x0E, 0x1F, 0x07, 0xCD, 0x12, 0xA3}; static char MatchE[] = {0x07, 0x1F, 0xC3}; static int Offsets[] = {0x09, 0x18, 0x5A}; extern char PatchCode[]; extern char PatchCode1[]; extern unsigned short PatchSize, Patches[]; extern char PatchCode1[]; extern unsigned short PatchSize1, Patches1[]; static FILESTATUS3 FileStatus; static void Usage() { printf ("Usage:\n"); printf (" PatchLDR (patch using BIOS function Int15/EAX=E820)\n"); printf (" PatchLDR E820 (patch using BIOS function Int15/EAX=E820)\n"); printf (" PatchLDR DA88 (patch using BIOS function Int15/AX=DA88)\n"); exit (99); } int main (int argc, char *argv[]) { APIRET rc; FILE *f; int i, j; unsigned long filelen; int MatchBPos, MatchEPos; unsigned short VarBase; enum {unknown = 0, E820, DA88} Method = 0; char doit = FALSE; switch (argc) { case 0 : case 1 : Method = E820; break; case 2 : if (!stricmp (argv[1], "E820")) Method = E820; if (!stricmp (argv[1], "DA88")) Method = DA88; break; } if (Method == unknown) Usage(); rc = DosQueryPathInfo ("OS2LDR", FIL_STANDARD, &FileStatus, sizeof (FileStatus)); if (rc == 3) { printf ("File OS2LDR not found\n"); exit (1); } f = fopen ("OS2LDR", "rb"); if (f == NULL) { printf ("File OS2LDR not found\n"); exit (1); } filelen = fread (buf, 1, sizeof (buf), f); fclose (f); if (filelen == sizeof (buf)) { printf ("OS2LDR is too big\n"); exit (2); } for (i = 0; i < (filelen - sizeof (MatchB)); i++) if (!memcmp (buf + i, MatchB, sizeof (MatchB))) { doit = TRUE; MatchBPos = i + sizeof (MatchB) + 2; break; } if (!doit) { printf ("OS2LDR cannot be patched\n"); exit (3); } doit = FALSE; for (i = MatchBPos; i < (filelen - sizeof (MatchE)); i++) if (!memcmp (buf + i, MatchE, sizeof (MatchE))) { doit = TRUE; MatchEPos = i - 3; break; } if (!doit) { printf ("OS2LDR cannot be patched\n"); exit (3); } if ((MatchEPos - MatchBPos) < PatchSize) { printf ("OS2LDR cannot be patched\n"); exit (3); } VarBase = *(unsigned short *)(buf + MatchBPos + Offsets[0] - (sizeof (MatchB) + 2)); doit = (*(unsigned short *)(buf + MatchBPos + Offsets[1] - (sizeof (MatchB) + 2)) - VarBase) == 2; if (!doit) { printf ("OS2LDR cannot be patched\n"); exit (3); } doit = (*(unsigned short *)(buf + MatchBPos + Offsets[2] - (sizeof (MatchB) + 2)) - VarBase) == 8; if (!doit) { printf ("OS2LDR cannot be patched\n"); exit (3); } f = fopen ("OS2LDR.bak", "wb"); if (f == NULL) { printf ("New file OS2LDR.bak cannot be created\n"); exit (4); } i = fwrite (buf, 1, filelen, f); fclose (f); if (i != filelen) { printf ("New file OS2LDR.bak cannot be created\n"); exit (4); } rc = DosSetPathInfo ("OS2LDR.bak", FIL_STANDARD, &FileStatus, sizeof (FileStatus), DSPI_WRTTHRU); if (Method == E820) { memcpy (buf + MatchBPos, PatchCode, PatchSize); memset (buf + MatchBPos + PatchSize, 0x90, MatchEPos - MatchBPos - PatchSize); *(unsigned short*)(buf + MatchBPos + Patches[0]) += VarBase; *(unsigned short*)(buf + MatchBPos + Patches[1]) += VarBase; } else if (Method == DA88) { memcpy (buf + MatchBPos, PatchCode1, PatchSize1); memset (buf + MatchBPos + PatchSize1, 0x90, MatchEPos - MatchBPos - PatchSize1); *(unsigned short*)(buf + MatchBPos + Patches1[0]) += VarBase; *(unsigned short*)(buf + MatchBPos + Patches1[1]) += VarBase; } f = fopen ("OS2LDR", "wb"); if (f == NULL) { printf ("New file OS2LDR cannot be created\n"); exit (4); } i = fwrite (buf, 1, filelen, f); fclose (f); if (i != filelen) { printf ("New file OS2LDR cannot be created\n"); exit (4); } rc = DosSetPathInfo ("OS2LDR", FIL_STANDARD, &FileStatus, sizeof (FileStatus), DSPI_WRTTHRU); return (0); }