📄 copyboot.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <memory.h>
#include <bios.h>
/* Eliminate unnecessary code in the EXE image... */
char **__crt0_glob_function(char *arg) { return 0; }
void __crt0_load_environment_file(char *progname) {}
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define SECTOR_SIZE 512
typedef int BOOL ;
typedef unsigned char BYTE8 ;
typedef unsigned short WORD16 ;
typedef unsigned long DWORD32 ;
#define PCK __attribute__((packed))
typedef struct PARAMS
{
WORD16 bytes_per_sctr PCK ; /* Bytes per sector */
BYTE8 sctrs_per_clust PCK ; /* Sectors per cluster */
WORD16 rsvd_sectors PCK ; /* rsvd sectors (boot sector) */
BYTE8 number_fats PCK ; /* Number of FATs */
WORD16 dir_entries PCK ; /* # root-directory entries */
WORD16 total_sctrs PCK ; /* # sectors in logical volume */
BYTE8 media_desc PCK ; /* Media descriptor byte */
WORD16 sctrs_per_fat PCK ; /* Sectors per FAT */
/* Additional information (MS/DOS 3.0) ... */
WORD16 sctrs_per_track PCK ; /* Sectors per track */
WORD16 number_heads PCK ; /* Number of heads */
DWORD32 hidden_sctrs PCK ; /* Number of hidden sectors */
/* Additional information (MS/DOS 4.0) ... */
DWORD32 ttl_sctrs_vol PCK ; /* ttl log sctrs in log volume */
BYTE8 phys_drive PCK ; /* physical drive number */
BYTE8 reserved1 PCK ; /* reserved */
BYTE8 ext_boot_sig PCK ; /* extended boot signature */
DWORD32 volume_id PCK ; /* 32-bit binary volume ID */
BYTE8 volume_label[11] PCK ; /* volume label */
BYTE8 reserved2[8] PCK ; /* reserved */
/* Additional information written by COPYBOOT.EXE ... */
WORD16 fat_nibbles PCK ; /* 4-bit Nibbles per FAT entry */
WORD16 bytes_per_clust PCK ; /* Bytes per cluster */
WORD16 dir_sector0 PCK ; /* log sctr # of 1st dir sctr */
WORD16 data_sector0 PCK ; /* log sctr # of 1st data sctr */
WORD16 dir_sectors PCK ; /* # directory sectors */
WORD16 para_per_clust PCK ; /* paragraphs per cluster */
WORD16 kb_needed PCK ; /* total memory space required */
WORD16 end_of_chain PCK ; /* end marker for FAT chain */
} PARAMS ;
void Abort(char *fmt, ...) ;
BOOL FAT12(int drive) ;
BOOL FAT16(int drive) ;
BYTE8 * GetFAT(int drive) ;
BOOL Read_Sector(int drive, int sector, void *buffer) ;
BOOL RW_Sector(int command, int drive, int sector, void *buffer) ;
void Summary(PARAMS *p) ;
void Usage(void) ;
BOOL Write_Sector(int drive, int sector, void *buffer) ;
BOOL summary = FALSE ;
int main(int argc, char *argv[])
{
static char filename[] = "BOOTLOAD.BIN" ;
int target_drive, sctr_buffers, bytes_needed ;
static char old[SECTOR_SIZE] ;
static char new[SECTOR_SIZE] ;
BOOL fat12, fat16 ;
char *diskname ;
PARAMS *p ;
FILE *fp ;
if (argc != 2) Usage() ;
strupr(diskname = argv[1]) ;
if (strcmp(diskname, "A") && strcmp(diskname, "A:") &&
strcmp(diskname, "B") && strcmp(diskname, "B:"))
{
Usage() ;
}
target_drive = diskname[0] - 'A' ;
fat12 = FAT12(target_drive) ;
fat16 = FAT16(target_drive) ;
if (!fat12 && !fat16)
{
Abort("Target diskette is NOT formatted FAT12 or FAT16!\n") ;
}
fp = fopen(filename, "rb") ;
if (!fp) Abort("Can't open file: %s\n", filename) ;
if (fread(new, sizeof(new), 1, fp) != 1)
{
Abort("Can't read file: %s\n", filename) ;
}
fclose(fp) ;
if (!Read_Sector(target_drive, 0, old))
{
Abort("Can't read boot sector of drive %c.\n",
diskname[0]) ;
}
memcpy(p = (PARAMS *) &new[11], &old[11], sizeof(PARAMS)) ;
p->ext_boot_sig = 0x29 ;
if (fat12) p->fat_nibbles = 3 ;
if (fat16) p->fat_nibbles = 4 ;
p->bytes_per_clust = p->bytes_per_sctr * p->sctrs_per_clust ;
p->dir_sector0 = 1 + p->number_fats * p->sctrs_per_fat ;
p->data_sector0 = p->dir_sector0 +
(32 * p->dir_entries) / p->bytes_per_sctr ;
p->dir_sectors = (32 * p->dir_entries) / p->bytes_per_sctr ;
p->para_per_clust = p->bytes_per_clust / 16 ;
sctr_buffers = p->dir_sectors ;
if (p->sctrs_per_fat > sctr_buffers) sctr_buffers = p->sctrs_per_fat ;
bytes_needed = p->bytes_per_sctr * (1 + sctr_buffers) ;
p->kb_needed = (bytes_needed + 1023) / 1024 ;
p->end_of_chain = fat16 ? 0xFFF0 : 0x0FF0 ;
Summary(p) ;
if (!Write_Sector(target_drive, 0, new))
{
Abort("Can't write boot sector of drive %c.\n",
diskname[0]) ;
}
printf("Boot loader transferred to boot sector of drive '%c'.\n",
diskname[0]) ;
return 0 ;
}
void Summary(PARAMS *p)
{
char label[12] ;
if (!summary) return ;
printf("\n") ;
printf("%11d Bytes per sector\n", p->bytes_per_sctr) ;
printf("%11d Sectors per cluster\n", p->sctrs_per_clust) ;
printf("%11d rsvd sectors (boot sector)\n", p->rsvd_sectors) ;
printf("%11d Number of FATs\n", p->number_fats) ;
printf("%11d root-directory entries\n", p->dir_entries) ;
printf("%11d sectors in logical volume\n", p->total_sctrs) ;
printf("%11X Media descriptor byte\n", p->media_desc) ;
printf("%11d Sectors per FAT\n", p->sctrs_per_fat) ;
/* Additional information (MS/DOS 3.0) ... */
printf("%11d Sectors per track\n", p->sctrs_per_track) ;
printf("%11d Number of heads\n", p->number_heads) ;
printf("%11ld Number of hidden sectors\n", p->hidden_sctrs) ;
/* Additional information (MS/DOS 4.0) ... */
printf("%11ld ttl log sctrs in log volume\n", p->ttl_sctrs_vol) ;
printf("%11d physical drive number\n", p->phys_drive) ;
printf("%11X reserved\n", p->reserved1) ;
printf("%11X extended boot signature\n", p->ext_boot_sig) ;
printf("%11lX 32-bit binary volume ID\n", p->volume_id) ;
memcpy(label, p->volume_label, 11) ;
label[11] = '\0' ;
printf("%s volume label\n", label) ;
/* Additional information written by COPYBOOT.EXE ... */
printf("%11d 4-bit Nibbles per FAT entry\n", p->fat_nibbles) ;
printf("%11d Bytes per cluster\n", p->bytes_per_clust) ;
printf("%11d log sctr # of 1st dir sctr\n", p->dir_sector0) ;
printf("%11d log sctr # of 1st data sctr\n", p->data_sector0) ;
printf("%11d directory sectors\n", p->dir_sectors) ;
printf("%11d paragraphs per cluster\n", p->para_per_clust) ;
printf("%11d total KB memory space required\n", p->kb_needed) ;
printf("%11X end marker for FAT chain\n", p->end_of_chain) ;
printf("\n") ;
}
BYTE8 *GetFAT(int drive)
{
static BYTE8 fat[SECTOR_SIZE] ;
static int previous = -1 ;
if (drive != previous)
{
if (!Read_Sector(drive, 1, fat))
{
Abort("Can't read 1st sector of 1st FAT!") ;
}
previous = drive ;
}
return fat ;
}
BOOL FAT12(int drive)
{
BYTE8 *fat = GetFAT(drive) ;
return fat[1] == 0xFF && fat[2] == 0xFF && fat[3] != 0xFF ;
}
BOOL FAT16(int drive)
{
BYTE8 *fat = GetFAT(drive) ;
return fat[1] == 0xFF && fat[2] == 0xFF &&
fat[3] == 0xFF && fat[4] != 0xFF ;
}
BOOL RW_Sector(int command, int drive, int sector, void *buffer)
{
int attempt ;
sector++ ;
for (attempt = 0; attempt < 3; attempt++)
{
if (!biosdisk(command, drive, 0, 0, sector, 1, buffer))
{
return TRUE ;
}
biosdisk(0, drive, 0, 0, 0, 0, NULL) ;
}
return FALSE ;
}
BOOL Read_Sector(int drive, int sector, void *buffer)
{
return RW_Sector(2, drive, sector, buffer) ;
}
BOOL Write_Sector(int drive, int sector, void *buffer)
{
return RW_Sector(3, drive, sector, buffer) ;
}
void Abort(char *fmt, ...)
{
va_list args ;
va_start(args, fmt) ;
vfprintf(stderr, fmt, args) ;
va_end(args) ;
exit(255) ;
}
void Usage(void)
{
Abort("Usage: COPYBOOT A:\n") ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -