Subversion Repositories Kolibri OS

Rev

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

Rev 5984 Rev 6078
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. 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: 5984 $
8
$Revision: 6078 $
9
 
9
 
10
; NTFS driver
10
; NTFS driver
11
 
11
 
12
; Basic concepts:
12
; Basic concepts:
13
; File is a FileRecord in the $MFT.
13
; File is a FileRecord in the $MFT.
14
; $MFT is a file, that consists of FileRecords and starts with FileRecord of itself.
14
; $MFT is a file, that consists of FileRecords and starts with FileRecord of itself.
15
; FileRecord (FILE) consists of a header and attributes.
15
; FileRecord (FILE) consists of a header and attributes.
16
; Attribute consists of a header and a body.
16
; Attribute consists of a header and a body.
17
; Attribute's body can be inside (resident) or outside of FileRecord.
17
; Attribute's body can be inside (resident) or outside of FileRecord.
18
; File's data is a body of $Data (80h) attribute.
18
; File's data is a body of $Data (80h) attribute.
19
; FileRecords is a data of the $MFT file.
19
; FileRecords is a data of the $MFT file.
20
; Directory is a file, that consists of index nodes.
20
; Directory is a file, that consists of index nodes.
21
; Resident index node is always located in a body of $IndexRoot (90h) attribute.
21
; Resident index node is always located in a body of $IndexRoot (90h) attribute.
22
; Body of $IndexAllocation (A0h) attribute is always non resident
22
; Body of $IndexAllocation (A0h) attribute is always non resident
23
;  and consists of IndexRecords.
23
;  and consists of IndexRecords.
24
; IndexRecord (INDX) consists of a header and an index node.
24
; IndexRecord (INDX) consists of a header and an index node.
25
; Index node consists of a header and indexes.
25
; Index node consists of a header and indexes.
26
; Index consists of a header and a copy of indexed attribute's body.
26
; Index consists of a header and a copy of indexed attribute's body.
27
; Directories index $Filename (30h) attribute of all existing files.
27
; Directories index $Filename (30h) attribute of all existing files.
28
; $IndexRoot and $IndexAllocation attributes of a directory has a name — $I30.
28
; $IndexRoot and $IndexAllocation attributes of a directory has a name — $I30.
29
 
29
 
30
; Offsets:
30
; Offsets:
31
    ; record header
31
    ; record header
32
updateSequenceOffset = 4
32
updateSequenceOffset = 4
33
updateSequenceSize = 6
33
updateSequenceSize = 6
34
reuseCounter = 16
34
reuseCounter = 16
35
hardLinkCounter = 12h
35
hardLinkCounter = 12h
36
attributeOffset = 14h
36
attributeOffset = 14h
37
recordFlags = 16h
37
recordFlags = 16h
38
recordRealSize = 18h
38
recordRealSize = 18h
39
recordAllocatedSize = 1ch
39
recordAllocatedSize = 1ch
-
 
40
baseRecordReference = 20h       ; for auxiliary records
-
 
41
baseRecordReuse = 26h
40
newAttributeID = 28h
42
newAttributeID = 28h
41
    ; attribute header
43
    ; attribute header
42
attributeType = 0
44
attributeType = 0
43
sizeWithHeader = 4
45
sizeWithHeader = 4
44
nonResidentFlag = 8
46
nonResidentFlag = 8
45
nameLength = 9
47
nameLength = 9
46
nameOffset = 10
48
nameOffset = 10
-
 
49
attributeFlags = 12
47
attributeID = 14
50
attributeID = 14
48
sizeWithoutHeader = 16
51
sizeWithoutHeader = 16
49
attributeFlags = 16h
52
indexedFlag = 16h
50
    ; non resident attribute header
53
    ; non resident attribute header
51
lastVCN = 18h
54
lastVCN = 18h
52
dataRunsOffset = 20h
55
dataRunsOffset = 20h
53
attributeAllocatedSize = 28h
56
attributeAllocatedSize = 28h
54
attributeRealSize = 30h
57
attributeRealSize = 30h
55
initialDataSize = 38h
58
initialDataSize = 38h
56
    ; $IndexRoot
59
    ; $IndexRoot
57
collationRule = 4
60
collationRule = 4
58
indexRecordSize = 8
61
indexRecordSize = 8
59
indexRecordSizeClus = 12
62
indexRecordSizeClus = 12
60
    ; node header
63
    ; node header
61
indexOffset = 0
64
indexOffset = 0
62
nodeRealSize = 4
65
nodeRealSize = 4
63
nodeAllocatedSize = 8
66
nodeAllocatedSize = 8
64
    ; $Filename index
67
    ; $Filename index
65
fileRecordReference = 0
68
fileRecordReference = 0
66
fileReferenceReuse = 6
69
fileReferenceReuse = 6
67
indexAllocatedSize = 8
70
indexAllocatedSize = 8
68
indexRawSize = 10
71
indexRawSize = 10
69
indexFlags = 12
72
indexFlags = 12
70
directoryRecordReference = 16
73
directoryRecordReference = 16
71
directoryReferenceReuse = 16h
74
directoryReferenceReuse = 16h
72
fileAllocatedSize = 38h
75
fileAllocatedSize = 38h
73
fileRealSize = 40h
76
fileRealSize = 40h
74
fileFlags = 48h
77
fileFlags = 48h
75
fileNameLength = 50h
78
fileNameLength = 50h
76
 
79
 
77
struct NTFS PARTITION
80
struct NTFS PARTITION
78
Lock                MUTEX   ?   ; Currently operations with one partition
81
Lock                MUTEX   ?   ; Currently operations with one partition
79
; can not be executed in parallel since the legacy code is not ready.
82
; can not be executed in parallel since the legacy code is not ready.
80
sectors_per_cluster     dd  ?
83
sectors_per_cluster     dd  ?
81
mft_cluster             dd  ?   ; location
84
mft_cluster             dd  ?   ; location
82
mftmirr_cluster         dd  ?   ; location
85
mftmirr_cluster         dd  ?   ; location
83
frs_size                dd  ?   ; in bytes
86
frs_size                dd  ?   ; in bytes
84
frs_buffer              dd  ?   ; MFT fileRecord buffer
87
frs_buffer              dd  ?   ; MFT fileRecord buffer
85
mft_retrieval           dd  ?
88
mft_retrieval           dd  ?
86
mft_retrieval_size      dd  ?
89
mft_retrieval_size      dd  ?
87
mft_retrieval_alloc     dd  ?
90
mft_retrieval_alloc     dd  ?
88
mft_retrieval_end       dd  ?
91
mft_retrieval_end       dd  ?
89
cur_index_size          dd  ?   ; in sectors
92
cur_index_size          dd  ?   ; in sectors
90
cur_index_buf           dd  ?   ; index node buffer
93
cur_index_buf           dd  ?   ; index node buffer
91
BitmapBuffer            dd  ?
94
BitmapBuffer            dd  ?
92
BitmapTotalSize         dd  ?   ; bytes reserved
95
BitmapTotalSize         dd  ?   ; bytes reserved
93
BitmapSize              dd  ?   ; bytes readen
96
BitmapSize              dd  ?   ; bytes readen
94
BitmapLocation          dd  ?   ; starting sector
97
BitmapLocation          dd  ?   ; starting sector
95
BitmapStart             dd  ?   ; first byte after area, reserved for MFT
98
BitmapStart             dd  ?   ; first byte after area, reserved for MFT
96
mftBitmapBuffer         dd  ?   ; one cluster
99
mftBitmapBuffer         dd  ?   ; one cluster
97
mftBitmapSize           dd  ?   ; bytes readen
100
mftBitmapSize           dd  ?   ; bytes readen
98
mftBitmapLocation       dd  ?   ; starting sector
101
mftBitmapLocation       dd  ?   ; starting sector
99
 
102
 
100
ntfs_cur_attr           dd  ?   ; attribute type
103
ntfs_cur_attr           dd  ?   ; attribute type
101
ntfs_cur_iRecord        dd  ?   ; number of fileRecord in MFT
104
ntfs_cur_iRecord        dd  ?   ; number of fileRecord in MFT
102
ntfs_cur_offs           dd  ?   ; attribute VCN in sectors
105
ntfs_cur_offs           dd  ?   ; attribute VCN in sectors
103
ntfs_cur_size           dd  ?   ; max sectors to read
106
ntfs_cur_size           dd  ?   ; max sectors to read
104
ntfs_cur_buf            dd  ?
107
ntfs_cur_buf            dd  ?
105
ntfs_cur_read           dd  ?   ; bytes readen
108
ntfs_cur_read           dd  ?   ; bytes readen
106
ntfsLastRead            dd  ?   ; last readen block of sectors
109
ntfsLastRead            dd  ?   ; last readen block of sectors
107
newMftRecord            dd  ?   ; number of fileRecord in MFT
110
newMftRecord            dd  ?   ; number of fileRecord in MFT
108
fileDataStart           dd  ?   ; starting cluster
111
fileDataStart           dd  ?   ; starting cluster
109
fileDataSize            dd  ?   ; in clusters
112
fileDataSize            dd  ?   ; in clusters
110
fileRealSize            dd  ?   ; in bytes
113
fileRealSize            dd  ?   ; in bytes
111
indexOffset             dd  ?
114
indexOffset             dd  ?
112
nodeLastRead            dd  ?
115
nodeLastRead            dd  ?
113
ntfs_bCanContinue       db  ?
116
ntfs_bCanContinue       db  ?
114
ntfsNotFound            db  ?
-
 
115
ntfsFolder              db  ?
117
ntfsFolder              db  ?
-
 
118
ntfsWriteAttr           db  ?   ; Warning: Don't forget to turn off!!!
116
ntfsFragmentCount       db  ?
119
ntfsFragmentCount       db  ?
117
 
120
 
118
cur_subnode_size        dd  ?
121
cur_subnode_size        dd  ?
119
ntfs_attr_iRecord       dd  ?
122
ntfs_attr_iRecord       dd  ?
120
ntfs_attr_iBaseRecord   dd  ?
123
ntfs_attr_iBaseRecord   dd  ?
121
ntfs_attr_offs          dd  ?
124
ntfs_attr_offs          dd  ?
122
ntfs_attr_list          dd  ?
125
ntfs_attr_list          dd  ?
123
ntfs_attr_size          dq  ?
126
ntfs_attr_size          dq  ?
124
ntfs_cur_tail           dd  ?
127
ntfs_cur_tail           dd  ?
125
 
128
 
126
ntfs_attrlist_buf       rb  0x400
129
ntfs_attrlist_buf       rb  0x400
127
ntfs_attrlist_mft_buf   rb  0x400
130
ntfs_attrlist_mft_buf   rb  0x400
128
ntfs_bitmap_buf         rb  0x400
131
ntfs_bitmap_buf         rb  0x400
129
ends
132
ends
130
 
133
 
131
; NTFS external functions
134
; NTFS external functions
132
;   in:
135
;   in:
133
; ebx -> parameter structure of sysfunc 70
136
; ebx -> parameter structure of sysfunc 70
134
; ebp -> NTFS structure
137
; ebp -> NTFS structure
135
; [esi]+[esp+4] = name
138
; [esi]+[esp+4] = name
136
;   out:
139
;   out:
137
; eax, ebx = return values for sysfunc 70
140
; eax, ebx = return values for sysfunc 70
138
iglobal
141
iglobal
139
align 4
142
align 4
140
ntfs_user_functions:
143
ntfs_user_functions:
141
        dd      ntfs_free
144
        dd      ntfs_free
