Программа BOOTVIEW
Приведем исходный текст программы BOOTVIEW (листинг 2.2), показывающей содержимое загрузочной записи для указанного логического диска.
Для работы с загрузочной записью мы подготовили структуры EBPB и BOOT, описывающие расширенный блок параметров и загрузочную запись, соответственно.
Поле серийного номера диска разбито на две компоненты - volser_lo и volser_hi. Это сделано для облегчения представления серийного номера в том виде, который используется командой DIR операционной системы MS-DOS.
Листинг 2.2. Файл bootview\ bootview.cpp
#include <stdio.h> #include <dos.h> #include <conio.h> #include <ctype.h>
typedef struct _EBPB_ { unsigned sectsize; char clustsize; unsigned ressecs; char fatcnt; unsigned rootsize; unsigned totsecs; char media; unsigned fatsize; unsigned seccnt; unsigned headcnt; unsigned hiddensec_low; unsigned hiddensec_hi; unsigned long drvsecs; } EBPB;
typedef struct _BOOT_ { char jmp[3]; char oem[8]; EBPB bpb; char drive; char reserved; char signature; unsigned volser_lo; unsigned volser_hi; char label[11]; char fat_format[8]; char boot_code[450]; } BOOT;
int getboot(BOOT far *boot, int drive);
int main(void) { char boot[512]; BOOT far* boot_rec = (BOOT far*)boot; int i, status; char drive;
printf("\nЧтение загрузочной записи логического диска" "\n (C)Фролов А., 1995\n");
// Запрашиваем диск, для которого необходимо // выполнить чтение загрузочной записи printf( "\nВведите обозначение диска, для просмотра" "\nзагрузочной записи (A, B, ...):"); drive = getche();
// Вычисляем номер дисковода drive = toupper(drive) - 'A';
// Читаем загрузочную запись в буфер status = getboot((BOOT far*)boot_rec, drive);
// Если произошла ошибка (например, неправильно // указано обозначение диска), // завершаем работу программы if(status) { printf("\nОшибка при чтении загрузочного сектора"); return(-1); }
printf("\nСодержимое загрузочного " "сектора для диска %c", drive + 'A'); printf("\n" "\nOEM - название фирмы и версия DOS - ");
for(i = 0; i < 8; i++) printf("%c", boot_rec->oem[i]);
printf("\nНомер диска - %x" "\nПризнак расширенной BOOT-записи - %c" "\nСерийный номер диска - %04X-%04X" "\nМетка диска - ", (unsigned char)boot_rec->drive, boot_rec->signature, boot_rec->volser_hi, boot_rec->volser_lo);
for(i = 0; i < 11; i++) printf("%c", boot_rec->label[i]);
printf("\nФормат FAT - "); for(i = 0; i < 8; i++) printf("%c", boot_rec->fat_format[i]);
printf("\n\nИнформация из BPB :"); printf("\nКоличество байтов в секторе - %d" "\nКоличество секторов в кластере - %d" "\nЗарезервировано секторов - %d" "\nКоличество копий FAT - %d" "\nМакс. количество файлов в корневом каталоге - %d" "\ nОбщее количество секторов на диске - %d" "\nБайт-описатель среды - %x" "\nКоличество секторов в FAT - %d", boot_rec->bpb.sectsize, boot_rec->bpb.clustsize, boot_rec->bpb.ressecs, boot_rec->bpb.fatcnt, boot_rec->bpb.rootsize, boot_rec->bpb.totsecs, (unsigned char)boot_rec->bpb.media, boot_rec->bpb.fatsize);
printf("\n\nИнформация из расширения BPB :"); printf("\nСекторов на дорожке - %d" "\nКоличество головок - %d" "\nСкрытых секторов для диска < 32 Mбайт - %d" "\nСкрытых секторов для диска >= 32 Mбайт - %d" "\nВсего секторов на диске - %u", boot_rec->bpb.seccnt, boot_rec->bpb.headcnt, boot_rec->bpb.hiddensec_low, boot_rec->bpb.hiddensec_hi, boot_rec->bpb.totsecs);
return 0; }
/** * getboot * * Прочитать загрузочную запись * * int getmboot(BOOT far *boot, int drive); * * boot - указатель на буфер, в который * будет прочитана загрузочная запись * * drive - номер физического НМД * (0 - первый НМД, 1 - второй, ...) **/
int getboot(BOOT far *boot, int drive) { union REGS reg; struct SREGS segreg;
reg.x.ax = drive; reg.x.bx = FP_OFF(boot); segreg.ds = FP_SEG(boot); reg.x.cx = 1; reg.x.dx = 0; int86x(0x25, ®, ®, &segreg);
// Извлекаем из стека оставшееся там после // вызова прерывания слово asm pop ax return(reg.x.cflag); }