Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3742 clevermous 3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 3742 $
9
 
3742 clevermous 10
struct NTFS PARTITION
11
Lock                    MUTEX ?    ; currently operations with one partition
12
                                   ; can not be executed in parallel since the
13
                                   ; legacy code is not ready; this mutex guards
14
                                   ; all operations
15
sectors_per_cluster     dd      ?
16
mft_cluster             dd      ?
17
mftmirr_cluster         dd      ?
18
frs_size                dd      ?       ; FRS size in bytes
19
iab_size                dd      ?       ; IndexAllocationBuffer size in bytes
20
frs_buffer              dd      ?
21
iab_buffer              dd      ?
22
mft_retrieval           dd      ?
23
mft_retrieval_size      dd      ?
24
mft_retrieval_alloc     dd      ?
25
mft_retrieval_end       dd      ?
26
cur_index_size          dd      ?
27
cur_index_buf           dd      ?
2288 clevermous 28
 
3742 clevermous 29
ntfs_cur_attr   dd      ?
30
ntfs_cur_iRecord dd     ?
31
ntfs_cur_offs   dd      ?       ; in sectors
32
ntfs_cur_size   dd      ?       ; in sectors
33
ntfs_cur_buf    dd      ?
34
ntfs_cur_read   dd      ?       ; [output]
35
ntfs_bCanContinue db    ?
36
                rb      3
37
 
38
cur_subnode_size        dd      ?
39
ntfs_attr_iRecord       dd      ?
40
ntfs_attr_iBaseRecord   dd      ?
41
ntfs_attr_offs          dd      ?
42
ntfs_attr_list          dd      ?
43
ntfs_attr_size          dq      ?
44
ntfs_cur_tail           dd      ?
45
 
46
ntfs_attrlist_buf       rb      0x400
47
ntfs_attrlist_mft_buf   rb      0x400
48
ntfs_bitmap_buf         rb      0x400
49
ends
50
 
51
iglobal
52
align 4
53
ntfs_user_functions:
54
        dd      ntfs_free
