Subversion Repositories Kolibri OS

Rev

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

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