142
        dd      (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
145
        dd      (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
143
        dd      ntfs_ReadFile
146
        dd      ntfs_ReadFile
144
        dd      ntfs_ReadFolder
147
        dd      ntfs_ReadFolder
145
        dd      ntfs_CreateFile
148
        dd      ntfs_CreateFile
146
        dd      ntfs_Write
149
        dd      ntfs_WriteFile
147
        dd      ntfs_SetFileEnd
150
        dd      ntfs_SetFileEnd
148
        dd      ntfs_GetFileInfo
151
        dd      ntfs_GetFileInfo
149
        dd      ntfs_SetFileInfo
152
        dd      ntfs_SetFileInfo
150
        dd      0
153
        dd      0
151
        dd      ntfs_Delete
154
        dd      ntfs_Delete
152
        dd      ntfs_CreateFolder
155
        dd      ntfs_CreateFolder
153
ntfs_user_functions_end:
156
ntfs_user_functions_end:
154
endg
157
endg
155
 
158
 
156
ntfs_test_bootsec:
159
ntfs_test_bootsec:
157
; in: ebx -> buffer, edx = size of partition
160
; in: ebx -> buffer, edx = size of partition
158
; out: CF=1 -> invalid
161
; out: CF=1 -> invalid
159
; 1. Name=='NTFS    '
162
; 1. Name=='NTFS    '
160
        cmp     dword [ebx+3], 'NTFS'
163
        cmp     dword [ebx+3], 'NTFS'
161
        jnz     .no
164
        jnz     .no
162
        cmp     dword [ebx+7], '    '
165
        cmp     dword [ebx+7], '    '
163
        jnz     .no
166
        jnz     .no
164
; 2. Number of bytes per sector is the same as for physical device
167
; 2. Number of bytes per sector is the same as for physical device
165
; (that is, 0x200 for hard disk)
168
; (that is, 0x200 for hard disk)
166
        cmp     word [ebx+11], 0x200
169
        cmp     word [ebx+11], 0x200
167
        jnz     .no
170
        jnz     .no
168
; 3. Number of sectors per cluster must be power of 2
171
; 3. Number of sectors per cluster must be power of 2
169
        movzx   eax, byte [ebx+13]
172
        movzx   eax, byte [ebx+13]
170
        dec     eax
173
        dec     eax
171
        js      .no
174
        js      .no
172
        test    al, [ebx+13]
175
        test    al, [ebx+13]
173
        jnz     .no
176
        jnz     .no
174
; 4. FAT parameters must be zero
177
; 4. FAT parameters must be zero
175
        cmp     word [ebx+14], 0
178
        cmp     word [ebx+14], 0
176
        jnz     .no
179
        jnz     .no
177
        cmp     dword [ebx+16], 0
180
        cmp     dword [ebx+16], 0
178
        jnz     .no
181
        jnz     .no
179
        cmp     byte [ebx+20], 0
182
        cmp     byte [ebx+20], 0
180
        jnz     .no
183
        jnz     .no
181
        cmp     word [ebx+22], 0
184
        cmp     word [ebx+22], 0
182
        jnz     .no
185
        jnz     .no
183
        cmp     dword [ebx+32], 0
186
        cmp     dword [ebx+32], 0
184
        jnz     .no
187
        jnz     .no
185
; 5. Number of sectors <= partition size
188
; 5. Number of sectors <= partition size
186
        cmp     dword [ebx+0x2C], 0
189
        cmp     dword [ebx+0x2C], 0
187
        ja      .no
190
        ja      .no
188
        cmp     [ebx+0x28], edx
191
        cmp     [ebx+0x28], edx
189
        ja      .no
192
        ja      .no
190
; 6. $MFT and $MFTMirr clusters must be within partition
193
; 6. $MFT and $MFTMirr clusters must be within partition
191
        cmp     dword [ebx+0x34], 0
194
        cmp     dword [ebx+0x34], 0
192
        ja      .no
195
        ja      .no
193
        push    edx
196
        push    edx
194
        movzx   eax, byte [ebx+13]
197
        movzx   eax, byte [ebx+13]
195
        mul     dword [ebx+0x30]
198
        mul     dword [ebx+0x30]
196
        test    edx, edx
199
        test    edx, edx
197
        pop     edx
200
        pop     edx
198
        jnz     .no
201
        jnz     .no
199
        cmp     eax, edx
202
        cmp     eax, edx
200
        ja      .no
203
        ja      .no
201
        cmp     dword [ebx+0x3C], 0
204
        cmp     dword [ebx+0x3C], 0
202
        ja      .no
205
        ja      .no
203
        push    edx
206
        push    edx
204
        movzx   eax, byte [ebx+13]
207
        movzx   eax, byte [ebx+13]
205
        mul     dword [ebx+0x38]
208
        mul     dword [ebx+0x38]
206
        test    edx, edx
209
        test    edx, edx
207
        pop     edx
210
        pop     edx
208
        jnz     .no
211
        jnz     .no
209
        cmp     eax, edx
212
        cmp     eax, edx
210
        ja      .no
213
        ja      .no
211
; 7. Clusters per FRS must be either power of 2 or between -31 and -9
214
; 7. Clusters per FRS must be either power of 2 or between -31 and -9
212
        movsx   eax, byte [ebx+0x40]
215
        movsx   eax, byte [ebx+0x40]
213
        cmp     al, -31
216
        cmp     al, -31
214
        jl      .no
217
        jl      .no
215
        cmp     al, -9
218
        cmp     al, -9
216
        jle     @f
219
        jle     @f
217
        dec     eax
220
        dec     eax
218
        js      .no
221
        js      .no
219
        test    [ebx+0x40], al
222
        test    [ebx+0x40], al
220
        jnz     .no
223
        jnz     .no
221
@@:         ; 8. Same for clusters per IndexAllocationBuffer
224
@@:         ; 8. Same for clusters per IndexAllocationBuffer
222
        movsx   eax, byte [ebx+0x44]
225
        movsx   eax, byte [ebx+0x44]
223
        cmp     al, -31
226
        cmp     al, -31
224
        jl      .no
227
        jl      .no
225
        cmp     al, -9
228
        cmp     al, -9
226
        jle     @f
229
        jle     @f
227
        dec     eax
230
        dec     eax
228
        js      .no
231
        js      .no
229
        test    [ebx+0x44], al
232
        test    [ebx+0x44], al
230
        jnz     .no
233
        jnz     .no
231
@@:         ; OK, this is correct NTFS bootsector
234
@@:         ; OK, this is correct NTFS bootsector
232
        clc
235
        clc
233
        ret
236
        ret
234
.no:        ; No, this bootsector isn't NTFS
237
.no:        ; No, this bootsector isn't NTFS
235
        stc
238
        stc
236
        ret
239
        ret
237
 
240
 
238
ntfs_create_partition:
241
ntfs_create_partition:
239
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
242
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
240
        jnz     .nope
243
        jnz     .nope
241
        mov     edx, dword [ebp+PARTITION.Length]
244
        mov     edx, dword [ebp+PARTITION.Length]
242
        cmp     dword [esp+4], 0
245
        cmp     dword [esp+4], 0
243
        jz      .boot_read_ok
246
        jz      .boot_read_ok
244
        add     ebx, 512
247
        add     ebx, 512
245
        lea     eax, [edx-1]
248
        lea     eax, [edx-1]
246
        call    fs_read32_sys
249
        call    fs_read32_sys
247
        test    eax, eax
250
        test    eax, eax
248
        jnz     @f
251
        jnz     @f
249
        call    ntfs_test_bootsec
252
        call    ntfs_test_bootsec
250
        jnc     .ntfs_setup
253
        jnc     .ntfs_setup
251
@@:
254
@@:
252
        mov     eax, edx
255
        mov     eax, edx
253
        shr     eax, 1
256
        shr     eax, 1
254
        call    fs_read32_sys
257
        call    fs_read32_sys
255
        test    eax, eax
258
        test    eax, eax
256
        jnz     .nope
259
        jnz     .nope
257
.boot_read_ok:
260
.boot_read_ok:
258
        call    ntfs_test_bootsec
261
        call    ntfs_test_bootsec
259
        jnc     .ntfs_setup
262
        jnc     .ntfs_setup
260
.nope:
263
.nope:
261
        xor     eax, eax
264
        xor     eax, eax
262
        jmp     .exit
265
        jmp     .exit
263
; By given bootsector, initialize some NTFS variables
266
; By given bootsector, initialize some NTFS variables
264
.ntfs_setup:
267
.ntfs_setup:
265
        movi    eax, sizeof.NTFS
268
        movi    eax, sizeof.NTFS
266
        call    malloc
269
        call    malloc
267
        test    eax, eax
270
        test    eax, eax
268
        jz      .exit
271
        jz      .exit
269
        mov     ecx, dword [ebp+PARTITION.FirstSector]
272
        mov     ecx, dword [ebp+PARTITION.FirstSector]
270
        mov     dword [eax+NTFS.FirstSector], ecx
273
        mov     dword [eax+NTFS.FirstSector], ecx
271
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
274
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
272
        mov     dword [eax+NTFS.FirstSector+4], ecx
275
        mov     dword [eax+NTFS.FirstSector+4], ecx
273
        mov     ecx, dword [ebp+PARTITION.Length]
-
 
274
        mov     dword [eax+NTFS.Length], ecx
-
 
275
        mov     ecx, dword [ebp+PARTITION.Length+4]
-
 
276
        mov     dword [eax+NTFS.Length+4], ecx
-
 
277
        mov     ecx, [ebp+PARTITION.Disk]
276
        mov     ecx, [ebp+PARTITION.Disk]
278
        mov     [eax+NTFS.Disk], ecx
277
        mov     [eax+NTFS.Disk], ecx
279
        mov     [eax+NTFS.FSUserFunctions], ntfs_user_functions
278
        mov     [eax+NTFS.FSUserFunctions], ntfs_user_functions
-
 
279
        mov     [eax+NTFS.ntfsWriteAttr], 0
280
 
280
 
281
        push    ebx ebp esi
281
        push    ebx ebp esi
282
        mov     ebp, eax
282
        mov     ebp, eax
283
        lea     ecx, [ebp+NTFS.Lock]
283
        lea     ecx, [ebp+NTFS.Lock]
284
        call    mutex_init
284
        call    mutex_init
285
        movzx   eax, byte [ebx+13]
285
        movzx   eax, byte [ebx+13]
286
        mov     [ebp+NTFS.sectors_per_cluster], eax
286
        mov     [ebp+NTFS.sectors_per_cluster], eax
287
        mov     eax, [ebx+0x28]
287
        mov     eax, [ebx+0x28]
288
        mov     dword [ebp+NTFS.Length], eax
288
        mov     dword [ebp+NTFS.Length], eax
289
        and     dword [ebp+NTFS.Length+4], 0
289
        and     dword [ebp+NTFS.Length+4], 0
290
        mov     eax, [ebx+0x30]
290
        mov     eax, [ebx+0x30]
291
        mov     [ebp+NTFS.mft_cluster], eax
291
        mov     [ebp+NTFS.mft_cluster], eax
292
        mov     eax, [ebx+0x38]
292
        mov     eax, [ebx+0x38]
293
        mov     [ebp+NTFS.mftmirr_cluster], eax
293
        mov     [ebp+NTFS.mftmirr_cluster], eax
294
        movsx   eax, byte [ebx+0x40]
294
        movsx   eax, byte [ebx+0x40]
295
        test    eax, eax
295
        test    eax, eax
296
        js      @f
296
        js      @f
297
        mul     [ebp+NTFS.sectors_per_cluster]
297
        mul     [ebp+NTFS.sectors_per_cluster]
298
        shl     eax, 9
298
        shl     eax, 9
299
        jmp     .1
299
        jmp     .1
300
@@:
300
@@:
301
        neg     eax
301
        neg     eax
302
        mov     ecx, eax
302
        mov     ecx, eax
303
        mov     eax, 1
303
        mov     eax, 1
304
        shl     eax, cl
304
        shl     eax, cl
305
.1:
305
.1:
306
        mov     [ebp+NTFS.frs_size], eax
306
        mov     [ebp+NTFS.frs_size], eax
307
        stdcall kernel_alloc, eax
307
        stdcall kernel_alloc, eax
308
        test    eax, eax
308
        test    eax, eax
309
        jz      .fail_free
309
        jz      .fail_free
310
        mov     [ebp+NTFS.frs_buffer], eax
310
        mov     [ebp+NTFS.frs_buffer], eax
311
; read $MFT disposition
311
; read $MFT disposition
312
        mov     eax, [ebp+NTFS.mft_cluster]
312
        mov     eax, [ebp+NTFS.mft_cluster]
313
        mul     [ebp+NTFS.sectors_per_cluster]
313
        mul     [ebp+NTFS.sectors_per_cluster]
314
        call    ntfs_read_frs_sector
314
        call    ntfs_read_frs_sector
315
        test    eax, eax
315
        test    eax, eax
316
        jnz     .usemirr
316
        jnz     .usemirr
317
        cmp     dword [ebx], 'FILE'
317
        cmp     dword [ebx], 'FILE'
318
        jnz     .usemirr
318
        jnz     .usemirr
319
        call    ntfs_restore_usa_frs
319
        call    ntfs_restore_usa_frs
320
        jnc     .mftok
320
        jnc     .mftok
321
.usemirr:
321
.usemirr:
322
        mov     eax, [ebp+NTFS.mftmirr_cluster]
322
        mov     eax, [ebp+NTFS.mftmirr_cluster]
323
        mul     [ebp+NTFS.sectors_per_cluster]
323
        mul     [ebp+NTFS.sectors_per_cluster]
324
        call    ntfs_read_frs_sector
324
        call    ntfs_read_frs_sector
325
        test    eax, eax
325
        test    eax, eax
326
        jnz     .fail_free_frs
326
        jnz     .fail_free_frs
327
        cmp     dword [ebx], 'FILE'
327
        cmp     dword [ebx], 'FILE'
328
        jnz     .fail_free_frs
328
        jnz     .fail_free_frs
329
        call    ntfs_restore_usa_frs
329
        call    ntfs_restore_usa_frs
330
        jc      .fail_free_frs
330
        jc      .fail_free_frs
331
.mftok:
331
.mftok:
332
; read $MFT table retrieval information
332
; read $MFT table retrieval information
333
; start with one page, increase if not enough (when MFT too fragmented)
333
; start with one page, increase if not enough (when MFT too fragmented)
334
        push    ebx
334
        push    ebx
335
        stdcall kernel_alloc, 0x1000
335
        stdcall kernel_alloc, 0x1000
336
        pop     ebx
336
        pop     ebx
337
        test    eax, eax
337
        test    eax, eax
338
        jz      .fail_free_frs
338
        jz      .fail_free_frs
339
        mov     [ebp+NTFS.mft_retrieval], eax
339
        mov     [ebp+NTFS.mft_retrieval], eax
340
        and     [ebp+NTFS.mft_retrieval_size], 0
340
        and     [ebp+NTFS.mft_retrieval_size], 0
341
        mov     [ebp+NTFS.mft_retrieval_alloc], 0x1000/8
341
        mov     [ebp+NTFS.mft_retrieval_alloc], 0x1000/8
342
; $MFT base record must contain unnamed non-resident $DATA attribute
342
; $MFT base record must contain unnamed non-resident $DATA attribute
343
        movzx   eax, word [ebx+14h]
343
        movzx   eax, word [ebx+14h]
344
        add     eax, ebx
344
        add     eax, ebx
345
.scandata:
345
.scandata:
346
        cmp     dword [eax], -1
346
        cmp     dword [eax], -1
347
        jz      .fail_free_mft
347
        jz      .fail_free_mft
348
        cmp     dword [eax], 0x80
348
        cmp     dword [eax], 0x80
349
        jnz     @f
349
        jnz     @f
350
        cmp     byte [eax+9], 0
350
        cmp     byte [eax+9], 0
351
        jz      .founddata
351
        jz      .founddata
352
@@:
352
@@:
353
        add     eax, [eax+4]
353
        add     eax, [eax+4]
354
        jmp     .scandata
354
        jmp     .scandata
355
.founddata:
355
.founddata:
356
        cmp     byte [eax+8], 0
356
        cmp     byte [eax+8], 0
357
        jz      .fail_free_mft
357
        jz      .fail_free_mft
358
; load first portion of $DATA attribute retrieval information
358
; load first portion of $DATA attribute retrieval information
359
        mov     edx, [eax+0x18]
359
        mov     edx, [eax+0x18]
360
        mov     [ebp+NTFS.mft_retrieval_end], edx
360
        mov     [ebp+NTFS.mft_retrieval_end], edx
361
        mov     esi, eax
361
        mov     esi, eax
362
        movzx   eax, word [eax+0x20]
362
        movzx   eax, word [eax+0x20]
363
        add     esi, eax
363
        add     esi, eax
364
        sub     esp, 10h
364
        sub     esp, 10h
365
.scanmcb:
365
.scanmcb:
366
        call    ntfs_decode_mcb_entry
366
        call    ntfs_decode_mcb_entry
367
        jnc     .scanmcbend
367
        jnc     .scanmcbend
368
        call    .get_mft_retrieval_ptr
368
        call    .get_mft_retrieval_ptr
369
        mov     edx, [esp]      ; block length
369
        mov     edx, [esp]      ; block length
370
        mov     [eax], edx
370
        mov     [eax], edx
371
        mov     edx, [esp+8]    ; block addr (relative)
371
        mov     edx, [esp+8]    ; block addr (relative)
372
        mov     [eax+4], edx
372
        mov     [eax+4], edx
373
        inc     [ebp+NTFS.mft_retrieval_size]
373
        inc     [ebp+NTFS.mft_retrieval_size]
374
        jmp     .scanmcb
374
        jmp     .scanmcb
375
.scanmcbend:
375
.scanmcbend:
376
        add     esp, 10h
376
        add     esp, 10h
377
; there may be other portions of $DATA attribute in auxiliary records;
377
; there may be other portions of $DATA attribute in auxiliary records;
378
; if they will be needed, they will be loaded later
378
; if they will be needed, they will be loaded later
379
        mov     [ebp+NTFS.cur_index_size], 0x1000/0x200
379
        mov     [ebp+NTFS.cur_index_size], 0x1000/0x200
380
        stdcall kernel_alloc, 0x1000
380
        stdcall kernel_alloc, 0x1000
381
        test    eax, eax
381
        test    eax, eax
382
        jz      .fail_free_mft
382
        jz      .fail_free_mft
383
        mov     [ebp+NTFS.cur_index_buf], eax
383
        mov     [ebp+NTFS.cur_index_buf], eax
384
; reserve adress space for bitmap buffer and load some part of bitmap
384
; reserve adress space for bitmap buffer and load some part of bitmap
385
        mov     eax, dword [ebp+NTFS.Length]
385
        mov     eax, dword [ebp+NTFS.Length]
386
        xor     edx, edx
386
        xor     edx, edx
387
        div     [ebp+NTFS.sectors_per_cluster]
387
        div     [ebp+NTFS.sectors_per_cluster]
388
        shr     eax, 3
388
        shr     eax, 3
389
        mov     [ebp+NTFS.BitmapTotalSize], eax
389
        mov     [ebp+NTFS.BitmapTotalSize], eax
390
        add     eax, 7FFFh
390
        add     eax, 7FFFh
391
        and     eax, not 7FFFh
391
        and     eax, not 7FFFh
392
        push    eax
392
        push    eax
393
        call    alloc_kernel_space
393
        call    alloc_kernel_space
394
        test    eax, eax
394
        test    eax, eax
395
        jz      .failFreeIndex
395
        jz      .failFreeIndex
396
        mov     [ebp+NTFS.BitmapBuffer], eax
396
        mov     [ebp+NTFS.BitmapBuffer], eax
397
        mov     [ebp+NTFS.ntfs_cur_buf], eax
397
        mov     [ebp+NTFS.ntfs_cur_buf], eax
398
        mov     eax, [ebp+NTFS.BitmapTotalSize]
398
        mov     eax, [ebp+NTFS.BitmapTotalSize]
399
        add     eax, [ebp+NTFS.mft_cluster]
399
        add     eax, [ebp+NTFS.mft_cluster]
400
        shr     eax, 3+2        ; reserve 1/8 of partition for $MFT
400
        shr     eax, 3+2        ; reserve 1/8 of partition for $MFT
401
        shl     eax, 2
401
        shl     eax, 2
402
        mov     [ebp+NTFS.BitmapStart], eax
402
        mov     [ebp+NTFS.BitmapStart], eax
403
        shr     eax, 15
403
        shr     eax, 15
404
        inc     eax
404
        inc     eax
405
        shl     eax, 3
405
        shl     eax, 3
406
        push    eax
406
        push    eax
407
        push    eax
407
        push    eax
408
        shl     eax, 3
408
        shl     eax, 3
409
        mov     [ebp+NTFS.ntfs_cur_size], eax
409
        mov     [ebp+NTFS.ntfs_cur_size], eax
410
        call    alloc_pages
410
        call    alloc_pages
411
        test    eax, eax
411
        test    eax, eax
412
        pop     ecx
412
        pop     ecx
413
        jz      .failFreeBitmap
413
        jz      .failFreeBitmap
414
        add     eax, 3
414
        add     eax, 3
415
        mov     ebx, [ebp+NTFS.BitmapBuffer]
415
        mov     ebx, [ebp+NTFS.BitmapBuffer]
416
        call    commit_pages
416
        call    commit_pages
417
        mov     [ebp+NTFS.ntfs_cur_iRecord], 6
417
        mov     [ebp+NTFS.ntfs_cur_iRecord], 6
418
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
418
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
419
        mov     [ebp+NTFS.ntfs_cur_offs], 0
419
        mov     [ebp+NTFS.ntfs_cur_offs], 0
420
        call    ntfs_read_attr
420
        call    ntfs_read_attr
421
        jc      .failFreeBitmap
421
        jc      .failFreeBitmap
422
        mov     eax, [ebp+NTFS.ntfs_cur_read]
422
        mov     eax, [ebp+NTFS.ntfs_cur_read]
423
        mov     [ebp+NTFS.BitmapSize], eax
423
        mov     [ebp+NTFS.BitmapSize], eax
424
        mov     eax, [ebp+NTFS.ntfsLastRead]
424
        mov     eax, [ebp+NTFS.ntfsLastRead]
425
        mov     [ebp+NTFS.BitmapLocation], eax
425
        mov     [ebp+NTFS.BitmapLocation], eax
426
; read MFT $BITMAP attribute
426
; read MFT $BITMAP attribute
427
        mov     eax, [ebp+NTFS.sectors_per_cluster]
427
        mov     eax, [ebp+NTFS.sectors_per_cluster]
428
        mov     [ebp+NTFS.ntfs_cur_size], eax
428
        mov     [ebp+NTFS.ntfs_cur_size], eax
429
        shl     eax, 9
429
        shl     eax, 9
430
        stdcall kernel_alloc, eax
430
        stdcall kernel_alloc, eax
431
        test    eax, eax
431
        test    eax, eax
432
        jz      .failFreeBitmap
432
        jz      .failFreeBitmap
433
        mov     [ebp+NTFS.mftBitmapBuffer], eax
433
        mov     [ebp+NTFS.mftBitmapBuffer], eax
434
        mov     [ebp+NTFS.ntfs_cur_buf], eax
434
        mov     [ebp+NTFS.ntfs_cur_buf], eax
435
        mov     [ebp+NTFS.ntfs_cur_iRecord], 0
435
        mov     [ebp+NTFS.ntfs_cur_iRecord], 0
436
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0
436
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0
437
        mov     [ebp+NTFS.ntfs_cur_offs], 0
437
        mov     [ebp+NTFS.ntfs_cur_offs], 0
438
        call    ntfs_read_attr
438
        call    ntfs_read_attr
439
        mov     eax, [ebp+NTFS.ntfs_cur_read]
439
        mov     eax, [ebp+NTFS.ntfs_cur_read]
440
        cmp     eax, 4
440
        cmp     eax, 4
441
        jc      .failFreeBitmapMFT
441
        jc      .failFreeBitmapMFT
442
        mov     [ebp+NTFS.mftBitmapSize], eax
442
        mov     [ebp+NTFS.mftBitmapSize], eax
443
        mov     eax, [ebp+NTFS.ntfsLastRead]
443
        mov     eax, [ebp+NTFS.ntfsLastRead]
444
        mov     [ebp+NTFS.mftBitmapLocation], eax
444
        mov     [ebp+NTFS.mftBitmapLocation], eax
445
 
445
 
446
        mov     eax, ebp
446
        mov     eax, ebp
447
.pop_exit:
447
.pop_exit:
448
        pop     esi ebp ebx
448
        pop     esi ebp ebx
449
.exit:
449
.exit:
450
        cmp     dword [esp+4], 0
450
        cmp     dword [esp+4], 0
451
        jz      @f
451
        jz      @f
452
        sub     ebx, 512
452
        sub     ebx, 512
453
@@:
453
@@:
454
        ret
454
        ret
455
 
455
 
456
.failFreeBitmapMFT:
456
.failFreeBitmapMFT:
457
        stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
457
        stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
458
.failFreeBitmap:
458
.failFreeBitmap:
459
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
459
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
460
.failFreeIndex:
460
.failFreeIndex:
461
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
461
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
462
.fail_free_mft:
462
.fail_free_mft:
463
        stdcall kernel_free, [ebp+NTFS.mft_retrieval]
463
        stdcall kernel_free, [ebp+NTFS.mft_retrieval]
464
.fail_free_frs:
464
.fail_free_frs:
465
        stdcall kernel_free, [ebp+NTFS.frs_buffer]
465
        stdcall kernel_free, [ebp+NTFS.frs_buffer]
466
.fail_free:
466
.fail_free:
467
        mov     eax, ebp
467
        mov     eax, ebp
468
        call    free
468
        call    free
469
        xor     eax, eax
469
        xor     eax, eax
470
        jmp     .pop_exit
470
        jmp     .pop_exit
471
 
471
 
472
.get_mft_retrieval_ptr:
472
.get_mft_retrieval_ptr:
473
        pushad
473
        pushad
474
        mov     eax, [ebp+NTFS.mft_retrieval_size]
474
        mov     eax, [ebp+NTFS.mft_retrieval_size]
475
        cmp     eax, [ebp+NTFS.mft_retrieval_alloc]
475
        cmp     eax, [ebp+NTFS.mft_retrieval_alloc]
476
        jnz     .ok
476
        jnz     .ok
477
        add     eax, 0x1000/8
477
        add     eax, 0x1000/8
478
        mov     [ebp+NTFS.mft_retrieval_alloc], eax
478
        mov     [ebp+NTFS.mft_retrieval_alloc], eax
479
        shl     eax, 3
479
        shl     eax, 3
480
        stdcall kernel_alloc, eax
480
        stdcall kernel_alloc, eax
481
        test    eax, eax
481
        test    eax, eax
482
        jnz     @f
482
        jnz     @f
483
        popad
483
        popad
484
        add     esp, 14h
484
        add     esp, 14h
485
        jmp     .fail_free_mft
485
        jmp     .fail_free_mft
486
@@:
486
@@:
487
        mov     esi, [ebp+NTFS.mft_retrieval]
487
        mov     esi, [ebp+NTFS.mft_retrieval]
488
        mov     edi, eax
488
        mov     edi, eax
489
        mov     ecx, [ebp+NTFS.mft_retrieval_size]
489
        mov     ecx, [ebp+NTFS.mft_retrieval_size]
490
        add     ecx, ecx
490
        add     ecx, ecx
491
        rep movsd
491
        rep movsd
492
        push    [ebp+NTFS.mft_retrieval]
492
        push    [ebp+NTFS.mft_retrieval]
493
        mov     [ebp+NTFS.mft_retrieval], eax
493
        mov     [ebp+NTFS.mft_retrieval], eax
494
        call    kernel_free
494
        call    kernel_free
495
        mov     eax, [ebp+NTFS.mft_retrieval_size]
495
        mov     eax, [ebp+NTFS.mft_retrieval_size]
496
.ok:
496
.ok:
497
        shl     eax, 3
497
        shl     eax, 3
498
        add     eax, [ebp+NTFS.mft_retrieval]
498
        add     eax, [ebp+NTFS.mft_retrieval]
499
        mov     [esp+28], eax
499
        mov     [esp+28], eax
500
        popad
500
        popad
501
        ret
501
        ret
502
 
502
 
503
ntfs_free:
503
ntfs_free:
504
        push    ebx
504
        push    ebx
505
        mov     ebx, eax
505
        mov     ebx, eax
506
        stdcall kernel_free, [ebx+NTFS.frs_buffer]
506
        stdcall kernel_free, [ebx+NTFS.frs_buffer]
507
        stdcall kernel_free, [ebx+NTFS.mft_retrieval]
507
        stdcall kernel_free, [ebx+NTFS.mft_retrieval]
508
        stdcall kernel_free, [ebx+NTFS.cur_index_buf]
508
        stdcall kernel_free, [ebx+NTFS.cur_index_buf]
509
        stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
509
        stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
510
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
510
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
511
        mov     eax, ebx
511
        mov     eax, ebx
512
        pop     ebx
512
        pop     ebx
513
        jmp     free
513
        jmp     free
514
 
514
 
515
ntfs_lock:
515
ntfs_lock:
516
        lea     ecx, [ebp+NTFS.Lock]
516
        lea     ecx, [ebp+NTFS.Lock]
517
        jmp     mutex_lock
517
        jmp     mutex_lock
518
 
518
 
519
ntfs_unlock:
519
ntfs_unlock:
520
        lea     ecx, [ebp+NTFS.Lock]
520
        lea     ecx, [ebp+NTFS.Lock]
521
        jmp     mutex_unlock
521
        jmp     mutex_unlock
522
 
522
 
523
ntfs_read_frs_sector:
523
ntfs_read_frs_sector:
524
        push    ecx
524
        push    ecx
525
        mov     ebx, [ebp+NTFS.frs_buffer]
525
        mov     ebx, [ebp+NTFS.frs_buffer]
526
        push    ebx
526
        push    ebx
527
        mov     ecx, [ebp+NTFS.frs_size]
527
        mov     ecx, [ebp+NTFS.frs_size]
528
        shr     ecx, 9
528
        shr     ecx, 9
529
        push    ecx
529
        push    ecx
530
        mov     ecx, eax
530
        mov     ecx, eax
531
@@:
531
@@:
532
        mov     eax, ecx
532
        mov     eax, ecx
533
        call    fs_read32_sys
533
        call    fs_read32_sys
534
        test    eax, eax
534
        test    eax, eax
535
        jnz     .fail
535
        jnz     .fail
536
        add     ebx, 0x200
536
        add     ebx, 0x200
537
        inc     ecx
537
        inc     ecx
538
        dec     dword [esp]
538
        dec     dword [esp]
539
        jnz     @b
539
        jnz     @b
540
        pop     eax
540
        pop     eax
541
.fail:
541
.fail:
542
        pop     ebx
542
        pop     ebx
543
        pop     ecx
543
        pop     ecx
544
        ret
544
        ret
545
 
545
 
546
ntfs_read_attr:
546
ntfs_read_attr:
-
 
547
; [ebp+NTFS.ntfsWriteAttr]=1 -> write attribute
547
;   in:
548
;   in:
548
; [ebp+NTFS.ntfs_cur_iRecord] = number of fileRecord
549
; [ebp+NTFS.ntfs_cur_iRecord] = number of fileRecord
549
; [ebp+NTFS.ntfs_cur_attr] = attribute type
550
; [ebp+NTFS.ntfs_cur_attr] = attribute type
550
; [ebp+NTFS.ntfs_cur_offs] = attribute VCN in sectors
551
; [ebp+NTFS.ntfs_cur_offs] = attribute VCN in sectors
551
; [ebp+NTFS.ntfs_cur_buf] -> buffer for data
552
; [ebp+NTFS.ntfs_cur_buf] -> buffer for data
552
; [ebp+NTFS.ntfs_cur_size] = max sectors to read
553
; [ebp+NTFS.ntfs_cur_size] = max sectors to read
553
;   out:
554
;   out:
554
; [ebp+NTFS.ntfs_cur_read] = bytes readen
555
; [ebp+NTFS.ntfs_cur_read] = bytes readen
555
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
556
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
556
        xor     eax, eax
557
        xor     eax, eax
557
        pushad
558
        pushad
558
        and     [ebp+NTFS.ntfs_cur_read], 0
559
        and     [ebp+NTFS.ntfs_cur_read], 0
559
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
560
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
560
        jnz     .nomft
561
        jnz     .nomft
561
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
562
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
562
        jnz     .nomft
563
        jnz     .nomft
563
        mov     eax, [ebp+NTFS.mft_retrieval_end]
564
        mov     eax, [ebp+NTFS.mft_retrieval_end]
564
        inc     eax
565
        inc     eax
565
        mul     [ebp+NTFS.sectors_per_cluster]
566
        mul     [ebp+NTFS.sectors_per_cluster]
566
        cmp     eax, [ebp+NTFS.ntfs_cur_offs]
567
        cmp     eax, [ebp+NTFS.ntfs_cur_offs]
567
        jbe     .nomft
568
        jbe     .nomft
568
; precalculated part of $Mft $DATA
569
; precalculated part of $Mft $DATA
569
        mov     esi, [ebp+NTFS.mft_retrieval]
570
        mov     esi, [ebp+NTFS.mft_retrieval]
570
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
571
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
571
        xor     edx, edx
572
        xor     edx, edx
572
        div     [ebp+NTFS.sectors_per_cluster]
573
        div     [ebp+NTFS.sectors_per_cluster]
573
; eax = VCN, edx = offset in sectors from beginning of cluster
574
; eax = VCN, edx = offset in sectors from beginning of cluster
574
        xor     ecx, ecx        ; ecx will contain LCN
575
        xor     ecx, ecx        ; ecx will contain LCN
575
.mftscan:
576
.mftscan:
576
        add     ecx, [esi+4]
577
        add     ecx, [esi+4]
577
        sub     eax, [esi]
578
        sub     eax, [esi]
578
        jb      @f
579
        jb      @f
579
        add     esi, 8
580
        add     esi, 8
580
        push    eax
581
        push    eax
581
        mov     eax, [ebp+NTFS.mft_retrieval_end]
582
        mov     eax, [ebp+NTFS.mft_retrieval_end]
582
        shl     eax, 3
583
        shl     eax, 3
583
        add     eax, [ebp+NTFS.mft_retrieval]
584
        add     eax, [ebp+NTFS.mft_retrieval]
584
        cmp     eax, esi
585
        cmp     eax, esi
585
        pop     eax
586
        pop     eax
586
        jnz     .mftscan
587
        jnz     .mftscan
587
        jmp     .nomft
588
        jmp     .nomft
588
@@:
589
@@:
589
        push    ecx
590
        push    ecx
590
        add     ecx, eax
591
        add     ecx, eax
591
        add     ecx, [esi]
592
        add     ecx, [esi]
592
        push    eax
593
        push    eax
593
        push    edx
594
        push    edx
594
        mov     eax, [ebp+NTFS.sectors_per_cluster]
595
        mov     eax, [ebp+NTFS.sectors_per_cluster]
595
        mul     ecx
596
        mul     ecx
596
; eax = sector on partition
597
; eax = sector on partition
597
        pop     edx
598
        pop     edx
598
        add     eax, edx
599
        add     eax, edx
599
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
600
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
600
        pop     ecx
601
        pop     ecx
601
        neg     ecx
602
        neg     ecx
602
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
603
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
603
        sub     ecx, edx
604
        sub     ecx, edx
604
        mov     [ebp+NTFS.ntfsLastRead], eax
605
        mov     [ebp+NTFS.ntfsLastRead], eax
605
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
606
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
606
        jb      @f
607
        jb      @f
607
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
608
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
608
@@:
609
@@:
609
; ecx = number of sequential sectors to read
610
; ecx = number of sequential sectors to read
610
        push    eax
611
        push    eax
611
        call    fs_read32_sys
612
        call    fs_read32_sys
612
        pop     edx
613
        pop     edx
613
        test    eax, eax
614
        test    eax, eax
614
        jnz     .errread
615
        jnz     .errread
615
        add     [ebp+NTFS.ntfs_cur_read], 0x200
616
        add     [ebp+NTFS.ntfs_cur_read], 0x200
616
        dec     [ebp+NTFS.ntfs_cur_size]
617
        dec     [ebp+NTFS.ntfs_cur_size]
617
        inc     [ebp+NTFS.ntfs_cur_offs]
618
        inc     [ebp+NTFS.ntfs_cur_offs]
618
        add     ebx, 0x200
619
        add     ebx, 0x200
619
        mov     [ebp+NTFS.ntfs_cur_buf], ebx
620
        mov     [ebp+NTFS.ntfs_cur_buf], ebx
620
        lea     eax, [edx+1]
621
        lea     eax, [edx+1]
621
        loop    @b
622
        loop    @b
622
        pop     ecx
623
        pop     ecx
623
        xor     eax, eax
624
        xor     eax, eax
624
        xor     edx, edx
625
        xor     edx, edx
625
        cmp     [ebp+NTFS.ntfs_cur_size], eax
626
        cmp     [ebp+NTFS.ntfs_cur_size], eax
626
        jz      @f
627
        jz      @f
627
        add     esi, 8
628
        add     esi, 8
628
        push    eax
629
        push    eax
629
        mov     eax, [ebp+NTFS.mft_retrieval_end]
630
        mov     eax, [ebp+NTFS.mft_retrieval_end]
630
        shl     eax, 3
631
        shl     eax, 3
631
        add     eax, [ebp+NTFS.mft_retrieval]
632
        add     eax, [ebp+NTFS.mft_retrieval]
632
        cmp     eax, esi
633
        cmp     eax, esi
633
        pop     eax
634
        pop     eax
634
        jz      .nomft
635
        jz      .nomft
635
        jmp     .mftscan
636
        jmp     .mftscan
636
@@:
637
@@:
637
        popad
638
        popad
638
        ret
639
        ret
639
.errread:
640
.errread:
640
        pop     ecx
641
        pop     ecx
641
.errret:
642
.errret:
642
        mov     [esp+28], eax
643
        mov     [esp+28], eax
643
        stc
644
        stc
644
        popad
645
        popad
645
        ret
646
        ret
646
.nomft:
647
.nomft:
647
; 1. Read file record.
648
; 1. Read file record.
648
; N.B. This will do recursive call of read_attr for $MFT::$Data.
649
; N.B. This will do recursive call of read_attr for $MFT::$Data.
649
        mov     eax, [ebp+NTFS.ntfs_cur_iRecord]
650
        mov     eax, [ebp+NTFS.ntfs_cur_iRecord]
650
        mov     [ebp+NTFS.ntfs_attr_iRecord], eax
651
        mov     [ebp+NTFS.ntfs_attr_iRecord], eax
651
        and     [ebp+NTFS.ntfs_attr_list], 0
652
        and     [ebp+NTFS.ntfs_attr_list], 0
652
        or      dword [ebp+NTFS.ntfs_attr_size], -1
653
        or      dword [ebp+NTFS.ntfs_attr_size], -1
653
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
654
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
654
        or      [ebp+NTFS.ntfs_attr_iBaseRecord], -1
655
        or      [ebp+NTFS.ntfs_attr_iBaseRecord], -1
655
        call    ntfs_read_file_record
656
        call    ntfs_read_file_record
656
        jc      .errret
657
        jc      .errret
657
; 2. Find required attribute.
658
; 2. Find required attribute.
658
        mov     eax, [ebp+NTFS.frs_buffer]
659
        mov     eax, [ebp+NTFS.frs_buffer]
659
; a) For auxiliary records, read base record
660
; a) For auxiliary records, read base record
660
; N.B. If base record is present,
661
; N.B. If base record is present,
661
;      base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero
662
;      base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero
662
        cmp     dword [eax+24h], 0
663
        cmp     dword [eax+24h], 0
663
        jz      @f
664
        jz      @f
664
        mov     eax, [eax+20h]
665
        mov     eax, [eax+20h]
665
;        test    eax, eax
666
;        test    eax, eax
666
;        jz      @f
667
;        jz      @f
667
.beginfindattr:
668
.beginfindattr:
668
        mov     [ebp+NTFS.ntfs_attr_iRecord], eax
669
        mov     [ebp+NTFS.ntfs_attr_iRecord], eax
669
        call    ntfs_read_file_record
670
        call    ntfs_read_file_record
670
        jc      .errret
671
        jc      .errret
671
@@:
672
@@:
672
; b) Scan for required attribute and for $ATTR_LIST
673
; b) Scan for required attribute and for $ATTR_LIST
673
        mov     eax, [ebp+NTFS.frs_buffer]
674
        mov     eax, [ebp+NTFS.frs_buffer]
674
        movzx   ecx, word [eax+14h]
675
        movzx   ecx, word [eax+14h]
675
        add     eax, ecx
676
        add     eax, ecx
676
        mov     ecx, [ebp+NTFS.ntfs_cur_attr]
677
        mov     ecx, [ebp+NTFS.ntfs_cur_attr]
677
        and     [ebp+NTFS.ntfs_attr_offs], 0
678
        and     [ebp+NTFS.ntfs_attr_offs], 0
678
.scanattr:
679
.scanattr:
679
        cmp     dword [eax], -1
680
        cmp     dword [eax], -1
680
        jz      .scandone
681
        jz      .scandone
681
        cmp     dword [eax], ecx
682
        cmp     dword [eax], ecx
682
        jz      .okattr
683
        jz      .okattr
683
        cmp     [ebp+NTFS.ntfs_attr_iBaseRecord], -1
684
        cmp     [ebp+NTFS.ntfs_attr_iBaseRecord], -1
684
        jnz     .scancont
685
        jnz     .scancont
685
        cmp     dword [eax], 0x20       ; $ATTR_LIST
686
        cmp     dword [eax], 0x20       ; $ATTR_LIST
686
        jnz     .scancont
687
        jnz     .scancont
687
        mov     [ebp+NTFS.ntfs_attr_list], eax
688
        mov     [ebp+NTFS.ntfs_attr_list], eax
688
        jmp     .scancont
689
        jmp     .scancont
689
.okattr:
690
.okattr:
690
; ignore named $DATA attributes (aka NTFS streams)
691
; ignore named $DATA attributes (aka NTFS streams)
691
        cmp     ecx, 0x80
692
        cmp     ecx, 0x80
692
        jnz     @f
693
        jnz     @f
693
        cmp     byte [eax+9], 0
694
        cmp     byte [eax+9], 0
694
        jnz     .scancont
695
        jnz     .scancont
695
@@:
696
@@:
696
        mov     [ebp+NTFS.ntfs_attr_offs], eax
697
        mov     [ebp+NTFS.ntfs_attr_offs], eax
697
.scancont:
698
.scancont:
698
        add     eax, [eax+4]
699
        add     eax, [eax+4]
699
        jmp     .scanattr
700
        jmp     .scanattr
700
.continue:
701
.continue:
701
        pushad
702
        pushad
702
        and     [ebp+NTFS.ntfs_cur_read], 0
703
        and     [ebp+NTFS.ntfs_cur_read], 0
703
.scandone:
704
.scandone:
704
; c) Check for required offset and length
705
; c) Check for required offset and length
705
        mov     ecx, [ebp+NTFS.ntfs_attr_offs]
706
        mov     ecx, [ebp+NTFS.ntfs_attr_offs]
706
        jecxz   .noattr
707
        jecxz   .noattr
707
        push    [ebp+NTFS.ntfs_cur_size]
708
        push    [ebp+NTFS.ntfs_cur_size]
708
        push    [ebp+NTFS.ntfs_cur_read]
709
        push    [ebp+NTFS.ntfs_cur_read]
709
        call    .doreadattr
710
        call    .doreadattr
710
        pop     edx
711
        pop     edx
711
        pop     ecx
712
        pop     ecx
712
        jc      @f
713
        jc      @f
713
        cmp     [ebp+NTFS.ntfs_bCanContinue], 0
714
        cmp     [ebp+NTFS.ntfs_bCanContinue], 0
714
        jz      @f
715
        jz      @f
715
        sub     edx, [ebp+NTFS.ntfs_cur_read]
716
        sub     edx, [ebp+NTFS.ntfs_cur_read]
716
        neg     edx
717
        neg     edx
717
        shr     edx, 9
718
        shr     edx, 9
718
        sub     ecx, edx
719
        sub     ecx, edx
719
        mov     [ebp+NTFS.ntfs_cur_size], ecx
720
        mov     [ebp+NTFS.ntfs_cur_size], ecx
720
        jnz     .not_in_cur
721
        jnz     .not_in_cur
721
@@:
722
@@:
722
        popad
723
        popad
723
        ret
724
        ret
724
.noattr:
725
.noattr:
725
.not_in_cur:
726
.not_in_cur:
726
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x20
727
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x20
727
        jz      @f
728
        jz      @f
728
        mov     ecx, [ebp+NTFS.ntfs_attr_list]
729
        mov     ecx, [ebp+NTFS.ntfs_attr_list]
729
        test    ecx, ecx
730
        test    ecx, ecx
730
        jnz     .lookattr
731
        jnz     .lookattr