55
        dd      (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
56
        dd      ntfs_Read
57
        dd      ntfs_ReadFolder
58
        dd      ntfs_Rewrite
59
        dd      ntfs_Write
60
        dd      ntfs_SetFileEnd
61
        dd      ntfs_GetFileInfo
62
        dd      ntfs_SetFileInfo
63
        dd      0
64
        dd      ntfs_Delete
65
        dd      ntfs_CreateFolder
66
ntfs_user_functions_end:
67
endg
68
 
2288 clevermous 69
ntfs_test_bootsec:
70
; in: ebx->buffer, edx=size of partition
71
; out: CF set <=> invalid
72
; 1. Name=='NTFS    '
73
        cmp     dword [ebx+3], 'NTFS'
74
        jnz     .no
75
        cmp     dword [ebx+7], '    '
76
        jnz     .no
77
; 2. Number of bytes per sector is the same as for physical device
78
; (that is, 0x200 for hard disk)
79
        cmp     word [ebx+11], 0x200
80
        jnz     .no
81
; 3. Number of sectors per cluster must be power of 2
82
        movzx   eax, byte [ebx+13]
83
        dec     eax
84
        js      .no
85
        test    al, [ebx+13]
86
        jnz     .no
87
; 4. FAT parameters must be zero
88
        cmp     word [ebx+14], 0
89
        jnz     .no
90
        cmp     dword [ebx+16], 0
91
        jnz     .no
92
        cmp     byte [ebx+20], 0
93
        jnz     .no
94
        cmp     word [ebx+22], 0
95
        jnz     .no
96
        cmp     dword [ebx+32], 0
97
        jnz     .no
98
; 5. Number of sectors <= partition size
99
        cmp     dword [ebx+0x2C], 0
100
        ja      .no
101
        cmp     [ebx+0x28], edx
102
        ja      .no
103
; 6. $MFT and $MFTMirr clusters must be within partition
104
        cmp     dword [ebx+0x34], 0
105
        ja      .no
106
        push    edx
107
        movzx   eax, byte [ebx+13]
108
        mul     dword [ebx+0x30]
109
        test    edx, edx
110
        pop     edx
111
        jnz     .no
112
        cmp     eax, edx
113
        ja      .no
114
        cmp     dword [ebx+0x3C], 0
115
        ja      .no
116
        push    edx
117
        movzx   eax, byte [ebx+13]
118
        mul     dword [ebx+0x38]
119
        test    edx, edx
120
        pop     edx
121
        jnz     .no
122
        cmp     eax, edx
123
        ja      .no
124
; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2
125
        movsx   eax, byte [ebx+0x40]
126
        cmp     al, -31
127
        jl      .no
128
        cmp     al, -9
129
        jle     @f
130
        dec     eax
131
        js      .no
132
        test    [ebx+0x40], al
133
        jnz     .no
134
@@:
135
; 8. Same for clusters per IndexAllocationBuffer
136
        movsx   eax, byte [ebx+0x44]
137
        cmp     al, -31
138
        jl      .no
139
        cmp     al, -9
140
        jle     @f
141
        dec     eax
142
        js      .no
143
        test    [ebx+0x44], al
144
        jnz     .no
145
@@:
146
; OK, this is correct NTFS bootsector
147
        clc
148
        ret
149
.no:
150
; No, this bootsector isn't NTFS
151
        stc
152
        ret
153
 
3742 clevermous 154
proc ntfs_create_partition
155
        mov     edx, dword [ebp+PARTITION.Length]
156
        cmp     dword [esp+4], 0
157
        jz      .boot_read_ok
158
        add     ebx, 512
159
        lea     eax, [edx-1]
160
        call    fs_read32_sys
161
        test    eax, eax
162
        jnz     @f
163
        call    ntfs_test_bootsec
164
        jnc     .ntfs_setup
165
@@:
166
        mov     eax, edx
167
        shr     eax, 1
168
        call    fs_read32_sys
169
        test    eax, eax
170
        jnz     .nope                   ; no chance...
171
.boot_read_ok:
172
        call    ntfs_test_bootsec
173
        jnc     .ntfs_setup
174
.nope:
175
        xor     eax, eax
176
        jmp     .exit
177
 
178
.ntfs_setup:
2288 clevermous 179
; By given bootsector, initialize some NTFS variables
3742 clevermous 180
        movi    eax, sizeof.NTFS
181
        call    malloc
182
        test    eax, eax
183
        jz      .exit
184
        mov     ecx, dword [ebp+PARTITION.FirstSector]
185
        mov     dword [eax+NTFS.FirstSector], ecx
186
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
187
        mov     dword [eax+NTFS.FirstSector+4], ecx
188
        mov     ecx, dword [ebp+PARTITION.Length]
189
        mov     dword [eax+NTFS.Length], ecx
190
        mov     ecx, dword [ebp+PARTITION.Length+4]
191
        mov     dword [eax+NTFS.Length+4], ecx
192
        mov     ecx, [ebp+PARTITION.Disk]
193
        mov     [eax+NTFS.Disk], ecx
194
        mov     [eax+NTFS.FSUserFunctions], ntfs_user_functions
195
        push    ebx ebp esi
196
        mov     ebp, eax
197
 
198
        lea     ecx, [ebp+NTFS.Lock]
199
        call    mutex_init
200
 
2288 clevermous 201
        movzx   eax, byte [ebx+13]
3742 clevermous 202
        mov     [ebp+NTFS.sectors_per_cluster], eax
2288 clevermous 203
        mov     eax, [ebx+0x28]
3742 clevermous 204
        mov     dword [ebp+NTFS.Length], eax
205
        and     dword [ebp+NTFS.Length+4], 0
2288 clevermous 206
        mov     eax, [ebx+0x30]
3742 clevermous 207
        mov     [ebp+NTFS.mft_cluster], eax
2288 clevermous 208
        mov     eax, [ebx+0x38]
3742 clevermous 209
        mov     [ebp+NTFS.mftmirr_cluster], eax
2288 clevermous 210
        movsx   eax, byte [ebx+0x40]
211
        test    eax, eax
212
        js      .1
3742 clevermous 213
        mul     [ebp+NTFS.sectors_per_cluster]
2288 clevermous 214
        shl     eax, 9
215
        jmp     .2
216
.1:
217
        neg     eax
218
        mov     ecx, eax
219
        mov     eax, 1
220
        shl     eax, cl
221
.2:
3742 clevermous 222
        mov     [ebp+NTFS.frs_size], eax
2288 clevermous 223
        movsx   eax, byte [ebx+0x44]
224
        test    eax, eax
225
        js      .3
3742 clevermous 226
        mul     [ebp+NTFS.sectors_per_cluster]
2288 clevermous 227
        shl     eax, 9
228
        jmp     .4
229
.3:
230
        neg     eax
231
        mov     ecx, eax
232
        mov     eax, 1
233
        shl     eax, cl
234
.4:
3742 clevermous 235
        mov     [ebp+NTFS.iab_size], eax
2288 clevermous 236
; allocate space for buffers
3742 clevermous 237
        add     eax, [ebp+NTFS.frs_size]
2288 clevermous 238
        push    eax
239
        call    kernel_alloc
240
        test    eax, eax
3742 clevermous 241
        jz      .fail_free
242
        mov     [ebp+NTFS.frs_buffer], eax
243
        add     eax, [ebp+NTFS.frs_size]
244
        mov     [ebp+NTFS.iab_buffer], eax
2288 clevermous 245
; read $MFT disposition
3742 clevermous 246
        mov     eax, [ebp+NTFS.mft_cluster]
247
        mul     [ebp+NTFS.sectors_per_cluster]
2288 clevermous 248
        call    ntfs_read_frs_sector
3742 clevermous 249
        test    eax, eax
2288 clevermous 250
        jnz     .usemirr
251
        cmp     dword [ebx], 'FILE'
252
        jnz     .usemirr
253
        call    ntfs_restore_usa_frs
254
        jnc     .mftok
255
.usemirr:
3742 clevermous 256
        mov     eax, [ebp+NTFS.mftmirr_cluster]
257
        mul     [ebp+NTFS.sectors_per_cluster]
2288 clevermous 258
        call    ntfs_read_frs_sector
3742 clevermous 259
        test    eax, eax
2288 clevermous 260
        jnz     @f
261
        cmp     dword [ebx], 'FILE'
262
        jnz     @f
263
        call    ntfs_restore_usa_frs
264
        jnc     .mftok
265
@@:
266
; $MFT and $MFTMirr invalid!
267
.fail_free_frs:
3742 clevermous 268
        push    [ebp+NTFS.frs_buffer]
2288 clevermous 269
        call    kernel_free
3742 clevermous 270
.fail_free:
271
        mov     eax, ebp
272
        call    free
273
        xor     eax, eax
274
.pop_exit:
275
        pop     esi ebp ebx
276
.exit:
277
        cmp     dword [esp+4], 0
278
        jz      @f
279
        sub     ebx, 512
280
@@:
281
        ret
2288 clevermous 282
.fail_free_mft:
3742 clevermous 283
        push    [ebp+NTFS.mft_retrieval]
2288 clevermous 284
        call    kernel_free
285
        jmp     .fail_free_frs
286
.mftok:
287
; read $MFT table retrieval information
288
; start with one page, increase if not enough (when MFT too fragmented)
289
        push    ebx
290
        push    0x1000
291
        call    kernel_alloc
292
        pop     ebx
293
        test    eax, eax
294
        jz      .fail_free_frs
3742 clevermous 295
        mov     [ebp+NTFS.mft_retrieval], eax
296
        and     [ebp+NTFS.mft_retrieval_size], 0
297
        mov     [ebp+NTFS.mft_retrieval_alloc], 0x1000/8
2288 clevermous 298
; $MFT base record must contain unnamed non-resident $DATA attribute
299
        movzx   eax, word [ebx+14h]
300
        add     eax, ebx
301
.scandata:
302
        cmp     dword [eax], -1
303
        jz      .fail_free_mft
304
        cmp     dword [eax], 0x80
305
        jnz     @f
306
        cmp     byte [eax+9], 0
307
        jz      .founddata
308
@@:
309
        add     eax, [eax+4]
310
        jmp     .scandata
311
.founddata:
312
        cmp     byte [eax+8], 0
313
        jz      .fail_free_mft
314
; load first portion of $DATA attribute retrieval information
315
        mov     edx, [eax+0x18]
3742 clevermous 316
        mov     [ebp+NTFS.mft_retrieval_end], edx
2288 clevermous 317
        mov     esi, eax
318
        movzx   eax, word [eax+0x20]
319
        add     esi, eax
320
        sub     esp, 10h
321
.scanmcb:
322
        call    ntfs_decode_mcb_entry
323
        jnc     .scanmcbend
324
        call    .get_mft_retrieval_ptr
325
        mov     edx, [esp]      ; block length
326
        mov     [eax], edx
327
        mov     edx, [esp+8]    ; block addr (relative)
328
        mov     [eax+4], edx
3742 clevermous 329
        inc     [ebp+NTFS.mft_retrieval_size]
2288 clevermous 330
        jmp     .scanmcb
331
.scanmcbend:
332
        add     esp, 10h
333
; there may be other portions of $DATA attribute in auxiliary records;
334
; if they will be needed, they will be loaded later
335
 
3742 clevermous 336
        mov     [ebp+NTFS.cur_index_size], 0x1000/0x200
2288 clevermous 337
        push    0x1000
338
        call    kernel_alloc
339
        test    eax, eax
340
        jz      .fail_free_mft
3742 clevermous 341
        mov     [ebp+NTFS.cur_index_buf], eax
2288 clevermous 342
 
3742 clevermous 343
        mov     eax, ebp
344
        jmp     .pop_exit
345
endp
2288 clevermous 346
 
347
.get_mft_retrieval_ptr:
348
        pushad
3742 clevermous 349
        mov     eax, [ebp+NTFS.mft_retrieval_size]
350
        cmp     eax, [ebp+NTFS.mft_retrieval_alloc]
2288 clevermous 351
        jnz     .ok
352
        add     eax, 0x1000/8
3742 clevermous 353
        mov     [ebp+NTFS.mft_retrieval_alloc], eax
2288 clevermous 354
        shl     eax, 3
355
        push    eax
356
        call    kernel_alloc
357
        test    eax, eax
358
        jnz     @f
359
        popad
360
        add     esp, 14h
361
        jmp     .fail_free_mft
362
@@:
3742 clevermous 363
        mov     esi, [ebp+NTFS.mft_retrieval]
2288 clevermous 364
        mov     edi, eax
3742 clevermous 365
        mov     ecx, [ebp+NTFS.mft_retrieval_size]
2288 clevermous 366
        add     ecx, ecx
367
        rep movsd
3742 clevermous 368
        push    [ebp+NTFS.mft_retrieval]
369
        mov     [ebp+NTFS.mft_retrieval], eax
2288 clevermous 370
        call    kernel_free
3742 clevermous 371
        mov     eax, [ebp+NTFS.mft_retrieval_size]
2288 clevermous 372
.ok:
373
        shl     eax, 3
3742 clevermous 374
        add     eax, [ebp+NTFS.mft_retrieval]
2288 clevermous 375
        mov     [esp+28], eax
376
        popad
377
        ret
378
 
3742 clevermous 379
proc ntfs_free
380
        push    ebx
381
        xchg    ebx, eax
382
        stdcall kernel_free, [ebx+NTFS.frs_buffer]
383
        stdcall kernel_free, [ebx+NTFS.mft_retrieval]
384
        stdcall kernel_free, [ebx+NTFS.cur_index_buf]
385
        xchg    ebx, eax
386
        call    free
387
        pop     ebx
388
        ret
389
endp
390
 
391
proc ntfs_lock
392
        lea     ecx, [ebp+NTFS.Lock]
393
        jmp     mutex_lock
394
endp
395
 
396
proc ntfs_unlock
397
        lea     ecx, [ebp+NTFS.Lock]
398
        jmp     mutex_unlock
399
endp
400
 
2288 clevermous 401
ntfs_read_frs_sector:
3742 clevermous 402
        push    ecx
403
        mov     ebx, [ebp+NTFS.frs_buffer]
404
        push    ebx
405
        mov     ecx, [ebp+NTFS.frs_size]
2288 clevermous 406
        shr     ecx, 9
3742 clevermous 407
        push    ecx
408
        mov     ecx, eax
2288 clevermous 409
@@:
3742 clevermous 410
        mov     eax, ecx
411
        call    fs_read32_sys
412
        test    eax, eax
2288 clevermous 413
        jnz     .fail
414
        add     ebx, 0x200
3742 clevermous 415
        inc     ecx
416
        dec     dword [esp]
417
        jnz     @b
418
        pop     eax
2288 clevermous 419
.fail:
420
        pop     ebx
3742 clevermous 421
        pop     ecx
2288 clevermous 422
        ret
423
 
424
ntfs_read_attr:
3742 clevermous 425
; in: variables in ebp+NTFS.*
426
; out: [ebp+NTFS.ntfs_cur_read]
427
; out: CF=1 => notfound, in this case eax=0 => disk ok, otherwise eax=disk error code
428
        xor     eax, eax
2288 clevermous 429
        pushad
3742 clevermous 430
        and     [ebp+NTFS.ntfs_cur_read], 0
431
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
2288 clevermous 432
        jnz     .nomft
3742 clevermous 433
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
2288 clevermous 434
        jnz     .nomft
3742 clevermous 435
        mov     eax, [ebp+NTFS.mft_retrieval_end]
2288 clevermous 436
        inc     eax
3742 clevermous 437
        mul     [ebp+NTFS.sectors_per_cluster]
438
        cmp     eax, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 439
        jbe     .nomft
440
; precalculated part of $Mft $DATA
3742 clevermous 441
        mov     esi, [ebp+NTFS.mft_retrieval]
442
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 443
        xor     edx, edx
3742 clevermous 444
        div     [ebp+NTFS.sectors_per_cluster]
2288 clevermous 445
; eax = VCN, edx = offset in sectors from beginning of cluster
446
        xor     ecx, ecx        ; ecx will contain LCN
447
.mftscan:
448
        add     ecx, [esi+4]
449
        sub     eax, [esi]
450
        jb      @f
451
        add     esi, 8
452
        push    eax
3742 clevermous 453
        mov     eax, [ebp+NTFS.mft_retrieval_end]
2288 clevermous 454
        shl     eax, 3
3742 clevermous 455
        add     eax, [ebp+NTFS.mft_retrieval]
2288 clevermous 456
        cmp     eax, esi
457
        pop     eax
458
        jnz     .mftscan
459
        jmp     .nomft
460
@@:
461
        push    ecx
462
        add     ecx, eax
463
        add     ecx, [esi]
464
        push    eax
465
        push    edx
3742 clevermous 466
        mov     eax, [ebp+NTFS.sectors_per_cluster]
2288 clevermous 467
        mul     ecx
468
; eax = sector on partition
469
        pop     edx
470
        add     eax, edx
3742 clevermous 471
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
2288 clevermous 472
        pop     ecx
473
        neg     ecx
3742 clevermous 474
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
2288 clevermous 475
        sub     ecx, edx
3742 clevermous 476
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
2288 clevermous 477
        jb      @f
3742 clevermous 478
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
2288 clevermous 479
@@:
480
; ecx = number of sequential sectors to read
3742 clevermous 481
        push    eax
482
        call    fs_read32_sys
483
        pop     edx
484
        test    eax, eax
2288 clevermous 485
        jnz     .errread
3742 clevermous 486
        add     [ebp+NTFS.ntfs_cur_read], 0x200
487
        dec     [ebp+NTFS.ntfs_cur_size]
488
        inc     [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 489
        add     ebx, 0x200
3742 clevermous 490
        mov     [ebp+NTFS.ntfs_cur_buf], ebx
491
        lea     eax, [edx+1]
2288 clevermous 492
        loop    @b
493
        pop     ecx
494
        xor     eax, eax
495
        xor     edx, edx
3742 clevermous 496
        cmp     [ebp+NTFS.ntfs_cur_size], eax
2288 clevermous 497
        jz      @f
498
        add     esi, 8
499
        push    eax
3742 clevermous 500
        mov     eax, [ebp+NTFS.mft_retrieval_end]
2288 clevermous 501
        shl     eax, 3
3742 clevermous 502
        add     eax, [ebp+NTFS.mft_retrieval]
2288 clevermous 503
        cmp     eax, esi
504
        pop     eax
505
        jz      .nomft
506
        jmp     .mftscan
507
@@:
508
        popad
509
        ret
510
.errread:
511
        pop     ecx
512
.errret:
3742 clevermous 513
        mov     [esp+28], eax
2288 clevermous 514
        stc
515
        popad
516
        ret
517
.nomft:
518
; 1. Read file record.
519
; N.B. This will do recursive call of read_attr for $MFT::$Data.
3742 clevermous 520
        mov     eax, [ebp+NTFS.ntfs_cur_iRecord]
521
        mov     [ebp+NTFS.ntfs_attr_iRecord], eax
522
        and     [ebp+NTFS.ntfs_attr_list], 0
523
        or      dword [ebp+NTFS.ntfs_attr_size], -1
524
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
525
        or      [ebp+NTFS.ntfs_attr_iBaseRecord], -1
2288 clevermous 526
        call    ntfs_read_file_record
3742 clevermous 527
        jc      .errret
2288 clevermous 528
; 2. Find required attribute.
3742 clevermous 529
        mov     eax, [ebp+NTFS.frs_buffer]
2288 clevermous 530
; a) For auxiliary records, read base record
531
; N.B. If base record is present,
532
;      base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero
533
        cmp     dword [eax+24h], 0
534
        jz      @f
535
        mov     eax, [eax+20h]
536
;        test    eax, eax
537
;        jz      @f
538
.beginfindattr:
3742 clevermous 539
        mov     [ebp+NTFS.ntfs_attr_iRecord], eax
2288 clevermous 540
        call    ntfs_read_file_record
3742 clevermous 541
        jc      .errret
2288 clevermous 542
@@:
543
; b) Scan for required attribute and for $ATTR_LIST
3742 clevermous 544
        mov     eax, [ebp+NTFS.frs_buffer]
