Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Текст программы. /*-------Лабораторная работа 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: 494; Нарушение авторских прав |