731
.ret_is_attr:
732
.ret_is_attr:
732
        and     dword [esp+28], 0
733
        and     dword [esp+28], 0
733
        cmp     [ebp+NTFS.ntfs_attr_offs], 1     ; CF set <=> ntfs_attr_offs == 0
734
        cmp     [ebp+NTFS.ntfs_attr_offs], 1     ; CF set <=> ntfs_attr_offs == 0
734
        popad
735
        popad
735
        ret
736
        ret
736
.lookattr:
737
.lookattr:
737
; required attribute or required offset was not found in base record;
738
; required attribute or required offset was not found in base record;
738
; it may be present in auxiliary records;
739
; it may be present in auxiliary records;
739
; scan $ATTR_LIST
740
; scan $ATTR_LIST
740
        mov     eax, [ebp+NTFS.ntfs_attr_iBaseRecord]
741
        mov     eax, [ebp+NTFS.ntfs_attr_iBaseRecord]
741
        cmp     eax, -1
742
        cmp     eax, -1
742
        jz      @f
743
        jz      @f
743
        call    ntfs_read_file_record
744
        call    ntfs_read_file_record
744
        jc      .errret
745
        jc      .errret
745
        or      [ebp+NTFS.ntfs_attr_iBaseRecord], -1
746
        or      [ebp+NTFS.ntfs_attr_iBaseRecord], -1
746
@@:
747
@@:
747
        push    [ebp+NTFS.ntfs_cur_offs]
748
        push    [ebp+NTFS.ntfs_cur_offs]
748
        push    [ebp+NTFS.ntfs_cur_size]
749
        push    [ebp+NTFS.ntfs_cur_size]
749
        push    [ebp+NTFS.ntfs_cur_read]
750
        push    [ebp+NTFS.ntfs_cur_read]
750
        push    [ebp+NTFS.ntfs_cur_buf]
751
        push    [ebp+NTFS.ntfs_cur_buf]
751
        push    dword [ebp+NTFS.ntfs_attr_size]
752
        push    dword [ebp+NTFS.ntfs_attr_size]
752
        push    dword [ebp+NTFS.ntfs_attr_size+4]
753
        push    dword [ebp+NTFS.ntfs_attr_size+4]
753
        or      dword [ebp+NTFS.ntfs_attr_size], -1
754
        or      dword [ebp+NTFS.ntfs_attr_size], -1
754
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
755
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
755
        and     [ebp+NTFS.ntfs_cur_offs], 0
756
        and     [ebp+NTFS.ntfs_cur_offs], 0
756
        mov     [ebp+NTFS.ntfs_cur_size], 2
757
        mov     [ebp+NTFS.ntfs_cur_size], 2
757
        and     [ebp+NTFS.ntfs_cur_read], 0
758
        and     [ebp+NTFS.ntfs_cur_read], 0
758
        lea     eax, [ebp+NTFS.ntfs_attrlist_buf]
759
        lea     eax, [ebp+NTFS.ntfs_attrlist_buf]
759
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
760
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
760
        jnz     @f
761
        jnz     @f
761
        lea     eax, [ebp+NTFS.ntfs_attrlist_mft_buf]
762
        lea     eax, [ebp+NTFS.ntfs_attrlist_mft_buf]
762
@@:
763
@@:
763
        mov     [ebp+NTFS.ntfs_cur_buf], eax
764
        mov     [ebp+NTFS.ntfs_cur_buf], eax
764
        push    eax
765
        push    eax
765
        call    .doreadattr
766
        call    .doreadattr
766
        pop     esi
767
        pop     esi
767
        mov     edx, 1
768
        mov     edx, 1
768
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
769
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
769
        pop     dword [ebp+NTFS.ntfs_attr_size]
770
        pop     dword [ebp+NTFS.ntfs_attr_size]
770
        mov     ecx, [ebp+NTFS.ntfs_cur_read]
771
        mov     ecx, [ebp+NTFS.ntfs_cur_read]
771
        pop     [ebp+NTFS.ntfs_cur_buf]
772
        pop     [ebp+NTFS.ntfs_cur_buf]
772
        pop     [ebp+NTFS.ntfs_cur_read]
773
        pop     [ebp+NTFS.ntfs_cur_read]
773
        pop     [ebp+NTFS.ntfs_cur_size]
774
        pop     [ebp+NTFS.ntfs_cur_size]
774
        pop     [ebp+NTFS.ntfs_cur_offs]
775
        pop     [ebp+NTFS.ntfs_cur_offs]
775
        jc      .errret
776
        jc      .errret
776
        or      edi, -1
777
        or      edi, -1
777
        lea     ecx, [ecx+esi-1Ah]
778
        lea     ecx, [ecx+esi-1Ah]
778
.scanliststart:
779
.scanliststart:
779
        push    ecx
780
        push    ecx
780
        mov     eax, [ebp+NTFS.ntfs_cur_attr]
781
        mov     eax, [ebp+NTFS.ntfs_cur_attr]
781
.scanlist:
782
.scanlist:
782
        cmp     esi, [esp]
783
        cmp     esi, [esp]
783
        jae     .scanlistdone
784
        jae     .scanlistdone
784
        cmp     eax, [esi]
785
        cmp     eax, [esi]
785
        jz      @f
786
        jz      @f
786
.scanlistcont:
787
.scanlistcont:
787
        movzx   ecx, word [esi+4]
788
        movzx   ecx, word [esi+4]
788
        add     esi, ecx
789
        add     esi, ecx
789
        jmp     .scanlist
790
        jmp     .scanlist
790
@@:
791
@@:
791
; ignore named $DATA attributes (aka NTFS streams)
792
; ignore named $DATA attributes (aka NTFS streams)
792
        cmp     eax, 0x80
793
        cmp     eax, 0x80
793
        jnz     @f
794
        jnz     @f
794
        cmp     byte [esi+6], 0
795
        cmp     byte [esi+6], 0
795
        jnz     .scanlistcont
796
        jnz     .scanlistcont
796
@@:
797
@@:
797
        push    eax
798
        push    eax
798
        mov     eax, [esi+8]
799
        mov     eax, [esi+8]
799
        test    eax, eax
800
        test    eax, eax
800
        jnz     .testf
801
        jnz     .testf
801
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
802
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
802
        and     eax, dword [ebp+NTFS.ntfs_attr_size+4]
803
        and     eax, dword [ebp+NTFS.ntfs_attr_size+4]
803
        cmp     eax, -1
804
        cmp     eax, -1
804
        jnz     .testfz
805
        jnz     .testfz
805
; if attribute is in auxiliary records, its size is defined only in first
806
; if attribute is in auxiliary records, its size is defined only in first
806
        mov     eax, [esi+10h]
807
        mov     eax, [esi+10h]
807
        call    ntfs_read_file_record
808
        call    ntfs_read_file_record
808
        jnc     @f
809
        jnc     @f
809
.errret_pop:
810
.errret_pop:
810
        pop     ecx ecx
811
        pop     ecx ecx
811
        jmp     .errret
812
        jmp     .errret
812
.errret2_pop:
813
.errret2_pop:
813
        xor     eax, eax
814
        xor     eax, eax
814
        jmp     .errret_pop
815
        jmp     .errret_pop
815
@@:
816
@@:
816
        mov     eax, [ebp+NTFS.frs_buffer]
817
        mov     eax, [ebp+NTFS.frs_buffer]
817
        movzx   ecx, word [eax+14h]
818
        movzx   ecx, word [eax+14h]
818
        add     eax, ecx
819
        add     eax, ecx
819
        mov     ecx, [ebp+NTFS.ntfs_cur_attr]
820
        mov     ecx, [ebp+NTFS.ntfs_cur_attr]
820
@@:
821
@@:
821
        cmp     dword [eax], -1
822
        cmp     dword [eax], -1
822
        jz      .errret2_pop
823
        jz      .errret2_pop
823
        cmp     dword [eax], ecx
824
        cmp     dword [eax], ecx
824
        jz      @f
825
        jz      @f
825
.l1:
826
.l1:
826
        add     eax, [eax+4]
827
        add     eax, [eax+4]
827
        jmp     @b
828
        jmp     @b
828
@@:
829
@@:
829
        cmp     eax, 0x80
830
        cmp     eax, 0x80
830
        jnz     @f
831
        jnz     @f
831
        cmp     byte [eax+9], 0
832
        cmp     byte [eax+9], 0
832
        jnz     .l1
833
        jnz     .l1
833
@@:
834
@@:
834
        cmp     byte [eax+8], 0
835
        cmp     byte [eax+8], 0
835
        jnz     .sdnores
836
        jnz     .sdnores
836
        mov     eax, [eax+10h]
837
        mov     eax, [eax+10h]
837
        mov     dword [ebp+NTFS.ntfs_attr_size], eax
838
        mov     dword [ebp+NTFS.ntfs_attr_size], eax
838
        and     dword [ebp+NTFS.ntfs_attr_size+4], 0
839
        and     dword [ebp+NTFS.ntfs_attr_size+4], 0
839
        jmp     .testfz
840
        jmp     .testfz
840
.sdnores:
841
.sdnores:
841
        mov     ecx, [eax+30h]
842
        mov     ecx, [eax+30h]
842
        mov     dword [ebp+NTFS.ntfs_attr_size], ecx
843
        mov     dword [ebp+NTFS.ntfs_attr_size], ecx
843
        mov     ecx, [eax+34h]
844
        mov     ecx, [eax+34h]
844
        mov     dword [ebp+NTFS.ntfs_attr_size+4], ecx
845
        mov     dword [ebp+NTFS.ntfs_attr_size+4], ecx
845
.testfz:
846
.testfz:
846
        xor     eax, eax
847
        xor     eax, eax
847
.testf:
848
.testf:
848
        imul    eax, [ebp+NTFS.sectors_per_cluster]
849
        imul    eax, [ebp+NTFS.sectors_per_cluster]
849
        cmp     eax, [ebp+NTFS.ntfs_cur_offs]
850
        cmp     eax, [ebp+NTFS.ntfs_cur_offs]
850
        pop     eax
851
        pop     eax
851
        ja      @f
852
        ja      @f
852
        mov     edi, [esi+10h]  ; keep previous iRecord
853
        mov     edi, [esi+10h]  ; keep previous iRecord
853
        jmp     .scanlistcont
854
        jmp     .scanlistcont
854
@@:
855
@@:
855
        pop     ecx
856
        pop     ecx
856
.scanlistfound:
857
.scanlistfound:
857
        cmp     edi, -1
858
        cmp     edi, -1
858
        jnz     @f
859
        jnz     @f
859
        popad
860
        popad
860
        ret
861
        ret
861
@@:
862
@@:
862
        mov     eax, [ebp+NTFS.ntfs_cur_iRecord]
863
        mov     eax, [ebp+NTFS.ntfs_cur_iRecord]
863
        mov     [ebp+NTFS.ntfs_attr_iBaseRecord], eax
864
        mov     [ebp+NTFS.ntfs_attr_iBaseRecord], eax
864
        mov     eax, edi
865
        mov     eax, edi
865
        jmp     .beginfindattr
866
        jmp     .beginfindattr
866
.scanlistdone:
867
.scanlistdone:
867
        pop     ecx
868
        pop     ecx
868
        sub     ecx, ebp
869
        sub     ecx, ebp
869
        sub     ecx, NTFS.ntfs_attrlist_buf-1Ah
870
        sub     ecx, NTFS.ntfs_attrlist_buf-1Ah
870
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
871
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
871
        jnz     @f
872
        jnz     @f
872
        sub     ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
873
        sub     ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
873
@@:
874
@@:
874
        cmp     ecx, 0x400
875
        cmp     ecx, 0x400
875
        jnz     .scanlistfound
876
        jnz     .scanlistfound
876
        inc     edx
877
        inc     edx
877
        push    esi edi
878
        push    esi edi
878
        lea     esi, [ebp+NTFS.ntfs_attrlist_buf+0x200]
879
        lea     esi, [ebp+NTFS.ntfs_attrlist_buf+0x200]
879
        lea     edi, [ebp+NTFS.ntfs_attrlist_buf]
880
        lea     edi, [ebp+NTFS.ntfs_attrlist_buf]
880
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
881
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
881
        jnz     @f
882
        jnz     @f
882
        lea     esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200]
883
        lea     esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200]
883
        lea     edi, [ebp+NTFS.ntfs_attrlist_mft_buf]
884
        lea     edi, [ebp+NTFS.ntfs_attrlist_mft_buf]
884
@@:
885
@@:
885
        mov     ecx, 0x200/4
886
        mov     ecx, 0x200/4
886
        rep movsd
887
        rep movsd
887
        mov     eax, edi
888
        mov     eax, edi
888
        pop     edi esi
889
        pop     edi esi
889
        sub     esi, 0x200
890
        sub     esi, 0x200
890
        push    [ebp+NTFS.ntfs_cur_offs]
891
        push    [ebp+NTFS.ntfs_cur_offs]
891
        push    [ebp+NTFS.ntfs_cur_size]
892
        push    [ebp+NTFS.ntfs_cur_size]
892
        push    [ebp+NTFS.ntfs_cur_read]
893
        push    [ebp+NTFS.ntfs_cur_read]
893
        push    [ebp+NTFS.ntfs_cur_buf]
894
        push    [ebp+NTFS.ntfs_cur_buf]
894
        push    dword [ebp+NTFS.ntfs_attr_size]
895
        push    dword [ebp+NTFS.ntfs_attr_size]
895
        push    dword [ebp+NTFS.ntfs_attr_size+4]
896
        push    dword [ebp+NTFS.ntfs_attr_size+4]
896
        or      dword [ebp+NTFS.ntfs_attr_size], -1
897
        or      dword [ebp+NTFS.ntfs_attr_size], -1
897
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
898
        or      dword [ebp+NTFS.ntfs_attr_size+4], -1
898
        mov     [ebp+NTFS.ntfs_cur_offs], edx
899
        mov     [ebp+NTFS.ntfs_cur_offs], edx
899
        mov     [ebp+NTFS.ntfs_cur_size], 1
900
        mov     [ebp+NTFS.ntfs_cur_size], 1
900
        and     [ebp+NTFS.ntfs_cur_read], 0
901
        and     [ebp+NTFS.ntfs_cur_read], 0
901
        mov     [ebp+NTFS.ntfs_cur_buf], eax
902
        mov     [ebp+NTFS.ntfs_cur_buf], eax
902
        mov     ecx, [ebp+NTFS.ntfs_attr_list]
903
        mov     ecx, [ebp+NTFS.ntfs_attr_list]
903
        push    esi edx edi
904
        push    esi edx edi
904
        call    .doreadattr
905
        call    .doreadattr
905
        pop     edi edx esi
906
        pop     edi edx esi
906
        mov     ecx, [ebp+NTFS.ntfs_cur_read]
907
        mov     ecx, [ebp+NTFS.ntfs_cur_read]
907
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
908
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
908
        pop     dword [ebp+NTFS.ntfs_attr_size]
909
        pop     dword [ebp+NTFS.ntfs_attr_size]
909
        pop     [ebp+NTFS.ntfs_cur_buf]
910
        pop     [ebp+NTFS.ntfs_cur_buf]
910
        pop     [ebp+NTFS.ntfs_cur_read]
911
        pop     [ebp+NTFS.ntfs_cur_read]
911
        pop     [ebp+NTFS.ntfs_cur_size]
912
        pop     [ebp+NTFS.ntfs_cur_size]
912
        pop     [ebp+NTFS.ntfs_cur_offs]
913
        pop     [ebp+NTFS.ntfs_cur_offs]
913
        jc      .errret
914
        jc      .errret
914
        lea     ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A]
915
        lea     ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A]
915
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
916
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
916
        jnz     .scanliststart
917
        jnz     .scanliststart
917
        add     ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
918
        add     ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
918
        jmp     .scanliststart
919
        jmp     .scanliststart
919
 
920
 
920
.doreadattr:
921
.doreadattr:
921
        mov     [ebp+NTFS.ntfs_bCanContinue], 0
922
        mov     [ebp+NTFS.ntfs_bCanContinue], 0
922
        cmp     byte [ecx+8], 0
923
        cmp     byte [ecx+8], 0
923
        jnz     .nonresident
924
        jnz     .nonresident
924
        mov     eax, [ecx+10h]  ; length
925
        mov     eax, [ecx+10h]  ; length
925
        mov     esi, eax
926
        mov     esi, eax
926
        mov     edx, [ebp+NTFS.ntfs_cur_offs]
927
        mov     edx, [ebp+NTFS.ntfs_cur_offs]
927
        shr     eax, 9
928
        shr     eax, 9
928
        cmp     eax, edx
929
        cmp     eax, edx
929
        jb      .okret
930
        jb      .okret
930
        shl     edx, 9
931
        shl     edx, 9
931
        sub     esi, edx
932
        sub     esi, edx
932
        movzx   eax, word [ecx+14h]
933
        movzx   eax, word [ecx+14h]
933
        add     edx, eax
934
        add     edx, eax
934
        add     edx, ecx        ; edx -> data
935
        add     edx, ecx        ; edx -> data
935
        mov     eax, [ebp+NTFS.ntfs_cur_size]
936
        mov     eax, [ebp+NTFS.ntfs_cur_size]
936
        cmp     eax, (0xFFFFFFFF shr 9)+1
937
        cmp     eax, (0xFFFFFFFF shr 9)+1
937
        jbe     @f
938
        jbe     @f
938
        mov     eax, (0xFFFFFFFF shr 9)+1
939
        mov     eax, (0xFFFFFFFF shr 9)+1
939
@@:
940
@@:
940
        shl     eax, 9
941
        shl     eax, 9
941
        cmp     eax, esi
942
        cmp     eax, esi
942
        jbe     @f
943
        jbe     @f
943
        mov     eax, esi
944
        mov     eax, esi
944
@@:
945
@@:
945
; eax = length, edx -> data
946
; eax = length, edx -> data
946
        mov     [ebp+NTFS.ntfs_cur_read], eax
947
        mov     [ebp+NTFS.ntfs_cur_read], eax
947
        mov     ecx, eax
948
        mov     ecx, eax
948
        mov     eax, edx
949
        mov     eax, edx
949
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
950
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
950
        call    memmove
951
        call    memmove
951
        and     [ebp+NTFS.ntfs_cur_size], 0      ; CF=0
952
        and     [ebp+NTFS.ntfs_cur_size], 0      ; CF=0
952
        ret
953
        ret
953
.nonresident:
954
.nonresident:
954
; Not all auxiliary records contain correct FileSize info
955
; Not all auxiliary records contain correct FileSize info
955
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
956
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
956
        mov     edx, dword [ebp+NTFS.ntfs_attr_size+4]
957
        mov     edx, dword [ebp+NTFS.ntfs_attr_size+4]
957
        push    eax
958
        push    eax
958
        and     eax, edx
959
        and     eax, edx
959
        cmp     eax, -1
960
        cmp     eax, -1
960
        pop     eax
961
        pop     eax
961
        jnz     @f
962
        jnz     @f
962
        mov     eax, [ecx+30h]  ; FileSize
963
        mov     eax, [ecx+30h]  ; FileSize
963
        mov     edx, [ecx+34h]
964
        mov     edx, [ecx+34h]
964
        mov     dword [ebp+NTFS.ntfs_attr_size], eax
965
        mov     dword [ebp+NTFS.ntfs_attr_size], eax
965
        mov     dword [ebp+NTFS.ntfs_attr_size+4], edx
966
        mov     dword [ebp+NTFS.ntfs_attr_size+4], edx
966
@@:
967
@@:
967
        add     eax, 0x1FF
968
        add     eax, 0x1FF
968
        adc     edx, 0
969
        adc     edx, 0
969
        shrd    eax, edx, 9
970
        shrd    eax, edx, 9
970
        sub     eax, [ebp+NTFS.ntfs_cur_offs]
971
        sub     eax, [ebp+NTFS.ntfs_cur_offs]
971
        ja      @f
972
        ja      @f
972
; return with nothing read
973
; return with nothing read
973
        and     [ebp+NTFS.ntfs_cur_size], 0
974
        and     [ebp+NTFS.ntfs_cur_size], 0
974
.okret:
975
.okret:
975
        clc
976
        clc
976
        ret
977
        ret
977
@@:
978
@@:
978
; reduce read length
979
; reduce read length
979
        and     [ebp+NTFS.ntfs_cur_tail], 0
980
        and     [ebp+NTFS.ntfs_cur_tail], 0
980
        cmp     [ebp+NTFS.ntfs_cur_size], eax
981
        cmp     [ebp+NTFS.ntfs_cur_size], eax
981
        jb      @f
982
        jb      @f
982
        mov     [ebp+NTFS.ntfs_cur_size], eax
983
        mov     [ebp+NTFS.ntfs_cur_size], eax
983
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
984
        mov     eax, dword [ebp+NTFS.ntfs_attr_size]
984
        and     eax, 0x1FF
985
        and     eax, 0x1FF
985
        mov     [ebp+NTFS.ntfs_cur_tail], eax
986
        mov     [ebp+NTFS.ntfs_cur_tail], eax
986
@@:
987
@@:
987
        cmp     [ebp+NTFS.ntfs_cur_size], 0
988
        cmp     [ebp+NTFS.ntfs_cur_size], 0
988
        jz      .okret
989
        jz      .okret
989
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
990
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
990
        xor     edx, edx
991
        xor     edx, edx
991
        div     [ebp+NTFS.sectors_per_cluster]
992
        div     [ebp+NTFS.sectors_per_cluster]
992
        sub     eax, [ecx+10h]  ; first_vbo
993
        sub     eax, [ecx+10h]  ; first_vbo
993
        jb      .okret
994
        jb      .okret
994
; eax = cluster, edx = starting sector
995
; eax = cluster, edx = starting sector
-
 
996
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
-
 
997
        jnz     .sys
-
 
998
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
-
 
999
        jz      .sys
-
 
1000
        push    fs_read64_app
-
 
1001
        cmp     [ebp+NTFS.ntfsWriteAttr], 1
-
 
1002
        jnz     @f
-
 
1003
        mov     dword[esp], fs_write64_app
-
 
1004
        jmp     @f
-
 
1005
.sys:
-
 
1006
        push    fs_read64_sys
-
 
1007
@@:
995
        sub     esp, 10h
1008
        sub     esp, 10h
996
        movzx   esi, word [ecx+20h]     ; mcb_info_ofs
1009
        movzx   esi, word [ecx+20h]     ; mcb_info_ofs
997
        add     esi, ecx
1010
        add     esi, ecx
998
        xor     edi, edi
1011
        xor     edi, edi
999
        mov     [ebp+NTFS.ntfsFragmentCount], 0
1012
        mov     [ebp+NTFS.ntfsFragmentCount], 0
1000
.readloop:
1013
.readloop:
1001
        call    ntfs_decode_mcb_entry
1014
        call    ntfs_decode_mcb_entry
1002
        jnc     .break
1015
        jnc     .break
1003
        add     edi, [esp+8]
1016
        add     edi, [esp+8]
1004
        sub     eax, [esp]
1017
        sub     eax, [esp]
1005
        jae     .readloop
1018
        jae     .readloop
1006
        push    ecx
1019
        push    ecx
1007
        push    eax
1020
        push    eax
1008
        add     eax, [esp+8]
1021
        add     eax, [esp+8]
1009
        add     eax, edi
1022
        add     eax, edi
1010
        imul    eax, [ebp+NTFS.sectors_per_cluster]
1023
        imul    eax, [ebp+NTFS.sectors_per_cluster]
1011
        add     eax, edx
1024
        add     eax, edx
1012
        pop     ecx
1025
        pop     ecx
1013
        neg     ecx
1026
        neg     ecx
1014
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
1027
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
1015
        sub     ecx, edx
1028
        sub     ecx, edx
1016
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
1029
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
1017
        jb      @f
1030
        jb      @f
1018
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
1031
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
1019
@@:
1032
@@:
1020
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
1033
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
1021
        mov     [ebp+NTFS.ntfsLastRead], eax
1034
        mov     [ebp+NTFS.ntfsLastRead], eax
1022
        push    ecx
1035
        push    ecx
1023
        xor     edx, edx
1036
        xor     edx, edx
1024
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
-
 
1025
        jnz     .sys
-
 
1026
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
-
 
1027
        jz      .sys
-
 
1028
        call    fs_read64_app
1037
        call    dword[esp+18h]
1029
        jmp     .appsys
-
 
1030
.sys:
-
 
1031
        call    fs_read64_sys
-
 
1032
.appsys:
-
 
1033
        pop     ecx
1038
        pop     ecx
1034
        test    eax, eax
1039
        test    eax, eax
1035
        jnz     .errread2
1040
        jnz     .errread2
1036
        sub     [ebp+NTFS.ntfs_cur_size], ecx
1041
        sub     [ebp+NTFS.ntfs_cur_size], ecx
1037
        add     [ebp+NTFS.ntfs_cur_offs], ecx
1042
        add     [ebp+NTFS.ntfs_cur_offs], ecx
1038
        shl     ecx, 9
1043
        shl     ecx, 9
1039
        add     [ebp+NTFS.ntfs_cur_read], ecx
1044
        add     [ebp+NTFS.ntfs_cur_read], ecx
1040
        add     [ebp+NTFS.ntfs_cur_buf], ecx
1045
        add     [ebp+NTFS.ntfs_cur_buf], ecx
1041
        inc     [ebp+NTFS.ntfsFragmentCount]
1046
        inc     [ebp+NTFS.ntfsFragmentCount]
1042
        pop     ecx
1047
        pop     ecx
1043
        xor     eax, eax
1048
        xor     eax, eax
1044
        xor     edx, edx
1049
        xor     edx, edx
1045
        cmp     [ebp+NTFS.ntfs_cur_size], 0
1050
        cmp     [ebp+NTFS.ntfs_cur_size], 0
1046
        jnz     .readloop
1051
        jnz     .readloop
1047
        add     esp, 10h
1052
        add     esp, 14h
1048
        mov     eax, [ebp+NTFS.ntfs_cur_tail]
1053
        mov     eax, [ebp+NTFS.ntfs_cur_tail]
1049
        test    eax, eax
1054
        test    eax, eax
1050
        jz      @f
1055
        jz      @f
1051
        sub     eax, 0x200
1056
        sub     eax, 0x200
1052
        add     [ebp+NTFS.ntfs_cur_read], eax
1057
        add     [ebp+NTFS.ntfs_cur_read], eax
1053
@@:
1058
@@:
1054
        clc
1059
        clc
1055
        ret
1060
        ret
1056
.errread2:
1061
.errread2:
1057
        pop     ecx
1062
        pop     ecx
1058
        add     esp, 10h
1063
        add     esp, 14h
1059
        stc
1064
        stc
1060
        ret
1065
        ret
1061
.break:
1066
.break:
1062
        add     esp, 10h        ; CF=0
1067
        add     esp, 14h        ; CF=0
1063
        mov     [ebp+NTFS.ntfs_bCanContinue], 1
1068
        mov     [ebp+NTFS.ntfs_bCanContinue], 1
1064
        ret
1069
        ret
1065
 
1070
 
1066
ntfs_read_file_record:
1071
ntfs_read_file_record:
1067
; in: eax = iRecord
1072
; in: eax = iRecord
1068
; out: [ebp+NTFS.frs_buffer] = record data
1073
; out: [ebp+NTFS.frs_buffer] = record data
1069
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
1074
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
1070
    ; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
1075
    ; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
1071
        push    ecx edx
1076
        push    ecx edx
1072
        mov     ecx, [ebp+NTFS.frs_size]
1077
        mov     ecx, [ebp+NTFS.frs_size]
1073
        mul     ecx
1078
        mul     ecx
1074
        shrd    eax, edx, 9
1079
        shrd    eax, edx, 9
1075
        shr     edx, 9
1080
        shr     edx, 9
1076
        jnz     .errret
1081
        jnz     .errret
1077
        push    [ebp+NTFS.ntfs_attr_iRecord]
1082
        push    [ebp+NTFS.ntfs_attr_iRecord]
1078
        push    [ebp+NTFS.ntfs_attr_iBaseRecord]
1083
        push    [ebp+NTFS.ntfs_attr_iBaseRecord]
1079
        push    [ebp+NTFS.ntfs_attr_offs]
1084
        push    [ebp+NTFS.ntfs_attr_offs]
1080
        push    [ebp+NTFS.ntfs_attr_list]
