Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Описание алгоритм программы




Функция main запрашивает имя файла, потом обрабатывает его и, если все нормально, то запускает вспомогательные функции необходимые для просмотра FAT заданного файла.

Функция Read_Mbr выполняет выборку элемента таблицы разделов для заданного диска.

Функция Read_Boot считывает boot-сектор логического диска, причем для гибкого диска адрес этого сектора назначается — 0, 0, 1, а для жесткого — выбирается из part.

Функция Get_First определяет абсолютный номер начального сектора логического диска и сохраняет его переменной First_Sect. Это значение вычисляется из физического адреса начала, который берется из полей Begin_Hd, Begin_SecTrk элемента таблицы разделов.

Функция Read_Fat считывает в память FAT целиком, адрес начала FAT на диске и ее размер определяются из ранее прочитанного boot-сектора.

Функция Read_13читает один сектор с помощью прерывания BIOS.

Функция Sect_to_Daddrпреобразует номер логического сектора в физический адрес.

Функция Clust_to_Sect преобразует номер кластера в номер сектора.

Функция Next_Clust определяет номер следующего кластера, анализируя FAT. Для последнего кластера (и для корневого каталога) эта функция возвращает нулевое значение.

Функция Get_Name предназначена для лексического разбора задания, она выделяет из задания очередное слово и переназначает jobptr. Пустое (NULL) значение jobptr — свидетельство об исчерпании задания.

Функция Find_Nameвыполняет поиск имени в каталоге. Здесь cname — требуемое имя, функция возвращает индекс найденного элемента в массиве dir или (-1).

Функция End_of_Job выполняет выдачу на экран различных сообщений при ошибках или при завершении программы.

 

 

Текст программы

/*-------Практическая работа 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);

}

 

 










Последнее изменение этой страницы: 2018-05-10; просмотров: 196.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...