Category : Utilities for DOS and Windows Machines
Archive   : BTEASY12.ZIP
Filename : BOOTINST.C
Output of file : BOOTINST.C contained in archive : BTEASY12.ZIP
* Boot installator.
* Author: Serge Vakulenko,
*/
#include
#include
#include
#define BOOTFILE "boot.bin"
#define SAVEFILE "bootsav.bin"
#define SAVE2FILE "boot2sav.bin"
#define PartAddr 0x1be /* Offset to partition table */
#define ValidationAddr 0x1fe /* Offset to validation bytes */
#define MAGIC 0xaa55 /* Validation tag */
#define DISK1 0
#define DISK2 1
#define READ 0
#define WRITE 1
typedef struct PartitionEntry {
unsigned char bootIndicator;
unsigned char beginHead;
unsigned char beginSector;
unsigned char beginCyl;
unsigned char systemId;
unsigned char endHead;
unsigned char endSector;
unsigned char endCyl;
unsigned short relSectorLow;
unsigned short relSectorHigh;
unsigned short numSectorsLow;
unsigned short numSectorsHigh;
} PartitionEntry;
unsigned char bootRecord [512];
unsigned char bootProg [512];
yes ()
{
char reply [80];
printf (" (yes/no) ");
fgets (reply, sizeof (reply), stdin);
return (!stricmp (reply, "y\n") || !stricmp (reply, "yes\n"));
}
main (argc, argv)
char **argv;
{
char *bootfile;
int disk2present;
printf ("Boot installer, version 1.2, Copyright (C) Serge Vakulenko\n\n");
printf ("This utility allows you to install new boot program on your\n");
printf ("hard disk. The usage is:\n\n");
printf (" bootinst [bootfile]\n\n");
printf ("It installs boot block from bootfile (default boot.bin) to the first\n");
printf ("drive and, if second drive is present, to the second drive.\n");
printf ("Old boot sectors are saved to bootsav.bin and boot2sav.bin respectively.\n");
printf ("\nYou can copy and distribute this software free of charge,\n");
printf ("provided that sources are included. No warranty, of course.\n\n");
if (argc > 3)
return (-1);
bootfile = argc>1 ? argv[1] : BOOTFILE;
if (access (bootfile, 4) < 0) {
perror (bootfile);
return (-1);
}
/*
* Is second disk present? Try to read boot sector,
* check that it is bootable and has valid partition table.
*/
disk2present = (bootio (DISK2, READ, 0, 0, 1, bootRecord) == 0 &&
*(short *) &bootRecord [ValidationAddr] == (short) MAGIC &&
(bootRecord [PartAddr] == 0 || bootRecord [PartAddr] == 0x80) &&
(bootRecord [PartAddr+16] == 0 || bootRecord [PartAddr+16] == 0x80) &&
(bootRecord [PartAddr+32] == 0 || bootRecord [PartAddr+32] == 0x80) &&
(bootRecord [PartAddr+48] == 0 || bootRecord [PartAddr+48] == 0x80));
printf ("Continue with installation?");
if (! yes ())
return (0);
install (DISK1, bootfile, SAVEFILE);
if (disk2present)
install (DISK2, bootfile, SAVE2FILE);
return (0);
}
install (disk, file, savefile)
char *file, *savefile;
{
int rc, fd;
rc = bootio (disk, READ, 0, 0, 1, bootRecord);
if (rc) {
fprintf (stderr, "Error %d reading boot record from disk %d\n",
rc, disk);
exit (-1);
}
if (*(short *) &bootRecord [ValidationAddr] != (short) MAGIC) {
fprintf (stderr, "Bad master boot record on disk %d!\n",
disk);
exit (-1);
}
printtable (disk);
fd = open (file, O_RDONLY|O_BINARY);
if (fd < 0) {
fprintf (stderr, "Cannot read file %s\n", file);
exit (-1);
}
if (read (fd, bootProg, 512) != 512) {
fprintf (stderr, "Error reading %s\n", file);
exit (-1);
}
close (fd);
if (*(short *) &bootProg [ValidationAddr] != (short) MAGIC) {
fprintf (stderr, "Bad boot image in file %s\n", file);
exit (-1);
}
printf ("\nAre you sure you want to install new boot on disk %d?",
disk);
if (! yes ())
exit (0);
close (creat (savefile, 0664));
fd = open (savefile, O_WRONLY|O_BINARY);
if (fd < 0) {
fprintf (stderr, "Cannot write to file %s\n", savefile);
exit (-1);
}
if (write (fd, bootRecord, 512) != 512) {
fprintf (stderr, "Error writing to %s\n", savefile);
exit (-1);
}
close (fd);
memcpy (bootRecord, bootProg, PartAddr);
rc = bootio (disk, WRITE, 0, 0, 1, bootRecord);
if (rc) {
fprintf (stderr, "Error %d updating boot record on disk %d\n",
rc, disk);
exit (-1);
}
printf ("New boot record successfully installed.\n");
}
bootio (disk, op, head, cyl, sect, buf)
char *buf;
{
return (biosdisk (op==WRITE ? 3 : 2, disk==DISK1 ? 0x80 : 0x81,
head, cyl, sect, 1, buf));
}
static char head1 [] = "ÚÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿\n";
static char head2 [] = "³ ³Partition³Can ³Boot³ Beginning ³ Ending ³ Relative³Number of³\n";
static char head3 [] = "³N³ Type ³Boot³Part³Head Cyl Sect³Head Cyl Sect³ Sectors ³ Sectors ³\n";
static char head4 [] = "ÃÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÅÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´\n";
static char mid1 [] = "³%d³%-9.9s³%-4.4s³%-4.4s³%3u ³%4u ³%3u ³%3u ³%4u ³%3u ³%8lu ³%8lu ³\n";
static char mid2 [] = "ÃÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´\n";
static char foot [] = "ÀÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ\n";
printtable (disk)
{
PartitionEntry *part = (PartitionEntry *) (bootRecord + PartAddr);
int i, cb;
long relSectors;
long numSectors;
char *typeString, block [512];
printf ("\n");
printf (head1);
printf (head2);
printf (head3);
printf (head4);
for (i=0; i<4; ++i) {
switch (part->systemId) {
default: typeString = " ?????"; cb = 1; break;
case 0: typeString = " empty"; cb = 0; break;
case 1: typeString = " dos-12"; cb = 1; break;
case 2: typeString = " xenix"; cb = 1; break;
case 3: typeString = "xenix usr"; cb = 0; break;
case 4: typeString = " dos-16"; cb = 1; break;
case 5: typeString = " extend"; cb = 0; break;
case 6: typeString = " bigdos"; cb = 1; break;
case 7: typeString = " hpfs"; cb = 1; break;
case 0x75: typeString = " pcix"; cb = 1; break;
case 0xdb: typeString = " cp/m"; cb = 1; break;
case 0xff: typeString = " bbt"; cb = 0; break;
case 0x08: typeString = " aix"; cb = 0; break;
case 0x09: typeString = " coherent"; cb = 1; break;
case 0x0A: typeString = " os/2"; cb = 1; break;
case 0x10: typeString = " opus"; cb = 1; break;
case 0x40: typeString = "venix 286"; cb = 1; break;
case 0x50:
case 0x51: typeString = " dm"; cb = 1; break;
case 0x52: typeString = "microport"; cb = 1; break;
case 0x56: typeString = " gb"; cb = 1; break;
case 0x61:
case 0xE1:
case 0xE3:
case 0xE4:
case 0xF1:
case 0xF4: typeString = " speed"; cb = 1; break;
case 0x63: typeString = " unix"; cb = 1; break;
case 0x64: typeString = "novell286"; cb = 1; break;
case 0x65: typeString = "novell386"; cb = 1; break;
case 0x80: typeString = "old minix"; cb = 1; break;
case 0x81: typeString = " minix"; cb = 1; break;
case 0x82: typeString = " linux"; cb = 1; break;
case 0x93: typeString = " amoeba"; cb = 1; break;
case 0x94: typeString = "amoebaBBT"; cb = 0; break;
case 0xA5: typeString = " 386bsd"; cb = 1; break;
case 0xB7: typeString = " bsdi"; cb = 1; break;
case 0xB8: typeString = "bsdi swap"; cb = 0; break;
case 0xF2: typeString = " dos sec"; cb = 1; break;
}
relSectors = part->relSectorLow |
(unsigned long) part->relSectorHigh<<16;
numSectors = part->numSectorsLow |
(unsigned long) part->numSectorsHigh<<16;
if (cb && (bootio (disk, READ, part->beginHead, part->beginCyl,
part->beginSector, block) != 0 ||
*(short *) &block [ValidationAddr] != (short) MAGIC))
cb = 0;
printf (mid1, i+1, typeString, cb ? " yes" : " no",
(part->bootIndicator & 0x80) ? " yes" : " no",
part->beginHead, part->beginCyl |
part->beginSector<<2 & 0x300,
part->beginSector & 077, part->endHead,
part->endCyl | part->endSector<<2 & 0x300,
part->endSector & 077, relSectors, numSectors);
if (i < 3)
printf (mid2);
++part;
}
printf (foot);
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/