1085
        push    [ebp+NTFS.ntfs_attr_list]
1081
        push    dword [ebp+NTFS.ntfs_attr_size+4]
1086
        push    dword [ebp+NTFS.ntfs_attr_size+4]
1082
        push    dword [ebp+NTFS.ntfs_attr_size]
1087
        push    dword [ebp+NTFS.ntfs_attr_size]
1083
        push    [ebp+NTFS.ntfs_cur_iRecord]
1088
        push    [ebp+NTFS.ntfs_cur_iRecord]
1084
        push    [ebp+NTFS.ntfs_cur_attr]
1089
        push    [ebp+NTFS.ntfs_cur_attr]
1085
        push    [ebp+NTFS.ntfs_cur_offs]
1090
        push    [ebp+NTFS.ntfs_cur_offs]
1086
        push    [ebp+NTFS.ntfs_cur_size]
1091
        push    [ebp+NTFS.ntfs_cur_size]
1087
        push    [ebp+NTFS.ntfs_cur_buf]
1092
        push    [ebp+NTFS.ntfs_cur_buf]
1088
        push    [ebp+NTFS.ntfs_cur_read]
1093
        push    [ebp+NTFS.ntfs_cur_read]
1089
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80   ; $DATA
1094
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80   ; $DATA
1090
        and     [ebp+NTFS.ntfs_cur_iRecord], 0   ; $Mft
1095
        and     [ebp+NTFS.ntfs_cur_iRecord], 0   ; $Mft
1091
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1096
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1092
        shr     ecx, 9
1097
        shr     ecx, 9
1093
        mov     [ebp+NTFS.ntfs_cur_size], ecx
1098
        mov     [ebp+NTFS.ntfs_cur_size], ecx
1094
        mov     eax, [ebp+NTFS.frs_buffer]
1099
        mov     eax, [ebp+NTFS.frs_buffer]
1095
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1100
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1096
        call    ntfs_read_attr
1101
        call    ntfs_read_attr
1097
        mov     edx, [ebp+NTFS.ntfs_cur_read]
1102
        mov     edx, [ebp+NTFS.ntfs_cur_read]
1098
        pop     [ebp+NTFS.ntfs_cur_read]
1103
        pop     [ebp+NTFS.ntfs_cur_read]
1099
        pop     [ebp+NTFS.ntfs_cur_buf]
1104
        pop     [ebp+NTFS.ntfs_cur_buf]
1100
        pop     [ebp+NTFS.ntfs_cur_size]
1105
        pop     [ebp+NTFS.ntfs_cur_size]
1101
        pop     [ebp+NTFS.ntfs_cur_offs]
1106
        pop     [ebp+NTFS.ntfs_cur_offs]
1102
        pop     [ebp+NTFS.ntfs_cur_attr]
1107
        pop     [ebp+NTFS.ntfs_cur_attr]
1103
        pop     [ebp+NTFS.ntfs_cur_iRecord]
1108
        pop     [ebp+NTFS.ntfs_cur_iRecord]
1104
        pop     dword [ebp+NTFS.ntfs_attr_size]
1109
        pop     dword [ebp+NTFS.ntfs_attr_size]
1105
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
1110
        pop     dword [ebp+NTFS.ntfs_attr_size+4]
1106
        pop     [ebp+NTFS.ntfs_attr_list]
1111
        pop     [ebp+NTFS.ntfs_attr_list]
1107
        pop     [ebp+NTFS.ntfs_attr_offs]
1112
        pop     [ebp+NTFS.ntfs_attr_offs]
1108
        pop     [ebp+NTFS.ntfs_attr_iBaseRecord]
1113
        pop     [ebp+NTFS.ntfs_attr_iBaseRecord]
1109
        pop     [ebp+NTFS.ntfs_attr_iRecord]
1114
        pop     [ebp+NTFS.ntfs_attr_iRecord]
1110
        jc      .ret
1115
        jc      .ret
1111
        cmp     edx, [ebp+NTFS.frs_size]
1116
        cmp     edx, [ebp+NTFS.frs_size]
1112
        jnz     .errret
1117
        jnz     .errret
1113
        mov     eax, [ebp+NTFS.frs_buffer]
1118
        mov     eax, [ebp+NTFS.frs_buffer]
1114
        cmp     dword [eax], 'FILE'
1119
        cmp     dword [eax], 'FILE'
1115
        jnz     .errret
1120
        jnz     .errret
1116
        push    ebx
1121
        push    ebx
1117
        mov     ebx, eax
1122
        mov     ebx, eax
1118
        call    ntfs_restore_usa_frs
1123
        call    ntfs_restore_usa_frs
1119
        pop     ebx
1124
        pop     ebx
1120
        jc      .errret
1125
        jc      .errret
1121
.ret:
1126
.ret:
1122
        pop     edx ecx
1127
        pop     edx ecx
1123
        ret
1128
        ret
1124
.errret:
1129
.errret:
1125
        pop     edx ecx
1130
        pop     edx ecx
1126
        xor     eax, eax
1131
        xor     eax, eax
1127
        stc
1132
        stc
1128
        ret
1133
        ret
1129
 
1134
 
1130
ntfs_restore_usa_frs:
1135
ntfs_restore_usa_frs:
1131
        mov     eax, [ebp+NTFS.frs_size]
1136
        mov     eax, [ebp+NTFS.frs_size]
1132
ntfs_restore_usa:
1137
ntfs_restore_usa:
1133
        pushad
1138
        pushad
1134
        shr     eax, 9
1139
        shr     eax, 9
1135
        mov     ecx, eax
1140
        mov     ecx, eax
1136
        inc     eax
1141
        inc     eax
1137
        cmp     [ebx+6], ax
1142
        cmp     [ebx+6], ax
1138
        jnz     .err
1143
        jnz     .err
1139
        movzx   eax, word [ebx+4]
1144
        movzx   eax, word [ebx+4]
1140
        lea     esi, [eax+ebx]
1145
        lea     esi, [eax+ebx]
1141
        lodsw
1146
        lodsw
1142
        mov     edx, eax
1147
        mov     edx, eax
1143
        lea     edi, [ebx+0x1FE]
1148
        lea     edi, [ebx+0x1FE]
1144
@@:
1149
@@:
1145
        cmp     [edi], dx
1150
        cmp     [edi], dx
1146
        jnz     .err
1151
        jnz     .err
1147
        lodsw
1152
        lodsw
1148
        stosw
1153
        stosw
1149
        add     edi, 0x1FE
1154
        add     edi, 0x1FE
1150
        loop    @b
1155
        loop    @b
1151
        popad
1156
        popad
1152
        clc
1157
        clc
1153
        ret
1158
        ret
1154
.err:
1159
.err:
1155
        popad
1160
        popad
1156
        stc
1161
        stc
1157
        ret
1162
        ret
1158
 
1163
 
1159
ntfs_decode_mcb_entry:
1164
ntfs_decode_mcb_entry:
-
 
1165
;   in:
-
 
1166
; esi -> mcb entry
-
 
1167
; esp -> buffer (16 bytes)
-
 
1168
;   out:
-
 
1169
; esi -> next mcb entry
-
 
1170
; esp -> data run size
-
 
1171
; esp+8 -> cluster (delta)
-
 
1172
; CF=0 -> mcb end
1160
        push    eax ecx edi
1173
        push    eax ecx edi
1161
        lea     edi, [esp+16]
1174
        lea     edi, [esp+16]
1162
        xor     eax, eax
1175
        xor     eax, eax
1163
        lodsb
1176
        lodsb
1164
        test    al, al
1177
        test    al, al
1165
        jz      .end
1178
        jz      .end
1166
        mov     ecx, eax
1179
        mov     ecx, eax
1167
        and     ecx, 0xF
1180
        and     ecx, 0xF
1168
        cmp     ecx, 8
1181
        cmp     ecx, 8
1169
        ja      .end
1182
        ja      .end
1170
        push    ecx
1183
        push    ecx
1171
        rep movsb
1184
        rep movsb
1172
        pop     ecx
1185
        pop     ecx
1173
        sub     ecx, 8
1186
        sub     ecx, 8
1174
        neg     ecx
1187
        neg     ecx
1175
        cmp     byte [esi-1], 80h
1188
        cmp     byte [esi-1], 80h
1176
        jae     .end
1189
        jae     .end
1177
        push    eax
1190
        push    eax
1178
        xor     eax, eax
1191
        xor     eax, eax
1179
        rep stosb
1192
        rep stosb
1180
        pop     ecx
1193
        pop     ecx
1181
        shr     ecx, 4
1194
        shr     ecx, 4
1182
        cmp     ecx, 8
1195
        cmp     ecx, 8
1183
        ja      .end
1196
        ja      .end
1184
        push    ecx
1197
        push    ecx
1185
        rep movsb
1198
        rep movsb
1186
        pop     ecx
1199
        pop     ecx
1187
        sub     ecx, 8
1200
        sub     ecx, 8
1188
        neg     ecx
1201
        neg     ecx
1189
        cmp     byte [esi-1], 80h
1202
        cmp     byte [esi-1], 80h
1190
        cmc
1203
        cmc
1191
        sbb     eax, eax
1204
        sbb     eax, eax
1192
        rep stosb
1205
        rep stosb
1193
        stc
1206
        stc
1194
.end:
1207
.end:
1195
        pop     edi ecx eax
1208
        pop     edi ecx eax
1196
        ret
1209
        ret
1197
 
1210
 
1198
unichar_toupper:
1211
unichar_toupper:
1199
        push    eax
1212
        push    eax
1200
        call    uni2ansi_char
1213
        call    uni2ansi_char
1201
        cmp     al, '_'
1214
        cmp     al, '_'
1202
        jz      .unk
1215
        jz      .unk
1203
        add     esp, 4
1216
        add     esp, 4
1204
        call    char_toupper
1217
        call    char_toupper
1205
        jmp     ansi2uni_char
1218
        jmp     ansi2uni_char
1206
.unk:
1219
.unk:
1207
        pop     eax
1220
        pop     eax
1208
        ret
1221
        ret
1209
 
1222
 
1210
ntfs_find_lfn:
1223
ntfs_find_lfn:
1211
; in: [esi]+[esp+4] = name
1224
; in: [esi]+[esp+4] = name
1212
;   out:
1225
;   out:
1213
; [ebp+NTFS.ntfs_cur_iRecord] = number of MFT fileRecord
1226
; [ebp+NTFS.ntfs_cur_iRecord] = number of MFT fileRecord
1214
; eax = pointer in parent index node
1227
; eax -> index in the parent index node
1215
; CF=1 -> file not found (or just error)
1228
; CF=1 -> file not found, eax=0 -> error
1216
        mov     [ebp+NTFS.ntfs_cur_iRecord], 5   ; start parse from root cluster
1229
        mov     [ebp+NTFS.ntfs_cur_iRecord], 5   ; start parse from root cluster
1217
.doit2:
1230
.doit2:
1218
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1231
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1219
        and     [ebp+NTFS.ntfs_cur_offs], 0
1232
        and     [ebp+NTFS.ntfs_cur_offs], 0
1220
        mov     eax, [ebp+NTFS.cur_index_size]
1233
        mov     eax, [ebp+NTFS.cur_index_size]
1221
        mov     [ebp+NTFS.ntfs_cur_size], eax
1234
        mov     [ebp+NTFS.ntfs_cur_size], eax
1222
        mov     eax, [ebp+NTFS.cur_index_buf]
1235
        mov     eax, [ebp+NTFS.cur_index_buf]
1223
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1236
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1224
        call    ntfs_read_attr
1237
        call    ntfs_read_attr
-
 
1238
        mov     eax, 0
1225
        jnc     @f
1239
        jnc     @f
1226
.ret:
1240
.ret:
1227
        ret     4
1241
        ret     4
1228
@@:
1242
@@:
1229
        xor     eax, eax
-
 
1230
        cmp     [ebp+NTFS.ntfs_cur_read], 0x20
1243
        cmp     [ebp+NTFS.ntfs_cur_read], 0x20
1231
        jc      .ret
1244
        jc      .ret
1232
        pushad
1245
        pushad
1233
        mov     esi, [ebp+NTFS.cur_index_buf]
1246
        mov     esi, [ebp+NTFS.cur_index_buf]
1234
        mov     eax, [esi+14h]
1247
        mov     eax, [esi+14h]
1235
        add     eax, 10h
1248
        add     eax, 10h
1236
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1249
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1237
        jae     .readok1
1250
        jae     .readok1
1238
        add     eax, 1FFh
1251
        add     eax, 1FFh
1239
        shr     eax, 9
1252
        shr     eax, 9
1240
        cmp     eax, [ebp+NTFS.cur_index_size]
1253
        cmp     eax, [ebp+NTFS.cur_index_size]
1241
        ja      @f
1254
        ja      @f
1242
.stc_ret:
1255
.stc_ret:
1243
        popad
1256
        popad
1244
        stc
1257
        stc
1245
        ret     4
1258
        ret     4
1246
@@:
1259
@@:
1247
; reallocate
1260
; reallocate
1248
        push    eax
1261
        push    eax
1249
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1262
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1250
        pop     eax
1263
        pop     eax
1251
        mov     [ebp+NTFS.cur_index_size], eax
1264
        mov     [ebp+NTFS.cur_index_size], eax
1252
        stdcall kernel_alloc, eax
1265
        stdcall kernel_alloc, eax
1253
        test    eax, eax
1266
        test    eax, eax
1254
        jnz     @f
1267
        jnz     @f
1255
        and     [ebp+NTFS.cur_index_size], 0
1268
        and     [ebp+NTFS.cur_index_size], 0
1256
        and     [ebp+NTFS.cur_index_buf], 0
1269
        and     [ebp+NTFS.cur_index_buf], 0
1257
        jmp     .stc_ret
1270
        jmp     .stc_ret
1258
@@:
1271
@@:
1259
        mov     [ebp+NTFS.cur_index_buf], eax
1272
        mov     [ebp+NTFS.cur_index_buf], eax
1260
        popad
1273
        popad
1261
        jmp     .doit2
1274
        jmp     .doit2
1262
.readok1:
1275
.readok1:
1263
        mov     edx, [esi+8]    ; subnode_size
1276
        mov     edx, [esi+8]    ; subnode_size
1264
        shr     edx, 9
1277
        shr     edx, 9
1265
        cmp     edx, [ebp+NTFS.cur_index_size]
1278
        cmp     edx, [ebp+NTFS.cur_index_size]
1266
        jbe     .ok2
1279
        jbe     .ok2
1267
        push    esi edx
1280
        push    esi edx
1268
        stdcall kernel_alloc, edx
1281
        stdcall kernel_alloc, edx
1269
        pop     edx esi
1282
        pop     edx esi
1270
        test    eax, eax
1283
        test    eax, eax
1271
        jz      .stc_ret
1284
        jz      .stc_ret
1272
        mov     edi, eax
1285
        mov     edi, eax
1273
        mov     ecx, [ebp+NTFS.cur_index_size]
1286
        mov     ecx, [ebp+NTFS.cur_index_size]
1274
        shl     ecx, 9-2
1287
        shl     ecx, 9-2
1275
        rep movsd
1288
        rep movsd
1276
        mov     esi, eax
1289
        mov     esi, eax
1277
        mov     [ebp+NTFS.cur_index_size], edx
1290
        mov     [ebp+NTFS.cur_index_size], edx
1278
        push    esi edx
1291
        push    esi edx
1279
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1292
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1280
        pop     edx esi
1293
        pop     edx esi
1281
        mov     [ebp+NTFS.cur_index_buf], esi
1294
        mov     [ebp+NTFS.cur_index_buf], esi
1282
.ok2:
1295
.ok2:
1283
        add     esi, 10h
1296
        add     esi, 10h
1284
        mov     edi, [esp+4]
1297
        mov     edi, [esp+4]
1285
; edi -> name, esi -> current index data, edx = subnode size
1298
; edi -> name, esi -> current index data, edx = subnode size
1286
.scanloop:
1299
.scanloop:
1287
        add     esi, [esi]
1300
        add     esi, [esi]
1288
.scanloopint:
1301
.scanloopint:
1289
        test    byte [esi+0Ch], 2
1302
        test    byte [esi+0Ch], 2
1290
        jnz     .subnode
1303
        jnz     .subnode
1291
        push    esi
1304
        push    esi
1292
        add     esi, 0x52
1305
        add     esi, 0x52
1293
        movzx   ecx, byte [esi-2]
1306
        movzx   ecx, byte [esi-2]
1294
        push    edi
1307
        push    edi
1295
@@:
1308
@@:
1296
        lodsw
1309
        lodsw
1297
        call    unichar_toupper
1310
        call    unichar_toupper
1298
        push    eax
1311
        push    eax
1299
        mov     al, [edi]
1312
        mov     al, [edi]
1300
        inc     edi
1313
        inc     edi
1301
        cmp     al, '/'
1314
        cmp     al, '/'
1302
        jz      .slash
1315
        jz      .slash
1303
        call    char_toupper
1316
        call    char_toupper
1304
        call    ansi2uni_char
1317
        call    ansi2uni_char
1305
        cmp     ax, [esp]
1318
        cmp     ax, [esp]
1306
        pop     eax
1319
        pop     eax
1307
        loopz   @b
1320
        loopz   @b
1308
        jz      .found
1321
        jz      .found
1309
        pop     edi
1322
        pop     edi
1310
        pop     esi
1323
        pop     esi
1311
        jb      .subnode
1324
        jb      .subnode
1312
.scanloopcont:
1325
.scanloopcont:
1313
        movzx   eax, word [esi+8]
1326
        movzx   eax, word [esi+8]
1314
        add     esi, eax
1327
        add     esi, eax
1315
        jmp     .scanloopint
1328
        jmp     .scanloopint
1316
.slash:
1329
.slash:
1317
        pop     eax
1330
        pop     eax
1318
        pop     edi
1331
        pop     edi
1319
        pop     esi
1332
        pop     esi
1320
.subnode:
1333
.subnode:
1321
        test    byte [esi+0Ch], 1
1334
        test    byte [esi+0Ch], 1
1322
        jz      .notfound
1335
        jz      .notfound
1323
        movzx   eax, word [esi+8]
1336
        movzx   eax, word [esi+8]
1324
        mov     eax, [esi+eax-8]
1337
        mov     eax, [esi+eax-8]
1325
        imul    eax, [ebp+NTFS.sectors_per_cluster]
1338
        imul    eax, [ebp+NTFS.sectors_per_cluster]
1326
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1339
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1327
        mov     [ebp+NTFS.ntfs_cur_attr], 0xA0   ; $INDEX_ALLOCATION
1340
        mov     [ebp+NTFS.ntfs_cur_attr], 0xA0   ; $INDEX_ALLOCATION
1328
        mov     [ebp+NTFS.ntfs_cur_size], edx
1341
        mov     [ebp+NTFS.ntfs_cur_size], edx
1329
        mov     eax, [ebp+NTFS.cur_index_buf]
1342
        mov     eax, [ebp+NTFS.cur_index_buf]
1330
        mov     esi, eax
1343
        mov     esi, eax
1331
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1344
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1332
        push    edx
1345
        push    edx
1333
        call    ntfs_read_attr
1346
        call    ntfs_read_attr
1334
        pop     edx
1347
        pop     edx
1335
        mov     eax, edx
1348
        mov     eax, edx
1336
        shl     eax, 9
1349
        shl     eax, 9
1337
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1350
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1338
        jnz     .err
1351
        jnz     .err
1339
        cmp     dword [esi], 'INDX'
1352
        cmp     dword [esi], 'INDX'
1340
        jnz     .err
1353
        jnz     .err
1341
        mov     [ebp+NTFS.ntfs_cur_buf], esi
1354
        mov     [ebp+NTFS.ntfs_cur_buf], esi
1342
        mov     ebx, esi
1355
        mov     ebx, esi
1343
        call    ntfs_restore_usa
1356
        call    ntfs_restore_usa
1344
        jc      .err
1357
        jc      .err
1345
        add     esi, 0x18
1358
        add     esi, 0x18
1346
        jmp     .scanloop
1359
        jmp     .scanloop
1347
.notfound:
1360
.notfound:
1348
        mov     [ebp+NTFS.ntfsNotFound], 1
-
 
1349
        mov     [esp+1Ch], esi
1361
        mov     [esp+1Ch], esi
1350
.err:
1362
.err:
1351
        popad
1363
        popad
1352
        stc
1364
        stc
1353
        ret     4
1365
        ret     4
1354
.found:
1366
.found:
1355
        cmp     byte [edi], 0
1367
        cmp     byte [edi], 0
1356
        jz      .done
1368
        jz      .done
1357
        cmp     byte [edi], '/'
1369
        cmp     byte [edi], '/'
1358
        jz      .next
1370
        jz      .next
1359
        pop     edi
1371
        pop     edi
1360
        pop     esi
1372
        pop     esi
1361
        jmp     .scanloopcont
1373
        jmp     .scanloopcont
1362
.done:
1374
.done:
1363
.next:
1375
.next:
1364
        pop     esi
1376
        pop     esi
1365
        pop     esi
1377
        pop     esi
1366
        mov     eax, [esi]
1378
        mov     eax, [esi]
1367
        mov     [ebp+NTFS.ntfs_cur_iRecord], eax
1379
        mov     [ebp+NTFS.ntfs_cur_iRecord], eax
1368
        mov     [esp+1Ch], esi
1380
        mov     [esp+1Ch], esi
1369
        mov     [esp+4], edi
1381
        mov     [esp+4], edi
1370
        popad
1382
        popad
1371
        inc     esi
1383
        inc     esi
1372
        cmp     byte [esi-1], 0
1384
        cmp     byte [esi-1], 0
1373
        jnz     .doit2
1385
        jnz     .doit2
1374
        cmp     dword [esp+4], 0
1386
        cmp     dword [esp+4], 0
1375
        jz      @f
1387
        jz      @f
1376
        mov     esi, [esp+4]
1388
        mov     esi, [esp+4]
1377
        mov     dword [esp+4], 0
1389
        mov     dword [esp+4], 0
1378
        jmp     .doit2
1390
        jmp     .doit2
1379
@@:
1391
@@:
1380
        ret     4
1392
        ret     4
1381
 
1393
 
1382
;----------------------------------------------------------------
1394
;----------------------------------------------------------------
1383
ntfs_ReadFile:
1395
ntfs_ReadFile:
1384
        cmp     byte [esi], 0
1396
        cmp     byte [esi], 0
1385
        jnz     @f
1397
        jnz     @f
1386
        or      ebx, -1
1398
        or      ebx, -1
1387
        movi    eax, ERROR_ACCESS_DENIED
1399
        movi    eax, ERROR_ACCESS_DENIED
1388
        ret
1400
        ret
1389
@@:
1401
@@:
1390
        call    ntfs_lock
1402
        call    ntfs_lock
1391
        stdcall ntfs_find_lfn, [esp+4]
1403
        stdcall ntfs_find_lfn, [esp+4]
1392
        jnc     .found
1404
        jnc     .found
1393
        call    ntfs_unlock
1405
        call    ntfs_unlock
1394
        or      ebx, -1
1406
        or      ebx, -1
1395
        movi    eax, ERROR_FILE_NOT_FOUND
1407
        movi    eax, ERROR_FILE_NOT_FOUND
1396
        ret
1408
        ret
1397
.found:
1409
.found:
1398
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80   ; $DATA
1410
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80   ; $DATA
1399
        and     [ebp+NTFS.ntfs_cur_offs], 0
1411
        and     [ebp+NTFS.ntfs_cur_offs], 0
1400
        and     [ebp+NTFS.ntfs_cur_size], 0
1412
        and     [ebp+NTFS.ntfs_cur_size], 0
1401
        call    ntfs_read_attr
1413
        call    ntfs_read_attr
1402
        jnc     @f
1414
        jnc     @f
1403
        call    ntfs_unlock
1415
        call    ntfs_unlock
1404
        or      ebx, -1
1416
        or      ebx, -1
1405
        movi    eax, ERROR_ACCESS_DENIED
1417
        movi    eax, ERROR_ACCESS_DENIED
1406
        ret
1418
        ret
1407
@@:
1419
@@:
1408
        pushad
1420
        pushad
1409
        and     dword [esp+10h], 0
1421
        and     dword [esp+10h], 0
1410
        xor     eax, eax
1422
        xor     eax, eax
1411
        cmp     dword [ebx+8], 0x200
1423
        cmp     dword [ebx+8], 0x200
1412
        jb      @f
1424
        jb      @f
1413
.eof0:
1425
.eof0:
1414
        popad
1426
        popad
1415
        xor     ebx, ebx
1427
        xor     ebx, ebx
1416
.eof:
1428
.eof:
1417
        push    ERROR_END_OF_FILE
1429
        push    ERROR_END_OF_FILE
1418
        call    ntfs_unlock
1430
        call    ntfs_unlock
1419
        pop     eax
1431
        pop     eax
1420
        ret
1432
        ret
1421
@@:
1433
@@:
1422
        mov     ecx, [ebx+12]
1434
        mov     ecx, [ebx+12]
1423
        mov     edx, [ebx+16]
1435
        mov     edx, [ebx+16]
1424
        mov     eax, [ebx+4]
1436
        mov     eax, [ebx+4]
1425
        test    eax, 0x1FF
1437
        test    eax, 0x1FF
1426
        jz      .alignedstart
1438
        jz      .alignedstart
1427
        push    edx
1439
        push    edx
1428
        mov     edx, [ebx+8]
1440
        mov     edx, [ebx+8]
1429
        shrd    eax, edx, 9
1441
        shrd    eax, edx, 9
1430
        pop     edx
1442
        pop     edx
1431
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1443
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1432
        mov     [ebp+NTFS.ntfs_cur_size], 1
1444
        mov     [ebp+NTFS.ntfs_cur_size], 1
1433
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1445
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1434
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1446
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1435
        call    ntfs_read_attr.continue
1447
        call    ntfs_read_attr.continue
1436
        mov     eax, [ebx+4]
1448
        mov     eax, [ebx+4]
1437
        and     eax, 0x1FF
1449
        and     eax, 0x1FF
1438
        lea     esi, [ebp+NTFS.ntfs_bitmap_buf+eax]
1450
        lea     esi, [ebp+NTFS.ntfs_bitmap_buf+eax]
1439
        sub     eax, [ebp+NTFS.ntfs_cur_read]
1451
        sub     eax, [ebp+NTFS.ntfs_cur_read]
1440
        jae     .eof0
1452
        jae     .eof0
1441
        neg     eax
1453
        neg     eax
1442
        push    ecx
1454
        push    ecx
1443
        cmp     ecx, eax
1455
        cmp     ecx, eax
1444
        jb      @f
1456
        jb      @f
1445
        mov     ecx, eax
1457
        mov     ecx, eax
1446
@@:
1458
@@:
1447
        mov     [esp+10h+4], ecx
1459
        mov     [esp+10h+4], ecx
1448
        mov     edi, edx
1460
        mov     edi, edx
1449
        rep movsb
1461
        rep movsb
1450
        mov     edx, edi
1462
        mov     edx, edi
1451
        pop     ecx
1463
        pop     ecx
1452
        sub     ecx, [esp+10h]
1464
        sub     ecx, [esp+10h]
1453
        jnz     @f
1465
        jnz     @f
1454
.retok:
1466
.retok:
1455
        popad
1467
        popad
1456
        call    ntfs_unlock
1468
        call    ntfs_unlock
1457
        xor     eax, eax
1469
        xor     eax, eax
1458
        ret
1470
        ret
1459
@@:
1471
@@:
1460
        cmp     [ebp+NTFS.ntfs_cur_read], 0x200
1472
        cmp     [ebp+NTFS.ntfs_cur_read], 0x200
1461
        jz      .alignedstart
1473
        jz      .alignedstart
1462
.eof_ebx:
1474
.eof_ebx:
1463
        popad
1475
        popad
1464
        jmp     .eof
1476
        jmp     .eof
1465
.alignedstart:
1477
.alignedstart:
1466
        mov     eax, [ebx+4]
1478
        mov     eax, [ebx+4]
1467
        push    edx
1479
        push    edx
1468
        mov     edx, [ebx+8]
1480
        mov     edx, [ebx+8]
1469
        add     eax, 511
1481
        add     eax, 511
1470
        adc     edx, 0
1482
        adc     edx, 0