2288 clevermous 545
        movzx   ecx, word [eax+14h]
546
        add     eax, ecx
3742 clevermous 547
        mov     ecx, [ebp+NTFS.ntfs_cur_attr]
548
        and     [ebp+NTFS.ntfs_attr_offs], 0
2288 clevermous 549
.scanattr:
550
        cmp     dword [eax], -1
551
        jz      .scandone
552
        cmp     dword [eax], ecx
553
        jz      .okattr
3742 clevermous 554
        cmp     [ebp+NTFS.ntfs_attr_iBaseRecord], -1
2288 clevermous 555
        jnz     .scancont
556
        cmp     dword [eax], 0x20       ; $ATTR_LIST
557
        jnz     .scancont
3742 clevermous 558
        mov     [ebp+NTFS.ntfs_attr_list], eax
2288 clevermous 559
        jmp     .scancont
560
.okattr:
561
; ignore named $DATA attributes (aka NTFS streams)
562
        cmp     ecx, 0x80
563
        jnz     @f
564
        cmp     byte [eax+9], 0
565
        jnz     .scancont
566
@@:
3742 clevermous 567
        mov     [ebp+NTFS.ntfs_attr_offs], eax
2288 clevermous 568
.scancont:
569
        add     eax, [eax+4]
570
        jmp     .scanattr
571
.continue:
572
        pushad
3742 clevermous 573
        and     [ebp+NTFS.ntfs_cur_read], 0
2288 clevermous 574
.scandone:
575
; c) Check for required offset and length
3742 clevermous 576
        mov     ecx, [ebp+NTFS.ntfs_attr_offs]
2288 clevermous 577
        jecxz   .noattr
3742 clevermous 578
        push    [ebp+NTFS.ntfs_cur_size]
579
        push    [ebp+NTFS.ntfs_cur_read]
2288 clevermous 580
        call    .doreadattr
581
        pop     edx
3742 clevermous 582
        pop     ecx
2288 clevermous 583
        jc      @f
3742 clevermous 584
        cmp     [ebp+NTFS.ntfs_bCanContinue], 0
2288 clevermous 585
        jz      @f
3742 clevermous 586
        sub     edx, [ebp+NTFS.ntfs_cur_read]
2288 clevermous 587
        neg     edx
588
        shr     edx, 9
3742 clevermous 589
        sub     ecx, edx
590
        mov     [ebp+NTFS.ntfs_cur_size], ecx
2288 clevermous 591
        jnz     .not_in_cur
592
@@:
593
        popad
594
        ret
595
.noattr:
596
.not_in_cur:
3742 clevermous 597
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x20
2288 clevermous 598
        jz      @f
3742 clevermous 599
        mov     ecx, [ebp+NTFS.ntfs_attr_list]
2288 clevermous 600
        test    ecx, ecx
601
        jnz     .lookattr
602
.ret_is_attr:
3742 clevermous 603
        and     dword [esp+28], 0
604
        cmp     [ebp+NTFS.ntfs_attr_offs], 1     ; CF set <=> ntfs_attr_offs == 0
2288 clevermous 605
        popad
606
        ret
607
.lookattr:
608
; required attribute or required offset was not found in base record;
609
; it may be present in auxiliary records;
610
; scan $ATTR_LIST
3742 clevermous 611
        mov     eax, [ebp+NTFS.ntfs_attr_iBaseRecord]
2288 clevermous 612
        cmp     eax, -1
613
        jz      @f
614
        call    ntfs_read_file_record
3742 clevermous 615
        jc      .errret
616
        or      [ebp+NTFS.ntfs_attr_iBaseRecord], -1
2288 clevermous 617
@@:
3742 clevermous 618
        push    [ebp+NTFS.ntfs_cur_offs]
619
        push    [ebp+NTFS.ntfs_cur_size]
620
        push    [ebp+NTFS.ntfs_cur_read]
621
        push    [ebp+NTFS.ntfs_cur_buf]
622
        push    dword [ebp+NTFS.ntfs_attr_size]
623
        push    dword [ebp+NTFS.ntfs_attr_size+4]
624
        or      dword [ebp+NTFS.ntfs_attr_size], -1
625
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
626
        and     [ebp+NTFS.ntfs_cur_offs], 0
627
        mov     [ebp+NTFS.ntfs_cur_size], 2
628
        and     [ebp+NTFS.ntfs_cur_read], 0
629
        lea     eax, [ebp+NTFS.ntfs_attrlist_buf]
630
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
2288 clevermous 631
        jnz     @f
3742 clevermous 632
        lea     eax, [ebp+NTFS.ntfs_attrlist_mft_buf]
2288 clevermous 633
@@:
3742 clevermous 634
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2288 clevermous 635
        push    eax
636
        call    .doreadattr
637
        pop     esi
638
        mov     edx, 1
3742 clevermous 639
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
640
        pop     dword [ebp+NTFS.ntfs_attr_size]
641
        mov     ecx, [ebp+NTFS.ntfs_cur_read]
642
        pop     [ebp+NTFS.ntfs_cur_buf]
643
        pop     [ebp+NTFS.ntfs_cur_read]
644
        pop     [ebp+NTFS.ntfs_cur_size]
645
        pop     [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 646
        jc      .errret
647
        or      edi, -1
3742 clevermous 648
        lea     ecx, [ecx+esi-1Ah]
2288 clevermous 649
.scanliststart:
3742 clevermous 650
        push    ecx
651
        mov     eax, [ebp+NTFS.ntfs_cur_attr]
2288 clevermous 652
.scanlist:
3742 clevermous 653
        cmp     esi, [esp]
2288 clevermous 654
        jae     .scanlistdone
655
        cmp     eax, [esi]
656
        jz      @f
657
.scanlistcont:
658
        movzx   ecx, word [esi+4]
659
        add     esi, ecx
660
        jmp     .scanlist
661
@@:
662
; ignore named $DATA attributes (aka NTFS streams)
663
        cmp     eax, 0x80
664
        jnz     @f
665
        cmp     byte [esi+6], 0
666
        jnz     .scanlistcont
667
@@:
668
        push    eax
669
        mov     eax, [esi+8]
670
        test    eax, eax
671
        jnz     .testf
3742 clevermous 672
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
673
        and     eax, dword [ebp+NTFS.ntfs_attr_size+4]
2288 clevermous 674
        cmp     eax, -1
675
        jnz     .testfz
676
; if attribute is in auxiliary records, its size is defined only in first
677
        mov     eax, [esi+10h]
678
        call    ntfs_read_file_record
3742 clevermous 679
        jnc     @f
2288 clevermous 680
.errret_pop:
3742 clevermous 681
        pop     ecx ecx
2288 clevermous 682
        jmp     .errret
3742 clevermous 683
.errret2_pop:
684
        xor     eax, eax
685
        jmp     .errret_pop
2288 clevermous 686
@@:
3742 clevermous 687
        mov     eax, [ebp+NTFS.frs_buffer]
2288 clevermous 688
        movzx   ecx, word [eax+14h]
689
        add     eax, ecx
3742 clevermous 690
        mov     ecx, [ebp+NTFS.ntfs_cur_attr]
2288 clevermous 691
@@:
692
        cmp     dword [eax], -1
3742 clevermous 693
        jz      .errret2_pop
2288 clevermous 694
        cmp     dword [eax], ecx
695
        jz      @f
696
.l1:
697
        add     eax, [eax+4]
698
        jmp     @b
699
@@:
700
        cmp     eax, 0x80
701
        jnz     @f
702
        cmp     byte [eax+9], 0
703
        jnz     .l1
704
@@:
705
        cmp     byte [eax+8], 0
706
        jnz     .sdnores
707
        mov     eax, [eax+10h]
3742 clevermous 708
        mov     dword [ebp+NTFS.ntfs_attr_size], eax
709
        and     dword [ebp+NTFS.ntfs_attr_size+4], 0
2288 clevermous 710
        jmp     .testfz
711
.sdnores:
712
        mov     ecx, [eax+30h]
3742 clevermous 713
        mov     dword [ebp+NTFS.ntfs_attr_size], ecx
2288 clevermous 714
        mov     ecx, [eax+34h]
3742 clevermous 715
        mov     dword [ebp+NTFS.ntfs_attr_size+4], ecx
2288 clevermous 716
.testfz:
717
        xor     eax, eax
718
.testf:
3742 clevermous 719
        imul    eax, [ebp+NTFS.sectors_per_cluster]
720
        cmp     eax, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 721
        pop     eax
722
        ja      @f
723
        mov     edi, [esi+10h]  ; keep previous iRecord
724
        jmp     .scanlistcont
725
@@:
3742 clevermous 726
        pop     ecx
2288 clevermous 727
.scanlistfound:
728
        cmp     edi, -1
729
        jnz     @f
730
        popad
731
        ret
732
@@:
3742 clevermous 733
        mov     eax, [ebp+NTFS.ntfs_cur_iRecord]
734
        mov     [ebp+NTFS.ntfs_attr_iBaseRecord], eax
2288 clevermous 735
        mov     eax, edi
736
        jmp     .beginfindattr
737
.scanlistdone:
3742 clevermous 738
        pop     ecx
739
        sub     ecx, ebp
740
        sub     ecx, NTFS.ntfs_attrlist_buf-1Ah
741
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
2288 clevermous 742
        jnz     @f
3742 clevermous 743
        sub     ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
2288 clevermous 744
@@:
3742 clevermous 745
        cmp     ecx, 0x400
2288 clevermous 746
        jnz     .scanlistfound
747
        inc     edx
748
        push    esi edi
3742 clevermous 749
        lea     esi, [ebp+NTFS.ntfs_attrlist_buf+0x200]
750
        lea     edi, [ebp+NTFS.ntfs_attrlist_buf]
751
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
2288 clevermous 752
        jnz     @f
3742 clevermous 753
        lea     esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200]
