Subversion Repositories Kolibri OS

Rev

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

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