1471
        shrd    eax, edx, 9
1483
        shrd    eax, edx, 9
1472
        pop     edx
1484
        pop     edx
1473
.zero1:
-
 
1474
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1485
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1475
        mov     [ebp+NTFS.ntfs_cur_buf], edx
1486
        mov     [ebp+NTFS.ntfs_cur_buf], edx
1476
        mov     eax, ecx
1487
        mov     eax, ecx
1477
        shr     eax, 9
1488
        shr     eax, 9
1478
        mov     [ebp+NTFS.ntfs_cur_size], eax
1489
        mov     [ebp+NTFS.ntfs_cur_size], eax
1479
        add     eax, [ebp+NTFS.ntfs_cur_offs]
1490
        add     eax, [ebp+NTFS.ntfs_cur_offs]
1480
        push    eax
1491
        push    eax
1481
        call    ntfs_read_attr.continue
1492
        call    ntfs_read_attr.continue
1482
        pop     [ebp+NTFS.ntfs_cur_offs]
1493
        pop     [ebp+NTFS.ntfs_cur_offs]
1483
        mov     eax, [ebp+NTFS.ntfs_cur_read]
1494
        mov     eax, [ebp+NTFS.ntfs_cur_read]
1484
        add     [esp+10h], eax
1495
        add     [esp+10h], eax
1485
        mov     eax, ecx
1496
        mov     eax, ecx
1486
        and     eax, not 0x1FF
1497
        and     eax, not 0x1FF
1487
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1498
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1488
        jnz     .eof_ebx
1499
        jnz     .eof_ebx
1489
        and     ecx, 0x1FF
1500
        and     ecx, 0x1FF
1490
        jz      .retok
1501
        jz      .retok
1491
        add     edx, [ebp+NTFS.ntfs_cur_read]
1502
        add     edx, [ebp+NTFS.ntfs_cur_read]
1492
        mov     [ebp+NTFS.ntfs_cur_size], 1
1503
        mov     [ebp+NTFS.ntfs_cur_size], 1
1493
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1504
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1494
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1505
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1495
        call    ntfs_read_attr.continue
1506
        call    ntfs_read_attr.continue
1496
        cmp     [ebp+NTFS.ntfs_cur_read], ecx
1507
        cmp     [ebp+NTFS.ntfs_cur_read], ecx
1497
        jb      @f
1508
        jb      @f
1498
        mov     [ebp+NTFS.ntfs_cur_read], ecx
1509
        mov     [ebp+NTFS.ntfs_cur_read], ecx
1499
@@:
1510
@@:
1500
        xchg    ecx, [ebp+NTFS.ntfs_cur_read]
1511
        xchg    ecx, [ebp+NTFS.ntfs_cur_read]
1501
        push    ecx
1512
        push    ecx
1502
        mov     edi, edx
1513
        mov     edi, edx
1503
        lea     esi, [ebp+NTFS.ntfs_bitmap_buf]
1514
        lea     esi, [ebp+NTFS.ntfs_bitmap_buf]
1504
        add     [esp+10h+4], ecx
1515
        add     [esp+10h+4], ecx
1505
        rep movsb
1516
        rep movsb
1506
        pop     ecx
1517
        pop     ecx
1507
        xor     eax, eax
1518
        xor     eax, eax
1508
        cmp     ecx, [ebp+NTFS.ntfs_cur_read]
1519
        cmp     ecx, [ebp+NTFS.ntfs_cur_read]
1509
        jz      @f
1520
        jz      @f
1510
        mov     al, ERROR_END_OF_FILE
1521
        mov     al, ERROR_END_OF_FILE
1511
@@:
1522
@@:
1512
        mov     [esp+1Ch], eax
1523
        mov     [esp+1Ch], eax
1513
        call    ntfs_unlock
1524
        call    ntfs_unlock
1514
        popad
1525
        popad
1515
        ret
1526
        ret
1516
 
1527
 
1517
;----------------------------------------------------------------
1528
;----------------------------------------------------------------
1518
ntfs_ReadFolder:
1529
ntfs_ReadFolder:
1519
        call    ntfs_lock
1530
        call    ntfs_lock
1520
        mov     eax, 5          ; root cluster
1531
        mov     eax, 5          ; root cluster
1521
        cmp     byte [esi], 0
1532
        cmp     byte [esi], 0
1522
        jz      .doit
1533
        jz      .doit
1523
        stdcall ntfs_find_lfn, [esp+4]
1534
        stdcall ntfs_find_lfn, [esp+4]
1524
        jnc     .doit2
1535
        jnc     .doit2
1525
.notfound:
1536
.notfound:
1526
        or      ebx, -1
1537
        or      ebx, -1
1527
        push    ERROR_FILE_NOT_FOUND
1538
        push    ERROR_FILE_NOT_FOUND
1528
.pop_ret:
1539
.pop_ret:
1529
        call    ntfs_unlock
1540
        call    ntfs_unlock
1530
        pop     eax
1541
        pop     eax
1531
        ret
1542
        ret
1532
.doit:
1543
.doit:
1533
        mov     [ebp+NTFS.ntfs_cur_iRecord], eax
1544
        mov     [ebp+NTFS.ntfs_cur_iRecord], eax
1534
.doit2:
1545
.doit2:
1535
        mov     [ebp+NTFS.ntfs_cur_attr], 0x10   ; $STANDARD_INFORMATION
1546
        mov     [ebp+NTFS.ntfs_cur_attr], 0x10   ; $STANDARD_INFORMATION
1536
        and     [ebp+NTFS.ntfs_cur_offs], 0
1547
        and     [ebp+NTFS.ntfs_cur_offs], 0
1537
        mov     [ebp+NTFS.ntfs_cur_size], 1
1548
        mov     [ebp+NTFS.ntfs_cur_size], 1
1538
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1549
        lea     eax, [ebp+NTFS.ntfs_bitmap_buf]
1539
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1550
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1540
        call    ntfs_read_attr
1551
        call    ntfs_read_attr
1541
        jc      .notfound
1552
        jc      .notfound
1542
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1553
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1543
        and     [ebp+NTFS.ntfs_cur_offs], 0
1554
        and     [ebp+NTFS.ntfs_cur_offs], 0
1544
        mov     eax, [ebp+NTFS.cur_index_size]
1555
        mov     eax, [ebp+NTFS.cur_index_size]
1545
        mov     [ebp+NTFS.ntfs_cur_size], eax
1556
        mov     [ebp+NTFS.ntfs_cur_size], eax
1546
        mov     eax, [ebp+NTFS.cur_index_buf]
1557
        mov     eax, [ebp+NTFS.cur_index_buf]
1547
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1558
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1548
        call    ntfs_read_attr
1559
        call    ntfs_read_attr
1549
        jnc     .ok
1560
        jnc     .ok
1550
        test    eax, eax
1561
        test    eax, eax
1551
        jz      .notfound
1562
        jz      .notfound
1552
        or      ebx, -1
1563
        or      ebx, -1
1553
        push    11
1564
        push    ERROR_DEVICE
1554
        jmp     .pop_ret
1565
        jmp     .pop_ret
1555
.ok:
1566
.ok:
1556
        cmp     [ebp+NTFS.ntfs_cur_read], 0x20
1567
        cmp     [ebp+NTFS.ntfs_cur_read], 0x20
1557
        jae     @f
1568
        jae     @f
1558
        or      ebx, -1
1569
        or      ebx, -1
1559
.fserr:
1570
.fserr:
1560
        push    ERROR_FAT_TABLE
1571
        push    ERROR_FAT_TABLE
1561
        jmp     .pop_ret
1572
        jmp     .pop_ret
1562
@@:
1573
@@:
1563
        pushad
1574
        pushad
1564
        mov     esi, [ebp+NTFS.cur_index_buf]
1575
        mov     esi, [ebp+NTFS.cur_index_buf]
1565
        mov     eax, [esi+14h]
1576
        mov     eax, [esi+14h]
1566
        add     eax, 10h
1577
        add     eax, 10h
1567
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1578
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1568
        jae     .readok1
1579
        jae     .readok1
1569
        add     eax, 1FFh
1580
        add     eax, 1FFh
1570
        shr     eax, 9
1581
        shr     eax, 9
1571
        cmp     eax, [ebp+NTFS.cur_index_size]
1582
        cmp     eax, [ebp+NTFS.cur_index_size]
1572
        ja      @f
1583
        ja      @f
1573
        popad
1584
        popad
1574
        jmp     .fserr
1585
        jmp     .fserr
1575
@@:
1586
@@:
1576
; reallocate
1587
; reallocate
1577
        push    eax
1588
        push    eax
1578
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1589
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1579
        pop     eax
1590
        pop     eax
1580
        mov     [ebp+NTFS.cur_index_size], eax
1591
        mov     [ebp+NTFS.cur_index_size], eax
1581
        stdcall kernel_alloc, eax
1592
        stdcall kernel_alloc, eax
1582
        test    eax, eax
1593
        test    eax, eax
1583
        jnz     @f
1594
        jnz     @f
1584
        and     [ebp+NTFS.cur_index_size], 0
1595
        and     [ebp+NTFS.cur_index_size], 0
1585
        and     [ebp+NTFS.cur_index_buf], 0
1596
        and     [ebp+NTFS.cur_index_buf], 0
1586
.nomem:
1597
.nomem:
1587
        call    ntfs_unlock
1598
        call    ntfs_unlock
1588
        popad
1599
        popad
1589
        or      ebx, -1
1600
        or      ebx, -1
1590
        movi    eax, 12
1601
        movi    eax, ERROR_OUT_OF_MEMORY
1591
        ret
1602
        ret
1592
@@:
1603
@@:
1593
        mov     [ebp+NTFS.cur_index_buf], eax
1604
        mov     [ebp+NTFS.cur_index_buf], eax
1594
        popad
1605
        popad
1595
        jmp     .doit2
1606
        jmp     .doit2
1596
.readok1:
1607
.readok1:
1597
        mov     edx, [esi+8]    ; subnode_size
1608
        mov     edx, [esi+8]    ; subnode_size
1598
        shr     edx, 9
1609
        shr     edx, 9
1599
        mov     [ebp+NTFS.cur_subnode_size], edx
1610
        mov     [ebp+NTFS.cur_subnode_size], edx
1600
        cmp     edx, [ebp+NTFS.cur_index_size]
1611
        cmp     edx, [ebp+NTFS.cur_index_size]
1601
        jbe     .ok2
1612
        jbe     .ok2
1602
        push    esi edx
1613
        push    esi edx
1603
        stdcall kernel_alloc, edx
1614
        stdcall kernel_alloc, edx
1604
        pop     edx esi
1615
        pop     edx esi
1605
        test    eax, eax
1616
        test    eax, eax
1606
        jz      .nomem
1617
        jz      .nomem
1607
        mov     edi, eax
1618
        mov     edi, eax
1608
        mov     ecx, [ebp+NTFS.cur_index_size]
1619
        mov     ecx, [ebp+NTFS.cur_index_size]
1609
        shl     ecx, 9-2
1620
        shl     ecx, 9-2
1610
        rep movsd
1621
        rep movsd
1611
        mov     esi, eax
1622
        mov     esi, eax
1612
        mov     [ebp+NTFS.cur_index_size], edx
1623
        mov     [ebp+NTFS.cur_index_size], edx
1613
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1624
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1614
        mov     [ebp+NTFS.cur_index_buf], esi
1625
        mov     [ebp+NTFS.cur_index_buf], esi
1615
.ok2:
1626
.ok2:
1616
        add     esi, 10h
1627
        add     esi, 10h
1617
        mov     edx, [ebx+16]
1628
        mov     edx, [ebx+16]
1618
        push    dword [ebx+8]   ; read ANSI/UNICODE name
1629
        push    dword [ebx+8]   ; read ANSI/UNICODE name
1619
; init header
1630
; init header
1620
        mov     edi, edx
1631
        mov     edi, edx
1621
        mov     ecx, 32/4
1632
        mov     ecx, 32/4
1622
        xor     eax, eax
1633
        xor     eax, eax
1623
        rep stosd
1634
        rep stosd
1624
        mov     byte [edx], 1   ; version
1635
        mov     byte [edx], 1   ; version
1625
        mov     ecx, [ebx+12]
1636
        mov     ecx, [ebx+12]
1626
        mov     ebx, [ebx+4]
1637
        mov     ebx, [ebx+4]
1627
        push    edx
1638
        push    edx
1628
        mov     edx, esp
1639
        mov     edx, esp
1629
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
1640
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
1630
; ecx = number of blocks to read
1641
; ecx = number of blocks to read
1631
; edx -> parameters block: dd , dd 
1642
; edx -> parameters block: dd , dd 
1632
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 5
1643
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 5
1633
        jz      .skip_specials
1644
        jz      .skip_specials
1634
; dot and dotdot entries
1645
; dot and dotdot entries
1635
        push    esi
1646
        push    esi
1636
        xor     esi, esi
1647
        xor     esi, esi
1637
        call    .add_special_entry
1648
        call    .add_special_entry
1638
        inc     esi
1649
        inc     esi
1639
        call    .add_special_entry
1650
        call    .add_special_entry
1640
        pop     esi
1651
        pop     esi
1641
.skip_specials:
1652
.skip_specials:
1642
; at first, dump index root
1653
; at first, dump index root
1643
        add     esi, [esi]
1654
        add     esi, [esi]
1644
.dump_root:
1655
.dump_root:
1645
        test    byte [esi+0Ch], 2
1656
        test    byte [esi+0Ch], 2
1646
        jnz     .dump_root_done
1657
        jnz     .dump_root_done
1647
        call    .add_entry
1658
        call    .add_entry
1648
        movzx   eax, word [esi+8]
1659
        movzx   eax, word [esi+8]
1649
        add     esi, eax
1660
        add     esi, eax
1650
        jmp     .dump_root
1661
        jmp     .dump_root
1651
.dump_root_done:
1662
.dump_root_done:
1652
; now dump all subnodes
1663
; now dump all subnodes
1653
        push    ecx edi
1664
        push    ecx edi
1654
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
1665
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
1655
        mov     [ebp+NTFS.ntfs_cur_buf], edi
1666
        mov     [ebp+NTFS.ntfs_cur_buf], edi
1656
        mov     ecx, 0x400/4
1667
        mov     ecx, 0x400/4
1657
        xor     eax, eax
1668
        xor     eax, eax
1658
        rep stosd
1669
        rep stosd
1659
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0   ; $BITMAP
1670
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0   ; $BITMAP
1660
        and     [ebp+NTFS.ntfs_cur_offs], 0
1671
        and     [ebp+NTFS.ntfs_cur_offs], 0
1661
        mov     [ebp+NTFS.ntfs_cur_size], 2
1672
        mov     [ebp+NTFS.ntfs_cur_size], 2
1662
        call    ntfs_read_attr
1673
        call    ntfs_read_attr
1663
        pop     edi ecx
1674
        pop     edi ecx
1664
        push    0       ; save offset in $BITMAP attribute
1675
        push    0       ; save offset in $BITMAP attribute
1665
        and     [ebp+NTFS.ntfs_cur_offs], 0
1676
        and     [ebp+NTFS.ntfs_cur_offs], 0
1666
.dumploop:
1677
.dumploop:
1667
        mov     [ebp+NTFS.ntfs_cur_attr], 0xA0
1678
        mov     [ebp+NTFS.ntfs_cur_attr], 0xA0
1668
        mov     eax, [ebp+NTFS.cur_subnode_size]
1679
        mov     eax, [ebp+NTFS.cur_subnode_size]
1669
        mov     [ebp+NTFS.ntfs_cur_size], eax
1680
        mov     [ebp+NTFS.ntfs_cur_size], eax
1670
        mov     eax, [ebp+NTFS.cur_index_buf]
1681
        mov     eax, [ebp+NTFS.cur_index_buf]
1671
        mov     esi, eax
1682
        mov     esi, eax
1672
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1683
        mov     [ebp+NTFS.ntfs_cur_buf], eax
1673
        push    [ebp+NTFS.ntfs_cur_offs]
1684
        push    [ebp+NTFS.ntfs_cur_offs]
1674
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
1685
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
1675
        imul    eax, [ebp+NTFS.cur_subnode_size]
1686
        imul    eax, [ebp+NTFS.cur_subnode_size]
1676
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1687
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1677
        call    ntfs_read_attr
1688
        call    ntfs_read_attr
1678
        pop     [ebp+NTFS.ntfs_cur_offs]
1689
        pop     [ebp+NTFS.ntfs_cur_offs]
1679
        mov     eax, [ebp+NTFS.cur_subnode_size]
1690
        mov     eax, [ebp+NTFS.cur_subnode_size]
1680
        shl     eax, 9
1691
        shl     eax, 9
1681
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1692
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1682
        jnz     .done
1693
        jnz     .done
1683
        push    eax
1694
        push    eax
1684
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
1695
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
1685
        and     eax, 0x400*8-1
1696
        and     eax, 0x400*8-1
1686
        bt      dword [ebp+NTFS.ntfs_bitmap_buf], eax
1697
        bt      dword [ebp+NTFS.ntfs_bitmap_buf], eax
1687
        pop     eax
1698
        pop     eax
1688
        jnc     .dump_subnode_done
1699
        jnc     .dump_subnode_done
1689
        cmp     dword [esi], 'INDX'
1700
        cmp     dword [esi], 'INDX'
1690
        jnz     .dump_subnode_done
1701
        jnz     .dump_subnode_done
1691
        push    ebx
1702
        push    ebx
1692
        mov     ebx, esi
1703
        mov     ebx, esi
1693
        call    ntfs_restore_usa
1704
        call    ntfs_restore_usa
1694
        pop     ebx
1705
        pop     ebx
1695
        jc      .dump_subnode_done
1706
        jc      .dump_subnode_done
1696
        add     esi, 0x18
1707
        add     esi, 0x18
1697
        add     esi, [esi]
1708
        add     esi, [esi]
1698
.dump_subnode:
1709
.dump_subnode:
1699
        test    byte [esi+0Ch], 2
1710
        test    byte [esi+0Ch], 2
1700
        jnz     .dump_subnode_done
1711
        jnz     .dump_subnode_done
1701
        call    .add_entry
1712
        call    .add_entry
1702
        movzx   eax, word [esi+8]
1713
        movzx   eax, word [esi+8]
1703
        add     esi, eax
1714
        add     esi, eax
1704
        jmp     .dump_subnode
1715
        jmp     .dump_subnode
1705
.dump_subnode_done:
1716
.dump_subnode_done:
1706
        inc     [ebp+NTFS.ntfs_cur_offs]
1717
        inc     [ebp+NTFS.ntfs_cur_offs]
1707
        test    [ebp+NTFS.ntfs_cur_offs], 0x400*8-1
1718
        test    [ebp+NTFS.ntfs_cur_offs], 0x400*8-1
1708
        jnz     .dumploop
1719
        jnz     .dumploop
1709
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0
1720
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0
1710
        push    ecx edi
1721
        push    ecx edi
1711
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
1722
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
1712
        mov     [ebp+NTFS.ntfs_cur_buf], edi
1723
        mov     [ebp+NTFS.ntfs_cur_buf], edi
1713
        mov     ecx, 0x400/4
1724
        mov     ecx, 0x400/4
1714
        xor     eax, eax
1725
        xor     eax, eax
1715
        rep stosd
1726
        rep stosd
1716
        pop     edi ecx
1727
        pop     edi ecx
1717
        pop     eax
1728
        pop     eax
1718
        push    [ebp+NTFS.ntfs_cur_offs]
1729
        push    [ebp+NTFS.ntfs_cur_offs]
1719
        inc     eax
1730
        inc     eax
1720
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1731
        mov     [ebp+NTFS.ntfs_cur_offs], eax
1721
        mov     [ebp+NTFS.ntfs_cur_size], 2
1732
        mov     [ebp+NTFS.ntfs_cur_size], 2
1722
        push    eax
1733
        push    eax
1723
        call    ntfs_read_attr
1734
        call    ntfs_read_attr
1724
        pop     eax
1735
        pop     eax
1725
        pop     [ebp+NTFS.ntfs_cur_offs]
1736
        pop     [ebp+NTFS.ntfs_cur_offs]
1726
        push    eax
1737
        push    eax
1727
        jmp     .dumploop
1738
        jmp     .dumploop
1728
.done:
1739
.done:
1729
        pop     eax
1740
        pop     eax
1730
        pop     edx
1741
        pop     edx
1731
        mov     ebx, [edx+4]
1742
        mov     ebx, [edx+4]
1732
        pop     edx
1743
        pop     edx
1733
        xor     eax, eax
1744
        xor     eax, eax
1734
        dec     ecx
1745
        dec     ecx
1735
        js      @f
1746
        js      @f
1736
        mov     al, ERROR_END_OF_FILE
1747
        mov     al, ERROR_END_OF_FILE
1737
@@:
1748
@@:
1738
        mov     [esp+1Ch], eax
1749
        mov     [esp+1Ch], eax
1739
        mov     [esp+10h], ebx
1750
        mov     [esp+10h], ebx
1740
        call    ntfs_unlock
1751
        call    ntfs_unlock
1741
        popad
1752
        popad
1742
        ret
1753
        ret
1743
 
1754
 
1744
.add_special_entry:
1755
.add_special_entry:
1745
        mov     eax, [edx]
1756
        mov     eax, [edx]
1746
        inc     dword [eax+8]   ; new file found
1757
        inc     dword [eax+8]   ; new file found
1747
        dec     ebx
1758
        dec     ebx
1748
        jns     .ret
1759
        jns     .ret
1749
        dec     ecx
1760
        dec     ecx
1750
        js      .ret
1761
        js      .ret
1751
        inc     dword [eax+4]   ; new file block copied
1762
        inc     dword [eax+4]   ; new file block copied
1752
        mov     eax, [edx+4]
1763
        mov     eax, [edx+4]
1753
        mov     [edi+4], eax
1764
        mov     [edi+4], eax
1754
;        mov     eax, dword [ntfs_bitmap_buf+0x20]
1765
;        mov     eax, dword [ntfs_bitmap_buf+0x20]
1755
;        or      al, 0x10
1766
;        or      al, 0x10
1756
        mov     eax, 0x10
1767
        mov     eax, 0x10
1757
        stosd
1768
        stosd
1758
        scasd
1769
        scasd
1759
        push    edx
1770
        push    edx
1760
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf]
1771
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf]
1761
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+4]
1772
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+4]
1762
        call    ntfs_datetime_to_bdfe
1773
        call    ntfs_datetime_to_bdfe
1763
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18]
1774
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18]
1764
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C]
1775
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C]
1765
        call    ntfs_datetime_to_bdfe
1776
        call    ntfs_datetime_to_bdfe
1766
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf+8]
1777
        mov     eax, dword [ebp+NTFS.ntfs_bitmap_buf+8]
1767
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC]
1778
        mov     edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC]
1768
        call    ntfs_datetime_to_bdfe
1779
        call    ntfs_datetime_to_bdfe
1769
        pop     edx
1780
        pop     edx
1770
        xor     eax, eax
1781
        xor     eax, eax
1771
        stosd
1782
        stosd
1772
        stosd
1783
        stosd
1773
        mov     al, '.'
1784
        mov     al, '.'
1774
        push    edi ecx
1785
        push    edi ecx
1775
        lea     ecx, [esi+1]
1786
        lea     ecx, [esi+1]
1776
        test    byte [edi-0x24], 1
1787
        test    byte [edi-0x24], 1
1777
        jz      @f
1788
        jz      @f
1778
        rep stosw
1789
        rep stosw
1779
        pop     ecx
1790
        pop     ecx
1780
        xor     eax, eax
1791
        xor     eax, eax
1781
        stosw
1792
        stosw
1782
        pop     edi
1793
        pop     edi
1783
        add     edi, 520
1794
        add     edi, 520
1784
        ret
1795
        ret
1785
@@:
1796
@@:
1786
        rep stosb
1797
        rep stosb
1787
        pop     ecx
1798
        pop     ecx
1788
        xor     eax, eax
1799
        xor     eax, eax
1789
        stosb
1800
        stosb
1790
        pop     edi
1801
        pop     edi
1791
        add     edi, 264
1802
        add     edi, 264
1792
.ret:
1803
.ret:
1793
        ret
1804
        ret
1794
 
1805
 
1795
.add_entry:
1806
.add_entry:
1796
; do not return DOS 8.3 names
1807
; do not return DOS 8.3 names
1797
        cmp     byte [esi+0x51], 2
1808
        cmp     byte [esi+0x51], 2
1798
        jz      .ret
1809
        jz      .ret
1799
; do not return system files
1810
; do not return system files
1800
; ... note that there will be no bad effects if system files also were reported ...
1811
; ... note that there will be no bad effects if system files also were reported ...
1801
        cmp     dword [esi], 0x10
1812
        cmp     dword [esi], 0x10
1802
        jb      .ret
1813
        jb      .ret
1803
        mov     eax, [edx]
1814
        mov     eax, [edx]
1804
        inc     dword [eax+8]   ; new file found
1815
        inc     dword [eax+8]   ; new file found
1805
        dec     ebx
1816
        dec     ebx
1806
        jns     .ret
1817
        jns     .ret
1807
        dec     ecx
1818
        dec     ecx
1808
        js      .ret
1819
        js      .ret
1809
        inc     dword [eax+4]   ; new file block copied
1820
        inc     dword [eax+4]   ; new file block copied
1810
        mov     eax, [edx+4]    ; flags
1821
        mov     eax, [edx+4]    ; flags
1811
        call    ntfs_direntry_to_bdfe
1822
        call    ntfs_direntry_to_bdfe
1812
        push    ecx esi edi
1823
        push    ecx esi edi
1813
        movzx   ecx, byte [esi+0x50]
1824
        movzx   ecx, byte [esi+0x50]
1814
        add     esi, 0x52
1825
        add     esi, 0x52
1815
        test    byte [edi-0x24], 1
1826
        test    byte [edi-0x24], 1
1816
        jz      .ansi
1827
        jz      .ansi
1817
        shr     ecx, 1
1828
        shr     ecx, 1
1818
        rep movsd
1829
        rep movsd
1819
        adc     ecx, ecx
1830
        adc     ecx, ecx
1820
        rep movsw
1831
        rep movsw
1821
        and     word [edi], 0
1832
        and     word [edi], 0
1822
        pop     edi
1833
        pop     edi
1823
        add     edi, 520
1834
        add     edi, 520
1824
        pop     esi ecx
1835
        pop     esi ecx
1825
        ret
1836
        ret
1826
.ansi:
1837
.ansi:
1827
        jecxz   .skip
1838
        jecxz   .skip
1828
@@:
1839
@@:
1829
        lodsw
1840
        lodsw
1830
        call    uni2ansi_char
1841
        call    uni2ansi_char
1831
        stosb
1842
        stosb
1832
        loop    @b
1843
        loop    @b
1833
.skip:
1844
.skip:
1834
        xor     al, al
1845
        xor     al, al
1835
        stosb
1846
        stosb
1836
        pop     edi
1847
        pop     edi
1837
        add     edi, 264
1848
        add     edi, 264
1838
        pop     esi ecx
1849
        pop     esi ecx
1839
        ret
1850
        ret
1840
 
1851
 
1841
ntfs_direntry_to_bdfe:
1852
ntfs_direntry_to_bdfe:
1842
        mov     [edi+4], eax    ; ANSI/UNICODE name
1853
        mov     [edi+4], eax    ; ANSI/UNICODE name
1843
        mov     eax, [esi+48h]
1854
        mov     eax, [esi+48h]
1844
        test    eax, 0x10000000
1855
        test    eax, 0x10000000
1845
        jz      @f
1856
        jz      @f
1846
        and     eax, not 0x10000000
1857
        and     eax, not 0x10000000
1847
        or      al, 0x10
1858
        or      al, 0x10
1848
@@:
1859
@@:
1849
        stosd
1860
        stosd
1850
        scasd
1861
        scasd
1851
        push    edx
1862
        push    edx
1852
        mov     eax, [esi+0x18]
1863
        mov     eax, [esi+0x18]
1853
        mov     edx, [esi+0x1C]
1864
        mov     edx, [esi+0x1C]
1854
        call    ntfs_datetime_to_bdfe
1865
        call    ntfs_datetime_to_bdfe
1855
        mov     eax, [esi+0x30]
1866
        mov     eax, [esi+0x30]