754
        lea     edi, [ebp+NTFS.ntfs_attrlist_mft_buf]
2288 clevermous 755
@@:
756
        mov     ecx, 0x200/4
757
        rep movsd
758
        mov     eax, edi
759
        pop     edi esi
760
        sub     esi, 0x200
3742 clevermous 761
        push    [ebp+NTFS.ntfs_cur_offs]
762
        push    [ebp+NTFS.ntfs_cur_size]
763
        push    [ebp+NTFS.ntfs_cur_read]
764
        push    [ebp+NTFS.ntfs_cur_buf]
765
        push    dword [ebp+NTFS.ntfs_attr_size]
766
        push    dword [ebp+NTFS.ntfs_attr_size+4]
767
        or      dword [ebp+NTFS.ntfs_attr_size], -1
768
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
769
        mov     [ebp+NTFS.ntfs_cur_offs], edx
770
        mov     [ebp+NTFS.ntfs_cur_size], 1
771
        and     [ebp+NTFS.ntfs_cur_read], 0
772
        mov     [ebp+NTFS.ntfs_cur_buf], eax
773
        mov     ecx, [ebp+NTFS.ntfs_attr_list]
774
        push    esi edx edi
2288 clevermous 775
        call    .doreadattr
3742 clevermous 776
        pop     edi edx esi
777
        mov     ecx, [ebp+NTFS.ntfs_cur_read]
778
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
779
        pop     dword [ebp+NTFS.ntfs_attr_size]
780
        pop     [ebp+NTFS.ntfs_cur_buf]
781
        pop     [ebp+NTFS.ntfs_cur_read]
782
        pop     [ebp+NTFS.ntfs_cur_size]
783
        pop     [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 784
        jc      .errret
3742 clevermous 785
        lea     ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A]
786
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
2288 clevermous 787
        jnz     .scanliststart
3742 clevermous 788
        add     ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
2288 clevermous 789
        jmp     .scanliststart
790
 
791
.doreadattr:
3742 clevermous 792
        mov     [ebp+NTFS.ntfs_bCanContinue], 0
2288 clevermous 793
        cmp     byte [ecx+8], 0
794
        jnz     .nonresident
795
        mov     eax, [ecx+10h]  ; length
796
        mov     esi, eax
3742 clevermous 797
        mov     edx, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 798
        shr     eax, 9
799
        cmp     eax, edx
800
        jb      .okret
801
        shl     edx, 9
802
        sub     esi, edx
803
        movzx   eax, word [ecx+14h]
804
        add     edx, eax
805
        add     edx, ecx        ; edx -> data
3742 clevermous 806
        mov     eax, [ebp+NTFS.ntfs_cur_size]
2288 clevermous 807
        cmp     eax, (0xFFFFFFFF shr 9)+1
808
        jbe     @f
809
        mov     eax, (0xFFFFFFFF shr 9)+1
810
@@:
811
        shl     eax, 9
812
        cmp     eax, esi
813
        jbe     @f
814
        mov     eax, esi
815
@@:
816
; eax = length, edx -> data
3742 clevermous 817
        mov     [ebp+NTFS.ntfs_cur_read], eax
2288 clevermous 818
        mov     ecx, eax
819
        mov     eax, edx
3742 clevermous 820
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
2288 clevermous 821
        call    memmove
3742 clevermous 822
        and     [ebp+NTFS.ntfs_cur_size], 0      ; CF=0
2288 clevermous 823
        ret
824
.nonresident:
825
; Not all auxiliary records contain correct FileSize info
3742 clevermous 826
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
827
        mov     edx, dword [ebp+NTFS.ntfs_attr_size+4]
2288 clevermous 828
        push    eax
829
        and     eax, edx
830
        cmp     eax, -1
831
        pop     eax
832
        jnz     @f
833
        mov     eax, [ecx+30h]  ; FileSize
834
        mov     edx, [ecx+34h]
3742 clevermous 835
        mov     dword [ebp+NTFS.ntfs_attr_size], eax
836
        mov     dword [ebp+NTFS.ntfs_attr_size+4], edx
2288 clevermous 837
@@:
838
        add     eax, 0x1FF
839
        adc     edx, 0
840
        shrd    eax, edx, 9
3742 clevermous 841
        sub     eax, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 842
        ja      @f
843
; return with nothing read
3742 clevermous 844
        and     [ebp+NTFS.ntfs_cur_size], 0
2288 clevermous 845
.okret:
846
        clc
847
        ret
848
@@:
849
; reduce read length
3742 clevermous 850
        and     [ebp+NTFS.ntfs_cur_tail], 0
851
        cmp     [ebp+NTFS.ntfs_cur_size], eax
2288 clevermous 852
        jb      @f
3742 clevermous 853
        mov     [ebp+NTFS.ntfs_cur_size], eax
854
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
2288 clevermous 855
        and     eax, 0x1FF
3742 clevermous 856
        mov     [ebp+NTFS.ntfs_cur_tail], eax
2288 clevermous 857
@@:
3742 clevermous 858
        cmp     [ebp+NTFS.ntfs_cur_size], 0
2288 clevermous 859
        jz      .okret
3742 clevermous 860
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 861
        xor     edx, edx
3742 clevermous 862
        div     [ebp+NTFS.sectors_per_cluster]
2288 clevermous 863
        sub     eax, [ecx+10h]  ; first_vbo
864
        jb      .okret
865
; eax = cluster, edx = starting sector
866
        sub     esp, 10h
867
        movzx   esi, word [ecx+20h]     ; mcb_info_ofs
868
        add     esi, ecx
3742 clevermous 869
        xor     edi, edi
2288 clevermous 870
.readloop:
871
        call    ntfs_decode_mcb_entry
872
        jnc     .break
3742 clevermous 873
        add     edi, [esp+8]
2288 clevermous 874
        sub     eax, [esp]
875
        jae     .readloop
876
        push    ecx
877
        push    eax
878
        add     eax, [esp+8]
3742 clevermous 879
        add     eax, edi
880
        imul    eax, [ebp+NTFS.sectors_per_cluster]
2288 clevermous 881
        add     eax, edx
882
        pop     ecx
883
        neg     ecx
3742 clevermous 884
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
2288 clevermous 885
        sub     ecx, edx
3742 clevermous 886
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
2288 clevermous 887
        jb      @f
3742 clevermous 888
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
2288 clevermous 889
@@:
3742 clevermous 890
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
2288 clevermous 891
@@:
3742 clevermous 892
        push    eax
893
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
894
        jnz     .sys
895
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
896
        jz      .sys
897
        call    fs_read32_app
898
        jmp     .appsys
899
.sys:
900
        call    fs_read32_sys
901
.appsys:
902
        pop     edx
903
        test    eax, eax
2288 clevermous 904
        jnz     .errread2
905
        add     ebx, 0x200
3742 clevermous 906
        mov     [ebp+NTFS.ntfs_cur_buf], ebx
907
        lea     eax, [edx+1]
908
        add     [ebp+NTFS.ntfs_cur_read], 0x200
909
        dec     [ebp+NTFS.ntfs_cur_size]
