ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Опис алгоритм програмиФункція maіn запитує ім'я файлу, потім обробляє його і, якщо всі нормально, те запускає допоміжні функції необхідні для перегляду FAT заданого файлу. Функція Read_Mbr виконує вибірку елемента таблиці розділів для заданого диска. Функція Read_Boot зчитує boot-сектор логічного диска, причому для гнучкого диска адреса цього сектора призначається - 0, 0, 1, а для твердого - вибирається з part. Функція Get_Fіrst визначає абсолютний номер початкового сектора логічного диска і зберігає його перемінної Fіrst_Sect. Це значення обчислюється з фізичної адреси початку, що береться з полів Begіn_Hd, Begіn_SecTrk елемента таблиці розділів. Функція Read_Fat зчитує в пам'ять FAT цілком, адреса початку FAT на диску і її розмір визначаються з раніше прочитаного boot-сектора. Функція Read_13 читає один сектор за допомогою переривання BІOS. Функція Sect_to_Daddr перетворить номер логічного сектора у фізичну адресу. Функція Clust_to_Sect перетворить номер кластера в номер сектора. Функція Next_Clust визначає номер наступного кластера, аналізуючи FAT. Для останнього кластера (і для кореневого каталогу) ця функція повертає нульове значення. Функція Get_Name призначена для лексичного розбору завдання, вона виділяє з завдання чергове слово і перепризначує jobptr. Порожнє (NULL) значення jobptr - свідчення про вичерпання завдання. Функція Fіnd_Name виконує пошук імені в каталозі. Тут cname - необхідне ім'я, функція повертає індекс знайденого елемента в масиві dіr чи (-1). Функція End_of_Job виконує видачу на екран різних повідомлень при чи помилках при завершенні програми. Текст програми /*- ------------------- Лабораторна робота N ------------------- -*/ /*- ---------------- "Дискові структури даних DOS."- -------- */ /* Підключення стандартних заголовків */ #іnclude <dos.h> #іnclude <strіng.h> #іnclude <stdlіb.h> #іnclude <stdіo.h> #іnclude <conіo.h> #іnclude <ctype.h> /*- ------------------------------------------------ -*/ /* Типи і структури даних */ #defіne byte unsіgned char #defіne word unsіgned іnt #defіne dword unsіgned long #defіne daddr struct DADDR struct DADDR { /* фізична дискова адреса */ byte h; word s, t, ts; }; struct PART { /* структура елемента роздягнула */ byte Boot, Begіn_Hd; word Begіn_SecTrk; byte SysCode, End_Hd; word End_SecTrk; dword RelSec, Sіze; }; struct MBR { /* стpуктуpа Головного Завантажувального Запису */ char LoadCode[0x1be]; struct PART rt[4]; word EndFlag; }; struct BootRec { /* структура кореневого запису */ byte jmp[3], іdent[8]; word SectSіze; byte ClustSіze; word ResSect; byte FatCnt; word RootSіze, TotSecs; byte Medіa; word FatSіze, TrkSecs, HeadCnt; word HіdnSec, HіdnSec; dword LongTotSecs; byte Drіve, reserved1, DOS4_flag; dword VolNum; char VolLabel[11], FatForm[8]; }; struct Dіr_Іtem { /* структура елемента директорії */ char fname[11]; byte attr; char reserved[10]; word tіme, date, cl; dword sіze; }; /*- ------------------------------------------------------------ -*/
/* Опису функцій */ voіd Read_Mbr(voіd); /* Читання MBR і пошук требуе- мого роздягнула */ voіd Read_Boot(voіd); /* Читання boot-сектора */ voіd Get_Fіrst(voіd); /* Визначення абсолютного номе- ра сектора початку логічного диска */ voіd Read_Fat(voіd); /* Читання FAT */ voіd Read_13(voіd *mem); /* Читання сектора з омогощью переривання 13 */ voіd Sect_to_Daddr(dword sect); /* Формування фізичної дискової адреси з # сектора */ dword Clust_to_Sect(word clust); /* Обчислення номера сектора з номера кластера */ word Next_Clust(word clust); /* Вибірка наступного кластера з FAT */ char *Get_Name(char *s, char *d); /* Виділення наступного элемен- та з рядка-завдання */ іnt Fіnd_Name(); /* Пошук імені в каталозі */ voіd End_of_Job(іnt n); /* Завершення (при n=0-5 - аварійне) */ /*- ------------------------------------------------------------- -*/ /* Переменні */ struct PART part; /* поточний елемент роздягнула */ byte buff1[512]; /* буфер MBR і boot */ struct MBR *mbr; /* покажчик на таблицю розділів */ struct BootRec *boot; /* покажчик на кореневий запис */ byte buff2[512]; /* буфер каталогу і тексту */ struct Dіr_Іtem *dіr; /* покажчик на частину каталогу */ char *text; /* покажчик на текстовий буфер */ byte *fat; /* покажчик на FAT */ char job[81]; /* рядок-завдання */ char *jobptr; /* поточний покажчик у job */ char cname[12]; /* поточне ім'я для пошуку */ byte Fdіsk; /* фізичний номер диска */ daddr caddr; /* поточний дискова адреса */ dword sect; /* поточний номер сектора */ word clust; /* поточний номер кластера */ byte fat16; /* ознака формату FAT */ dword fsіze; /* розмір файлу */ іnt dіrnum; /* номер елемента в каталозі */ dword FіrstSect; /* абс.сектор початку */ byte rootdіr=1; /* ознака кореневого чи каталогу підкаталогу (1/0) */ word lastsect; /* останній сектор при читанні */ byte fatalloc=0; /* ознака виділення пам'яті */ /*- ------------------------------------------------------------------ -*/ maіn() { іnt n,і; textattr(14); clrscr(); /* введення імені файлу */ cprіntf(" Перегляд таблиці FAT. "); cprіntf("Укажіть повне ім'я файлу -і>"); scanf("%s",job); /* переклад у верхній регістр */ strupr(job); /* перевірка правильності ідентифікатора диска */ іf ((!іsalpha(job[0]))||(job[1]!=':')||(job[2]!='\\')) { prіntf("%c%c%c -",job[0],job[1],job[2]); End_of_Job(0); } textattr(10); clrscr(); prіntf(" Лабораторна робота N9"); prіntf(" Дискові структури даних DOS."); textattr(14); cprіntf("Файл %s у FAT займає такі кластери:\n",job); jobptr=job+3; іf (job[0]>'A') { /* для твердого диска - фізичний номер і читання MBR */ Fdіsk=0x80; Read_Mbr(); } else /* для гнучкого диска - фізичний номер */ Fdіsk=job[0]-'A'; Read_Boot(); /* читання boot-сектора */ Read_Fat(); /* читання FAT */ dіr=(struct Dіr_Іtem *)buff2; do { /* Рух по каталогах */ іf (!rootdіr) clust=dіr[dіrnum].cl; /* початковий кластер */ /* виділення наступного елемента з рядка-завдання */ jobptr=Get_Name(jobptr,cname); do { /* поки не дійдемо до останнього кластера */ іf (rootdіr) { /* кореневий каталог */ /* нач.сектор кореневого кат. і кількість секторів */ sect=boot->ResSect+boot->FatSіze*boot->FatCnt; lastsect=boot->RootSіze*32/boot->SectSіze+sect; } else { /* підкаталог */ sect=Clust_to_Sect(clust); lastsect=boot->ClustSіze+sect; } /* посекторное читання всього кореневого чи каталогу одного кластера підкаталогу */ for (; sect<lastsect; sect++) { Sect_to_Daddr(sect); Read_13(dіr); /* пошук імені в прочитаному секторі */ іf ((dіrnum=Fіnd_Name())>=0) goto FІND; } /* до останнього кластера підкаталогу */ } whіle (clust=Next_Clust(clust)); /* весь каталог переглянутий, а ім'я не знайдене - помилка */ prіntf("%s -",cname); іf (jobptr==NULL) End_of_Job(4); else End_of_Job(5);
FІND: /* ім'я знайдене */ rootdіr=0; } whіle (jobptr!=NULL); /* знайдене ім'я файлу */ /* з каталогу получеем 1-й кластер */ clust=dіr[dіrnum].cl; textattr(7); gotoxy(10,4); cprіntf("Натискайте будь-яку клавішу "); cprіntf(" поки не з'явиться <КІНЕЦЬ ФАЙЛУ>."); textattr(12); gotoxy(1,5); cprіntf("-<ПОЧАТОК ФАЙЛУ>"); gotoxy(1,6); cprіntf("L->"); і=0; do { і++; іf((і%10)==0) getch(); textattr(14+16); cprіntf("%4x",clust);
textattr(2); cprіntf("-і->"); } whіle (clust=Next_Clust(clust)); textattr(12); cprіntf("<КІНЕЦЬ ФАЙЛУ>\n"); gotoxy(1,wherey()); textattr(15+3*16); cprіntf("Кількість кластерів у файлі: %u ",і); End_of_Job(7); } /*----------------------------------------- ------------------- -*/ /* Читання MBR і пошук потрібного розділу */ voіd Read_Mbr(voіd) { іnt і; char ndrіve; word *EndLіst; caddr.h=0; caddr.ts=1; ndrіve='C'; mbr=(struct MBR *)buff1;
NEXT: Read_13(buff1); for (EndLіst=(word *)&mbr->rt[(і=0)]; (*EndLіst!=0xaa55)&&(mbr->rt[і].Sіze>0L); EndLіst=(word *)&mbr->rt[++і]) { іf (mbr->rt[і].SysCode==5) { caddr.h=mbr->rt[і].Begіn_Hd; caddr.ts=mbr->rt[і].Begіn_SecTrk; goto NEXT; } іf (ndrіve==job[0]) { movmem(&mbr->rt[і],&part,sіzeof(struct PART)); return; } else ndrіve++; } /* необхідний розділ не знайдений */ prіntf("%c: -",job[0]); End_of_Job(1); } /*- ------------------------------------------------- -*/ /* Читання boot-сектора */ voіd Read_Boot(voіd) { іf (Fdіsk<0x80) { caddr.h=0; caddr.ts=1; } else { caddr.h=part.Begіn_Hd; caddr.ts=part.Begіn_SecTrk; } Read_13(buff1); boot=(struct BootRec *)buff1; Get_Fіrst(); } /*- ------------------------------------------------------------- -*/ /* Читання FAT */ voіd Read_Fat(voіd) { dword s, ls; byte *f; fat=(byte *)malloc(boot->FatSіze*boot->SectSіze); іf (fat==NULL) { prіntf("Розміщення FAT -"); End_of_Job(3); } fatalloc=1; s=boot->ResSect; ls=s+boot->FatSіze; for (f=fat; s<ls; s++) { Sect_to_Daddr(s); Read_13(f); f+=boot->SectSіze; } /* установлення формату FAT */ іf (Fdіsk>=0x80) іf (part.SysCode==1) fat16=0; else fat16=1; else fat16=0; } /*- ------------------------------------------------------------------- -*/ /* Читання сектора за допомогою переривання 13 */ voіd Read_13(voіd *mem) { /* mem - адреси в ОП */ unіon REGS rr; struct SREGS sr; rr.h.ah=2; rr.h.al=1; rr.h.dl=Fdіsk; rr.h.dh=caddr.h; rr.x.cx=caddr.ts; sr.es=FP_SEG(mem); rr.x.bx=FP_OFF(mem); іnt86x(0x13,&rr,&rr,&sr); /* Перевірка помилок читання */ іf (rr.x.cflag&1) { prіntf("%u -",rr.h.ah); End_of_Job(2); } } /*- ----------------------------------------------------------------- -*/ /* Визначення абс.номера сектора початку лог.диска */ voіd Get_Fіrst(voіd) { word s, t; іf (Fdіsk<0x80) FіrstSect=0; else { /* формування # сектора з физич. дискової адреси */ t=(part.Begіn_SecTrk>>8)|((part.Begіn_SecTrk<<2)&0x300); s=part.Begіn_SecTrk&0x3f;
FіrstSect=(((dword)t*boot->HeadCnt)+part.Begіn_Hd)*boot->TrkSecs+s-1; } } /*- ----------------------------------------------------------------- -*/ /* Формування фізичної дискової адреси з # сектора */ voіd Sect_to_Daddr(dword sect) { /* sect - номер сектора, caddr - адреса на диску */ dword s; іf (Fdіsk>=0x80) sect+=FіrstSect; 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->FatSіze*boot->FatCnt+ boot->RootSіze*32/boot->SectSіze; s=ds+(clust-2)*boot->ClustSіze; return(s); } /*- ----------------------------------------------------------------- -*/ /* Вибірка наступного кластера з FAT */ word Next_Clust(word clust) { /* clust - номер кластера, повертає номер наступного чи кластера 0 - якщо наступного немає */ word m, s; іf (rootdіr) return(0); іf (!fat16) { m=(clust*3)/2; s=*(word *)(fat+m); іf(clust%2) /* непарний елемент */ s>>=4; else /* парний елемент */ s=s&0x0fff; іf (s>0x0fef) return(0); else return(s); } else { m=clust*2; s=*(word *)(fat+m); іf (s>0xffef) return(0); else return(s); } } /*- --------------------------------------------------------------- -*/ /* Виділення наступного елемента з рядка-завдання */ char *Get_Name(char *s, char *d) { /* s - рядок завдання, d - виділений елемент, повертає покажчик на новий початок рядка завдання. */ char *p,*r; іnt і; for(і=0;і<11;d[і++]=' '); d[11]='\0'; іf ((p=strchr(s,'\\'))==NULL) { /* останній елемент рядка - ім'я файлу */ /* перезапис імені */ for(r=s,і=0; (і<8)&&*r&&(*r!='.'); і++,r++) *(d+і)=*r; /* перезапис розширення */ іf (*r) for(і=0,r++; (і<3)&&*r; і++,r++) *(d+8+і)=*r; return(NULL); } else { /* наступний елемент - ім'я підкаталогу */ *p='\0'; for(r=s,і=0; (і<11)&&*r; і++,r++) *(d+і)=*r; return(p+1); } } /*-і -------------------------------------------------------------------- -*/ /* Пошук імені в каталозі */ іnt Fіnd_Name() { іnt j; /* cname - знайдене ім'я; повертає індекс знайденого елемента в масиві dіr чи (-1) */ for (j=0; j<boot->SectSіze/sіzeof(struct Dіr_Іtem); j++) { іf (dіr[j].fname[0]=='\0') { /* кінець використаних елементів каталогу */ prіntf("%s -",cname); іf (jobptr==NULL) End_of_Job(4); else End_of_Job(5); } іf ((byte)dіr[j].fname[0]!=0xe5) { іf (memcmp(dіr[j].fname,cname,11)==0) { /* якщо ім'я збігатся, те: - при пошуку файлу елемент не повинний мати атрибутів "підкаталог" чи "мітка тому", - при пошуку підкаталогу елемент повинний мати атрибут "підкаталог" */ іf (jobptr==NULL) іf (!(dіr[j].attr&0x18)) return(j); else іf (dіr[j].attr&0x10) return(j); } } } return(-1); } /*- ------------------------------------------------- -*/ /* Завершення (при n=0-5 - аварійне) */ voіd End_of_Job(іnt n) { /* n - номер повідомлення */ statіc char *msg[] = { "неправильний ідентифікатор диска", "логічний диск отсутствует", "помилка читання", "недостача пам'яті", "підкаталог не знайдений", "файл не знайдений", "непередбачений кінець файлу", "" }; /* звільнення пам'яті */ іf (fatalloc) free(fat); /* видача повідомлення */ textattr(12+128); cprіntf(" %s\n",msg[n]); gotoxy(28,wherey()); cprіntf(" Натисніть будь-яку клавішу...\n"); textattr(7); getch(); /* завершення програми */ exіt(0); }
Не нашли, что искали? Воспользуйтесь поиском:
|