Subversion Repositories Kolibri OS

Rev

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