910
        inc     [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 911
        loop    @b
912
        pop     ecx
913
        xor     eax, eax
914
        xor     edx, edx
3742 clevermous 915
        cmp     [ebp+NTFS.ntfs_cur_size], 0
2288 clevermous 916
        jnz     .readloop
917
        add     esp, 10h
3742 clevermous 918
        mov     eax, [ebp+NTFS.ntfs_cur_tail]
2288 clevermous 919
        test    eax, eax
920
        jz      @f
921
        sub     eax, 0x200
3742 clevermous 922
        add     [ebp+NTFS.ntfs_cur_read], eax
2288 clevermous 923
@@:
924
        clc
925
        ret
926
.errread2:
927
        pop     ecx
928
        add     esp, 10h
929
        stc
930
        ret
931
.break:
932
        add     esp, 10h        ; CF=0
3742 clevermous 933
        mov     [ebp+NTFS.ntfs_bCanContinue], 1
2288 clevermous 934
        ret
935
 
936
ntfs_read_file_record:
937
; in: eax=iRecord
3742 clevermous 938
; out: [ebp+NTFS.frs_buffer] contains information
939
;      CF=1 - failed, in this case eax=0 => something with FS, eax nonzero => disk error
940
; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
2288 clevermous 941
        push    ecx edx
3742 clevermous 942
        mov     ecx, [ebp+NTFS.frs_size]
2288 clevermous 943
        mul     ecx
944
        shrd    eax, edx, 9
945
        shr     edx, 9
3742 clevermous 946
        jnz     .errret
947
        push    [ebp+NTFS.ntfs_attr_iRecord]
948
        push    [ebp+NTFS.ntfs_attr_iBaseRecord]
949
        push    [ebp+NTFS.ntfs_attr_offs]
950
        push    [ebp+NTFS.ntfs_attr_list]
951
        push    dword [ebp+NTFS.ntfs_attr_size+4]
952
        push    dword [ebp+NTFS.ntfs_attr_size]
953
        push    [ebp+NTFS.ntfs_cur_iRecord]
954
        push    [ebp+NTFS.ntfs_cur_attr]
955
        push    [ebp+NTFS.ntfs_cur_offs]
956
        push    [ebp+NTFS.ntfs_cur_size]
957
        push    [ebp+NTFS.ntfs_cur_buf]
958
        push    [ebp+NTFS.ntfs_cur_read]
959
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80   ; $DATA
960
        and     [ebp+NTFS.ntfs_cur_iRecord], 0   ; $Mft
961
        mov     [ebp+NTFS.ntfs_cur_offs], eax
2288 clevermous 962
        shr     ecx, 9
3742 clevermous 963
        mov     [ebp+NTFS.ntfs_cur_size], ecx
964
        mov     eax, [ebp+NTFS.frs_buffer]
965
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2288 clevermous 966
        call    ntfs_read_attr
3742 clevermous 967
        mov     edx, [ebp+NTFS.ntfs_cur_read]
968
        pop     [ebp+NTFS.ntfs_cur_read]
969
        pop     [ebp+NTFS.ntfs_cur_buf]
970
        pop     [ebp+NTFS.ntfs_cur_size]
971
        pop     [ebp+NTFS.ntfs_cur_offs]
972
        pop     [ebp+NTFS.ntfs_cur_attr]
973
        pop     [ebp+NTFS.ntfs_cur_iRecord]
974
        pop     dword [ebp+NTFS.ntfs_attr_size]
975
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
976
        pop     [ebp+NTFS.ntfs_attr_list]
977
        pop     [ebp+NTFS.ntfs_attr_offs]
978
        pop     [ebp+NTFS.ntfs_attr_iBaseRecord]
979
        pop     [ebp+NTFS.ntfs_attr_iRecord]
980
        jc      .ret
981
        cmp     edx, [ebp+NTFS.frs_size]
2288 clevermous 982
        jnz     .errret
3742 clevermous 983
        mov     eax, [ebp+NTFS.frs_buffer]
2288 clevermous 984
        cmp     dword [eax], 'FILE'
985
        jnz     .errret
986
        push    ebx
987
        mov     ebx, eax
988
        call    ntfs_restore_usa_frs
989
        pop     ebx
3742 clevermous 990
        jc      .errret
2288 clevermous 991
.ret:
3742 clevermous 992
        pop     edx ecx
2288 clevermous 993
        ret
3742 clevermous 994
.errret:
2288 clevermous 995
        pop     edx ecx
996
        xor     eax, eax
3742 clevermous 997
        stc
2288 clevermous 998
        ret
999
 
1000
ntfs_restore_usa_frs:
3742 clevermous 1001
        mov     eax, [ebp+NTFS.frs_size]
2288 clevermous 1002
ntfs_restore_usa:
1003
        pushad
1004
        shr     eax, 9
1005
        mov     ecx, eax
1006
        inc     eax
1007
        cmp     [ebx+6], ax
1008
        jnz     .err
1009
        movzx   eax, word [ebx+4]
1010
        lea     esi, [eax+ebx]
1011
        lodsw
1012
        mov     edx, eax
1013
        lea     edi, [ebx+0x1FE]
1014
@@:
1015
        cmp     [edi], dx
1016
        jnz     .err
1017
        lodsw
1018
        stosw
1019
        add     edi, 0x1FE
1020
        loop    @b
1021
        popad
1022
        clc
1023
        ret
1024
.err:
1025
        popad
1026
        stc
1027
        ret
1028
 
1029
ntfs_decode_mcb_entry:
1030
        push    eax ecx edi
1031
        lea     edi, [esp+16]
1032
        xor     eax, eax
1033
        lodsb
1034
        test    al, al
1035
        jz      .end
1036
        mov     ecx, eax
1037
        and     ecx, 0xF
1038
        cmp     ecx, 8
1039
        ja      .end
1040
        push    ecx
1041
        rep movsb
1042
        pop     ecx
1043
        sub     ecx, 8
1044
        neg     ecx
1045
        cmp     byte [esi-1], 80h
1046
        jae     .end
1047
        push    eax
1048
        xor     eax, eax
1049
        rep stosb
1050
        pop     ecx
1051
        shr     ecx, 4
1052
        cmp     ecx, 8
1053
        ja      .end
1054
        push    ecx
1055
        rep movsb
1056
        pop     ecx
1057
        sub     ecx, 8
1058
        neg     ecx
1059
        cmp     byte [esi-1], 80h
1060
        cmc
1061
        sbb     eax, eax
1062
        rep stosb
1063
        stc
1064
.end:
1065
        pop     edi ecx eax
1066
        ret
1067
 
1068
unichar_toupper:
1069
        push    eax
1070
        call    uni2ansi_char
1071
        cmp     al, '_'
1072
        jz      .unk
1073
        add     esp, 4
1504 diamond 1074
        call    char_toupper
1075
        jmp     ansi2uni_char
1076
.unk:
1077
        pop     eax
1078
        ret
2288 clevermous 1079
 
1080
ntfs_find_lfn:
3742 clevermous 1081
; in: esi+[esp+4] -> name
2288 clevermous 1082
; out: CF=1 - file not found
3742 clevermous 1083
;      else CF=0, [ebp+NTFS.ntfs_cur_iRecord] valid, eax->record in parent directory
1084
        mov     [ebp+NTFS.ntfs_cur_iRecord], 5   ; start parse from root cluster
2288 clevermous 1085
.doit2:
3742 clevermous 1086
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1087
        and     [ebp+NTFS.ntfs_cur_offs], 0
1088
        mov     eax, [ebp+NTFS.cur_index_size]
1089
        mov     [ebp+NTFS.ntfs_cur_size], eax
1090
        mov     eax, [ebp+NTFS.cur_index_buf]
1091
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2288 clevermous 1092
        call    ntfs_read_attr
1093
        jnc     @f
1094
.ret:
3742 clevermous 1095
        ret     4
2288 clevermous 1096
@@:
3742 clevermous 1097
        xor     eax, eax
1098
        cmp     [ebp+NTFS.ntfs_cur_read], 0x20
2288 clevermous 1099
        jc      .ret
1100
        pushad
3742 clevermous 1101
        mov     esi, [ebp+NTFS.cur_index_buf]
2288 clevermous 1102
        mov     eax, [esi+14h]
1103
        add     eax, 10h
3742 clevermous 1104
        cmp     [ebp+NTFS.ntfs_cur_read], eax
2288 clevermous 1105
        jae     .readok1
1106
        add     eax, 1FFh
1107
        shr     eax, 9
3742 clevermous 1108
        cmp     eax, [ebp+NTFS.cur_index_size]
2288 clevermous 1109
        ja      @f
1110
.stc_ret:
1111
        popad
1112
        stc
3742 clevermous 1113
        ret     4
2288 clevermous 1114
@@:
1115
; reallocate
1116
        push    eax
3742 clevermous 1117
        push    [ebp+NTFS.cur_index_buf]
2288 clevermous 1118
        call    kernel_free
1119
        pop     eax
3742 clevermous 1120
        mov     [ebp+NTFS.cur_index_size], eax
2288 clevermous 1121
        push    eax
1122
        call    kernel_alloc
1123
        test    eax, eax
1124
        jnz     @f
3742 clevermous 1125
        and     [ebp+NTFS.cur_index_size], 0
1126
        and     [ebp+NTFS.cur_index_buf], 0
2288 clevermous 1127
        jmp     .stc_ret
1128
@@:
3742 clevermous 1129
        mov     [ebp+NTFS.cur_index_buf], eax
2288 clevermous 1130
        popad
1131
        jmp     .doit2
1132
.readok1:
3742 clevermous 1133
        mov     edx, [esi+8]    ; subnode_size
1134
        shr     edx, 9
1135
        cmp     edx, [ebp+NTFS.cur_index_size]
2288 clevermous 1136
        jbe     .ok2
3742 clevermous 1137
        push    esi edx
1138
        push    edx
2288 clevermous 1139
        call    kernel_alloc
3742 clevermous 1140
        pop     edx esi
2288 clevermous 1141
        test    eax, eax
1142
        jz      .stc_ret
1143
        mov     edi, eax
3742 clevermous 1144
        mov     ecx, [ebp+NTFS.cur_index_size]
2288 clevermous 1145
        shl     ecx, 9-2
1146
        rep movsd
1147
        mov     esi, eax
3742 clevermous 1148
        mov     [ebp+NTFS.cur_index_size], edx
1149
        push    esi edx
1150
        push    [ebp+NTFS.cur_index_buf]
2288 clevermous 1151
        call    kernel_free
3742 clevermous 1152
        pop     edx esi
1153
        mov     [ebp+NTFS.cur_index_buf], esi
2288 clevermous 1154
.ok2:
1155
        add     esi, 10h
1156
        mov     edi, [esp+4]
3742 clevermous 1157
; edi -> name, esi -> current index data, edx = subnode size
2288 clevermous 1158
.scanloop:
1159
        add     esi, [esi]
1160
.scanloopint:
1161
        test    byte [esi+0Ch], 2
1162
        jnz     .subnode
1163
        push    esi
1164
        add     esi, 0x52
1165
        movzx   ecx, byte [esi-2]
1166
        push    edi
1167
@@:
1168
        lodsw
1169
        call    unichar_toupper
1170
        push    eax
1171
        mov     al, [edi]
1172
        inc     edi
1173
        cmp     al, '/'
1174
        jz      .slash
1175
        call    char_toupper
1176
        call    ansi2uni_char
1177
        cmp     ax, [esp]
1178
        pop     eax
1179
        loopz   @b
1180
        jz      .found
1181
        pop     edi
1182
        pop     esi
1183
        jb      .subnode
1184
.scanloopcont:
1185
        movzx   eax, word [esi+8]
1186
        add     esi, eax
1187
        jmp     .scanloopint
1188
.slash:
1189
        pop     eax
1190
        pop     edi
1191
        pop     esi
1192
.subnode:
1193
        test    byte [esi+0Ch], 1
1194
        jz      .notfound
1195
        movzx   eax, word [esi+8]
1196
        mov     eax, [esi+eax-8]
3742 clevermous 1197
        imul    eax, [ebp+NTFS.sectors_per_cluster]
1198
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1199
        mov     [ebp+NTFS.ntfs_cur_attr], 0xA0   ; $INDEX_ALLOCATION
1200
        mov     [ebp+NTFS.ntfs_cur_size], edx
1201
        mov     eax, [ebp+NTFS.cur_index_buf]
2288 clevermous 1202
        mov     esi, eax
3742 clevermous 1203
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1204
        push    edx
2288 clevermous 1205
        call    ntfs_read_attr
3742 clevermous 1206
        pop     edx
1207
        mov     eax, edx
2288 clevermous 1208
        shl     eax, 9
3742 clevermous 1209
        cmp     [ebp+NTFS.ntfs_cur_read], eax
2288 clevermous 1210
        jnz     .notfound
1211
        cmp     dword [esi], 'INDX'
1212
        jnz     .notfound
1213
        mov     ebx, esi
1214
        call    ntfs_restore_usa
1215
        jc      .notfound
1216
        add     esi, 0x18
1217
        jmp     .scanloop
1218
.notfound:
1219
        popad
1220
        stc
3742 clevermous 1221
        ret     4
2288 clevermous 1222
.found:
1223
        cmp     byte [edi], 0
1224
        jz      .done
1225
        cmp     byte [edi], '/'
1226
        jz      .next
1227
        pop     edi
1228
        pop     esi
1229
        jmp     .scanloopcont
1230
.done:
1231
.next:
1232
        pop     esi
1233
        pop     esi
1234
        mov     eax, [esi]
3742 clevermous 1235
        mov     [ebp+NTFS.ntfs_cur_iRecord], eax
2288 clevermous 1236
        mov     [esp+1Ch], esi
1237
        mov     [esp+4], edi
1238
        popad
1239
        inc     esi
1240
        cmp     byte [esi-1], 0
1241
        jnz     .doit2
3742 clevermous 1242
        cmp     dword [esp+4], 0
2288 clevermous 1243
        jz      @f
3742 clevermous 1244
        mov     esi, [esp+4]
1245
        mov     dword [esp+4], 0
2288 clevermous 1246
        jmp     .doit2
1247
@@:
3742 clevermous 1248
        ret     4
2288 clevermous 1249
 
1250
;----------------------------------------------------------------
3742 clevermous 1251
; ntfs_Read - NTFS implementation of reading a file
1252
; in:  ebp = pointer to NTFS structure
1253
; in:  esi+[esp+4] = name
1254
; in:  ebx = pointer to parameters from sysfunc 70
1255
; out: eax, ebx = return values for sysfunc 70
1256
;----------------------------------------------------------------
1257
ntfs_Read:
2288 clevermous 1258
        cmp     byte [esi], 0
1259
        jnz     @f
1260
        or      ebx, -1
3598 clevermous 1261
        movi    eax, ERROR_ACCESS_DENIED
2288 clevermous 1262
        ret
1263
@@:
3742 clevermous 1264
        call    ntfs_lock
1265
        stdcall ntfs_find_lfn, [esp+4]
2288 clevermous 1266
        jnc     .found
3742 clevermous 1267
        call    ntfs_unlock
2288 clevermous 1268
        or      ebx, -1
3598 clevermous 1269
        movi    eax, ERROR_FILE_NOT_FOUND
2288 clevermous 1270
        ret
1271
.found:
3742 clevermous 1272
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80   ; $DATA
1273
        and     [ebp+NTFS.ntfs_cur_offs], 0
1274
        and     [ebp+NTFS.ntfs_cur_size], 0
2288 clevermous 1275
        call    ntfs_read_attr
1276
        jnc     @f
3742 clevermous 1277
        call    ntfs_unlock
2288 clevermous 1278
        or      ebx, -1
3598 clevermous 1279
        movi    eax, ERROR_ACCESS_DENIED
2288 clevermous 1280
        ret
1281
@@:
1282
        pushad
1283
        and     dword [esp+10h], 0
1284
        xor     eax, eax
3742 clevermous 1285
        cmp     dword [ebx+8], 0x200
2288 clevermous 1286
        jb      @f
1287
.eof0:
1288
        popad
1289
        xor     ebx, ebx
1290
.eof:
3598 clevermous 1291
        movi    eax, ERROR_END_OF_FILE
3742 clevermous 1292
        push    eax
1293
        call    ntfs_unlock
1294
        pop     eax
2288 clevermous 1295
        ret
1296
@@:
3742 clevermous 1297
        mov     ecx, [ebx+12]
1298
        mov     edx, [ebx+16]
1299
        mov     eax, [ebx+4]
2288 clevermous 1300
        test    eax, 0x1FF
1301
        jz      .alignedstart
1302
        push    edx
3742 clevermous 1303
        mov     edx, [ebx+8]
2288 clevermous 1304
        shrd    eax, edx, 9
1400 turbanoff 1305
        pop     edx
3742 clevermous 1306
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1307
        mov     [ebp+NTFS.ntfs_cur_size], 1
1308
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1309
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2288 clevermous 1310
        call    ntfs_read_attr.continue
3742 clevermous 1311
        mov     eax, [ebx+4]
2288 clevermous 1312
        and     eax, 0x1FF
3742 clevermous 1313
        lea     esi, [ebp+NTFS.ntfs_bitmap_buf+eax]
1314
        sub     eax, [ebp+NTFS.ntfs_cur_read]
2288 clevermous 1315
        jae     .eof0
1316
        neg     eax
1317
        push    ecx
1318
        cmp     ecx, eax
1319
        jb      @f
1320
        mov     ecx, eax
1321
@@:
1322
        mov     [esp+10h+4], ecx
1323
        mov     edi, edx
1324
        rep movsb
1325
        mov     edx, edi
1326
        pop     ecx
1327
        sub     ecx, [esp+10h]
1328
        jnz     @f
1329
.retok:
1330
        popad
3742 clevermous 1331
        call    ntfs_unlock
2288 clevermous 1332
        xor     eax, eax
1400 turbanoff 1333
        ret
2288 clevermous 1334
@@:
3742 clevermous 1335
        cmp     [ebp+NTFS.ntfs_cur_read], 0x200
2288 clevermous 1336
        jz      .alignedstart
1337
.eof_ebx:
1338
        popad
1339
        jmp     .eof
1340
.alignedstart:
3742 clevermous 1341
        mov     eax, [ebx+4]
2288 clevermous 1342
        push    edx
3742 clevermous 1343
        mov     edx, [ebx+8]
2288 clevermous 1344
        add     eax, 511
1345
        adc     edx, 0
1346
        shrd    eax, edx, 9
1347
        pop     edx
1348
.zero1:
3742 clevermous 1349
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1350
        mov     [ebp+NTFS.ntfs_cur_buf], edx
2288 clevermous 1351
        mov     eax, ecx
1352
        shr     eax, 9
3742 clevermous 1353
        mov     [ebp+NTFS.ntfs_cur_size], eax
1354
        add     eax, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 1355
        push    eax
1356
        call    ntfs_read_attr.continue
3742 clevermous 1357
        pop     [ebp+NTFS.ntfs_cur_offs]
1358
        mov     eax, [ebp+NTFS.ntfs_cur_read]
2288 clevermous 1359
        add     [esp+10h], eax
1360
        mov     eax, ecx
1361
        and     eax, not 0x1FF
3742 clevermous 1362
        cmp     [ebp+NTFS.ntfs_cur_read], eax
2288 clevermous 1363
        jnz     .eof_ebx
1364
        and     ecx, 0x1FF
1365
        jz      .retok
3742 clevermous 1366
        add     edx, [ebp+NTFS.ntfs_cur_read]
1367
        mov     [ebp+NTFS.ntfs_cur_size], 1
1368
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1369
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2288 clevermous 1370
        call    ntfs_read_attr.continue
3742 clevermous 1371
        cmp     [ebp+NTFS.ntfs_cur_read], ecx
2288 clevermous 1372
        jb      @f
3742 clevermous 1373
        mov     [ebp+NTFS.ntfs_cur_read], ecx
2288 clevermous 1374
@@:
3742 clevermous 1375
        xchg    ecx, [ebp+NTFS.ntfs_cur_read]
2288 clevermous 1376
        push    ecx
1377
        mov     edi, edx
3742 clevermous 1378
        lea     esi, [ebp+NTFS.ntfs_bitmap_buf]
2288 clevermous 1379
        add     [esp+10h+4], ecx
1380
        rep movsb
1381
        pop     ecx
1382
        xor     eax, eax
3742 clevermous 1383
        cmp     ecx, [ebp+NTFS.ntfs_cur_read]
2288 clevermous 1384
        jz      @f
1385
        mov     al, ERROR_END_OF_FILE
1386
@@:
1387
        mov     [esp+1Ch], eax
3742 clevermous 1388
        call    ntfs_unlock
2288 clevermous 1389
        popad
1390
        ret
1400 turbanoff 1391
 
2288 clevermous 1392
;----------------------------------------------------------------
3742 clevermous 1393
; ntfs_ReadFolder - NTFS implementation of reading a folder
1394
; in:  ebp = pointer to NTFS structure
1395
; in:  esi+[esp+4] = name
1396
; in:  ebx = pointer to parameters from sysfunc 70
1397
; out: eax, ebx = return values for sysfunc 70
1398
;----------------------------------------------------------------
1399
ntfs_ReadFolder:
1400
        call    ntfs_lock
2288 clevermous 1401
        mov     eax, 5          ; root cluster
1402
        cmp     byte [esi], 0
1403
        jz      .doit
3742 clevermous 1404
        stdcall ntfs_find_lfn, [esp+4]
2288 clevermous 1405
        jnc     .doit2
1406
.notfound:
1407
        or      ebx, -1
1408
        push    ERROR_FILE_NOT_FOUND
1409
.pop_ret:
3742 clevermous 1410
        call    ntfs_unlock
2288 clevermous 1411
        pop     eax
1412
        ret
1413
.doit:
3742 clevermous 1414
        mov     [ebp+NTFS.ntfs_cur_iRecord], eax
2288 clevermous 1415
.doit2:
3742 clevermous 1416
        mov     [ebp+NTFS.ntfs_cur_attr], 0x10   ; $STANDARD_INFORMATION
1417
        and     [ebp+NTFS.ntfs_cur_offs], 0
1418
        mov     [ebp+NTFS.ntfs_cur_size], 1
1419
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1420
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2288 clevermous 1421
        call    ntfs_read_attr
1422
        jc      .notfound
3742 clevermous 1423
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1424
        and     [ebp+NTFS.ntfs_cur_offs], 0
1425
        mov     eax, [ebp+NTFS.cur_index_size]
1426
        mov     [ebp+NTFS.ntfs_cur_size], eax
1427
        mov     eax, [ebp+NTFS.cur_index_buf]
1428
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2288 clevermous 1429
        call    ntfs_read_attr
1430
        jnc     .ok
3742 clevermous 1431
        test    eax, eax
2288 clevermous 1432
        jz      .notfound
1433
        or      ebx, -1
1434
        push    11
1435
        jmp     .pop_ret
1436
.ok:
3742 clevermous 1437
        cmp     [ebp+NTFS.ntfs_cur_read], 0x20
2288 clevermous 1438
        jae     @f
1439
        or      ebx, -1
1440
.fserr:
1441
        push    ERROR_FAT_TABLE
1442
        jmp     .pop_ret
1443
@@:
1444
        pushad
3742 clevermous 1445
        mov     esi, [ebp+NTFS.cur_index_buf]
2288 clevermous 1446
        mov     eax, [esi+14h]
1447
        add     eax, 10h
3742 clevermous 1448
        cmp     [ebp+NTFS.ntfs_cur_read], eax
2288 clevermous 1449
        jae     .readok1
1450
        add     eax, 1FFh
1451
        shr     eax, 9
3742 clevermous 1452
        cmp     eax, [ebp+NTFS.cur_index_size]
2288 clevermous 1453
        ja      @f
1454
        popad
1455
        jmp     .fserr
1456
@@:
1457
; reallocate
1458
        push    eax
3742 clevermous 1459
        push    [ebp+NTFS.cur_index_buf]
2288 clevermous 1460
        call    kernel_free
1461
        pop     eax
3742 clevermous 1462
        mov     [ebp+NTFS.cur_index_size], eax
2288 clevermous 1463
        push    eax
1464
        call    kernel_alloc
1465
        test    eax, eax
1466
        jnz     @f
3742 clevermous 1467
        and     [ebp+NTFS.cur_index_size], 0
1468
        and     [ebp+NTFS.cur_index_buf], 0
2288 clevermous 1469
.nomem:
3742 clevermous 1470
        call    ntfs_unlock
2288 clevermous 1471
        popad
1472
        or      ebx, -1
3598 clevermous 1473
        movi    eax, 12
2288 clevermous 1474
        ret
1475
@@:
3742 clevermous 1476
        mov     [ebp+NTFS.cur_index_buf], eax
2288 clevermous 1477
        popad
1478
        jmp     .doit2
1479
.readok1:
3742 clevermous 1480
        mov     edx, [esi+8]    ; subnode_size
1481
        shr     edx, 9
1482
        mov     [ebp+NTFS.cur_subnode_size], edx
1483
        cmp     edx, [ebp+NTFS.cur_index_size]
2288 clevermous 1484
        jbe     .ok2
3742 clevermous 1485
        push    esi edx
1486
        push    edx
2288 clevermous 1487
        call    kernel_alloc
3742 clevermous 1488
        pop     edx esi
2288 clevermous 1489
        test    eax, eax
1490
        jz      .nomem
1491
        mov     edi, eax
3742 clevermous 1492
        mov     ecx, [ebp+NTFS.cur_index_size]
2288 clevermous 1493
        shl     ecx, 9-2
1494
        rep movsd
1495
        mov     esi, eax
3742 clevermous 1496
        mov     [ebp+NTFS.cur_index_size], edx
1497
        push    [ebp+NTFS.cur_index_buf]
2288 clevermous 1498
        call    kernel_free
3742 clevermous 1499
        mov     [ebp+NTFS.cur_index_buf], esi
2288 clevermous 1500
.ok2:
1501
        add     esi, 10h
3742 clevermous 1502
        mov     edx, [ebx+16]
1503
        push    dword [ebx+8]   ; read ANSI/UNICODE name
2288 clevermous 1504
; init header
1505
        mov     edi, edx
1506
        mov     ecx, 32/4
1507
        xor     eax, eax
1508
        rep stosd
1509
        mov     byte [edx], 1   ; version
3742 clevermous 1510
        mov     ecx, [ebx+12]
1511
        mov     ebx, [ebx+4]
2288 clevermous 1512
        push    edx
1513
        mov     edx, esp
3742 clevermous 1514
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
2288 clevermous 1515
; ecx = number of blocks to read
1516
; edx -> parameters block: dd , dd 
3742 clevermous 1517
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 5
2288 clevermous 1518
        jz      .skip_specials
1519
; dot and dotdot entries
1520
        push    esi
1521
        xor     esi, esi
1522
        call    .add_special_entry
1523
        inc     esi
1524
        call    .add_special_entry
1525
        pop     esi
1526
.skip_specials:
1527
; at first, dump index root
1528
        add     esi, [esi]
1529
.dump_root:
1530
        test    byte [esi+0Ch], 2
1531
        jnz     .dump_root_done
1532
        call    .add_entry
1533
        movzx   eax, word [esi+8]
1534
        add     esi, eax
1535
        jmp     .dump_root
1536
.dump_root_done:
1537
; now dump all subnodes
1538
        push    ecx edi
3742 clevermous 1539
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
1540
        mov     [ebp+NTFS.ntfs_cur_buf], edi
2288 clevermous 1541
        mov     ecx, 0x400/4
1542
        xor     eax, eax
1543
        rep stosd
3742 clevermous 1544
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0   ; $BITMAP
1545
        and     [ebp+NTFS.ntfs_cur_offs], 0
1546
        mov     [ebp+NTFS.ntfs_cur_size], 2
2288 clevermous 1547
        call    ntfs_read_attr
1548
        pop     edi ecx
1549
        push    0       ; save offset in $BITMAP attribute
3742 clevermous 1550
        and     [ebp+NTFS.ntfs_cur_offs], 0
2288 clevermous 1551
.dumploop:
3742 clevermous 1552
        mov     [ebp+NTFS.ntfs_cur_attr], 0xA0
1553
        mov     eax, [ebp+NTFS.cur_subnode_size]
1554
        mov     [ebp+NTFS.ntfs_cur_size], eax
1555
        mov     eax, [ebp+NTFS.cur_index_buf]
2288 clevermous 1556
        mov     esi, eax
3742 clevermous 1557
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1558
        push    [ebp+NTFS.ntfs_cur_offs]
1559
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
1560
        imul    eax, [ebp+NTFS.cur_subnode_size]
1561
        mov     [ebp+NTFS.ntfs_cur_offs], eax
2288 clevermous 1562
        call    ntfs_read_attr
3742 clevermous 1563
        pop     [ebp+NTFS.ntfs_cur_offs]
1564
        mov     eax, [ebp+NTFS.cur_subnode_size]
2288 clevermous 1565
        shl     eax, 9
3742 clevermous 1566
        cmp     [ebp+NTFS.ntfs_cur_read], eax
2288 clevermous 1567
        jnz     .done
1568
        push    eax
3742 clevermous 1569
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 1570
        and     eax, 0x400*8-1
3742 clevermous 1571
        bt      dword [ebp+NTFS.ntfs_bitmap_buf], eax
2288 clevermous 1572
        pop     eax
1573
        jnc     .dump_subnode_done
1574
        cmp     dword [esi], 'INDX'
1575
        jnz     .dump_subnode_done
1576
        push    ebx
1577
        mov     ebx, esi
1578
        call    ntfs_restore_usa
1579
        pop     ebx
1580
        jc      .dump_subnode_done
1581
        add     esi, 0x18
1582
        add     esi, [esi]
1583
.dump_subnode:
1584
        test    byte [esi+0Ch], 2
1585
        jnz     .dump_subnode_done
1586
        call    .add_entry
1587
        movzx   eax, word [esi+8]
1588
        add     esi, eax
1589
        jmp     .dump_subnode
1590
.dump_subnode_done:
3742 clevermous 1591
        inc     [ebp+NTFS.ntfs_cur_offs]
1592
        test    [ebp+NTFS.ntfs_cur_offs], 0x400*8-1
2288 clevermous 1593
        jnz     .dumploop
3742 clevermous 1594
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0
2288 clevermous 1595
        push    ecx edi
3742 clevermous 1596
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
1597
        mov     [ebp+NTFS.ntfs_cur_buf], edi
2288 clevermous 1598
        mov     ecx, 0x400/4
1599
        xor     eax, eax
1600
        rep stosd
1601
        pop     edi ecx
1602
        pop     eax
3742 clevermous 1603
        push    [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 1604
        inc     eax
3742 clevermous 1605
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1606
        mov     [ebp+NTFS.ntfs_cur_size], 2
2288 clevermous 1607
        push    eax
1608
        call    ntfs_read_attr
1609
        pop     eax
3742 clevermous 1610
        pop     [ebp+NTFS.ntfs_cur_offs]
2288 clevermous 1611
        push    eax
1612
        jmp     .dumploop
1613
.done:
1614
        pop     eax
1615
        pop     edx
1616
        mov     ebx, [edx+4]
1617
        pop     edx
1618
        xor     eax, eax
1619
        dec     ecx
1620
        js      @f
1621
        mov     al, ERROR_END_OF_FILE
1622
@@:
1623
        mov     [esp+1Ch], eax
1624
        mov     [esp+10h], ebx
3742 clevermous 1625
        call    ntfs_unlock
2288 clevermous 1626
        popad
1627
        ret
1628
 
1629
.add_special_entry:
1630
        mov     eax, [edx]
1631
        inc     dword [eax+8]   ; new file found
1632
        dec     ebx
1633
        jns     .ret
1634
        dec     ecx
1635
        js      .ret
1636
        inc     dword [eax+4]   ; new file block copied
1637
        mov     eax, [edx+4]
1638
        mov     [edi+4], eax
1639
;        mov     eax, dword [ntfs_bitmap_buf+0x20]
1640
;        or      al, 0x10
1641
        mov     eax, 0x10
1642
        stosd
1643
        scasd
1644
        push    edx
3742 clevermous 1645
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf]
1646
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+4]
2288 clevermous 1647
        call    ntfs_datetime_to_bdfe
