Subversion Repositories Kolibri OS

Rev

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