Текст программы. /*-------Лабораторная работа N9----------------*/
/*-------Лабораторная работа N9----------------*/
/*-----"Дисковые структуры данных DOS."--------*/
/* Подключение стандартных заголовков */
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
/*------------------------------------------------*/
/* Типи и структуры данных */
#define byte unsigned char
#define word unsigned int
#define dword unsigned long
#define daddr struct DADDR
struct DADDR { /* физический дисковый адрес */
byte h;
word s, t, ts;
};
struct PART { /* структура элемента раздела */
byte Boot, Begin_Hd;
word Begin_SecTrk;
byte SysCode, End_Hd;
word End_SecTrk;
dword RelSec, Size;
};
struct MBR
{ /* стpуктуpа Главной Загрузочной Записи */
char LoadCode[0x1be];
struct PART rt[4];
word EndFlag;
};
struct BootRec
{ /* структура корневой записи */
byte jmp[3], ident[8];
word SectSize;
byte ClustSize;
word ResSect;
byte FatCnt;
word RootSize, TotSecs;
byte Media;
word FatSize, TrkSecs, HeadCnt;
word HidnSecL, HidnSecH;
dword LongTotSecs;
byte Drive, reserved1, DOS4_flag;
dword VolNum;
char VolLabel[11], FatForm[8];
};
struct Dir_Item
{ /* структура элемента директории */
char fname[11];
byte attr;
char reserved[10];
word time, date, cl;
dword size;
};
/*-----------------------------------------------*/
/* Описания функций */
void Read_Mbr(void);
/* Чтение MBR и поиск требуемого раздела */
void Read_Boot(void); /* Чтение boot-сектора */
void Get_First(void); /* Определение абсолютного номера сектора начала логического диска */
void Read_Fat(void); /* Чтение FAT */
void Read_13(void *mem);
/* Чтение сектора с омогощью прерывания 13 */
void Sect_to_Daddr(dword sect);
/* Формирование физического дискового адреса из # сектора */
dword Clust_to_Sect(word clust);
/* Вычисление номера сектора из номера кластера */
word Next_Clust(word clust);
/* Выборка следующего кластера из FAT */
char *Get_Name(char *s, char *d);
/* Выделение следующего элемента из строки-задания */
int Find_Name(); /* Поиск имени в каталоге */
void End_of_Job(int n); /* Завершение (при n=0-5 — аварийное) */
/*------------------------------------------------*/
/* Переменнi */
struct PART part; /* текущий элемент раздела */
byte buff1[512]; /* буфер MBR и boot */
struct MBR *mbr; /* указатель на таблицу разделов */
struct BootRec *boot; /* указатель на корневую запись */
byte buff2[512]; /* буфер каталога и текста */
struct Dir_Item *dir; /* указатель на часть каталога */
char *text; /* указатель на текстовий буфер */
byte *fat; /* указатель на FAT */
char job[81]; /* строка-задание */
char *jobptr; /* текущий указатель в job */
char cname[12]; /* текущее имя для поиска */
byte Fdisk; /* физический номер диска */
daddr caddr; /* текущий дисковый адрес */
dword sect; /* текущий номер сектора */
word clust; /* текущий номер кластера */
byte fat16; /* признак формату FAT */
dword fsize; /* размер файла */
int dirnum; /* номер элемента в каталоге */
dword FirstSect; /* абс.сектор начала */
byte rootdir=1; /* признак корневого каталога
или подкаталога (1/0) */
word lastsect; /* последний сектор при чтении /
byte fatalloc=0; /* признак выделения памяти */
/*-----------------------------------------------*/
main() {
int n,i;
textattr(14);
clrscr();
/* ввод имени файла */
cprintf(" Просмотр таблицы FAT. ");
cprintf("Укажите полное имя файла -->");
scanf("%s",job);
/* перевод в верхний регистр */
strupr(job);
/* проверка правильности идентификатора диска */
if ((!isalpha(job[0]))||(job[1]!=':')||(job[2]!='\\')) {
printf("%c%c%c -",job[0],job[1],job[2]);
End_of_Job(0);
}
textattr(10);
clrscr();
printf(" Лабораторная работа N9");
printf(" Дисковые структуры данных DOS.");
textattr(14);
cprintf("Файл %s в FAT занимает такие кластеры:\n",job);
jobptr=job+3;
if (job[0]>'A') {
/* для жесткого диска — физический номер и чтение MBR */
Fdisk=0x80;
Read_Mbr();
}
else /* для гибкого диска — физический номер */
Fdisk=job[0]-'A';
Read_Boot(); /* чтение boot-сектора */
Read_Fat(); /* чтение FAT */
dir=(struct Dir_Item *)buff2;
do { /* рух по каталогам */
if (!rootdir) clust=dir[dirnum].cl; /* начальный кластер */
/* выделение следующего элемента из строки-задания */
jobptr=Get_Name(jobptr,cname);
do { /* пока не дойдем до последнего кластера */
if (rootdir) { /* корневой каталог */
/* нач.сектор корневого кат. и количество секторов */
sect=boot->ResSect+boot->FatSize*boot->FatCnt;
lastsect=boot->RootSize*32/boot->SectSize+sect;
}
else { /* подкаталог */
sect=Clust_to_Sect(clust);
lastsect=boot->ClustSize+sect;
}
/* посекторное чтение всего корневого каталога
или одного кластера подкаталога */
for (; sect<lastsect; sect++) {
Sect_to_Daddr(sect);
Read_13(dir);
/* поиск имени в прочитанном секторе */
if ((dirnum=Find_Name())>=0) goto FIND;
}
/* до последнего кластера подкаталога */
}
while (clust=Next_Clust(clust));
/* весь каталог просмотрен, а имя не найдено — ошибка */
printf("%s -",cname);
if (jobptr==NULL) End_of_Job(4);
else End_of_Job(5);
FIND: /* имя найдено */
rootdir=0;
}
while (jobptr!=NULL);
/* найдено имя файла */
/* из каталога получеем 1-й кластер */
clust=dir[dirnum].cl;
textattr(7);
gotoxy(10,4);
cprintf("Нажимайте любую клавишу ");
cprintf(" пока не появится <КОНЕЦ ФАЙЛА>.");
textattr(12);
gotoxy(1,5);
cprintf("-<НАЧАЛО ФАЙЛА>");
gotoxy(1,6);
cprintf("L->");
i=0;
do {
i++;
if((i%10)==0) getch();
textattr(14+16);
cprintf("%4x",clust);
textattr(2);
cprintf("--->");
}
while (clust=Next_Clust(clust));
textattr(12);
cprintf("<КОНЕЦ ФАЙЛА>\n");
gotoxy(1,wherey());
textattr(15+3*16);
cprintf("Количество кластеров в файле: %u ",i);
End_of_Job(7);
}
/*-----------------------------------------------*/
/* Чтение MBR и поиск нужного раздела */
void Read_Mbr(void) {
int i;
char ndrive;
word *EndList;
caddr.h=0;
caddr.ts=1;
ndrive='C';
mbr=(struct MBR *)buff1;
NEXT: Read_13(buff1);
for (EndList=(word *)&mbr->rt[(i=0)];
(*EndList!=0xaa55)&&(mbr->rt[i].Size>0L);
EndList=(word *)&mbr->rt[++i]) {
if (mbr->rt[i].SysCode==5) {
caddr.h=mbr->rt[i].Begin_Hd;
caddr.ts=mbr->rt[i].Begin_SecTrk;
goto NEXT;
}
if (ndrive==job[0]) {
movmem(&mbr->rt[i],&part,sizeof(struct PART));
return;
}
else ndrive++;
}
/* требуемый раздел не найден */
printf("%c: -",job[0]);
End_of_Job(1);
}
/*-----------------------------------------------*/
/* Чтение boot-сектора */
void Read_Boot(void) {
if (Fdisk<0x80) {
caddr.h=0;
caddr.ts=1;
}
else {
caddr.h=part.Begin_Hd;
caddr.ts=part.Begin_SecTrk;
}
Read_13(buff1);
boot=(struct BootRec *)buff1;
Get_First();
}
/*------------------------------------------------*/
/* Чтение FAT */
void Read_Fat(void) {
dword s, ls;
byte *f;
fat=(byte *)malloc(boot->FatSize*boot->SectSize);
if (fat==NULL) {
printf("Размещение FAT -");
End_of_Job(3);
}
fatalloc=1;
s=boot->ResSect;
ls=s+boot->FatSize;
for (f=fat; s<ls; s++) {
Sect_to_Daddr(s);
Read_13(f);
f+=boot->SectSize;
}
/* установление формата FAT */
if (Fdisk>=0x80)
if (part.SysCode==1) fat16=0;
else fat16=1;
else fat16=0;
}
/*-----------------------------------------------*/
/* Чтение сектора при помощи прерывания 13 */
void Read_13(void *mem) {
/* mem — адреса в ОП */
union REGS rr;
struct SREGS sr;
rr.h.ah=2;
rr.h.al=1;
rr.h.dl=Fdisk;
rr.h.dh=caddr.h;
rr.x.cx=caddr.ts;
sr.es=FP_SEG(mem);
rr.x.bx=FP_OFF(mem);
int86x(0x13,&rr,&rr,&sr);
/* Проверка ошибок чтения */
if (rr.x.cflag&1) {
printf("%u -",rr.h.ah);
End_of_Job(2);
}
}
/*------------------------------------------------*/
/* Определение абс.номера сектора начала лог.диска */
void Get_First(void) {
word s, t;
if (Fdisk<0x80) FirstSect=0;
else {
/* формирование # сектора из физич. дискового адреса */
t=(part.Begin_SecTrk>>8)|((part.Begin_SecTrk<<2)&0x300);
s=part.Begin_SecTrk&0x3f;
FirstSect=(((dword)t*boot->HeadCnt)+part.Begin_Hd)*
boot->TrkSecs+s-1;
}
}
/*------------------------------------------------*/
/* Формирование физического дискового адреса из # сектора */
void Sect_to_Daddr(dword sect) {
/* sect — номер сектора, caddr — адрес на диске */
dword s;
if (Fdisk>=0x80) sect+=FirstSect;
caddr.s=sect%boot->TrkSecs+1;
s=sect/boot->TrkSecs;
caddr.h=s%boot->HeadCnt;
caddr.t=s/boot->HeadCnt;
caddr.ts=(caddr.t<<8)|caddr.s|((caddr.t&0x300)>>2);
}
/*-----------------------------------------------*/
/* Вычисление номера сектора из номера кластера */
dword Clust_to_Sect(word clust) {
/* clust — номер кластера, возвращает номер сектора */
dword ds, s;
ds=boot->ResSect+boot->FatSize*boot->FatCnt+
boot->RootSize*32/boot->SectSize;
s=ds+(clust-2)*boot->ClustSize;
return(s);
}
/*------------------------------------------------*/
/* Выборка следующего кластера из FAT */
word Next_Clust(word clust) {
/* clust — номер кластера, возвращает номер следующего кластера
или 0 — если следующего нет */
word m, s;
if (rootdir) return(0);
if (!fat16) {
m=(clust*3)/2;
s=*(word *)(fat+m);
if(clust%2) /* нечетный элемент */
s>>=4;
else /* четный элемент */
s=s&0x0fff;
if (s>0x0fef) return(0);
else return(s);
}
else {
m=clust*2;
s=*(word *)(fat+m);
if (s>0xffef) return(0);
else return(s);
}
}
/*------------------------------------------------*/
/* Выделение следующего элемента из строки-задания */
char *Get_Name(char *s, char *d) {
/* s — строка задания, d — выделенный элемент, возвращает указатель на новое начало строки задания. */
char *p,*r;
int i;
for(i=0;i<11;d[i++]=' ');
d[11]='\0';
if ((p=strchr(s,'\\'))==NULL) {
/* последний элемент строки — имя файла */
/* перезапись имени */
for(r=s,i=0; (i<8)&&*r&&(*r!='.'); i++,r++) *(d+i)=*r;
/* перезапись расширения */
if (*r) for(i=0,r++; (i<3)&&*r; i++,r++) *(d+8+i)=*r;
return(NULL);
}
else {
/* следующий элемент — имя подкаталога */
*p='\0';
for(r=s,i=0; (i<11)&&*r; i++,r++) *(d+i)=*r;
return(p+1);
}
}
/*-----------------------------------------------*/
/* Поиск имени в каталоге */
int Find_Name() {
int j;
/* cname — найденное имя; возвращает индекс найденного
элемента в массиве dir или (-1) */
for (j=0; j<boot->SectSize/sizeof(struct Dir_Item); j++) {
if (dir[j].fname[0]=='\0') {
/* конец использованных элементов каталога */
printf("%s -",cname);
if (jobptr==NULL) End_of_Job(4);
else End_of_Job(5);
}
if ((byte)dir[j].fname[0]!=0xe5) {
if (memcmp(dir[j].fname,cname,11)==0) {
/* если iм`я збiгатся, то:
- при поиске файла элемент не должен иметь атрибутов "подкаталог" или "метка тома",
- при поиске подкаталога элемент должен иметь атрибут "подкаталог" */
if (jobptr==NULL)
if (!(dir[j].attr&0x18)) return(j);
else
if (dir[j].attr&0x10) return(j);
}
}
}
return(-1);
}
/*-----------------------------------------------*/
/* Завершение (при n=0-5 — аварийное) */
void End_of_Job(int n) {
/* n — номер сообщения */
static char *msg[] = {
"неправильный идентификатор диска",
"логический диск отсутствует",
"ошибка чтения",
"нехватка памяти",
"подкаталог не найден",
"файл не найден",
"непредусмотренный конец файла",
"" };
/* освобождение памяти */
if (fatalloc) free(fat);
/* выдача сообщения */
textattr(12+128);
cprintf(" %s\n",msg[n]);
gotoxy(28,wherey());
cprintf(" Нажмите любую клавишу...\n");
textattr(7);
getch();
/* завершение программы */
exit(0);
}
Date: 2015-05-22; view: 539; Нарушение авторских прав Понравилась страница? Лайкни для друзей: |
|
|