Subversion Repositories Kolibri OS

Rev

Rev 521 | Rev 820 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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