Subversion Repositories Kolibri OS

Rev

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

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