Приветы,люди! Поможите кто шарит плиз. Вообщем, дали задание написать прогу на Паскале, что бы выводила таблицу ФАТ винта - ничего ненашел в инете- собственно понятно что дело в ассемблерной вставке - но увы асм - вообще гол...подскажите кто знает. Заранее благодарю
Dark
23.01.2006 7:07
поищи по интернет запрос FAT таблица найди ее структуру - напиши обработчик Будут вопросы - приходи Я НАХОДИЛ
Altair
24.01.2006 6:15
Дарк, посыл человека в гугл не есть хорошо! Yurik, у нас на форуме я выкладывал уже кое какую информацию о FAT. вот здесь
Сразу реши, программа будет на ассемблере или на паскале со вставками асма ? Если второе то вот посотри сюда Там автор приводит пример программы выводящей карту диска и какую-то информацию еще.
Dark
24.01.2006 14:40
Ну =) если бы Yrik пришел с тем что "я пробовал но вот у меня не получилось" - я б помог НО если человек говорит что ему нужен вывод FAT - не могу поверить что он ударил пальцем о палец... Думаю многие модеры согласяться со мной... И еще - нечетко поставлена задача у него нет просьбы чтоб я нашел либо выложил что нибудь... Гхм (пипипи) че то я с бессонницы философствую...
MixRin.RU$
24.01.2006 21:41
Цитата(Dark @ 24.01.2006 10:40)
Ну =) если бы Yrik пришел с тем что "я пробовал но вот у меня не получилось" - я б помог НО если человек говорит что ему нужен вывод FAT - не могу поверить что он ударил пальцем о палец... Думаю многие модеры согласяться со мной... И еще - нечетко поставлена задача у него нет просьбы чтоб я нашел либо выложил что нибудь... Гхм (пипипи) че то я с бессонницы философствую...
не все умеют грамотно составлять запросы поисковикам и тем более вылавливать нужные ссылки среди всякого 'гумна'.
Dark
25.01.2006 18:46
чес слово - шел шел по инету - и случайно нашел. FAT дискеты =)
; Чтение сектора (DX=номер сектора) ########################################## ; ES:DI - куда читать PROC ReadSect push di es ; Начало расчета сектора/дорожки/головки push cs pop ds mov cx,18 mov si,dx ; tmp=(Sect/Sectors); mov ax,si xor dx,dx div cx mov di,ax ; Sec=Sect-(tmp*Sectors)+1; mov ax,di imul cx mov dx,si sub dx,ax inc dx mov [AbsSectNum],dx ; Hea=tmp & 1; mov ax,di and ax,1 mov [AbsHeadNum],ax ; Trk=(Sect-(Hea*Sectors)-(Sec-1))/(Sectors*2); imul cx push ax mov ax,si pop dx sub ax,dx mov dx,[AbsSectNum] dec dx sub ax,dx mov dx,cx shl dx,1 push ax push dx xor dx,dx pop bx pop ax div bx ; AX = AbsTrackNum ; Конец расчетов mov cx,ax mov al,cl shr cx,2 and cl,0C0h mov ch,al and cx,0FFC0h mov ax,[AbsSectNum] ; г5T4T3T2T1T0T9T8T7T6T5T4T3T2T1T0¬ or cl,al ; CX = c c c c c c c c C c S s s s s s pop es bx ; ES:BX = Куда считывать mov dx,[AbsHeadNum] mov dh,dl ; Номер головки mov dl,0 ; Номер диска 0 = A mov al,1 ; Количество считываемых секторов mov ah,2 ; Номер функции int 13h ret ENDP ReadSect ; Чтение сектора в стандартный буффер ######################################## RSSData DW 0 PROC CachedReadSector cmp dx,[cs:RSSData] je RSSEnd mov [cs:RSSData],dx push di si es ax bx cx dx lea di,[sector] push cs pop es call ReadSect pop dx cx bx ax es si di RSSEnd: ret ENDP CachedReadSector ; Чтение FAT'а ############################################################### PROC ReadFAT push cs pop es mov dx,1 lea di,[FAT] readfat1: push es dx di
Call ReadSect pop di dx es add di,512 inc dx cmp dx,10 jne readfat1 ret ENDP ReadFAT ; Выдает следующий сектор после DX (через FAT) ############################### gns_flag DW 0 PROC GetNextSector cmp dx,2 je gns03 cmp [Word Ptr cs:gns_flag],0 jne gns04 push cx di bx lea di,[FAT] mov ax,dx mov bx,ax mov cx,3 mul cx shr ax,1 add di,ax mov dx,[di] and bx,1 je gns01 ; Если номер кластера четный shr dx,4 jmp gns02 gns01: and dx,0FFFh gns02: pop bx di cx ret gns03: mov dx,[RootSect] ret gns04: mov [Word Ptr cs:gns_flag],0 add dx,33-2 ret ENDP GetNextSector ; Конвертит номер сектора в номер кластера ################################### Sect2ClustRoot DW 0 PROC Sect2Clust cmp dx,33 jb Sect2Clust1 sub dx,33-2 mov [Word Ptr cs:Sect2ClustRoot],0 ret Sect2Clust1: mov [Word Ptr cs:Sect2ClustRoot],1 ret ENDP Sect2Clust ; По строке (обычно командной) выдает номер сектора (DS:DI = строка ) ######## ; Возвращает AX = номер превого сектора каталога GetSectorName DB 13 DUP (0),0 GetSectorClust DW 0 Prohod DW 0 PROC GetSectorNum call UpperString ; [DI] = D:\CAT1\CAT2\ mov al,[di] ; AL = Диск 'A'-'Z' sub al,'A' ; AL = Диск 0 - 32 xor ax,ax mov [Word Ptr cs:GetSectorClust],2 mov [Word Ptr cs:gns_flag],1 mov [cs:Prohod],ax add di,3 ; [DI] = CAT1\CAT2\
nextsubdir: mov si,di gsn003: mov al,[si] or al,al je gsn001 cmp al,'\' je gsn001 inc si jmp gsn003 gsn001: cmp di,si ; [DI] = CAT1\CAT2 je gsn002 ; [SI] = \CAT2 xor cx,cx mov bx,si push si lea si,[GetSectorName] gsn005: mov al,[di] cmp al,'.' ; Если есть расширение je gsn004 mov [cs:si],al inc di inc si inc cx cmp di,bx jne gsn005 pop di ; Добьем имя нулями gsn006: mov [Byte Ptr cs:si],20h inc cx inc si cmp cx,11 jne gsn006 jmp gsn007 gsn002: mov ax,[cs:Prohod] or ax,ax jne gsn0021 mov ax,[Root] ; Корень jmp gsn0022 gsn0021: mov ax,[GetSectorClust] gsn0022: ret gsn004: cmp cx,8 je gsn008 mov [Byte Ptr cs:si],20h inc cx inc si jmp gsn004 gsn008: inc di inc cx cmp cx,12 je gsn010 mov al,[di] or al,al je gsn009 mov [cs:si],al inc si jmp gsn008 gsn009: pop di jmp gsn006 gsn010: pop dx gsn007: push di
; Ищем в корне запрошеный каталог (CAT1) mov dx,[GetSectorClust] lea di,[sector] gsn13: call GetNextSector cmp dx,0FFFh je gsn14 push dx call CachedReadSector mov [Word Ptr cs:gns_flag],0 lea di,[sector] lea si,[GetSectorName] mov cx,16 ; 16 - количество записей в одном секторе gsn12: push di si cx call CmpStrings pop cx si di jc gsn11 notdir: add di,32 dec cx jne gsn12 pop dx jmp gsn13 gsn14: pop di ; Не найдено не фига xor ax,ax ret gsn11: ; Найдена запись - сравним аттрибуты mov al,[di+11] and al,10h je notdir ; Это не каталог mov ax,[di+01Ah] mov [GetSectorClust],ax pop dx di inc di mov [Word cs:Prohod],1 mov [Word Ptr cs:gns_flag],1 jmp nextsubdir ENDP GetSectorNum ; FindFirst ################################################################## ; Возвращает: AX=0=Ok; AX=1=Patch not found PROC FindFirst ; Читаем FAT push cs pop ds ; Узнаем номер сектора, где начинается корень lea di,[dos_CurDir] call GetSectorNum ; В AX - номер кластера с каталогом or ax,ax je ff03 mov dx,ax mov [Word Ptr cs:gns_flag],1 push cs pop es call GetNextSector ff02: push dx call CachedReadSector pop dx ; Копируем первую запись в каталоге в структуру _dos lea si,[sector] mov cx,16 ff01: mov al,[si] or al,al ; 0 - пустая запись каталога je nofile cmp al,'х' ; 'x' - удаленая запись je nofile mov ax,[si+11] cmp ax,0Fh ; Если это LFN je nofile lea di,[dos_FileName] mov bx,cx mov cx,32 rep movsb jmp ff_makefind nofile: add si,32 dec cx or cx,cx jne ff01 cmp dx,32 jna nofile1 call GetNextSector jmp ff02 nofile1: inc dx jmp ff02 ff_makefind: ; Копируем содержимое структуры dos_ в структуру _find lea si,[dos_FileName] lea di,[find_FileName] mov cx,32 rep movsb mov ax,16 sub ax,bx mov [di],dx mov [di+2],ax xor ax,ax ret ff03: mov ax,1 ret ENDP FindFirst ; Ищет следующий файл в каталоге ############################################# ; Возвращает: AX=0=Ok; AX=1=Patch not found PROC FindNext lea si,[find_FileName] mov dx,[si+32] ; DX - номер сектора mov ax,[si+34] fnNextSector0: cmp ax,15 ; Надо читать следующий je fnNextSector1 mov [Word Ptr cs:gns_flag],1 fnNextSector: push cs pop es push ax call Sect2Clust ; DX - номер кластера cmp [Word Ptr cs:Sect2ClustRoot],0 jne fnNextSector5 ; Если корень call GetNextSector cmp dx,0FFFh je fnNextSector2 fnNextSector4: push dx call CachedReadSector pop dx ax ; Нужный сектор считан inc ax ; AX - номер записи (0..15) push ax shl ax,5 ; AX=AX*5 lea si,[sector] add si,ax
; Проверим на пустую запись, удаление и LFN mov bl,[si] or bl,bl ; 0 - пустая запись каталога je fn_nofile cmp bl,'х' ; 'x' - удаленая запись je fn_nofile mov bx,[si+11] cmp bx,0Fh ; Если это LFN je fn_nofile
lea di,[dos_FileName] mov cx,32 rep movsb pop ax lea si,[dos_FileName] lea di,[find_FileName] mov cx,32 rep movsb mov [di],dx mov [di+2],ax xor ax,ax ret fn_nofile: pop ax jmp fnNextSector0 fnNextSector2: pop ax mov ax,1 ret fnNextSector1: xor ax,ax dec ax jmp fnNextSector fnNextSector5: cmp [Word Ptr cs:gns_flag],1 je fnNextSector51 inc dx cmp dx,33 je fnNextSector2 fnNextSector51: mov [Word Ptr cs:gns_flag],0 jmp fnNextSector4 ENDP FindNext
P.S. работоспособность не поверял P.S.S. Интересно - а автору темы это надо еще?
Yurik
25.01.2006 21:35
Привет! Сорри, что не отвечал - не работал инет. Спасибо всем кто откликнулся - пальцем об палец бью уже который день - но увы...кстати у меня тоже есть пример программы считки ФАТа дискеты, но! - программа просто находит где ни диискете БУТ, где ФАТ - просто откликаеться на номер введенного сектора - мол что это есть дата, бут, фат... поменял я в этой проге регистр, где указываеться номер диска по счету начиная с А -тобишь А, Б, Ц,Д - то есть мне нужен Ц - 2 получаецца - запускаю - нифига - прога нагло вылетает и ИксПи пишет, что было обращение к винту и все такое...короче то ли Икс Пи не разрешает, то ли я че то нахимичил... ДА! Кстати совсем забыл - задание у меня было : РАСШИФРОВАТЬ ФАТ! - больше ничего не написано А разве он зашифрован? Разве есть алгоритм шифрования? Разве нужен ключ... .Вообщем беда еще и в том что уточнить задание не имею возможности - так как учусь на заочном - кто учился, тот поймет...Вылаживаю код программа, о которой говорил выше -
Program Inf_Boot; Uses Crt, Dos; Type TBoot = Record JMPxx : Array [1..3] Of Byte; OEMname : Array [1..8] Of Char; SectSiz : Word; ClustSiz : Byte; ResSecs : Word; FatCnt : Byte; RootSiz, TotSecs : Word; Media : Byte; FatSize, TrkSecs, HeadCnt : Word; HidnSec, BigSectNumb : LongInt; DevNum, res1, Sygnatura : Byte; DiskSerialNum : LongInt; DiskVolume : Array [1..11] Of Char; FileSystemID : Array [1..8] Of Char; res2 : Array [1..512 - 62] Of Byte; End;
Var nBoot,nFAT,nRoot,nData,nMAX,Num : Word; Boot : TBoot;
Procedure ReadBoot(Disk : Byte); Var SegRec,OfsRec,Error : Word; Begin SegRec := Seg(Boot); OfsRec := Ofs(Boot); Asm mov AL,Disk mov CX,1 mov DX,0 mov DS,SegRec mov BX,OfsRec int 25h pop DX mov Error,AX
End; End;
Begin Write('Enter a number of floppy disk (a=0,b=1): '); ReadLn(Num); ReadBoot(Num); nBoot := 0; With Boot Do Begin nFAT := nBoot + ResSecs; nRoot := nFAT + FatSize * FatCnt;
nData := nRoot + (RootSiz * 32) Div SectSiz; nMAX := TotSecs; End; Repeat Write('Enter a number of sector: '); ReadLn(Num); If Num In [nBoot..nFAT - 1] Then WriteLn('Boot') Else If Num In [nFAT..nRoot - 1] Then WriteLn('FAT') Else If Num In [nRoot..nData - 1] Then WriteLn('Root') Else If Num In [nData..nMAX - 1] Then WriteLn('Data') Else WriteLn('Error');
Юрик, я думаю что WinXP просто блокирует обращение к винту, есть такое смутное сомнение, так что попробуй проверить на эмуляторе или чистом ДОС, стандартный виндовый эмуль (ntvdm) фигня имхо... По поводу 'расшифровать FAT' я думаю что надо просто сделать красивый вывод этой таблицы, то есть например:
PS я сам не знаю формат этой таблицы, поэтому прошу за совет не ругать
Yurik
27.01.2006 20:03
Короче манался я манался с этой прогой - много прошло через меня аналогичных, но! - не одна не захотела работать с ФАТ32. С дискетой-пожалуйста! с винтом - рантайм эррор с адресом того самого эррора! - забил и решал делать для ФАТ16 хоть... - !!! хотя вприципе и не было прог, которые бы тупо вылили раздел ФАТ - в виде даже билеберды на экран иль в файл - не суть важно. - Пробывал писать проги как написано в примерах в НГ и в Тече 6.0 , но при обработке формул то "деление на 0" выдает то еще что то...эх! нутром чую что проги не сложные, но чего то не хотять работать-еще не понятно в них смыл использовани сегмент:смещение - вроде как уже плоская модель используеться - возможно это служит в виде буфера результата обработки прерывания - туды вылазит ФАТ? ....фух....
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.