Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Paste Description for FAT Source Code

FAT filesystem driver Source Code
by Toaster a lá Peter Kleissner

FAT Source Code
Monday, April 2nd, 2007 at 10:49:08am MDT 

  1. Copyright (C) 2005-2007 Peter Kleissner
  2. see www.toasteros.at.tt -> Impressum -> License  // http://t0ast3r.t0.ohost.de/index.php?page=impressum&sub=license
  3. just see, learn, don't copy
  4.  
  5. ---==== Published under the ToasterOS GENERAL PUBLIC LICENSE ===---
  6.  
  7.  
  8. ; FAT functions
  9.  
  10. ; - Get_Short_Name
  11. ; - Determine_FAT_Type
  12. ; - Get_Count_of_Clusters
  13. ; - Get_DataSec
  14. ; - First_Sector_of_Cluster
  15. ; - Get_First_Data_Sector
  16. ; - Get_Root_Dir_Sectors
  17. ; - Get_FirstRootDirSecNum
  18. ; - Get_FATSz
  19. ; - Get_TotSec
  20. ; - Get_FATSecNum_Offset
  21. ; - Read_FAT_entry
  22. ; - Write_FAT_entry
  23. ; - Get_Next_Cluster
  24. ; - Get_Entry_Count
  25. ; - Return_SecPerClusVal
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32. Determine_FAT_Type:
  33.  
  34. ; [Drive] = drive to determine the FAT type
  35.  
  36. ; return:
  37. ; all FAT values in Drive_Buffer are set correct (inclusive FAT determination)
  38.  
  39.  
  40. ; read the BIOS Parameter Block
  41. Read 0, 1, Open_File_Destroy
  42.  
  43.  
  44. ; copy relevant values of the BIOS Parameter Block
  45.  
  46. ; set "Sectors per Cluster"
  47. movzx ebx,byte [API_Buffer+13]
  48. mov [Drive_Buffer+0Bh],bl
  49.  
  50. ; set "dwords per Sector"
  51. movzx eax,word [API_Buffer+11]
  52. shr ax,2
  53. mov [Drive_Buffer+0Ch],ax
  54.  
  55. ; set "dwords per Cluster"
  56. mul ebx        ; Sectors per Cluster" * "dwords per Sector"
  57. mov [Drive_Buffer+0Eh],eax
  58.  
  59. ; set "File Allocation Table" (= "Reserved Sector Count")
  60. mov ax,word [API_Buffer+14]                         ; FAT Offset = Reserved Sector Count
  61. mov [Drive_Buffer+1Ch],ax
  62.  
  63.  
  64. ; set the value "First_Data_Sector"
  65. call Get_First_Data_Sector
  66.  
  67. ; ---- OBSOLETE ----
  68. ; set the value "entries per cluster"
  69. ;call Get_Entry_Count
  70. ; ---- OBSOLETE ----
  71.  
  72. ; set the value "FAT Type"
  73. call Get_Count_of_Clusters
  74.  
  75. ; set the values "first root directory sector" and "last root directory sector"
  76. call Get_FirstRootDirSecNum
  77.  
  78. ret
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85. Get_First_Data_Sector:
  86.  
  87. ; static function (only called once), needs BIOS Parameter Block
  88. ; writes "First_Data_Sector" into Drive_Buffer
  89.  
  90. ; (BPB_NumFATs * FATSz)
  91. call Get_FATSz
  92. movzx ebx,byte [API_Buffer+16]
  93. mul ebx
  94.  
  95. ; BPB_ResvdSecCnt + (BPB_NumFATs * FATSz)
  96. movzx ecx,word [API_Buffer+14]
  97. add ecx,eax
  98.  
  99. ; BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors
  100. call Get_Root_Dir_Sectors
  101. add eax,ecx
  102.  
  103. mov [Drive_Buffer+12h],eax                              ; set "first data sector"
  104.  
  105. ret
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112. Get_FATSz:
  113.  
  114. ; static function (only called once), needs BIOS Parameter Block
  115. ; returns the FATSz
  116.  
  117.  
  118. ; C++
  119.  
  120. ; If(BPB_FATSz16 != 0)
  121. ;   FATSz = BPB_FATSz16;
  122. ; Else
  123. ;   FATSz = BPB_FATSz32;
  124.  
  125.  
  126. ; Assembler
  127.  
  128. movzx eax,word [API_Buffer+22]          ; eax = BPB_FATSz16
  129.  
  130. or eax,eax                                          ; eax = 0 ?
  131. jnz Get_FATSz_Exit                                    ; if not zero, it's FATSz16
  132.  
  133. ; else it's FATSz32
  134. mov eax,[API_Buffer+36]      ; eax = BPB_FATSz32
  135.  
  136. Get_FATSz_Exit:
  137.  
  138. ret
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145. Get_Count_of_Clusters:
  146.  
  147. ; static function (only called once), needs BIOS Parameter Block
  148. ; writes "FAT Type" into Drive_Buffer
  149.  
  150. ; CountofClusters = DataSec / BPB_SecPerClus
  151. call Get_DataSec
  152.  
  153. xor edx,edx
  154. movzx ebx,byte [Drive_Buffer+0Bh]
  155. div ebx
  156.  
  157.  
  158. ; C++
  159.  
  160. ; If(CountofClusters < 4085)
  161. ;   /* Volume is FAT12 */
  162. ; else
  163. ;   if(CountofClusters < 65525)
  164. ;     /* Volume is FAT16 */
  165. ;   else
  166. ;     /* Volume is FAT32 */
  167.  
  168.  
  169. ; Assembler
  170.  
  171. mov [Drive_Buffer+0Ah],byte 12          ; suppose FAT Type is FAT12
  172. cmp eax,4085
  173. jl Determine_FAT_Type_Exit                              ; if CountofClusters < 4085 exit
  174.  
  175. mov [Drive_Buffer+0Ah],byte 16          ; suppose FAT Type is FAT16
  176. cmp eax,65525
  177. jl Determine_FAT_Type_Exit                              ; if CountofClusters < 65525 exit
  178.  
  179. ; else FAT Type is FAT32
  180. mov [Drive_Buffer+0Ah],byte 32
  181.  
  182. Determine_FAT_Type_Exit:
  183.  
  184. ret
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191. Get_DataSec:
  192.  
  193. ; static function (only called once), needs BIOS Parameter Block and returns static value
  194. ; return = DataSec
  195.  
  196. ; DataSec = TotSec - FirstDataSector
  197. call Get_TotSec
  198. sub eax,[Drive_Buffer+12h]
  199.  
  200. ret
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207. Get_TotSec:
  208.  
  209. ; static function (only called once), needs BIOS Parameter Block and returns static value
  210. ; return = TotSec
  211.  
  212. ; C++
  213.  
  214. ; If(BPB_TotSec16 != 0)
  215. ;   TotSec = BPB_TotSec16;
  216. ; Else
  217. ;   TotSec = BPB_TotSec32;
  218.  
  219.  
  220. ; Assembler
  221.  
  222. movzx eax,word [API_Buffer+19]          ; eax = BPB_TotSec16
  223.  
  224. or eax,eax                                          ; eax = 0 ?
  225. jnz Get_TotSec_Exit                              ; if not zero, it's TotSec16
  226.  
  227. ; else it's TotSec32
  228. mov eax,[API_Buffer+32]      ; eax = BPB_TotSec32
  229.  
  230. Get_TotSec_Exit:
  231.  
  232. ret
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239. Get_Root_Dir_Sectors:
  240.  
  241. ; static function (only called once), needs BIOS Parameter Block
  242. ; return = Root Directory Sectors
  243.  
  244. ; (BPB_RootEntCnt * 32)
  245. movzx eax,word [API_Buffer+17]
  246. imul eax,32
  247.  
  248. ; eax = zero ? (only on FAT32 drives)
  249. or eax,eax
  250. jz Get_Root_Dir_Sectors_Exit
  251.  
  252. ; (BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)
  253. movzx edx,word [API_Buffer+11]
  254. dec edx
  255. add eax,edx
  256.  
  257. ; ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec
  258. xor edx,edx
  259. movzx ebx,word [API_Buffer+11]
  260. div ebx
  261.  
  262. Get_Root_Dir_Sectors_Exit:
  263.  
  264. ret
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271. Get_FirstRootDirSecNum:
  272.  
  273. ; static function (only called once), needs BIOS Parameter Block
  274. ; writes "first root directory sector" and "last root directory sector" into Drive_Buffer
  275.  
  276.  
  277. ; share function into FAT12/16 and FAT32
  278. cmp [Drive_Buffer+0Ah],byte 32
  279. je Get_FirstRootDirSecNum_FAT32
  280.  
  281.  
  282. ; FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz);
  283. call Get_FATSz
  284. movzx ebx,byte [API_Buffer+16]
  285. mul ebx        ; BPB_FATSz * BPB_NumFATs
  286.  
  287. movzx ebx,word [API_Buffer+14]
  288. add eax,ebx                                   ; BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16)
  289.  
  290. mov [Drive_Buffer+16h],eax                              ; set "first root directory sector"
  291.  
  292. call Get_Root_Dir_Sectors                                   ; calculate last root directory sector (add values)
  293. add ax,[Drive_Buffer+16h]
  294. mov [Drive_Buffer+1Ah],ax                                   ; set "last root directory sector"
  295.  
  296. ret
  297.  
  298.  
  299. Get_FirstRootDirSecNum_FAT32:
  300. ; FirstRootDirSecNum = BPB_RootClus * Sectors per Cluster
  301. mov eax,[API_Buffer+44]
  302. imul eax,[API_Buffer+13]
  303.  
  304. mov [Drive_Buffer+16h],eax                              ; set "first root directory sector"
  305. mov [Drive_Buffer+1Ah],word 00h     ; set "last root directory sector" (on FAT32 not avl)
  306.  
  307. ret
  308.  
  309.  
  310.  
  311.  
  312.  
  313. %if 0 = 1
  314.  
  315. Get_Entry_Count:
  316.  
  317. ; static function (only called once), needs BIOS Parameter Block
  318. ; writes "entries per cluster" into Drive_Buffer
  319.  
  320. ; calculate the count of entrys per sector (BPB_BytsPerSec / Entry_Size)
  321. movzx eax,word [API_Buffer+11]
  322. xor edx,edx
  323. mov ebx,32
  324. div ebx
  325.  
  326. ; calculate the count of entries per cluster
  327. movzx ebx,byte [API_Buffer+13]
  328. mul ebx        ; * sectors per cluster
  329.  
  330. mov [Drive_Buffer+1Ch],eax                              ; set "entries per cluster"
  331.  
  332. ret
  333.  
  334. %endif
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342. ; non static functions, which are called more than once and returns non static values
  343.  
  344.  
  345.  
  346. First_Sector_of_Cluster:
  347.  
  348. ; normal FAT32 ?
  349. cmp [Drive_Buffer+0Ah],byte 32
  350. je First_Sector_of_Cluster_normal
  351.  
  352. ; normal cluster type ?
  353. cmp [cluster_type],byte 18h
  354. jne First_Sector_of_Cluster_normal
  355.  
  356. ; else the cluster is a sector in the root directory area
  357. ; (do nothing)
  358.  
  359. ret
  360.  
  361.  
  362. ; eax = cluster n
  363. ; return = first sector of cluster n
  364.  
  365. ; n - 2
  366. First_Sector_of_Cluster_normal:
  367. dec eax
  368. dec eax
  369.  
  370. ; (n - 2) * BPB_SecPerClus
  371. movzx ebx,byte [Drive_Buffer+0Bh]
  372. mul ebx
  373.  
  374. ; ((n - 2) * BPB_SecPerClus) + FirstDataSector
  375. add eax,[Drive_Buffer+12h]
  376.  
  377. ret
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385. Get_FATSecNum_Offset:
  386.  
  387. ; eax = cluster number n
  388.  
  389. ; return = sector to read (element of the File Allocation Table)
  390. ; reutrn(edx) = Offset in the EFFECTIVE sector
  391.  
  392.  
  393. ; if FAT12 is set, and offset streches over boundarys, the carry flag is set
  394. ; in all other cases (non FAT12 or in boundarys) the carry flag is cleared
  395.  
  396.  
  397.  
  398. ; If(FATType == FAT16)
  399. ;   FATOffset = N * 2;
  400. ; Else
  401. ;   if (FATType == FAT32)
  402. ;     FATOffset = N * 4;
  403. ;
  404. ; ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
  405. ; ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);
  406.  
  407.  
  408. ; special FAT12?
  409. cmp [Drive_Buffer+0Ah],byte 12
  410. je Get_FATSecNum_Offset_FAT12
  411.  
  412. ; calculate the FATOffset (N * 2 or 4)
  413. shl eax,1                                                 ; suppose FAT Type is 16
  414. cmp [Drive_Buffer+0Ah],byte 16
  415. je Calculate_ThisFAT                        ; if FAT 16, exit
  416.  
  417. shl eax,1                                                 ; else mul one more with 2 (in effect eax * 4)
  418.  
  419. Calculate_ThisFAT:
  420. ; FATOffset / BPB_BytsPerSec
  421. xor edx,edx
  422. sub ebx,ebx
  423. imul bx, word [Drive_Buffer+0Ch], 4                    ; bx = bytes per sector
  424. div ebx        ; return(edx) = Offset in sector
  425.  
  426. ; BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec)
  427. movzx ebx,word [Drive_Buffer+1Ch]
  428. add eax,ebx                                   ; return = sector
  429.  
  430. clc
  431. ret
  432.  
  433.  
  434.  
  435. Get_FATSecNum_Offset_FAT12:
  436.  
  437. ; FATOffset = N + (N / 2);
  438. ; /* Multiply by 1.5 without using floating point, the divide by 2 rounds DOWN */
  439. ; ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
  440. ; ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);
  441. ;
  442. ; We now have to check for the sector boundary case:
  443. ;
  444. ; If(ThisFATEntOffset == (BPB_BytsPerSec – 1)) {
  445. ; /* This cluster access spans a sector boundary in the FAT */
  446. ; /* There are a number of strategies to handling this. The */
  447. ; /* easiest is to always load FAT sectors into memory */
  448. ; /* in pairs if the volume is FAT12 (if you want to load */
  449. ; /* FAT sector N, you also load FAT sector N+1 immediately */
  450. ; /* following it in memory unless sector N is the last FAT */
  451. ; /* sector). It is assumed that this is the strategy used here */
  452. ; /* which makes this if test for a sector boundary span */
  453. ; /* unnecessary. */
  454. ; }
  455.  
  456.  
  457. ; the same code as by "Calculate_ThisFAT"
  458. ; FATOffset / BPB_BytsPerSec
  459. xor edx,edx
  460. sub ebx,ebx
  461. imul bx, word [Drive_Buffer+0Ch], 4                    ; bx = bytes per sector
  462. div ebx        ; return(edx) = Offset in sector
  463.  
  464. ; BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec)
  465. movzx ebx,word [Drive_Buffer+1Ch]
  466. add eax,ebx                                   ; return = sector
  467.  
  468. ; If(ThisFATEntOffset == (BPB_BytsPerSec – 1)) then boundary strech
  469. dec ebx
  470. cmp edx,ebx
  471. je Get_FATSecNum_Offset_FAT12_boundary
  472.  
  473. clc
  474. ret
  475.  
  476. ; if here, the entry is over boundarys, so set cf to indicate it
  477. Get_FATSecNum_Offset_FAT12_boundary:
  478. stc
  479. ret
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487. Read_FAT_entry:
  488.  
  489. ; eax = Cluster
  490.  
  491. mov [Temp],eax            ; store the Cluster temporary (for FAT12)
  492.  
  493. ; special FAT12?
  494. cmp [Drive_Buffer+0Ah],byte 12
  495. je Read_FAT12_entry
  496.  
  497.  
  498. call Get_FATSecNum_Offset                            ; get the Sector and the Offset of the entry
  499.  
  500. ; read the SST
  501. Read eax, 1, Read_FAT_Entry_Exit
  502.  
  503.  
  504. ; now share the function into FAT16 and FAT32
  505. cmp [Drive_Buffer+0Ah],byte 32
  506. je Read_FAT32_entry
  507.  
  508. lea edi,[API_Buffer+edx]                                ; edi = Offset in the Buffer
  509. movzx eax,word [edi]                    ; eax = searched entry
  510. jmp Read_FAT_Entry_succ
  511.  
  512.  
  513. Read_FAT32_entry:
  514. lea edi,[API_Buffer+edx]                                ; edi = Offset in the Buffer
  515. mov eax,[edi]                  ; eax = searched entry
  516. ;jmp Read_FAT_Entry_succ
  517.  
  518.  
  519. Read_FAT_Entry_succ:
  520. clc
  521.  
  522. Read_FAT_Entry_Exit:
  523. ret
  524.  
  525.  
  526.  
  527. Read_FAT12_entry:                                   ; now: same code as by Read_FAT16/32_entry
  528.  
  529. call Get_FATSecNum_Offset                            ; get the Sector and the Offset of the entry
  530. jc Read_FAT12_entry_boundary                ; if the entry streches about sector boundarys, handle special
  531.  
  532. ; read the SST
  533. Read eax, 1, Read_FAT_Entry_Exit
  534.  
  535. lea edi,[API_Buffer+edx*2]                        ; edi = Offset in the Buffer
  536. movzx eax,word [edi]                    ; eax = searched (word) entry
  537.  
  538. ; odd?
  539. test [Temp],dword 01b
  540. je Read_FAT12_entry_odd
  541.  
  542. ; if here, we want the low 12 bits of the word, so clear the other (and exit)
  543. or eax,0F000h
  544. xor eax,0F000h
  545. jmp Read_FAT_Entry_succ
  546.  
  547. Read_FAT12_entry_odd:
  548. ; if here, we want only the high 12 bits of the word, so shift right about 4 bits (and exit)
  549. shr eax,4
  550. jmp Read_FAT_Entry_succ
  551.  
  552.  
  553. Read_FAT12_entry_boundary:                        ; if here, the entry streches over sector boundarys
  554.  
  555. mov [Temp],eax            ; save the sector
  556.  
  557. ; read the SST
  558. Read eax, 1, Read_FAT_Entry_Exit
  559.  
  560. lea edi,[API_Buffer+edx*2]                        ; edi = Offset in the Buffer
  561.  
  562. ; restore the needed sector (+ 1 !)
  563. mov eax,[Temp]
  564. inc eax
  565.  
  566. ; read the LEAST 4 bits of the ENTRY, which are - in fact - the HIGH NIBBLE bits of the read byte
  567. mov bl,[edi]                        ; just use bl instead of al; bl wouldn't change by the ToasterOS function definition
  568.  
  569. ; read the next Sector of the SST
  570. Read eax, 1, Read_FAT_Entry_Exit
  571.  
  572. ; now merge the 4 bits in bl and the byte at API_Buffer + 0
  573. movzx eax,byte [API_Buffer+0]
  574. shl eax,4                                          ; shl the byte (by 4 bits)
  575.  
  576. shr bl,4                                                ; the high nibble of the byte is the low nibble we need
  577.  
  578. or al,bl                                                ; add the entry (end exit)
  579. clc
  580.  
  581. ret
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589. Write_FAT_entry:
  590.  
  591. ; eax = Cluster
  592. ; ebx = value; or implicit used bx/b12 for using FAT12, FAT16
  593. ;   the caller shouldn't determine the size of using, because all FAT functions return 32 bit (probably zero extended) values
  594.  
  595. ; maintaily the code (explicit the initialising process) is the same as by Read_FAT_Entry
  596.  
  597. mov [Temp],eax            ; store the Cluster temporary (for FAT12)
  598.  
  599. ; special FAT12?
  600. cmp [Drive_Buffer+0Ah],byte 12
  601. je Write_FAT12_entry
  602.  
  603. push ebx                                                ; store ebx, it will be used in Get_FATSecNum_Offset
  604. call Get_FATSecNum_Offset                            ; get the Sector and the Offset of the entry
  605. pop ebx       ; restore ebx
  606.  
  607. add eax,[Drive_Buffer+1Ch]                        ; eax = sector to modify
  608. mov ecx,eax                              ; store to-change sector
  609.  
  610. ; read the SST
  611. Read eax, 1, Write_FAT_Entry_Exit
  612.  
  613.  
  614. ; now share the function into FAT16 and FAT32
  615. cmp [Drive_Buffer+0Ah],byte 32
  616. je Write_FAT32_entry
  617.  
  618. lea edi,[API_Buffer+edx*2]                        ; edi = Offset in the Buffer
  619. mov [edi],bx                        ; store new data into the entry
  620. jmp Write_entry
  621.  
  622. Write_FAT32_entry:
  623. lea edi,[API_Buffer+edx*4]                        ; edi = Offset in the Buffer
  624. mov [edi],ebx                  ; store new data (now 32 bit) into the entry
  625.  
  626.  
  627. Write_entry:                        ; write the to-change sector
  628. Write_into ecx, 1
  629.  
  630.  
  631. Write_FAT_Entry_Exit:
  632.  
  633. ret
  634.  
  635.  
  636.  
  637. Write_FAT12_entry:                              ; now: same code as by Read/Write_FAT16/32_entry
  638.  
  639. push ebx                                                ; store ebx, it will be used in Get_FATSecNum_Offset
  640. call Get_FATSecNum_Offset                            ; get the Sector and the Offset of the entry
  641. pop ebx       ; restore ebx
  642. jc Write_FAT12_entry_boundary            ; if the entry streches about sector boundarys, handle special
  643.  
  644. add eax,[Drive_Buffer+1Ch]                        ; eax = sector to modify
  645. mov ecx,eax
  646.  
  647. ; read the SST
  648. Read eax, 1, Write_FAT_Entry_Exit
  649.  
  650. lea edi,[API_Buffer+edx*2]                        ; edi = Offset in the Buffer
  651. mov ax,[edi]                        ; eax = searched (word) entry
  652.  
  653.  
  654. ; odd?
  655. test [Temp],dword 01b
  656. je Write_FAT12_entry_odd
  657.  
  658. ; if here, we want to change the low 12 bits of the word, so clear the other
  659. or ebx,0F000h
  660. xor ebx,0F000h            ; clear high 4 bits of the value to store (also: or)
  661. or ax,bx
  662. mov ax,[edi]
  663. jmp Write_entry
  664.  
  665. Write_FAT12_entry_odd:
  666. ; if here, we want to change only the high 12 bits of the word, so shift right about 4 bits
  667. or ebx,0F000h
  668. xor ebx,0F000h            ; clear high 4 bits of the value to store (also: or)
  669. shr ebx,4                                          ; shift ebx, the value
  670. or ax,bx
  671. mov ax,[edi]
  672. jmp Write_entry
  673.  
  674.  
  675. Write_FAT12_entry_boundary:                    ; if here, the entry streches over sector boundarys
  676.  
  677. add eax,[Drive_Buffer+1Ch]                        ; eax = sector to modify
  678. mov ecx,eax
  679.  
  680. ; read the SST
  681. Read eax, 1, Write_FAT_Entry_Exit
  682.  
  683. lea edi,[API_Buffer+edx*2]                        ; edi = Offset in the Buffer
  684.  
  685. ; modify the top 4 bits of the byte, which are the least 4 bits of the entry
  686. mov al,[edi]
  687. mov dl,bl
  688. or dl,00001111b
  689. xor dl,00001111b
  690. or al,bl
  691. mov [edi],al
  692.  
  693. ; write the first to-change sector
  694. Write_into ecx, 1, Write_FAT_Entry_Exit
  695.  
  696.  
  697. ; restore the needed sector (+ 1 !)
  698. inc ecx
  699.  
  700. ; read the next Sector of the SST
  701. Read ecx, 1, Write_FAT_Entry_data_losing
  702.  
  703.  
  704. ; store the remaining byte of the entry
  705. shr ebx,4
  706. mov [API_Buffer+0],bl
  707.  
  708. ; write the second to-change sector
  709. Write_into ecx, 1, Write_FAT_Entry_data_losing
  710.  
  711. jmp Write_FAT_Entry_Exit
  712.  
  713.  
  714.  
  715. Write_FAT_Entry_data_losing:
  716. ; comes here if there is an error while accessing (reading or writting) a FAT12 entry streches over sector boundarys
  717.  
  718. ; contact security guard/change to security mode?
  719. ; ?
  720.  
  721. ret
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729. Get_Next_Cluster:
  730.  
  731. ; eax = Cluster
  732. ;   even on FAT12/16 root directorys it's interpreted as cluster size
  733.  
  734. ; this function gets the next CLUSTER of any directory (specified by the given cluster), included the Root Directory
  735. ; cf is set if EOF is reached, then return = entry
  736.  
  737.  
  738. ; share into FAT12/16 and FAT32
  739. cmp [Drive_Buffer+0Ah],byte 32
  740. je Get_Next_Cluster_FAT32
  741.  
  742.  
  743. ; check if cluster is a sector of the FAT12/16 root directory
  744. cmp [cluster_type],byte 18h
  745. jne Get_Next_Cluster_no_root_directory
  746.  
  747.  
  748. ; if here, the cluster is a sector of the root directory
  749. ; if (Sectors per Cluster + Current Cluster) > Last_Root_Dir_Sector then EOC is reached
  750. push bx
  751. movzx bx,byte [Drive_Buffer+0Bh]
  752. add ax,bx                                                 ; add Sectors per Cluster
  753. pop bx
  754.  
  755. cmp [Drive_Buffer+1Ah],ax                                   ; eax > last sector of the root directory?
  756. jnl Get_Next_Cluster_RD_inc
  757.  
  758. ; if here, the last sector of the root directory is reached, so there is no more cluster
  759. mov eax,0FFFFFFFFh                                    ; EOC is reached
  760. stc
  761. ret
  762.  
  763. Get_Next_Cluster_RD_inc:                                        ; normal exit (already incremented)
  764. ; eax is already up to date (because of the add Sectors per Cluster)
  765. clc
  766. ret
  767.  
  768.  
  769.  
  770. Get_Next_Cluster_no_root_directory:                    ; share into FAT12 and FAT16
  771. cmp [Drive_Buffer+0Ah],byte 16
  772. je Get_Next_Cluster_FAT16
  773.  
  774.  
  775. Get_Next_Cluster_FAT12:
  776. call Read_FAT_entry
  777.  
  778. ; EOF reached?
  779. cmp eax,0FF8h
  780. jl Get_Next_Cluster_succ                                        ; if (eax < 0FF8h) then it's not the end
  781.  
  782. ; else set cf (and exit)
  783. stc
  784. ret
  785.  
  786.  
  787. Get_Next_Cluster_FAT16:
  788. call Read_FAT_entry
  789.  
  790. ; EOF reached?
  791. cmp eax,0FFF8h
  792. jl Get_Next_Cluster_succ                                        ; if (eax < 0FFF8h) then it's not the end
  793.  
  794. ; else set cf (and exit)
  795. stc
  796. ret
  797.  
  798.  
  799. Get_Next_Cluster_FAT32:
  800. call Read_FAT_entry
  801.  
  802. ; the function returns a (32 bit) pointer, but on FAT32 entries there are only 28 bits used, so clear the top 4 bits
  803. or eax,0F0000000h
  804. xor eax,0F0000000h
  805.  
  806. ; EOF reached?
  807. cmp eax,0FFFFFF8h
  808. jl Get_Next_Cluster_succ                                        ; if (eax < 0FFFFFF8h) then it's not the end
  809.  
  810. ; else set cf (and exit)
  811. stc
  812. ret
  813.  
  814.  
  815. Get_Next_Cluster_succ:
  816.  
  817. clc
  818. ret

advertising

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.

fantasy-obligation
fantasy-obligation
fantasy-obligation