Subversion Repositories Kolibri OS

Rev

Rev 9735 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2021-2022. All rights reserved. ;;
  4. ;;  Distributed under terms of the GNU General Public License.  ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 7136 $
  9.  
  10. ; exFAT external functions
  11. ;   in:
  12. ; ebx -> parameter structure of sysfunc 70
  13. ; ebp -> exFAT structure
  14. ; esi -> path string in UTF-8
  15. ;   out:
  16. ; eax, ebx = return values for sysfunc 70
  17. iglobal
  18. align 4
  19. exFAT_user_functions:
  20.         dd      exFAT_free
  21.         dd      (exFAT_user_functions_end - exFAT_user_functions - 4) / 4
  22.         dd      exFAT_ReadFile
  23.         dd      exFAT_ReadFolder
  24.         dd      0 ;exFAT_CreateFile
  25.         dd      0 ;exFAT_Write
  26.         dd      0 ;exFAT_SetFileEnd
  27.         dd      exFAT_GetFileInfo
  28.         dd      0 ;exFAT_SetFileInfo
  29.         dd      0
  30.         dd      0 ;exFAT_Delete
  31.         dd      0 ;exFAT_CreateFolder
  32.         dd      0 ;exFAT_Rename
  33. exFAT_user_functions_end:
  34. endg
  35.  
  36. struct exFAT PARTITION
  37. fat_change          db  ?   ; 1=fat has changed
  38. createOption        db  ?
  39.                     rb  2
  40. Lock                MUTEX   ; currently operations with one partition
  41. ; can not be executed in parallel since the legacy code is not ready
  42. fat_in_cache        dd  ?
  43. FAT_START           dd  ?   ; start of fat table
  44. ROOT_START          dd  ?   ; start of rootdir
  45. SECTORS_PER_CLUSTER dd  ?
  46. BYTES_PER_SECTOR    dd  ?   ; Note: if BPS <> 512 need lots of changes
  47. SECTORS_PER_FAT     dd  ?
  48. NUMBER_OF_FATS      dd  ?
  49. CLUSTER_HEAP_START  dd  ?
  50. CLUSTER_COUNT       dd  ?
  51. DATA_START          dd  ?   ; start of data area (=first cluster 2)
  52. LAST_CLUSTER        dd  ?   ; last availabe cluster
  53. fatRESERVED         dd  ?
  54. fatBAD              dd  ?
  55. fatEND              dd  ?
  56. fatMASK             dd  ?
  57. fatStartScan        dd  ?
  58. cluster_tmp         dd  ?   ; used by analyze_directory and analyze_directory_to_write
  59. ROOT_CLUSTER        dd  ?   ; first rootdir cluster
  60. fat_cache_ptr       dd  ?
  61. points_to_BDFE      dd  ?
  62. secondary_dir_entry dd  ?
  63. longname_sec1       dd  ?   ; used by analyze_directory to save 2 previous
  64. longname_sec2       dd  ?   ; directory sectors for delete long filename
  65. LFN_reserve_place   dd  ?
  66. path_in_UTF8        dd  ?
  67. General_Sec_Flags   dd  ?
  68. valid_data_length   dd  ?
  69. RAX_high            dd  ?
  70. RCX_high            dd  ?
  71. RDX_high            dd  ?
  72. RDI_high            dd  ?
  73. volumeLabel         rb  12
  74. ; The next two areas (32+32) should be arranged sequentially.
  75. ; Do not change their location!!!
  76. file_dir_entry      rb  32 ; Entry Type 0x85
  77. str_ext_dir_entry   rb  32 ; Entry Type 0xC0
  78. buffer              rb  512
  79. ends
  80.  
  81. ; these labels are located before the main function to make
  82. ; most of jumps to these be short
  83. exFAT_create_partition.free_return0:
  84.         mov     eax, ebp
  85.         call    free
  86.         pop     ebp
  87. ; DEBUGF  1, "K : exFAT_create_partition.free_return0 EAX: %x\n", eax
  88. exFAT_create_partition.return0:
  89.         xor     eax, eax
  90. ; DEBUGF  1, "K : exFAT_create_partition.return0 EAX: %x\n", eax
  91.         ret
  92.  
  93. ; Mount if it's a valid exFAT partition.
  94. exFAT_create_partition:
  95. ; DEBUGF  1, "K : exFAT_create_partition EAX: %x\n", eax
  96. ;   in:
  97. ; ebp -> PARTITION structure
  98. ; ebx -> boot sector
  99. ; ebx+512 -> buffer
  100. ;   out:
  101. ; eax -> exFAT structure, 0 = not exFAT
  102.         cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
  103.         jnz     .return0
  104. ; DEBUGF  1, "K : exFAT DISK.MediaInfo.SectorSize=512\n"
  105. ; bootsector must have been successfully read
  106.         cmp     dword [esp+4], 0
  107.         jnz     .return0
  108. ; DEBUGF  1, "K : exFAT bootsector successfully read\n"
  109. ; offset +510 = bootsector signature must be correct
  110.         cmp     word [ebx+0x1fe], 0xaa55
  111.         jnz     .return0
  112. ; DEBUGF  1, "K : exFAT bootsector signature correct\n"
  113. ; offset +109 = sectors per cluster must be nonzero
  114.         cmp     byte [ebx+0x6d], 0
  115.         jz      .return0
  116. ; DEBUGF  1, "K : exFAT sectors per cluster = nonzero\n"
  117. ; offset +108 = bytes per sector must be 0x200
  118. ; (LEGACY! In the future, increase support to 4096)
  119. ; the value for exFAT is a power of 2
  120.         cmp     byte [ebx+0x6c], 9
  121.         jnz     .return0
  122. ; DEBUGF  1, "K : exFAT bytes per sector = 512\n"
  123. ; Test name = 'EXFAT   '
  124.         cmp     dword [ebx+3], 'EXFA'
  125.         jnz     .return0
  126.         cmp     dword [ebx+7], 'T   '
  127.         jnz     .return0
  128. ; DEBUGF  1, "K : exFAT Test name EXFAT = OK \n"
  129.         movi    eax, sizeof.exFAT
  130.         call    malloc
  131.         test    eax, eax
  132.         jz      .return0
  133. ; DEBUGF  1, "K : exFAT malloc sizeof.exFAT = OK \n"
  134.         mov     ecx, dword [ebp+PARTITION.FirstSector]
  135.         mov     dword [eax+exFAT.FirstSector], ecx
  136. ; DEBUGF  1, "K : exFAT PARTITION.FirstSector ECX: %x\n", ecx
  137.         mov     ecx, dword [ebp+PARTITION.FirstSector+4]
  138.         mov     dword [eax+exFAT.FirstSector+4], ecx
  139. ; DEBUGF  1, "K : exFAT PARTITION.FirstSector+4 ECX: %x\n", ecx
  140.         mov     ecx, dword [ebp+PARTITION.Length]
  141.         mov     dword [eax+exFAT.Length], ecx
  142. ; DEBUGF  1, "K : exFAT PARTITION.Length ECX: %x\n", ecx
  143.         mov     ecx, dword [ebp+PARTITION.Length+4]
  144.         mov     dword [eax+exFAT.Length+4], ecx
  145. ; DEBUGF  1, "K : exFAT PARTITION.Length+4 ECX: %x\n", ecx
  146.         mov     ecx, [ebp+PARTITION.Disk]
  147.         mov     [eax+exFAT.Disk], ecx
  148. ; DEBUGF  1, "K : exFAT PARTITION.Disk ECX: %x\n", ecx
  149.         mov     [eax+exFAT.FSUserFunctions], exFAT_user_functions
  150.         or      [eax+exFAT.fat_in_cache], -1
  151.         mov     [eax+exFAT.fat_change], 0
  152.  
  153.         push    ebp
  154.         mov     ebp, eax
  155.         lea     ecx, [ebp+exFAT.Lock]
  156.         call    mutex_init
  157. ; offset +80 = sectors reserved
  158.         mov     eax, [ebx+0x50]
  159.         mov     [ebp+exFAT.FAT_START], eax
  160. ; DEBUGF  1, "K : exFAT.FAT_START EAX: %x\n", eax
  161. ; offset +109 = sectors per cluster. This is power of 2; Minimal value is 1;
  162. ; 2^0 =1 sector (512 Bytes) and maximum 32 MB cluster size in bytes
  163.         movzx   ecx, byte [ebx+0x6d]
  164.         mov     eax, 1
  165.         shl     eax, cl
  166.         mov     [ebp+exFAT.SECTORS_PER_CLUSTER], eax
  167. ; DEBUGF  1, "K : exFAT.SECTORS_PER_CLUSTER EAX: %x\n", eax
  168. ; offset +108 = bytes per sector. This is power of 2; Minimal value is 9;
  169. ; 2^9 =512 Bytes and maximum 2^12 =4096 Bytes
  170.         movzx   ecx, byte [ebx+0x6c]     ; bytes per sector
  171.         mov     eax, 1
  172.         shl     eax, cl
  173.         mov     [ebp+exFAT.BYTES_PER_SECTOR], eax
  174. ; DEBUGF  1, "K : exFAT.BYTES_PER_SECTOR EAX: %x\n", eax
  175. ;------------------------------------------------------------------------------
  176. ;        movzx   eax, word [ebx+0x11]    ; count of rootdir entries (=0 fat32)
  177. ;        shl     eax, 5                  ; mul 32
  178. ;        dec     ecx
  179. ;        add     eax, ecx                ; round up if not equal count
  180. ;        inc     ecx                     ; bytes per sector
  181. ;        xor     edx, edx
  182. ;        div     ecx
  183. ;        mov     [ebp+FAT.ROOT_SECTORS], eax     ; count of rootdir sectors
  184. ;------------------------------------------------------------------------------
  185. ; offset +84 = Size of FAT in sectors
  186.         mov     eax, [ebx+0x54]         ; sectors per fat
  187.         mov     [ebp+exFAT.SECTORS_PER_FAT], eax
  188. ; DEBUGF  1, "K : exFAT.SECTORS_PER_FAT EAX: %x\n", eax
  189. ;------------------------------------------------------------------------------
  190. ; offset +88 = Starting sector of cluster heap
  191.         mov     eax, [ebx+0x58]         ; Cluster offset
  192.         mov     [ebp+exFAT.CLUSTER_HEAP_START], eax
  193. ; DEBUGF  1, "K : exFAT.CLUSTER_HEAP_START EAX: %x\n", eax
  194. ;------------------------------------------------------------------------------
  195. ; offset +92 = Number of clusters
  196.         mov     eax, [ebx+0x5c]         ; Cluster count
  197.         mov     [ebp+exFAT.CLUSTER_COUNT], eax
  198. ; DEBUGF  1, "K : exFAT.CLUSTER_COUNT EAX: %x\n", eax
  199. ;------------------------------------------------------------------------------
  200. ; offset +110 = Either 1 or 2; if TexFAT is supported then it will be 2
  201.         movzx   eax, byte [ebx+0x6e]    ; number of fats
  202.         mov     [ebp+exFAT.NUMBER_OF_FATS], eax
  203. ; DEBUGF  1, "K : exFAT.NUMBER_OF_FATS EAX: %x\n", eax
  204.         mul     [ebp+exFAT.SECTORS_PER_FAT]
  205. ; DEBUGF  1, "K : exFAT.SECTORS_PER_FAT mul EAX: %x\n", eax
  206. ;        test    edx, edx
  207. ;        jnz     .free_return0
  208.         add     eax, [ebp+exFAT.FAT_START]
  209.         jc      .free_return0
  210.  
  211. ;        mov     [ebp+FAT.ROOT_START], eax       ; rootdir = fat_start + fat_size * fat_count
  212. ;        add     eax, [ebp+FAT.ROOT_SECTORS]     ; rootdir sectors should be 0 on fat32
  213. ;        jc      .free_return0
  214.         mov     [ebp+exFAT.DATA_START], eax
  215. ; DEBUGF  1, "K : exFAT.DATA_START EAX: %x\n", eax
  216. ;------------------------------------------------------------------------------
  217. ; offset +72 = Total number of Sectors
  218.         mov     eax, [ebx+0x48+4]         ; total sector count high part
  219.         test    eax, eax
  220.         jnz     .free_return0           ; 32-BIT LIMIT - MODIFY LATER WITY RASP !!!
  221. ; DEBUGF  1, "K : exFAT Total number of Sectors+4 EAX: %x\n", eax
  222.         mov     eax, [ebx+0x48]         ; total sector count low part
  223. ; DEBUGF  1, "K : exFAT Total number of Sectors EAX: %x\n", eax
  224.         cmp     dword [ebp+exFAT.Length+4], 0
  225.         jnz     @f
  226. ; DEBUGF  1, "K : exFAT.Length+4 = 0\n"
  227.         cmp     eax, dword [ebp+exFAT.Length]
  228.         ja      .free_return0
  229. ; DEBUGF  1, "K : exFAT.Length >= Total number of Sectors\n"
  230. @@:
  231.         mov     dword [ebp+exFAT.Length], eax
  232.         and     dword [ebp+exFAT.Length+4], 0
  233.         sub     eax, [ebp+exFAT.DATA_START]       ; eax = count of data sectors
  234.         jc      .free_return0
  235. ; DEBUGF  1, "K : EAX - exFAT.DATA_START EAX: %x\n", eax
  236.         xor     edx, edx
  237.         div     [ebp+exFAT.SECTORS_PER_CLUSTER]
  238.         inc     eax
  239.         mov     [ebp+exFAT.LAST_CLUSTER], eax
  240. ; DEBUGF  1, "K : exFAT.LAST_CLUSTER EAX: %x\n", eax
  241.         dec     eax                     ; cluster count
  242.         jz      .free_return0
  243. ; DEBUGF  1, "K : exFAT.LAST_CLUSTER >= 2 EAX: %x\n",eax
  244.         mov     [ebp+exFAT.fatStartScan], 2
  245. ;        cmp     eax, 0xfff5
  246. ;        jb      .fat16
  247. ;------------------------------------------------------------------------------
  248. ;.fat32:
  249. ;        pusha
  250. ;        lea     esi, [ebx+71]
  251. ;        lea     edi, [ebp+exFAT.volumeLabel]
  252. ;        movsd
  253. ;        movsd
  254. ;        movsd
  255. ;        popa
  256. ;------------------------------------------------------------------------------
  257. ; offset +96 = First cluster of root directory
  258.         mov     eax, [ebx+0x60]         ; rootdir cluster
  259.         mov     [ebp+exFAT.ROOT_CLUSTER], eax
  260. ; DEBUGF  1, "K : exFAT.ROOT_CLUSTER EAX: %x\n", eax
  261.         dec     eax
  262.         dec     eax
  263.         imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER]
  264.         add     eax, [ebp+exFAT.CLUSTER_HEAP_START]
  265.         mov     [ebp+exFAT.ROOT_START], eax
  266. ; DEBUGF  1, "K : exFAT.ROOT_START EAX: %x\n", eax
  267. ;------------------------------------------------------------------------------
  268. ;------------------------------------------------------------------------------
  269. ;        movzx   eax, word [ebx+0x30]
  270. ;        mov     [ebp+FAT.ADR_FSINFO], eax
  271. ;------------------------------------------------------------------------------
  272. ;        push    ebx
  273. ;        add     ebx, 512
  274. ;        call    fs_read32_sys
  275. ;        test    eax, eax
  276. ;        jnz     @f
  277. ;        mov     eax, [ebx+0x1ec]
  278. ;        cmp     eax, -1
  279. ;        jz      @f
  280. ;        mov     [ebp+exFAT.fatStartScan], eax
  281. ;@@:
  282. ;        pop     ebx
  283. ;------------------------------------------------------------------------------
  284.         mov     [ebp+exFAT.fatRESERVED], 0x0FFFFFF6
  285.         mov     [ebp+exFAT.fatBAD], 0x0FFFFFF7
  286.         mov     [ebp+exFAT.fatEND], 0x0FFFFFF8
  287.         mov     [ebp+exFAT.fatMASK], 0x0FFFFFFF
  288. ;------------------------------------------------------------------------------
  289. ;        mov     al, 32
  290. ;.fat_not_12_finalize:
  291. ;        mov     [ebp+FAT.fs_type], al
  292. ;------------------------------------------------------------------------------
  293. ; For FAT16 and FAT32, allocate 512 bytes for FAT cache.
  294.         mov     eax, 512
  295.         call    malloc
  296.         test    eax, eax
  297.         jz      .free_return0
  298.         mov     [ebp+exFAT.fat_cache_ptr], eax
  299. ; DEBUGF  1, "K : malloc exFAT.fat_cache_ptr EAX: %x\n", eax
  300.  
  301.         mov     eax, ebp
  302.         pop     ebp
  303.         ret
  304. ;------------------------------------------------------------------------------
  305. exFAT_free:
  306.         push    eax
  307.         mov     eax, [eax+exFAT.fat_cache_ptr]
  308. ; DEBUGF  1, "K : exFAT_free exFAT.fat_cache_ptr EAX: %x\n", eax
  309.         call    free
  310.         pop     eax
  311.         jmp     free
  312. ;------------------------------------------------------------------------------
  313. exFAT_lock:
  314. ; DEBUGF  1, "K : exFAT_lock \n"
  315.         lea     ecx, [ebp+exFAT.Lock]
  316.         jmp     mutex_lock
  317.  
  318. exFAT_unlock:
  319. ; DEBUGF  1, "K : exFAT_unlock \n"
  320.         lea     ecx, [ebp+exFAT.Lock]
  321.         jmp     mutex_unlock
  322. ;------------------------------------------------------------------------------
  323. exFAT_get_name:
  324.         cmp     byte [edi], 0
  325.         jz      .no
  326. ; DEBUGF  1, "K : exFAT_get_name EDI:%x [EDI]:%x\n", edi, [edi]
  327. ;        push    ebp
  328. ;        mov     ebp,[esp+12+8+4+4+7*4+262*2+4+4]
  329. ; DEBUGF  1, "K : exFAT_get_name START Input FS EBP:%x\n", ebp
  330. ;        pop     ebp
  331. ; in: edi -> FAT entry, esi -> buffer for UTF-16 name
  332. ; out: CF=1 -> no valid entry
  333.         cmp     byte [edi], 0x85 ; File/Folder Directory Entry of ExFAT
  334.         jz      .file_directory_entry
  335.         cmp     byte [edi], 0xC0 ; Stream Extension Directory Entry of ExFAT
  336.         jz      .stream_extension_directory_entry
  337.         cmp     byte [edi], 0xC1 ; File Name Extension Directory Entry of ExFAT
  338.         jz      .longname
  339.         push    edi esi
  340.         xchg    esi, edi
  341. ; DEBUGF  1, "K : exFAT Volume label dword [ESI]: %x\n", [esi]
  342.         cmp     byte [esi], 0x83 ; Indicates that the Volume label exists
  343.         jnz     .no_label
  344. .label:
  345. ; DEBUGF  1, "K : exFAT_get_name.label \n"
  346.         add     esi, 2
  347.         lea     edi, [ebp+exFAT.volumeLabel]
  348.        
  349.         push    ecx
  350.         mov     ecx, 12
  351.         call    UTF16to8_string
  352.         pop     ecx
  353.        
  354. ;        push    edi
  355. ;        lea     edi, [ebp+exFAT.volumeLabel]
  356. ; DEBUGF  1, "K : exFAT Volume label: %s\n", edi
  357. ;        pop     edi
  358. .no_label:
  359. ; DEBUGF  1, "K : exFAT_get_name.no_label \n"
  360.         pop     esi edi
  361. .no:
  362. ; DEBUGF  1, "K : exFAT_get_name.no \n"
  363.         stc
  364.         ret
  365. ;--------------------------------------
  366. .file_directory_entry:
  367.         movzx   eax, byte [edi+1]  ; Number of Secondary directory entries
  368.         dec     eax
  369.         mov     [ebp+exFAT.secondary_dir_entry], eax
  370.         lea     esi, [ebp+exFAT.file_dir_entry]
  371. ; DEBUGF  1, "K : exFAT.file_dir_entry ESI: %x [ESI]: %x\n", esi, [esi]
  372.         jmp     @f
  373. ;--------------------------------------
  374. .stream_extension_directory_entry:
  375.         lea     esi, [ebp+exFAT.str_ext_dir_entry]
  376. ; DEBUGF  1, "K : exFAT.str_ext_dir_entry ESI: %x [ESI]: %x\n", esi, [esi]
  377. @@:
  378.         push    edi
  379.         xchg    esi, edi
  380.         movsd
  381.         movsd
  382.         movsd
  383.         movsd
  384.         movsd
  385.         movsd
  386.         movsd
  387.         movsd
  388.         pop     edi
  389. ;        lea     esi, [esp+20]
  390.  
  391.         mov     esi, [ebp+exFAT.LFN_reserve_place]
  392.         mov     word [esi+260*2], 0     ; force null-terminating for orphans
  393.         jmp     .no
  394. ;--------------------------------------
  395. .longname:
  396. ;        push    ebp
  397. ;        mov     ebp,[esp+12+8+4+4+7*4+262*2+4+4]
  398. ; DEBUGF  1, "K : exFAT_get_name.longname 0 Input FS EBP:%x\n", ebp
  399. ;        pop     ebp
  400. ; DEBUGF  1, "K : exFAT_get_name.longname \n"
  401. ; DEBUGF  1, "K : exFAT_get_name.longname EDI:%x [EDI]:%x ESI:%x [ESI]:%x EBP:%x NAME:%s\n", edi, [edi], esi, [esi], ebp, ebp
  402. ; copy name (15 chars in UTF-16)
  403. ;        mov     word [esi+260*2], 0     ; force null-terminating for orphans
  404.  
  405. ;        push    ebp
  406. ;        mov     ebp,[esp+12+8+4+4+7*4+262*2+4+4]
  407. ; DEBUGF  1, "K : exFAT_get_name.longname Input FS EBP:%x\n", ebp
  408. ;        pop     ebp
  409.        
  410.         push    edi esi
  411.  
  412.         xchg    esi, edi
  413.         add     esi, 2
  414.  
  415.         movsd
  416.         movsd
  417.         movsd
  418.         movsd
  419.         movsd
  420.         movsd
  421.         movsd
  422.         movsw
  423. ; force null-terminating for incomplete name
  424.         xor     eax, eax
  425.         stosw
  426.         pop     esi edi
  427.        
  428. ;        push    ebp
  429. ;        mov     ebp,[esp+12+8+4+4+7*4+262*2+4+4]
  430. ; DEBUGF  1, "K : exFAT_get_name.longname Output FS EBP:%x\n", ebp
  431. ;        pop     ebp
  432.  
  433.         mov     eax, [ebp+exFAT.secondary_dir_entry]
  434.         dec     eax
  435.         mov     [ebp+exFAT.secondary_dir_entry], eax
  436.         jz      @f
  437.         add     esi, 30
  438.         jmp     .no
  439. ;        test    ax, ax
  440. ;        jnz     .no ; if this is not first entry, more processing required
  441. @@:
  442. ;         mov     esi, [ebp+exFAT.LFN_reserve_place]
  443. ; DEBUGF  1, "K : exFAT_get_name.longname END \n"
  444.         ret
  445. ;------------------------------------------------------------------------------
  446. exFAT_entry_to_bdfe:
  447. ; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
  448.         mov     eax, [ebp-4]
  449.         mov     [esi+4], eax    ; cp866/UNICODE name
  450. exFAT_entry_to_bdfe2:
  451. ;        movzx   eax, byte [edi+11]
  452.         movzx   eax, byte [edi+4]
  453.         mov     [esi], eax      ; attributes
  454.  
  455. ;        movzx   eax, word [edi+14]
  456.         movzx   eax, word [edi+8]
  457.         call    fat_time_to_bdfe
  458.         mov     [esi+8], eax    ; creation time
  459.  
  460. ;        movzx   eax, word [edi+16]
  461.         movzx   eax, word [edi+8+2]
  462.         call    fat_date_to_bdfe
  463.         mov     [esi+12], eax   ; creation date
  464.  
  465. ;        and     dword [esi+16], 0       ; last access time is not supported on FAT
  466.         movzx   eax, word [edi+16]
  467.         call    fat_time_to_bdfe
  468.         mov     [esi+16], eax    ; last access time
  469.  
  470. ;        movzx   eax, word [edi+18]
  471.         movzx   eax, word [edi+16+2]
  472.         call    fat_date_to_bdfe
  473.         mov     [esi+20], eax   ; last access date
  474.  
  475. ;        movzx   eax, word [edi+22]
  476.         movzx   eax, word [edi+12]
  477.         call    fat_time_to_bdfe
  478.         mov     [esi+24], eax   ; last write time
  479.  
  480. ;        movzx   eax, word [edi+24]
  481.         movzx   eax, word [edi+12+2]
  482.         call    fat_date_to_bdfe
  483.         mov     [esi+28], eax   ; last write date
  484.  
  485.         mov     al, [esi]
  486.         test    al, 10000b
  487.         jz      .file_size
  488.         xor     eax, eax
  489.         mov     [esi+32], eax   ; file size (low dword)
  490.         mov     [esi+36], eax   ; file size (high dword)
  491.         jmp     @f
  492. .file_size:
  493.         mov     eax, [edi+32+8]
  494.         mov     [esi+32], eax   ; file size (low dword)
  495.         mov     eax, [edi+32+8+4]
  496.         mov     [esi+36], eax   ; file size (high dword)
  497. @@:
  498.         test    ebp, ebp
  499.         jz      .ret
  500. .copy_path:
  501.         add     esi, 40
  502.         push    edi esi
  503.         mov     edi, esi
  504.         mov     esi, ebp
  505.         cmp     byte [ebp-4], 2
  506.         jz      .utf16
  507.         cmp     byte [ebp-4], 3
  508.         jz      .utf8
  509. @@:
  510.         lodsw
  511.         call    uni2ansi_char
  512.         stosb
  513.         test    al, al
  514.         jnz     @b
  515.         pop     esi edi
  516.         add     esi, 264
  517. .ret:
  518. ; DEBUGF  1, "K : exFAT_entry_to_bdfe +264 ESI:%x\n", esi
  519.         ret
  520.  
  521. .utf8:
  522.         push    ecx
  523.         mov     ecx, 519
  524.         call    UTF16to8_string
  525.         pop     ecx
  526.         jmp     @f
  527.  
  528. .utf16:
  529.         lodsw
  530.         stosw
  531.         test    eax, eax
  532.         jnz     .utf16
  533. @@:
  534.         pop     esi edi
  535.         add     esi, 520
  536. ; DEBUGF  1, "K : exFAT_entry_to_bdfe +520 ESI:%x\n", esi
  537.         ret
  538. ;------------------------------------------------------------------------------
  539. exFAT_get_FAT:
  540. ; DEBUGF  1, "K : exFAT_get_FAT \n"
  541. ; in: eax = cluster
  542. ; out: eax = next cluster, CF=1 -> error
  543.         push    ebx esi
  544. ;        cmp     [ebp+FAT.fs_type], 12
  545. ;        je      .FAT12
  546. ;        cmp     [ebp+FAT.fs_type], 16
  547. ;        je      @f
  548. ;        add     eax, eax
  549. ;@@:
  550. ;        add     eax, eax
  551.         shl     eax, 2
  552.         mov     esi, 511
  553.         and     esi, eax
  554.         shr     eax, 9
  555.         add     eax, [ebp+exFAT.FAT_START]
  556.         mov     ebx, [ebp+exFAT.fat_cache_ptr]
  557.         cmp     eax, [ebp+exFAT.fat_in_cache]
  558.         je      .inCache
  559.         cmp     [ebp+exFAT.fat_change], 0
  560.         je      @f
  561. ;        call    write_fat_sector
  562. @@:
  563.         mov     [ebp+exFAT.fat_in_cache], eax
  564.         call    fs_read32_sys
  565.         test    eax, eax
  566.         jnz     .error
  567. .inCache:
  568. ; DEBUGF  1, "K : exFAT_get_FAT.inCache \n"
  569.         mov     eax, [ebx+esi]
  570.         and     eax, [ebp+exFAT.fatMASK]
  571. .ret:
  572.         pop     esi ebx
  573.         ret
  574.  
  575. .error:
  576. ; DEBUGF  1, "K : exFAT_get_FAT.error \n"
  577.         stc
  578.         jmp     .ret
  579. ;------------------------------------------------------------------------------
  580. exFAT_hd_find_lfn:
  581. ; DEBUGF  1, "K : exFAT_hd_find_lfn path ESI: %s\n", esi
  582. ; in: esi -> path string in UTF-8
  583. ; out: CF=1 - file not found, eax=error code
  584. ;      else CF=0 and edi->direntry, eax=sector
  585.         push    esi edi
  586.         push    0
  587.         push    0
  588.         push    exFAT_notroot_first ; 0 ; fat1x_root_first
  589.         push    exFAT_notroot_next ; 0 ; fat1x_root_next
  590.         mov     eax, [ebp+exFAT.ROOT_CLUSTER]
  591. ;        mov     [ebp+exFAT.secondary_dir_entry], dword 1
  592. ;        cmp     [ebp+FAT.fs_type], 32
  593. ;        jz      .fat32
  594.         jmp     @f ; .fat32
  595. .loop:
  596.         and     [ebp+exFAT.longname_sec1], 0
  597.         and     [ebp+exFAT.longname_sec2], 0
  598.  
  599. ;        push    ebp
  600. ;        mov     ebp,[esp+12+8+4+4+7*4]
  601. ; DEBUGF  1, "K : exFAT_find_lfn Input FS EBP:%x\n", ebp
  602. ;        pop     ebp
  603.  
  604.         call    exFAT_find_lfn
  605.  
  606. ;        push    ebp
  607. ;        mov     ebp,[esp+12+8+4+4+7*4]
  608. ; DEBUGF  1, "K : exFAT_find_lfn Output FS EBP:%x\n", ebp
  609. ;        pop     ebp
  610.  
  611.         jc      .notfound
  612. ; DEBUGF  1, "K : exFAT_hd_find_lfn [ESI]: %x\n", [esi]
  613.         cmp     byte [esi], 0
  614.         jz      .found
  615. ;        test    byte [edi+11], 10h
  616.         lea     eax, [ebp+exFAT.file_dir_entry]
  617. ; DEBUGF  1, "K : exFAT_hd_find_lfn exFAT.file_dir_entry [EAX]: %x\n", [eax]
  618.         test    byte [eax+4], 10000b
  619.         jz      .notfound
  620.         and     dword [esp+12], 0
  621. ; this entry’s first cluster number
  622. ;        mov     eax, [edi+20-2]
  623. ;        mov     ax, [edi+26]    ; cluster
  624.         lea     eax, [ebp+exFAT.str_ext_dir_entry]
  625.         mov     eax, [eax+20]    ; cluster
  626. ;.fat32:
  627. @@:
  628. ; DEBUGF  1, "K : exFAT_hd_find_lfn exFAT cluster EAX: %x\n", eax
  629.         mov     [esp+8], eax
  630. ;        mov     dword [esp+4], exFAT_notroot_first ; fat_notroot_first
  631. ;        mov     dword [esp], exFAT_notroot_next ; fat_notroot_next
  632.         jmp     .loop
  633.  
  634. .notfound:
  635. ; DEBUGF  1, "K : exFAT_hd_find_lfn.notfound \n"
  636.         add     esp, 16
  637.         pop     edi esi
  638.         stc
  639.         ret
  640.  
  641. .found:
  642. ; DEBUGF  1, "K : exFAT_hd_find_lfn.found \n"
  643.         lea     eax, [esp+8]
  644.         cmp     dword [eax], 0
  645.         jz      .root
  646.         call    exFAT_get_sector
  647.         jmp     .cmn
  648.  
  649. .root:
  650. ; DEBUGF  1, "K : exFAT_hd_find_lfn.found.root \n"
  651.         mov     eax, [eax+4]
  652.         add     eax, [ebp+exFAT.ROOT_START]
  653. .cmn:
  654. ; DEBUGF  1, "K : exFAT_hd_find_lfn.found.cmn \n"
  655.         add     esp, 20         ; CF=0
  656.         pop     esi
  657.         ret
  658. ;------------------------------------------------------------------------------
  659. exFAT_find_lfn:
  660. ; DEBUGF  1, "K : exFAT_find_lfn \n"
  661. ;   in:
  662. ; esi -> path in UTF-8
  663. ; parameters in the stack
  664. ;   out:
  665. ; esi -> next name in the path
  666. ; edi -> direntry
  667. ; CF=1 -> file not found, eax = error code
  668.         mov     [ebp+exFAT.secondary_dir_entry], dword 1
  669.         lea     eax, [esp+12]
  670.         call    dword [eax-4]
  671.         jc      .reterr
  672.         sub     esp, 262*2      ; reserve place for LFN
  673. ;        lea     eax, [esp]
  674.         mov     eax, esp
  675.         mov     [ebp+exFAT.LFN_reserve_place], eax
  676.         mov     [ebp+exFAT.path_in_UTF8], esi
  677. .l1:
  678. ;        push    esi
  679. ;        lea     esi, [esp+4]
  680. ;        mov     esi, [ebp+exFAT.LFN_reserve_place]
  681. ; DEBUGF  1, "K : exFAT_find_lfn.exFAT_get_name \n"
  682.  
  683. ;        push    ebp
  684. ;        mov     ebp,[esp+12+8+4+4+7*4+262*2+4]
  685. ; DEBUGF  1, "K : exFAT_get_name Input FS EBP:%x\n", ebp
  686. ;        pop     ebp
  687.  
  688.         call    exFAT_get_name
  689. ;        mov     [ebp+exFAT.LFN_reserve_place], esi
  690. ;        pop     esi
  691.  
  692. ;        push    ebp
  693. ;        mov     ebp,[esp+12+8+4+4+7*4+262*2+4]
  694. ; DEBUGF  1, "K : exFAT_get_name Output FS EBP:%x\n", ebp
  695. ;        pop     ebp
  696.  
  697.         jc      .no
  698.  
  699.         push    eax
  700.         xor     eax, eax
  701.         cmp     [ebp+exFAT.secondary_dir_entry], eax
  702.         pop     eax
  703.         jnz     .no
  704.  
  705.         push    edi esi
  706.         mov     esi, [ebp+exFAT.path_in_UTF8]
  707.         lea     edi, [esp+8]
  708. @@:
  709.         call    utf8to16
  710.         call    utf16toUpper
  711.         mov     edx, eax
  712.         mov     ax, [edi]
  713.         call    utf16toUpper
  714.         cmp     ax, dx
  715.         jnz     .done
  716.         add     edi, 2
  717.         test    ax, ax
  718.         jnz     @b
  719.         dec     esi
  720.         pop     eax edi
  721. .found:
  722. ; DEBUGF  1, "K : exFAT_find_lfn.found \n"
  723.         add     esp, 262*2
  724. ; if this is LFN entry, advance to true entry
  725. ;        cmp     byte [edi+11], 0xF
  726. ;        jnz     @f
  727.         xor     eax, eax
  728.         cmp     [ebp+exFAT.secondary_dir_entry], eax
  729.         jz      @f
  730.         lea     eax, [esp+12]
  731.         call    dword[eax-8]
  732.         jc      .reterr
  733. @@:
  734. ; DEBUGF  1, "K : exFAT_find_lfn.OK \n"
  735.         xor     eax, eax
  736.         ret
  737.  
  738. .done:
  739. ; DEBUGF  1, "K : exFAT_find_lfn.done \n"
  740.         cmp     dx, '/'
  741.         jnz     @f
  742.         test    ax, ax
  743.         jnz     @f
  744.         mov     [esp], esi
  745. @@:
  746.         pop     esi edi
  747.         jz      .found
  748. .no:
  749. ; DEBUGF  1, "K : exFAT_find_lfn.no \n"
  750.         lea     eax, [esp+262*2+12]
  751.         call    dword[eax-8]
  752.         jnc     .l1
  753.         add     esp, 262*2
  754. .reterr:
  755. ; DEBUGF  1, "K : exFAT_find_lfn.reterr \n"
  756.         stc
  757.         ret
  758. ;------------------------------------------------------------------------------
  759. exFAT_ReadFile:
  760. ; DEBUGF  1, "K : exFAT_ReadFile \n"
  761. ; DEBUGF  1, "K : exFAT F70 +00: %x\n", [ebx]
  762. ; DEBUGF  1, "K : exFAT F70 +04: %x\n", [ebx+4]
  763. ; DEBUGF  1, "K : exFAT F70 +08: %x\n", [ebx+8]
  764. ; DEBUGF  1, "K : exFAT F70 +12: %x\n", [ebx+12]
  765. ; DEBUGF  1, "K : exFAT F70 +16: %x\n", [ebx+16]
  766. ; DEBUGF  1, "K : exFAT F70 +20: %x\n", [ebx+20]
  767. ; DEBUGF  1, "K : exFAT Path: %s\n", esi
  768.        
  769. ;        push    eax
  770. ;        pushfd
  771. ;        pop     eax
  772. ; DEBUGF  1, "K : eFlags:%x\n",eax
  773. ;        pop     eax
  774. ; DEBUGF  1, "K : EAX:%x EBX:%x ECX:%x EDX:%x\n", eax, ebx, ecx, edx
  775. ; DEBUGF  1, "K : EBP:%x ESI:%x EDI:%x\n", ebp, esi, edi
  776. ;   in:
  777. ; ebx -> parameter structure of sysfunc 70
  778. ; ebp -> exFAT structure
  779. ; esi -> path string in UTF-8
  780. ;   out:
  781. ; eax, ebx = return values for sysfunc 70
  782.         call    exFAT_lock
  783.         call    exFAT_hd_find_lfn
  784.         jc      .notFound
  785. ;        test    byte [edi+11], 0x10     ; do not allow read directories
  786. ;        jnz     .noaccess
  787.         lea     eax, [ebp+exFAT.file_dir_entry]
  788.         test    byte [eax+4], 10000b  ; do not allow read directories
  789.         jnz     .noaccess
  790. ; Rewrite code to work with more than 4 GB files !!!
  791. ;        cmp     dword [ebx+8], 0
  792. ;        jnz     .endOfFile
  793.  
  794.         mov     edx, [ebx+8]    ; file offset high
  795. ; DEBUGF  1, "K : exFAT_ReadFile Hdword file offset EDX:%x\n", edx
  796.         mov     [ebp+exFAT.RDX_high], edx
  797.         mov     edx, [ebx+4]    ; file offset low
  798. ; DEBUGF  1, "K : exFAT_ReadFile Ldword file offset EAX:%x\n", edx
  799.  
  800.         mov     ecx, [ebx+12]   ; size
  801.         mov     ebx, [ebx+16]   ; buffer
  802.         push    ebx
  803.         push    0
  804.         test    ecx, ecx ; read size 0?
  805.         jz      .done
  806.  
  807. ;        mov     eax, [edi+28] ; real file size
  808.         lea     eax, [ebp+exFAT.str_ext_dir_entry]
  809. ; DEBUGF  1, "K : exFAT 0xC0 +00: %x\n", [eax]
  810. ; DEBUGF  1, "K : exFAT 0xC0 +04: %x\n", [eax+4]
  811. ; DEBUGF  1, "K : exFAT 0xC0 +08: %x\n", [eax+8]
  812. ; DEBUGF  1, "K : exFAT 0xC0 +12: %x\n", [eax+12]
  813. ; DEBUGF  1, "K : exFAT 0xC0 +16: %x\n", [eax+16]
  814. ; DEBUGF  1, "K : exFAT 0xC0 +20: %x\n", [eax+20]
  815. ; DEBUGF  1, "K : exFAT 0xC0 +24: %x\n", [eax+24]
  816. ; DEBUGF  1, "K : exFAT 0xC0 +28: %x\n", [eax+28]
  817.         push    eax
  818.         movzx   eax, byte [eax+1]
  819.         mov     [ebp+exFAT.General_Sec_Flags], eax
  820.         pop     eax
  821.  
  822.         push    eax
  823.         mov     eax, [eax+12]    ; high dword of  real file size
  824.         mov     [ebp+exFAT.RAX_high], eax
  825. ; DEBUGF  1, "K : exFAT_ReadFile Hdword file size EAX:%x\n", eax
  826.         pop     eax
  827.  
  828.         mov     eax, [eax+8]    ; low dword of  real file size
  829. ; DEBUGF  1, "K : exFAT_ReadFile Ldword file size EAX:%x\n", eax
  830.  
  831. ;        sub     eax, edx ; low dword file size - file offset low = rest of file
  832. ;        jb      .fileEnd
  833.         sub     eax, edx ; low dword file size - file offset low = rest of file
  834.         push    eax
  835.         mov     eax, [ebp+exFAT.RDX_high]
  836.         sbb     [ebp+exFAT.RAX_high], eax
  837.         pop     eax
  838.         jb      .fileEnd
  839. ; DEBUGF  1, "K : exFAT_ReadFile Hdword rest of file RAX:%x\n", [ebp+exFAT.RAX_high]
  840. ; DEBUGF  1, "K : exFAT_ReadFile Ldword rest of file EAX:%x\n", eax
  841.  
  842.         push    eax
  843.         mov     eax, [ebp+exFAT.RAX_high]
  844.         test    eax, eax
  845.         pop     eax
  846.         jnz     @f
  847.  
  848.         cmp     eax, ecx ; rest of file - requested size
  849.         jae     @f
  850.  
  851. ; DEBUGF  1, "K : exFAT_ReadFile 6=EOF EAX:%x ECX:%x EDX:%x\n", eax, ecx, edx
  852.         mov     ecx, eax
  853.         mov     byte [esp], 6 ; 6 = end of file, EOF
  854. @@:
  855.         lea     eax, [ebp+exFAT.str_ext_dir_entry]
  856.         mov     eax, [eax+20]    ; cluster
  857. ; DEBUGF  1, "K : exFAT EAX:%x EBX:%x ECX:%x EDX:%x\n", eax, ebx, ecx, edx
  858. ; now eax=cluster, ebx=buffer for data, ecx=count, edx=position
  859.         mov     edi, [ebp+exFAT.SECTORS_PER_CLUSTER]
  860.         shl     edi, 9  ; bytes per cluster
  861. @@:
  862.         cmp     eax, 2
  863.         jb      .fileEnd
  864. .continue_1:
  865.         cmp     eax, [ebp+exFAT.fatRESERVED]
  866.         jae     .fileEnd
  867.  
  868.         push    eax
  869.         xor     eax, eax
  870.         sub     edx, edi ; file_offset_low - bytes per cluster
  871.         sbb     [ebp+exFAT.RDX_high], eax
  872.         pop     eax
  873.         jc      @f
  874.  
  875. ;        push    edi
  876. ;        lea     edi, [ebp+exFAT.file_dir_entry]
  877. ; Check - General Secondary Flags
  878. ; Bit 0 : Allocation possible
  879. ;         0 – No cluster allocated; 1 – cluster allocation is possible
  880. ; Bit 1 : No FAT chain
  881. ;         0 – Yes ; The clusters of this file/directory are NOT contiguous
  882. ;         1 – No; The Contiguous Cluster are allocated to this file/directory;
  883. ;         This improves the File read performance
  884. ; Bits 2 – 7 : Reserved
  885. ;        test    byte [edi+1], 11b
  886. ;        pop     edi
  887.         test    byte [ebp+exFAT.General_Sec_Flags], 11b
  888.         jz      .get_FAT_1
  889.         inc     eax
  890.         jmp     .continue_1
  891. .get_FAT_1:
  892.  
  893.         call    exFAT_get_FAT
  894.         jc      .noaccess2
  895.  
  896.         jmp     @b
  897.  
  898. .notFound:
  899. ; DEBUGF  1, "K : exFAT_ReadFile.notFound: \n"
  900.         push    eax
  901.         jmp     .ret
  902.  
  903. .noaccess:
  904. ; DEBUGF  1, "K : exFAT_ReadFile.noaccess \n"
  905.         push    ERROR_ACCESS_DENIED
  906.         jmp     .ret
  907.  
  908. .endOfFile:
  909. ; DEBUGF  1, "K : exFAT_ReadFile.endOfFile \n"
  910.         push    ERROR_END_OF_FILE
  911. .ret:
  912.         call    exFAT_unlock
  913.         pop     eax
  914.         xor     ebx, ebx
  915. ; DEBUGF  1, "K : exFAT_ReadFile Return EBX:%x\n", ebx
  916.         ret
  917.  
  918. @@:
  919. ; DEBUGF  1, "K : exFAT_ReadFile CONTINUE cluster EAX:%x\n", eax
  920.         mov     esi, eax
  921.         dec     eax
  922.         dec     eax
  923.  
  924.         push    ebx edx
  925.         xor     edx, edx
  926. ; DEBUGF  1, "K : exFAT_ReadFile IMUL in EDX:%x EAX:%x\n", EDX, eax
  927.         imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER] ; Sector edx:eax
  928. ; DEBUGF  1, "K : exFAT_ReadFile IMUL out EDX:%x EAX:%x\n", EDX, eax
  929.         xor     ebx, ebx
  930.         add     eax, [ebp+exFAT.CLUSTER_HEAP_START]
  931.         adc     edx, ebx
  932.         mov     [ebp+exFAT.RAX_high], edx
  933.         pop     edx ebx
  934. ; DEBUGF  1, "K : exFAT_ReadFile start sector RAX_H:%x EAX:%x RDX_H:%x EDX:%x EDI:%x\n", [ebp+exFAT.RAX_high], eax, [ebp+exFAT.RDX_high], edx, edi
  935.         push    eax
  936.         xor     eax, eax
  937.         add     edx, edi ; file offset low + bytes per cluster
  938.         adc     [ebp+exFAT.RDX_high], eax
  939.         pop     eax
  940.  
  941.         test    edx, edx
  942.         jz      .alignedCluster
  943.  
  944.         mov     edi, edx ; file offset low
  945.         push    eax
  946.         mov     eax, [ebp+exFAT.RDX_high]
  947.         mov     [ebp+exFAT.RDI_high], eax
  948.         pop     eax
  949.  
  950. ;        shr     edi, 9
  951.         push    ebx
  952.         mov     ebx, [ebp+exFAT.RDI_high]
  953.         shrd    edi, ebx, 5 ; /32
  954.         shr     ebx, 5 ; /32
  955.         shrd    edi, ebx, 4 ; /16
  956.         shr     ebx, 4 ; /16
  957.         mov     [ebp+exFAT.RDI_high], ebx
  958.         pop     ebx
  959.  
  960.         add     eax, edi ; RFile_start_sector_low - file_sector_offset_low
  961.         push    ebx
  962.         mov     ebx, [ebp+exFAT.RDI_high]
  963.         adc     [ebp+exFAT.RAX_high], ebx
  964.         pop     ebx
  965.  
  966.         and     edx, 511
  967.         and     dword [ebp+exFAT.RDX_high], 0
  968.  
  969.         cmp     ecx, 512
  970.         jc      .sectorPiece
  971.         test    edx, edx
  972.         jz      .alignedSector
  973. .sectorPiece:
  974. ; DEBUGF  1, "K : exFAT_ReadFile.sectorPiece \n"
  975.         push    eax ebx ecx edx
  976.         lea     ebx, [ebp+exFAT.buffer]
  977.         mov     edx, [ebp+exFAT.RAX_high]
  978.         xor     ecx, ecx
  979.         inc     ecx
  980. ; DEBUGF  1, "K : exFAT fs_read64_app EDX:%x EAX:%x ECX:%x EBX:%x EBP:%x\n", edx, eax, ecx, ebx, ebp
  981. ;        call    fs_read32_app
  982.         call    fs_read64_app
  983. ; DEBUGF  1, "K : exFAT fs_read64_app Output EAX:%x ECX:%x EBX:%x\n", eax, ecx, ebx
  984.         test    eax, eax
  985. ;        lea     eax, [ebp+exFAT.buffer]
  986.         mov     eax, ebx ; exFAT.buffer
  987.         pop     edx ecx ebx
  988.         jne     .noaccess3
  989. ; DEBUGF  1, "K : exFAT_ReadFile memmove(-1) EAX:%x EBX:%x ECX:%x EDX:%x\n", eax, ebx, ecx, edx
  990.         add     eax, edx ; exFAT.buffer + offset within a sector
  991.         push    ecx
  992.         add     ecx, edx ; requested size + offset within a sector
  993.         cmp     ecx, 512
  994.         jbe     @f
  995.         mov     ecx, 512
  996. @@:
  997.         sub     ecx, edx ; requested size - offset within a sector
  998. ; DEBUGF  1, "K : exFAT_ReadFile memmove EAX:%x EBX:%x ECX:%x\n", eax, ebx, ecx
  999. ; eax = from
  1000. ; ebx = to
  1001. ; ecx = no of bytes
  1002.         call    memmove
  1003. ; DEBUGF  1, "K : exFAT_ReadFile memmove(1) EAX:%x EBX:%x ECX:%x\n", eax, ebx, ecx
  1004.         sub     [esp], ecx
  1005.         add     ebx, ecx
  1006. ; DEBUGF  1, "K : exFAT_ReadFile memmove(2) EAX:%x EBX:%x ECX:%x\n", eax, ebx, ecx
  1007.         pop     ecx eax
  1008.         xor     edx, edx
  1009. ;        inc     edi ; file_sector_offset_low
  1010.         push    eax
  1011.         xor     eax, eax
  1012.         add     edi, 1 ; you cannot use INC EDI for qword!!!
  1013.         adc     [ebp+exFAT.RDI_high], eax
  1014.         pop     eax
  1015. ;        inc     eax ; RFile_start_sector_low
  1016.         push    ebx
  1017.         xor     ebx, ebx
  1018.         add     eax, 1 ; you cannot use INC EAX for qword!!!
  1019.         adc     [ebp+exFAT.RAX_high], ebx
  1020.         pop     ebx
  1021.         test    ecx, ecx
  1022.         jz      .done
  1023. .alignedSector:
  1024. ; DEBUGF  1, "K : exFAT_ReadFile.alignedSector \n"
  1025. ;        shl     edi, 9 ; RFile_start_sector_low * 512
  1026.         push    ebx
  1027.         mov     ebx, [ebp+exFAT.RDI_high]
  1028.         shld    ebx, edi, 5 ; *32
  1029.         shl     edi, 5 ; *32
  1030.         shld    ebx, edi, 4 ; *16
  1031.         shl     edi, 4 ; *16
  1032.         mov     [ebp+exFAT.RDI_high], ebx
  1033.         pop     ebx
  1034.  
  1035.         push    ebx
  1036.         xor     ebx, ebx
  1037.         mov     [ebp+exFAT.RCX_high], ebx
  1038.         add     ecx, edi ; requested size  + file_offset_low
  1039.         mov     ebx, [ebp+exFAT.RDI_high]
  1040.         adc     [ebp+exFAT.RCX_high], ebx
  1041.         pop     ebx
  1042.  
  1043.         xor     edi, edi
  1044.         mov     [ebp+exFAT.RDI_high], edi
  1045.         mov     edi, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1046.         shl     edi, 9  ; bytes per cluster
  1047. .alignedCluster:
  1048. ; DEBUGF  1, "K : exFAT_ReadFile.alignedCluster RAX_H:%x EAX:%x RDX_H:%x EDX:%x EDI:%x\n", [ebp+exFAT.RAX_high], eax, [ebp+exFAT.RDX_high], edx, edi
  1049.         cmp     ecx, 512
  1050.         jc      .sectorPiece
  1051.         mov     edx, [ebp+exFAT.RAX_high]
  1052.         mov     [ebp+exFAT.RDX_high], edx
  1053.         mov     edx, eax ; edx << RFile_start_sector_low
  1054.  
  1055.         xor     eax, eax
  1056.         mov     [ebp+exFAT.RAX_high], eax
  1057.         mov     eax, esi ; eax << cluster
  1058. @@:
  1059.         push    eax
  1060.         xor     eax, eax
  1061.         sub     ecx, edi ; requested size low - bytes per cluster
  1062.         sbb     [ebp+exFAT.RCX_high], eax
  1063.         pop     eax
  1064.         jbe     .readEnd
  1065.        
  1066. ;        push    edi
  1067. ;        lea     edi, [ebp+exFAT.file_dir_entry]
  1068. ; Check - General Secondary Flags
  1069. ; Bit 0 : Allocation possible
  1070. ;         0 – No cluster allocated; 1 – cluster allocation is possible
  1071. ; Bit 1 : No FAT chain
  1072. ;         0 – Yes ; The clusters of this file/directory are NOT contiguous
  1073. ;         1 – No; The Contiguous Cluster are allocated to this file/directory;
  1074. ;         This improves the File read performance
  1075. ; Bits 2 – 7 : Reserved
  1076. ;        test    byte [edi+1], 11b
  1077. ;        pop     edi
  1078.         test    byte [ebp+exFAT.General_Sec_Flags], 11b
  1079.         jz      .get_FAT
  1080.         inc     eax ; inc cluster
  1081.         jmp     .continue
  1082. .get_FAT:
  1083. ; DEBUGF  1, "K : exFAT_ReadFile.get_FAT \n"
  1084.         call    exFAT_get_FAT
  1085.         jc      .noaccess4
  1086.         cmp     eax, 2
  1087.         jb      .fileEnd2
  1088. .continue:
  1089. ; DEBUGF  1, "K : exFAT_ReadFile.continue \n"
  1090.         cmp     eax, [ebp+exFAT.fatRESERVED]
  1091.         jae     .fileEnd2
  1092.  
  1093.         inc     esi ; inc cluster
  1094.         cmp     eax, esi
  1095.         jz      @b
  1096. .fragmentEnd:
  1097. ; DEBUGF  1, "K : exFAT_ReadFile.fragmentEnd \n"
  1098.         xchg    eax, esi
  1099.         dec     eax
  1100.         dec     eax
  1101.  
  1102.         push    ebx edx
  1103.         xor     edx, edx
  1104.         imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER] ; Sector edx:eax
  1105.         xor     ebx, ebx
  1106.         add     eax, [ebp+exFAT.CLUSTER_HEAP_START]
  1107.         adc     edx, ebx
  1108.         mov     [ebp+exFAT.RAX_high], edx
  1109.         pop     edx ebx
  1110.        
  1111.         push    dword [ebp+exFAT.RCX_high]
  1112.         push    ecx ; requested size low
  1113.        
  1114.         mov     ecx, [ebp+exFAT.RAX_high]
  1115.         mov     [ebp+exFAT.RCX_high], ecx
  1116.         mov     ecx, eax ; ecx << RFile_start_sector_low
  1117.        
  1118.         xor     eax, eax
  1119.         mov     [ebp+exFAT.RAX_high], eax
  1120.         mov     eax, esi ; eax << custer
  1121.  
  1122.         dec     eax
  1123.         dec     eax
  1124.  
  1125.         push    ebx edx
  1126.         xor     edx, edx
  1127.         imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER] ; Sector edx:eax
  1128.         xor     ebx, ebx
  1129.         add     eax, [ebp+exFAT.CLUSTER_HEAP_START]
  1130.         adc     edx, ebx
  1131.         mov     [ebp+exFAT.RAX_high], edx
  1132.         pop     edx ebx
  1133.  
  1134.         push    dword [ebp+exFAT.RAX_high]
  1135.         push    eax
  1136. .readFragment:
  1137. ; DEBUGF  1, "K : exFAT_ReadFile.readFragment \n"
  1138.         push    eax
  1139.         mov     eax, [ebp+exFAT.RDX_high]
  1140.         sub     ecx, edx ; RFile_start_sector_low - RFile_start_sector_low
  1141.         sbb     [ebp+exFAT.RCX_high], eax
  1142.         pop     eax
  1143.  
  1144.         mov     eax, edx
  1145. ;        xor     edx, edx
  1146.         mov     edx, [ebp+exFAT.RDX_high]
  1147.  
  1148. ; DEBUGF  1, "K : exFAT fs_read64_app EDX:%x EAX:%x ECX:%x EBX:%x EBP:%x\n", edx, eax, ecx, ebx, ebp
  1149.         call    fs_read64_app
  1150. ; DEBUGF  1, "K : exFAT fs_read64_app Output EAX:%x ECX:%x EBX:%x\n", eax, ecx, ebx
  1151. ;        shl     ecx, 9
  1152.         push    ebx
  1153.         mov     ebx, [ebp+exFAT.RCX_high]
  1154.         shld    ebx, ecx, 5 ; *32
  1155.         shl     ecx, 5 ; *32
  1156.         shld    ebx, ecx, 4 ; *16
  1157.         shl     ecx, 4 ; *16
  1158.         mov     [ebp+exFAT.RCX_high], ebx
  1159.         pop     ebx
  1160.  
  1161.         add     ebx, ecx
  1162.  
  1163.         test    eax, eax
  1164.         pop     eax
  1165.         pop     dword [ebp+exFAT.RAX_high]
  1166.         jnz     .noaccess3
  1167.         pop     ecx
  1168.         pop     dword [ebp+exFAT.RCX_high]
  1169.         xor     edx, edx
  1170.         mov     [ebp+exFAT.RDX_high], edx
  1171.         jecxz   .done_1
  1172.         jmp     .alignedCluster
  1173. .done_1:
  1174.         jmp     .done
  1175.  
  1176. .readEnd:
  1177. ; DEBUGF  1, "K : exFAT_ReadFile.readEnd \n"
  1178.         push    ebx
  1179.         add     ecx, edi ; requested size  + bytes per cluster
  1180.         mov     ebx, [ebp+exFAT.RDI_high]
  1181.         adc     [ebp+exFAT.RCX_high], ebx
  1182.         pop     ebx
  1183.  
  1184.         mov     edi, [ebp+exFAT.RCX_high]
  1185.         mov     [ebp+exFAT.RDI_high], edi
  1186.         mov     edi, ecx
  1187.  
  1188.         and     ecx, 511
  1189.         and     dword [ebp+exFAT.RCX_high], 0
  1190. ;        shr     edi, 9
  1191.         push    ebx
  1192.         mov     ebx, [ebp+exFAT.RDI_high]
  1193.         shrd    edi, ebx, 5 ; /32
  1194.         shr     ebx, 5 ; /32
  1195.         shrd    edi, ebx, 4 ; /16
  1196.         shr     ebx, 4 ; /16
  1197.         mov     [ebp+exFAT.RDI_high], ebx
  1198.         pop     ebx
  1199.  
  1200.         dec     eax
  1201.         dec     eax
  1202.  
  1203.         push    ebx edx
  1204.         xor     edx, edx
  1205.         imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER] ; Sector edx:eax
  1206.         xor     ebx, ebx
  1207.         add     eax, [ebp+exFAT.CLUSTER_HEAP_START]
  1208.         adc     edx, ebx
  1209.         mov     [ebp+exFAT.RAX_high], edx
  1210.         pop     edx ebx
  1211.  
  1212.         add     eax, edi ; RFile_start_sector_low - file_sector_offset_low
  1213.         push    ebx
  1214.         mov     ebx, [ebp+exFAT.RDI_high]
  1215.         adc     [ebp+exFAT.RAX_high], ebx
  1216.         pop     ebx
  1217.  
  1218.         push    dword [ebp+exFAT.RCX_high]
  1219.         push    ecx
  1220.  
  1221.         push    dword [ebp+exFAT.RAX_high]
  1222.         push    eax
  1223.  
  1224.         mov     ecx, [ebp+exFAT.RAX_high]
  1225.         mov     [ebp+exFAT.RCX_high], ecx
  1226.         mov     ecx, eax
  1227.         jmp     .readFragment
  1228.  
  1229. .noaccess3:
  1230. ; DEBUGF  1, "K : exFAT_ReadFile.noaccess3 \n"
  1231.         pop     eax
  1232.         pop     dword [ebp+exFAT.RAX_high]
  1233. .noaccess2:
  1234. ; DEBUGF  1, "K : exFAT_ReadFile.noaccess2 \n"
  1235.         mov     byte [esp], ERROR_DEVICE
  1236. .done:
  1237. ; DEBUGF  1, "K : exFAT_ReadFile.done \n"
  1238.         call    exFAT_unlock
  1239.         pop     eax edx
  1240.         sub     ebx, edx
  1241. ; DEBUGF  1, "K : exFAT_ReadFile Return EBX:%x\n", ebx
  1242.            
  1243. ;        push    eax
  1244. ;        pushfd
  1245. ;        pop     eax
  1246. ; DEBUGF  1, "K : eFlags:%x\n",eax
  1247. ;        pop     eax
  1248. ; DEBUGF  1, "K : EAX:%x EBX:%x ECX:%x EDX:%x\n", eax, ebx, ecx, edx
  1249. ; DEBUGF  1, "K : EBP:%x ESI:%x EDI:%x\n", ebp, esi, edi
  1250.         ret
  1251.  
  1252. .fileEnd:
  1253. ; DEBUGF  1, "K : exFAT_ReadFile.fileEnd \n"
  1254.         mov     byte [esp], ERROR_END_OF_FILE
  1255.         jmp     .done
  1256.  
  1257. .noaccess4:
  1258. ; DEBUGF  1, "K : exFAT_ReadFile.noaccess4 \n"
  1259.         mov     byte [esp], ERROR_DEVICE
  1260.         jmp     @f
  1261.  
  1262. .fileEnd2:
  1263. ; DEBUGF  1, "K : exFAT_ReadFile.fileEnd2 \n"
  1264.         mov     byte [esp], ERROR_END_OF_FILE
  1265. @@:
  1266.         inc     esi
  1267.         xor     ecx, ecx
  1268.         mov     [ebp+exFAT.RCX_high], ecx
  1269.         jmp     .fragmentEnd
  1270. ;------------------------------------------------------------------------------
  1271. exFAT_ReadFolder:
  1272. ; DEBUGF  1, "K : exFAT_ReadFolder \n"
  1273. ; DEBUGF  1, "K : exFAT F70 +00: %x\n", [ebx]
  1274. ; DEBUGF  1, "K : exFAT F70 +04: %x\n", [ebx+4]
  1275. ; DEBUGF  1, "K : exFAT F70 +08: %x\n", [ebx+8]
  1276. ; DEBUGF  1, "K : exFAT F70 +12: %x\n", [ebx+12]
  1277. ; DEBUGF  1, "K : exFAT F70 +16: %x\n", [ebx+16]
  1278. ; DEBUGF  1, "K : exFAT F70 +20: %x\n", [ebx+20]
  1279. ; DEBUGF  1, "K : exFAT Path: %s\n", esi
  1280. ;        push    eax
  1281. ;        pushfd
  1282. ;        pop     eax
  1283. ; DEBUGF  1, "K : eFlags:%x\n",eax
  1284. ;        pop     eax
  1285. ; DEBUGF  1, "K : EAX:%x EBX:%x ECX:%x EDX:%x\n", eax, ebx, ecx, edx
  1286. ; DEBUGF  1, "K : EBP:%x ESI:%x EDI:%x\n", ebp, esi, edi
  1287. ;   in:
  1288. ; ebx -> parameter structure of sysfunc 70
  1289. ; ebp -> exFAT structure
  1290. ; esi -> path string in UTF-8
  1291. ;   out:
  1292. ; eax, ebx = return values for sysfunc 70
  1293.         call    exFAT_lock
  1294.         xor     eax, eax
  1295.         mov     [ebp+exFAT.General_Sec_Flags], eax
  1296.         mov     eax, [ebp+exFAT.ROOT_CLUSTER]
  1297. ; DEBUGF  1, "K : exFAT.ROOT_CLUSTER: %x\n", eax
  1298.         cmp     byte [esi], 0
  1299.         jz      .doit
  1300.        
  1301. ;        push    ebp
  1302. ;        mov     ebp,[esp+12+8+4+4]
  1303. ; DEBUGF  1, "K : exFAT Input FS EBP:%x\n", ebp
  1304. ;        pop     ebp
  1305.  
  1306.         call    exFAT_hd_find_lfn
  1307.  
  1308. ;        push    ebp
  1309. ;        mov     ebp,[esp+12+8+4+4]
  1310. ; DEBUGF  1, "K : exFAT Output FS EBP:%x\n", ebp
  1311. ;        pop     ebp
  1312.  
  1313.         jc      .error
  1314. ;        jmp     .error
  1315. ;        test    byte [edi+11], 0x10     ; do not allow read files
  1316. ;        jz      .accessDenied
  1317.         lea     eax, [ebp+exFAT.file_dir_entry]
  1318.         test    byte [eax+4], 10000b  ; do not allow read files
  1319.         jz      .accessDenied
  1320. ;        mov     eax, [edi+20-2]
  1321. ;        mov     ax, [edi+26]    ; eax=cluster
  1322.         lea     eax, [ebp+exFAT.str_ext_dir_entry]
  1323.         push    eax
  1324.         movzx   eax, byte [eax+1]
  1325.         mov     [ebp+exFAT.General_Sec_Flags], eax
  1326.         mov     eax, [esp]
  1327.         mov     eax, [eax+8] ; LOW dword of Valid data length - WARNING!!! late rewrite
  1328.         mov     [ebp+exFAT.valid_data_length], eax
  1329.         pop     eax
  1330.         mov     eax, [eax+20]    ; cluster
  1331.         jmp     .doit_1
  1332. .doit:
  1333.         mov     dword [ebp+exFAT.valid_data_length], 0xffffffff ; for ROOT
  1334. .doit_1:
  1335. ; DEBUGF  1, "K : exFAT.valid_data_length %x\n", [ebp+exFAT.valid_data_length]
  1336. ; DEBUGF  1, "K : exFAT_ReadFolder.doit \n"
  1337.         sub     esp, 262*2      ; reserve space for LFN
  1338.         push    dword [ebx+8]   ; cp866/UNICODE name
  1339.         mov     edx, [ebx+16]   ; pointer to buffer
  1340. ; init header
  1341.         push    eax
  1342.         mov     edi, edx
  1343.         mov     ecx, 32/4
  1344.         xor     eax, eax
  1345.         rep stosd
  1346.         pop     eax
  1347.         mov     byte [edx], 1   ; version
  1348. ;        mov     esi, edi        ; esi points to BDFE
  1349.         mov     [ebp+exFAT.points_to_BDFE], edi
  1350. ; DEBUGF  1, "K : exFAT.points_to_BDFE start EDI: %x\n", edi
  1351.         mov     ecx, [ebx+12]   ; number of blocks to read
  1352.         mov     ebx, [ebx+4]    ; index of the first block
  1353. ;------------------------------------------------------------------------------
  1354. ; DEBUGF  1, "K : exFAT_ReadFolder 1 ECX: %x\n", ecx
  1355.         cmp     [ebp+exFAT.valid_data_length], 0xffffffff
  1356.         je      .num_read_blocks
  1357.         inc     dword [edx+8]   ; new file found
  1358.         test    ecx, ecx
  1359.         jz      .num_read_blocks
  1360.         test    ebx, ebx
  1361.         jnz     .dec_offset
  1362. ; DEBUGF  1, "K : exFAT_ReadFolder create .. dir \n"
  1363.         inc     dword [edx+4]   ; new file block copied
  1364.         push    eax esi
  1365.         mov     esi, edi ; [ebp+exFAT.points_to_BDFE]
  1366.         mov     [esi], dword 0x10      ; attributes
  1367.         xor     eax, eax
  1368.         mov     [esi+8], eax    ; creation time
  1369.         mov     [esi+12], dword 0x010101 ; eax   ; creation date
  1370.         mov     [esi+16], eax    ; last access time
  1371.         mov     [esi+20], dword 0x020202 ;eax   ; last access date
  1372.         mov     [esi+24], eax   ; last write time
  1373.         mov     [esi+28], dword 0x010303 ; eax   ; last write date
  1374.         mov     [esi+32], eax   ; file size (low dword)
  1375.         mov     [esi+36], eax   ; file size (high dword)
  1376.         push    ebp
  1377.         lea     ebp, [esp+4+12]
  1378. ; DEBUGF  1, "K : exFAT_ReadFolder 1 ESI: %x EBP: %x\n", esi, ebp
  1379. ; DEBUGF  1, "K : exFAT_ReadFolder old file [EBP-4]: %x [EBP]: %x [EBP+4]: %x [EBP+8]: %x\n", [ebp-4], [ebp], [ebp+4], [ebp+8]
  1380.         mov     eax, [ebp-4]
  1381.         mov     [esi+4], eax    ; cp866/UNICODE name
  1382.         mov     [ebp], dword 0x002e002e ; imitate dir '..'
  1383.         xor     eax, eax
  1384.         mov     [ebp+4], eax
  1385.         call    exFAT_entry_to_bdfe2.copy_path
  1386.         pop     ebp
  1387.         mov     [ebp+exFAT.points_to_BDFE], esi
  1388. ; DEBUGF  1, "K : exFAT_ReadFolder 2 ESI: %x EBP: %x\n", esi, ebp
  1389.         pop     esi eax
  1390.         dec     ecx
  1391.         jmp     .num_read_blocks
  1392. .dec_offset:
  1393.         dec     ebx
  1394. .num_read_blocks:
  1395. ; DEBUGF  1, "K : exFAT_ReadFolder 2 ECX: %x\n", ecx
  1396. ;------------------------------------------------------------------------------
  1397.         lea     esi, [esp+4]    ; buffer for UTF-16 name (space for LFN)
  1398.         mov     [ebp+exFAT.LFN_reserve_place], esi
  1399. ;        push    eax
  1400. ;        dec     eax
  1401. ;        dec     eax
  1402. ;        imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1403. ;        add     eax, [ebp+exFAT.CLUSTER_HEAP_START]
  1404. ; DEBUGF  1, "K : exFAT ROOT SECTOR: %x\n", eax
  1405. ;        pop     eax
  1406.         mov     [ebp+exFAT.secondary_dir_entry], dword 1
  1407. .new_cluster:
  1408. ; DEBUGF  1, "K : exFAT_ReadFolder.new_cluster \n"
  1409.         mov     [ebp+exFAT.cluster_tmp], eax
  1410.         test    eax, eax
  1411. ;        jz      .notfound
  1412.         jnz     @f
  1413.         jmp     .notfound
  1414. @@:
  1415.         dec     eax
  1416.         dec     eax
  1417.         imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1418.         push    [ebp+exFAT.SECTORS_PER_CLUSTER]
  1419.         add     eax, [ebp+exFAT.CLUSTER_HEAP_START]
  1420.         push    ebx
  1421. .new_sector:
  1422. ; DEBUGF  1, "K : exFAT_ReadFolder.new_sector \n"
  1423.         lea     ebx, [ebp+exFAT.buffer]
  1424.         mov     edi, ebx
  1425.         push    eax
  1426. ; DEBUGF  1, "K : exFAT fs_read32_sys N1 EAX: %x\n", eax
  1427.         call    fs_read32_sys
  1428.         test    eax, eax
  1429.         pop     eax
  1430.         jnz     .notfound2
  1431.         add     ebx, 512
  1432.         push    eax
  1433. .l1:
  1434. ; DEBUGF  1, "K : exFAT_ReadFolder.l1 \n"
  1435. ;        push    esi
  1436. ;        lea     esi, [esp+20]
  1437.         call    exFAT_get_name
  1438. ;        pop     esi
  1439.         jc      .l2
  1440. ;        cmp     byte [edi], 0xC1 ; File Name Extension Directory Entry of ExFAT
  1441. ;        jnz     .do_bdfe
  1442.         xor     eax, eax
  1443.         cmp     [ebp+exFAT.secondary_dir_entry], eax
  1444.         jz      .do_bdfe
  1445. ;        add     edi, 0x20
  1446. ; DEBUGF  1, "K : exFAT_ReadFolder.do_bdfe EDI: %x  EBX: %x\n", edi, ebx
  1447. ; DEBUGF  1, "K : exFAT_ReadFolder.do_bdfe EDI:%x [EDI]:%x NAME:%s\n", edi, [edi], edi
  1448.         cmp     edi, ebx
  1449.         jb      .do_bdfe
  1450.         pop     eax
  1451.         inc     eax
  1452.         dec     dword [esp+4]
  1453.         jnz     @f
  1454.         mov     eax, [ebp+exFAT.cluster_tmp]
  1455.         test    eax, eax
  1456.         jz      .done
  1457. ; Check - General Secondary Flags
  1458. ; Bit 0 : Allocation possible
  1459. ;         0 – No cluster allocated; 1 – cluster allocation is possible
  1460. ; Bit 1 : No FAT chain
  1461. ;         0 – Yes ; The clusters of this file/directory are NOT contiguous
  1462. ;         1 – No; The Contiguous Cluster are allocated to this file/directory;
  1463. ;         This improves the File read performance
  1464. ; Bits 2 – 7 : Reserved
  1465.         test    byte [ebp+exFAT.General_Sec_Flags], 11b
  1466.         jz      .get_FAT_1
  1467.         inc     eax
  1468.         jmp     .continue_1
  1469. .get_FAT_1:
  1470. ; DEBUGF  1, "K : exFAT_ReadFolder N1 exFAT_get_FAT Input EAX: %x\n", eax
  1471.         call    exFAT_get_FAT
  1472. ; DEBUGF  1, "K : exFAT_ReadFolder N1 exFAT_get_FAT Output EAX: %x\n", eax
  1473.         jc      .notfound2
  1474.         cmp     eax, 2
  1475.         jb      .done
  1476. .continue_1:
  1477.         cmp     eax, [ebp+exFAT.fatRESERVED]
  1478.         jae     .done
  1479.         push    eax
  1480.         mov     eax, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1481.         mov     [esp+8], eax
  1482.         pop     eax
  1483.         mov     [ebp+exFAT.cluster_tmp], eax
  1484.         dec     eax
  1485.         dec     eax
  1486.         imul    eax, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1487.         add     eax, [ebp+exFAT.DATA_START]
  1488. @@:
  1489. ; DEBUGF  1, "K : exFAT_ReadFolder.@@ \n"
  1490.         lea     ebx, [ebp+exFAT.buffer]
  1491.         mov     edi, ebx
  1492.         push    eax
  1493. ; DEBUGF  1, "K : exFAT fs_read32_sys N2 EAX: %x\n", eax
  1494.         call    fs_read32_sys
  1495.         test    eax, eax
  1496.         pop     eax
  1497.         jnz     .notfound2
  1498.         add     ebx, 512
  1499.         push    eax
  1500. .do_bdfe:
  1501. ; DEBUGF  1, "K : exFAT_ReadFolder.do_bdfe \n"
  1502.         inc     dword [edx+8]   ; new file found
  1503.         dec     dword [esp+4]
  1504.         jns     .l2
  1505. ; DEBUGF  1, "K : exFAT_ReadFolder.do_bdfe ECX: %x\n", ecx
  1506.         dec     ecx
  1507.         js      .l2
  1508.         inc     dword [edx+4]   ; new file block copied
  1509.         push    esi edi
  1510.         mov     esi, [ebp+exFAT.points_to_BDFE]
  1511.         lea     edi, [ebp+exFAT.file_dir_entry]
  1512.         push    ebp
  1513.         lea     ebp, [esp+20+4+4]
  1514. ; DEBUGF  1, "K : exFAT_ReadFolder ESI: %x EBP: %x\n", esi, ebp
  1515. ; DEBUGF  1, "K : exFAT_ReadFolder.do_bdfe EDI:%x [EDI]:%x ESI:%x [ESI]:%x EBP:%x NAME:%s\n",  edi, [edi], esi, [esi], ebp, ebp
  1516.         call    exFAT_entry_to_bdfe
  1517.         pop     ebp
  1518.         mov     [ebp+exFAT.points_to_BDFE], esi
  1519.         pop     edi esi
  1520. .l2:
  1521. ; DEBUGF  1, "K : exFAT_ReadFolder.l2 \n"
  1522.         add     edi, 0x20
  1523. ; DEBUGF  1, "K : exFAT_ReadFolder.do_bdfe EDI: %x  EBX: %x\n", edi, ebx
  1524.         cmp     edi, ebx
  1525.         jb      .l1
  1526.         pop     eax
  1527.         inc     eax
  1528.         dec     dword [esp+4]
  1529.         jnz     .new_sector
  1530.         mov     eax, [ebp+exFAT.cluster_tmp]
  1531.         test    eax, eax
  1532.         jz      .done
  1533.  
  1534.         push    eax
  1535.         mov     eax, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1536.         shl     eax, 9
  1537.         sub     [ebp+exFAT.valid_data_length], eax
  1538.         pop     eax
  1539.         jbe     .done
  1540. ; Check - General Secondary Flags
  1541. ; Bit 0 : Allocation possible
  1542. ;         0 – No cluster allocated; 1 – cluster allocation is possible
  1543. ; Bit 1 : No FAT chain
  1544. ;         0 – Yes ; The clusters of this file/directory are NOT contiguous
  1545. ;         1 – No; The Contiguous Cluster are allocated to this file/directory;
  1546. ;         This improves the File read performance
  1547. ; Bits 2 – 7 : Reserved
  1548.         test    byte [ebp+exFAT.General_Sec_Flags], 11b
  1549.         jz      .get_FAT
  1550.         inc     eax
  1551.         jmp     .continue
  1552. .get_FAT:
  1553. ; DEBUGF  1, "K : exFAT_ReadFolder N2 exFAT_get_FAT Input EAX: %x\n", eax
  1554.         call    exFAT_get_FAT
  1555. ; DEBUGF  1, "K : exFAT_ReadFolder N2 exFAT_get_FAT Output EAX: %x\n", eax
  1556.         jc      .notfound2
  1557.         cmp     eax, 2
  1558.         jb      .done
  1559. .continue:
  1560.         cmp     eax, [ebp+exFAT.fatRESERVED]
  1561.         jae     .done
  1562.         push    eax
  1563.         mov     eax, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1564.         mov     [esp+8], eax
  1565.         pop     eax
  1566.         pop     ebx
  1567.         add     esp, 4
  1568.         jmp     .new_cluster
  1569. ;------------------------------------------------------------------------------
  1570. .notfound2:
  1571. ; DEBUGF  1, "K : exFAT_ReadFolder.notfound2 \n"
  1572.         add     esp, 8
  1573. .notfound:
  1574. ; DEBUGF  1, "K : exFAT_ReadFolder.notfound \n"
  1575.         add     esp, 262*2+4
  1576. ; DEBUGF  1, "K : exFAT_ReadFolder.ERROR_DEVICE \n"
  1577.         push    ERROR_DEVICE
  1578.         jmp     @f
  1579. ;------------------------------------------------------------------------------
  1580. .done:
  1581. ; DEBUGF  1, "K : exFAT_ReadFolder.done \n"
  1582. ; DEBUGF  1, "K : exFAT_ReadFolder TotalBloks: %x\n", [edx+8]
  1583. ; DEBUGF  1, "K : exFAT_ReadFolder Read Bloks: %x\n", [edx+4]
  1584.         add     esp, 262*2+12
  1585.         pushd   0
  1586. ; DEBUGF  1, "K : exFAT_ReadFolder.done ECX: %x\n", ecx
  1587.         dec     ecx
  1588.         js      @f
  1589. ; DEBUGF  1, "K : exFAT_ReadFolder.ERROR_END_OF_FILE \n"
  1590.         mov     byte [esp], ERROR_END_OF_FILE
  1591. @@:
  1592.         mov     ebx, [edx+4]
  1593. ;------------------------------------------------------------------------------
  1594. .ret:
  1595. ; DEBUGF  1, "K : exFAT_ReadFolder.ret \n"
  1596. ; DEBUGF  1, "K : exFAT_ReadFile Return ESI:%x\n", esi
  1597.         call    exFAT_unlock
  1598.         pop     eax
  1599. ; DEBUGF  1, "K : exFAT_ReadFile Return EBX:%x\n", ebx
  1600. ;        mov     esi, [ebp+exFAT.LFN_reserve_place]
  1601. ;        push    eax
  1602. ;        pushfd
  1603. ;        pop     eax
  1604. ; DEBUGF  1, "K : eFlags:%x\n",eax
  1605. ;        pop     eax
  1606. ; DEBUGF  1, "K : EAX:%x EBX:%x ECX:%x EDX:%x\n", eax, ebx, ecx, edx
  1607. ; DEBUGF  1, "K : EBP:%x ESI:%x EDI:%x\n", ebp, esi, edi
  1608.         ret
  1609. ;------------------------------------------------------------------------------
  1610. .error:
  1611. ; DEBUGF  1, "K : exFAT_ReadFolder.error \n"
  1612.         push    eax
  1613.         xor     ebx, ebx
  1614.         jmp     .ret
  1615. ;------------------------------------------------------------------------------
  1616. .accessDenied:
  1617. ; DEBUGF  1, "K : exFAT_ReadFolder.ERROR_ACCESS_DENIED \n"
  1618.         push    ERROR_ACCESS_DENIED
  1619.         xor     ebx, ebx
  1620.         jmp     .ret
  1621. ;------------------------------------------------------------------------------
  1622. exFAT_GetFileInfo:
  1623. ; DEBUGF  1, "K : exFAT_GetFileInfo \n"
  1624.         cmp     byte [esi], 0
  1625.         jz      .volume
  1626.         call    exFAT_lock
  1627.         call    exFAT_hd_find_lfn
  1628.         jc      @f
  1629.         lea     edi, [ebp+exFAT.file_dir_entry]
  1630.         push    ebp
  1631.         xor     ebp, ebp
  1632.         mov     esi, [ebx+16]
  1633.         mov     dword [esi+4], ebp
  1634.         call    exFAT_entry_to_bdfe2
  1635.         pop     ebp
  1636.         xor     eax, eax
  1637. @@:
  1638.         push    eax
  1639.         call    exFAT_unlock
  1640.         pop     eax
  1641. @@:
  1642.         ret
  1643.  
  1644. .volume:
  1645. ; DEBUGF  1, "K : exFAT_GetFileInfo.volume \n"
  1646.         mov     eax, dword[ebp+exFAT.Length]
  1647.         mov     edx, dword[ebp+exFAT.Length+4]
  1648.         mov     edi, [ebx+16]
  1649.         shld    edx, eax, 9
  1650.         shl     eax, 9
  1651.         mov     [edi+36], edx
  1652.         mov     [edi+32], eax
  1653.         mov     eax, [ebx+8]
  1654.         mov     byte [edi], 8
  1655.         mov     [edi+4], eax
  1656.         test    eax, eax
  1657.         jz      @b
  1658.         lea     esi, [ebp+exFAT.volumeLabel]
  1659.         mov     ecx, 11
  1660. @@:
  1661.         mov     byte [esi+ecx], 0
  1662.         dec     ecx
  1663.         jz      @f
  1664.         cmp     byte [esi+ecx], ' '
  1665.         jz      @b
  1666. @@:
  1667.         mov     cl, 12
  1668.         add     edi, 40
  1669.         cmp     eax, 2
  1670.         jz      @f
  1671.         rep movsb
  1672.         xor     eax, eax
  1673.         ret
  1674.  
  1675. @@:
  1676.         lodsb
  1677.         stosw
  1678.         loop    @b
  1679.         ret
  1680. ;------------------------------------------------------------------------------
  1681. exFAT_notroot_next:
  1682. ; DEBUGF  1, "K : exFAT_notroot_next \n"
  1683.         push    ecx
  1684.         lea     ecx, [ebp+exFAT.buffer+0x200-0x20]
  1685.         cmp     edi, ecx
  1686.         jae     exFAT_notroot_next_sector
  1687.         add     edi, 0x20
  1688. @@:
  1689.         pop     ecx
  1690.         ret
  1691.  
  1692. ;exFAT_notroot_next_write:
  1693. ;        push    ecx
  1694. ;        lea     ecx, [ebp+exFAT.buffer+0x200]
  1695. ;        cmp     edi, ecx
  1696. ;        jc      @b
  1697. ;        push    eax
  1698. ;        call    exFAT_notroot_end_write
  1699. ;        pop     eax
  1700. exFAT_notroot_next_sector:
  1701.         push    [ebp+exFAT.longname_sec2]
  1702.         pop     [ebp+exFAT.longname_sec1]
  1703.         push    eax
  1704. ; DEBUGF  1, "K : exFAT_notroot_next.exFAT_get_sector In EAX:%x\n", eax
  1705.         call    exFAT_get_sector
  1706. ; DEBUGF  1, "K : exFAT_notroot_next.exFAT_get_sector Out EAX:%x\n", eax
  1707.         mov     [ebp+exFAT.longname_sec2], eax
  1708.         pop     eax
  1709.         mov     ecx, [eax+4]
  1710.         inc     ecx
  1711.         cmp     ecx, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1712.         jae     exFAT_notroot_next_cluster
  1713.         mov     [eax+4], ecx
  1714.         jmp     @f
  1715.  
  1716. exFAT_notroot_next_err:
  1717. ;        dec     ecx
  1718.         pop     ecx
  1719. ;        js      .1
  1720.         movi    eax, ERROR_FILE_NOT_FOUND
  1721. ;.1:
  1722.         stc
  1723.         ret
  1724.  
  1725. exFAT_notroot_next_cluster:
  1726.         push    eax
  1727.         mov     eax, [eax]
  1728.  
  1729.         push    edi
  1730.         lea     edi, [ebp+exFAT.str_ext_dir_entry]
  1731. ; Check - General Secondary Flags
  1732. ; Bit 0 : Allocation possible
  1733. ;         0 – No cluster allocated; 1 – cluster allocation is possible
  1734. ; Bit 1 : No FAT chain
  1735. ;         0 – Yes ; The clusters of this file/directory are NOT contiguous
  1736. ;         1 – No; The Contiguous Cluster are allocated to this file/directory;
  1737. ;         This improves the File read performance
  1738. ; Bits 2 – 7 : Reserved
  1739.         test    byte [edi+1], 11b
  1740.         pop     edi
  1741.         jz      .get_FAT
  1742.         inc     eax
  1743.         jmp     .continue
  1744. .get_FAT:
  1745.         call    exFAT_get_FAT
  1746. .continue:
  1747.         mov     ecx, eax
  1748.         pop     eax
  1749.         jc      exFAT_notroot_first.deverr
  1750.         cmp     ecx, 2
  1751.         jb      exFAT_notroot_next_err
  1752.         cmp     ecx, [ebp+exFAT.fatRESERVED]
  1753.         jae     exFAT_notroot_next_err
  1754.         mov     [eax], ecx
  1755.         and     dword [eax+4], 0
  1756. @@:
  1757.         pop     ecx
  1758. exFAT_notroot_first:
  1759. ; DEBUGF  1, "K : exFAT_notroot_first \n"
  1760. ; DEBUGF  1, "K : exFAT_notroot_first.exFAT_get_sector In EAX:%x\n", eax
  1761.         call    exFAT_get_sector
  1762. ; DEBUGF  1, "K : exFAT_notroot_first.exFAT_get_sector Out EAX:%x\n", eax
  1763.         push    ebx
  1764.         lea     edi, [ebp+exFAT.buffer]
  1765.         mov     ebx, edi
  1766.         call    fs_read32_sys
  1767.         pop     ebx
  1768.         test    eax, eax
  1769.         jz      .ret ; CF=0
  1770.         push    ecx
  1771. .deverr:
  1772.         pop     ecx
  1773.         mov     eax, ERROR_DEVICE
  1774.         stc
  1775. .ret:
  1776.         ret
  1777.  
  1778. ;fat_notroot_begin_write:
  1779. ;        push    eax edi
  1780. ;        call    fat_notroot_first
  1781. ;        pop     edi eax
  1782. ;        ret
  1783.  
  1784. ;fat_notroot_end_write:
  1785. ;        call    fat_get_sector
  1786. ;        push    ebx
  1787. ;        lea     ebx, [ebp+FAT.buffer]
  1788. ;        call    fs_write32_sys
  1789. ;        pop     ebx
  1790. ;        ret
  1791. ;--------------------------------------
  1792. exFAT_get_sector:
  1793.         push    ecx
  1794.         mov     ecx, [eax]
  1795. ; DEBUGF  1, "K : exFAT_get_sector In [EAX]:%x [EAX+4]:%x\n", ecx, [eax+4]
  1796.         dec     ecx
  1797.         dec     ecx
  1798.         imul    ecx, [ebp+exFAT.SECTORS_PER_CLUSTER]
  1799. ;        add     ecx, [ebp+exFAT.DATA_START]
  1800.         add     ecx, [ebp+exFAT.CLUSTER_HEAP_START]
  1801.         add     ecx, [eax+4]
  1802.         mov     eax, ecx
  1803.         pop     ecx
  1804.         ret
  1805. ;------------------------------------------------------------------------------