3742 clevermous 1648
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18]
1649
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C]
2288 clevermous 1650
        call    ntfs_datetime_to_bdfe
3742 clevermous 1651
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf+8]
1652
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC]
2288 clevermous 1653
        call    ntfs_datetime_to_bdfe
1654
        pop     edx
1655
        xor     eax, eax
1656
        stosd
1657
        stosd
1658
        mov     al, '.'
1659
        push    edi ecx
1660
        lea     ecx, [esi+1]
1661
        test    byte [edi-0x24], 1
1662
        jz      @f
1663
        rep stosw
1664
        pop     ecx
1665
        xor     eax, eax
1666
        stosw
1667
        pop     edi
1668
        add     edi, 520
1669
        ret
1670
@@:
1671
        rep stosb
1672
        pop     ecx
1673
        xor     eax, eax
1674
        stosb
1675
        pop     edi
1676
        add     edi, 264
1677
.ret:
1678
        ret
1679
 
1680
.add_entry:
1681
; do not return DOS 8.3 names
1682
        cmp     byte [esi+0x51], 2
1683
        jz      .ret
1684
; do not return system files
1685
; ... note that there will be no bad effects if system files also were reported ...
1686
        cmp     dword [esi], 0x10
1687
        jb      .ret
1688
        mov     eax, [edx]
