Subversion Repositories Kolibri OS

Rev

Rev 9738 | Rev 9755 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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