Адрес файла в фат32

Тема в разделе "WASM.BEGINNERS", создана пользователем shershen, 17 май 2010.

  1. shershen

    shershen New Member

    Публикаций:
    0
    Регистрация:
    12 май 2010
    Сообщения:
    6
    Есть фат32, также мы имеем "Номер начального кластера файла в таблице расположения файлов (16 бит)", подскажите плз, как по этим двум байтам найти начало содержимого файла? Что это вообще за номер/адрес? Как-то не нашел подробной инфы в инете.
     
  2. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Вот тебе подробности инфы - изучай.
    http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/fatgen103.doc
     
  3. shershen

    shershen New Member

    Публикаций:
    0
    Регистрация:
    12 май 2010
    Сообщения:
    6
    Спасибо за ссылки. Видел, инфы не нашел/не понял. Объясните кто-нибудь плз в двух словах, куда ведут эти два байта адреса.
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну во-первых, не 16бит, а 32 - она же фат32 - это и есть разрядность номера кластера. (на самом деле верхние 8бит в фат32 зарезервированы и используются нижние 24).
    Чтобы найти цепочку размещения файла, нужно иметь адрес таблицы размещения (рассчитывается из заголовка) и номер начального кластера.
    Таблица размещения - массив всех кластеров на диске, каждая запись массива 32 бита (в фат16 - 16бит, в фат12 - 12бит соответственно). Содержит номер следующего кластера или специальные отрицательные значения (конец-цепочки, плохой-кластер, зарезервирован и тп).
    Алгоритм:
    Код (Text):
    1. ULONG i = 0;
    2. for (ULONG Cluster = FatEntry->FirstCluster; Cluster != FAT32_END_OF_CHAIN; Cluster = Fat32NextCluster (Cluster), i++)
    3.     printf("cluster chain entry #0x%08x = 0x%08x\n", i, Cluster);
    выведет список всех кластеров, занятых файлом.
    Дальше просто подряд читаешь эти кластеры и получаешь линейное содержимое файла.

    Вроде я доступно отписал, если будут вопросы, покажу свой простой драйвер fat12/16/32.
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Находим абсолютный номер сектора начала блока данных файловой системы, вычитаем из номера кластера два, умножаем на размер кластера, полученное значение прибавляем к началу блока данных файловой системы. Если ничего не перепутал, т.к. не помню точно... Как получить абсолютный номер сектора начала блока данных можно прочитать в документации, представленной cppasm.
     
  6. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Пока писал, Great ответил.

    Great
    Верхние не восемь, а четыре бита. FAT32 фактически FAT28.
     
  7. shershen

    shershen New Member

    Публикаций:
    0
    Регистрация:
    12 май 2010
    Сообщения:
    6
    Это как в школе/институте, когда препод спрашивает: "Вопросы есть?", а ты сидишь и молчишь, т.к. тебе не понятно нифига и хз что спрашивать :)

    Попробую объяснить подробней.
    У меня на диске есть файл. Я знаю его имя, значит могу найти всю информацию о нем. Вот что пишет интернет:

    - Имя (в формате 8.3).
    - Байт атрибутов (8 бит полезной информации, которая подробно описана ниже).
    - Время создания (24 бит).
    - Дата создания (16 бит).
    - Дата последнего доступа (16 бит).
    - Время последней модификации (16 бит).
    - Дата последней модификации (16 бит).
    - Номер начального кластера файла в таблице расположения файлов (16 бит).
    - Размер файла (32 бита).

    Зная эти 16 бит номера начального кластера я могу прочитать содержимое файла, так? Задача облегчается тем, что размер файла заведомо меньше размера кластера, и никаких цепочек искать не нужно. Вот как тут мне быть? Изучать устройство файловых систем ради разовой задачки совсем не хочется...
     
  8. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Там изучать с гулькин нос. На крайний случай можно взять загрузчик файловой системы FAT32 (выдирается из первых двух секторов файловой системы) и изучить. Он как раз и делает то, что нужно: находит файл по имени в корневом каталоге (в случае Win это ntldr), загружает его в память и передает управление. На процесс загрузки как раз и стоит обратить внимание.
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Mika0x65
    Ну четыре, я уже плохо помню, если честно) Точно, там самый старший разряд нулевой, значит четыре. Давно разбирался с фатом:)
    Сути это не меняет

    В случае вин - первый один сектор. Но он не интересен, ибо грузит только первый кластер файла.

    shershen
    ну я же подробно описал процесс загрузки всей цепочки кластеров. В чем проблема?
    Или ты не знаешь как кластер загрузить?
    гляди: http://code.google.com/p/gr8os/source/browse/trunk/kernel/builtin/fsfat/fsfat.cpp
    конечно, это драйвер под мою ОС и там не очень понятно что к чему, но архитектура похожа на виндовую.
    Сразу скажу, что нужные тебе функции: FsFatCreateVcb (создает volume control block на базе метаданных ФС, в том числе рассчитывается размер кластера), FsFatGetFatType (возвращает число 12, 16 или 32 - тип FAT), FsFatReadFatEntry (читает номер следующего кластера в таблице размещения), FsFatFileClusterByPos (читает номер i-го кластера из таблицы размещения файла), FsFatSizeOfClusterChain (вычисляет размер цепочки кластеров), FsFatReadCluster (читает содержимое кластера).
    Заголовки лежат там же в fsfat.h
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    В догонку тебе исходники bootfat.asm, честно сп..жженные из windows_2000_source_code.zip
    все тоже самое, что и в виндовом бутсекторе, только ntldr изменено на grldr.bin
    http://code.google.com/p/gr8os/source/browse/trunk/loader/bootfat.asm
    Код (Text):
    1. include 'macro/struct.inc'
    2.  
    3. DISPLAY 'Compiling boot sector start-up code',13,10
    4.  
    5. struct DIR_ENT
    6.     Filename    db 11 dup(?)
    7.     Attribute   db ?
    8.     Reserved    db 10 dup(?)
    9.     Time        dw 2 dup(?)
    10.     StartCluster    dw ?
    11.     FileSize    dd ?
    12. ends
    13.  
    14. ;
    15. ; This is the structure used to pass all shared data between the boot sector
    16. ; and GRLDR.
    17. ;
    18.  
    19. struct SHARED
    20.     ReadClusters        dd  ?       ; function pointer
    21.     ReadSectors     dd  ?       ; function pointer
    22.     SectorBase      dd  ?       ; starting sector
    23. ends
    24.  
    25. SectorSize  equ 512     ; sector size
    26.  
    27. BootSeg equ 07c0h
    28. DirSeg  equ 1000h
    29. NtLdrSeg equ 0800h
    30.  
    31.     ; NOT  'jmp short start'  !!
    32.     jmp near start
    33.  
    34. Version         db  "GR8OS1.0"
    35. BPB:
    36. BytesPerSector      dw  SectorSize  ; Size of a physical sector
    37. SectorsPerCluster   db  8       ; Sectors per allocation unit
    38. ReservedSectors     dw  1       ; Number of reserved sectors
    39. Fats            db  2       ; Number of fats
    40. DirectoryEntries    dw  512     ; Number of directory entries
    41. Sectors         dw  4*17*305-1  ; No. of sectors - no. of hidden sectors
    42. Media           db  0F8H        ; Media byte
    43. FatSectors      dw  8       ; Number of fat sectors
    44. SectorsPerTrack     dw  17      ; Sectors per track
    45. Heads           dw  4       ; Number of surfaces
    46. HiddenSectors       dd  1       ; Number of hidden sectors
    47. SectorsLong     dd  0       ; Number of sectors iff Sectors = 0
    48.  
    49. DriveNumber db  80h     ; Physical drive number (0 or 80h)
    50. CurrentHead db  ?       ; Unitialized
    51.  
    52. Signature   db  41      ; Signature Byte for bootsector
    53. BootID      dd  0xDEADC0DE       ; Boot ID field.
    54. Boot_Vol_Label  db  11 dup (?)
    55. Boot_System_ID  db  'FAT     '  ;"FAT     " or "OTHER_FS"
    56.  
    57. CurrentTrack    equ   BootSectorEnd + 4  ; current track
    58. CurrentSector   equ   BootSectorEnd + 6  ; current sector
    59. SectorCount equ   BootSectorEnd + 7  ; number of sectors to read
    60. ClusterBase equ   BootSectorEnd + 8  ; first sector of cluster # 2
    61. Retries     equ   BootSectorEnd + 10
    62. Arguments   equ   BootSectorEnd + 11 ; structure passed to GRLDR
    63.  
    64.  
    65. start:
    66.     xor ax, ax           ; Setup the stack to a known good spot
    67.     mov ss, ax
    68.     mov sp, 7c00h
    69.  
    70.     push BootSeg
    71.     pop ds
    72.  
    73.     MOV AL, [Fats]     ;Determine sector root directory starts on
    74.     MUL [FatSectors]
    75.     ADD AX, [ReservedSectors]
    76.     PUSH    AX      ; AX = Fats*FatSectors + ReservedSectors + HiddenSectors
    77.     XCHG    CX, AX       ; (CX) = start of DIR
    78. ;
    79. ; Take into account size of directory (only know number of directory entries)
    80. ;
    81.     MOV AX, sizeof.DIR_ENT     ; bytes per directory entry
    82.     MUL [DirectoryEntries]    ; convert to bytes in directory
    83.     MOV BX, [BytesPerSector]       ; add in sector size
    84.     ADD AX, BX
    85.     DEC AX          ; decrement so that we round up
    86.     DIV BX          ; convert to sector number
    87.     ADD CX, AX
    88.     MOV [ClusterBase],CX      ; save it for later
    89.  
    90.     push DirSeg
    91.     pop es
    92.  
    93.     xor bx,bx
    94.     pop word [Arguments + SHARED.SectorBase]
    95.     mov word [Arguments + SHARED.SectorBase+2],bx
    96.  
    97. ;
    98. ; (al) = # of sectors to read
    99. ;
    100.     push    cs
    101.     call    DoRead
    102.     jc  BootErr$he
    103.  
    104.     xor bx,bx
    105.     mov cx, [DirectoryEntries]
    106. L10:
    107.     mov di,bx
    108.     push    cx
    109.     mov cx,11
    110.     mov si, LOADERNAME
    111.     repe    cmpsb
    112.     pop cx
    113.     jz  L10end
    114.  
    115.     add bx,sizeof.DIR_ENT
    116.     loop  L10
    117. L10end:
    118.  
    119.     jcxz    BootErr$bnf
    120.  
    121.     mov dx,[es:bx + DIR_ENT.StartCluster] ; (dx) = starting cluster number
    122.     push    dx
    123.     mov ax,1            ; (al) = sectors to read
    124. ;
    125. ; Now, go read the file
    126. ;
    127.  
    128.     push    NtLdrSeg
    129.     pop es
    130.     xor bx,bx           ; (es:bx) -> start of GRLDR
    131.  
    132. ;
    133. ; (al) = # of sectors to read
    134. ; (es:bx)  ->  destination buffer
    135. ;
    136.  
    137.     push    cs
    138.     call    ClusterRead
    139.     jc  BootErr$he
    140.  
    141. ;
    142. ; GRLDR requires:
    143. ;   BX = Starting Cluster Number of GRLDR
    144. ;   DL = INT 13 drive number we booted from
    145. ;   DS:SI -> the boot media's BPB
    146. ;   DS:DI -> argument structure
    147. ;   1000:0000 - entire FAT is loaded
    148. ;
    149.  
    150.     pop BX          ; (bx) = Starting Cluster Number
    151.     mov si,BPB          ; ds:si -> BPB
    152.     mov di,Arguments        ; ds:di -> Arguments
    153.  
    154.     push    ds
    155.     pop word [di + SHARED.ReadClusters + 2]
    156.     mov word [di + SHARED.ReadClusters], ClusterRead
    157.     push    ds
    158.     pop word [di + SHARED.ReadSectors + 2]
    159.     mov word [di + SHARED.ReadSectors], DoRead
    160.     MOV dl, [DriveNumber]      ; dl = boot drive
    161.  
    162.     ;
    163.     ; Check LDR signature
    164.     ;
    165.  
    166.     ; ES = 0
    167.     push    es
    168.     push    0
    169.     pop es
    170.     mov eax, dword [es:0x8000]
    171.     pop es
    172.  
    173.     and eax, 0xFFFFFF
    174.     cmp eax, 'LDR'
    175.     jnz BootErr$ngs
    176.  
    177.  
    178. ;
    179. ; FAR JMP to 0000:8003.
    180. ;
    181. ;  First three bytes of GRLDR contain signature 'LDR'
    182. ;
    183.  
    184.     db  0EAh            ; JMP FAR PTR
    185.     dw  0x8003          ; 0000:8003
    186.     dw  0
    187.  
    188.  
    189. ;
    190. ; Print boot error
    191. ;
    192.  
    193. BootErr$ngs:
    194.     MOV SI,MSG_BAD_GRLDR
    195.     jmp short BootErr2
    196.  
    197. BootErr$bnf:
    198.     MOV SI,MSG_NO_GRLDR
    199.     jmp short BootErr2
    200.  
    201. BootErr$he:
    202.     MOV SI,MSG_READ_ERROR
    203. BootErr2:
    204.     call    BootErrPrint
    205.     MOV SI,MSG_REBOOT_ERROR
    206.     call    BootErrPrint
    207.     sti
    208.     jmp $           ;Wait forever
    209.  
    210. BootErrPrint:
    211.       LODSB             ; Get next character
    212.       or    al,al
    213.       jz    BEdone
    214.  
    215.       MOV     AH,14           ; Write teletype
    216.       MOV     BX,7            ; Attribute
    217.       INT     10H             ; Print it
    218.       jmp   BootErrPrint
    219. BEdone:
    220.  
    221.     ret
    222.  
    223.  
    224.  
    225. ClusterRead:
    226.     push    ax          ; (TOS) = # of sectors to read
    227.     dec dx
    228.     dec dx          ; adjust for reserved clusters 0 and 1
    229.     mov al, [SectorsPerCluster]
    230.     xor ah,ah
    231.     mul dx          ; DX:AX = starting sector number
    232.     add ax,[ClusterBase]      ; adjust for FATs, root dir, boot sec.
    233.     adc dx,0
    234.     mov word [Arguments + SHARED.SectorBase],ax
    235.     mov word [Arguments + SHARED.SectorBase+2],dx
    236.     pop ax          ; (al) = # of sectors to read
    237.  
    238.  
    239. DoRead:
    240.     mov [SectorCount],AL
    241. DRloop:
    242.     MOV AX, word [Arguments + SHARED.SectorBase]     ; Starting sector
    243.     MOV DX, word [Arguments + SHARED.SectorBase+2]     ; Starting sector
    244.     ADD AX, word [HiddenSectors]    ;adjust for partition's base sector
    245.     ADC DX,word [HiddenSectors+2]
    246.     DIV [SectorsPerTrack]
    247.     INC DL          ; sector numbers are 1-based
    248.     MOV [CurrentSector],DL
    249.     XOR DX,DX
    250.     DIV [Heads]
    251.     MOV [CurrentHead],DL
    252.     MOV [CurrentTrack],AX
    253.     MOV AX,[SectorsPerTrack]
    254.     SUB AL,[CurrentSector]
    255.     INC AX
    256.     cmp   al,[SectorCount]
    257.     jbe   DoCall
    258.     mov   al,[SectorCount]
    259.     xor   ah,ah
    260. DoCall:
    261.     PUSH    AX
    262.     MOV AH,2
    263.     MOV cx,[CurrentTrack]
    264.     SHL ch,6
    265.     OR  ch,[CurrentSector]
    266.     XCHG    CH,CL
    267.     MOV DX,WORD [DriveNumber]
    268.     INT 13H
    269.     jnc DcNoErr
    270.     add sp,2
    271.     stc
    272.     retf
    273. DcNoErr:
    274.     POP AX
    275.     SUB [SectorCount],AL      ; Are we finished?
    276.     jbe DRdone
    277.     ADD word [Arguments + SHARED.SectorBase],AX       ; increment logical sector position
    278.     ADC word [Arguments + SHARED.SectorBase+2],0
    279.     MUL [BytesPerSector]      ; determine next offset for read
    280.     ADD BX,AX           ; (BX)=(BX)+(SI)*(Bytes per sector)
    281.  
    282.     jmp DRloop
    283. DRdone:
    284.     mov [SectorCount],al
    285.     clc
    286.     retf
    287.  
    288.  
    289.  
    290.  
    291.  
    292.  
    293.  
    294. MSG_NO_GRLDR db 'Cannot find GRLDR',0
    295. MSG_BAD_GRLDR db 'No LDR signature',0
    296. MSG_READ_ERROR db 'Disk I/O error',0
    297. MSG_REBOOT_ERROR db 13,10,'Insert another disk',0
    298.  
    299.  
    300. LOADERNAME db 'GRLDR   BIN'
    301.  
    302.     rb 510-($-$$)
    303.     db  55h,0aah
    304.  
    305.  
    306.  
    307. BootSectorEnd:
    (fasm)
     
  11. shershen

    shershen New Member

    Публикаций:
    0
    Регистрация:
    12 май 2010
    Сообщения:
    6
    Большое спасибо. Однако, вы меня сильно переоцениваете :) А я, видимо, недооценил сложность задачи, так что пойдем другим путем...
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    блин да там просто перемножить размер сектора в байтах на число секторов в кластере на номер начального кластера И ФСИО!!1
     
  13. shershen

    shershen New Member

    Публикаций:
    0
    Регистрация:
    12 май 2010
    Сообщения:
    6
    Так если, фсио, зачем вы меня ассемблером пугаете? :dntknw:
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну так это сэмпл. Можно и на си и вообще на чём хочешь. Язык не важен.
    я же тебе дал сорс драйвера на си, в чем проблема?