1689
        inc     dword [eax+8]   ; new file found
1690
        dec     ebx
1691
        jns     .ret
1692
        dec     ecx
1693
        js      .ret
1694
        inc     dword [eax+4]   ; new file block copied
1695
        mov     eax, [edx+4]    ; flags
1696
        call    ntfs_direntry_to_bdfe
1697
        push    ecx esi edi
1698
        movzx   ecx, byte [esi+0x50]
1699
        add     esi, 0x52
1700
        test    byte [edi-0x24], 1
1701
        jz      .ansi
1702
        shr     ecx, 1
1703
        rep movsd
1704
        adc     ecx, ecx
1705
        rep movsw
1706
        and     word [edi], 0
1707
        pop     edi
1708
        add     edi, 520
1709
        pop     esi ecx
1710
        ret
1711
.ansi:
1712
        jecxz   .skip
1713
@@:
1714
        lodsw
1715
        call    uni2ansi_char
1716
        stosb
1717
        loop    @b
1718
.skip:
1719
        xor     al, al
1720
        stosb
1721
        pop     edi
1722
        add     edi, 264
1723
        pop     esi ecx
1724
        ret
1725
 
1726
ntfs_direntry_to_bdfe:
1727
        mov     [edi+4], eax    ; ANSI/UNICODE name