1856
        mov     edx, [esi+0x34]
1867
        mov     edx, [esi+0x34]
1857
        call    ntfs_datetime_to_bdfe
1868
        call    ntfs_datetime_to_bdfe
1858
        mov     eax, [esi+0x20]
1869
        mov     eax, [esi+0x20]
1859
        mov     edx, [esi+0x24]
1870
        mov     edx, [esi+0x24]
1860
        call    ntfs_datetime_to_bdfe
1871
        call    ntfs_datetime_to_bdfe
1861
        pop     edx
1872
        pop     edx
1862
        mov     eax, [esi+0x40]
1873
        mov     eax, [esi+0x40]
1863
        stosd
1874
        stosd
1864
        mov     eax, [esi+0x44]
1875
        mov     eax, [esi+0x44]
1865
        stosd
1876
        stosd
1866
        ret
1877
        ret
1867
 
1878
 
1868
iglobal
1879
iglobal
1869
_24             dd      24
1880
_24             dd      24
1870
_60             dd      60
1881
_60             dd      60
1871
_10000000       dd      10000000
1882
_10000000       dd      10000000
1872
days400year     dd      365*400+100-4+1
1883
days400year     dd      365*400+100-4+1
1873
days100year     dd      365*100+25-1
1884
days100year     dd      365*100+25-1
1874
days4year       dd      365*4+1
1885
days4year       dd      365*4+1
1875
days1year       dd      365
1886
days1year       dd      365
1876
months  dd  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1887
months  dd  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1877
months2 dd  31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1888
months2 dd  31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1878
_400            dd      400
1889
_400            dd      400
1879
_100            dd      100
1890
_100            dd      100
1880
endg
1891
endg
1881
 
1892
 
1882
ntfs_datetime_to_bdfe:
1893
ntfs_datetime_to_bdfe:
1883
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
1894
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
1884
        push    eax
1895
        push    eax
1885
        mov     eax, edx
1896
        mov     eax, edx
1886
        xor     edx, edx
1897
        xor     edx, edx
1887
        div     [_10000000]
1898
        div     [_10000000]
1888
        xchg    eax, [esp]
1899
        xchg    eax, [esp]
1889
        div     [_10000000]
1900
        div     [_10000000]
1890
        pop     edx
1901
        pop     edx
1891
    .sec:
1902
    .sec:
1892
; edx:eax = number of seconds since January 1, 1601
1903
; edx:eax = number of seconds since January 1, 1601
1893
        push    eax
1904
        push    eax
1894
        mov     eax, edx
1905
        mov     eax, edx
1895
        xor     edx, edx
1906
        xor     edx, edx
1896
        div     [_60]
1907
        div     [_60]
1897
        xchg    eax, [esp]
1908
        xchg    eax, [esp]
1898
        div     [_60]
1909
        div     [_60]
1899
        mov     [edi], dl
1910
        mov     [edi], dl
1900
        pop     edx
1911
        pop     edx
1901
; edx:eax = number of minutes
1912
; edx:eax = number of minutes
1902
        div     [_60]
1913
        div     [_60]
1903
        mov     [edi+1], dl
1914
        mov     [edi+1], dl
1904
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
1915
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
1905
        xor     edx, edx
1916
        xor     edx, edx
1906
        div     [_24]
1917
        div     [_24]
1907
        mov     [edi+2], dl
1918
        mov     [edi+2], dl
1908
        mov     [edi+3], byte 0
1919
        mov     [edi+3], byte 0
1909
; eax = number of days since January 1, 1601
1920
; eax = number of days since January 1, 1601
1910
        xor     edx, edx
1921
        xor     edx, edx
1911
        div     [days400year]
1922
        div     [days400year]
1912
        imul    eax, 400
1923
        imul    eax, 400
1913
        add     eax, 1601
1924
        add     eax, 1601
1914
        mov     [edi+6], ax
1925
        mov     [edi+6], ax
1915
        mov     eax, edx
1926
        mov     eax, edx
1916
        xor     edx, edx
1927
        xor     edx, edx
1917
        div     [days100year]
1928
        div     [days100year]
1918
        cmp     al, 4
1929
        cmp     al, 4
1919
        jnz     @f
1930
        jnz     @f
1920
        dec     eax
1931
        dec     eax
1921
        add     edx, [days100year]
1932
        add     edx, [days100year]
1922
@@:
1933
@@:
1923
        imul    eax, 100
1934
        imul    eax, 100
1924
        add     [edi+6], ax
1935
        add     [edi+6], ax
1925
        mov     eax, edx
1936
        mov     eax, edx
1926
        xor     edx, edx
1937
        xor     edx, edx
1927
        div     [days4year]
1938
        div     [days4year]
1928
        shl     eax, 2
1939
        shl     eax, 2
1929
        add     [edi+6], ax
1940
        add     [edi+6], ax
1930
        mov     eax, edx
1941
        mov     eax, edx
1931
        xor     edx, edx
1942
        xor     edx, edx
1932
        div     [days1year]
1943
        div     [days1year]
1933
        cmp     al, 4
1944
        cmp     al, 4
1934
        jnz     @f
1945
        jnz     @f
1935
        dec     eax
1946
        dec     eax
1936
        add     edx, [days1year]
1947
        add     edx, [days1year]
1937
@@:
1948
@@:
1938
        add     [edi+6], ax
1949
        add     [edi+6], ax
1939
        push    esi edx
1950
        push    esi edx
1940
        mov     esi, months
1951
        mov     esi, months
1941
        movzx   eax, word [edi+6]
1952
        movzx   eax, word [edi+6]
1942
        test    al, 3
1953
        test    al, 3
1943
        jnz     .noleap
1954
        jnz     .noleap
1944
        xor     edx, edx
1955
        xor     edx, edx
1945
        push    eax
1956
        push    eax
1946
        div     [_400]
1957
        div     [_400]
1947
        pop     eax
1958
        pop     eax
1948
        test    edx, edx
1959
        test    edx, edx
1949
        jz      .leap
1960
        jz      .leap
1950
        xor     edx, edx
1961
        xor     edx, edx
1951
        div     [_100]
1962
        div     [_100]
1952
        test    edx, edx
1963
        test    edx, edx
1953
        jz      .noleap
1964
        jz      .noleap
1954
.leap:
1965
.leap:
1955
        mov     esi, months2
1966
        mov     esi, months2
1956
.noleap:
1967
.noleap:
1957
        pop     edx
1968
        pop     edx
1958
        xor     eax, eax
1969
        xor     eax, eax
1959
        inc     eax
1970
        inc     eax
1960
@@:
1971
@@:
1961
        sub     edx, [esi]
1972
        sub     edx, [esi]
1962
        jb      @f
1973
        jb      @f
1963
        add     esi, 4
1974
        add     esi, 4
1964
        inc     eax
1975
        inc     eax
1965
        jmp     @b
1976
        jmp     @b
1966
@@:
1977
@@:
1967
        add     edx, [esi]
1978
        add     edx, [esi]
1968
        pop     esi
1979
        pop     esi
1969
        inc     edx
1980
        inc     edx
1970
        mov     [edi+4], dl
1981
        mov     [edi+4], dl
1971
        mov     [edi+5], al
1982
        mov     [edi+5], al
1972
        add     edi, 8
1983
        add     edi, 8
1973
        ret
1984
        ret
1974
 
1985
 
1975
;----------------------------------------------------------------
1986
;----------------------------------------------------------------
1976
ntfs_CreateFolder:
1987
ntfs_CreateFolder:
1977
        mov     [ebp+NTFS.ntfsFolder], 1
1988
        mov     [ebp+NTFS.ntfsFolder], 1
1978
        jmp     @f
1989
        jmp     @f
-
 
1990
 
1979
ntfs_CreateFile:
1991
ntfs_CreateFile:
1980
        mov     [ebp+NTFS.ntfsFolder], 0
1992
        mov     [ebp+NTFS.ntfsFolder], 0
1981
@@:
1993
@@:
1982
        cmp     byte [esi], 0
1994
        cmp     byte [esi], 0
1983
        jnz     @f
1995
        jnz     @f
1984
        xor     ebx, ebx
1996
        xor     ebx, ebx
1985
        movi    eax, ERROR_ACCESS_DENIED    ; root directory itself
1997
        movi    eax, ERROR_ACCESS_DENIED
1986
        ret
1998
        ret
1987
@@: ; 1. Search file
1999
@@: ; 1. Search file
1988
        call    ntfs_lock
2000
        call    ntfs_lock
1989
        mov     [ebp+NTFS.ntfsNotFound], 0
-
 
1990
        stdcall ntfs_find_lfn, [esp+4]
2001
        stdcall ntfs_find_lfn, [esp+4]
1991
        jnc     @f      ; found; rewrite
2002
        jnc     .found
1992
        cmp     [ebp+NTFS.ntfsFragmentCount], 1
2003
        cmp     [ebp+NTFS.ntfsFragmentCount], 1
1993
        jnz     @f      ; record fragmented
2004
        jnz     ntfsUnsupported     ; record fragmented
-
 
2005
        test    eax, eax
-
 
2006
        jz      ntfsFail
-
 
2007
        jmp     .notFound
-
 
2008
 
-
 
2009
.found:     ; rewrite
-
 
2010
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 16
-
 
2011
        jc      ntfsDenied
1994
        cmp     [ebp+NTFS.ntfsNotFound], 1
2012
        cmp     [ebp+NTFS.ntfsFolder], 1
1995
        jz      .notFound
2013
        jz      ntfsDenied
-
 
2014
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
-
 
2015
        mov     [ebp+NTFS.ntfs_cur_offs], 0
-
 
2016
        mov     [ebp+NTFS.ntfs_cur_size], 0
1996
        push    ERROR_FS_FAIL
2017
        call    ntfs_read_attr
1997
        jmp     ntfsError
2018
        jc      ntfsDenied
-
 
2019
        mov     eax, [ebp+NTFS.frs_buffer]
-
 
2020
        cmp     word [eax+baseRecordReuse], 0
-
 
2021
        jnz     ntfsUnsupported     ; auxiliary record
-
 
2022
        cmp     byte [eax+hardLinkCounter], 1
-
 
2023
        jnz     ntfsUnsupported     ; file copying required
-
 
2024
        mov     ecx, [ebp+NTFS.ntfs_attr_offs]
-
 
2025
        cmp     byte [ecx+nonResidentFlag], 1
-
 
2026
        jnz     ntfsUnsupported     ; resident $DATA
-
 
2027
        mov     eax, [ebx+4]
-
 
2028
        mov     edx, [ebx+8]
-
 
2029
        add     eax, [ebx+12]
1998
@@:
2030
        adc     edx, 0
-
 
2031
        cmp     edx, [ecx+attributeRealSize+4]
1999
        push    ERROR_UNSUPPORTED_FS
2032
        jnz     ntfsUnsupported
-
 
2033
        cmp     [ecx+attributeRealSize], eax
2000
        jmp     ntfsError
2034
        jnz     ntfsUnsupported
-
 
2035
        jmp     ntfs_WriteFile.write
-
 
2036
 
2001
.notFound:  ; create; check name
2037
.notFound:  ; create; check path folders
2002
        cmp     dword [esp+4], 0
2038
        cmp     dword [esp+4], 0
2003
        jnz     .bad
2039
        jnz     ntfsNotFound
2004
        cmp     byte [esi], 0
2040
        cmp     byte [esi], 0
2005
        jnz     @f
-
 
2006
.bad:       ; path folder not found
-
 
2007
        push    ERROR_FILE_NOT_FOUND
-
 
2008
        jmp     ntfsError
2041
        jz      ntfsNotFound
2009
@@: ; 2. Prepair directory record
2042
; 2. Prepare directory record
2010
        mov     ecx, esi
2043
        mov     ecx, esi
2011
@@:         ; count characters
2044
@@:         ; count characters
2012
        inc     ecx
2045
        inc     ecx
2013
        cmp     byte [ecx], '/'
2046
        cmp     byte [ecx], '/'
2014
        jz      .bad
2047
        jz      ntfsNotFound
2015
        cmp     byte [ecx], 0
2048
        cmp     byte [ecx], 0
2016
        jnz     @b
2049
        jnz     @b
2017
        sub     ecx, esi
2050
        sub     ecx, esi
2018
        push    ecx
2051
        push    ecx
2019
        lea     ecx, [ecx*2+52h]    ; precalculate index length
2052
        lea     ecx, [ecx*2+52h]    ; precalculate index length
2020
        add     ecx, 7              ; align 8
2053
        add     ecx, 7              ; align 8
2021
        and     ecx, not 7
2054
        and     ecx, not 7
2022
        mov     edi, [ebp+NTFS.cur_index_buf]
2055
        mov     edi, [ebp+NTFS.cur_index_buf]
2023
        push    esi
2056
        push    esi
2024
        push    ecx
2057
        push    ecx
2025
        cmp     dword [edi], 'INDX'         ; where are we?
2058
        cmp     dword [edi], 'INDX'
2026
        jz      .indexRecord
2059
        jz      .indexRecord
2027
        mov     esi, [ebp+NTFS.frs_buffer]  ; mftRecord
2060
        mov     esi, [ebp+NTFS.frs_buffer]  ; indexRoot
2028
        mov     edx, [esi+recordRealSize]
2061
        mov     edx, [esi+recordRealSize]
2029
        add     edx, ecx
2062
        add     edx, ecx
2030
        cmp     [esi+recordAllocatedSize], edx
2063
        cmp     [esi+recordAllocatedSize], edx
2031
        jnc     @f
2064
        jnc     @f
2032
        add     esp, 12
2065
        add     esp, 12
2033
        push    ERROR_UNSUPPORTED_FS    ; indexAllocation required
2066
        jmp     ntfsUnsupported     ; indexAllocation required
2034
        jmp     ntfsError
-
 
2035
@@:         ; index fits in the indexRoot
2067
@@:         ; index fits in the indexRoot
2036
        mov     [esi+recordRealSize], edx
2068
        mov     [esi+recordRealSize], edx
2037
        mov     ecx, edx
2069
        mov     ecx, edx
2038
        shr     ecx, 2
2070
        shr     ecx, 2
2039
        rep movsd
2071
        rep movsd
2040
        mov     edi, [ebp+NTFS.ntfs_attr_offs]
2072
        mov     edi, [ebp+NTFS.ntfs_attr_offs]
2041
        sub     edi, [ebp+NTFS.frs_buffer]
2073
        sub     edi, [ebp+NTFS.frs_buffer]
2042
        add     edi, [ebp+NTFS.cur_index_buf]
2074
        add     edi, [ebp+NTFS.cur_index_buf]
2043
        mov     esi, [esp]
2075
        mov     esi, [esp]
2044
        add     [edi+sizeWithHeader], esi
2076
        add     [edi+sizeWithHeader], esi
2045
        add     [edi+sizeWithoutHeader], esi
2077
        add     [edi+sizeWithoutHeader], esi
2046
        mov     cx, [edi+attributeOffset]
2078
        mov     cl, [edi+attributeOffset]
2047
        add     edi, ecx
2079
        add     edi, ecx
2048
        add     [edi+16+nodeRealSize], esi
2080
        add     [edi+16+nodeRealSize], esi
2049
        add     [edi+16+nodeAllocatedSize], esi
2081
        add     [edi+16+nodeAllocatedSize], esi
2050
        sub     eax, [ebp+NTFS.cur_index_buf]
2082
        sub     eax, [ebp+NTFS.cur_index_buf]
2051
        add     eax, edi
2083
        add     eax, edi
2052
        mov     edi, [ebp+NTFS.cur_index_buf]
2084
        mov     edi, [ebp+NTFS.cur_index_buf]
2053
        add     edi, edx
2085
        add     edi, edx
2054
        sub     edi, 4
2086
        sub     edi, 4
2055
        jmp     .common
2087
        jmp     .common
2056
 
2088
 
2057
.indexRecord:
2089
.indexRecord:
2058
        mov     edx, [edi+1ch]
2090
        mov     edx, [edi+28]
2059
        add     edx, ecx
2091
        add     edx, ecx
2060
        cmp     [edi+20h], edx
2092
        cmp     [edi+32], edx
2061
        jnc     @f
2093
        jnc     @f
2062
        add     esp, 12
2094
        add     esp, 12
2063
        push    ERROR_UNSUPPORTED_FS    ; new node required
2095
        jmp     ntfsUnsupported     ; new node required
2064
        jmp     ntfsError
-
 
2065
@@:         ; index fits in the node
2096
@@:         ; index fits in the node
2066
        mov     [edi+1ch], edx
2097
        mov     [edi+28], edx
2067
        lea     edi, [edi+edx+14h]
2098
        lea     edi, [edi+edx+24-4]
2068
.common:
2099
.common:
2069
        mov     esi, edi
2100
        mov     esi, edi
2070
        sub     esi, [esp]
2101
        sub     esi, [esp]
2071
        mov     ecx, esi
2102
        mov     ecx, esi
2072
        sub     ecx, eax    ; eax = pointer in the node
2103
        sub     ecx, eax    ; eax = pointer in the node
2073
        shr     ecx, 2
2104
        shr     ecx, 2
2074
        inc     ecx
2105
        inc     ecx
2075
        std
2106
        std
2076
        rep movsd           ; move forward, make space
2107
        rep movsd           ; move forward, make space
2077
        mov     ecx, [esp]
2108
        mov     ecx, [esp]
2078
        shr     ecx, 2
2109
        shr     ecx, 2
2079
        xor     eax, eax
2110
        xor     eax, eax
2080
        rep stosd
2111
        rep stosd
2081
        cld
2112
        cld
2082
        add     edi, 4
2113
        add     edi, 4
2083
        pop     eax
2114
        pop     eax
2084
        pop     esi
2115
        pop     esi
2085
        mov     [edi+indexAllocatedSize], ax     ; fill index with data
2116
        mov     [edi+indexAllocatedSize], ax     ; fill index with data
2086
        mov     eax, [esp]
2117
        mov     eax, [esp]
2087
        lea     eax, [eax*2+42h]
2118
        lea     eax, [eax*2+42h]
2088
        mov     [edi+indexRawSize], ax
2119
        mov     [edi+indexRawSize], ax
2089
        mov     eax, [ebp+NTFS.ntfs_attr_iRecord]
2120
        mov     eax, [ebp+NTFS.ntfs_attr_iRecord]
2090
        mov     [edi+directoryRecordReference], eax
2121
        mov     [edi+directoryRecordReference], eax
2091
        mov     eax, [ebp+NTFS.frs_buffer]
2122
        mov     eax, [ebp+NTFS.frs_buffer]
2092
        mov     eax, [eax+reuseCounter]
2123
        mov     eax, [eax+reuseCounter]
2093
        mov     [edi+directoryReferenceReuse], ax
2124
        mov     [edi+directoryReferenceReuse], ax
2094
        mov     eax, [ebx+12]
2125
        mov     eax, [ebx+12]
2095
        mov     [ebp+NTFS.fileRealSize], eax
2126
        mov     [ebp+NTFS.fileRealSize], eax
2096
        mov     [edi+fileRealSize], eax
2127
        mov     [edi+fileRealSize], eax
2097
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
2128
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
2098
        shl     ecx, 9
2129
        shl     ecx, 9
2099
        add     eax, ecx
2130
        add     eax, ecx
2100
        dec     eax
2131
        dec     eax
2101
        xor     edx, edx
2132
        xor     edx, edx
2102
        div     ecx
2133
        div     ecx
2103
        mov     [ebp+NTFS.fileDataSize], eax
2134
        mov     [ebp+NTFS.fileDataSize], eax
2104
        mul     ecx
2135
        mul     ecx
2105
        mov     [edi+fileAllocatedSize], eax
2136
        mov     [edi+fileAllocatedSize], eax
2106
        pop     ecx
2137
        pop     ecx
2107
        mov     [ebp+NTFS.indexOffset], edi
2138
        mov     [ebp+NTFS.indexOffset], edi
2108
        mov     [edi+fileNameLength], cl
2139
        mov     [edi+fileNameLength], cl
2109
        add     edi, 52h
2140
        add     edi, 52h
2110
@@:         ; record filename
2141
@@:         ; record filename
2111
        lodsb
2142
        lodsb
2112
        call    ansi2uni_char
2143
        call    ansi2uni_char
2113
        stosw
2144
        stosw
2114
        dec     ecx
2145
        dec     ecx
2115
        jnz     @b
2146
        jnz     @b
2116
        mov     eax, [ebp+NTFS.ntfsLastRead]
2147
        mov     eax, [ebp+NTFS.ntfsLastRead]
2117
        mov     [ebp+NTFS.nodeLastRead], eax
2148
        mov     [ebp+NTFS.nodeLastRead], eax
2118
        cmp     [ebp+NTFS.ntfsFolder], 0
2149
        cmp     [ebp+NTFS.ntfsFolder], 0
2119
        jz      @f
2150
        jz      @f
2120
        mov     edi, [ebp+NTFS.indexOffset]
2151
        mov     edi, [ebp+NTFS.indexOffset]
2121
        mov     byte [edi+fileFlags+3], 16
2152
        mov     byte [edi+fileFlags+3], 16
2122
        jmp     .mftBitmap
2153
        jmp     .mftBitmap
2123
 
2154
 
2124
@@: ; 3. File data
2155
@@: ; 3. File data
2125
        cmp     [ebp+NTFS.fileRealSize], 0
2156
        cmp     [ebp+NTFS.fileRealSize], 0
2126
        jz      .mftBitmap
2157
        jz      .mftBitmap
2127
    ; One piece free space bitmap search engine
2158
; One piece free space bitmap search engine
2128
        mov     edi, [ebp+NTFS.BitmapBuffer]
2159
        mov     edi, [ebp+NTFS.BitmapBuffer]
2129
        add     edi, [ebp+NTFS.BitmapStart]
2160
        add     edi, [ebp+NTFS.BitmapStart]
2130
        mov     eax, [ebp+NTFS.fileDataSize]
2161
        mov     eax, [ebp+NTFS.fileDataSize]
2131
        shr     eax, 5
2162
        shr     eax, 5
2132
        jz      .small
2163
        jz      .small
2133
        push    eax         ; bitmap dwords
2164
        push    eax         ; bitmap dwords
2134
        add     edi, 4
2165
        add     edi, 4
2135
        xor     edx, edx
-
 
2136
.start:
2166
.start:
2137
        mov     ecx, [ebp+NTFS.BitmapSize]
2167
        mov     ecx, [ebp+NTFS.BitmapSize]
2138
        mov     eax, edi
-
 
2139
        sub     eax, [ebp+NTFS.BitmapBuffer]
2168
        add     ecx, [ebp+NTFS.BitmapBuffer]
2140
        sub     ecx, eax
2169
        sub     ecx, edi
2141
        shr     ecx, 2
2170
        shr     ecx, 2
2142
@@:
2171
@@:
2143
        xor     eax, eax
2172
        xor     eax, eax
2144
        repnz scasd         ; search for empty dword
2173
        repnz scasd         ; search for empty dword
2145
        jz      @f
2174
        jz      @f
2146
        call    bitmapBuffering
2175
        call    bitmapBuffering
2147
        jmp     @b
2176
        jmp     @b
2148
@@:
2177
@@:
2149
        cmp     ecx, [esp]
2178
        cmp     ecx, [esp]
2150
        jnc     @f
2179
        jnc     @f
2151
        call    bitmapBuffering
2180
        call    bitmapBuffering
2152
        jmp     @b
2181
        jmp     @b
2153
@@:
2182
@@:
2154
        sub     edi, 4
2183
        sub     edi, 4
2155
        mov     ecx, [esp]
2184
        mov     ecx, [esp]
2156
        mov     esi, edi
2185
        mov     esi, edi
2157
        xor     eax, eax
2186
        xor     eax, eax
2158
        repz scasd          ; check following dwords
2187
        repz scasd          ; check following dwords
2159
        jnz     .start
2188
        jnz     .start
2160
        sub     esi, 4
2189
        sub     esi, 4
2161
        mov     eax, [esi]
2190
        mov     eax, [esi]
-
 
2191
        xor     edx, edx
2162
        bsr     edx, eax
2192
        bsr     edx, eax
2163
        inc     edx
2193
        inc     edx
2164
        push    edx         ; starting bit
2194
        push    edx         ; starting bit
2165
        push    esi         ; starting dword
2195
        push    esi         ; starting dword
2166
        add     esi, 4
2196
        add     esi, 4
2167
        neg     edx
2197
        neg     edx
2168
        add     edx, 32
2198
        add     edx, 32
2169
        mov     eax, [ebp+NTFS.fileDataSize]
2199
        mov     eax, [ebp+NTFS.fileDataSize]
2170
        sub     eax, edx
2200
        sub     eax, edx
2171
        mov     edx, eax
2201
        mov     edx, eax
2172
        shr     eax, 5
2202
        shr     eax, 5
2173
        shl     eax, 2
2203
        shl     eax, 2
2174
        add     esi, eax
2204
        add     esi, eax
2175
        mov     eax, [esi]
2205
        mov     eax, [esi]
2176
        bsf     ecx, eax    ; last dword
2206
        bsf     ecx, eax    ; last dword
2177
        jz      .done
2207
        jz      .done
2178
        and     edx, 31
2208
        and     edx, 31
2179
        cmp     ecx, edx
2209
        cmp     ecx, edx
2180
        jnc     .done
2210
        jnc     .done
2181
        add     esp, 8
2211
        add     esp, 8
2182
        jmp     .start
2212
        jmp     .start
2183
 
2213
 
2184
.small:     ; less than 32 clusters
2214
.small:     ; less than 32 clusters
2185
        mov     ecx, [ebp+NTFS.BitmapSize]
2215
        mov     ecx, [ebp+NTFS.BitmapSize]
2186
        sub     ecx, [ebp+NTFS.BitmapStart]
2216
        sub     ecx, [ebp+NTFS.BitmapStart]
2187
        shr     ecx, 2
2217
        shr     ecx, 2
2188
.smStart:
2218
.smStart:
2189
        mov     eax, -1
2219
        mov     eax, -1
2190
        repz scasd          ; search for zero bits
2220
        repz scasd          ; search for zero bits
2191
        push    ecx
2221
        push    ecx
2192
        test    ecx, ecx
2222
        test    ecx, ecx
2193
        jnz     @f
2223
        jnz     @f
2194
        call    bitmapBuffering
2224
        call    bitmapBuffering
2195
        pop     eax
2225
        pop     eax
2196
        jmp     .smStart
2226
        jmp     .smStart
2197
@@:
2227
@@:
2198
        sub     edi, 4
2228
        sub     edi, 4
2199
        mov     eax, [edi]
2229
        mov     eax, [edi]
2200
        not     eax
2230
        not     eax
2201
@@:
2231
@@:
2202
        bsf     ecx, eax    ; first 0
2232
        bsf     ecx, eax    ; first 0
2203
        jz      .again
2233
        jz      .again
2204
        not     eax
2234
        not     eax
2205
        shr     eax, cl
2235
        shr     eax, cl
2206
        shl     eax, cl
2236
        shl     eax, cl
2207
        bsf     edx, eax    ; next 1
2237
        bsf     edx, eax    ; next 1
2208
        jz      @f
2238
        jz      @f
2209
        sub     edx, ecx
2239
        sub     edx, ecx
2210
        cmp     edx, [ebp+NTFS.fileDataSize]
2240
        cmp     edx, [ebp+NTFS.fileDataSize]
2211
        jnc     .got        ; fits inside
2241
        jnc     .got        ; fits inside
2212
        bsf     ecx, eax
2242
        bsf     ecx, eax
2213
        not     eax
2243
        not     eax
2214
        shr     eax, cl
2244
        shr     eax, cl
2215
        shl     eax, cl
2245
        shl     eax, cl
2216
        jmp     @b
2246
        jmp     @b
2217
@@:         ; next dword
2247
@@:         ; next dword
2218
        mov     eax, [edi+4]
2248
        mov     eax, [edi+4]
2219
        bsf     edx, eax
2249
        bsf     edx, eax
2220
        jz      .got        ; empty
2250
        jz      .got        ; empty
2221
        add     edx, 32
2251
        add     edx, 32
2222
        sub     edx, ecx
2252
        sub     edx, ecx
2223
        cmp     edx, [ebp+NTFS.fileDataSize]
2253
        cmp     edx, [ebp+NTFS.fileDataSize]
