Subversion Repositories Kolibri OS

Rev

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