1728
        mov     eax, [esi+48h]
1729
        test    eax, 0x10000000
1730
        jz      @f
1731
        and     eax, not 0x10000000
1732
        or      al, 0x10
1733
@@:
1734
        stosd
1735
        scasd
1736
        push    edx
1737
        mov     eax, [esi+0x18]
1738
        mov     edx, [esi+0x1C]
1739
        call    ntfs_datetime_to_bdfe
1740
        mov     eax, [esi+0x30]
1741
        mov     edx, [esi+0x34]
1742
        call    ntfs_datetime_to_bdfe
1743
        mov     eax, [esi+0x20]
1744
        mov     edx, [esi+0x24]
1745
        call    ntfs_datetime_to_bdfe
1746
        pop     edx
1747
        mov     eax, [esi+0x40]
1748
        stosd
1749
        mov     eax, [esi+0x44]
1750
        stosd
1751
        ret
1752
 
1753
iglobal
1754
_24             dd      24
1755
_60             dd      60
1756
_10000000       dd      10000000
1757
days400year     dd      365*400+100-4+1
1758
days100year     dd      365*100+25-1
1759
days4year       dd      365*4+1
1760
days1year       dd      365
1761
months  dd      31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1762
months2 dd      31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1763
_400            dd      400
1764
_100            dd      100
1765
endg
1766
 
1767
ntfs_datetime_to_bdfe:
1768
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
1769
        push    eax
1770
        mov     eax, edx
1771
        xor     edx, edx
1772
        div     [_10000000]
1773
        xchg    eax, [esp]
1774
        div     [_10000000]
1775
        pop     edx
1776
    .sec:
1777
; edx:eax = number of seconds since January 1, 1601
1778
        push    eax
1779
        mov     eax, edx
1780
        xor     edx, edx
1781
        div     [_60]
1782
        xchg    eax, [esp]
1783
        div     [_60]
1784
        mov     [edi], dl
1785
        pop     edx
1786
; edx:eax = number of minutes
1787
        div     [_60]
1788
        mov     [edi+1], dl
1789
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
1790
        xor     edx, edx
1791
        div     [_24]
1792
        mov     [edi+2], dl
1793
        mov     [edi+3], byte 0
1794
; eax = number of days since January 1, 1601
1795
        xor     edx, edx
1796
        div     [days400year]
1797
        imul    eax, 400
1798
        add     eax, 1601
1799
        mov     [edi+6], ax
1800
        mov     eax, edx
1801
        xor     edx, edx
1802
        div     [days100year]
1803
        cmp     al, 4
1804
        jnz     @f
1805
        dec     eax
1806
        add     edx, [days100year]
1807
@@:
1808
        imul    eax, 100
1809
        add     [edi+6], ax
1810
        mov     eax, edx
1811
        xor     edx, edx
1812
        div     [days4year]
1813
        shl     eax, 2
1814
        add     [edi+6], ax
1815
        mov     eax, edx
1816
        xor     edx, edx
1817
        div     [days1year]
1818
        cmp     al, 4
1819
        jnz     @f
1820
        dec     eax
1821
        add     edx, [days1year]
1822
@@:
1823
        add     [edi+6], ax
1824
        push    esi edx
1825
        mov     esi, months
1826
        movzx   eax, word [edi+6]
1827
        test    al, 3
1828
        jnz     .noleap
1829
        xor     edx, edx
1830
        push    eax
1831
        div     [_400]
1832
        pop     eax
1833
        test    edx, edx
1834
        jz      .leap
1835
        xor     edx, edx
1836
        div     [_100]
1837
        test    edx, edx
1838
        jz      .noleap
1839
.leap:
1840
        mov     esi, months2
1841
.noleap:
1842
        pop     edx
1843
        xor     eax, eax
1844
        inc     eax
1845
@@:
1846
        sub     edx, [esi]
1847
        jb      @f
1848
        add     esi, 4
1849
        inc     eax
1850
        jmp     @b
1851
@@:
1852
        add     edx, [esi]
1853
        pop     esi
1854
        inc     edx
1855
        mov     [edi+4], dl
1856
        mov     [edi+5], al
1857
        add     edi, 8
1858
        ret
1859
 
1860
;----------------------------------------------------------------
3742 clevermous 1861
; ntfs_Rewrite - NTFS implementation of creating a new file
1862
; in:  ebp = pointer to NTFS structure
1863
; in:  esi+[esp+4] = name
1864
; in:  ebx = pointer to parameters from sysfunc 70
1865
; out: eax, ebx = return values for sysfunc 70
1866
;----------------------------------------------------------------
1867
ntfs_Rewrite:
1868
ntfs_CreateFolder:
2288 clevermous 1869
        xor     ebx, ebx
1870
        mov     eax, ERROR_UNSUPPORTED_FS
1871
        ret
1872
 
1873
;----------------------------------------------------------------
3742 clevermous 1874
; ntfs_Write - NTFS implementation of writing to file
1875
; in:  ebp = pointer to NTFS structure
1876
; in:  esi+[esp+4] = name
1877
; in:  ebx = pointer to parameters from sysfunc 70
1878
; out: eax, ebx = return values for sysfunc 70
1879
;----------------------------------------------------------------
1880
ntfs_Write:
2288 clevermous 1881
        xor     ebx, ebx
1882
        mov     eax, ERROR_UNSUPPORTED_FS
1883
        ret
1884
 
3742 clevermous 1885
ntfs_SetFileEnd:
1886
ntfs_SetFileInfo:
1887
ntfs_Delete:
2288 clevermous 1888
        mov     eax, ERROR_UNSUPPORTED_FS
1889
        ret
1890
 
3742 clevermous 1891
;----------------------------------------------------------------
1892
; ntfs_GetFileInfo - NTFS implementation of getting file info
1893
; in:  ebp = pointer to NTFS structure
1894
; in:  esi+[esp+4] = name
1895
; in:  ebx = pointer to parameters from sysfunc 70
1896
; out: eax, ebx = return values for sysfunc 70
1897
;----------------------------------------------------------------
1898
ntfs_GetFileInfo:
2288 clevermous 1899
        cmp     byte [esi], 0
1900
        jnz     @f
3598 clevermous 1901
        movi    eax, 2
2288 clevermous 1902
        ret
1903
@@:
3742 clevermous 1904
        call    ntfs_lock
1905
        stdcall ntfs_find_lfn, [esp+4]
2288 clevermous 1906
        jnc     .doit
3742 clevermous 1907
        test    eax, eax
3598 clevermous 1908
        movi    eax, ERROR_FILE_NOT_FOUND
2288 clevermous 1909
        jz      @f
1910
        mov     al, 11
1911
@@:
3742 clevermous 1912
        push    eax
1913
        call    ntfs_unlock
1914
        pop     eax
2288 clevermous 1915
        ret
1916
.doit:
1917
        push    esi edi
1918
        mov     esi, eax
3742 clevermous 1919
        mov     edi, [ebx+16]
2288 clevermous 1920
        xor     eax, eax
1921
        call    ntfs_direntry_to_bdfe
1922
        pop     edi esi
3742 clevermous 1923
        call    ntfs_unlock
2288 clevermous 1924
        xor     eax, eax
1925
        ret
1926