2224
        jnc     .got        ; share between dwords
2254
        jnc     .got        ; share between dwords
2225
.again:
2255
.again:
2226
        add     edi, 4
2256
        add     edi, 4
2227
        pop     ecx
2257
        pop     ecx
2228
        jmp     .smStart
2258
        jmp     .smStart
2229
 
2259
 
2230
.got:
2260
.got:
2231
        push    ecx         ; starting bit
2261
        push    ecx         ; starting bit
2232
        push    edi         ; starting dword
2262
        push    edi         ; starting dword
2233
.done:      ; mark space
2263
.done:      ; mark space
2234
        mov     ecx, [esp+4]
2264
        mov     ecx, [esp+4]
2235
        cmp     ecx, 32
2265
        cmp     ecx, 32
2236
        jc      @f
2266
        jc      @f
2237
        xor     ecx, ecx
2267
        xor     ecx, ecx
2238
        add     dword [esp], 4
2268
        add     dword [esp], 4
2239
        mov     [esp+4], ecx
2269
        mov     [esp+4], ecx
2240
@@:
2270
@@:
2241
        mov     edi, [esp]
2271
        mov     edi, [esp]
2242
        mov     esi, [ebp+NTFS.fileDataSize]
2272
        xor     eax, eax
-
 
2273
        dec     eax
2243
        mov     edx, [edi]
2274
        shr     eax, cl
2244
        ror     edx, cl
2275
        shl     eax, cl
2245
        neg     ecx
2276
        neg     ecx
2246
        add     ecx, 32
2277
        add     ecx, 32
2247
        mov     eax, -1
-
 
2248
        sub     esi, ecx
2278
        sub     ecx, [ebp+NTFS.fileDataSize]
2249
        jnc     @f
2279
        jc      @f
2250
        mov     esi, ecx    ; fits inside
2280
        shl     eax, cl     ; fits inside dword
2251
        mov     ecx, [ebp+NTFS.fileDataSize]
-
 
2252
        shrd    edx, eax, cl
-
 
2253
        sub     esi, ecx
-
 
2254
        mov     ecx, esi
-
 
2255
        ror     edx, cl
2281
        shr     eax, cl
2256
        mov     [edi], edx
2282
        or      [edi], eax
2257
        jmp     .writeData
2283
        jmp     .writeData
2258
 
2284
 
2259
@@:
2285
@@:
2260
        shrd    edx, eax, cl
2286
        or      [edi], eax
2261
        mov     [edi], edx
2287
        neg     ecx
2262
        mov     ecx, esi
2288
        push    ecx
2263
        shr     ecx, 5
2289
        shr     ecx, 5
2264
        add     edi, 4
2290
        add     edi, 4
-
 
2291
        xor     eax, eax
-
 
2292
        dec     eax
2265
        rep stosd
2293
        rep stosd
2266
        mov     ecx, esi
2294
        pop     ecx
2267
        and     ecx, 31
2295
        and     ecx, 31
2268
        mov     edx, [edi]
2296
        shr     eax, cl
2269
        shr     edx, cl
2297
        shl     eax, cl
2270
        shld    edx, eax, cl
2298
        not     eax
2271
        mov     [edi], edx
2299
        or      [edi], eax
2272
.writeData:
2300
.writeData:
2273
        pop     edx
2301
        pop     edx
2274
        sub     edx, [ebp+NTFS.BitmapBuffer]
2302
        sub     edx, [ebp+NTFS.BitmapBuffer]
2275
        shl     edx, 3
2303
        shl     edx, 3
2276
        pop     eax
2304
        pop     eax
2277
        add     eax, edx
2305
        add     eax, edx
2278
        pop     edx
2306
        pop     edx
2279
        mov     [ebp+NTFS.fileDataStart], eax
2307
        mov     [ebp+NTFS.fileDataStart], eax
2280
        mul     [ebp+NTFS.sectors_per_cluster]
2308
        mul     [ebp+NTFS.sectors_per_cluster]
2281
        mov     ecx, [ebp+NTFS.fileRealSize]
2309
        mov     ecx, [ebp+NTFS.fileRealSize]
2282
        add     ecx, 511
2310
        add     ecx, 511
2283
        shr     ecx, 9
2311
        shr     ecx, 9
2284
        mov     ebx, [ebx+16]
2312
        mov     ebx, [ebx+16]
2285
        call    fs_write64_app
2313
        call    fs_write64_app
2286
        test    eax, eax
2314
        test    eax, eax
2287
        jz      .mftBitmap
-
 
2288
        push    11
-
 
2289
        jmp     ntfsError
2315
        jnz     ntfsDevice
2290
 
-
 
2291
    ; 4. MFT record
2316
    ; 4. MFT record
2292
.mftBitmap: ; search for free record
2317
.mftBitmap: ; search for free record
2293
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
2318
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
2294
        mov     ecx, [ebp+NTFS.mftBitmapSize]
2319
        mov     ecx, [ebp+NTFS.mftBitmapSize]
2295
        mov     al, -1
2320
        mov     al, -1
2296
        add     edi, 3
2321
        add     edi, 3
2297
        sub     ecx, 3
2322
        sub     ecx, 3
2298
        repz scasb
2323
        repz scasb
2299
        dec     edi
2324
        dec     edi
2300
        movzx   eax, byte [edi]
2325
        movzx   eax, byte [edi]
2301
        not     al
2326
        not     al
2302
        bsf     ecx, eax
2327
        bsf     ecx, eax
2303
        jnz     @f
-
 
2304
        push    ERROR_UNSUPPORTED_FS    ; no free records
2328
        jz      ntfsUnsupported     ; no free records
2305
        jmp     ntfsError
-
 
2306
@@:         ; mark record
-
 
2307
        mov     al, [edi]
-
 
2308
        bts     eax, ecx
2329
        bts     [edi], ecx
2309
        mov     [edi], al
-
 
2310
    ; get record location
2330
; get record location
2311
        sub     edi, [ebp+NTFS.mftBitmapBuffer]
2331
        sub     edi, [ebp+NTFS.mftBitmapBuffer]
2312
        shl     edi, 3
2332
        shl     edi, 3
2313
        add     edi, ecx
2333
        add     edi, ecx
2314
        mov     [ebp+NTFS.newMftRecord], edi
2334
        mov     [ebp+NTFS.newMftRecord], edi
2315
        mov     eax, [ebp+NTFS.frs_size]
2335
        mov     eax, [ebp+NTFS.frs_size]
2316
        shr     eax, 9
2336
        shr     eax, 9
2317
        mul     edi
2337
        mul     edi
2318
        mov     [ebp+NTFS.ntfs_cur_iRecord], 0
2338
        mov     [ebp+NTFS.ntfs_cur_iRecord], 0
2319
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
2339
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
2320
        mov     [ebp+NTFS.ntfs_cur_offs], eax
2340
        mov     [ebp+NTFS.ntfs_cur_offs], eax
2321
        mov     [ebp+NTFS.ntfs_cur_size], 1
2341
        mov     [ebp+NTFS.ntfs_cur_size], 1
2322
        mov     eax, [ebp+NTFS.frs_buffer]
2342
        mov     eax, [ebp+NTFS.frs_buffer]
2323
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2343
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2324
        call    ntfs_read_attr
2344
        call    ntfs_read_attr
2325
        cmp     [ebp+NTFS.ntfs_cur_read], 0
2345
        cmp     [ebp+NTFS.ntfs_cur_read], 0
2326
        jnz     .mftRecord
2346
        jnz     .mftRecord
2327
    ; extend MFT $DATA
2347
; extend MFT $DATA
2328
        mov     eax, [ebp+NTFS.mft_cluster]
2348
        mov     eax, [ebp+NTFS.mft_cluster]
2329
        mul     [ebp+NTFS.sectors_per_cluster]
2349
        mul     [ebp+NTFS.sectors_per_cluster]
2330
        push    ERROR_UNSUPPORTED_FS
-
 
2331
        cmp     eax, [ebp+NTFS.ntfsLastRead]
2350
        cmp     eax, [ebp+NTFS.ntfsLastRead]
2332
        jnz     ntfsError       ; auxiliary record
2351
        jnz     ntfsUnsupported     ; auxiliary record
2333
        mov     edi, [ebp+NTFS.ntfs_attr_offs]
2352
        mov     edi, [ebp+NTFS.ntfs_attr_offs]
2334
        mov     ebx, [ebp+NTFS.sectors_per_cluster]
2353
        mov     ebx, [ebp+NTFS.sectors_per_cluster]
2335
        shl     ebx, 9+3
2354
        shl     ebx, 9+3
2336
        add     dword [edi+lastVCN], 8
2355
        add     dword [edi+lastVCN], 8
2337
        add     [edi+attributeAllocatedSize], ebx
2356
        add     [edi+attributeAllocatedSize], ebx
-
 
2357
        adc     byte [edi+attributeAllocatedSize+4], 0
2338
        add     [edi+attributeRealSize], ebx
2358
        add     [edi+attributeRealSize], ebx
-
 
2359
        adc     byte [edi+attributeRealSize+4], 0
2339
        add     [edi+initialDataSize], ebx
2360
        add     [edi+initialDataSize], ebx
-
 
2361
        adc     byte [edi+initialDataSize+4], 0
2340
        add     edi, [edi+dataRunsOffset]
2362
        movzx   eax, byte [edi+dataRunsOffset]
-
 
2363
        add     edi, eax
2341
        movzx   eax, byte [edi]
2364
        mov     al, [edi]
2342
        inc     edi
2365
        inc     edi
2343
        shl     eax, 4
2366
        shl     eax, 4
2344
        shr     al, 4
2367
        shr     al, 4
2345
        mov     cl, 4
2368
        mov     cl, 4
2346
        sub     cl, al
2369
        sub     cl, al
2347
        shl     cl, 3
2370
        shl     cl, 3
2348
        add     ah, al
2371
        add     ah, al
2349
        shr     eax, 8
2372
        shr     eax, 8
2350
        cmp     byte [edi+eax], 0
2373
        cmp     byte [edi+eax], 0
2351
        jnz     ntfsError       ; $MFT fragmented
2374
        jnz     ntfsUnsupported     ; $MFT fragmented
2352
        mov     al, 8
2375
        mov     al, 8
2353
        mov     edx, [edi]
2376
        mov     edx, [edi]
2354
        rol     eax, cl
2377
        rol     eax, cl
2355
        rol     edx, cl
2378
        rol     edx, cl
2356
        add     eax, edx
2379
        add     eax, edx
2357
        jc      ntfsError
2380
        jc      ntfsUnsupported
2358
        ror     eax, cl
2381
        ror     eax, cl
2359
        shr     edx, cl
2382
        shr     edx, cl
2360
        mov     [edi], eax
2383
        mov     [edi], eax
2361
        add     edx, [ebp+NTFS.mft_cluster]
2384
        add     edx, [ebp+NTFS.mft_cluster]
2362
        mov     esi, edx
2385
        mov     esi, edx
2363
        mov     ecx, edx
2386
        mov     ecx, edx
2364
        and     ecx, 7
2387
        and     ecx, 7
2365
        shr     edx, 3
2388
        shr     edx, 3
2366
        add     edx, [ebp+NTFS.BitmapBuffer]
2389
        add     edx, [ebp+NTFS.BitmapBuffer]
2367
        movzx   eax, word [edx]
2390
        mov     ax, [edx]
2368
        shr     eax, cl
2391
        shr     ax, cl
-
 
2392
        test    al, al
2369
        jnz     ntfsError
2393
        jnz     ntfsUnsupported
2370
        mov     al, -1
2394
        dec     al
2371
        xchg    [edx], al
2395
        xchg    [edx], al
2372
        mov     [edx+1], al
2396
        mov     [edx+1], al
2373
        pop     eax
-
 
2374
        push    12
-
 
2375
        stdcall kernel_alloc, ebx
2397
        stdcall kernel_alloc, ebx
2376
        test    eax, eax
2398
        test    eax, eax
2377
        jz      ntfsError
2399
        jz      ntfsNoMemory
2378
        mov     ecx, ebx
2400
        mov     ecx, ebx
2379
        shr     ecx, 2
2401
        shr     ecx, 2
2380
        mov     edi, eax
2402
        mov     edi, eax
2381
        push    ebx
2403
        push    ebx
2382
        mov     ebx, eax
2404
        mov     ebx, eax
2383
        xor     eax, eax
2405
        xor     eax, eax
2384
        rep stosd
2406
        rep stosd
2385
        mov     eax, esi
2407
        mov     eax, esi
2386
        mul     [ebp+NTFS.sectors_per_cluster]
2408
        mul     [ebp+NTFS.sectors_per_cluster]
2387
        pop     ecx
2409
        pop     ecx
2388
        shr     ecx, 9
2410
        shr     ecx, 9
2389
        call    fs_write64_sys  ; clear new records
2411
        call    fs_write64_sys  ; clear new records
2390
        stdcall kernel_free, ebx
2412
        stdcall kernel_free, ebx
2391
        pop     eax
-
 
2392
        push    11
-
 
2393
        mov     eax, esi
2413
        mov     eax, esi
2394
        shr     eax, 3+9
2414
        shr     eax, 3+9
2395
        mov     ebx, eax
2415
        mov     ebx, eax
2396
        shl     ebx, 9
2416
        shl     ebx, 9
2397
        add     ebx, [ebp+NTFS.BitmapBuffer]
2417
        add     ebx, [ebp+NTFS.BitmapBuffer]
2398
        add     eax, [ebp+NTFS.BitmapLocation]
2418
        add     eax, [ebp+NTFS.BitmapLocation]
2399
        mov     ecx, 1
2419
        mov     ecx, 1
2400
        xor     edx, edx
2420
        xor     edx, edx
2401
        call    fs_write64_app  ; partition bitmap
2421
        call    fs_write64_app  ; partition bitmap
2402
        test    eax, eax
2422
        test    eax, eax
2403
        jnz     ntfsError
2423
        jnz     ntfsDevice
2404
        mov     eax, [ebp+NTFS.frs_buffer]
2424
        mov     eax, [ebp+NTFS.frs_buffer]
2405
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2425
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2406
        call    writeRecord     ; $MFT
2426
        call    writeRecord     ; $MFT
2407
        test    eax, eax
2427
        test    eax, eax
2408
        jnz     ntfsError
2428
        jnz     ntfsDevice
2409
        mov     eax, [ebp+NTFS.mftmirr_cluster]
2429
        mov     eax, [ebp+NTFS.mftmirr_cluster]
2410
        mul     [ebp+NTFS.sectors_per_cluster]
2430
        mul     [ebp+NTFS.sectors_per_cluster]
2411
        mov     ebx, [ebp+NTFS.frs_buffer]
2431
        mov     ebx, [ebp+NTFS.frs_buffer]
2412
        movzx   ecx, word [ebx+updateSequenceSize]
2432
        movzx   ecx, word [ebx+updateSequenceSize]
2413
        dec     ecx
2433
        dec     ecx
2414
        call    fs_write64_sys  ; $MFTMirr
2434
        call    fs_write64_sys  ; $MFTMirr
2415
        test    eax, eax
2435
        test    eax, eax
2416
        jnz     ntfsError
2436
        jnz     ntfsDevice
2417
        pop     eax
-
 
2418
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
2437
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
2419
        add     [ebp+NTFS.ntfsLastRead], eax
2438
        add     [ebp+NTFS.ntfsLastRead], eax
2420
.mftRecord:
2439
.mftRecord:
2421
        mov     esi, [ebp+NTFS.indexOffset]
2440
        mov     esi, [ebp+NTFS.indexOffset]
2422
        mov     edi, [ebp+NTFS.frs_buffer]
2441
        mov     edi, [ebp+NTFS.frs_buffer]
2423
        xor     eax, eax
2442
        xor     eax, eax
2424
        movzx   ecx, word [esi+indexAllocatedSize]
2443
        movzx   ecx, word [esi+indexAllocatedSize]
2425
        add     ecx, 8+30h+48h+50h+8
2444
        add     ecx, 8+30h+48h+50h+8
2426
        push    ecx
2445
        push    ecx
2427
        shr     ecx, 2
2446
        shr     ecx, 2
2428
        rep stosd
2447
        rep stosd
2429
        mov     edi, [ebp+NTFS.frs_buffer]
2448
        mov     edi, [ebp+NTFS.frs_buffer]
2430
    ; record header
2449
; record header
2431
        mov     dword[edi], 'FILE'
2450
        mov     dword[edi], 'FILE'
2432
        mov     byte [edi+updateSequenceOffset], 2ah
2451
        mov     byte [edi+updateSequenceOffset], 2ah
2433
        mov     byte [edi+updateSequenceSize], 3
2452
        mov     byte [edi+updateSequenceSize], 3
2434
        mov     byte [edi+hardLinkCounter], 1
2453
        mov     byte [edi+hardLinkCounter], 1
2435
        mov     byte [edi+attributeOffset], 30h
2454
        mov     byte [edi+attributeOffset], 30h
2436
        pop     dword[edi+recordRealSize]
2455
        pop     dword[edi+recordRealSize]
2437
        mov     word [edi+recordAllocatedSize], 1024
2456
        mov     word [edi+recordAllocatedSize], 1024
2438
        mov     byte [edi+newAttributeID], 3
2457
        mov     byte [edi+newAttributeID], 3
2439
        rdtsc
2458
        rdtsc
2440
        mov     [edi+2ah], ax
2459
        mov     [edi+2ah], ax
2441
        add     edi, 30h
2460
        add     edi, 30h
2442
    ; $StandardInformation
2461
; $StandardInformation
2443
        mov     byte [edi+attributeType], 10h
2462
        mov     byte [edi+attributeType], 10h
2444
        mov     byte [edi+sizeWithHeader], 48h
2463
        mov     byte [edi+sizeWithHeader], 48h
2445
        mov     byte [edi+sizeWithoutHeader], 30h
2464
        mov     byte [edi+sizeWithoutHeader], 30h
2446
        mov     byte [edi+attributeOffset], 18h
2465
        mov     byte [edi+attributeOffset], 18h
2447
        add     edi, 48h
2466
        add     edi, 48h
2448
    ; $FileName
2467
; $FileName
2449
        mov     byte [edi+attributeType], 30h
2468
        mov     byte [edi+attributeType], 30h
2450
        mov     byte [edi+attributeID], 1
2469
        mov     byte [edi+attributeID], 1
2451
        mov     cx, [esi+indexRawSize]
2470
        mov     cx, [esi+indexRawSize]
2452
        mov     [edi+sizeWithoutHeader], ecx
2471
        mov     [edi+sizeWithoutHeader], ecx
2453
        mov     cx, [esi+indexAllocatedSize]
2472
        mov     cx, [esi+indexAllocatedSize]
2454
        add     ecx, 8
2473
        add     ecx, 8
2455
        mov     [edi+sizeWithHeader], ecx
2474
        mov     [edi+sizeWithHeader], ecx
2456
        mov     byte [edi+attributeOffset], 18h
2475
        mov     byte [edi+attributeOffset], 18h
2457
        mov     byte [edi+attributeFlags], 1
2476
        mov     byte [edi+indexedFlag], 1
2458
        add     edi, 18h
2477
        add     edi, 18h
2459
        add     esi, 16
2478
        add     esi, 16
2460
        sub     ecx, 18h
2479
        sub     ecx, 18h
2461
        shr     ecx, 2
2480
        shr     ecx, 2
2462
        rep movsd
2481
        rep movsd
2463
        cmp     [ebp+NTFS.ntfsFolder], 0
2482
        cmp     [ebp+NTFS.ntfsFolder], 0
2464
        jnz     @f
2483
        jnz     @f
2465
    ; $Data
2484
; $Data
2466
        mov     byte [edi+attributeType], 80h
2485
        mov     byte [edi+attributeType], 80h
2467
        cmp     [ebp+NTFS.fileRealSize], 0
2486
        cmp     [ebp+NTFS.fileRealSize], 0
2468
        jz      .zeroSize
2487
        jz      .zeroSize
2469
        mov     esi, [ebp+NTFS.indexOffset]
2488
        mov     esi, [ebp+NTFS.indexOffset]
2470
        mov     byte [edi+nonResidentFlag], 1
2489
        mov     byte [edi+nonResidentFlag], 1
2471
        mov     byte [edi+dataRunsOffset], 40h
2490
        mov     byte [edi+dataRunsOffset], 40h
2472
        mov     eax, [esi+fileAllocatedSize]
2491
        mov     eax, [esi+fileAllocatedSize]
2473
        mov     [edi+attributeAllocatedSize], eax
2492
        mov     [edi+attributeAllocatedSize], eax
2474
        mov     eax, [esi+fileRealSize]
2493
        mov     eax, [esi+fileRealSize]
2475
        mov     [edi+attributeRealSize], eax
2494
        mov     [edi+attributeRealSize], eax
2476
        mov     [edi+initialDataSize], eax
2495
        mov     [edi+initialDataSize], eax
2477
        mov     byte [edi+40h], 44h
2496
        mov     byte [edi+40h], 44h
2478
        mov     eax, [ebp+NTFS.fileDataSize]
2497
        mov     eax, [ebp+NTFS.fileDataSize]
2479
        mov     [edi+41h], eax
2498
        mov     [edi+41h], eax
2480
        dec     eax
2499
        dec     eax
2481
        mov     [edi+lastVCN], eax
2500
        mov     [edi+lastVCN], eax
2482
        mov     eax, [ebp+NTFS.fileDataStart]
2501
        mov     eax, [ebp+NTFS.fileDataStart]
2483
        mov     [edi+45h], eax
2502
        mov     [edi+45h], eax
2484
        mov     al, 1
2503
        mov     al, 1
2485
        jmp     .writeMftRecord
2504
        jmp     .writeMftRecord
2486
 
2505
 
2487
.zeroSize:
2506
.zeroSize:
2488
        mov     byte [edi+attributeOffset], 18h
2507
        mov     byte [edi+attributeOffset], 18h
2489
        mov     al, 1
2508
        mov     al, 1
2490
        jmp     .writeMftRecord
2509
        jmp     .writeMftRecord
2491
 
2510
 
2492
@@: ; $IndexRoot
2511
@@: ; $IndexRoot
2493
        mov     byte [edi+attributeType], 90h
2512
        mov     byte [edi+attributeType], 90h
2494
        mov     byte [edi+nameLength], 4
2513
        mov     byte [edi+nameLength], 4
2495
        mov     byte [edi+nameOffset], 18h
2514
        mov     byte [edi+nameOffset], 18h
2496
        mov     byte [edi+sizeWithoutHeader], 30h
2515
        mov     byte [edi+sizeWithoutHeader], 30h
2497
        mov     byte [edi+attributeOffset], 20h
2516
        mov     byte [edi+attributeOffset], 20h
2498
        mov     dword[edi+18h], 490024h     ; unicode $I30
2517
        mov     dword[edi+18h], 490024h     ; unicode $I30
2499
        mov     dword[edi+18h+4], 300033h
2518
        mov     dword[edi+18h+4], 300033h
2500
        add     edi, 20h
-
 
2501
        mov     byte [edi+attributeType], 30h
2519
        mov     byte [edi+20h+attributeType], 30h
2502
        mov     byte [edi+collationRule], 1
2520
        mov     byte [edi+20h+collationRule], 1
2503
        mov     eax, [ebp+NTFS.sectors_per_cluster]
2521
        mov     eax, [ebp+NTFS.sectors_per_cluster]
2504
        shl     eax, 9
2522
        shl     eax, 9
2505
        mov     [edi+indexRecordSize], eax
2523
        mov     [edi+20h+indexRecordSize], eax
2506
        mov     byte [edi+indexRecordSizeClus], 1
2524
        mov     byte [edi+20h+indexRecordSizeClus], 1
2507
        mov     byte [edi+16+indexOffset], 16
2525
        mov     byte [edi+30h+indexOffset], 16
2508
        mov     byte [edi+16+nodeRealSize], 32
2526
        mov     byte [edi+30h+nodeRealSize], 32
2509
        mov     byte [edi+16+nodeAllocatedSize], 32
2527
        mov     byte [edi+30h+nodeAllocatedSize], 32
2510
        mov     byte [edi+32+indexAllocatedSize], 16
2528
        mov     byte [edi+40h+indexAllocatedSize], 16
2511
        mov     byte [edi+32+indexFlags], 2
2529
        mov     byte [edi+40h+indexFlags], 2
2512
        sub     edi, 20h
-
 
2513
        mov     al, 3
2530
        mov     al, 3
2514
.writeMftRecord:
2531
.writeMftRecord:
2515
        mov     byte [edi+sizeWithHeader], 50h
2532
        mov     byte [edi+sizeWithHeader], 50h
2516
        mov     byte [edi+attributeID], 2
2533
        mov     byte [edi+attributeID], 2
2517
        mov     dword[edi+50h], -1      ; $End
2534
        mov     dword[edi+50h], -1      ; $End
2518
        mov     edi, [ebp+NTFS.frs_buffer]
2535
        mov     edi, [ebp+NTFS.frs_buffer]
2519
        mov     [edi+recordFlags], al
2536
        mov     [edi+recordFlags], al
2520
        mov     [ebp+NTFS.ntfs_cur_buf], edi
2537
        mov     [ebp+NTFS.ntfs_cur_buf], edi
2521
        call    writeRecord
2538
        call    writeRecord
2522
        test    eax, eax
2539
        test    eax, eax
2523
        jz      @f
-
 
2524
        push    11
-
 
2525
        jmp     ntfsError
2540
        jnz     ntfsDevice
2526
@@:
-
 
2527
        mov     esi, [ebp+PARTITION.Disk]
2541
        mov     esi, [ebp+PARTITION.Disk]
2528
        call    disk_sync
2542
        call    disk_sync
2529
    ; write MFT bitmap
2543
; write MFT bitmap
2530
        mov     eax, [ebp+NTFS.newMftRecord]
2544
        mov     eax, [ebp+NTFS.newMftRecord]
2531
        shr     eax, 3+9
2545
        shr     eax, 3+9
2532
        mov     ebx, eax
2546
        mov     ebx, eax
2533
        shl     ebx, 9
2547
        shl     ebx, 9
2534
        add     eax, [ebp+NTFS.mftBitmapLocation]
2548
        add     eax, [ebp+NTFS.mftBitmapLocation]
2535
        add     ebx, [ebp+NTFS.mftBitmapBuffer]
2549
        add     ebx, [ebp+NTFS.mftBitmapBuffer]
2536
        mov     ecx, 1
2550
        mov     ecx, 1
2537
        xor     edx, edx
2551
        xor     edx, edx
2538
        call    fs_write64_sys
2552
        call    fs_write64_sys
2539
        test    eax, eax
2553
        test    eax, eax
2540
        jz      @f
-
 
2541
        push    11
-
 
2542
        jmp     ntfsError
2554
        jnz     ntfsDevice
2543
@@: ; 5. Write partition bitmap
2555
; 5. Write partition bitmap
2544
        cmp     [ebp+NTFS.ntfsFolder], 0
2556
        cmp     [ebp+NTFS.ntfsFolder], 0
2545
        jnz     @f
2557
        jnz     @f
2546
        cmp     [ebp+NTFS.fileRealSize], 0
2558
        cmp     [ebp+NTFS.fileRealSize], 0
2547
        jz      @f
2559
        jz      @f
2548
        mov     ecx, [ebp+NTFS.fileDataStart]
2560
        mov     ecx, [ebp+NTFS.fileDataStart]
2549
        mov     eax, ecx
2561
        mov     eax, ecx
2550
        add     ecx, [ebp+NTFS.fileDataSize]
2562
        add     ecx, [ebp+NTFS.fileDataSize]
2551
        add     ecx, 4095
2563
        add     ecx, 4095
2552
        shr     ecx, 3+9
2564
        shr     ecx, 3+9
2553
        shr     eax, 3+9
2565
        shr     eax, 3+9
2554
        sub     ecx, eax
2566
        sub     ecx, eax
2555
        mov     ebx, eax
2567
        mov     ebx, eax
2556
        shl     ebx, 9
2568
        shl     ebx, 9
2557
        add     eax, [ebp+NTFS.BitmapLocation]
2569
        add     eax, [ebp+NTFS.BitmapLocation]
2558
        add     ebx, [ebp+NTFS.BitmapBuffer]
2570
        add     ebx, [ebp+NTFS.BitmapBuffer]
