Subversion Repositories Kolibri OS

Rev

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

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