2559
        xor     edx, edx
2571
        xor     edx, edx
2560
        call    fs_write64_app
2572
        call    fs_write64_app
2561
        test    eax, eax
2573
        test    eax, eax
2562
        jz      @f
-
 
2563
        push    11
-
 
2564
        jmp     ntfsError
2574
        jnz     ntfsDevice
2565
@@:
2575
@@:
2566
        mov     esi, [ebp+PARTITION.Disk]
2576
        mov     esi, [ebp+PARTITION.Disk]
2567
        call    disk_sync
2577
        call    disk_sync
2568
        mov     edi, [ebp+NTFS.indexOffset]
2578
        mov     edi, [ebp+NTFS.indexOffset]
2569
        mov     eax, [ebp+NTFS.newMftRecord]
2579
        mov     eax, [ebp+NTFS.newMftRecord]
2570
        mov     [edi+fileRecordReference], eax
2580
        mov     [edi+fileRecordReference], eax
2571
    ; 6. Write directory node
2581
; 6. Write directory node
2572
        mov     eax, [ebp+NTFS.nodeLastRead]
2582
        mov     eax, [ebp+NTFS.nodeLastRead]
2573
        mov     [ebp+NTFS.ntfsLastRead], eax
2583
        mov     [ebp+NTFS.ntfsLastRead], eax
2574
        mov     eax, [ebp+NTFS.cur_index_buf]
2584
        mov     eax, [ebp+NTFS.cur_index_buf]
2575
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2585
        mov     [ebp+NTFS.ntfs_cur_buf], eax
2576
        call    writeRecord
2586
        call    writeRecord
2577
        push    eax
2587
        test    eax, eax
-
 
2588
        jnz     ntfsDevice
-
 
2589
        mov     ebx, [ebp+NTFS.fileRealSize]
-
 
2590
ntfsDone:
2578
        mov     esi, [ebp+PARTITION.Disk]
2591
        mov     esi, [ebp+PARTITION.Disk]
2579
        call    disk_sync
2592
        call    disk_sync
2580
        call    ntfs_unlock
2593
        call    ntfs_unlock
2581
        pop     eax
2594
        xor     eax, eax
2582
        mov     ebx, [ebp+NTFS.fileRealSize]
-
 
2583
        ret
2595
        ret
2584
 
2596
 
2585
writeRecord:
2597
writeRecord:
2586
;   in:
2598
;   in:
2587
; [ebp+NTFS.ntfs_cur_buf] = record
2599
; [ebp+NTFS.ntfs_cur_buf] = record
2588
; [ebp+NTFS.ntfsLastRead] = partition sector
2600
; [ebp+NTFS.ntfsLastRead] = partition sector
2589
    ; making updateSequence
2601
    ; making updateSequence
2590
        mov     esi, [ebp+NTFS.ntfs_cur_buf]
2602
        mov     esi, [ebp+NTFS.ntfs_cur_buf]
2591
        mov     edi, esi
2603
        mov     edi, esi
2592
        movzx   ecx, word [esi+updateSequenceOffset]
2604
        movzx   ecx, word [esi+updateSequenceOffset]
2593
        add     edi, ecx
2605
        add     edi, ecx
2594
        mov     ax, [edi]
2606
        mov     ax, [edi]
2595
        add     edi, 2
2607
        add     edi, 2
2596
        mov     cx, [esi+updateSequenceSize]
2608
        mov     cx, [esi+updateSequenceSize]
2597
        dec     ecx
2609
        dec     ecx
2598
        push    ecx
2610
        push    ecx
2599
@@:
2611
@@:
2600
        add     esi, 510
2612
        add     esi, 510
2601
        movsw
2613
        movsw
2602
        mov     [esi-2], ax
2614
        mov     [esi-2], ax
2603
        dec     ecx
2615
        dec     ecx
2604
        jnz     @b
2616
        jnz     @b
2605
    ; writing to disk
2617
; writing to disk
2606
        mov     eax, [ebp+NTFS.ntfsLastRead]
2618
        mov     eax, [ebp+NTFS.ntfsLastRead]
2607
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
2619
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
2608
        pop     ecx
2620
        pop     ecx
2609
        xor     edx, edx
2621
        xor     edx, edx
2610
        jmp     fs_write64_sys
2622
        jmp     fs_write64_sys
2611
 
2623
 
2612
bitmapBuffering:
2624
bitmapBuffering:
2613
; Extend BitmapBuffer and read next 32kb of bitmap
2625
; Extend BitmapBuffer and read next 32kb of bitmap
2614
; Warning: $Bitmap fragmentation is not foreseen
2626
; Warning: $Bitmap fragmentation is not foreseen
-
 
2627
; if edi -> position in bitmap buffer,
-
 
2628
; then ecx = number of buffered dwords left
2615
        push    ebx
2629
        push    ebx
2616
        mov     eax, [ebp+NTFS.BitmapTotalSize]
2630
        mov     eax, [ebp+NTFS.BitmapTotalSize]
2617
        cmp     eax, [ebp+NTFS.BitmapSize]
2631
        cmp     eax, [ebp+NTFS.BitmapSize]
2618
        jz      .end
2632
        jz      .end
2619
        stdcall alloc_pages, 8
2633
        stdcall alloc_pages, 8
2620
        test    eax, eax
2634
        test    eax, eax
2621
        jz      .end
2635
        jz      .end
2622
        add     eax, 3
2636
        add     eax, 3
2623
        mov     ebx, [ebp+NTFS.BitmapBuffer]
2637
        mov     ebx, [ebp+NTFS.BitmapBuffer]
2624
        add     ebx, [ebp+NTFS.BitmapSize]
2638
        add     ebx, [ebp+NTFS.BitmapSize]
2625
        push    ebx
2639
        push    ebx
2626
        mov     ecx, 8
2640
        mov     ecx, 8
2627
        call    commit_pages
2641
        call    commit_pages
2628
        mov     eax, [ebp+NTFS.BitmapSize]
2642
        mov     eax, [ebp+NTFS.BitmapSize]
2629
        shr     eax, 9
2643
        shr     eax, 9
2630
        add     eax, [ebp+NTFS.BitmapLocation]
2644
        add     eax, [ebp+NTFS.BitmapLocation]
2631
        pop     ebx
2645
        pop     ebx
2632
        mov     ecx, 64
2646
        mov     ecx, 64
2633
        xor     edx, edx
2647
        xor     edx, edx
2634
        call    fs_read64_app
2648
        call    fs_read64_app
2635
        test    eax, eax
2649
        test    eax, eax
2636
        jnz     .err
2650
        jnz     .err
2637
        add     [ebp+NTFS.BitmapSize], 8000h
2651
        add     [ebp+NTFS.BitmapSize], 8000h
2638
        mov     eax, [ebp+NTFS.BitmapTotalSize]
2652
        mov     eax, [ebp+NTFS.BitmapTotalSize]
2639
        cmp     eax, [ebp+NTFS.BitmapSize]
2653
        cmp     eax, [ebp+NTFS.BitmapSize]
2640
        jnc     @f
2654
        jnc     @f
2641
        mov     [ebp+NTFS.BitmapSize], eax
2655
        mov     [ebp+NTFS.BitmapSize], eax
2642
@@:
2656
@@:
2643
        mov     ecx, [ebp+NTFS.BitmapSize]
2657
        mov     ecx, [ebp+NTFS.BitmapSize]
2644
        mov     eax, edi
-
 
2645
        sub     eax, [ebp+NTFS.BitmapBuffer]
2658
        add     ecx, [ebp+NTFS.BitmapBuffer]
2646
        sub     ecx, eax
2659
        sub     ecx, edi
2647
        shr     ecx, 2
2660
        shr     ecx, 2
2648
        pop     ebx
2661
        pop     ebx
2649
        ret
2662
        ret
2650
 
2663
 
2651
.err:
2664
.err:
2652
        mov     eax, [ebp+NTFS.BitmapBuffer]
2665
        mov     eax, [ebp+NTFS.BitmapBuffer]
2653
        add     eax, [ebp+NTFS.BitmapSize]
2666
        add     eax, [ebp+NTFS.BitmapSize]
2654
        mov     ecx, 8
2667
        mov     ecx, 8
2655
        call    release_pages
2668
        call    release_pages
2656
.end:
2669
.end:
2657
        add     esp, 12     ; double ret
2670
        add     esp, 12     ; double ret
2658
        push    ERROR_DISK_FULL
2671
        push    ERROR_DISK_FULL
2659
        jmp     ntfsError
2672
        jmp     ntfsOut
2660
 
2673
 
2661
;----------------------------------------------------------------
2674
;----------------------------------------------------------------
-
 
2675
ntfs_WriteFile:
-
 
2676
        cmp     byte [esi], 0
2662
ntfs_Write:
2677
        jnz     @f
2663
        xor     ebx, ebx
2678
        xor     ebx, ebx
2664
        mov     eax, ERROR_UNSUPPORTED_FS
2679
        movi    eax, ERROR_ACCESS_DENIED
-
 
2680
        ret
-
 
2681
@@:
-
 
2682
        call    ntfs_lock
-
 
2683
        stdcall ntfs_find_lfn, [esp+4]
-
 
2684
        jc      ntfsNotFound
-
 
2685
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 16
-
 
2686
        jc      ntfsDenied
-
 
2687
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
-
 
2688
        mov     [ebp+NTFS.ntfs_cur_offs], 0
-
 
2689
        mov     [ebp+NTFS.ntfs_cur_size], 0
-
 
2690
        call    ntfs_read_attr
-
 
2691
        jc      ntfsDenied
-
 
2692
        mov     eax, [ebp+NTFS.frs_buffer]
-
 
2693
        cmp     word [eax+baseRecordReuse], 0
-
 
2694
        jnz     ntfsUnsupported     ; auxiliary record
-
 
2695
        cmp     byte [eax+hardLinkCounter], 1
-
 
2696
        jnz     ntfsUnsupported     ; file copying required
-
 
2697
        mov     ecx, [ebp+NTFS.ntfs_attr_offs]
-
 
2698
        cmp     byte [ecx+nonResidentFlag], 1
-
 
2699
        jnz     ntfsUnsupported     ; resident $DATA
-
 
2700
        cmp     word [ecx+attributeFlags], 0
-
 
2701
        jnz     ntfsUnsupported
-
 
2702
        mov     eax, [ebx+4]
-
 
2703
        mov     edx, [ebx+8]
-
 
2704
        add     eax, [ebx+12]
-
 
2705
        adc     edx, 0
-
 
2706
        cmp     edx, [ecx+attributeRealSize+4]
-
 
2707
        jc      .write
-
 
2708
        jnz     ntfsUnsupported     ; end of file
-
 
2709
        cmp     [ecx+attributeRealSize], eax
-
 
2710
        jc      ntfsUnsupported
-
 
2711
.write:
-
 
2712
        mov     eax, [ebx+4]
-
 
2713
        mov     edx, [ebx+8]
-
 
2714
        mov     ecx, [ebx+12]
-
 
2715
        mov     esi, [ebx+16]
-
 
2716
        shrd    eax, edx, 9
-
 
2717
        test    dword[ebx+4], 1FFh
-
 
2718
        jz      .aligned
-
 
2719
        mov     [ebp+NTFS.ntfs_cur_offs], eax
-
 
2720
        mov     [ebp+NTFS.ntfs_cur_size], 1
-
 
2721
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
-
 
2722
        mov     [ebp+NTFS.ntfs_cur_buf], edi
-
 
2723
        call    ntfs_read_attr.continue
-
 
2724
        jc      ntfsDevice
-
 
2725
        mov     eax, [ebx+4]
-
 
2726
        and     eax, 1FFh
-
 
2727
        add     edi, eax
-
 
2728
        sub     eax, [ebp+NTFS.ntfs_cur_read]
-
 
2729
        neg     eax
-
 
2730
        push    ecx
-
 
2731
        cmp     ecx, eax
-
 
2732
        jb      @f
-
 
2733
        mov     ecx, eax
-
 
2734
@@:
-
 
2735
        sub     [esp], ecx
-
 
2736
        rep movsb
-
 
2737
        push    ebx
-
 
2738
        mov     eax, [ebp+NTFS.ntfsLastRead]
-
 
2739
        lea     ebx, [ebp+NTFS.ntfs_bitmap_buf]
-
 
2740
        mov     ecx, 1
-
 
2741
        xor     edx, edx
-
 
2742
        call    fs_write64_app
-
 
2743
        pop     ebx
-
 
2744
        pop     ecx
-
 
2745
        test    eax, eax
-
 
2746
        jnz     ntfsDevice
-
 
2747
        test    ecx, ecx
-
 
2748
        jz      @f
-
 
2749
        mov     eax, [ebx+4]
-
 
2750
        mov     edx, [ebx+8]
-
 
2751
        shrd    eax, edx, 9
-
 
2752
        inc     eax
-
 
2753
.aligned:
-
 
2754
        push    ecx
-
 
2755
        shr     ecx, 9
-
 
2756
        mov     [ebp+NTFS.ntfs_cur_offs], eax
-
 
2757
        mov     [ebp+NTFS.ntfs_cur_size], ecx
-
 
2758
        mov     [ebp+NTFS.ntfs_cur_buf], esi
-
 
2759
        add     eax, ecx
-
 
2760
        push    eax
-
 
2761
        mov     [ebp+NTFS.ntfsWriteAttr], 1
-
 
2762
        call    ntfs_read_attr.continue
-
 
2763
        mov     [ebp+NTFS.ntfsWriteAttr], 0
-
 
2764
        pop     [ebp+NTFS.ntfs_cur_offs]
-
 
2765
        pop     ecx
-
 
2766
        jc      ntfsDevice
-
 
2767
        and     ecx, 1FFh
-
 
2768
        jz      @f
-
 
2769
        add     esi, [ebp+NTFS.ntfs_cur_read]
-
 
2770
        mov     [ebp+NTFS.ntfs_cur_size], 1
-
 
2771
        lea     edi, [ebp+NTFS.ntfs_bitmap_buf]
-
 
2772
        mov     [ebp+NTFS.ntfs_cur_buf], edi
-
 
2773
        call    ntfs_read_attr.continue
-
 
2774
        jc      ntfsDevice
-
 
2775
        rep movsb
-
 
2776
        push    ebx
-
 
2777
        mov     eax, [ebp+NTFS.ntfsLastRead]
-
 
2778
        lea     ebx, [ebp+NTFS.ntfs_bitmap_buf]
-
 
2779
        mov     ecx, 1
-
 
2780
        xor     edx, edx
-
 
2781
        call    fs_write64_app
-
 
2782
        pop     ebx
-
 
2783
        test    eax, eax
-
 
2784
        jnz     ntfsDevice
-
 
2785
@@:
-
 
2786
        mov     ebx, [ebx+12]
-
 
2787
        jmp     ntfsDone
-
 
2788
 
-
 
2789
;----------------------------------------------------------------
-
 
2790
ntfs_Delete:
-
 
2791
        cmp     byte [esi], 0
-
 
2792
        jnz     @f
-
 
2793
        xor     ebx, ebx
-
 
2794
        movi    eax, ERROR_ACCESS_DENIED
-
 
2795
        ret
-
 
2796
@@:
-
 
2797
        call    ntfs_lock
-
 
2798
        stdcall ntfs_find_lfn, [esp+4]
-
 
2799
        jc      ntfsNotFound
-
 
2800
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 16
-
 
2801
        jc      ntfsDenied
-
 
2802
        cmp     [ebp+NTFS.ntfsFragmentCount], 1
-
 
2803
        jnz     ntfsUnsupported     ; record fragmented
-
 
2804
        test    byte [eax+indexFlags], 1
-
 
2805
        jnz     ntfsUnsupported     ; index has a subnode
-
 
2806
        mov     edx, [ebp+NTFS.ntfs_cur_iRecord]
-
 
2807
        shr     edx, 3
-
 
2808
        cmp     edx, [ebp+NTFS.mftBitmapSize]
-
 
2809
        jnc     ntfsUnsupported
-
 
2810
; delete index from the node
-
 
2811
        movzx   edx, word [eax+indexAllocatedSize]
-
 
2812
        mov     edi, [ebp+NTFS.cur_index_buf]
-
 
2813
        cmp     dword [edi], 'INDX'
-
 
2814
        jz      .indexRecord
-
 
2815
        mov     esi, [ebp+NTFS.frs_buffer]  ; indexRoot
-
 
2816
        mov     ecx, [esi+recordRealSize]
-
 
2817
        shr     ecx, 2
-
 
2818
        rep movsd
-
 
2819
        mov     esi, [ebp+NTFS.cur_index_buf]
-
 
2820
        mov     edi, [ebp+NTFS.ntfs_attr_offs]
-
 
2821
        sub     edi, [ebp+NTFS.frs_buffer]
-
 
2822
        add     edi, esi
-
 
2823
        sub     [edi+sizeWithHeader], edx
-
 
2824
        sub     [edi+sizeWithoutHeader], edx
-
 
2825
        mov     cl, [edi+attributeOffset]
-
 
2826
        add     edi, ecx
-
 
2827
        sub     [edi+16+nodeRealSize], edx
-
 
2828
        sub     [edi+16+nodeAllocatedSize], edx
-
 
2829
        sub     eax, esi
-
 
2830
        add     eax, edi
-
 
2831
        sub     [esi+recordRealSize], edx
-
 
2832
        mov     ecx, [esi+recordRealSize]
-
 
2833
        jmp     @f
-
 
2834
 
-
 
2835
.indexRecord:
-
 
2836
        sub     [edi+28], edx
-
 
2837
        mov     ecx, [edi+28]
-
 
2838
        add     ecx, 24
-
 
2839
@@:
-
 
2840
        add     ecx, [ebp+NTFS.cur_index_buf]
-
 
2841
        sub     ecx, eax
-
 
2842
        shr     ecx, 2
-
 
2843
        mov     esi, eax
-
 
2844
        add     esi, edx
-
 
2845
        mov     edi, eax
-
 
2846
        rep movsd
-
 
2847
        mov     eax, [ebp+NTFS.ntfsLastRead]
-
 
2848
        mov     [ebp+NTFS.nodeLastRead], eax
-
 
2849
; examine file record
-
 
2850
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
-
 
2851
        mov     [ebp+NTFS.ntfs_cur_offs], 0
-
 
2852
        mov     [ebp+NTFS.ntfs_cur_size], 0
-
 
2853
        call    ntfs_read_attr
-
 
2854
        jc      .folder
-
 
2855
        mov     esi, [ebp+NTFS.frs_buffer]
-
 
2856
        cmp     word [esi+baseRecordReuse], 0
-
 
2857
        jnz     ntfsUnsupported     ; auxiliary record
-
 
2858
        cmp     byte [esi+hardLinkCounter], 2
-
 
2859
        jnc     .writeFileRecord    ; delete hard link
-
 
2860
        mov     esi, [ebp+NTFS.ntfs_attr_offs]
-
 
2861
        cmp     byte [esi+nonResidentFlag], 0
-
 
2862
        jz      .writeBitmapMFT
-
 
2863
        movzx   eax, byte [esi+dataRunsOffset]
-
 
2864
        add     esi, eax
-
 
2865
        xor     edi, edi
-
 
2866
        sub     esp, 16
-
 
2867
.clearBitmap:       ; "delete" file data
-
 
2868
        call    ntfs_decode_mcb_entry
-
 
2869
        jnc     .mcbEnd
-
 
2870
        cmp     dword[esp+8], 0
-
 
2871
        jz      .clearBitmap
-
 
2872
        add     edi, [esp+8]
-
 
2873
        mov     ebx, [esp]
-
 
2874
        mov     eax, edi
-
 
2875
        add     eax, ebx
-
 
2876
        shr     eax, 3
-
 
2877
        inc     eax
-
 
2878
        cmp     eax, [ebp+NTFS.BitmapSize]
-
 
2879
        jc      .buffered
-
 
2880
        add     eax, [ebp+NTFS.BitmapBuffer]
-
 
2881
        add     esp, 16
-
 
2882
        push    edi
-
 
2883
        mov     edi, eax
-
 
2884
@@:
-
 
2885
        call    bitmapBuffering
-
 
2886
        shl     ecx, 2
-
 
2887
        js      @b
-
 
2888
        pop     edi
-
 
2889
        sub     esp, 16
-
 
2890
.buffered:
-
 
2891
        push    edi
-
 
2892
        mov     ecx, edi
-
 
2893
        shr     edi, 5
-
 
2894
        shl     edi, 2
-
 
2895
        add     edi, [ebp+NTFS.BitmapBuffer]
-
 
2896
        and     ecx, 31
-
 
2897
        xor     eax, eax
-
 
2898
        dec     eax
-
 
2899
        shr     eax, cl
-
 
2900
        shl     eax, cl
-
 
2901
        neg     ecx
-
 
2902
        add     ecx, 32
-
 
2903
        sub     ecx, ebx
-
 
2904
        jc      @f
-
 
2905
        shl     eax, cl     ; fits inside dword
-
 
2906
        shr     eax, cl
-
 
2907
        not     eax
-
 
2908
        and     [edi], eax
-
 
2909
        jmp     .writeBitmap
-
 
2910
 
-
 
2911
@@:
-
 
2912
        not     eax
-
 
2913
        and     [edi], eax
-
 
2914
        neg     ecx
-
 
2915
        push    ecx
-
 
2916
        shr     ecx, 5
-
 
2917
        add     edi, 4
-
 
2918
        xor     eax, eax
-
 
2919
        rep stosd
-
 
2920
        pop     ecx
-
 
2921
        and     ecx, 31
-
 
2922
        dec     eax
-
 
2923
        shr     eax, cl
-
 
2924
        shl     eax, cl
-
 
2925
        and     [edi], eax
-
 
2926
.writeBitmap:
-
 
2927
        pop     edi
-
 
2928
        mov     ecx, edi
-
 
2929
        add     ecx, ebx
-
 
2930
        add     ecx, 4095
-
 
2931
        shr     ecx, 3+9
-
 
2932
        mov     eax, edi
-
 
2933
        shr     eax, 3+9
-
 
2934
        sub     ecx, eax
-
 
2935
        mov     ebx, eax
-
 
2936
        shl     ebx, 9
-
 
2937
        add     eax, [ebp+NTFS.BitmapLocation]
-
 
2938
        add     ebx, [ebp+NTFS.BitmapBuffer]
-
 
2939
        xor     edx, edx
-
 
2940
        call    fs_write64_app
-
 
2941
        jmp     .clearBitmap
-
 
2942
 
-
 
2943
.mcbEnd:
-
 
2944
        add     esp, 16
-
 
2945
        jmp     .writeBitmapMFT
-
 
2946
 
-
 
2947
.folder:    ; empty?
-
 
2948
        lea     esi, [ebp+NTFS.ntfs_bitmap_buf]
-
 
2949
        mov     [ebp+NTFS.ntfs_cur_buf], esi
-
 
2950
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90
-
 
2951
        mov     [ebp+NTFS.ntfs_cur_offs], 0
-
 
2952
        mov     [ebp+NTFS.ntfs_cur_size], 1
-
 
2953
        call    ntfs_read_attr
-
 
2954
        cmp     [ebp+NTFS.ntfs_cur_read], 48
-
 
2955
        jnz     ntfsDenied
-
 
2956
        test    byte [esi+32+indexFlags], 1
-
 
2957
        jnz     ntfsDenied
-
 
2958
.writeBitmapMFT:    ; "delete" file record
-
 
2959
        mov     eax, [ebp+NTFS.ntfs_cur_iRecord]
-
 
2960
        mov     ecx, eax
-
 
2961
        shr     eax, 3
-
 
2962
        and     ecx, 7
-
 
2963
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
-
 
2964
        btr     [edi+eax], ecx
-
 
2965
        shr     eax, 9
-
 
2966
        mov     ebx, eax
-
 
2967
        shl     ebx, 9
-
 
2968
        add     eax, [ebp+NTFS.mftBitmapLocation]
-
 
2969
        add     ebx, edi
-
 
2970
        mov     ecx, 1
-
 
2971
        xor     edx, edx
-
 
2972
        call    fs_write64_sys
-
 
2973
        mov     esi, [ebp+NTFS.frs_buffer]
-
 
2974
        mov     byte [esi+recordFlags], 0
-
 
2975
.writeFileRecord:
-
 
2976
        dec     byte [esi+hardLinkCounter]
-
 
2977
        mov     [ebp+NTFS.ntfs_cur_buf], esi
-
 
2978
        call    writeRecord
-
 
2979
; write directory node
-
 
2980
        mov     eax, [ebp+NTFS.nodeLastRead]
-
 
2981
        mov     [ebp+NTFS.ntfsLastRead], eax
-
 
2982
        mov     eax, [ebp+NTFS.cur_index_buf]
-
 
2983
        mov     [ebp+NTFS.ntfs_cur_buf], eax
-
 
2984
        call    writeRecord
-
 
2985
        test    eax, eax
-
 
2986
        jz      ntfsDone
2665
        ret
2987
        jmp     ntfsDevice
2666
 
2988
 
2667
;----------------------------------------------------------------
2989
;----------------------------------------------------------------
2668
ntfs_SetFileEnd:
2990
ntfs_SetFileEnd:
2669
ntfs_SetFileInfo:
2991
ntfs_SetFileInfo:
2670
ntfs_Delete:
-
 
2671
        mov     eax, ERROR_UNSUPPORTED_FS
2992
        movi    eax, ERROR_UNSUPPORTED_FS
2672
        ret
2993
        ret
2673
 
2994
 
2674
;----------------------------------------------------------------
2995
;----------------------------------------------------------------
2675
ntfs_GetFileInfo:
2996
ntfs_GetFileInfo:
2676
        cmp     byte [esi], 0
2997
        cmp     byte [esi], 0
2677
        jnz     @f
2998
        jnz     @f
2678
        movi    eax, 2
2999
        movi    eax, ERROR_UNSUPPORTED_FS
2679
        ret
3000
        ret
2680
@@:
3001
@@:
2681
        call    ntfs_lock
3002
        call    ntfs_lock
2682
        stdcall ntfs_find_lfn, [esp+4]
3003
        stdcall ntfs_find_lfn, [esp+4]
2683
        jnc     .doit
3004
        jnc     .found
2684
        test    eax, eax
3005
        test    eax, eax
2685
        push    ERROR_FILE_NOT_FOUND
-
 
2686
        jz      ntfsError
3006
        jz      ntfsFail
2687
        pop     eax
-
 
2688
        push    11
-
 
2689
        jmp     ntfsError
3007
        jmp     ntfsNotFound
2690
.doit:
3008
.found:
2691
        push    esi edi
3009
        push    esi edi
2692
        mov     esi, eax
3010
        mov     esi, eax
2693
        mov     edi, [ebx+16]
3011
        mov     edi, [ebx+16]
2694
        xor     eax, eax
3012
        xor     eax, eax
2695
        call    ntfs_direntry_to_bdfe
3013
        call    ntfs_direntry_to_bdfe
2696
        pop     edi esi
3014
        pop     edi esi
2697
        call    ntfs_unlock
3015
        call    ntfs_unlock
2698
        xor     eax, eax
3016
        xor     eax, eax
2699
        ret
3017
        ret
-
 
3018
 
-
 
3019
ntfsUnsupported:
2700
 
3020
        push    ERROR_UNSUPPORTED_FS
2701
ntfsError:
3021
ntfsOut:
2702
        call    ntfs_unlock
3022
        call    ntfs_unlock
2703
        xor     ebx, ebx
3023
        xor     ebx, ebx
2704
        pop     eax
3024
        pop     eax
2705
        ret
3025
        ret
-
 
3026
ntfsDevice:
-
 
3027
        push    ERROR_DEVICE
-
 
3028
        jmp     ntfsOut
-
 
3029
ntfsNotFound:
-
 
3030
        push    ERROR_FILE_NOT_FOUND
-
 
3031
        jmp     ntfsOut
-
 
3032
ntfsDenied:
-
 
3033
        push    ERROR_ACCESS_DENIED
-
 
3034
        jmp     ntfsOut
-
 
3035
ntfsFail:
-
 
3036
        push    ERROR_FS_FAIL
-
 
3037
        jmp     ntfsOut
-
 
3038
ntfsNoMemory:
-
 
3039
        push    ERROR_OUT_OF_MEMORY
-
 
3040
        jmp     ntfsOut