Subversion Repositories Kolibri OS

Rev

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

Rev 6420 Rev 6426
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2016. 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: 6420 $
8
$Revision: 6426 $
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
magic = 0
32
magic = 0
33
updateSequenceOffset = 4
33
updateSequenceOffset = 4
34
updateSequenceSize = 6
34
updateSequenceSize = 6
35
    ; FileRecord header
35
    ; FileRecord header
36
reuseCounter = 16
36
reuseCounter = 16
37
hardLinkCounter = 12h
37
hardLinkCounter = 12h
38
attributeOffset = 14h
38
attributeOffset = 14h
39
recordFlags = 16h
39
recordFlags = 16h
40
recordRealSize = 18h
40
recordRealSize = 18h
41
recordAllocatedSize = 1ch
41
recordAllocatedSize = 1ch
42
baseRecordReference = 20h       ; for auxiliary records
42
baseRecordReference = 20h       ; for auxiliary records
43
baseRecordReuse = 26h
43
baseRecordReuse = 26h
44
newAttributeID = 28h
44
newAttributeID = 28h
45
    ; attribute header
45
    ; attribute header
46
attributeType = 0
46
attributeType = 0
47
sizeWithHeader = 4
47
sizeWithHeader = 4
48
nonResidentFlag = 8
48
nonResidentFlag = 8
49
nameLength = 9
49
nameLength = 9
50
nameOffset = 10
50
nameOffset = 10
51
attributeFlags = 12
51
attributeFlags = 12
52
attributeID = 14
52
attributeID = 14
53
    ; resident attribute header
53
    ; resident attribute header
54
sizeWithoutHeader = 10h
54
sizeWithoutHeader = 10h
55
attributeOffset = 14h
55
attributeOffset = 14h
56
indexedFlag = 16h
56
indexedFlag = 16h
57
    ; non resident attribute header
57
    ; non resident attribute header
58
firstVCN = 10h
58
firstVCN = 10h
59
lastVCN = 18h
59
lastVCN = 18h
60
dataRunsOffset = 20h
60
dataRunsOffset = 20h
61
attributeAllocatedSize = 28h
61
attributeAllocatedSize = 28h
62
attributeRealSize = 30h
62
attributeRealSize = 30h
63
initialDataSize = 38h
63
initialDataSize = 38h
64
    ; $IndexRoot
64
    ; $IndexRoot
65
indexedAttributesType = 0
65
indexedAttributesType = 0
66
collationRule = 4
66
collationRule = 4
67
indexRecordSize = 8
67
indexRecordSize = 8
68
indexRecordSizeClus = 12        ; in sectors if less than one cluster
68
indexRecordSizeClus = 12        ; in sectors if less than one cluster
69
rootNode = 16
69
rootNode = 16
70
    ; IndexRecord header
70
    ; IndexRecord header
71
recordVCN = 16
71
recordVCN = 16
72
recordNode = 18h
72
recordNode = 18h
73
    ; node header
73
    ; node header
74
indexOffset = 0
74
indexOffset = 0
75
nodeRealSize = 4
75
nodeRealSize = 4
76
nodeAllocatedSize = 8
76
nodeAllocatedSize = 8
77
nonLeafFlag = 12
77
nonLeafFlag = 12
78
    ; $Filename index
78
    ; $Filename index
79
fileRecordReference = 0
79
fileRecordReference = 0
80
fileReferenceReuse = 6
80
fileReferenceReuse = 6
81
indexAllocatedSize = 8
81
indexAllocatedSize = 8
82
indexRawSize = 10
82
indexRawSize = 10
83
indexFlags = 12
83
indexFlags = 12
84
directoryRecordReference = 16
84
directoryRecordReference = 16
85
directoryReferenceReuse = 16h
85
directoryReferenceReuse = 16h
86
fileCreated = 18h
86
fileCreated = 18h
87
fileModified = 20h
87
fileModified = 20h
88
recordModified = 28h
88
recordModified = 28h
89
fileAccessed = 30h
89
fileAccessed = 30h
90
fileAllocatedSize = 38h
90
fileAllocatedSize = 38h
91
fileRealSize = 40h
91
fileRealSize = 40h
92
fileFlags = 48h
92
fileFlags = 48h
93
fileNameLength = 50h
93
fileNameLength = 50h
94
namespace = 51h
94
namespace = 51h
95
fileName = 52h
95
fileName = 52h
96
 
96
 
97
struct NTFS PARTITION
97
struct NTFS PARTITION
98
Lock            MUTEX   ?   ; Currently operations with one partition
98
Lock            MUTEX   ?   ; Currently operations with one partition
99
; can not be executed in parallel since the legacy code is not ready.
99
; can not be executed in parallel since the legacy code is not ready.
100
sectors_per_cluster dd  ?
100
sectors_per_cluster dd  ?
101
mft_cluster         dd  ?   ; location
101
mft_cluster         dd  ?   ; location
102
mftmirr_cluster     dd  ?   ; location
102
mftmirr_cluster     dd  ?   ; location
103
frs_size            dd  ?   ; in bytes
103
frs_size            dd  ?   ; in bytes
104
frs_buffer          dd  ?   ; MFT fileRecord buffer
104
frs_buffer          dd  ?   ; MFT fileRecord buffer
105
mft_retrieval_end   dd  ?
105
mft_retrieval_end   dd  ?
106
mftSize             dd  ?   ; in sectors
106
mftSize             dd  ?   ; in sectors
107
cur_index_size      dd  ?   ; in sectors
107
cur_index_size      dd  ?   ; in sectors
108
cur_index_buf       dd  ?   ; index node buffer
108
cur_index_buf       dd  ?   ; index node buffer
109
secondIndexBuffer   dd  ?
109
secondIndexBuffer   dd  ?
110
BitmapBuffer        dd  ?
110
BitmapBuffer        dd  ?
111
BitmapTotalSize     dd  ?   ; bytes reserved
111
BitmapTotalSize     dd  ?   ; bytes reserved
112
BitmapSize          dd  ?   ; bytes readen
112
BitmapSize          dd  ?   ; bytes readen
113
BitmapLocation      dd  ?   ; starting sector
113
BitmapLocation      dd  ?   ; starting sector
114
BitmapStart         dd  ?   ; first byte after area, reserved for MFT
114
BitmapStart         dd  ?   ; first byte after area, reserved for MFT
115
mftBitmapBuffer     dd  ?   ; one cluster
115
mftBitmapBuffer     dd  ?   ; one cluster
116
mftBitmapSize       dd  ?   ; bytes readen
116
mftBitmapSize       dd  ?   ; bytes readen
117
mftBitmapLocation   dd  ?   ; starting sector
117
mftBitmapLocation   dd  ?   ; starting sector
118
 
118
 
119
attr_size           dq  ?
119
attr_size           dq  ?
120
attr_offs           dd  ?
120
attr_offs           dd  ?
121
attr_list           dd  ?
121
attr_list           dd  ?
122
attr_iBaseRecord    dd  ?
122
attr_iBaseRecord    dd  ?
123
cur_attr            dd  ?   ; attribute type
123
cur_attr            dd  ?   ; attribute type
124
cur_iRecord         dd  ?   ; number of fileRecord in MFT
124
cur_iRecord         dd  ?   ; number of fileRecord in MFT
125
cur_offs            dd  ?   ; attribute VCN in sectors
125
cur_offs            dd  ?   ; attribute VCN in sectors
126
cur_size            dd  ?   ; max sectors to read
126
cur_size            dd  ?   ; max sectors to read
127
cur_buf             dd  ?
127
cur_buf             dd  ?
128
cur_read            dd  ?   ; bytes readen
128
cur_read            dd  ?   ; bytes readen
129
cur_tail            dd  ?
129
cur_tail            dd  ?
130
cur_subnode_size    dd  ?
130
cur_subnode_size    dd  ?
131
LastRead            dd  ?   ; last readen block of sectors
131
LastRead            dd  ?   ; last readen block of sectors
132
mftLastRead         dd  ?
132
mftLastRead         dd  ?
133
rootLastRead        dd  ?
133
rootLastRead        dd  ?
134
nodeLastRead        dd  ?
134
nodeLastRead        dd  ?
135
indexRoot           dd  ?
135
indexRoot           dd  ?
136
indexPointer        dd  ?
136
indexPointer        dd  ?
137
newRecord           dd  ?
137
newRecord           dd  ?
138
fileDataStart       dd  ?   ; starting cluster
138
fileDataStart       dd  ?   ; starting cluster
139
fileDataSize        dd  ?   ; in clusters
139
fileDataSize        dd  ?   ; in clusters
140
fileDataBuffer      dd  ?
140
fileDataBuffer      dd  ?
141
fileRealSize        dd  ?   ; in bytes
141
fileRealSize        dd  ?   ; in bytes
142
fragmentCount       db  ?
142
fragmentCount       db  ?
143
bCanContinue        db  ?
143
bCanContinue        db  ?
144
bFolder             db  ?
144
bFolder             db  ?
145
bWriteAttr          db  ?   ; Warning: Don't forget to turn off!!!
145
bWriteAttr          db  ?   ; Warning: Don't forget to turn off!!!
146
 
146
 
147
align 256
147
align 256
148
mft_retrieval       rb  768
148
mft_retrieval       rb  768
149
attrlist_buf        rb  1024
149
attrlist_buf        rb  1024
150
attrlist_mft_buf    rb  1024
150
attrlist_mft_buf    rb  1024
151
bitmap_buf          rb  1024
151
bitmap_buf          rb  1024
152
ends
152
ends
153
 
153
 
154
; NTFS external functions
154
; NTFS external functions
155
;   in:
155
;   in:
156
; ebx -> parameter structure of sysfunc 70
156
; ebx -> parameter structure of sysfunc 70
157
; ebp -> NTFS structure
157
; ebp -> NTFS structure
158
; [esi]+[esp+4] = name
158
; [esi]+[esp+4] = name
159
;   out:
159
;   out:
160
; eax, ebx = return values for sysfunc 70
160
; eax, ebx = return values for sysfunc 70
161
iglobal
161
iglobal
162
align 4
162
align 4
163
ntfs_user_functions:
163
ntfs_user_functions:
164
        dd      ntfs_free
164
        dd      ntfs_free
165
        dd      (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
165
        dd      (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
166
        dd      ntfs_ReadFile
166
        dd      ntfs_ReadFile
167
        dd      ntfs_ReadFolder
167
        dd      ntfs_ReadFolder
168
        dd      ntfs_CreateFile
168
        dd      ntfs_CreateFile
169
        dd      ntfs_WriteFile
169
        dd      ntfs_WriteFile
170
        dd      ntfs_SetFileEnd
170
        dd      ntfs_SetFileEnd
171
        dd      ntfs_GetFileInfo
171
        dd      ntfs_GetFileInfo
172
        dd      ntfs_SetFileInfo
172
        dd      ntfs_SetFileInfo
173
        dd      0
173
        dd      0
174
        dd      ntfs_Delete
174
        dd      ntfs_Delete
175
        dd      ntfs_CreateFolder
175
        dd      ntfs_CreateFolder
176
ntfs_user_functions_end:
176
ntfs_user_functions_end:
177
endg
177
endg
178
 
178
 
179
ntfs_test_bootsec:
179
ntfs_test_bootsec:
180
; in: ebx -> buffer, edx = size of partition
180
; in: ebx -> buffer, edx = size of partition
181
; out: CF=1 -> invalid
181
; out: CF=1 -> invalid
182
; 1. Name=='NTFS    '
182
; 1. Name=='NTFS    '
183
        cmp     dword [ebx+3], 'NTFS'
183
        cmp     dword [ebx+3], 'NTFS'
184
        jnz     .no
184
        jnz     .no
185
        cmp     dword [ebx+7], '    '
185
        cmp     dword [ebx+7], '    '
186
        jnz     .no
186
        jnz     .no
187
; 2. Number of bytes per sector is the same as for physical device
187
; 2. Number of bytes per sector is the same as for physical device
188
; (that is, 0x200 for hard disk)
188
; (that is, 0x200 for hard disk)
189
        cmp     word [ebx+11], 0x200
189
        cmp     word [ebx+11], 0x200
190
        jnz     .no
190
        jnz     .no
191
; 3. Number of sectors per cluster must be power of 2
191
; 3. Number of sectors per cluster must be power of 2
192
        movzx   eax, byte [ebx+13]
192
        movzx   eax, byte [ebx+13]
193
        dec     eax
193
        dec     eax
194
        js      .no
194
        js      .no
195
        test    al, [ebx+13]
195
        test    al, [ebx+13]
196
        jnz     .no
196
        jnz     .no
197
; 4. FAT parameters must be zero
197
; 4. FAT parameters must be zero
198
        cmp     word [ebx+14], 0
198
        cmp     word [ebx+14], 0
199
        jnz     .no
199
        jnz     .no
200
        cmp     dword [ebx+16], 0
200
        cmp     dword [ebx+16], 0
201
        jnz     .no
201
        jnz     .no
202
        cmp     byte [ebx+20], 0
202
        cmp     byte [ebx+20], 0
203
        jnz     .no
203
        jnz     .no
204
        cmp     word [ebx+22], 0
204
        cmp     word [ebx+22], 0
205
        jnz     .no
205
        jnz     .no
206
        cmp     dword [ebx+32], 0
206
        cmp     dword [ebx+32], 0
207
        jnz     .no
207
        jnz     .no
208
; 5. Number of sectors <= partition size
208
; 5. Number of sectors <= partition size
209
        cmp     dword [ebx+0x2C], 0
209
        cmp     dword [ebx+0x2C], 0
210
        ja      .no
210
        ja      .no
211
        cmp     [ebx+0x28], edx
211
        cmp     [ebx+0x28], edx
212
        ja      .no
212
        ja      .no
213
; 6. $MFT and $MFTMirr clusters must be within partition
213
; 6. $MFT and $MFTMirr clusters must be within partition
214
        cmp     dword [ebx+0x34], 0
214
        cmp     dword [ebx+0x34], 0
215
        ja      .no
215
        ja      .no
216
        push    edx
216
        push    edx
217
        movzx   eax, byte [ebx+13]
217
        movzx   eax, byte [ebx+13]
218
        mul     dword [ebx+0x30]
218
        mul     dword [ebx+0x30]
219
        test    edx, edx
219
        test    edx, edx
220
        pop     edx
220
        pop     edx
221
        jnz     .no
221
        jnz     .no
222
        cmp     eax, edx
222
        cmp     eax, edx
223
        ja      .no
223
        ja      .no
224
        cmp     dword [ebx+0x3C], 0
224
        cmp     dword [ebx+0x3C], 0
225
        ja      .no
225
        ja      .no
226
        push    edx
226
        push    edx
227
        movzx   eax, byte [ebx+13]
227
        movzx   eax, byte [ebx+13]
228
        mul     dword [ebx+0x38]
228
        mul     dword [ebx+0x38]
229
        test    edx, edx
229
        test    edx, edx
230
        pop     edx
230
        pop     edx
231
        jnz     .no
231
        jnz     .no
232
        cmp     eax, edx
232
        cmp     eax, edx
233
        ja      .no
233
        ja      .no
234
; 7. Clusters per FRS must be either power of 2 or between -31 and -9
234
; 7. Clusters per FRS must be either power of 2 or between -31 and -9
235
        movsx   eax, byte [ebx+0x40]
235
        movsx   eax, byte [ebx+0x40]
236
        cmp     al, -31
236
        cmp     al, -31
237
        jl      .no
237
        jl      .no
238
        cmp     al, -9
238
        cmp     al, -9
239
        jle     @f
239
        jle     @f
240
        dec     eax
240
        dec     eax
241
        js      .no
241
        js      .no
242
        test    [ebx+0x40], al
242
        test    [ebx+0x40], al
243
        jnz     .no
243
        jnz     .no
244
@@:         ; 8. Same for clusters per IndexAllocationBuffer
244
@@:         ; 8. Same for clusters per IndexAllocationBuffer
245
        movsx   eax, byte [ebx+0x44]
245
        movsx   eax, byte [ebx+0x44]
246
        cmp     al, -31
246
        cmp     al, -31
247
        jl      .no
247
        jl      .no
248
        cmp     al, -9
248
        cmp     al, -9
249
        jle     @f
249
        jle     @f
250
        dec     eax
250
        dec     eax
251
        js      .no
251
        js      .no
252
        test    [ebx+0x44], al
252
        test    [ebx+0x44], al
253
        jnz     .no
253
        jnz     .no
254
@@:         ; OK, this is correct NTFS bootsector
254
@@:         ; OK, this is correct NTFS bootsector
255
        clc
255
        clc
256
        ret
256
        ret
257
.no:        ; No, this bootsector isn't NTFS
257
.no:        ; No, this bootsector isn't NTFS
258
        stc
258
        stc
259
        ret
259
        ret
260
 
260
 
261
ntfs_create_partition:
261
ntfs_create_partition:
262
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
262
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
263
        jnz     .nope
263
        jnz     .nope
264
        mov     edx, dword [ebp+PARTITION.Length]
264
        mov     edx, dword [ebp+PARTITION.Length]
265
        cmp     dword [esp+4], 0
265
        cmp     dword [esp+4], 0
266
        jz      .boot_read_ok
266
        jz      .boot_read_ok
267
        add     ebx, 512
267
        add     ebx, 512
268
        lea     eax, [edx-1]
268
        lea     eax, [edx-1]
269
        call    fs_read32_sys
269
        call    fs_read32_sys
270
        test    eax, eax
270
        test    eax, eax
271
        jnz     @f
271
        jnz     @f
272
        call    ntfs_test_bootsec
272
        call    ntfs_test_bootsec
273
        jnc     .ntfs_setup
273
        jnc     .ntfs_setup
274
@@:
274
@@:
275
        mov     eax, edx
275
        mov     eax, edx
276
        shr     eax, 1
276
        shr     eax, 1
277
        call    fs_read32_sys
277
        call    fs_read32_sys
278
        test    eax, eax
278
        test    eax, eax
279
        jnz     .nope
279
        jnz     .nope
280
.boot_read_ok:
280
.boot_read_ok:
281
        call    ntfs_test_bootsec
281
        call    ntfs_test_bootsec
282
        jnc     .ntfs_setup
282
        jnc     .ntfs_setup
283
.nope:
283
.nope:
284
        xor     eax, eax
284
        xor     eax, eax
285
        jmp     .exit
285
        jmp     .exit
286
 
286
 
287
.ntfs_setup:    ; By given bootsector, initialize some NTFS variables
287
.ntfs_setup:    ; By given bootsector, initialize some NTFS variables
288
        stdcall kernel_alloc, 1000h
288
        stdcall kernel_alloc, 1000h
289
        test    eax, eax
289
        test    eax, eax
290
        jz      .exit
290
        jz      .exit
291
        mov     ecx, dword [ebp+PARTITION.FirstSector]
291
        mov     ecx, dword [ebp+PARTITION.FirstSector]
292
        mov     dword [eax+NTFS.FirstSector], ecx
292
        mov     dword [eax+NTFS.FirstSector], ecx
293
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
293
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
294
        mov     dword [eax+NTFS.FirstSector+4], ecx
294
        mov     dword [eax+NTFS.FirstSector+4], ecx
295
        mov     ecx, [ebp+PARTITION.Disk]
295
        mov     ecx, [ebp+PARTITION.Disk]
296
        mov     [eax+NTFS.Disk], ecx
296
        mov     [eax+NTFS.Disk], ecx
297
        mov     [eax+NTFS.FSUserFunctions], ntfs_user_functions
297
        mov     [eax+NTFS.FSUserFunctions], ntfs_user_functions
298
        mov     [eax+NTFS.bWriteAttr], 0
298
        mov     [eax+NTFS.bWriteAttr], 0
299
 
299
 
300
        push    ebx ebp esi
300
        push    ebx ebp esi
301
        mov     ebp, eax
301
        mov     ebp, eax
302
        lea     ecx, [ebp+NTFS.Lock]
302
        lea     ecx, [ebp+NTFS.Lock]
303
        call    mutex_init
303
        call    mutex_init
304
        movzx   eax, byte [ebx+13]
304
        movzx   eax, byte [ebx+13]
305
        mov     [ebp+NTFS.sectors_per_cluster], eax
305
        mov     [ebp+NTFS.sectors_per_cluster], eax
306
        mov     eax, [ebx+0x28]
306
        mov     eax, [ebx+0x28]
307
        mov     dword [ebp+NTFS.Length], eax
307
        mov     dword [ebp+NTFS.Length], eax
308
        and     dword [ebp+NTFS.Length+4], 0
308
        and     dword [ebp+NTFS.Length+4], 0
309
        mov     eax, [ebx+0x30]
309
        mov     eax, [ebx+0x30]
310
        mov     [ebp+NTFS.mft_cluster], eax
310
        mov     [ebp+NTFS.mft_cluster], eax
311
        mov     eax, [ebx+0x38]
311
        mov     eax, [ebx+0x38]
312
        mov     [ebp+NTFS.mftmirr_cluster], eax
312
        mov     [ebp+NTFS.mftmirr_cluster], eax
313
        movsx   eax, byte [ebx+0x40]
313
        movsx   eax, byte [ebx+0x40]
314
        test    eax, eax
314
        test    eax, eax
315
        js      @f
315
        js      @f
316
        mul     [ebp+NTFS.sectors_per_cluster]
316
        mul     [ebp+NTFS.sectors_per_cluster]
317
        shl     eax, 9
317
        shl     eax, 9
318
        jmp     .1
318
        jmp     .1
319
 
319
 
320
@@:
320
@@:
321
        neg     eax
321
        neg     eax
322
        mov     ecx, eax
322
        mov     ecx, eax
323
        mov     eax, 1
323
        mov     eax, 1
324
        shl     eax, cl
324
        shl     eax, cl
325
.1:
325
.1:
326
        mov     [ebp+NTFS.frs_size], eax
326
        mov     [ebp+NTFS.frs_size], eax
327
        stdcall kernel_alloc, eax
327
        stdcall kernel_alloc, eax
328
        test    eax, eax
328
        test    eax, eax
329
        jz      .fail_free
329
        jz      .fail_free
330
        mov     [ebp+NTFS.frs_buffer], eax
330
        mov     [ebp+NTFS.frs_buffer], eax
331
; read $MFT disposition
331
; read $MFT disposition
332
        mov     eax, [ebp+NTFS.mft_cluster]
332
        mov     eax, [ebp+NTFS.mft_cluster]
333
        mul     [ebp+NTFS.sectors_per_cluster]
333
        mul     [ebp+NTFS.sectors_per_cluster]
334
        mov     ecx, [ebp+NTFS.frs_size]
334
        mov     ecx, [ebp+NTFS.frs_size]
335
        shr     ecx, 9
335
        shr     ecx, 9
336
        mov     ebx, [ebp+NTFS.frs_buffer]
336
        mov     ebx, [ebp+NTFS.frs_buffer]
337
        call    fs_read64_sys
337
        call    fs_read64_sys
338
        test    eax, eax
338
        test    eax, eax
339
        jnz     .usemirr
339
        jnz     .usemirr
340
        cmp     dword [ebx], 'FILE'
340
        cmp     dword [ebx], 'FILE'
341
        jnz     .usemirr
341
        jnz     .usemirr
342
        call    ntfs_restore_usa_frs
342
        call    ntfs_restore_usa_frs
343
        jnc     .mftok
343
        jnc     .mftok
344
.usemirr:
344
.usemirr:
345
        mov     eax, [ebp+NTFS.mftmirr_cluster]
345
        mov     eax, [ebp+NTFS.mftmirr_cluster]
346
        mul     [ebp+NTFS.sectors_per_cluster]
346
        mul     [ebp+NTFS.sectors_per_cluster]
347
        mov     ecx, [ebp+NTFS.frs_size]
347
        mov     ecx, [ebp+NTFS.frs_size]
348
        shr     ecx, 9
348
        shr     ecx, 9
349
        mov     ebx, [ebp+NTFS.frs_buffer]
349
        mov     ebx, [ebp+NTFS.frs_buffer]
350
        call    fs_read64_sys
350
        call    fs_read64_sys
351
        test    eax, eax
351
        test    eax, eax
352
        jnz     .fail_free_frs
352
        jnz     .fail_free_frs
353
        cmp     dword [ebx], 'FILE'
353
        cmp     dword [ebx], 'FILE'
354
        jnz     .fail_free_frs
354
        jnz     .fail_free_frs
355
        call    ntfs_restore_usa_frs
355
        call    ntfs_restore_usa_frs
356
        jc      .fail_free_frs
356
        jc      .fail_free_frs
357
.mftok:     ; prepare $MFT retrieval information
357
.mftok:     ; prepare $MFT retrieval information
358
; search for unnamed non-resident $DATA attribute
358
; search for unnamed non-resident $DATA attribute
359
        movzx   eax, word [ebx+attributeOffset]
359
        movzx   eax, word [ebx+attributeOffset]
360
        add     eax, ebx
360
        add     eax, ebx
361
.scandata:
361
.scandata:
362
        cmp     dword [eax], -1
362
        cmp     dword [eax], -1
363
        jz      .fail_free_frs
363
        jz      .fail_free_frs
364
        cmp     dword [eax], 0x80
364
        cmp     dword [eax], 0x80
365
        jnz     @f
365
        jnz     @f
366
        cmp     byte [eax+nameLength], 0
366
        cmp     byte [eax+nameLength], 0
367
        jz      .founddata
367
        jz      .founddata
368
@@:
368
@@:
369
        add     eax, [eax+sizeWithHeader]
369
        add     eax, [eax+sizeWithHeader]
370
        jmp     .scandata
370
        jmp     .scandata
371
 
371
 
372
.founddata:
372
.founddata:
373
        cmp     byte [eax+nonResidentFlag], 0
373
        cmp     byte [eax+nonResidentFlag], 0
374
        jz      .fail_free_frs
374
        jz      .fail_free_frs
375
        movzx   esi, word [eax+dataRunsOffset]
375
        movzx   esi, word [eax+dataRunsOffset]
376
        add     esi, eax
376
        add     esi, eax
377
        mov     edx, [eax+attributeAllocatedSize+4]
377
        mov     edx, [eax+attributeAllocatedSize+4]
378
        mov     eax, [eax+attributeAllocatedSize]
378
        mov     eax, [eax+attributeAllocatedSize]
379
        shrd    eax, edx, 9
379
        shrd    eax, edx, 9
380
        mov     [ebp+NTFS.mftSize], eax
380
        mov     [ebp+NTFS.mftSize], eax
381
        sub     esp, 10h
381
        sub     esp, 10h
382
        lea     ecx, [ebp+NTFS.mft_retrieval]
382
        lea     ecx, [ebp+NTFS.mft_retrieval]
383
        xor     edx, edx
383
        xor     edx, edx
384
.scanmcb:   ; load descriptions of fragments
384
.scanmcb:   ; load descriptions of fragments
385
        call    ntfs_decode_mcb_entry
385
        call    ntfs_decode_mcb_entry
386
        jnc     .scanmcbend
386
        jnc     .scanmcbend
387
        mov     eax, [esp]      ; block length
387
        mov     eax, [esp]      ; block length
388
        mov     [ecx], eax
388
        mov     [ecx], eax
389
        add     edx, [esp+8]    ; block addr
389
        add     edx, [esp+8]    ; block addr
390
        mov     [ecx+4], edx
390
        mov     [ecx+4], edx
391
        add     ecx, 8
391
        add     ecx, 8
392
        jmp     .scanmcb
392
        jmp     .scanmcb
393
 
393
 
394
.scanmcbend:
394
.scanmcbend:
395
        add     esp, 10h
395
        add     esp, 10h
396
        lea     eax, [ebp+NTFS.attrlist_buf]
396
        lea     eax, [ebp+NTFS.attrlist_buf]
397
        cmp     eax, ecx
397
        cmp     eax, ecx
398
        jc      @f
398
        jc      @f
399
        mov     eax, ecx
399
        mov     eax, ecx
400
@@:
400
@@:
401
        mov     [ebp+NTFS.mft_retrieval_end], eax
401
        mov     [ebp+NTFS.mft_retrieval_end], eax
402
; allocate index buffers
402
; allocate index buffers
403
        stdcall kernel_alloc, 2000h
403
        stdcall kernel_alloc, 2000h
404
        test    eax, eax
404
        test    eax, eax
405
        jz      .fail_free_frs
405
        jz      .fail_free_frs
406
        mov     [ebp+NTFS.cur_index_buf], eax
406
        mov     [ebp+NTFS.cur_index_buf], eax
407
        add     eax, 1000h
407
        add     eax, 1000h
408
        mov     [ebp+NTFS.secondIndexBuffer], eax
408
        mov     [ebp+NTFS.secondIndexBuffer], eax
409
        mov     [ebp+NTFS.cur_index_size], 8
409
        mov     [ebp+NTFS.cur_index_size], 8
410
; reserve adress space for bitmap buffer and load some part of bitmap
410
; reserve adress space for bitmap buffer and load some part of bitmap
411
        mov     eax, dword [ebp+NTFS.Length]
411
        mov     eax, dword [ebp+NTFS.Length]
412
        xor     edx, edx
412
        xor     edx, edx
413
        div     [ebp+NTFS.sectors_per_cluster]
413
        div     [ebp+NTFS.sectors_per_cluster]
414
        shr     eax, 3
414
        shr     eax, 3
415
        mov     [ebp+NTFS.BitmapTotalSize], eax
415
        mov     [ebp+NTFS.BitmapTotalSize], eax
416
        add     eax, 7FFFh
416
        add     eax, 7FFFh
417
        and     eax, not 7FFFh
417
        and     eax, not 7FFFh
418
        push    eax
418
        push    eax
419
        call    alloc_kernel_space
419
        call    alloc_kernel_space
420
        test    eax, eax
420
        test    eax, eax
421
        jz      .failFreeIndex
421
        jz      .failFreeIndex
422
        mov     [ebp+NTFS.BitmapBuffer], eax
422
        mov     [ebp+NTFS.BitmapBuffer], eax
423
        mov     [ebp+NTFS.cur_buf], eax
423
        mov     [ebp+NTFS.cur_buf], eax
424
        mov     eax, [ebp+NTFS.BitmapTotalSize]
424
        mov     eax, [ebp+NTFS.BitmapTotalSize]
425
        add     eax, [ebp+NTFS.mft_cluster]
425
        add     eax, [ebp+NTFS.mft_cluster]
426
        shr     eax, 3+2        ; reserve 1/8 of partition for $MFT
426
        shr     eax, 3+2        ; reserve 1/8 of partition for $MFT
427
        shl     eax, 2
427
        shl     eax, 2
428
        mov     [ebp+NTFS.BitmapStart], eax
428
        mov     [ebp+NTFS.BitmapStart], eax
429
        shr     eax, 15
429
        shr     eax, 15
430
        inc     eax
430
        inc     eax
431
        shl     eax, 3
431
        shl     eax, 3
432
        push    eax
432
        push    eax
433
        push    eax
433
        push    eax
434
        shl     eax, 3
434
        shl     eax, 3
435
        mov     [ebp+NTFS.cur_size], eax
435
        mov     [ebp+NTFS.cur_size], eax
436
        call    alloc_pages
436
        call    alloc_pages
437
        test    eax, eax
437
        test    eax, eax
438
        pop     ecx
438
        pop     ecx
439
        jz      .failFreeBitmap
439
        jz      .failFreeBitmap
440
        add     eax, 3
440
        add     eax, 3
441
        mov     ebx, [ebp+NTFS.BitmapBuffer]
441
        mov     ebx, [ebp+NTFS.BitmapBuffer]
442
        call    commit_pages
442
        call    commit_pages
443
        mov     [ebp+NTFS.cur_iRecord], 6
443
        mov     [ebp+NTFS.cur_iRecord], 6
444
        mov     [ebp+NTFS.cur_attr], 0x80
444
        mov     [ebp+NTFS.cur_attr], 0x80
445
        mov     [ebp+NTFS.cur_offs], 0
445
        mov     [ebp+NTFS.cur_offs], 0
446
        call    ntfs_read_attr
446
        call    ntfs_read_attr
447
        jc      .failFreeBitmap
447
        jc      .failFreeBitmap
448
        mov     eax, [ebp+NTFS.cur_read]
448
        mov     eax, [ebp+NTFS.cur_read]
449
        mov     [ebp+NTFS.BitmapSize], eax
449
        mov     [ebp+NTFS.BitmapSize], eax
450
        mov     eax, [ebp+NTFS.LastRead]
450
        mov     eax, [ebp+NTFS.LastRead]
451
        mov     [ebp+NTFS.BitmapLocation], eax
451
        mov     [ebp+NTFS.BitmapLocation], eax
452
; read MFT $BITMAP attribute
452
; read MFT $BITMAP attribute
453
        mov     eax, [ebp+NTFS.sectors_per_cluster]
453
        mov     eax, [ebp+NTFS.sectors_per_cluster]
454
        mov     [ebp+NTFS.cur_size], eax
454
        mov     [ebp+NTFS.cur_size], eax
455
        shl     eax, 9
455
        shl     eax, 9
456
        stdcall kernel_alloc, eax
456
        stdcall kernel_alloc, eax
457
        test    eax, eax
457
        test    eax, eax
458
        jz      .failFreeBitmap
458
        jz      .failFreeBitmap
459
        mov     [ebp+NTFS.mftBitmapBuffer], eax
459
        mov     [ebp+NTFS.mftBitmapBuffer], eax
460
        mov     [ebp+NTFS.cur_buf], eax
460
        mov     [ebp+NTFS.cur_buf], eax
461
        mov     [ebp+NTFS.cur_iRecord], 0
461
        mov     [ebp+NTFS.cur_iRecord], 0
462
        mov     [ebp+NTFS.cur_attr], 0xB0
462
        mov     [ebp+NTFS.cur_attr], 0xB0
463
        mov     [ebp+NTFS.cur_offs], 0
463
        mov     [ebp+NTFS.cur_offs], 0
464
        call    ntfs_read_attr
464
        call    ntfs_read_attr
465
        mov     eax, [ebp+NTFS.cur_read]
465
        mov     eax, [ebp+NTFS.cur_read]
466
        cmp     eax, 4
466
        cmp     eax, 4
467
        jc      .failFreeBitmapMFT
467
        jc      .failFreeBitmapMFT
468
        mov     ecx, [ebp+NTFS.attr_offs]
468
        mov     ecx, [ebp+NTFS.attr_offs]
469
        cmp     byte [ecx+nonResidentFlag], 1
469
        cmp     byte [ecx+nonResidentFlag], 1
470
        jnz     .failFreeBitmapMFT
470
        jnz     .failFreeBitmapMFT
471
        mov     [ebp+NTFS.mftBitmapSize], eax
471
        mov     [ebp+NTFS.mftBitmapSize], eax
472
        mov     eax, [ebp+NTFS.LastRead]
472
        mov     eax, [ebp+NTFS.LastRead]
473
        mov     [ebp+NTFS.mftBitmapLocation], eax
473
        mov     [ebp+NTFS.mftBitmapLocation], eax
474
 
474
 
475
        mov     eax, ebp
475
        mov     eax, ebp
476
.pop_exit:
476
.pop_exit:
477
        pop     esi ebp ebx
477
        pop     esi ebp ebx
478
.exit:
478
.exit:
479
        cmp     dword [esp+4], 0
479
        cmp     dword [esp+4], 0
480
        jz      @f
480
        jz      @f
481
        sub     ebx, 512
481
        sub     ebx, 512
482
@@:
482
@@:
483
        ret
483
        ret
484
 
484
 
485
.failFreeBitmapMFT:
485
.failFreeBitmapMFT:
486
        stdcall kernel_free, [ebp+NTFS.mftBitmapBuffer]
486
        stdcall kernel_free, [ebp+NTFS.mftBitmapBuffer]
487
.failFreeBitmap:
487
.failFreeBitmap:
488
        stdcall kernel_free, [ebp+NTFS.BitmapBuffer]
488
        stdcall kernel_free, [ebp+NTFS.BitmapBuffer]
489
.failFreeIndex:
489
.failFreeIndex:
490
        mov     eax, [ebp+NTFS.cur_index_buf]
490
        mov     eax, [ebp+NTFS.cur_index_buf]
491
        cmp     eax, [ebp+NTFS.secondIndexBuffer]
491
        cmp     eax, [ebp+NTFS.secondIndexBuffer]
492
        jc      @f
492
        jc      @f
493
        mov     eax, [ebp+NTFS.secondIndexBuffer]
493
        mov     eax, [ebp+NTFS.secondIndexBuffer]
494
@@:
494
@@:
495
        stdcall kernel_free, eax
495
        stdcall kernel_free, eax
496
.fail_free_frs:
496
.fail_free_frs:
497
        stdcall kernel_free, [ebp+NTFS.frs_buffer]
497
        stdcall kernel_free, [ebp+NTFS.frs_buffer]
498
.fail_free:
498
.fail_free:
499
        stdcall kernel_free, ebp
499
        stdcall kernel_free, ebp
500
        xor     eax, eax
500
        xor     eax, eax
501
        jmp     .pop_exit
501
        jmp     .pop_exit
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.mftBitmapBuffer]
507
        stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
508
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
508
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
509
        mov     eax, [ebx+NTFS.cur_index_buf]
509
        mov     eax, [ebx+NTFS.cur_index_buf]
510
        cmp     eax, [ebx+NTFS.secondIndexBuffer]
510
        cmp     eax, [ebx+NTFS.secondIndexBuffer]
511
        jc      @f
511
        jc      @f
512
        mov     eax, [ebx+NTFS.secondIndexBuffer]
512
        mov     eax, [ebx+NTFS.secondIndexBuffer]
513
@@:
513
@@:
514
        stdcall kernel_free, eax
514
        stdcall kernel_free, eax
515
        stdcall kernel_free, ebx
515
        stdcall kernel_free, ebx
516
        pop     ebx
516
        pop     ebx
517
        ret
517
        ret
518
 
518
 
519
ntfs_lock:
519
ntfs_lock:
520
        lea     ecx, [ebp+NTFS.Lock]
520
        lea     ecx, [ebp+NTFS.Lock]
521
        jmp     mutex_lock
521
        jmp     mutex_lock
522
 
522
 
523
ntfs_unlock:
523
ntfs_unlock:
524
        lea     ecx, [ebp+NTFS.Lock]
524
        lea     ecx, [ebp+NTFS.Lock]
525
        jmp     mutex_unlock
525
        jmp     mutex_unlock
526
 
526
 
527
ntfs_read_attr:
527
ntfs_read_attr:
528
; [ebp+NTFS.bWriteAttr]=1 -> write attribute
528
; [ebp+NTFS.bWriteAttr]=1 -> write attribute
529
;   in:
529
;   in:
530
; [ebp+NTFS.cur_iRecord] = number of fileRecord
530
; [ebp+NTFS.cur_iRecord] = number of fileRecord
531
; [ebp+NTFS.cur_attr] = attribute type
531
; [ebp+NTFS.cur_attr] = attribute type
532
; [ebp+NTFS.cur_offs] = attribute VCN in sectors
532
; [ebp+NTFS.cur_offs] = attribute VCN in sectors
533
; [ebp+NTFS.cur_buf] -> buffer for data
533
; [ebp+NTFS.cur_buf] -> buffer for data
534
; [ebp+NTFS.cur_size] = max sectors to read
534
; [ebp+NTFS.cur_size] = max sectors to read
535
;   out:
535
;   out:
536
; [ebp+NTFS.cur_read] = bytes readen
536
; [ebp+NTFS.cur_read] = bytes readen
537
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
537
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
538
        xor     eax, eax
538
        xor     eax, eax
539
        pushad
539
        pushad
540
        and     [ebp+NTFS.cur_read], 0
540
        and     [ebp+NTFS.cur_read], 0
541
        cmp     [ebp+NTFS.cur_iRecord], 0
541
        cmp     [ebp+NTFS.cur_iRecord], 0
542
        jnz     .nomft
542
        jnz     .nomft
543
        cmp     [ebp+NTFS.cur_attr], 0x80
543
        cmp     [ebp+NTFS.cur_attr], 0x80
544
        jnz     .nomft
544
        jnz     .nomft
545
; precalculated part of $Mft $DATA
545
; precalculated part of $Mft $DATA
546
        mov     eax, [ebp+NTFS.cur_offs]
546
        mov     eax, [ebp+NTFS.cur_offs]
547
        xor     edx, edx
547
        xor     edx, edx
548
        div     [ebp+NTFS.sectors_per_cluster]
548
        div     [ebp+NTFS.sectors_per_cluster]
549
        mov     ebx, edx
549
        mov     ebx, edx
550
        mov     [ebp+NTFS.fragmentCount], 0
550
        mov     [ebp+NTFS.fragmentCount], 0
551
; eax = VCN, ebx = offset in sectors from beginning of cluster
551
; eax = VCN, ebx = offset in sectors from beginning of cluster
552
        lea     esi, [ebp+NTFS.mft_retrieval]
552
        lea     esi, [ebp+NTFS.mft_retrieval]
553
        sub     esi, 8
553
        sub     esi, 8
554
.mftscan:
554
.mftscan:
555
        add     esi, 8
555
        add     esi, 8
556
        cmp     esi, [ebp+NTFS.mft_retrieval_end]
556
        cmp     esi, [ebp+NTFS.mft_retrieval_end]
557
        jz      .nomft
557
        jz      .nomft
558
        mov     ecx, [esi+4]
558
        mov     ecx, [esi+4]
559
        sub     eax, [esi]
559
        sub     eax, [esi]
560
        jnc     .mftscan
560
        jnc     .mftscan
561
        add     ecx, eax
561
        add     ecx, eax
562
        add     ecx, [esi]
562
        add     ecx, [esi]
563
        neg     eax
563
        neg     eax
564
        mul     [ebp+NTFS.sectors_per_cluster]
564
        mul     [ebp+NTFS.sectors_per_cluster]
565
        xchg    eax, ecx
565
        xchg    eax, ecx
566
        mul     [ebp+NTFS.sectors_per_cluster]
566
        mul     [ebp+NTFS.sectors_per_cluster]
567
        sub     ecx, ebx
567
        sub     ecx, ebx
568
        add     eax, ebx
568
        add     eax, ebx
569
        mov     ebx, [ebp+NTFS.cur_buf]
569
        mov     ebx, [ebp+NTFS.cur_buf]
570
        cmp     ecx, [ebp+NTFS.cur_size]
570
        cmp     ecx, [ebp+NTFS.cur_size]
571
        jb      @f
571
        jb      @f
572
        mov     ecx, [ebp+NTFS.cur_size]
572
        mov     ecx, [ebp+NTFS.cur_size]
573
@@:
573
@@:
574
        mov     [ebp+NTFS.LastRead], eax
574
        mov     [ebp+NTFS.LastRead], eax
575
        mov     edi, ecx
575
        mov     edi, ecx
576
        call    fs_read64_sys
576
        call    fs_read64_sys
577
        test    eax, eax
577
        test    eax, eax
578
        jnz     .errret
578
        jnz     .errret
579
        sub     [ebp+NTFS.cur_size], edi
579
        sub     [ebp+NTFS.cur_size], edi
580
        add     [ebp+NTFS.cur_offs], edi
580
        add     [ebp+NTFS.cur_offs], edi
581
        shl     edi, 9
581
        shl     edi, 9
582
        add     [ebp+NTFS.cur_read], edi
582
        add     [ebp+NTFS.cur_read], edi
583
        add     [ebp+NTFS.cur_buf], edi
583
        add     [ebp+NTFS.cur_buf], edi
584
        inc     [ebp+NTFS.fragmentCount]
584
        inc     [ebp+NTFS.fragmentCount]
585
        xor     eax, eax
585
        xor     eax, eax
586
        xor     ebx, ebx
586
        xor     ebx, ebx
587
        cmp     [ebp+NTFS.cur_size], eax
587
        cmp     [ebp+NTFS.cur_size], eax
588
        jz      @f
588
        jz      @f
589
        jmp     .mftscan
589
        jmp     .mftscan
590
 
590
 
591
.errret2_pop:
591
.errret2_pop:
592
        xor     eax, eax
592
        xor     eax, eax
593
.errret_pop:
593
.errret_pop:
594
        pop     ecx
594
        pop     ecx
595
        pop     ecx
595
        pop     ecx
596
.errret:
596
.errret:
597
        mov     [esp+28], eax
597
        mov     [esp+28], eax
598
        stc
598
        stc
599
@@:
599
@@:
600
        popad
600
        popad
601
        ret
601
        ret
602
 
602
 
603
.nomft:
603
.nomft:
604
; 1. Read file record.
604
; 1. Read file record.
605
; N.B. This will do recursive call of read_attr for $MFT::$Data.
605
; N.B. This will do recursive call of read_attr for $MFT::$Data.
606
        mov     eax, [ebp+NTFS.cur_iRecord]
606
        mov     eax, [ebp+NTFS.cur_iRecord]
607
        and     [ebp+NTFS.attr_list], 0
607
        and     [ebp+NTFS.attr_list], 0
608
        or      dword [ebp+NTFS.attr_size+4], -1
608
        or      dword [ebp+NTFS.attr_size+4], -1
609
        or      [ebp+NTFS.attr_iBaseRecord], -1
609
        or      [ebp+NTFS.attr_iBaseRecord], -1
610
        call    ntfs_read_file_record
610
        call    ntfs_read_file_record
611
        jc      .errret
611
        jc      .errret
612
; 2. Find required attribute.
612
; 2. Find required attribute.
613
        mov     eax, [ebp+NTFS.frs_buffer]
613
        mov     eax, [ebp+NTFS.frs_buffer]
614
; a) For auxiliary records, read base record.
614
; a) For auxiliary records, read base record.
615
; If base record is present, base iRecord may be 0 (for $Mft),
615
; If base record is present, base iRecord may be 0 (for $Mft),
616
; but SequenceNumber is nonzero.
616
; but SequenceNumber is nonzero.
617
        cmp     word [eax+baseRecordReuse], 0
617
        cmp     word [eax+baseRecordReuse], 0
618
        jz      @f
618
        jz      @f
619
        mov     eax, [eax+baseRecordReference]
619
        mov     eax, [eax+baseRecordReference]
620
.beginfindattr:
620
.beginfindattr:
621
        call    ntfs_read_file_record
621
        call    ntfs_read_file_record
622
        jc      .errret
622
        jc      .errret
623
        jmp     @f
623
        jmp     @f
624
 
624
 
625
.newAttribute:
625
.newAttribute:
626
        pushad
626
        pushad
627
        and     [ebp+NTFS.cur_read], 0
627
        and     [ebp+NTFS.cur_read], 0
628
@@:
628
@@:
629
; b) Scan for required attribute and for $ATTR_LIST
629
; b) Scan for required attribute and for $ATTR_LIST
630
        mov     eax, [ebp+NTFS.frs_buffer]
630
        mov     eax, [ebp+NTFS.frs_buffer]
631
        movzx   ecx, word [eax+attributeOffset]
631
        movzx   ecx, word [eax+attributeOffset]
632
        add     eax, ecx
632
        add     eax, ecx
633
        mov     ecx, [ebp+NTFS.cur_attr]
633
        mov     ecx, [ebp+NTFS.cur_attr]
634
        and     [ebp+NTFS.attr_offs], 0
634
        and     [ebp+NTFS.attr_offs], 0
635
.scanattr:
635
.scanattr:
636
        cmp     dword [eax], -1
636
        cmp     dword [eax], -1
637
        jz      .scandone
637
        jz      .scandone
638
        cmp     dword [eax], ecx
638
        cmp     dword [eax], ecx
639
        jz      .okattr
639
        jz      .okattr
640
        cmp     [ebp+NTFS.attr_iBaseRecord], -1
640
        cmp     [ebp+NTFS.attr_iBaseRecord], -1
641
        jnz     .scancont
641
        jnz     .scancont
642
        cmp     dword [eax], 0x20       ; $ATTR_LIST
642
        cmp     dword [eax], 0x20       ; $ATTR_LIST
643
        jnz     .scancont
643
        jnz     .scancont
644
        mov     [ebp+NTFS.attr_list], eax
644
        mov     [ebp+NTFS.attr_list], eax
645
        jmp     .scancont
645
        jmp     .scancont
646
 
646
 
647
.okattr:
647
.okattr:
648
; ignore named $DATA attributes (aka NTFS streams)
648
; ignore named $DATA attributes (aka NTFS streams)
649
        cmp     ecx, 0x80
649
        cmp     ecx, 0x80
650
        jnz     @f
650
        jnz     @f
651
        cmp     byte [eax+nameLength], 0
651
        cmp     byte [eax+nameLength], 0
652
        jnz     .scancont
652
        jnz     .scancont
653
@@:
653
@@:
654
        mov     [ebp+NTFS.attr_offs], eax
654
        mov     [ebp+NTFS.attr_offs], eax
655
.scancont:
655
.scancont:
656
        add     eax, [eax+sizeWithHeader]
656
        add     eax, [eax+sizeWithHeader]
657
        jmp     .scanattr
657
        jmp     .scanattr
658
 
658
 
659
.continue:
659
.continue:
660
        pushad
660
        pushad
661
        and     [ebp+NTFS.cur_read], 0
661
        and     [ebp+NTFS.cur_read], 0
662
.scandone:
662
.scandone:
663
; c) Check for required offset and length
663
; c) Check for required offset and length
664
        mov     ecx, [ebp+NTFS.attr_offs]
664
        mov     ecx, [ebp+NTFS.attr_offs]
665
        jecxz   .noattr
665
        jecxz   .noattr
666
        push    [ebp+NTFS.cur_size]
666
        push    [ebp+NTFS.cur_size]
667
        push    [ebp+NTFS.cur_read]
667
        push    [ebp+NTFS.cur_read]
668
        call    .doreadattr
668
        call    .doreadattr
669
        pop     edx
669
        pop     edx
670
        pop     ecx
670
        pop     ecx
671
        jc      .ret
671
        jc      .ret
672
        cmp     [ebp+NTFS.bCanContinue], 0
672
        cmp     [ebp+NTFS.bCanContinue], 0
673
        jz      .ret
673
        jz      .ret
674
        sub     edx, [ebp+NTFS.cur_read]
674
        sub     edx, [ebp+NTFS.cur_read]
675
        neg     edx
675
        neg     edx
676
        shr     edx, 9
676
        shr     edx, 9
677
        sub     ecx, edx
677
        sub     ecx, edx
678
        mov     [ebp+NTFS.cur_size], ecx
678
        mov     [ebp+NTFS.cur_size], ecx
679
        jz      .ret
679
        jz      .ret
680
.noattr:
680
.noattr:
681
        cmp     [ebp+NTFS.cur_attr], 0x20
681
        cmp     [ebp+NTFS.cur_attr], 0x20
682
        jz      @f
682
        jz      @f
683
        mov     ecx, [ebp+NTFS.attr_list]
683
        mov     ecx, [ebp+NTFS.attr_list]
684
        test    ecx, ecx
684
        test    ecx, ecx
685
        jnz     .lookattr
685
        jnz     .lookattr
686
        and     dword [esp+28], 0
686
        and     dword [esp+28], 0
687
        cmp     [ebp+NTFS.attr_offs], 1     ; define CF
687
        cmp     [ebp+NTFS.attr_offs], 1     ; define CF
688
.ret:
688
.ret:
689
        popad
689
        popad
690
        ret
690
        ret
691
 
691
 
692
.lookattr:
692
.lookattr:
693
; required attribute or required offset was not found in base record;
693
; required attribute or required offset was not found in base record;
694
; it may be present in auxiliary records;
694
; it may be present in auxiliary records;
695
; scan $ATTR_LIST
695
; scan $ATTR_LIST
696
        mov     eax, [ebp+NTFS.attr_iBaseRecord]
696
        mov     eax, [ebp+NTFS.attr_iBaseRecord]
697
        cmp     eax, -1
697
        cmp     eax, -1
698
        jz      @f
698
        jz      @f
699
        call    ntfs_read_file_record
699
        call    ntfs_read_file_record
700
        jc      .errret
700
        jc      .errret
701
        or      [ebp+NTFS.attr_iBaseRecord], -1
701
        or      [ebp+NTFS.attr_iBaseRecord], -1
702
@@:
702
@@:
703
        push    [ebp+NTFS.cur_offs]
703
        push    [ebp+NTFS.cur_offs]
704
        push    [ebp+NTFS.cur_size]
704
        push    [ebp+NTFS.cur_size]
705
        push    [ebp+NTFS.cur_read]
705
        push    [ebp+NTFS.cur_read]
706
        push    [ebp+NTFS.cur_buf]
706
        push    [ebp+NTFS.cur_buf]
707
        push    dword [ebp+NTFS.attr_size]
707
        push    dword [ebp+NTFS.attr_size]
708
        push    dword [ebp+NTFS.attr_size+4]
708
        push    dword [ebp+NTFS.attr_size+4]
709
        or      dword [ebp+NTFS.attr_size+4], -1
709
        or      dword [ebp+NTFS.attr_size+4], -1
710
        and     [ebp+NTFS.cur_offs], 0
710
        and     [ebp+NTFS.cur_offs], 0
711
        mov     [ebp+NTFS.cur_size], 2
711
        mov     [ebp+NTFS.cur_size], 2
712
        and     [ebp+NTFS.cur_read], 0
712
        and     [ebp+NTFS.cur_read], 0
713
        lea     eax, [ebp+NTFS.attrlist_buf]
713
        lea     eax, [ebp+NTFS.attrlist_buf]
714
        cmp     [ebp+NTFS.cur_iRecord], 0
714
        cmp     [ebp+NTFS.cur_iRecord], 0
715
        jnz     @f
715
        jnz     @f
716
        lea     eax, [ebp+NTFS.attrlist_mft_buf]
716
        lea     eax, [ebp+NTFS.attrlist_mft_buf]
717
@@:
717
@@:
718
        mov     [ebp+NTFS.cur_buf], eax
718
        mov     [ebp+NTFS.cur_buf], eax
719
        push    eax
719
        push    eax
720
        call    .doreadattr
720
        call    .doreadattr
721
        pop     esi
721
        pop     esi
722
        mov     edx, 1
722
        mov     edx, 1
723
        pop     dword [ebp+NTFS.attr_size+4]
723
        pop     dword [ebp+NTFS.attr_size+4]
724
        pop     dword [ebp+NTFS.attr_size]
724
        pop     dword [ebp+NTFS.attr_size]
725
        mov     ecx, [ebp+NTFS.cur_read]
725
        mov     ecx, [ebp+NTFS.cur_read]
726
        pop     [ebp+NTFS.cur_buf]
726
        pop     [ebp+NTFS.cur_buf]
727
        pop     [ebp+NTFS.cur_read]
727
        pop     [ebp+NTFS.cur_read]
728
        pop     [ebp+NTFS.cur_size]
728
        pop     [ebp+NTFS.cur_size]
729
        pop     [ebp+NTFS.cur_offs]
729
        pop     [ebp+NTFS.cur_offs]
730
        jc      .errret
730
        jc      .errret
731
        or      edi, -1
731
        or      edi, -1
732
        lea     ecx, [ecx+esi-1Ah]
732
        lea     ecx, [ecx+esi-1Ah]
733
.scanliststart:
733
.scanliststart:
734
        push    ecx
734
        push    ecx
735
        mov     eax, [ebp+NTFS.cur_attr]
735
        mov     eax, [ebp+NTFS.cur_attr]
736
.scanlist:
736
.scanlist:
737
        cmp     esi, [esp]
737
        cmp     esi, [esp]
738
        jae     .scanlistdone
738
        jae     .scanlistdone
739
        cmp     eax, [esi]
739
        cmp     eax, [esi]
740
        jz      @f
740
        jz      @f
741
.scanlistcont:
741
.scanlistcont:
742
        movzx   ecx, word [esi+4]
742
        movzx   ecx, word [esi+4]
743
        add     esi, ecx
743
        add     esi, ecx
744
        jmp     .scanlist
744
        jmp     .scanlist
745
 
745
 
746
@@:
746
@@:
747
; ignore named $DATA attributes (aka NTFS streams)
747
; ignore named $DATA attributes (aka NTFS streams)
748
        cmp     eax, 0x80
748
        cmp     eax, 0x80
749
        jnz     @f
749
        jnz     @f
750
        cmp     byte [esi+6], 0
750
        cmp     byte [esi+6], 0
751
        jnz     .scanlistcont
751
        jnz     .scanlistcont
752
@@:
752
@@:
753
        push    eax
753
        push    eax
754
        mov     eax, [esi+8]
754
        mov     eax, [esi+8]
755
        test    eax, eax
755
        test    eax, eax
756
        jnz     .testf
756
        jnz     .testf
757
        cmp     dword [ebp+NTFS.attr_size+4], -1
757
        cmp     dword [ebp+NTFS.attr_size+4], -1
758
        jnz     .testfz
758
        jnz     .testfz
759
; if attribute is in auxiliary records, its size is defined only in first
759
; if attribute is in auxiliary records, its size is defined only in first
760
        mov     eax, [esi+10h]
760
        mov     eax, [esi+10h]
761
        call    ntfs_read_file_record
761
        call    ntfs_read_file_record
762
        jc      .errret_pop
762
        jc      .errret_pop
763
        mov     eax, [ebp+NTFS.frs_buffer]
763
        mov     eax, [ebp+NTFS.frs_buffer]
764
        movzx   ecx, word [eax+14h]
764
        movzx   ecx, word [eax+14h]
765
        add     eax, ecx
765
        add     eax, ecx
766
        mov     ecx, [ebp+NTFS.cur_attr]
766
        mov     ecx, [ebp+NTFS.cur_attr]
767
@@:
767
@@:
768
        cmp     dword [eax], -1
768
        cmp     dword [eax], -1
769
        jz      .errret2_pop
769
        jz      .errret2_pop
770
        cmp     dword [eax], ecx
770
        cmp     dword [eax], ecx
771
        jz      @f
771
        jz      @f
772
.l1:
772
.l1:
773
        add     eax, [eax+4]
773
        add     eax, [eax+4]
774
        jmp     @b
774
        jmp     @b
775
 
775
 
776
@@:
776
@@:
777
        cmp     eax, 0x80
777
        cmp     eax, 0x80
778
        jnz     @f
778
        jnz     @f
779
        cmp     byte [eax+9], 0
779
        cmp     byte [eax+9], 0
780
        jnz     .l1
780
        jnz     .l1
781
@@:
781
@@:
782
        cmp     byte [eax+8], 0
782
        cmp     byte [eax+8], 0
783
        jnz     .sdnores
783
        jnz     .sdnores
784
        mov     eax, [eax+10h]
784
        mov     eax, [eax+10h]
785
        mov     dword [ebp+NTFS.attr_size], eax
785
        mov     dword [ebp+NTFS.attr_size], eax
786
        and     dword [ebp+NTFS.attr_size+4], 0
786
        and     dword [ebp+NTFS.attr_size+4], 0
787
        jmp     .testfz
787
        jmp     .testfz
788
 
788
 
789
.sdnores:
789
.sdnores:
790
        mov     ecx, [eax+30h]
790
        mov     ecx, [eax+30h]
791
        mov     dword [ebp+NTFS.attr_size], ecx
791
        mov     dword [ebp+NTFS.attr_size], ecx
792
        mov     ecx, [eax+34h]
792
        mov     ecx, [eax+34h]
793
        mov     dword [ebp+NTFS.attr_size+4], ecx
793
        mov     dword [ebp+NTFS.attr_size+4], ecx
794
.testfz:
794
.testfz:
795
        xor     eax, eax
795
        xor     eax, eax
796
.testf:
796
.testf:
797
        imul    eax, [ebp+NTFS.sectors_per_cluster]
797
        imul    eax, [ebp+NTFS.sectors_per_cluster]
798
        cmp     eax, [ebp+NTFS.cur_offs]
798
        cmp     eax, [ebp+NTFS.cur_offs]
799
        pop     eax
799
        pop     eax
800
        ja      @f
800
        ja      @f
801
        mov     edi, [esi+10h]  ; keep previous iRecord
801
        mov     edi, [esi+10h]  ; keep previous iRecord
802
        jmp     .scanlistcont
802
        jmp     .scanlistcont
803
 
803
 
804
@@:
804
@@:
805
        pop     ecx
805
        pop     ecx
806
.scanlistfound:
806
.scanlistfound:
807
        cmp     edi, -1
807
        cmp     edi, -1
808
        jz      .ret
808
        jz      .ret
809
        mov     eax, [ebp+NTFS.cur_iRecord]
809
        mov     eax, [ebp+NTFS.cur_iRecord]
810
        mov     [ebp+NTFS.attr_iBaseRecord], eax
810
        mov     [ebp+NTFS.attr_iBaseRecord], eax
811
        mov     eax, edi
811
        mov     eax, edi
812
        jmp     .beginfindattr
812
        jmp     .beginfindattr
813
 
813
 
814
.scanlistdone:
814
.scanlistdone:
815
        pop     ecx
815
        pop     ecx
816
        sub     ecx, ebp
816
        sub     ecx, ebp
817
        sub     ecx, NTFS.attrlist_buf-1Ah
817
        sub     ecx, NTFS.attrlist_buf-1Ah
818
        cmp     [ebp+NTFS.cur_iRecord], 0
818
        cmp     [ebp+NTFS.cur_iRecord], 0
819
        jnz     @f
819
        jnz     @f
820
        sub     ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
820
        sub     ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
821
@@:
821
@@:
822
        cmp     ecx, 0x400
822
        cmp     ecx, 0x400
823
        jnz     .scanlistfound
823
        jnz     .scanlistfound
824
        inc     edx
824
        inc     edx
825
        push    esi edi
825
        push    esi edi
826
        lea     esi, [ebp+NTFS.attrlist_buf+0x200]
826
        lea     esi, [ebp+NTFS.attrlist_buf+0x200]
827
        lea     edi, [ebp+NTFS.attrlist_buf]
827
        lea     edi, [ebp+NTFS.attrlist_buf]
828
        cmp     [ebp+NTFS.cur_iRecord], 0
828
        cmp     [ebp+NTFS.cur_iRecord], 0
829
        jnz     @f
829
        jnz     @f
830
        lea     esi, [ebp+NTFS.attrlist_mft_buf+0x200]
830
        lea     esi, [ebp+NTFS.attrlist_mft_buf+0x200]
831
        lea     edi, [ebp+NTFS.attrlist_mft_buf]
831
        lea     edi, [ebp+NTFS.attrlist_mft_buf]
832
@@:
832
@@:
833
        mov     ecx, 0x200/4
833
        mov     ecx, 0x200/4
834
        rep movsd
834
        rep movsd
835
        mov     eax, edi
835
        mov     eax, edi
836
        pop     edi esi
836
        pop     edi esi
837
        sub     esi, 0x200
837
        sub     esi, 0x200
838
        push    [ebp+NTFS.cur_offs]
838
        push    [ebp+NTFS.cur_offs]
839
        push    [ebp+NTFS.cur_size]
839
        push    [ebp+NTFS.cur_size]
840
        push    [ebp+NTFS.cur_read]
840
        push    [ebp+NTFS.cur_read]
841
        push    [ebp+NTFS.cur_buf]
841
        push    [ebp+NTFS.cur_buf]
842
        push    dword [ebp+NTFS.attr_size]
842
        push    dword [ebp+NTFS.attr_size]
843
        push    dword [ebp+NTFS.attr_size+4]
843
        push    dword [ebp+NTFS.attr_size+4]
844
        or      dword [ebp+NTFS.attr_size+4], -1
844
        or      dword [ebp+NTFS.attr_size+4], -1
845
        mov     [ebp+NTFS.cur_offs], edx
845
        mov     [ebp+NTFS.cur_offs], edx
846
        mov     [ebp+NTFS.cur_size], 1
846
        mov     [ebp+NTFS.cur_size], 1
847
        and     [ebp+NTFS.cur_read], 0
847
        and     [ebp+NTFS.cur_read], 0
848
        mov     [ebp+NTFS.cur_buf], eax
848
        mov     [ebp+NTFS.cur_buf], eax
849
        mov     ecx, [ebp+NTFS.attr_list]
849
        mov     ecx, [ebp+NTFS.attr_list]
850
        push    esi edx edi
850
        push    esi edx edi
851
        call    .doreadattr
851
        call    .doreadattr
852
        pop     edi edx esi
852
        pop     edi edx esi
853
        mov     ecx, [ebp+NTFS.cur_read]
853
        mov     ecx, [ebp+NTFS.cur_read]
854
        pop     dword [ebp+NTFS.attr_size+4]
854
        pop     dword [ebp+NTFS.attr_size+4]
855
        pop     dword [ebp+NTFS.attr_size]
855
        pop     dword [ebp+NTFS.attr_size]
856
        pop     [ebp+NTFS.cur_buf]
856
        pop     [ebp+NTFS.cur_buf]
857
        pop     [ebp+NTFS.cur_read]
857
        pop     [ebp+NTFS.cur_read]
858
        pop     [ebp+NTFS.cur_size]
858
        pop     [ebp+NTFS.cur_size]
859
        pop     [ebp+NTFS.cur_offs]
859
        pop     [ebp+NTFS.cur_offs]
860
        jc      .errret
860
        jc      .errret
861
        lea     ecx, [ecx+ebp+NTFS.attrlist_buf+0x200-0x1A]
861
        lea     ecx, [ecx+ebp+NTFS.attrlist_buf+0x200-0x1A]
862
        cmp     [ebp+NTFS.cur_iRecord], 0
862
        cmp     [ebp+NTFS.cur_iRecord], 0
863
        jnz     .scanliststart
863
        jnz     .scanliststart
864
        add     ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
864
        add     ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
865
        jmp     .scanliststart
865
        jmp     .scanliststart
866
 
866
 
867
.doreadattr:
867
.doreadattr:
868
        mov     [ebp+NTFS.bCanContinue], 0
868
        mov     [ebp+NTFS.bCanContinue], 0
869
        cmp     byte [ecx+nonResidentFlag], 0
869
        cmp     byte [ecx+nonResidentFlag], 0
870
        jnz     .nonresident
870
        jnz     .nonresident
871
        mov     eax, [ecx+sizeWithoutHeader]
871
        mov     eax, [ecx+sizeWithoutHeader]
872
        mov     esi, eax
872
        mov     esi, eax
873
        mov     edx, [ebp+NTFS.cur_offs]
873
        mov     edx, [ebp+NTFS.cur_offs]
874
        shr     eax, 9
874
        shr     eax, 9
875
        cmp     eax, edx
875
        cmp     eax, edx
876
        jb      .okret
876
        jb      .okret
877
        shl     edx, 9
877
        shl     edx, 9
878
        sub     esi, edx
878
        sub     esi, edx
879
        movzx   eax, word [ecx+attributeOffset]
879
        movzx   eax, word [ecx+attributeOffset]
880
        add     edx, eax
880
        add     edx, eax
881
        add     edx, ecx        ; edx -> data
881
        add     edx, ecx        ; edx -> data
882
        mov     eax, [ebp+NTFS.cur_size]
882
        mov     eax, [ebp+NTFS.cur_size]
883
        cmp     eax, (0xFFFFFFFF shr 9)+1
883
        cmp     eax, (0xFFFFFFFF shr 9)+1
884
        jbe     @f
884
        jbe     @f
885
        mov     eax, (0xFFFFFFFF shr 9)+1
885
        mov     eax, (0xFFFFFFFF shr 9)+1
886
@@:
886
@@:
887
        shl     eax, 9
887
        shl     eax, 9
888
        cmp     eax, esi
888
        cmp     eax, esi
889
        jbe     @f
889
        jbe     @f
890
        mov     eax, esi
890
        mov     eax, esi
891
@@:
891
@@:
892
; eax = length, edx -> data
892
; eax = length, edx -> data
893
        mov     [ebp+NTFS.cur_read], eax
893
        mov     [ebp+NTFS.cur_read], eax
894
        mov     ecx, eax
894
        mov     ecx, eax
895
        mov     eax, edx
895
        mov     eax, edx
896
        mov     ebx, [ebp+NTFS.cur_buf]
896
        mov     ebx, [ebp+NTFS.cur_buf]
897
        call    memmove
897
        call    memmove
898
        and     [ebp+NTFS.cur_size], 0      ; CF=0
898
        and     [ebp+NTFS.cur_size], 0      ; CF=0
899
        ret
899
        ret
900
 
900
 
901
.nonresident:
901
.nonresident:
902
; Not all auxiliary records contain correct FileSize info
902
; Not all auxiliary records contain correct FileSize info
903
        mov     eax, dword [ebp+NTFS.attr_size]
903
        mov     eax, dword [ebp+NTFS.attr_size]
904
        mov     edx, dword [ebp+NTFS.attr_size+4]
904
        mov     edx, dword [ebp+NTFS.attr_size+4]
905
        cmp     edx, -1
905
        cmp     edx, -1
906
        jnz     @f
906
        jnz     @f
907
        mov     eax, [ecx+attributeRealSize]
907
        mov     eax, [ecx+attributeRealSize]
908
        mov     edx, [ecx+attributeRealSize+4]
908
        mov     edx, [ecx+attributeRealSize+4]
909
        mov     dword [ebp+NTFS.attr_size], eax
909
        mov     dword [ebp+NTFS.attr_size], eax
910
        mov     dword [ebp+NTFS.attr_size+4], edx
910
        mov     dword [ebp+NTFS.attr_size+4], edx
911
@@:
911
@@:
912
        add     eax, 0x1FF
912
        add     eax, 0x1FF
913
        adc     edx, 0
913
        adc     edx, 0
914
        shrd    eax, edx, 9
914
        shrd    eax, edx, 9
915
        sub     eax, [ebp+NTFS.cur_offs]
915
        sub     eax, [ebp+NTFS.cur_offs]
916
        ja      @f
916
        ja      @f
917
; return with nothing read
917
; return with nothing read
918
        and     [ebp+NTFS.cur_size], 0
918
        and     [ebp+NTFS.cur_size], 0
919
.okret:
919
.okret:
920
        clc
920
        clc
921
        ret
921
        ret
922
 
922
 
923
@@:
923
@@:
924
; reduce read length
924
; reduce read length
925
        and     [ebp+NTFS.cur_tail], 0
925
        and     [ebp+NTFS.cur_tail], 0
926
        cmp     [ebp+NTFS.cur_size], eax
926
        cmp     [ebp+NTFS.cur_size], eax
927
        jb      @f
927
        jb      @f
928
        mov     [ebp+NTFS.cur_size], eax
928
        mov     [ebp+NTFS.cur_size], eax
929
        mov     eax, dword [ebp+NTFS.attr_size]
929
        mov     eax, dword [ebp+NTFS.attr_size]
930
        and     eax, 0x1FF
930
        and     eax, 0x1FF
931
        mov     [ebp+NTFS.cur_tail], eax
931
        mov     [ebp+NTFS.cur_tail], eax
932
@@:
932
@@:
933
        mov     eax, [ebp+NTFS.cur_offs]
933
        mov     eax, [ebp+NTFS.cur_offs]
934
        xor     edx, edx
934
        xor     edx, edx
935
        div     [ebp+NTFS.sectors_per_cluster]
935
        div     [ebp+NTFS.sectors_per_cluster]
936
        sub     eax, [ecx+firstVCN]
936
        sub     eax, [ecx+firstVCN]
937
        jb      .okret
937
        jb      .okret
938
        mov     ebx, edx
938
        mov     ebx, edx
939
; eax = starting cluster, ebx = sector in the cluster
939
; eax = starting cluster, ebx = sector in the cluster
940
        cmp     [ebp+NTFS.cur_attr], 0x80
940
        cmp     [ebp+NTFS.cur_attr], 0x80
941
        jnz     .sys
941
        jnz     .sys
942
        cmp     [ebp+NTFS.cur_iRecord], 0
942
        cmp     [ebp+NTFS.cur_iRecord], 0
943
        jz      .sys
943
        jz      .sys
944
        push    fs_read64_app
944
        push    fs_read64_app
945
        cmp     [ebp+NTFS.bWriteAttr], 1
945
        cmp     [ebp+NTFS.bWriteAttr], 1
946
        jnz     @f
946
        jnz     @f
947
        mov     dword[esp], fs_write64_app
947
        mov     dword[esp], fs_write64_app
948
        jmp     @f
948
        jmp     @f
949
 
949
 
950
.sys:
950
.sys:
951
        push    fs_read64_sys
951
        push    fs_read64_sys
952
@@:
952
@@:
953
        sub     esp, 10h
953
        sub     esp, 10h
954
        movzx   esi, word [ecx+dataRunsOffset]
954
        movzx   esi, word [ecx+dataRunsOffset]
955
        add     esi, ecx
955
        add     esi, ecx
956
        xor     edi, edi
956
        xor     edi, edi
957
        mov     [ebp+NTFS.fragmentCount], 0
957
        mov     [ebp+NTFS.fragmentCount], 0
958
.readloop:
958
.readloop:
959
        call    ntfs_decode_mcb_entry
959
        call    ntfs_decode_mcb_entry
960
        jnc     .break
960
        jnc     .break
961
        add     edi, [esp+8]
961
        add     edi, [esp+8]
962
        sub     eax, [esp]
962
        sub     eax, [esp]
963
        jae     .readloop
963
        jae     .readloop
964
        mov     ecx, edi
964
        mov     ecx, edi
965
        add     ecx, eax
965
        add     ecx, eax
966
        add     ecx, [esp]
966
        add     ecx, [esp]
967
        neg     eax
967
        neg     eax
968
        mul     [ebp+NTFS.sectors_per_cluster]
968
        mul     [ebp+NTFS.sectors_per_cluster]
969
        xchg    eax, ecx
969
        xchg    eax, ecx
970
        mul     [ebp+NTFS.sectors_per_cluster]
970
        mul     [ebp+NTFS.sectors_per_cluster]
971
        sub     ecx, ebx
971
        sub     ecx, ebx
972
        add     eax, ebx
972
        add     eax, ebx
973
        mov     ebx, [ebp+NTFS.cur_buf]
973
        mov     ebx, [ebp+NTFS.cur_buf]
974
        cmp     ecx, [ebp+NTFS.cur_size]
974
        cmp     ecx, [ebp+NTFS.cur_size]
975
        jb      @f
975
        jb      @f
976
        mov     ecx, [ebp+NTFS.cur_size]
976
        mov     ecx, [ebp+NTFS.cur_size]
977
@@:
977
@@:
978
        mov     [ebp+NTFS.LastRead], eax
978
        mov     [ebp+NTFS.LastRead], eax
979
        push    ecx
979
        push    ecx
980
        call    dword[esp+14h]
980
        call    dword[esp+14h]
981
        pop     ecx
981
        pop     ecx
982
        test    eax, eax
982
        test    eax, eax
983
        jnz     .errread2
983
        jnz     .errread2
984
        sub     [ebp+NTFS.cur_size], ecx
984
        sub     [ebp+NTFS.cur_size], ecx
985
        add     [ebp+NTFS.cur_offs], ecx
985
        add     [ebp+NTFS.cur_offs], ecx
986
        shl     ecx, 9
986
        shl     ecx, 9
987
        add     [ebp+NTFS.cur_read], ecx
987
        add     [ebp+NTFS.cur_read], ecx
988
        add     [ebp+NTFS.cur_buf], ecx
988
        add     [ebp+NTFS.cur_buf], ecx
989
        inc     [ebp+NTFS.fragmentCount]
989
        inc     [ebp+NTFS.fragmentCount]
990
        xor     eax, eax
990
        xor     eax, eax
991
        xor     ebx, ebx
991
        xor     ebx, ebx
992
        cmp     [ebp+NTFS.cur_size], 0
992
        cmp     [ebp+NTFS.cur_size], 0
993
        jnz     .readloop
993
        jnz     .readloop
994
        add     esp, 14h
994
        add     esp, 14h
995
        mov     eax, [ebp+NTFS.cur_tail]
995
        mov     eax, [ebp+NTFS.cur_tail]
996
        test    eax, eax
996
        test    eax, eax
997
        jz      @f
997
        jz      @f
998
        sub     eax, 0x200
998
        sub     eax, 0x200
999
        add     [ebp+NTFS.cur_read], eax
999
        add     [ebp+NTFS.cur_read], eax
1000
@@:
1000
@@:
1001
        clc
1001
        clc
1002
        ret
1002
        ret
1003
 
1003
 
1004
.errread2:
1004
.errread2:
1005
        add     esp, 14h
1005
        add     esp, 14h
1006
        stc
1006
        stc
1007
        ret
1007
        ret
1008
 
1008
 
1009
.break:
1009
.break:
1010
        add     esp, 14h        ; CF=0
1010
        add     esp, 14h        ; CF=0
1011
        mov     [ebp+NTFS.bCanContinue], 1
1011
        mov     [ebp+NTFS.bCanContinue], 1
1012
        ret
1012
        ret
1013
 
1013
 
1014
ntfs_read_file_record:
1014
ntfs_read_file_record:
1015
; in: eax = iRecord
1015
; in: eax = iRecord
1016
; out: [ebp+NTFS.frs_buffer] -> file record
1016
; out: [ebp+NTFS.frs_buffer] -> file record
1017
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
1017
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
1018
    ; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
1018
    ; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
1019
        push    ecx edx
1019
        push    ecx edx
1020
        mov     ecx, [ebp+NTFS.frs_size]
1020
        mov     ecx, [ebp+NTFS.frs_size]
1021
        mul     ecx
1021
        mul     ecx
1022
        shrd    eax, edx, 9
1022
        shrd    eax, edx, 9
1023
        shr     edx, 9
1023
        shr     edx, 9
1024
        jnz     .errret
1024
        jnz     .errret
1025
        push    [ebp+NTFS.attr_iBaseRecord]
1025
        push    [ebp+NTFS.attr_iBaseRecord]
1026
        push    [ebp+NTFS.attr_offs]
1026
        push    [ebp+NTFS.attr_offs]
1027
        push    [ebp+NTFS.attr_list]
1027
        push    [ebp+NTFS.attr_list]
1028
        push    dword [ebp+NTFS.attr_size+4]
1028
        push    dword [ebp+NTFS.attr_size+4]
1029
        push    dword [ebp+NTFS.attr_size]
1029
        push    dword [ebp+NTFS.attr_size]
1030
        push    [ebp+NTFS.cur_iRecord]
1030
        push    [ebp+NTFS.cur_iRecord]
1031
        push    [ebp+NTFS.cur_attr]
1031
        push    [ebp+NTFS.cur_attr]
1032
        push    [ebp+NTFS.cur_offs]
1032
        push    [ebp+NTFS.cur_offs]
1033
        push    [ebp+NTFS.cur_size]
1033
        push    [ebp+NTFS.cur_size]
1034
        push    [ebp+NTFS.cur_buf]
1034
        push    [ebp+NTFS.cur_buf]
1035
        push    [ebp+NTFS.cur_read]
1035
        push    [ebp+NTFS.cur_read]
1036
        mov     [ebp+NTFS.cur_attr], 0x80   ; $DATA
1036
        mov     [ebp+NTFS.cur_attr], 0x80   ; $DATA
1037
        and     [ebp+NTFS.cur_iRecord], 0   ; $Mft
1037
        and     [ebp+NTFS.cur_iRecord], 0   ; $Mft
1038
        mov     [ebp+NTFS.cur_offs], eax
1038
        mov     [ebp+NTFS.cur_offs], eax
1039
        shr     ecx, 9
1039
        shr     ecx, 9
1040
        mov     [ebp+NTFS.cur_size], ecx
1040
        mov     [ebp+NTFS.cur_size], ecx
1041
        mov     eax, [ebp+NTFS.frs_buffer]
1041
        mov     eax, [ebp+NTFS.frs_buffer]
1042
        mov     [ebp+NTFS.cur_buf], eax
1042
        mov     [ebp+NTFS.cur_buf], eax
1043
        call    ntfs_read_attr
1043
        call    ntfs_read_attr
1044
        mov     edx, [ebp+NTFS.cur_read]
1044
        mov     edx, [ebp+NTFS.cur_read]
1045
        pop     [ebp+NTFS.cur_read]
1045
        pop     [ebp+NTFS.cur_read]
1046
        pop     [ebp+NTFS.cur_buf]
1046
        pop     [ebp+NTFS.cur_buf]
1047
        pop     [ebp+NTFS.cur_size]
1047
        pop     [ebp+NTFS.cur_size]
1048
        pop     [ebp+NTFS.cur_offs]
1048
        pop     [ebp+NTFS.cur_offs]
1049
        pop     [ebp+NTFS.cur_attr]
1049
        pop     [ebp+NTFS.cur_attr]
1050
        pop     [ebp+NTFS.cur_iRecord]
1050
        pop     [ebp+NTFS.cur_iRecord]
1051
        pop     dword [ebp+NTFS.attr_size]
1051
        pop     dword [ebp+NTFS.attr_size]
1052
        pop     dword [ebp+NTFS.attr_size+4]
1052
        pop     dword [ebp+NTFS.attr_size+4]
1053
        pop     [ebp+NTFS.attr_list]
1053
        pop     [ebp+NTFS.attr_list]
1054
        pop     [ebp+NTFS.attr_offs]
1054
        pop     [ebp+NTFS.attr_offs]
1055
        pop     [ebp+NTFS.attr_iBaseRecord]
1055
        pop     [ebp+NTFS.attr_iBaseRecord]
1056
        jc      .ret
1056
        jc      .ret
1057
        cmp     edx, [ebp+NTFS.frs_size]
1057
        cmp     edx, [ebp+NTFS.frs_size]
1058
        jnz     .errret
1058
        jnz     .errret
1059
        mov     eax, [ebp+NTFS.LastRead]
1059
        mov     eax, [ebp+NTFS.LastRead]
1060
        mov     [ebp+NTFS.mftLastRead], eax
1060
        mov     [ebp+NTFS.mftLastRead], eax
1061
        mov     eax, [ebp+NTFS.frs_buffer]
1061
        mov     eax, [ebp+NTFS.frs_buffer]
1062
        cmp     dword [eax], 'FILE'
1062
        cmp     dword [eax], 'FILE'
1063
        jnz     .errret
1063
        jnz     .errret
1064
        push    ebx
1064
        push    ebx
1065
        mov     ebx, eax
1065
        mov     ebx, eax
1066
        call    ntfs_restore_usa_frs
1066
        call    ntfs_restore_usa_frs
1067
        pop     ebx
1067
        pop     ebx
1068
        jc      .errret
1068
        jc      .errret
1069
.ret:
1069
.ret:
1070
        pop     edx ecx
1070
        pop     edx ecx
1071
        ret
1071
        ret
1072
 
1072
 
1073
.errret:
1073
.errret:
1074
        pop     edx ecx
1074
        pop     edx ecx
1075
        xor     eax, eax
1075
        xor     eax, eax
1076
        stc
1076
        stc
1077
        ret
1077
        ret
1078
 
1078
 
1079
ntfs_restore_usa_frs:
1079
ntfs_restore_usa_frs:
1080
        mov     eax, [ebp+NTFS.frs_size]
1080
        mov     eax, [ebp+NTFS.frs_size]
1081
ntfs_restore_usa:
1081
ntfs_restore_usa:
1082
;   in:
1082
;   in:
1083
; ebx -> record
1083
; ebx -> record
1084
; eax = size in bytes
1084
; eax = size in bytes
1085
        pushad
1085
        pushad
1086
        shr     eax, 9
1086
        shr     eax, 9
1087
        mov     ecx, eax
1087
        mov     ecx, eax
1088
        inc     eax
1088
        inc     eax
1089
        cmp     [ebx+updateSequenceSize], ax
1089
        cmp     [ebx+updateSequenceSize], ax
1090
        jnz     .err
1090
        jnz     .err
1091
        movzx   eax, word [ebx+updateSequenceOffset]
1091
        movzx   eax, word [ebx+updateSequenceOffset]
1092
        lea     esi, [eax+ebx]
1092
        lea     esi, [eax+ebx]
1093
        lodsw
1093
        lodsw
1094
        mov     edx, eax
1094
        mov     edx, eax
1095
        lea     edi, [ebx+0x1FE]
1095
        lea     edi, [ebx+0x1FE]
1096
@@:
1096
@@:
1097
        cmp     [edi], dx
1097
        cmp     [edi], dx
1098
        jnz     .err
1098
        jnz     .err
1099
        lodsw
1099
        lodsw
1100
        stosw
1100
        stosw
1101
        add     edi, 0x1FE
1101
        add     edi, 0x1FE
1102
        loop    @b
1102
        loop    @b
1103
        popad
1103
        popad
1104
        clc
1104
        clc
1105
        ret
1105
        ret
1106
 
1106
 
1107
.err:
1107
.err:
1108
        popad
1108
        popad
1109
        stc
1109
        stc
1110
        ret
1110
        ret
1111
 
1111
 
1112
ntfs_decode_mcb_entry:
1112
ntfs_decode_mcb_entry:
1113
;   in:
1113
;   in:
1114
; esi -> MCB entry
1114
; esi -> MCB entry
1115
; esp -> buffer (16 bytes)
1115
; esp -> buffer (16 bytes)
1116
;   out:
1116
;   out:
1117
; esi -> next MCB entry
1117
; esi -> next MCB entry
1118
; esp -> data run size
1118
; esp -> data run size
1119
; esp+8 -> cluster (delta)
1119
; esp+8 -> cluster (delta)
1120
; CF=0 -> MCB end
1120
; CF=0 -> MCB end
1121
        push    eax ecx edi
1121
        push    eax ecx edi
1122
        lea     edi, [esp+16]
1122
        lea     edi, [esp+16]
1123
        xor     eax, eax
1123
        xor     eax, eax
1124
        lodsb
1124
        lodsb
1125
        test    al, al
1125
        test    al, al
1126
        jz      .end
1126
        jz      .end
1127
        mov     ecx, eax
1127
        mov     ecx, eax
1128
        and     ecx, 0xF
1128
        and     ecx, 0xF
1129
        cmp     ecx, 8
1129
        cmp     ecx, 8
1130
        ja      .end
1130
        ja      .end
1131
        push    ecx
1131
        push    ecx
1132
        rep movsb
1132
        rep movsb
1133
        pop     ecx
1133
        pop     ecx
1134
        sub     ecx, 8
1134
        sub     ecx, 8
1135
        neg     ecx
1135
        neg     ecx
1136
        cmp     byte [esi-1], 80h
1136
        cmp     byte [esi-1], 80h
1137
        jae     .end
1137
        jae     .end
1138
        push    eax
1138
        push    eax
1139
        xor     eax, eax
1139
        xor     eax, eax
1140
        rep stosb
1140
        rep stosb
1141
        pop     ecx
1141
        pop     ecx
1142
        shr     ecx, 4
1142
        shr     ecx, 4
1143
        cmp     ecx, 8
1143
        cmp     ecx, 8
1144
        ja      .end
1144
        ja      .end
1145
        push    ecx
1145
        push    ecx
1146
        rep movsb
1146
        rep movsb
1147
        pop     ecx
1147
        pop     ecx
1148
        sub     ecx, 8
1148
        sub     ecx, 8
1149
        neg     ecx
1149
        neg     ecx
1150
        cmp     byte [esi-1], 80h
1150
        cmp     byte [esi-1], 80h
1151
        cmc
1151
        cmc
1152
        sbb     eax, eax
1152
        sbb     eax, eax
1153
        rep stosb
1153
        rep stosb
1154
        stc
1154
        stc
1155
.end:
1155
.end:
1156
        pop     edi ecx eax
1156
        pop     edi ecx eax
1157
        ret
1157
        ret
1158
 
1158
 
1159
unichar_toupper:
1159
unichar_toupper:
1160
        push    eax
1160
        push    eax
1161
        call    uni2ansi_char
1161
        call    uni2ansi_char
1162
        cmp     al, '_'
1162
        cmp     al, '_'
1163
        jz      .unk
1163
        jz      .unk
1164
        add     esp, 4
1164
        add     esp, 4
1165
        call    char_toupper
1165
        call    char_toupper
1166
        jmp     ansi2uni_char
1166
        jmp     ansi2uni_char
1167
.unk:
1167
.unk:
1168
        pop     eax
1168
        pop     eax
1169
        ret
1169
        ret
1170
 
1170
 
1171
ntfs_find_lfn:
1171
ntfs_find_lfn:
1172
; in: [esi]+[esp+4] = name
1172
; in: [esi]+[esp+4] = name
1173
;   out:
1173
;   out:
1174
; [ebp+NTFS.cur_iRecord] = target fileRecord
1174
; [ebp+NTFS.cur_iRecord] = target fileRecord
1175
; eax -> target index in the node
1175
; eax -> target index in the node
1176
; [ebp+NTFS.LastRead] = target node location
1176
; [ebp+NTFS.LastRead] = target node location
1177
; [ebp+NTFS.indexPointer] -> index, that points the target subnode
1177
; [ebp+NTFS.indexPointer] -> index, that points the target subnode
1178
; [ebp+NTFS.nodeLastRead] = branch node location
1178
; [ebp+NTFS.nodeLastRead] = branch node location
1179
; [ebp+NTFS.indexRoot] -> attribute
1179
; [ebp+NTFS.indexRoot] -> attribute
1180
; [ebp+NTFS.rootLastRead] = directory fileRecord location
1180
; [ebp+NTFS.rootLastRead] = directory fileRecord location
1181
; [ebp+NTFS.cur_size] = index record size in sectors
1181
; [ebp+NTFS.cur_size] = index record size in sectors
1182
; [ebp+NTFS.cur_subnode_size] = index record size in clusters or sectors
1182
; [ebp+NTFS.cur_subnode_size] = index record size in clusters or sectors
1183
; CF=1 -> file not found, eax=0 -> error
1183
; CF=1 -> file not found, eax=0 -> error
1184
        mov     [ebp+NTFS.cur_iRecord], 5   ; start from root directory
1184
        mov     [ebp+NTFS.cur_iRecord], 5   ; start from root directory
1185
.doit2:
1185
.doit2:
1186
        mov     [ebp+NTFS.cur_attr], 0x90   ; $INDEX_ROOT
1186
        mov     [ebp+NTFS.cur_attr], 0x90   ; $INDEX_ROOT
1187
        and     [ebp+NTFS.cur_offs], 0
1187
        and     [ebp+NTFS.cur_offs], 0
1188
        mov     eax, [ebp+NTFS.cur_index_size]
1188
        mov     eax, [ebp+NTFS.cur_index_size]
1189
        mov     [ebp+NTFS.cur_size], eax
1189
        mov     [ebp+NTFS.cur_size], eax
1190
        mov     eax, [ebp+NTFS.cur_index_buf]
1190
        mov     eax, [ebp+NTFS.cur_index_buf]
1191
        mov     [ebp+NTFS.cur_buf], eax
1191
        mov     [ebp+NTFS.cur_buf], eax
1192
        call    ntfs_read_attr
1192
        call    ntfs_read_attr
1193
        mov     eax, 0
1193
        mov     eax, 0
1194
        jc      .ret
1194
        jc      .ret
1195
        cmp     [ebp+NTFS.cur_read], 0x20
1195
        cmp     [ebp+NTFS.cur_read], 0x20
1196
        jc      .ret
1196
        jc      .ret
1197
        push    esi
1197
        push    esi
1198
        pushad
1198
        pushad
1199
        mov     esi, [ebp+NTFS.cur_index_buf]
1199
        mov     esi, [ebp+NTFS.cur_index_buf]
1200
        mov     eax, [esi+indexRecordSize]
1200
        mov     eax, [esi+indexRecordSize]
1201
        shr     eax, 9
1201
        shr     eax, 9
1202
        cmp     [ebp+NTFS.cur_index_size], eax
1202
        cmp     [ebp+NTFS.cur_index_size], eax
1203
        jc      .realloc
1203
        jc      .realloc
1204
        mov     [ebp+NTFS.cur_size], eax
1204
        mov     [ebp+NTFS.cur_size], eax
1205
        mov     al, [esi+indexRecordSizeClus]
1205
        mov     al, [esi+indexRecordSizeClus]
1206
        mov     [ebp+NTFS.cur_subnode_size], eax
1206
        mov     [ebp+NTFS.cur_subnode_size], eax
1207
        add     esi, rootNode
1207
        add     esi, rootNode
1208
        mov     eax, [esi+nodeRealSize]
1208
        mov     eax, [esi+nodeRealSize]
1209
        add     eax, rootNode
1209
        add     eax, rootNode
1210
        cmp     [ebp+NTFS.cur_read], eax
1210
        cmp     [ebp+NTFS.cur_read], eax
1211
        jc      .err
1211
        jc      .err
1212
        mov     edi, [esp+4]
1212
        mov     edi, [esp+4]
1213
        mov     eax, [ebp+NTFS.mftLastRead]
1213
        mov     eax, [ebp+NTFS.mftLastRead]
1214
        mov     [ebp+NTFS.rootLastRead], eax
1214
        mov     [ebp+NTFS.rootLastRead], eax
1215
        mov     eax, [ebp+NTFS.attr_offs]
1215
        mov     eax, [ebp+NTFS.attr_offs]
1216
        mov     [ebp+NTFS.indexRoot], eax
1216
        mov     [ebp+NTFS.indexRoot], eax
1217
; edi -> name, esi -> current index node
1217
; edi -> name, esi -> current index node
1218
.scanloop:
1218
.scanloop:
1219
        add     esi, [esi+indexOffset]
1219
        add     esi, [esi+indexOffset]
1220
.scanloopint:
1220
.scanloopint:
1221
        test    byte [esi+indexFlags], 2
1221
        test    byte [esi+indexFlags], 2
1222
        jnz     .subnode
1222
        jnz     .subnode
1223
        push    esi
1223
        push    esi
1224
        movzx   ecx, byte [esi+fileNameLength]
1224
        movzx   ecx, byte [esi+fileNameLength]
1225
        add     esi, fileName
1225
        add     esi, fileName
1226
        push    edi
1226
        push    edi
1227
@@:
1227
@@:
1228
        lodsw
1228
        lodsw
1229
        call    unichar_toupper
1229
        call    unichar_toupper
1230
        push    eax
1230
        push    eax
1231
        mov     al, [edi]
1231
        mov     al, [edi]
1232
        inc     edi
1232
        inc     edi
1233
        cmp     al, '/'
1233
        cmp     al, '/'
1234
        jz      .slash
1234
        jz      .slash
1235
        call    char_toupper
1235
        call    char_toupper
1236
        call    ansi2uni_char
1236
        call    ansi2uni_char
1237
        cmp     ax, [esp]
1237
        cmp     ax, [esp]
1238
        pop     eax
1238
        pop     eax
1239
        loopz   @b
1239
        loopz   @b
1240
        jz      .found
1240
        jz      .found
1241
        pop     edi
1241
        pop     edi
1242
        pop     esi
1242
        pop     esi
1243
        jb      .subnode
1243
        jb      .subnode
1244
.scanloopcont:
1244
.scanloopcont:
1245
        movzx   eax, word [esi+indexAllocatedSize]
1245
        movzx   eax, word [esi+indexAllocatedSize]
1246
        add     esi, eax
1246
        add     esi, eax
1247
        jmp     .scanloopint
1247
        jmp     .scanloopint
1248
 
1248
 
1249
.realloc:
1249
.realloc:
1250
        mov     edi, eax
1250
        mov     edi, eax
1251
        mov     eax, [esi+indexRecordSize]
1251
        mov     eax, [esi+indexRecordSize]
1252
        shl     eax, 1
1252
        shl     eax, 1
1253
        stdcall kernel_alloc, eax
1253
        stdcall kernel_alloc, eax
1254
        test    eax, eax
1254
        test    eax, eax
1255
        jz      .err
1255
        jz      .err
1256
        mov     edx, [ebp+NTFS.cur_index_buf]
1256
        mov     edx, [ebp+NTFS.cur_index_buf]
1257
        cmp     edx, [ebp+NTFS.secondIndexBuffer]
1257
        cmp     edx, [ebp+NTFS.secondIndexBuffer]
1258
        jc      @f
1258
        jc      @f
1259
        mov     edx, [ebp+NTFS.secondIndexBuffer]
1259
        mov     edx, [ebp+NTFS.secondIndexBuffer]
1260
@@:
1260
@@:
1261
        mov     [ebp+NTFS.cur_index_buf], eax
1261
        mov     [ebp+NTFS.cur_index_buf], eax
1262
        add     eax, [esi+indexRecordSize]
1262
        add     eax, [esi+indexRecordSize]
1263
        mov     [ebp+NTFS.secondIndexBuffer], eax
1263
        mov     [ebp+NTFS.secondIndexBuffer], eax
1264
        mov     [ebp+NTFS.cur_index_size], edi
1264
        mov     [ebp+NTFS.cur_index_size], edi
1265
        stdcall kernel_free, edx
1265
        stdcall kernel_free, edx
1266
        popad
1266
        popad
1267
        pop     eax
1267
        pop     eax
1268
        jmp     .doit2
1268
        jmp     .doit2
1269
 
1269
 
1270
.notfound:
1270
.notfound:
1271
        mov     [esp+1Ch], esi
1271
        mov     [esp+1Ch], esi
1272
.err:
1272
.err:
1273
        popad
1273
        popad
1274
        stc
1274
        stc
1275
.ret2:
1275
.ret2:
1276
        pop     esi
1276
        pop     esi
1277
.ret:
1277
.ret:
1278
        ret     4
1278
        ret     4
1279
 
1279
 
1280
.slash:
1280
.slash:
1281
        pop     eax
1281
        pop     eax
1282
        pop     edi
1282
        pop     edi
1283
        pop     esi
1283
        pop     esi
1284
.subnode:
1284
.subnode:
1285
        test    byte [esi+indexFlags], 1
1285
        test    byte [esi+indexFlags], 1
1286
        jz      .notfound
1286
        jz      .notfound
1287
        mov     eax, [ebp+NTFS.LastRead]
1287
        mov     eax, [ebp+NTFS.LastRead]
1288
        mov     [ebp+NTFS.nodeLastRead], eax
1288
        mov     [ebp+NTFS.nodeLastRead], eax
1289
        mov     [ebp+NTFS.indexPointer], esi
1289
        mov     [ebp+NTFS.indexPointer], esi
1290
        movzx   eax, word [esi+indexAllocatedSize]
1290
        movzx   eax, word [esi+indexAllocatedSize]
1291
        mov     eax, [esi+eax-8]
1291
        mov     eax, [esi+eax-8]
1292
        mov     edx, [ebp+NTFS.cur_size]
1292
        mov     edx, [ebp+NTFS.cur_size]
1293
        push    edx
1293
        push    edx
1294
        cmp     edx, [ebp+NTFS.cur_subnode_size]
1294
        cmp     edx, [ebp+NTFS.cur_subnode_size]
1295
        jz      @f
1295
        jz      @f
1296
        mul     [ebp+NTFS.sectors_per_cluster]
1296
        mul     [ebp+NTFS.sectors_per_cluster]
1297
@@:
1297
@@:
1298
        mov     esi, [ebp+NTFS.cur_index_buf]
1298
        mov     esi, [ebp+NTFS.cur_index_buf]
1299
        xchg    [ebp+NTFS.secondIndexBuffer], esi
1299
        xchg    [ebp+NTFS.secondIndexBuffer], esi
1300
        mov     [ebp+NTFS.cur_index_buf], esi
1300
        mov     [ebp+NTFS.cur_index_buf], esi
1301
        mov     [ebp+NTFS.cur_buf], esi
1301
        mov     [ebp+NTFS.cur_buf], esi
1302
        mov     [ebp+NTFS.cur_attr], 0xA0   ; $INDEX_ALLOCATION
1302
        mov     [ebp+NTFS.cur_attr], 0xA0   ; $INDEX_ALLOCATION
1303
        mov     [ebp+NTFS.cur_offs], eax
1303
        mov     [ebp+NTFS.cur_offs], eax
1304
        call    ntfs_read_attr.newAttribute
1304
        call    ntfs_read_attr.newAttribute
1305
        pop     eax
1305
        pop     eax
1306
        mov     [ebp+NTFS.cur_size], eax
1306
        mov     [ebp+NTFS.cur_size], eax
1307
        shl     eax, 9
1307
        shl     eax, 9
1308
        cmp     [ebp+NTFS.cur_read], eax
1308
        cmp     [ebp+NTFS.cur_read], eax
1309
        jnz     .err
1309
        jnz     .err
1310
        cmp     dword [esi], 'INDX'
1310
        cmp     dword [esi], 'INDX'
1311
        jnz     .err
1311
        jnz     .err
1312
        mov     ebx, esi
1312
        mov     ebx, esi
1313
        call    ntfs_restore_usa
1313
        call    ntfs_restore_usa
1314
        jc      .err
1314
        jc      .err
1315
        add     esi, recordNode
1315
        add     esi, recordNode
1316
        jmp     .scanloop
1316
        jmp     .scanloop
1317
 
1317
 
1318
.found:
1318
.found:
1319
        cmp     byte [edi], 0
1319
        cmp     byte [edi], 0
1320
        jz      @f
1320
        jz      @f
1321
        cmp     byte [edi], '/'
1321
        cmp     byte [edi], '/'
1322
        jz      @f
1322
        jz      @f
1323
        pop     edi
1323
        pop     edi
1324
        pop     esi
1324
        pop     esi
1325
        jmp     .scanloopcont
1325
        jmp     .scanloopcont
1326
 
1326
 
1327
@@:
1327
@@:
1328
        pop     esi
1328
        pop     esi
1329
        pop     esi
1329
        pop     esi
1330
        mov     eax, [esi]
1330
        mov     eax, [esi]
1331
        mov     [ebp+NTFS.cur_iRecord], eax
1331
        mov     [ebp+NTFS.cur_iRecord], eax
1332
        mov     [esp+1Ch], esi
1332
        mov     [esp+1Ch], esi
1333
        mov     [esp+4], edi
1333
        mov     [esp+4], edi
1334
        popad
1334
        popad
1335
        inc     esi
1335
        inc     esi
1336
        cmp     byte [esi-1], 0
1336
        cmp     byte [esi-1], 0
1337
        jnz     @f
1337
        jnz     @f
1338
        cmp     dword [esp+8], 0
1338
        cmp     dword [esp+8], 0
1339
        jz      .ret2
1339
        jz      .ret2
1340
        mov     esi, [esp+8]
1340
        mov     esi, [esp+8]
1341
        mov     dword [esp+8], 0
1341
        mov     dword [esp+8], 0
1342
@@:
1342
@@:
1343
        pop     eax
1343
        pop     eax
1344
        jmp     .doit2
1344
        jmp     .doit2
1345
 
1345
 
1346
;----------------------------------------------------------------
1346
;----------------------------------------------------------------
1347
ntfs_ReadFile:
1347
ntfs_ReadFile:
1348
        cmp     byte [esi], 0
1348
        cmp     byte [esi], 0
1349
        jnz     @f
1349
        jnz     @f
1350
        or      ebx, -1
1350
        or      ebx, -1
1351
        movi    eax, ERROR_ACCESS_DENIED
1351
        movi    eax, ERROR_ACCESS_DENIED
1352
        ret
1352
        ret
1353
 
1353
 
1354
@@:
1354
@@:
1355
        call    ntfs_lock
1355
        call    ntfs_lock
1356
        stdcall ntfs_find_lfn, [esp+4]
1356
        stdcall ntfs_find_lfn, [esp+4]
1357
        jnc     .found
1357
        jnc     .found
1358
        call    ntfs_unlock
1358
        call    ntfs_unlock
1359
        or      ebx, -1
1359
        or      ebx, -1
1360
        movi    eax, ERROR_FILE_NOT_FOUND
1360
        movi    eax, ERROR_FILE_NOT_FOUND
1361
        ret
1361
        ret
1362
 
1362
 
1363
.found:
1363
.found:
1364
        mov     [ebp+NTFS.cur_attr], 0x80   ; $DATA
1364
        mov     [ebp+NTFS.cur_attr], 0x80   ; $DATA
1365
        and     [ebp+NTFS.cur_offs], 0
1365
        and     [ebp+NTFS.cur_offs], 0
1366
        and     [ebp+NTFS.cur_size], 0
1366
        and     [ebp+NTFS.cur_size], 0
1367
        call    ntfs_read_attr
1367
        call    ntfs_read_attr
1368
        jnc     @f
1368
        jnc     @f
1369
        call    ntfs_unlock
1369
        call    ntfs_unlock
1370
        or      ebx, -1
1370
        or      ebx, -1
1371
        movi    eax, ERROR_ACCESS_DENIED
1371
        movi    eax, ERROR_ACCESS_DENIED
1372
        ret
1372
        ret
1373
 
1373
 
1374
@@:
1374
@@:
1375
        pushad
1375
        pushad
1376
        and     dword [esp+10h], 0
1376
        and     dword [esp+10h], 0
1377
        xor     eax, eax
1377
        xor     eax, eax
1378
        cmp     dword [ebx+8], 0x200
1378
        cmp     dword [ebx+8], 0x200
1379
        jb      @f
1379
        jb      @f
1380
.eof0:
1380
.eof0:
1381
        popad
1381
        popad
1382
        xor     ebx, ebx
1382
        xor     ebx, ebx
1383
.eof:
1383
.eof:
1384
        call    ntfs_unlock
1384
        call    ntfs_unlock
1385
        movi    eax, ERROR_END_OF_FILE
1385
        movi    eax, ERROR_END_OF_FILE
1386
        ret
1386
        ret
1387
 
1387
 
1388
@@:
1388
@@:
1389
        mov     ecx, [ebx+12]
1389
        mov     ecx, [ebx+12]
1390
        mov     edx, [ebx+16]
1390
        mov     edx, [ebx+16]
1391
        mov     eax, [ebx+4]
1391
        mov     eax, [ebx+4]
1392
        test    eax, 0x1FF
1392
        test    eax, 0x1FF
1393
        jz      .alignedstart
1393
        jz      .alignedstart
1394
        push    edx
1394
        push    edx
1395
        mov     edx, [ebx+8]
1395
        mov     edx, [ebx+8]
1396
        shrd    eax, edx, 9
1396
        shrd    eax, edx, 9
1397
        pop     edx
1397
        pop     edx
1398
        mov     [ebp+NTFS.cur_offs], eax
1398
        mov     [ebp+NTFS.cur_offs], eax
1399
        mov     [ebp+NTFS.cur_size], 1
1399
        mov     [ebp+NTFS.cur_size], 1
1400
        lea     eax, [ebp+NTFS.bitmap_buf]
1400
        lea     eax, [ebp+NTFS.bitmap_buf]
1401
        mov     [ebp+NTFS.cur_buf], eax
1401
        mov     [ebp+NTFS.cur_buf], eax
1402
        call    ntfs_read_attr.continue
1402
        call    ntfs_read_attr.continue
1403
        mov     eax, [ebx+4]
1403
        mov     eax, [ebx+4]
1404
        and     eax, 0x1FF
1404
        and     eax, 0x1FF
1405
        lea     esi, [ebp+NTFS.bitmap_buf+eax]
1405
        lea     esi, [ebp+NTFS.bitmap_buf+eax]
1406
        sub     eax, [ebp+NTFS.cur_read]
1406
        sub     eax, [ebp+NTFS.cur_read]
1407
        jae     .eof0
1407
        jae     .eof0
1408
        neg     eax
1408
        neg     eax
1409
        push    ecx
1409
        push    ecx
1410
        cmp     ecx, eax
1410
        cmp     ecx, eax
1411
        jb      @f
1411
        jb      @f
1412
        mov     ecx, eax
1412
        mov     ecx, eax
1413
@@:
1413
@@:
1414
        mov     [esp+10h+4], ecx
1414
        mov     [esp+10h+4], ecx
1415
        mov     edi, edx
1415
        mov     edi, edx
1416
        rep movsb
1416
        rep movsb
1417
        mov     edx, edi
1417
        mov     edx, edi
1418
        pop     ecx
1418
        pop     ecx
1419
        sub     ecx, [esp+10h]
1419
        sub     ecx, [esp+10h]
1420
        jnz     @f
1420
        jnz     @f
1421
.retok:
1421
.retok:
1422
        popad
1422
        popad
1423
        call    ntfs_unlock
1423
        call    ntfs_unlock
1424
        xor     eax, eax
1424
        xor     eax, eax
1425
        ret
1425
        ret
1426
 
1426
 
1427
@@:
1427
@@:
1428
        cmp     [ebp+NTFS.cur_read], 0x200
1428
        cmp     [ebp+NTFS.cur_read], 0x200
1429
        jz      .alignedstart
1429
        jz      .alignedstart
1430
.eof_ebx:
1430
.eof_ebx:
1431
        popad
1431
        popad
1432
        jmp     .eof
1432
        jmp     .eof
1433
 
1433
 
1434
.alignedstart:
1434
.alignedstart:
1435
        mov     eax, [ebx+4]
1435
        mov     eax, [ebx+4]
1436
        push    edx
1436
        push    edx
1437
        mov     edx, [ebx+8]
1437
        mov     edx, [ebx+8]
1438
        add     eax, 511
1438
        add     eax, 511
1439
        adc     edx, 0
1439
        adc     edx, 0
1440
        shrd    eax, edx, 9
1440
        shrd    eax, edx, 9
1441
        pop     edx
1441
        pop     edx
1442
        mov     [ebp+NTFS.cur_offs], eax
1442
        mov     [ebp+NTFS.cur_offs], eax
1443
        mov     [ebp+NTFS.cur_buf], edx
1443
        mov     [ebp+NTFS.cur_buf], edx
1444
        mov     eax, ecx
1444
        mov     eax, ecx
1445
        shr     eax, 9
1445
        shr     eax, 9
1446
        mov     [ebp+NTFS.cur_size], eax
1446
        mov     [ebp+NTFS.cur_size], eax
1447
        add     eax, [ebp+NTFS.cur_offs]
1447
        add     eax, [ebp+NTFS.cur_offs]
1448
        push    eax
1448
        push    eax
1449
        call    ntfs_read_attr.continue
1449
        call    ntfs_read_attr.continue
1450
        pop     [ebp+NTFS.cur_offs]
1450
        pop     [ebp+NTFS.cur_offs]
1451
        mov     eax, [ebp+NTFS.cur_read]
1451
        mov     eax, [ebp+NTFS.cur_read]
1452
        add     [esp+10h], eax
1452
        add     [esp+10h], eax
1453
        mov     eax, ecx
1453
        mov     eax, ecx
1454
        and     eax, not 0x1FF
1454
        and     eax, not 0x1FF
1455
        cmp     [ebp+NTFS.cur_read], eax
1455
        cmp     [ebp+NTFS.cur_read], eax
1456
        jnz     .eof_ebx
1456
        jnz     .eof_ebx
1457
        and     ecx, 0x1FF
1457
        and     ecx, 0x1FF
1458
        jz      .retok
1458
        jz      .retok
1459
        add     edx, [ebp+NTFS.cur_read]
1459
        add     edx, [ebp+NTFS.cur_read]
1460
        mov     [ebp+NTFS.cur_size], 1
1460
        mov     [ebp+NTFS.cur_size], 1
1461
        lea     eax, [ebp+NTFS.bitmap_buf]
1461
        lea     eax, [ebp+NTFS.bitmap_buf]
1462
        mov     [ebp+NTFS.cur_buf], eax
1462
        mov     [ebp+NTFS.cur_buf], eax
1463
        call    ntfs_read_attr.continue
1463
        call    ntfs_read_attr.continue
1464
        cmp     [ebp+NTFS.cur_read], ecx
1464
        cmp     [ebp+NTFS.cur_read], ecx
1465
        jb      @f
1465
        jb      @f
1466
        mov     [ebp+NTFS.cur_read], ecx
1466
        mov     [ebp+NTFS.cur_read], ecx
1467
@@:
1467
@@:
1468
        xchg    ecx, [ebp+NTFS.cur_read]
1468
        xchg    ecx, [ebp+NTFS.cur_read]
1469
        push    ecx
1469
        push    ecx
1470
        mov     edi, edx
1470
        mov     edi, edx
1471
        lea     esi, [ebp+NTFS.bitmap_buf]
1471
        lea     esi, [ebp+NTFS.bitmap_buf]
1472
        add     [esp+10h+4], ecx
1472
        add     [esp+10h+4], ecx
1473
        rep movsb
1473
        rep movsb
1474
        pop     ecx
1474
        pop     ecx
1475
        xor     eax, eax
1475
        xor     eax, eax
1476
        cmp     ecx, [ebp+NTFS.cur_read]
1476
        cmp     ecx, [ebp+NTFS.cur_read]
1477
        jz      @f
1477
        jz      @f
1478
        mov     al, ERROR_END_OF_FILE
1478
        mov     al, ERROR_END_OF_FILE
1479
@@:
1479
@@:
1480
        mov     [esp+1Ch], eax
1480
        mov     [esp+1Ch], eax
1481
        call    ntfs_unlock
1481
        call    ntfs_unlock
1482
        popad
1482
        popad
1483
        ret
1483
        ret
1484
 
1484
 
1485
;----------------------------------------------------------------
1485
;----------------------------------------------------------------
1486
ntfs_ReadFolder:
1486
ntfs_ReadFolder:
1487
        call    ntfs_lock
1487
        call    ntfs_lock
1488
        mov     [ebp+NTFS.cur_iRecord], 5   ; root directory
1488
        mov     [ebp+NTFS.cur_iRecord], 5   ; root directory
1489
        cmp     byte [esi], 0
1489
        cmp     byte [esi], 0
1490
        jz      @f
1490
        jz      @f
1491
        stdcall ntfs_find_lfn, [esp+4]
1491
        stdcall ntfs_find_lfn, [esp+4]
1492
        jc      ntfsNotFound
1492
        jc      ntfsNotFound
1493
@@:
1493
@@:
1494
        mov     [ebp+NTFS.cur_attr], 0x10   ; $STANDARD_INFORMATION
1494
        mov     [ebp+NTFS.cur_attr], 0x10   ; $STANDARD_INFORMATION
1495
        and     [ebp+NTFS.cur_offs], 0
1495
        and     [ebp+NTFS.cur_offs], 0
1496
        mov     [ebp+NTFS.cur_size], 1
1496
        mov     [ebp+NTFS.cur_size], 1
1497
        lea     eax, [ebp+NTFS.bitmap_buf]
1497
        lea     eax, [ebp+NTFS.bitmap_buf]
1498
        mov     [ebp+NTFS.cur_buf], eax
1498
        mov     [ebp+NTFS.cur_buf], eax
1499
        call    ntfs_read_attr
1499
        call    ntfs_read_attr
1500
        jc      ntfsFail
1500
        jc      ntfsFail
1501
        mov     [ebp+NTFS.cur_attr], 0x90   ; $INDEX_ROOT
1501
        mov     [ebp+NTFS.cur_attr], 0x90   ; $INDEX_ROOT
1502
.doit:
1502
.doit:
1503
        mov     eax, [ebp+NTFS.cur_index_size]
1503
        mov     eax, [ebp+NTFS.cur_index_size]
1504
        mov     [ebp+NTFS.cur_size], eax
1504
        mov     [ebp+NTFS.cur_size], eax
1505
        mov     eax, [ebp+NTFS.cur_index_buf]
1505
        mov     eax, [ebp+NTFS.cur_index_buf]
1506
        mov     [ebp+NTFS.cur_buf], eax
1506
        mov     [ebp+NTFS.cur_buf], eax
1507
        call    ntfs_read_attr.newAttribute
1507
        call    ntfs_read_attr.newAttribute
1508
        jc      ntfsFail
1508
        jc      ntfsFail
1509
        cmp     [ebp+NTFS.cur_read], 0x20
1509
        cmp     [ebp+NTFS.cur_read], 0x20
1510
        jc      ntfsFail
1510
        jc      ntfsFail
1511
        mov     esi, [ebp+NTFS.cur_index_buf]
1511
        mov     esi, [ebp+NTFS.cur_index_buf]
1512
        mov     eax, [esi+indexRecordSize]
1512
        mov     eax, [esi+indexRecordSize]
1513
        shr     eax, 9
1513
        shr     eax, 9
1514
        cmp     [ebp+NTFS.cur_index_size], eax
1514
        cmp     [ebp+NTFS.cur_index_size], eax
1515
        jc      .realloc
1515
        jc      .realloc
1516
        mov     [ebp+NTFS.cur_subnode_size], eax
1516
        mov     [ebp+NTFS.cur_subnode_size], eax
1517
        add     esi, rootNode
1517
        add     esi, rootNode
1518
        mov     eax, [esi+nodeRealSize]
1518
        mov     eax, [esi+nodeRealSize]
1519
        add     eax, rootNode
1519
        add     eax, rootNode
1520
        cmp     [ebp+NTFS.cur_read], eax
1520
        cmp     [ebp+NTFS.cur_read], eax
1521
        jc      ntfsFail
1521
        jc      ntfsFail
1522
        mov     edi, [ebx+16]
1522
        mov     edi, [ebx+16]
1523
        mov     ecx, [ebx+12]
1523
        mov     ecx, [ebx+12]
1524
        pushd   [ebx]
1524
        pushd   [ebx]
1525
        pushd   [ebx+8]     ; read ANSI/UNICODE name
1525
        pushd   [ebx+8]     ; read ANSI/UNICODE name
1526
        push    edi
1526
        push    edi
1527
        mov     edx, esp
1527
        mov     edx, esp
1528
        mov     ebx, [ebx+4]
1528
        mov     ebx, [ebx+4]
1529
; init header
1529
; init header
1530
        xor     eax, eax
1530
        xor     eax, eax
1531
        mov     [edi+8], eax
1531
        mov     [edi+8], eax
1532
        mov     [edi+4], eax
1532
        mov     [edi+4], eax
1533
        inc     eax
1533
        inc     eax
1534
        mov     [edi], eax      ; version
1534
        mov     [edi], eax      ; version
1535
        add     edi, 32
1535
        add     edi, 32
1536
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
1536
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
1537
; ecx = number of blocks to read
1537
; ecx = number of blocks to read
1538
; edx -> parameters block: dd , dd 
1538
; edx -> parameters block: dd , dd 
1539
        cmp     [ebp+NTFS.cur_iRecord], 5
1539
        cmp     [ebp+NTFS.cur_iRecord], 5
1540
        jz      .skip_specials
1540
        jz      .skip_specials
1541
; dot and dotdot entries
1541
; dot and dotdot entries
1542
        push    esi
1542
        push    esi
1543
        xor     esi, esi
1543
        xor     esi, esi
1544
        call    .add_special_entry
1544
        call    .add_special_entry
1545
        inc     esi
1545
        inc     esi
1546
        call    .add_special_entry
1546
        call    .add_special_entry
1547
        pop     esi
1547
        pop     esi
1548
.skip_specials:
1548
.skip_specials:
1549
; at first, dump index root
1549
; at first, dump index root
1550
        add     esi, [esi+indexOffset]
1550
        add     esi, [esi+indexOffset]
1551
.dump_root:
1551
.dump_root:
1552
        test    byte [esi+indexFlags], 2
1552
        test    byte [esi+indexFlags], 2
1553
        jnz     .dump_root_done
1553
        jnz     .dump_root_done
1554
        call    .add_entry
1554
        call    .add_entry
1555
        movzx   eax, word [esi+indexAllocatedSize]
1555
        movzx   eax, word [esi+indexAllocatedSize]
1556
        add     esi, eax
1556
        add     esi, eax
1557
        jmp     .dump_root
1557
        jmp     .dump_root
1558
 
1558
 
1559
.realloc:
1559
.realloc:
1560
        mov     edi, eax
1560
        mov     edi, eax
1561
        mov     eax, [esi+indexRecordSize]
1561
        mov     eax, [esi+indexRecordSize]
1562
        shl     eax, 1
1562
        shl     eax, 1
1563
        stdcall kernel_alloc, eax
1563
        stdcall kernel_alloc, eax
1564
        test    eax, eax
1564
        test    eax, eax
1565
        jz      ntfsFail
1565
        jz      ntfsFail
1566
        mov     edx, [ebp+NTFS.cur_index_buf]
1566
        mov     edx, [ebp+NTFS.cur_index_buf]
1567
        cmp     edx, [ebp+NTFS.secondIndexBuffer]
1567
        cmp     edx, [ebp+NTFS.secondIndexBuffer]
1568
        jc      @f
1568
        jc      @f
1569
        mov     edx, [ebp+NTFS.secondIndexBuffer]
1569
        mov     edx, [ebp+NTFS.secondIndexBuffer]
1570
@@:
1570
@@:
1571
        mov     [ebp+NTFS.cur_index_buf], eax
1571
        mov     [ebp+NTFS.cur_index_buf], eax
1572
        add     eax, [esi+indexRecordSize]
1572
        add     eax, [esi+indexRecordSize]
1573
        mov     [ebp+NTFS.secondIndexBuffer], eax
1573
        mov     [ebp+NTFS.secondIndexBuffer], eax
1574
        mov     [ebp+NTFS.cur_index_size], edi
1574
        mov     [ebp+NTFS.cur_index_size], edi
1575
        stdcall kernel_free, edx
1575
        stdcall kernel_free, edx
1576
        jmp     .doit
1576
        jmp     .doit
1577
 
1577
 
1578
.dump_root_done:
1578
.dump_root_done:
1579
; now dump all subnodes
1579
; now dump all subnodes
1580
        push    ecx edi
1580
        push    ecx edi
1581
        lea     edi, [ebp+NTFS.bitmap_buf]
1581
        lea     edi, [ebp+NTFS.bitmap_buf]
1582
        mov     [ebp+NTFS.cur_buf], edi
1582
        mov     [ebp+NTFS.cur_buf], edi
1583
        mov     ecx, 0x400/4
1583
        mov     ecx, 0x400/4
1584
        xor     eax, eax
1584
        xor     eax, eax
1585
        rep stosd
1585
        rep stosd
1586
        mov     [ebp+NTFS.cur_attr], 0xB0   ; $BITMAP
1586
        mov     [ebp+NTFS.cur_attr], 0xB0   ; $BITMAP
1587
        and     [ebp+NTFS.cur_offs], 0
1587
        and     [ebp+NTFS.cur_offs], 0
1588
        mov     [ebp+NTFS.cur_size], 2
1588
        mov     [ebp+NTFS.cur_size], 2
1589
        call    ntfs_read_attr.newAttribute
1589
        call    ntfs_read_attr.newAttribute
1590
        pop     edi ecx
1590
        pop     edi ecx
1591
        push    0       ; save offset in $BITMAP attribute
1591
        push    0       ; save offset in $BITMAP attribute
1592
        and     [ebp+NTFS.cur_offs], 0
1592
        and     [ebp+NTFS.cur_offs], 0
1593
.dumploop:
1593
.dumploop:
1594
        mov     [ebp+NTFS.cur_attr], 0xA0
1594
        mov     [ebp+NTFS.cur_attr], 0xA0
1595
        mov     eax, [ebp+NTFS.cur_subnode_size]
1595
        mov     eax, [ebp+NTFS.cur_subnode_size]
1596
        mov     [ebp+NTFS.cur_size], eax
1596
        mov     [ebp+NTFS.cur_size], eax
1597
        mov     esi, [ebp+NTFS.cur_index_buf]
1597
        mov     esi, [ebp+NTFS.cur_index_buf]
1598
        mov     [ebp+NTFS.cur_buf], esi
1598
        mov     [ebp+NTFS.cur_buf], esi
1599
        mov     eax, [ebp+NTFS.cur_offs]
1599
        mov     eax, [ebp+NTFS.cur_offs]
1600
        push    eax
1600
        push    eax
1601
        imul    eax, [ebp+NTFS.cur_subnode_size]
1601
        imul    eax, [ebp+NTFS.cur_subnode_size]
1602
        mov     [ebp+NTFS.cur_offs], eax
1602
        mov     [ebp+NTFS.cur_offs], eax
1603
        call    ntfs_read_attr.newAttribute
1603
        call    ntfs_read_attr.newAttribute
1604
        pop     [ebp+NTFS.cur_offs]
1604
        pop     [ebp+NTFS.cur_offs]
1605
        mov     eax, [ebp+NTFS.cur_subnode_size]
1605
        mov     eax, [ebp+NTFS.cur_subnode_size]
1606
        shl     eax, 9
1606
        shl     eax, 9
1607
        cmp     [ebp+NTFS.cur_read], eax
1607
        cmp     [ebp+NTFS.cur_read], eax
1608
        jnz     .done
1608
        jnz     .done
1609
        push    eax
1609
        push    eax
1610
        mov     eax, [ebp+NTFS.cur_offs]
1610
        mov     eax, [ebp+NTFS.cur_offs]
1611
        and     eax, 0x400*8-1
1611
        and     eax, 0x400*8-1
1612
        bt      dword [ebp+NTFS.bitmap_buf], eax
1612
        bt      dword [ebp+NTFS.bitmap_buf], eax
1613
        pop     eax
1613
        pop     eax
1614
        jnc     .dump_subnode_done
1614
        jnc     .dump_subnode_done
1615
        cmp     dword [esi], 'INDX'
1615
        cmp     dword [esi], 'INDX'
1616
        jnz     .dump_subnode_done
1616
        jnz     .dump_subnode_done
1617
        push    ebx
1617
        push    ebx
1618
        mov     ebx, esi
1618
        mov     ebx, esi
1619
        call    ntfs_restore_usa
1619
        call    ntfs_restore_usa
1620
        pop     ebx
1620
        pop     ebx
1621
        jc      .dump_subnode_done
1621
        jc      .dump_subnode_done
1622
        add     esi, recordNode
1622
        add     esi, recordNode
1623
        add     esi, [esi+indexOffset]
1623
        add     esi, [esi+indexOffset]
1624
.dump_subnode:
1624
.dump_subnode:
1625
        test    byte [esi+indexFlags], 2
1625
        test    byte [esi+indexFlags], 2
1626
        jnz     .dump_subnode_done
1626
        jnz     .dump_subnode_done
1627
        call    .add_entry
1627
        call    .add_entry
1628
        movzx   eax, word [esi+indexAllocatedSize]
1628
        movzx   eax, word [esi+indexAllocatedSize]
1629
        add     esi, eax
1629
        add     esi, eax
1630
        jmp     .dump_subnode
1630
        jmp     .dump_subnode
1631
 
1631
 
1632
.dump_subnode_done:
1632
.dump_subnode_done:
1633
        inc     [ebp+NTFS.cur_offs]
1633
        inc     [ebp+NTFS.cur_offs]
1634
        test    [ebp+NTFS.cur_offs], 0x400*8-1
1634
        test    [ebp+NTFS.cur_offs], 0x400*8-1
1635
        jnz     .dumploop
1635
        jnz     .dumploop
1636
        mov     [ebp+NTFS.cur_attr], 0xB0
1636
        mov     [ebp+NTFS.cur_attr], 0xB0
1637
        push    ecx edi
1637
        push    ecx edi
1638
        lea     edi, [ebp+NTFS.bitmap_buf]
1638
        lea     edi, [ebp+NTFS.bitmap_buf]
1639
        mov     [ebp+NTFS.cur_buf], edi
1639
        mov     [ebp+NTFS.cur_buf], edi
1640
        mov     ecx, 0x400/4
1640
        mov     ecx, 0x400/4
1641
        xor     eax, eax
1641
        xor     eax, eax
1642
        rep stosd
1642
        rep stosd
1643
        pop     edi ecx
1643
        pop     edi ecx
1644
        pop     eax
1644
        pop     eax
1645
        push    [ebp+NTFS.cur_offs]
1645
        push    [ebp+NTFS.cur_offs]
1646
        inc     eax
1646
        inc     eax
1647
        mov     [ebp+NTFS.cur_offs], eax
1647
        mov     [ebp+NTFS.cur_offs], eax
1648
        mov     [ebp+NTFS.cur_size], 2
1648
        mov     [ebp+NTFS.cur_size], 2
1649
        push    eax
1649
        push    eax
1650
        call    ntfs_read_attr.newAttribute
1650
        call    ntfs_read_attr.newAttribute
1651
        pop     eax
1651
        pop     eax
1652
        pop     [ebp+NTFS.cur_offs]
1652
        pop     [ebp+NTFS.cur_offs]
1653
        push    eax
1653
        push    eax
1654
        jmp     .dumploop
1654
        jmp     .dumploop
1655
 
1655
 
1656
.done:
1656
.done:
1657
        pop     eax
1657
        pop     eax
1658
        pop     eax
1658
        pop     eax
1659
        mov     ebx, [eax+4]
1659
        mov     ebx, [eax+4]
1660
        pop     eax
1660
        pop     eax
1661
        pop     eax
1661
        pop     eax
1662
        test    eax, eax
1662
        test    eax, eax
1663
        jz      .ret
1663
        jz      .ret
1664
        xor     eax, eax
1664
        xor     eax, eax
1665
        dec     ecx
1665
        dec     ecx
1666
        js      @f
1666
        js      @f
1667
        mov     al, ERROR_END_OF_FILE
1667
        mov     al, ERROR_END_OF_FILE
1668
@@:
1668
@@:
1669
        push    eax
1669
        push    eax
1670
        call    ntfs_unlock
1670
        call    ntfs_unlock
1671
        pop     eax
1671
        pop     eax
1672
        ret
1672
        ret
1673
 
1673
 
1674
.add_special_entry:
1674
.add_special_entry:
1675
        mov     eax, [edx]
1675
        mov     eax, [edx]
1676
        inc     dword [eax+8]   ; new file found
1676
        inc     dword [eax+8]   ; new file found
1677
        dec     ebx
1677
        dec     ebx
1678
        jns     .ret
1678
        jns     .ret
1679
        dec     ecx
1679
        dec     ecx
1680
        js      .ret
1680
        js      .ret
1681
        inc     dword [eax+4]   ; new file block copied
1681
        inc     dword [eax+4]   ; new file block copied
1682
        mov     eax, [edx+4]
1682
        mov     eax, [edx+4]
1683
        mov     [edi+4], eax
1683
        mov     [edi+4], eax
1684
        mov     eax, 0x10
1684
        mov     eax, 0x10
1685
        stosd
1685
        stosd
1686
        scasd
1686
        scasd
1687
        push    edx
1687
        push    edx
1688
        mov     eax, dword [ebp+NTFS.bitmap_buf]
1688
        mov     eax, dword [ebp+NTFS.bitmap_buf]
1689
        mov     edx, dword [ebp+NTFS.bitmap_buf+4]
1689
        mov     edx, dword [ebp+NTFS.bitmap_buf+4]
1690
        call    ntfs_datetime_to_bdfe
1690
        call    ntfs_datetime_to_bdfe
1691
        mov     eax, dword [ebp+NTFS.bitmap_buf+0x18]
1691
        mov     eax, dword [ebp+NTFS.bitmap_buf+0x18]
1692
        mov     edx, dword [ebp+NTFS.bitmap_buf+0x1C]
1692
        mov     edx, dword [ebp+NTFS.bitmap_buf+0x1C]
1693
        call    ntfs_datetime_to_bdfe
1693
        call    ntfs_datetime_to_bdfe
1694
        mov     eax, dword [ebp+NTFS.bitmap_buf+8]
1694
        mov     eax, dword [ebp+NTFS.bitmap_buf+8]
1695
        mov     edx, dword [ebp+NTFS.bitmap_buf+0xC]
1695
        mov     edx, dword [ebp+NTFS.bitmap_buf+0xC]
1696
        call    ntfs_datetime_to_bdfe
1696
        call    ntfs_datetime_to_bdfe
1697
        pop     edx
1697
        pop     edx
1698
        xor     eax, eax
1698
        xor     eax, eax
1699
        stosd
1699
        stosd
1700
        stosd
1700
        stosd
1701
        mov     al, '.'
1701
        mov     al, '.'
1702
        push    edi ecx
1702
        push    edi ecx
1703
        lea     ecx, [esi+1]
1703
        lea     ecx, [esi+1]
1704
        test    byte [edi-0x24], 1
1704
        test    byte [edi-0x24], 1
1705
        jz      @f
1705
        jz      @f
1706
        rep stosw
1706
        rep stosw
1707
        pop     ecx
1707
        pop     ecx
1708
        xor     eax, eax
1708
        xor     eax, eax
1709
        stosw
1709
        stosw
1710
        pop     edi
1710
        pop     edi
1711
        add     edi, 520
1711
        add     edi, 520
1712
        ret
1712
        ret
1713
 
1713
 
1714
@@:
1714
@@:
1715
        rep stosb
1715
        rep stosb
1716
        pop     ecx
1716
        pop     ecx
1717
        xor     eax, eax
1717
        xor     eax, eax
1718
        stosb
1718
        stosb
1719
        pop     edi
1719
        pop     edi
1720
        add     edi, 264
1720
        add     edi, 264
1721
.ret:
1721
.ret:
1722
        ret
1722
        ret
1723
 
1723
 
1724
.add_entry:
1724
.add_entry:
1725
; do not return DOS 8.3 names
1725
; do not return DOS 8.3 names
1726
        cmp     byte [esi+namespace], 2
1726
        cmp     byte [esi+namespace], 2
1727
        jz      .ret
1727
        jz      .ret
1728
; do not return system files
1728
; do not return system files
1729
; ... note that there will be no bad effects if system files also were reported ...
1729
; ... note that there will be no bad effects if system files also were reported ...
1730
        cmp     dword [esi+fileRecordReference], 0x10
1730
        cmp     dword [esi+fileRecordReference], 0x10
1731
        jb      .ret
1731
        jb      .ret
1732
        mov     eax, [edx]
1732
        mov     eax, [edx]
1733
        inc     dword [eax+8]   ; new file found
1733
        inc     dword [eax+8]   ; new file found
1734
        dec     ebx
1734
        dec     ebx
1735
        jns     .ret
1735
        jns     .ret
1736
        dec     ecx
1736
        dec     ecx
1737
        js      .ret
1737
        js      .ret
1738
        inc     dword [eax+4]   ; new file block copied
1738
        inc     dword [eax+4]   ; new file block copied
1739
        mov     eax, [edx+4]    ; flags
1739
        mov     eax, [edx+4]    ; flags
1740
        call    ntfs_direntry_to_bdfe
1740
        call    ntfs_direntry_to_bdfe
1741
        push    ecx esi edi
1741
        push    ecx esi edi
1742
        movzx   ecx, byte [esi+fileNameLength]
1742
        movzx   ecx, byte [esi+fileNameLength]
1743
        add     esi, fileName
1743
        add     esi, fileName
1744
        test    byte [edi-0x24], 1
1744
        test    byte [edi-0x24], 1
1745
        jz      .ansi
1745
        jz      .ansi
1746
        shr     ecx, 1
1746
        shr     ecx, 1
1747
        rep movsd
1747
        rep movsd
1748
        adc     ecx, ecx
1748
        adc     ecx, ecx
1749
        rep movsw
1749
        rep movsw
1750
        and     word [edi], 0
1750
        and     word [edi], 0
1751
        pop     edi
1751
        pop     edi
1752
        add     edi, 520
1752
        add     edi, 520
1753
        pop     esi ecx
1753
        pop     esi ecx
1754
        ret
1754
        ret
1755
 
1755
 
1756
.ansi:
1756
.ansi:
1757
        jecxz   .skip
1757
        jecxz   .skip
1758
@@:
1758
@@:
1759
        lodsw
1759
        lodsw
1760
        call    uni2ansi_char
1760
        call    uni2ansi_char
1761
        stosb
1761
        stosb
1762
        loop    @b
1762
        loop    @b
1763
.skip:
1763
.skip:
1764
        xor     al, al
1764
        xor     al, al
1765
        stosb
1765
        stosb
1766
        pop     edi
1766
        pop     edi
1767
        add     edi, 264
1767
        add     edi, 264
1768
        pop     esi ecx
1768
        pop     esi ecx
1769
        ret
1769
        ret
1770
 
1770
 
1771
ntfs_direntry_to_bdfe:
1771
ntfs_direntry_to_bdfe:
1772
        mov     [edi+4], eax    ; ANSI/UNICODE name
1772
        mov     [edi+4], eax    ; ANSI/UNICODE name
1773
        mov     eax, [esi+fileFlags]
1773
        mov     eax, [esi+fileFlags]
1774
        test    eax, 0x10000000
1774
        test    eax, 0x10000000
1775
        jz      @f
1775
        jz      @f
1776
        and     eax, not 0x10000000
1776
        and     eax, not 0x10000000
1777
        or      al, 0x10
1777
        or      al, 0x10
1778
@@:
1778
@@:
1779
        stosd
1779
        stosd
1780
        scasd
1780
        scasd
1781
        push    edx
1781
        push    edx
1782
        mov     eax, [esi+fileCreated]
1782
        mov     eax, [esi+fileCreated]
1783
        mov     edx, [esi+fileCreated+4]
1783
        mov     edx, [esi+fileCreated+4]
1784
        call    ntfs_datetime_to_bdfe
1784
        call    ntfs_datetime_to_bdfe
1785
        mov     eax, [esi+fileAccessed]
1785
        mov     eax, [esi+fileAccessed]
1786
        mov     edx, [esi+fileAccessed+4]
1786
        mov     edx, [esi+fileAccessed+4]
1787
        call    ntfs_datetime_to_bdfe
1787
        call    ntfs_datetime_to_bdfe
1788
        mov     eax, [esi+fileModified]
1788
        mov     eax, [esi+fileModified]
1789
        mov     edx, [esi+fileModified+4]
1789
        mov     edx, [esi+fileModified+4]
1790
        call    ntfs_datetime_to_bdfe
1790
        call    ntfs_datetime_to_bdfe
1791
        pop     edx
1791
        pop     edx
1792
        mov     eax, [esi+fileRealSize]
1792
        mov     eax, [esi+fileRealSize]
1793
        stosd
1793
        stosd
1794
        mov     eax, [esi+fileRealSize+4]
1794
        mov     eax, [esi+fileRealSize+4]
1795
        stosd
1795
        stosd
1796
        ret
1796
        ret
1797
 
1797
 
1798
iglobal
1798
iglobal
1799
months  db  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1799
months  db  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1800
months2 db  31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1800
months2 db  31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1801
endg
1801
endg
1802
 
1802
 
1803
ntfs_datetime_to_bdfe:
1803
ntfs_datetime_to_bdfe:
1804
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
1804
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
1805
        push    ebx ecx
1805
        push    ebx ecx
1806
        mov     ebx, eax
1806
        mov     ebx, eax
1807
        mov     eax, edx
1807
        mov     eax, edx
1808
        xor     edx, edx
1808
        xor     edx, edx
1809
        mov     ecx, 10000000
1809
        mov     ecx, 10000000
1810
        div     ecx
1810
        div     ecx
1811
        xchg    eax, ebx
1811
        xchg    eax, ebx
1812
        div     ecx
1812
        div     ecx
1813
.forEXT:
1813
.forEXT:
1814
        xchg    eax, ebx
1814
        xchg    eax, ebx
1815
        xor     edx, edx
1815
        xor     edx, edx
1816
        mov     ecx, 60
1816
        mov     ecx, 60
1817
        div     ecx
1817
        div     ecx
1818
        xchg    eax, ebx
1818
        xchg    eax, ebx
1819
        div     ecx
1819
        div     ecx
1820
        mov     [edi], dl
1820
        mov     [edi], dl
1821
        mov     edx, ebx
1821
        mov     edx, ebx
1822
; edx:eax = number of minutes
1822
; edx:eax = number of minutes
1823
        div     ecx
1823
        div     ecx
1824
        mov     [edi+1], dl
1824
        mov     [edi+1], dl
1825
; eax = number of hours
1825
; eax = number of hours
1826
        xor     edx, edx
1826
        xor     edx, edx
1827
        mov     cl, 24
1827
        mov     cl, 24
1828
        div     ecx
1828
        div     ecx
1829
        mov     [edi+2], dx
1829
        mov     [edi+2], dx
1830
; eax = number of days since January 1, 1601
1830
; eax = number of days since January 1, 1601
1831
        xor     edx, edx
1831
        xor     edx, edx
1832
        mov     cx, 365
1832
        mov     cx, 365
1833
        div     ecx
1833
        div     ecx
1834
        mov     ebx, eax
1834
        mov     ebx, eax
1835
        add     ebx, 1601
1835
        add     ebx, 1601
1836
        shr     eax, 2
1836
        shr     eax, 2
1837
        sub     edx, eax
1837
        sub     edx, eax
1838
        mov     cl, 25
1838
        mov     cl, 25
1839
        div     cl
1839
        div     cl
1840
        xor     ah, ah
1840
        xor     ah, ah
1841
        add     edx, eax
1841
        add     edx, eax
1842
        shr     eax, 2
1842
        shr     eax, 2
1843
        sub     edx, eax
1843
        sub     edx, eax
1844
        jns     @f
1844
        jns     @f
1845
        dec     ebx
1845
        dec     ebx
1846
        add     edx, 365
1846
        add     edx, 365
1847
        test    bl, 3
1847
        test    bl, 3
1848
        jnz     @f
1848
        jnz     @f
1849
        inc     edx
1849
        inc     edx
1850
@@:
1850
@@:
1851
        xor     eax, eax
1851
        xor     eax, eax
1852
        mov     ecx, months-1
1852
        mov     ecx, months-1
1853
        test    bl, 3
1853
        test    bl, 3
1854
        jnz     @f
1854
        jnz     @f
1855
        add     ecx, 12
1855
        add     ecx, 12
1856
@@:
1856
@@:
1857
        inc     ecx
1857
        inc     ecx
1858
        inc     eax
1858
        inc     eax
1859
        sub     dl, [ecx]
1859
        sub     dl, [ecx]
1860
        jnc     @b
1860
        jnc     @b
1861
        dec     dh
1861
        dec     dh
1862
        jns     @b
1862
        jns     @b
1863
        add     dl, [ecx]
1863
        add     dl, [ecx]
1864
        inc     edx
1864
        inc     edx
1865
        mov     [edi+4], dl
1865
        mov     [edi+4], dl
1866
        mov     [edi+5], al
1866
        mov     [edi+5], al
1867
        mov     [edi+6], bx
1867
        mov     [edi+6], bx
1868
        add     edi, 8
1868
        add     edi, 8
1869
        pop     ecx ebx
1869
        pop     ecx ebx
1870
        ret
1870
        ret
1871
 
1871
 
1872
.sec:
1872
.sec:
1873
        push    ebx ecx
1873
        push    ebx ecx
1874
        mov     ebx, edx
1874
        mov     ebx, edx
1875
        jmp     .forEXT
1875
        jmp     .forEXT
1876
 
1876
 
1877
;----------------------------------------------------------------
1877
;----------------------------------------------------------------
1878
ntfs_GetFileInfo:
1878
ntfs_GetFileInfo:
1879
        cmp     byte [esi], 0
-
 
1880
        jnz     @f
-
 
1881
        movi    eax, ERROR_UNSUPPORTED_FS
-
 
1882
        ret
-
 
1883
@@:
-
 
1884
        call    ntfs_lock
1879
        call    ntfs_lock
-
 
1880
        mov     edi, [ebx+16]
-
 
1881
        cmp     byte [esi], 0
-
 
1882
        jz      .volume
1885
        stdcall ntfs_find_lfn, [esp+4]
1883
        stdcall ntfs_find_lfn, [esp+4]
1886
        jnc     .found
1884
        jnc     .found
1887
        test    eax, eax
1885
        test    eax, eax
1888
        jz      ntfsFail
1886
        jz      ntfsFail
1889
        jmp     ntfsNotFound
1887
        jmp     ntfsNotFound
1890
 
1888
 
1891
.found:
1889
.found:
1892
        push    esi edi
-
 
1893
        mov     esi, eax
1890
        mov     esi, eax
1894
        mov     edi, [ebx+16]
-
 
1895
        xor     eax, eax
1891
        xor     eax, eax
1896
        call    ntfs_direntry_to_bdfe
1892
        call    ntfs_direntry_to_bdfe
1897
        pop     edi esi
1893
.end:
1898
        call    ntfs_unlock
1894
        call    ntfs_unlock
1899
        xor     eax, eax
1895
        xor     eax, eax
1900
        ret
1896
        ret
-
 
1897
 
-
 
1898
.volume:
-
 
1899
        mov     byte [edi], 8
-
 
1900
        mov     eax, [ebx+8]
-
 
1901
        mov     [edi+4], eax
-
 
1902
        mov     eax, dword [ebp+NTFS.Length]
-
 
1903
        mov     edx, dword [ebp+NTFS.Length+4]
-
 
1904
        shld    edx, eax, 9
-
 
1905
        shl     eax, 9
-
 
1906
        mov     [edi+36], edx
-
 
1907
        mov     [edi+32], eax
-
 
1908
        add     edi, 40
-
 
1909
        mov     [ebp+NTFS.cur_buf], edi
-
 
1910
        mov     [ebp+NTFS.cur_iRecord], 3
-
 
1911
        mov     [ebp+NTFS.cur_attr], 0x60
-
 
1912
        mov     [ebp+NTFS.cur_offs], 0
-
 
1913
        mov     [ebp+NTFS.cur_size], 1
-
 
1914
        call    ntfs_read_attr
-
 
1915
        jc      ntfsFail
-
 
1916
        mov     ecx, [ebp+NTFS.cur_read]
-
 
1917
        mov     [edi+ecx], ax
-
 
1918
        cmp     [ebx+8], eax
-
 
1919
        jnz     .end
-
 
1920
        mov     esi, edi
-
 
1921
        shr     ecx, 1
-
 
1922
@@:
-
 
1923
        lodsw
-
 
1924
        call    uni2ansi_char
-
 
1925
        stosb
-
 
1926
        dec     ecx
-
 
1927
        jnz     @b
-
 
1928
        mov     byte [edi], 0
-
 
1929
        jmp     .end
1901
 
1930
 
1902
;----------------------------------------------------------------
1931
;----------------------------------------------------------------
1903
ntfs_CreateFolder:
1932
ntfs_CreateFolder:
1904
        mov     [ebp+NTFS.bFolder], 1
1933
        mov     [ebp+NTFS.bFolder], 1
1905
        jmp     @f
1934
        jmp     @f
1906
 
1935
 
1907
ntfs_CreateFile:
1936
ntfs_CreateFile:
1908
        mov     [ebp+NTFS.bFolder], 0
1937
        mov     [ebp+NTFS.bFolder], 0
1909
@@:
1938
@@:
1910
        cmp     byte [esi], 0
1939
        cmp     byte [esi], 0
1911
        jnz     @f
1940
        jnz     @f
1912
        xor     ebx, ebx
1941
        xor     ebx, ebx
1913
        movi    eax, ERROR_ACCESS_DENIED
1942
        movi    eax, ERROR_ACCESS_DENIED
1914
        ret
1943
        ret
1915
 
1944
 
1916
@@: ; 1. Search file
1945
@@: ; 1. Search file
1917
        call    ntfs_lock
1946
        call    ntfs_lock
1918
        stdcall ntfs_find_lfn, [esp+4]
1947
        stdcall ntfs_find_lfn, [esp+4]
1919
        jc      .notFound
1948
        jc      .notFound
1920
; found, rewrite
1949
; found, rewrite
1921
        cmp     [ebp+NTFS.cur_iRecord], 16
1950
        cmp     [ebp+NTFS.cur_iRecord], 16
1922
        jc      ntfsDenied
1951
        jc      ntfsDenied
1923
        cmp     [ebp+NTFS.bFolder], 1
1952
        cmp     [ebp+NTFS.bFolder], 1
1924
        jz      .folder
1953
        jz      .folder
1925
        test    byte [eax+fileFlags], 1
1954
        test    byte [eax+fileFlags], 1
1926
        jnz     ntfsDenied
1955
        jnz     ntfsDenied
1927
        cmp     [ebp+NTFS.fragmentCount], 1
1956
        cmp     [ebp+NTFS.fragmentCount], 1
1928
        jnz     ntfsUnsupported     ; record fragmented
1957
        jnz     ntfsUnsupported     ; record fragmented
1929
; edit directory node
1958
; edit directory node
1930
        mov     edi, [ebp+NTFS.cur_index_buf]
1959
        mov     edi, [ebp+NTFS.cur_index_buf]
1931
        cmp     dword [edi], 'INDX'
1960
        cmp     dword [edi], 'INDX'
1932
        jz      @f
1961
        jz      @f
1933
        mov     esi, [ebp+NTFS.frs_buffer]
1962
        mov     esi, [ebp+NTFS.frs_buffer]
1934
        mov     ecx, [esi+recordRealSize]
1963
        mov     ecx, [esi+recordRealSize]
1935
        shr     ecx, 2
1964
        shr     ecx, 2
1936
        rep movsd
1965
        rep movsd
1937
        mov     esi, [ebp+NTFS.attr_offs]
1966
        mov     esi, [ebp+NTFS.attr_offs]
1938
        mov     cl, [esi+attributeOffset]
1967
        mov     cl, [esi+attributeOffset]
1939
        sub     esi, [ebp+NTFS.frs_buffer]
1968
        sub     esi, [ebp+NTFS.frs_buffer]
1940
        add     eax, ecx
1969
        add     eax, ecx
1941
        add     eax, esi
1970
        add     eax, esi
1942
@@:
1971
@@:
1943
        mov     edi, eax
1972
        mov     edi, eax
1944
        mov     eax, [ebx+12]
1973
        mov     eax, [ebx+12]
1945
        mov     [edi+fileRealSize], eax
1974
        mov     [edi+fileRealSize], eax
1946
        mov     dword [edi+fileRealSize+4], 0
1975
        mov     dword [edi+fileRealSize+4], 0
1947
        push    ebx eax
1976
        push    ebx eax
1948
        call    ntfsGetTime
1977
        call    ntfsGetTime
1949
        mov     [edi+fileModified], eax
1978
        mov     [edi+fileModified], eax
1950
        mov     [edi+fileModified+4], edx
1979
        mov     [edi+fileModified+4], edx
1951
        mov     [edi+recordModified], eax
1980
        mov     [edi+recordModified], eax
1952
        mov     [edi+recordModified+4], edx
1981
        mov     [edi+recordModified+4], edx
1953
        mov     [edi+fileAccessed], eax
1982
        mov     [edi+fileAccessed], eax
1954
        mov     [edi+fileAccessed+4], edx
1983
        mov     [edi+fileAccessed+4], edx
1955
        pop     edx ebx
1984
        pop     edx ebx
1956
        mov     eax, [ebp+NTFS.LastRead]
1985
        mov     eax, [ebp+NTFS.LastRead]
1957
        mov     [ebp+NTFS.nodeLastRead], eax
1986
        mov     [ebp+NTFS.nodeLastRead], eax
1958
        mov     [ebp+NTFS.cur_attr], 0x80
1987
        mov     [ebp+NTFS.cur_attr], 0x80
1959
        mov     [ebp+NTFS.cur_offs], 0
1988
        mov     [ebp+NTFS.cur_offs], 0
1960
        mov     [ebp+NTFS.cur_size], 0
1989
        mov     [ebp+NTFS.cur_size], 0
1961
        call    ntfs_read_attr
1990
        call    ntfs_read_attr
1962
        jc      ntfsFail
1991
        jc      ntfsFail
1963
        mov     esi, edi
1992
        mov     esi, edi
1964
        mov     edi, [ebp+NTFS.frs_buffer]
1993
        mov     edi, [ebp+NTFS.frs_buffer]
1965
        cmp     word [edi+baseRecordReuse], 0
1994
        cmp     word [edi+baseRecordReuse], 0
1966
        jnz     ntfsUnsupported     ; auxiliary record
1995
        jnz     ntfsUnsupported     ; auxiliary record
1967
        mov     al, [edi+attributeOffset]
1996
        mov     al, [edi+attributeOffset]
1968
        add     edi, eax
1997
        add     edi, eax
1969
        mov     al, [edi+attributeOffset]
1998
        mov     al, [edi+attributeOffset]
1970
        add     edi, eax
1999
        add     edi, eax
1971
        mov     ecx, 6
2000
        mov     ecx, 6
1972
        add     esi, fileModified
2001
        add     esi, fileModified
1973
        add     edi, 8
2002
        add     edi, 8
1974
        rep movsd
2003
        rep movsd
1975
        mov     eax, edx
2004
        mov     eax, edx
1976
        xor     edx, edx
2005
        xor     edx, edx
1977
        mov     ecx, [ebp+NTFS.attr_offs]
2006
        mov     ecx, [ebp+NTFS.attr_offs]
1978
        cmp     word [ecx+attributeFlags], 0
2007
        cmp     word [ecx+attributeFlags], 0
1979
        jnz     ntfsUnsupported
2008
        jnz     ntfsUnsupported
1980
        push    ebx
2009
        push    ebx
1981
        cmp     byte [ecx+nonResidentFlag], 0
2010
        cmp     byte [ecx+nonResidentFlag], 0
1982
        jz      @f
2011
        jz      @f
1983
        cmp     [ecx+attributeRealSize+4], edx
2012
        cmp     [ecx+attributeRealSize+4], edx
1984
        jnz     @f
2013
        jnz     @f
1985
        cmp     [ecx+attributeRealSize], eax
2014
        cmp     [ecx+attributeRealSize], eax
1986
        jz      ntfs_WriteFile.writeNode
2015
        jz      ntfs_WriteFile.writeNode
1987
@@:
2016
@@:
1988
        jmp     ntfs_WriteFile.resizeAttribute
2017
        jmp     ntfs_WriteFile.resizeAttribute
1989
 
2018
 
1990
.folder:
2019
.folder:
1991
        bt      dword [eax+fileFlags], 28
2020
        bt      dword [eax+fileFlags], 28
1992
        jnc     ntfsDenied
2021
        jnc     ntfsDenied
1993
        push    0
2022
        push    0
1994
        jmp     ntfsOut
2023
        jmp     ntfsOut
1995
 
2024
 
1996
.notFound:  ; create
2025
.notFound:  ; create
1997
        test    eax, eax
2026
        test    eax, eax
1998
        jz      ntfsFail
2027
        jz      ntfsFail
1999
        cmp     [ebp+NTFS.fragmentCount], 1
2028
        cmp     [ebp+NTFS.fragmentCount], 1
2000
        jnz     ntfsUnsupported     ; record fragmented
2029
        jnz     ntfsUnsupported     ; record fragmented
2001
; 2. Prepare directory record
2030
; 2. Prepare directory record
2002
        mov     ecx, esi
2031
        mov     ecx, esi
2003
@@:         ; count characters
2032
@@:         ; count characters
2004
        inc     ecx
2033
        inc     ecx
2005
        cmp     byte [ecx], '/'
2034
        cmp     byte [ecx], '/'
2006
        jz      ntfsNotFound    ; path folder not found
2035
        jz      ntfsNotFound    ; path folder not found
2007
        cmp     byte [ecx], 0
2036
        cmp     byte [ecx], 0
2008
        jnz     @b
2037
        jnz     @b
2009
        sub     ecx, esi
2038
        sub     ecx, esi
2010
        push    ecx     ; name length
2039
        push    ecx     ; name length
2011
        shl     ecx, 1
2040
        shl     ecx, 1
2012
        add     ecx, fileName+7
2041
        add     ecx, fileName+7
2013
        and     ecx, not 7
2042
        and     ecx, not 7
2014
        mov     edi, [ebp+NTFS.cur_index_buf]
2043
        mov     edi, [ebp+NTFS.cur_index_buf]
2015
        mov     edx, [ebx+12]
2044
        mov     edx, [ebx+12]
2016
        mov     [ebp+NTFS.fileRealSize], edx
2045
        mov     [ebp+NTFS.fileRealSize], edx
2017
        mov     edx, [ebx+16]
2046
        mov     edx, [ebx+16]
2018
        mov     [ebp+NTFS.fileDataBuffer], edx
2047
        mov     [ebp+NTFS.fileDataBuffer], edx
2019
        push    esi
2048
        push    esi
2020
        push    ecx     ; index length
2049
        push    ecx     ; index length
2021
        mov     edx, ecx
2050
        mov     edx, ecx
2022
        cmp     dword [edi], 'INDX'
2051
        cmp     dword [edi], 'INDX'
2023
        jz      .indexRecord
2052
        jz      .indexRecord
2024
        mov     esi, [ebp+NTFS.frs_buffer]  ; indexRoot
2053
        mov     esi, [ebp+NTFS.frs_buffer]  ; indexRoot
2025
        mov     ecx, [esi+recordRealSize]
2054
        mov     ecx, [esi+recordRealSize]
2026
        add     edx, ecx
2055
        add     edx, ecx
2027
        cmp     [esi+recordAllocatedSize], edx
2056
        cmp     [esi+recordAllocatedSize], edx
2028
        jc      .growTree
2057
        jc      .growTree
2029
        mov     [esi+recordRealSize], edx
2058
        mov     [esi+recordRealSize], edx
2030
        shr     ecx, 2
2059
        shr     ecx, 2
2031
        rep movsd
2060
        rep movsd
2032
        mov     edi, [ebp+NTFS.indexRoot]
2061
        mov     edi, [ebp+NTFS.indexRoot]
2033
        sub     edi, [ebp+NTFS.frs_buffer]
2062
        sub     edi, [ebp+NTFS.frs_buffer]
2034
        add     edi, [ebp+NTFS.cur_index_buf]
2063
        add     edi, [ebp+NTFS.cur_index_buf]
2035
        mov     esi, [esp]
2064
        mov     esi, [esp]
2036
        add     [edi+sizeWithHeader], esi
2065
        add     [edi+sizeWithHeader], esi
2037
        add     [edi+sizeWithoutHeader], esi
2066
        add     [edi+sizeWithoutHeader], esi
2038
        mov     cl, [edi+attributeOffset]
2067
        mov     cl, [edi+attributeOffset]
2039
        add     edi, ecx
2068
        add     edi, ecx
2040
        add     [edi+rootNode+nodeRealSize], esi
2069
        add     [edi+rootNode+nodeRealSize], esi
2041
        add     [edi+rootNode+nodeAllocatedSize], esi
2070
        add     [edi+rootNode+nodeAllocatedSize], esi
2042
        sub     eax, [ebp+NTFS.cur_index_buf]
2071
        sub     eax, [ebp+NTFS.cur_index_buf]
2043
        add     eax, edi
2072
        add     eax, edi
2044
        mov     edi, [ebp+NTFS.cur_index_buf]
2073
        mov     edi, [ebp+NTFS.cur_index_buf]
2045
        jmp     .common
2074
        jmp     .common
2046
 
2075
 
2047
.growTree:  ; create indexRecord
2076
.growTree:  ; create indexRecord
2048
        mov     edi, [ebp+NTFS.cur_index_buf]
2077
        mov     edi, [ebp+NTFS.cur_index_buf]
2049
        mov     ecx, 10
2078
        mov     ecx, 10
2050
        xor     eax, eax
2079
        xor     eax, eax
2051
        rep stosd
2080
        rep stosd
2052
        mov     esi, [ebp+NTFS.indexRoot]
2081
        mov     esi, [ebp+NTFS.indexRoot]
2053
        mov     al, [esi+attributeOffset]
2082
        mov     al, [esi+attributeOffset]
2054
        add     esi, eax
2083
        add     esi, eax
2055
        rdtsc
2084
        rdtsc
2056
        stosw
2085
        stosw
2057
        mov     eax, [esi+indexRecordSize]
2086
        mov     eax, [esi+indexRecordSize]
2058
        cmp     eax, [ebp+NTFS.frs_size]
2087
        cmp     eax, [ebp+NTFS.frs_size]
2059
        jc      .errorPop3
2088
        jc      .errorPop3
2060
        shr     eax, 9
2089
        shr     eax, 9
2061
        inc     eax
2090
        inc     eax
2062
        mov     edi, [ebp+NTFS.cur_index_buf]
2091
        mov     edi, [ebp+NTFS.cur_index_buf]
2063
        mov     dword[edi], 'INDX'
2092
        mov     dword[edi], 'INDX'
2064
        mov     byte [edi+updateSequenceOffset], 28h
2093
        mov     byte [edi+updateSequenceOffset], 28h
2065
        mov     [edi+updateSequenceSize], al
2094
        mov     [edi+updateSequenceSize], al
2066
        add     edi, recordNode
2095
        add     edi, recordNode
2067
        shl     eax, 1
2096
        shl     eax, 1
2068
        add     eax, 28h-recordNode+7
2097
        add     eax, 28h-recordNode+7
2069
        and     eax, not 7
2098
        and     eax, not 7
2070
        mov     [edi+indexOffset], eax
2099
        mov     [edi+indexOffset], eax
2071
        mov     ecx, [esi+indexRecordSize]
2100
        mov     ecx, [esi+indexRecordSize]
2072
        sub     ecx, recordNode
2101
        sub     ecx, recordNode
2073
        mov     [edi+nodeAllocatedSize], ecx
2102
        mov     [edi+nodeAllocatedSize], ecx
2074
        add     esi, rootNode
2103
        add     esi, rootNode
2075
        push    esi
2104
        push    esi
2076
        mov     ecx, [esi+nodeRealSize]
2105
        mov     ecx, [esi+nodeRealSize]
2077
        sub     ecx, [esi+indexOffset]
2106
        sub     ecx, [esi+indexOffset]
2078
        add     eax, ecx
2107
        add     eax, ecx
2079
        mov     [edi+nodeRealSize], eax
2108
        mov     [edi+nodeRealSize], eax
2080
        mov     eax, [esi+nonLeafFlag]
2109
        mov     eax, [esi+nonLeafFlag]
2081
        mov     [edi+nonLeafFlag], eax
2110
        mov     [edi+nonLeafFlag], eax
2082
        shr     ecx, 2
2111
        shr     ecx, 2
2083
        add     esi, [esi+indexOffset]
2112
        add     esi, [esi+indexOffset]
2084
        add     edi, [edi+indexOffset]
2113
        add     edi, [edi+indexOffset]
2085
        rep movsd       ; copy root indexes
2114
        rep movsd       ; copy root indexes
2086
; clear root node
2115
; clear root node
2087
        mov     cl, 10
2116
        mov     cl, 10
2088
        mov     edi, [esp]
2117
        mov     edi, [esp]
2089
        xor     eax, eax
2118
        xor     eax, eax
2090
        rep stosd
2119
        rep stosd
2091
        pop     edi
2120
        pop     edi
2092
        mov     byte [edi+indexOffset], 16
2121
        mov     byte [edi+indexOffset], 16
2093
        mov     byte [edi+nodeRealSize], 28h
2122
        mov     byte [edi+nodeRealSize], 28h
2094
        mov     byte [edi+nodeAllocatedSize], 28h
2123
        mov     byte [edi+nodeAllocatedSize], 28h
2095
        mov     byte [edi+nonLeafFlag], 1
2124
        mov     byte [edi+nonLeafFlag], 1
2096
        mov     byte [edi+16+indexAllocatedSize], 18h
2125
        mov     byte [edi+16+indexAllocatedSize], 18h
2097
        mov     byte [edi+16+indexFlags], 3
2126
        mov     byte [edi+16+indexFlags], 3
2098
        mov     esi, [ebp+NTFS.indexRoot]
2127
        mov     esi, [ebp+NTFS.indexRoot]
2099
        add     edi, 28h
2128
        add     edi, 28h
2100
        mov     eax, edi
2129
        mov     eax, edi
2101
        sub     eax, esi
2130
        sub     eax, esi
2102
        mov     word [esi+sizeWithoutHeader], 38h
2131
        mov     word [esi+sizeWithoutHeader], 38h
2103
        xchg    [esi+sizeWithHeader], eax
2132
        xchg    [esi+sizeWithHeader], eax
2104
        add     esi, eax
2133
        add     esi, eax
2105
        mov     [ebp+NTFS.attr_offs], edi
2134
        mov     [ebp+NTFS.attr_offs], edi
2106
        cmp     byte [esi], 0xA0
2135
        cmp     byte [esi], 0xA0
2107
        jnz     @f
2136
        jnz     @f
2108
        cmp     dword [esi+attributeAllocatedSize], 0
2137
        cmp     dword [esi+attributeAllocatedSize], 0
2109
        jz      @f
2138
        jz      @f
2110
        mov     eax, [ebp+NTFS.frs_buffer]
2139
        mov     eax, [ebp+NTFS.frs_buffer]
2111
        mov     ecx, eax
2140
        mov     ecx, eax
2112
        add     ecx, [eax+recordRealSize]
2141
        add     ecx, [eax+recordRealSize]
2113
        sub     ecx, esi
2142
        sub     ecx, esi
2114
        shr     ecx, 2
2143
        shr     ecx, 2
2115
        rep movsd
2144
        rep movsd
2116
        sub     edi, eax
2145
        sub     edi, eax
2117
        mov     [eax+recordRealSize], edi
2146
        mov     [eax+recordRealSize], edi
2118
        call    .ntfsNodeAlloc
2147
        call    .ntfsNodeAlloc
2119
        jc      ntfsErrorPop3
2148
        jc      ntfsErrorPop3
2120
        mov     eax, [ebp+NTFS.newRecord]
2149
        mov     eax, [ebp+NTFS.newRecord]
2121
        mov     edi, [ebp+NTFS.cur_index_buf]
2150
        mov     edi, [ebp+NTFS.cur_index_buf]
2122
        mov     [edi+recordVCN], eax
2151
        mov     [edi+recordVCN], eax
2123
        mov     edi, [ebp+NTFS.attr_offs]
2152
        mov     edi, [ebp+NTFS.attr_offs]
2124
        mov     [edi-8], eax
2153
        mov     [edi-8], eax
2125
        jmp     .refresh
2154
        jmp     .refresh
2126
 
2155
 
2127
@@:
2156
@@:
2128
        mov     cl, 32
2157
        mov     cl, 32
2129
        xor     eax, eax
2158
        xor     eax, eax
2130
        rep stosd
2159
        rep stosd
2131
        mov     eax, [ebp+NTFS.cur_subnode_size]
2160
        mov     eax, [ebp+NTFS.cur_subnode_size]
2132
        cmp     eax, [ebp+NTFS.cur_size]
2161
        cmp     eax, [ebp+NTFS.cur_size]
2133
        jnz     @f
2162
        jnz     @f
2134
        mov     al, 1
2163
        mov     al, 1
2135
@@:
2164
@@:
2136
        mov     [ebp+NTFS.fileDataSize], eax
2165
        mov     [ebp+NTFS.fileDataSize], eax
2137
        mov     edi, [ebp+NTFS.BitmapStart]
2166
        mov     edi, [ebp+NTFS.BitmapStart]
2138
        call    ntfsSpaceAlloc
2167
        call    ntfsSpaceAlloc
2139
        movi    eax, ERROR_DISK_FULL
2168
        movi    eax, ERROR_DISK_FULL
2140
        jc      ntfsErrorPop3
2169
        jc      ntfsErrorPop3
2141
; create $IndexAllocation
2170
; create $IndexAllocation
2142
        mov     edi, [ebp+NTFS.attr_offs]
2171
        mov     edi, [ebp+NTFS.attr_offs]
2143
        mov     byte [edi+attributeType], 0xA0
2172
        mov     byte [edi+attributeType], 0xA0
2144
        mov     byte [edi+nonResidentFlag], 1
2173
        mov     byte [edi+nonResidentFlag], 1
2145
        mov     byte [edi+nameLength], 4
2174
        mov     byte [edi+nameLength], 4
2146
        mov     byte [edi+nameOffset], 40h
2175
        mov     byte [edi+nameOffset], 40h
2147
        mov     byte [edi+dataRunsOffset], 48h
2176
        mov     byte [edi+dataRunsOffset], 48h
2148
        mov     byte [edi+sizeWithHeader], 50h
2177
        mov     byte [edi+sizeWithHeader], 50h
2149
        mov     eax, [ebp+NTFS.fileDataSize]
2178
        mov     eax, [ebp+NTFS.fileDataSize]
2150
        dec     eax
2179
        dec     eax
2151
        mov     [edi+lastVCN], eax
2180
        mov     [edi+lastVCN], eax
2152
        inc     eax
2181
        inc     eax
2153
        mul     [ebp+NTFS.sectors_per_cluster]
2182
        mul     [ebp+NTFS.sectors_per_cluster]
2154
        shl     eax, 9
2183
        shl     eax, 9
2155
        mov     [edi+attributeAllocatedSize], eax
2184
        mov     [edi+attributeAllocatedSize], eax
2156
        mov     [edi+attributeRealSize], eax
2185
        mov     [edi+attributeRealSize], eax
2157
        mov     [edi+initialDataSize], eax
2186
        mov     [edi+initialDataSize], eax
2158
        mov     dword[edi+40h], 490024h     ; unicode $I30
2187
        mov     dword[edi+40h], 490024h     ; unicode $I30
2159
        mov     dword[edi+40h+4], 300033h
2188
        mov     dword[edi+40h+4], 300033h
2160
        push    edi
2189
        push    edi
2161
        mov     esi, edi
2190
        mov     esi, edi
2162
        add     edi, 48h
2191
        add     edi, 48h
2163
        call    createMcbEntry
2192
        call    createMcbEntry
2164
        mov     esi, [ebp+NTFS.frs_buffer]
2193
        mov     esi, [ebp+NTFS.frs_buffer]
2165
        pop     edi
2194
        pop     edi
2166
        mov     al, [esi+newAttributeID]
2195
        mov     al, [esi+newAttributeID]
2167
        mov     [edi+attributeID], al
2196
        mov     [edi+attributeID], al
2168
        add     edi, 50h
2197
        add     edi, 50h
2169
        inc     eax
2198
        inc     eax
2170
; create $Bitmap
2199
; create $Bitmap
2171
        mov     [edi+attributeID], al
2200
        mov     [edi+attributeID], al
2172
        inc     eax
2201
        inc     eax
2173
        mov     [esi+newAttributeID], al
2202
        mov     [esi+newAttributeID], al
2174
        mov     byte [edi+attributeType], 0xB0
2203
        mov     byte [edi+attributeType], 0xB0
2175
        mov     byte [edi+nameLength], 4
2204
        mov     byte [edi+nameLength], 4
2176
        mov     byte [edi+nameOffset], 18h
2205
        mov     byte [edi+nameOffset], 18h
2177
        mov     byte [edi+attributeOffset], 20h
2206
        mov     byte [edi+attributeOffset], 20h
2178
        mov     byte [edi+sizeWithoutHeader], 8
2207
        mov     byte [edi+sizeWithoutHeader], 8
2179
        mov     byte [edi+sizeWithHeader], 28h
2208
        mov     byte [edi+sizeWithHeader], 28h
2180
        mov     dword[edi+18h], 490024h     ; unicode $I30
2209
        mov     dword[edi+18h], 490024h     ; unicode $I30
2181
        mov     dword[edi+18h+4], 300033h
2210
        mov     dword[edi+18h+4], 300033h
2182
        mov     byte [edi+20h], 1
2211
        mov     byte [edi+20h], 1
2183
        mov     dword[edi+28h], -1
2212
        mov     dword[edi+28h], -1
2184
        add     edi, 30h
2213
        add     edi, 30h
2185
        sub     edi, esi
2214
        sub     edi, esi
2186
        mov     [esi+recordRealSize], edi
2215
        mov     [esi+recordRealSize], edi
2187
        mov     eax, [ebp+NTFS.fileDataStart]
2216
        mov     eax, [ebp+NTFS.fileDataStart]
2188
        mul     [ebp+NTFS.sectors_per_cluster]
2217
        mul     [ebp+NTFS.sectors_per_cluster]
2189
        mov     edx, eax
2218
        mov     edx, eax
2190
        jmp     @f
2219
        jmp     @f
2191
 
2220
 
2192
.refresh:
2221
.refresh:
2193
        mov     [ebp+NTFS.cur_size], 0
2222
        mov     [ebp+NTFS.cur_size], 0
2194
        call    ntfs_read_attr.continue
2223
        call    ntfs_read_attr.continue
2195
        movi    eax, ERROR_FS_FAIL
2224
        movi    eax, ERROR_FS_FAIL
2196
        jc      ntfsErrorPop3
2225
        jc      ntfsErrorPop3
2197
        mov     edx, [ebp+NTFS.LastRead]
2226
        mov     edx, [ebp+NTFS.LastRead]
2198
@@:
2227
@@:
2199
        mov     ebx, [ebp+NTFS.cur_index_buf]
2228
        mov     ebx, [ebp+NTFS.cur_index_buf]
2200
        call    writeRecord
2229
        call    writeRecord
2201
        mov     ebx, [ebp+NTFS.frs_buffer]
2230
        mov     ebx, [ebp+NTFS.frs_buffer]
2202
        mov     edx, [ebp+NTFS.rootLastRead]
2231
        mov     edx, [ebp+NTFS.rootLastRead]
2203
        call    writeRecord
2232
        call    writeRecord
2204
        mov     esi, [esp+4]
2233
        mov     esi, [esp+4]
2205
        stdcall ntfs_find_lfn.doit2, 0
2234
        stdcall ntfs_find_lfn.doit2, 0
2206
        test    eax, eax
2235
        test    eax, eax
2207
        jz      .errorPop3
2236
        jz      .errorPop3
2208
        mov     edi, [ebp+NTFS.cur_index_buf]
2237
        mov     edi, [ebp+NTFS.cur_index_buf]
2209
        mov     edx, [esp]
2238
        mov     edx, [esp]
2210
.indexRecord:
2239
.indexRecord:
2211
        add     edi, recordNode
2240
        add     edi, recordNode
2212
        add     edx, [edi+nodeRealSize]
2241
        add     edx, [edi+nodeRealSize]
2213
        cmp     [edi+nodeAllocatedSize], edx
2242
        cmp     [edi+nodeAllocatedSize], edx
2214
        jc      .arborizeTree
2243
        jc      .arborizeTree
2215
        mov     [edi+nodeRealSize], edx
2244
        mov     [edi+nodeRealSize], edx
2216
        jmp     .common
2245
        jmp     .common
2217
 
2246
 
2218
.errorPop3:
2247
.errorPop3:
2219
        add     esp, 12
2248
        add     esp, 12
2220
        jmp     ntfsUnsupported
2249
        jmp     ntfsUnsupported
2221
 
2250
 
2222
.ntfsNodeAlloc:
2251
.ntfsNodeAlloc:
2223
; in: [ebp+NTFS.attr_offs] -> $IndexAllocation
2252
; in: [ebp+NTFS.attr_offs] -> $IndexAllocation
2224
;   out:
2253
;   out:
2225
; [ebp+NTFS.newRecord] = node VCN
2254
; [ebp+NTFS.newRecord] = node VCN
2226
; [ebp+NTFS.cur_offs]
2255
; [ebp+NTFS.cur_offs]
2227
; CF=1 -> eax = error code
2256
; CF=1 -> eax = error code
2228
        mov     esi, [ebp+NTFS.attr_offs]
2257
        mov     esi, [ebp+NTFS.attr_offs]
2229
        add     esi, [esi+sizeWithHeader]
2258
        add     esi, [esi+sizeWithHeader]
2230
        cmp     byte [esi], 0xB0
2259
        cmp     byte [esi], 0xB0
2231
        jnz     .ret
2260
        jnz     .ret
2232
        movzx   ecx, word [esi+sizeWithoutHeader]
2261
        movzx   ecx, word [esi+sizeWithoutHeader]
2233
        shr     ecx, 2
2262
        shr     ecx, 2
2234
        movzx   edi, byte [esi+attributeOffset]
2263
        movzx   edi, byte [esi+attributeOffset]
2235
        add     edi, esi
2264
        add     edi, esi
2236
        mov     edx, edi
2265
        mov     edx, edi
2237
        or      eax, -1
2266
        or      eax, -1
2238
        repz scasd
2267
        repz scasd
2239
        jnz     @f
2268
        jnz     @f
2240
        cmp     [edi], eax
2269
        cmp     [edi], eax
2241
        jnz     .ret
2270
        jnz     .ret
2242
; extend folder $Bitmap
2271
; extend folder $Bitmap
2243
        add     word [esi+sizeWithHeader], 8
2272
        add     word [esi+sizeWithHeader], 8
2244
        add     word [esi+sizeWithoutHeader], 8
2273
        add     word [esi+sizeWithoutHeader], 8
2245
        mov     esi, [ebp+NTFS.frs_buffer]
2274
        mov     esi, [ebp+NTFS.frs_buffer]
2246
        mov     eax, [esi+recordRealSize]
2275
        mov     eax, [esi+recordRealSize]
2247
        add     eax, 8
2276
        add     eax, 8
2248
        cmp     [esi+recordAllocatedSize], eax
2277
        cmp     [esi+recordAllocatedSize], eax
2249
        jc      .ret
2278
        jc      .ret
2250
        mov     [esi+recordRealSize], eax
2279
        mov     [esi+recordRealSize], eax
2251
        xor     eax, eax
2280
        xor     eax, eax
2252
        stosd
2281
        stosd
2253
        mov     [edi], eax
2282
        mov     [edi], eax
2254
        mov     [edi+8], eax
2283
        mov     [edi+8], eax
2255
        dec     eax
2284
        dec     eax
2256
        mov     [edi+4], eax
2285
        mov     [edi+4], eax
2257
@@:
2286
@@:
2258
        sub     edi, 4
2287
        sub     edi, 4
2259
        mov     eax, [edi]
2288
        mov     eax, [edi]
2260
        not     eax
2289
        not     eax
2261
        bsf     eax, eax
2290
        bsf     eax, eax
2262
        bts     [edi], eax
2291
        bts     [edi], eax
2263
        sub     edi, edx
2292
        sub     edi, edx
2264
        shl     edi, 3
2293
        shl     edi, 3
2265
        add     eax, edi
2294
        add     eax, edi
2266
        mul     [ebp+NTFS.cur_subnode_size]
2295
        mul     [ebp+NTFS.cur_subnode_size]
2267
        mov     [ebp+NTFS.newRecord], eax
2296
        mov     [ebp+NTFS.newRecord], eax
2268
        mov     ecx, [ebp+NTFS.cur_size]
2297
        mov     ecx, [ebp+NTFS.cur_size]
2269
        cmp     ecx, [ebp+NTFS.cur_subnode_size]
2298
        cmp     ecx, [ebp+NTFS.cur_subnode_size]
2270
        jz      @f
2299
        jz      @f
2271
        mul     [ebp+NTFS.sectors_per_cluster]
2300
        mul     [ebp+NTFS.sectors_per_cluster]
2272
@@:
2301
@@:
2273
        mov     [ebp+NTFS.cur_offs], eax
2302
        mov     [ebp+NTFS.cur_offs], eax
2274
        add     eax, ecx
2303
        add     eax, ecx
2275
        shl     eax, 9
2304
        shl     eax, 9
2276
        mov     esi, [ebp+NTFS.attr_offs]
2305
        mov     esi, [ebp+NTFS.attr_offs]
2277
        cmp     [esi+attributeAllocatedSize], eax
2306
        cmp     [esi+attributeAllocatedSize], eax
2278
        jnc     @f
2307
        jnc     @f
2279
        xor     edx, edx
2308
        xor     edx, edx
2280
        jmp     resizeAttribute
2309
        jmp     resizeAttribute
2281
 
2310
 
2282
.ret:
2311
.ret:
2283
        movi    eax, ERROR_UNSUPPORTED_FS
2312
        movi    eax, ERROR_UNSUPPORTED_FS
2284
        stc
2313
        stc
2285
@@:
2314
@@:
2286
        ret
2315
        ret
2287
 
2316
 
2288
.arborizeTree:      ; find median index
2317
.arborizeTree:      ; find median index
2289
        mov     ecx, [edi+nodeRealSize]
2318
        mov     ecx, [edi+nodeRealSize]
2290
        sub     ecx, [edi+indexOffset]
2319
        sub     ecx, [edi+indexOffset]
2291
        shr     ecx, 1
2320
        shr     ecx, 1
2292
        add     edi, [edi+indexOffset]
2321
        add     edi, [edi+indexOffset]
2293
        xor     eax, eax
2322
        xor     eax, eax
2294
@@:
2323
@@:
2295
        add     edi, eax
2324
        add     edi, eax
2296
        mov     ax, [edi+indexAllocatedSize]
2325
        mov     ax, [edi+indexAllocatedSize]
2297
        sub     ecx, eax
2326
        sub     ecx, eax
2298
        jnc     @b
2327
        jnc     @b
2299
        add     eax, 8
2328
        add     eax, 8
2300
        mov     esi, [ebp+NTFS.secondIndexBuffer]
2329
        mov     esi, [ebp+NTFS.secondIndexBuffer]
2301
        cmp     dword [esi], 'INDX'
2330
        cmp     dword [esi], 'INDX'
2302
        jz      @f
2331
        jz      @f
2303
; move index to the root node
2332
; move index to the root node
2304
        mov     esi, [ebp+NTFS.frs_buffer]
2333
        mov     esi, [ebp+NTFS.frs_buffer]
2305
        mov     ecx, eax
2334
        mov     ecx, eax
2306
        add     ecx, 8
2335
        add     ecx, 8
2307
        add     ecx, [esi+recordRealSize]
2336
        add     ecx, [esi+recordRealSize]
2308
        cmp     [esi+recordAllocatedSize], ecx
2337
        cmp     [esi+recordAllocatedSize], ecx
2309
        jc      .growTree
2338
        jc      .growTree
2310
        push    edi eax
2339
        push    edi eax
2311
        call    .ntfsNodeAlloc
2340
        call    .ntfsNodeAlloc
2312
        jc      ntfsErrorPop5
2341
        jc      ntfsErrorPop5
2313
        pop     eax
2342
        pop     eax
2314
        mov     edi, [ebp+NTFS.indexRoot]
2343
        mov     edi, [ebp+NTFS.indexRoot]
2315
        add     [ebp+NTFS.attr_offs], eax
2344
        add     [ebp+NTFS.attr_offs], eax
2316
        add     [edi+sizeWithHeader], eax
2345
        add     [edi+sizeWithHeader], eax
2317
        add     [edi+sizeWithoutHeader], eax
2346
        add     [edi+sizeWithoutHeader], eax
2318
        movzx   ecx, byte [edi+attributeOffset]
2347
        movzx   ecx, byte [edi+attributeOffset]
2319
        add     ecx, edi
2348
        add     ecx, edi
2320
        add     [ecx+rootNode+nodeRealSize], eax
2349
        add     [ecx+rootNode+nodeRealSize], eax
2321
        add     [ecx+rootNode+nodeAllocatedSize], eax
2350
        add     [ecx+rootNode+nodeAllocatedSize], eax
2322
        add     ecx, [ebp+NTFS.indexPointer]
2351
        add     ecx, [ebp+NTFS.indexPointer]
2323
        sub     ecx, [ebp+NTFS.secondIndexBuffer]
2352
        sub     ecx, [ebp+NTFS.secondIndexBuffer]
2324
        mov     esi, [ebp+NTFS.frs_buffer]
2353
        mov     esi, [ebp+NTFS.frs_buffer]
2325
        add     [esi+recordRealSize], eax
2354
        add     [esi+recordRealSize], eax
2326
        add     esi, [esi+recordRealSize]
2355
        add     esi, [esi+recordRealSize]
2327
        mov     edi, esi
2356
        mov     edi, esi
2328
        sub     esi, eax
2357
        sub     esi, eax
2329
        neg     ecx
2358
        neg     ecx
2330
        add     ecx, esi
2359
        add     ecx, esi
2331
        shr     ecx, 2
2360
        shr     ecx, 2
2332
        sub     esi, 4
2361
        sub     esi, 4
2333
        sub     edi, 4
2362
        sub     edi, 4
2334
        std
2363
        std
2335
        rep movsd   ; make space
2364
        rep movsd   ; make space
2336
        mov     [edi], ecx
2365
        mov     [edi], ecx
2337
        mov     edi, esi
2366
        mov     edi, esi
2338
        add     edi, 4
2367
        add     edi, 4
2339
        mov     esi, [esp]
2368
        mov     esi, [esp]
2340
        add     word [esi+indexAllocatedSize], 8
2369
        add     word [esi+indexAllocatedSize], 8
2341
        mov     byte [esi+indexFlags], 1
2370
        mov     byte [esi+indexFlags], 1
2342
        mov     ecx, eax
2371
        mov     ecx, eax
2343
        sub     ecx, 8
2372
        sub     ecx, 8
2344
        shr     ecx, 2
2373
        shr     ecx, 2
2345
        cld
2374
        cld
2346
        rep movsd   ; insert index
2375
        rep movsd   ; insert index
2347
        mov     eax, [ebp+NTFS.newRecord]
2376
        mov     eax, [ebp+NTFS.newRecord]
2348
        stosd
2377
        stosd
2349
        jmp     .splitNode
2378
        jmp     .splitNode
2350
 
2379
 
2351
.growBranch:    ; move node and replace it with empty one
2380
.growBranch:    ; move node and replace it with empty one
2352
        mov     esi, [ebp+NTFS.cur_index_buf]
2381
        mov     esi, [ebp+NTFS.cur_index_buf]
2353
        mov     edi, [ebp+NTFS.secondIndexBuffer]
2382
        mov     edi, [ebp+NTFS.secondIndexBuffer]
2354
        mov     eax, [esi+recordVCN]
2383
        mov     eax, [esi+recordVCN]
2355
        mov     [edi+recordVCN], eax
2384
        mov     [edi+recordVCN], eax
2356
        add     edi, recordNode
2385
        add     edi, recordNode
2357
        mov     eax, [edi+indexOffset]
2386
        mov     eax, [edi+indexOffset]
2358
        add     eax, 18h
2387
        add     eax, 18h
2359
        mov     [edi+nodeRealSize], eax
2388
        mov     [edi+nodeRealSize], eax
2360
        add     edi, [edi+indexOffset]
2389
        add     edi, [edi+indexOffset]
2361
        mov     ecx, 6
2390
        mov     ecx, 6
2362
        xor     eax, eax
2391
        xor     eax, eax
2363
        mov     [ebp+NTFS.indexPointer], edi
2392
        mov     [ebp+NTFS.indexPointer], edi
2364
        push    edi
2393
        push    edi
2365
        rep stosd
2394
        rep stosd
2366
        pop     edi
2395
        pop     edi
2367
        mov     eax, [ebp+NTFS.newRecord]
2396
        mov     eax, [ebp+NTFS.newRecord]
2368
        mov     byte [edi+indexAllocatedSize], 18h
2397
        mov     byte [edi+indexAllocatedSize], 18h
2369
        mov     byte [edi+indexFlags], 3
2398
        mov     byte [edi+indexFlags], 3
2370
        mov     [edi+16], eax
2399
        mov     [edi+16], eax
2371
        mov     [esi+recordVCN], eax
2400
        mov     [esi+recordVCN], eax
2372
        mov     eax, [ebp+NTFS.LastRead]
2401
        mov     eax, [ebp+NTFS.LastRead]
2373
        mov     [ebp+NTFS.nodeLastRead], eax
2402
        mov     [ebp+NTFS.nodeLastRead], eax
2374
        push    [ebp+NTFS.cur_size]
2403
        push    [ebp+NTFS.cur_size]
2375
        mov     [ebp+NTFS.cur_size], 0
2404
        mov     [ebp+NTFS.cur_size], 0
2376
        call    ntfs_read_attr.continue
2405
        call    ntfs_read_attr.continue
2377
        pop     [ebp+NTFS.cur_size]
2406
        pop     [ebp+NTFS.cur_size]
2378
        movi    eax, ERROR_FS_FAIL
2407
        movi    eax, ERROR_FS_FAIL
2379
        jc      ntfsErrorPop5
2408
        jc      ntfsErrorPop5
2380
        pop     eax edi
2409
        pop     eax edi
2381
@@:         ; move index to the branch node
2410
@@:         ; move index to the branch node
2382
        push    edi eax
2411
        push    edi eax
2383
        call    .ntfsNodeAlloc
2412
        call    .ntfsNodeAlloc
2384
        jc      ntfsErrorPop5
2413
        jc      ntfsErrorPop5
2385
        mov     eax, [esp]
2414
        mov     eax, [esp]
2386
        mov     esi, [ebp+NTFS.secondIndexBuffer]
2415
        mov     esi, [ebp+NTFS.secondIndexBuffer]
2387
        add     esi, recordNode
2416
        add     esi, recordNode
2388
        mov     ecx, [esi+nodeRealSize]
2417
        mov     ecx, [esi+nodeRealSize]
2389
        add     eax, ecx
2418
        add     eax, ecx
2390
        cmp     [esi+nodeAllocatedSize], eax
2419
        cmp     [esi+nodeAllocatedSize], eax
2391
        jc      .growBranch
2420
        jc      .growBranch
2392
        mov     [esi+nodeRealSize], eax
2421
        mov     [esi+nodeRealSize], eax
2393
        lea     edi, [esi+eax-4]
2422
        lea     edi, [esi+eax-4]
2394
        add     esi, ecx
2423
        add     esi, ecx
2395
        mov     ecx, esi
2424
        mov     ecx, esi
2396
        sub     ecx, [ebp+NTFS.indexPointer]
2425
        sub     ecx, [ebp+NTFS.indexPointer]
2397
        shr     ecx, 2
2426
        shr     ecx, 2
2398
        sub     esi, 4
2427
        sub     esi, 4
2399
        std
2428
        std
2400
        rep movsd   ; make space
2429
        rep movsd   ; make space
2401
        mov     [edi], ecx
2430
        mov     [edi], ecx
2402
        pop     ecx
2431
        pop     ecx
2403
        sub     ecx, 8
2432
        sub     ecx, 8
2404
        shr     ecx, 2
2433
        shr     ecx, 2
2405
        mov     edi, esi
2434
        mov     edi, esi
2406
        add     edi, 4
2435
        add     edi, 4
2407
        mov     esi, [esp]
2436
        mov     esi, [esp]
2408
        add     word [esi+indexAllocatedSize], 8
2437
        add     word [esi+indexAllocatedSize], 8
2409
        mov     byte [esi+indexFlags], 1
2438
        mov     byte [esi+indexFlags], 1
2410
        cld
2439
        cld
2411
        rep movsd   ; insert index
2440
        rep movsd   ; insert index
2412
        mov     eax, [ebp+NTFS.newRecord]
2441
        mov     eax, [ebp+NTFS.newRecord]
2413
        stosd
2442
        stosd
2414
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
2443
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
2415
        mov     edx, [ebp+NTFS.nodeLastRead]
2444
        mov     edx, [ebp+NTFS.nodeLastRead]
2416
        push    esi
2445
        push    esi
2417
        call    writeRecord
2446
        call    writeRecord
2418
        pop     esi
2447
        pop     esi
2419
.splitNode:
2448
.splitNode:
2420
        mov     edi, [ebp+NTFS.cur_index_buf]
2449
        mov     edi, [ebp+NTFS.cur_index_buf]
2421
        mov     eax, edi
2450
        mov     eax, edi
2422
        add     eax, recordNode
2451
        add     eax, recordNode
2423
        add     eax, [edi+recordNode+nodeRealSize]
2452
        add     eax, [edi+recordNode+nodeRealSize]
2424
        sub     eax, esi
2453
        sub     eax, esi
2425
        push    eax
2454
        push    eax
2426
        mov     ecx, [edi+recordNode+indexOffset]
2455
        mov     ecx, [edi+recordNode+indexOffset]
2427
        add     eax, ecx
2456
        add     eax, ecx
2428
        add     ecx, recordNode
2457
        add     ecx, recordNode
2429
        shr     ecx, 2
2458
        shr     ecx, 2
2430
        push    esi
2459
        push    esi
2431
        mov     esi, edi
2460
        mov     esi, edi
2432
        mov     edi, [ebp+NTFS.secondIndexBuffer]
2461
        mov     edi, [ebp+NTFS.secondIndexBuffer]
2433
        rep movsd
2462
        rep movsd
2434
        pop     esi
2463
        pop     esi
2435
        pop     ecx
2464
        pop     ecx
2436
        shr     ecx, 2
2465
        shr     ecx, 2
2437
        rep movsd
2466
        rep movsd
2438
        mov     edi, [ebp+NTFS.secondIndexBuffer]
2467
        mov     edi, [ebp+NTFS.secondIndexBuffer]
2439
        mov     [edi+recordNode+nodeRealSize], eax
2468
        mov     [edi+recordNode+nodeRealSize], eax
2440
        pop     edi
2469
        pop     edi
2441
        mov     cl, 4
2470
        mov     cl, 4
2442
        xor     eax, eax
2471
        xor     eax, eax
2443
        mov     esi, edi
2472
        mov     esi, edi
2444
        rep stosd
2473
        rep stosd
2445
        mov     byte [esi+indexAllocatedSize], 16
2474
        mov     byte [esi+indexAllocatedSize], 16
2446
        mov     byte [esi+indexFlags], 2
2475
        mov     byte [esi+indexFlags], 2
2447
        mov     esi, [ebp+NTFS.cur_index_buf]
2476
        mov     esi, [ebp+NTFS.cur_index_buf]
2448
        mov     eax, [ebp+NTFS.newRecord]
2477
        mov     eax, [ebp+NTFS.newRecord]
2449
        mov     [esi+recordVCN], eax
2478
        mov     [esi+recordVCN], eax
2450
        add     esi, recordNode
2479
        add     esi, recordNode
2451
        sub     edi, esi
2480
        sub     edi, esi
2452
        mov     [esi+nodeRealSize], edi
2481
        mov     [esi+nodeRealSize], edi
2453
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
2482
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
2454
        mov     edx, [ebp+NTFS.LastRead]
2483
        mov     edx, [ebp+NTFS.LastRead]
2455
        call    writeRecord
2484
        call    writeRecord
2456
        jmp     .refresh
2485
        jmp     .refresh
2457
 
2486
 
2458
.common:
2487
.common:
2459
        add     edi, edx
2488
        add     edi, edx
2460
        sub     edi, 4
2489
        sub     edi, 4
2461
        mov     esi, edi
2490
        mov     esi, edi
2462
        sub     esi, [esp]
2491
        sub     esi, [esp]
2463
        mov     ecx, esi
2492
        mov     ecx, esi
2464
        sub     ecx, eax    ; eax = pointer in the record
2493
        sub     ecx, eax    ; eax = pointer in the record
2465
        shr     ecx, 2
2494
        shr     ecx, 2
2466
        inc     ecx
2495
        inc     ecx
2467
        std
2496
        std
2468
        rep movsd           ; move forward, make space
2497
        rep movsd           ; move forward, make space
2469
        mov     ecx, [esp]
2498
        mov     ecx, [esp]
2470
        shr     ecx, 2
2499
        shr     ecx, 2
2471
        xor     eax, eax
2500
        xor     eax, eax
2472
        rep stosd
2501
        rep stosd
2473
        cld
2502
        cld
2474
        add     edi, 4
2503
        add     edi, 4
2475
        call    ntfsGetTime
2504
        call    ntfsGetTime
2476
        mov     [edi+fileCreated], eax
2505
        mov     [edi+fileCreated], eax
2477
        mov     [edi+fileCreated+4], edx
2506
        mov     [edi+fileCreated+4], edx
2478
        mov     [edi+fileModified], eax
2507
        mov     [edi+fileModified], eax
2479
        mov     [edi+fileModified+4], edx
2508
        mov     [edi+fileModified+4], edx
2480
        mov     [edi+recordModified], eax
2509
        mov     [edi+recordModified], eax
2481
        mov     [edi+recordModified+4], edx
2510
        mov     [edi+recordModified+4], edx
2482
        mov     [edi+fileAccessed], eax
2511
        mov     [edi+fileAccessed], eax
2483
        mov     [edi+fileAccessed+4], edx
2512
        mov     [edi+fileAccessed+4], edx
2484
        pop     ecx
2513
        pop     ecx
2485
        pop     esi
2514
        pop     esi
2486
        mov     [edi+indexAllocatedSize], cx    ; fill index with data
2515
        mov     [edi+indexAllocatedSize], cx    ; fill index with data
2487
        mov     eax, [esp]
2516
        mov     eax, [esp]
2488
        shl     eax, 1
2517
        shl     eax, 1
2489
        add     eax, 42h
2518
        add     eax, 42h
2490
        mov     [edi+indexRawSize], ax
2519
        mov     [edi+indexRawSize], ax
2491
        mov     eax, [ebp+NTFS.cur_iRecord]
2520
        mov     eax, [ebp+NTFS.cur_iRecord]
2492
        mov     [edi+directoryRecordReference], eax
2521
        mov     [edi+directoryRecordReference], eax
2493
        mov     eax, [ebp+NTFS.frs_buffer]
2522
        mov     eax, [ebp+NTFS.frs_buffer]
2494
        mov     eax, [eax+reuseCounter]
2523
        mov     eax, [eax+reuseCounter]
2495
        mov     [edi+directoryReferenceReuse], ax
2524
        mov     [edi+directoryReferenceReuse], ax
2496
        mov     eax, [ebp+NTFS.frs_size]
2525
        mov     eax, [ebp+NTFS.frs_size]
2497
        shr     eax, 8
2526
        shr     eax, 8
2498
        add     ecx, 30h+48h+8+18h+8
2527
        add     ecx, 30h+48h+8+18h+8
2499
        add     ecx, eax
2528
        add     ecx, eax
2500
        mov     eax, [ebp+NTFS.fileRealSize]
2529
        mov     eax, [ebp+NTFS.fileRealSize]
2501
        add     ecx, eax
2530
        add     ecx, eax
2502
        mov     [edi+fileRealSize], eax
2531
        mov     [edi+fileRealSize], eax
2503
        cmp     [ebp+NTFS.frs_size], ecx
2532
        cmp     [ebp+NTFS.frs_size], ecx
2504
        jc      @f
2533
        jc      @f
2505
        xor     eax, eax
2534
        xor     eax, eax
2506
@@:
2535
@@:
2507
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
2536
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
2508
        shl     ecx, 9
2537
        shl     ecx, 9
2509
        add     eax, ecx
2538
        add     eax, ecx
2510
        dec     eax
2539
        dec     eax
2511
        xor     edx, edx
2540
        xor     edx, edx
2512
        div     ecx
2541
        div     ecx
2513
        mov     [ebp+NTFS.fileDataSize], eax
2542
        mov     [ebp+NTFS.fileDataSize], eax
2514
        mul     ecx
2543
        mul     ecx
2515
        mov     [edi+fileAllocatedSize], eax
2544
        mov     [edi+fileAllocatedSize], eax
2516
        pop     ecx
2545
        pop     ecx
2517
        mov     [ebp+NTFS.indexPointer], edi
2546
        mov     [ebp+NTFS.indexPointer], edi
2518
        mov     [edi+fileNameLength], cl
2547
        mov     [edi+fileNameLength], cl
2519
        add     edi, fileName
2548
        add     edi, fileName
2520
@@:         ; record filename
2549
@@:         ; record filename
2521
        lodsb
2550
        lodsb
2522
        call    ansi2uni_char
2551
        call    ansi2uni_char
2523
        stosw
2552
        stosw
2524
        dec     ecx
2553
        dec     ecx
2525
        jnz     @b
2554
        jnz     @b
2526
        mov     eax, [ebp+NTFS.LastRead]
2555
        mov     eax, [ebp+NTFS.LastRead]
2527
        mov     [ebp+NTFS.nodeLastRead], eax
2556
        mov     [ebp+NTFS.nodeLastRead], eax
2528
        cmp     [ebp+NTFS.bFolder], 0
2557
        cmp     [ebp+NTFS.bFolder], 0
2529
        jz      @f
2558
        jz      @f
2530
        mov     edi, [ebp+NTFS.indexPointer]
2559
        mov     edi, [ebp+NTFS.indexPointer]
2531
        bts     dword [edi+fileFlags], 28
2560
        bts     dword [edi+fileFlags], 28
2532
        jmp     .mftBitmap
2561
        jmp     .mftBitmap
2533
 
2562
 
2534
@@: ; 3. File data
2563
@@: ; 3. File data
2535
        cmp     [ebp+NTFS.fileDataSize], 0
2564
        cmp     [ebp+NTFS.fileDataSize], 0
2536
        jz      .mftBitmap
2565
        jz      .mftBitmap
2537
        mov     edi, [ebp+NTFS.BitmapStart]
2566
        mov     edi, [ebp+NTFS.BitmapStart]
2538
        call    ntfsSpaceAlloc
2567
        call    ntfsSpaceAlloc
2539
        jc      ntfsDiskFull
2568
        jc      ntfsDiskFull
2540
        mov     eax, [ebp+NTFS.fileDataStart]
2569
        mov     eax, [ebp+NTFS.fileDataStart]
2541
        mul     [ebp+NTFS.sectors_per_cluster]
2570
        mul     [ebp+NTFS.sectors_per_cluster]
2542
        mov     ecx, [ebp+NTFS.fileRealSize]
2571
        mov     ecx, [ebp+NTFS.fileRealSize]
2543
        add     ecx, 511
2572
        add     ecx, 511
2544
        shr     ecx, 9
2573
        shr     ecx, 9
2545
        mov     ebx, [ebp+NTFS.fileDataBuffer]
2574
        mov     ebx, [ebp+NTFS.fileDataBuffer]
2546
        call    fs_write64_app
2575
        call    fs_write64_app
2547
        test    eax, eax
2576
        test    eax, eax
2548
        jnz     ntfsDevice
2577
        jnz     ntfsDevice
2549
    ; 4. MFT record
2578
    ; 4. MFT record
2550
.mftBitmap: ; search for free record
2579
.mftBitmap: ; search for free record
2551
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
2580
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
2552
        mov     ecx, [ebp+NTFS.mftBitmapSize]
2581
        mov     ecx, [ebp+NTFS.mftBitmapSize]
2553
        mov     al, -1
2582
        mov     al, -1
2554
        add     edi, 3
2583
        add     edi, 3
2555
        sub     ecx, 3
2584
        sub     ecx, 3
2556
        repz scasb
2585
        repz scasb
2557
        dec     edi
2586
        dec     edi
2558
        movzx   eax, byte [edi]
2587
        movzx   eax, byte [edi]
2559
        not     al
2588
        not     al
2560
        bsf     ecx, eax
2589
        bsf     ecx, eax
2561
        jz      .extendBitmapMFT    ; no free records
2590
        jz      .extendBitmapMFT    ; no free records
2562
        bts     [edi], ecx
2591
        bts     [edi], ecx
2563
; get record location
2592
; get record location
2564
        sub     edi, [ebp+NTFS.mftBitmapBuffer]
2593
        sub     edi, [ebp+NTFS.mftBitmapBuffer]
2565
        shl     edi, 3
2594
        shl     edi, 3
2566
        add     edi, ecx
2595
        add     edi, ecx
2567
        mov     [ebp+NTFS.newRecord], edi
2596
        mov     [ebp+NTFS.newRecord], edi
2568
        mov     eax, [ebp+NTFS.frs_size]
2597
        mov     eax, [ebp+NTFS.frs_size]
2569
        shr     eax, 9
2598
        shr     eax, 9
2570
        mul     edi
2599
        mul     edi
2571
        mov     [ebp+NTFS.cur_iRecord], 0
2600
        mov     [ebp+NTFS.cur_iRecord], 0
2572
        mov     [ebp+NTFS.cur_attr], 0x80
2601
        mov     [ebp+NTFS.cur_attr], 0x80
2573
        mov     [ebp+NTFS.cur_offs], eax
2602
        mov     [ebp+NTFS.cur_offs], eax
2574
        push    eax
2603
        push    eax
2575
        mov     [ebp+NTFS.cur_size], 0
2604
        mov     [ebp+NTFS.cur_size], 0
2576
        mov     eax, [ebp+NTFS.frs_buffer]
2605
        mov     eax, [ebp+NTFS.frs_buffer]
2577
        mov     [ebp+NTFS.cur_buf], eax
2606
        mov     [ebp+NTFS.cur_buf], eax
2578
        call    ntfs_read_attr
2607
        call    ntfs_read_attr
2579
        pop     eax
2608
        pop     eax
2580
        jc      ntfsFail
2609
        jc      ntfsFail
2581
        cmp     eax, [ebp+NTFS.mftSize]
2610
        cmp     eax, [ebp+NTFS.mftSize]
2582
        jnc     .extendMFT
2611
        jnc     .extendMFT
2583
        jmp     .mftRecord
2612
        jmp     .mftRecord
2584
 
2613
 
2585
.extendBitmapMFT:
2614
.extendBitmapMFT:
2586
        mov     eax, [ebp+NTFS.sectors_per_cluster]
2615
        mov     eax, [ebp+NTFS.sectors_per_cluster]
2587
        mov     [ebp+NTFS.cur_offs], eax
2616
        mov     [ebp+NTFS.cur_offs], eax
2588
        shl     eax, 9
2617
        shl     eax, 9
2589
        cmp     [ebp+NTFS.mftBitmapSize], eax
2618
        cmp     [ebp+NTFS.mftBitmapSize], eax
2590
        jnc     ntfsUnsupported
2619
        jnc     ntfsUnsupported
2591
        mov     [ebp+NTFS.cur_iRecord], 0
2620
        mov     [ebp+NTFS.cur_iRecord], 0
2592
        mov     [ebp+NTFS.cur_attr], 0xB0
2621
        mov     [ebp+NTFS.cur_attr], 0xB0
2593
        mov     [ebp+NTFS.cur_size], 0
2622
        mov     [ebp+NTFS.cur_size], 0
2594
        call    ntfs_read_attr
2623
        call    ntfs_read_attr
2595
        jc      ntfsFail
2624
        jc      ntfsFail
2596
        mov     eax, [ebp+NTFS.mft_cluster]
2625
        mov     eax, [ebp+NTFS.mft_cluster]
2597
        mul     [ebp+NTFS.sectors_per_cluster]
2626
        mul     [ebp+NTFS.sectors_per_cluster]
2598
        cmp     eax, [ebp+NTFS.LastRead]
2627
        cmp     eax, [ebp+NTFS.LastRead]
2599
        jnz     ntfsUnsupported     ; auxiliary record
2628
        jnz     ntfsUnsupported     ; auxiliary record
2600
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
2629
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
2601
        mov     ecx, [ebp+NTFS.mftBitmapSize]
2630
        mov     ecx, [ebp+NTFS.mftBitmapSize]
2602
        add     edi, ecx
2631
        add     edi, ecx
2603
        mov     eax, ecx
2632
        mov     eax, ecx
2604
        mov     edx, [ebp+NTFS.attr_offs]
2633
        mov     edx, [ebp+NTFS.attr_offs]
2605
        add     ecx, 8
2634
        add     ecx, 8
2606
        mov     [edx+attributeRealSize], ecx
2635
        mov     [edx+attributeRealSize], ecx
2607
        mov     [edx+initialDataSize], ecx
2636
        mov     [edx+initialDataSize], ecx
2608
        shl     eax, 3
2637
        shl     eax, 3
2609
        mov     [ebp+NTFS.newRecord], eax
2638
        mov     [ebp+NTFS.newRecord], eax
2610
        mov     dword [edi], 1
2639
        mov     dword [edi], 1
2611
        mov     dword [edi+4], 0
2640
        mov     dword [edi+4], 0
2612
        mov     [ebp+NTFS.cur_attr], 0x80
2641
        mov     [ebp+NTFS.cur_attr], 0x80
2613
        mov     [ebp+NTFS.cur_offs], 0
2642
        mov     [ebp+NTFS.cur_offs], 0
2614
        call    ntfs_read_attr.newAttribute
2643
        call    ntfs_read_attr.newAttribute
2615
        jc      ntfsFail
2644
        jc      ntfsFail
2616
        mov     [ebp+NTFS.mftBitmapSize], ecx
2645
        mov     [ebp+NTFS.mftBitmapSize], ecx
2617
.extendMFT:
2646
.extendMFT:
2618
        mov     eax, [ebp+NTFS.mft_cluster]
2647
        mov     eax, [ebp+NTFS.mft_cluster]
2619
        mul     [ebp+NTFS.sectors_per_cluster]
2648
        mul     [ebp+NTFS.sectors_per_cluster]
2620
        cmp     eax, [ebp+NTFS.LastRead]
2649
        cmp     eax, [ebp+NTFS.LastRead]
2621
        jnz     ntfsUnsupported     ; auxiliary record
2650
        jnz     ntfsUnsupported     ; auxiliary record
2622
        mov     ecx, [ebp+NTFS.attr_offs]
2651
        mov     ecx, [ebp+NTFS.attr_offs]
2623
        mov     eax, [ecx+attributeRealSize]
2652
        mov     eax, [ecx+attributeRealSize]
2624
        mov     edx, [ecx+attributeRealSize+4]
2653
        mov     edx, [ecx+attributeRealSize+4]
2625
        xor     ax, ax
2654
        xor     ax, ax
2626
        add     eax, 10000h
2655
        add     eax, 10000h
2627
        adc     edx, 0
2656
        adc     edx, 0
2628
        push    [ebp+NTFS.fileDataStart]
2657
        push    [ebp+NTFS.fileDataStart]
2629
        push    [ebp+NTFS.fileDataSize]
2658
        push    [ebp+NTFS.fileDataSize]
2630
        call    resizeAttribute
2659
        call    resizeAttribute
2631
        jc      ntfsErrorPop2
2660
        jc      ntfsErrorPop2
2632
        mov     ebx, [ebp+NTFS.frs_buffer]
2661
        mov     ebx, [ebp+NTFS.frs_buffer]
2633
        mov     edx, [ebp+NTFS.LastRead]
2662
        mov     edx, [ebp+NTFS.LastRead]
2634
        call    writeRecord     ; $MFT
2663
        call    writeRecord     ; $MFT
2635
        mov     eax, [ebp+NTFS.mftmirr_cluster]
2664
        mov     eax, [ebp+NTFS.mftmirr_cluster]
2636
        mul     [ebp+NTFS.sectors_per_cluster]
2665
        mul     [ebp+NTFS.sectors_per_cluster]
2637
        mov     ecx, [ebp+NTFS.frs_size]
2666
        mov     ecx, [ebp+NTFS.frs_size]
2638
        shr     ecx, 9
2667
        shr     ecx, 9
2639
        call    fs_write64_sys  ; $MFTMirr
2668
        call    fs_write64_sys  ; $MFTMirr
2640
; update $MFT retrieval information
2669
; update $MFT retrieval information
2641
        mov     edi, [ebp+NTFS.mft_retrieval_end]
2670
        mov     edi, [ebp+NTFS.mft_retrieval_end]
2642
        mov     eax, [edi-4]
2671
        mov     eax, [edi-4]
2643
        add     eax, [edi-8]
2672
        add     eax, [edi-8]
2644
        mov     edx, [ebp+NTFS.fileDataSize]
2673
        mov     edx, [ebp+NTFS.fileDataSize]
2645
        cmp     eax, [ebp+NTFS.fileDataStart]
2674
        cmp     eax, [ebp+NTFS.fileDataStart]
2646
        jnz     .newFragment
2675
        jnz     .newFragment
2647
        add     [edi-8], edx
2676
        add     [edi-8], edx
2648
        jmp     @f
2677
        jmp     @f
2649
.newFragment:
2678
.newFragment:
2650
        lea     eax, [ebp+NTFS.attrlist_buf]
2679
        lea     eax, [ebp+NTFS.attrlist_buf]
2651
        cmp     eax, edi
2680
        cmp     eax, edi
2652
        jz      @f
2681
        jz      @f
2653
        mov     [edi], edx
2682
        mov     [edi], edx
2654
        mov     eax, [ebp+NTFS.fileDataStart]
2683
        mov     eax, [ebp+NTFS.fileDataStart]
2655
        mov     [edi+4], eax
2684
        mov     [edi+4], eax
2656
        add     [ebp+NTFS.mft_retrieval_end], 8
2685
        add     [ebp+NTFS.mft_retrieval_end], 8
2657
@@:
2686
@@:
2658
        mov     eax, [ebp+NTFS.fileDataSize]
2687
        mov     eax, [ebp+NTFS.fileDataSize]
2659
        mul     [ebp+NTFS.sectors_per_cluster]
2688
        mul     [ebp+NTFS.sectors_per_cluster]
2660
        add     [ebp+NTFS.mftSize], eax
2689
        add     [ebp+NTFS.mftSize], eax
2661
        call    ntfsSpaceClean
2690
        call    ntfsSpaceClean
2662
        pop     [ebp+NTFS.fileDataSize]
2691
        pop     [ebp+NTFS.fileDataSize]
2663
        pop     [ebp+NTFS.fileDataStart]
2692
        pop     [ebp+NTFS.fileDataStart]
2664
.mftRecord:
2693
.mftRecord:
2665
        mov     ecx, [ebp+NTFS.frs_size]
2694
        mov     ecx, [ebp+NTFS.frs_size]
2666
        shr     ecx, 2
2695
        shr     ecx, 2
2667
        mov     edi, [ebp+NTFS.frs_buffer]
2696
        mov     edi, [ebp+NTFS.frs_buffer]
2668
        xor     eax, eax
2697
        xor     eax, eax
2669
        rep stosd
2698
        rep stosd
2670
        mov     esi, [ebp+NTFS.indexPointer]
2699
        mov     esi, [ebp+NTFS.indexPointer]
2671
        mov     eax, [ebp+NTFS.newRecord]
2700
        mov     eax, [ebp+NTFS.newRecord]
2672
        mov     [esi+fileRecordReference], eax
2701
        mov     [esi+fileRecordReference], eax
2673
        rdtsc
2702
        rdtsc
2674
        mov     [esi+fileReferenceReuse], ax
2703
        mov     [esi+fileReferenceReuse], ax
2675
        mov     edi, [ebp+NTFS.frs_buffer]
2704
        mov     edi, [ebp+NTFS.frs_buffer]
2676
; record header
2705
; record header
2677
        mov     [edi+reuseCounter], ax
2706
        mov     [edi+reuseCounter], ax
2678
        mov     [edi+2ah], ax
2707
        mov     [edi+2ah], ax
2679
        mov     eax, [ebp+NTFS.frs_size]
2708
        mov     eax, [ebp+NTFS.frs_size]
2680
        mov     [edi+recordAllocatedSize], eax
2709
        mov     [edi+recordAllocatedSize], eax
2681
        shr     eax, 9
2710
        shr     eax, 9
2682
        inc     eax
2711
        inc     eax
2683
        mov     [edi+updateSequenceSize], al
2712
        mov     [edi+updateSequenceSize], al
2684
        shl     eax, 1
2713
        shl     eax, 1
2685
        add     eax, 2ah+7
2714
        add     eax, 2ah+7
2686
        and     eax, not 7
2715
        and     eax, not 7
2687
        mov     dword[edi], 'FILE'
2716
        mov     dword[edi], 'FILE'
2688
        mov     byte [edi+updateSequenceOffset], 2ah
2717
        mov     byte [edi+updateSequenceOffset], 2ah
2689
        mov     byte [edi+hardLinkCounter], 1
2718
        mov     byte [edi+hardLinkCounter], 1
2690
        mov     byte [edi+newAttributeID], 3
2719
        mov     byte [edi+newAttributeID], 3
2691
        mov     [edi+attributeOffset], al
2720
        mov     [edi+attributeOffset], al
2692
        add     edi, eax
2721
        add     edi, eax
2693
; $StandardInformation
2722
; $StandardInformation
2694
        mov     byte [edi+attributeType], 10h
2723
        mov     byte [edi+attributeType], 10h
2695
        mov     byte [edi+sizeWithHeader], 48h
2724
        mov     byte [edi+sizeWithHeader], 48h
2696
        mov     byte [edi+sizeWithoutHeader], 30h
2725
        mov     byte [edi+sizeWithoutHeader], 30h
2697
        mov     byte [edi+attributeOffset], 18h
2726
        mov     byte [edi+attributeOffset], 18h
2698
        mov     cl, 8
2727
        mov     cl, 8
2699
        add     esi, fileCreated
2728
        add     esi, fileCreated
2700
        add     edi, 18h
2729
        add     edi, 18h
2701
        rep movsd
2730
        rep movsd
2702
        add     edi, 16
2731
        add     edi, 16
2703
        mov     esi, [ebp+NTFS.indexPointer]
2732
        mov     esi, [ebp+NTFS.indexPointer]
2704
; $FileName
2733
; $FileName
2705
        mov     byte [edi+attributeType], 30h
2734
        mov     byte [edi+attributeType], 30h
2706
        mov     byte [edi+attributeID], 1
2735
        mov     byte [edi+attributeID], 1
2707
        mov     byte [edi+attributeOffset], 18h
2736
        mov     byte [edi+attributeOffset], 18h
2708
        mov     byte [edi+indexedFlag], 1
2737
        mov     byte [edi+indexedFlag], 1
2709
        mov     cx, [esi+indexRawSize]
2738
        mov     cx, [esi+indexRawSize]
2710
        mov     [edi+sizeWithoutHeader], ecx
2739
        mov     [edi+sizeWithoutHeader], ecx
2711
        mov     cx, [esi+indexAllocatedSize]
2740
        mov     cx, [esi+indexAllocatedSize]
2712
        add     ecx, 8
2741
        add     ecx, 8
2713
        mov     [edi+sizeWithHeader], ecx
2742
        mov     [edi+sizeWithHeader], ecx
2714
        add     edi, 18h
2743
        add     edi, 18h
2715
        add     esi, 16
2744
        add     esi, 16
2716
        sub     ecx, 18h
2745
        sub     ecx, 18h
2717
        shr     ecx, 2
2746
        shr     ecx, 2
2718
        rep movsd
2747
        rep movsd
2719
        mov     byte [edi+sizeWithHeader], 50h
2748
        mov     byte [edi+sizeWithHeader], 50h
2720
        mov     byte [edi+attributeID], 2
2749
        mov     byte [edi+attributeID], 2
2721
        cmp     [ebp+NTFS.bFolder], 1
2750
        cmp     [ebp+NTFS.bFolder], 1
2722
        jz      .indexRoot
2751
        jz      .indexRoot
2723
; $Data
2752
; $Data
2724
        mov     byte [edi+attributeType], 80h
2753
        mov     byte [edi+attributeType], 80h
2725
        mov     eax, [ebp+NTFS.fileDataSize]
2754
        mov     eax, [ebp+NTFS.fileDataSize]
2726
        test    eax, eax
2755
        test    eax, eax
2727
        jz      .resident
2756
        jz      .resident
2728
        mov     esi, [ebp+NTFS.indexPointer]
2757
        mov     esi, [ebp+NTFS.indexPointer]
2729
        dec     eax
2758
        dec     eax
2730
        mov     [edi+lastVCN], eax
2759
        mov     [edi+lastVCN], eax
2731
        mov     byte [edi+nonResidentFlag], 1
2760
        mov     byte [edi+nonResidentFlag], 1
2732
        mov     byte [edi+dataRunsOffset], 40h
2761
        mov     byte [edi+dataRunsOffset], 40h
2733
        mov     eax, [esi+fileAllocatedSize]
2762
        mov     eax, [esi+fileAllocatedSize]
2734
        mov     [edi+attributeAllocatedSize], eax
2763
        mov     [edi+attributeAllocatedSize], eax
2735
        mov     eax, [esi+fileRealSize]
2764
        mov     eax, [esi+fileRealSize]
2736
        mov     [edi+attributeRealSize], eax
2765
        mov     [edi+attributeRealSize], eax
2737
        mov     [edi+initialDataSize], eax
2766
        mov     [edi+initialDataSize], eax
2738
        push    edi
2767
        push    edi
2739
        mov     esi, edi
2768
        mov     esi, edi
2740
        add     edi, 40h
2769
        add     edi, 40h
2741
        call    createMcbEntry
2770
        call    createMcbEntry
2742
        inc     edi
2771
        inc     edi
2743
        jmp     @f
2772
        jmp     @f
2744
 
2773
 
2745
.resident:
2774
.resident:
2746
        mov     ecx, [ebp+NTFS.fileRealSize]
2775
        mov     ecx, [ebp+NTFS.fileRealSize]
2747
        mov     [edi+sizeWithoutHeader], ecx
2776
        mov     [edi+sizeWithoutHeader], ecx
2748
        mov     byte [edi+attributeOffset], 18h
2777
        mov     byte [edi+attributeOffset], 18h
2749
        push    edi
2778
        push    edi
2750
        mov     esi, [ebp+NTFS.fileDataBuffer]
2779
        mov     esi, [ebp+NTFS.fileDataBuffer]
2751
        add     edi, 18h
2780
        add     edi, 18h
2752
        rep movsb
2781
        rep movsb
2753
@@:
2782
@@:
2754
        mov     eax, edi
2783
        mov     eax, edi
2755
        pop     edi
2784
        pop     edi
2756
        sub     eax, edi
2785
        sub     eax, edi
2757
        add     eax, 7
2786
        add     eax, 7
2758
        and     eax, not 7
2787
        and     eax, not 7
2759
        mov     [edi+sizeWithHeader], eax
2788
        mov     [edi+sizeWithHeader], eax
2760
        add     edi, eax
2789
        add     edi, eax
2761
        mov     al, 1
2790
        mov     al, 1
2762
        jmp     .end
2791
        jmp     .end
2763
 
2792
 
2764
.indexRoot:
2793
.indexRoot:
2765
        mov     byte [edi+attributeType], 90h
2794
        mov     byte [edi+attributeType], 90h
2766
        mov     byte [edi+nameLength], 4
2795
        mov     byte [edi+nameLength], 4
2767
        mov     byte [edi+nameOffset], 18h
2796
        mov     byte [edi+nameOffset], 18h
2768
        mov     byte [edi+sizeWithoutHeader], 30h
2797
        mov     byte [edi+sizeWithoutHeader], 30h
2769
        mov     byte [edi+attributeOffset], 20h
2798
        mov     byte [edi+attributeOffset], 20h
2770
        mov     dword[edi+18h], 490024h     ; unicode $I30
2799
        mov     dword[edi+18h], 490024h     ; unicode $I30
2771
        mov     dword[edi+18h+4], 300033h
2800
        mov     dword[edi+18h+4], 300033h
2772
        mov     byte [edi+20h+indexedAttributesType], 30h
2801
        mov     byte [edi+20h+indexedAttributesType], 30h
2773
        mov     byte [edi+20h+collationRule], 1
2802
        mov     byte [edi+20h+collationRule], 1
2774
        mov     eax, [ebp+NTFS.sectors_per_cluster]
2803
        mov     eax, [ebp+NTFS.sectors_per_cluster]
2775
        mov     dl, 1
2804
        mov     dl, 1
2776
        shl     eax, 8
2805
        shl     eax, 8
2777
@@:
2806
@@:
2778
        shl     eax, 1
2807
        shl     eax, 1
2779
        shl     edx, 1
2808
        shl     edx, 1
2780
        cmp     eax, [ebp+NTFS.frs_size]
2809
        cmp     eax, [ebp+NTFS.frs_size]
2781
        jc      @b
2810
        jc      @b
2782
        shr     edx, 1
2811
        shr     edx, 1
2783
        mov     [edi+20h+indexRecordSize], eax
2812
        mov     [edi+20h+indexRecordSize], eax
2784
        mov     [edi+20h+indexRecordSizeClus], dl
2813
        mov     [edi+20h+indexRecordSizeClus], dl
2785
        mov     byte [edi+30h+indexOffset], 16
2814
        mov     byte [edi+30h+indexOffset], 16
2786
        mov     byte [edi+30h+nodeRealSize], 32
2815
        mov     byte [edi+30h+nodeRealSize], 32
2787
        mov     byte [edi+30h+nodeAllocatedSize], 32
2816
        mov     byte [edi+30h+nodeAllocatedSize], 32
2788
        mov     byte [edi+40h+indexAllocatedSize], 16
2817
        mov     byte [edi+40h+indexAllocatedSize], 16
2789
        mov     byte [edi+40h+indexFlags], 2
2818
        mov     byte [edi+40h+indexFlags], 2
2790
        add     edi, 50h
2819
        add     edi, 50h
2791
        mov     al, 3
2820
        mov     al, 3
2792
.end:
2821
.end:
2793
        mov     ebx, [ebp+NTFS.frs_buffer]
2822
        mov     ebx, [ebp+NTFS.frs_buffer]
2794
        mov     dword [edi], -1
2823
        mov     dword [edi], -1
2795
        mov     dword [edi+4], 0
2824
        mov     dword [edi+4], 0
2796
        add     edi, 8
2825
        add     edi, 8
2797
        sub     edi, ebx
2826
        sub     edi, ebx
2798
        mov     [ebx+recordFlags], al
2827
        mov     [ebx+recordFlags], al
2799
        mov     [ebx+recordRealSize], edi
2828
        mov     [ebx+recordRealSize], edi
2800
        mov     edx, [ebp+NTFS.LastRead]
2829
        mov     edx, [ebp+NTFS.LastRead]
2801
        call    writeRecord
2830
        call    writeRecord
2802
; write MFT bitmap
2831
; write MFT bitmap
2803
        mov     eax, [ebp+NTFS.newRecord]
2832
        mov     eax, [ebp+NTFS.newRecord]
2804
        shr     eax, 3+9
2833
        shr     eax, 3+9
2805
        mov     ebx, eax
2834
        mov     ebx, eax
2806
        shl     ebx, 9
2835
        shl     ebx, 9
2807
        add     eax, [ebp+NTFS.mftBitmapLocation]
2836
        add     eax, [ebp+NTFS.mftBitmapLocation]
2808
        add     ebx, [ebp+NTFS.mftBitmapBuffer]
2837
        add     ebx, [ebp+NTFS.mftBitmapBuffer]
2809
        mov     ecx, 1
2838
        mov     ecx, 1
2810
        xor     edx, edx
2839
        xor     edx, edx
2811
        call    fs_write64_sys
2840
        call    fs_write64_sys
2812
; 5. Write directory node
2841
; 5. Write directory node
2813
        mov     ebx, [ebp+NTFS.cur_index_buf]
2842
        mov     ebx, [ebp+NTFS.cur_index_buf]
2814
        mov     edx, [ebp+NTFS.nodeLastRead]
2843
        mov     edx, [ebp+NTFS.nodeLastRead]
2815
        call    writeRecord
2844
        call    writeRecord
2816
        mov     ebx, [ebp+NTFS.fileRealSize]
2845
        mov     ebx, [ebp+NTFS.fileRealSize]
2817
ntfsDone:
2846
ntfsDone:
2818
        mov     esi, [ebp+PARTITION.Disk]
2847
        mov     esi, [ebp+PARTITION.Disk]
2819
        call    disk_sync
2848
        call    disk_sync
2820
        call    ntfs_unlock
2849
        call    ntfs_unlock
2821
        xor     eax, eax
2850
        xor     eax, eax
2822
        ret
2851
        ret
2823
 
2852
 
2824
writeRecord:
2853
writeRecord:
2825
; make updateSequence and write to disk
2854
; make updateSequence and write to disk
2826
;   in:
2855
;   in:
2827
; ebx -> record
2856
; ebx -> record
2828
; edx = partition sector
2857
; edx = partition sector
2829
        mov     esi, ebx
2858
        mov     esi, ebx
2830
        mov     edi, ebx
2859
        mov     edi, ebx
2831
        movzx   ecx, word [esi+updateSequenceOffset]
2860
        movzx   ecx, word [esi+updateSequenceOffset]
2832
        add     edi, ecx
2861
        add     edi, ecx
2833
        mov     ax, [edi]
2862
        mov     ax, [edi]
2834
        inc     ax
2863
        inc     ax
2835
        stosw
2864
        stosw
2836
        mov     cx, [esi+updateSequenceSize]
2865
        mov     cx, [esi+updateSequenceSize]
2837
        dec     ecx
2866
        dec     ecx
2838
        push    ecx
2867
        push    ecx
2839
@@:
2868
@@:
2840
        add     esi, 510
2869
        add     esi, 510
2841
        movsw
2870
        movsw
2842
        mov     [esi-2], ax
2871
        mov     [esi-2], ax
2843
        dec     ecx
2872
        dec     ecx
2844
        jnz     @b
2873
        jnz     @b
2845
        mov     eax, edx
2874
        mov     eax, edx
2846
        xor     edx, edx
2875
        xor     edx, edx
2847
        pop     ecx
2876
        pop     ecx
2848
        jmp     fs_write64_sys
2877
        jmp     fs_write64_sys
2849
 
2878
 
2850
createMcbEntry:
2879
createMcbEntry:
2851
;   in:
2880
;   in:
2852
; [ebp+NTFS.fileDataStart] = position value
2881
; [ebp+NTFS.fileDataStart] = position value
2853
; [ebp+NTFS.fileDataSize] = size value
2882
; [ebp+NTFS.fileDataSize] = size value
2854
; edi -> destination
2883
; edi -> destination
2855
; esi -> attribute header
2884
; esi -> attribute header
2856
        mov     eax, [ebp+NTFS.fileDataStart]
2885
        mov     eax, [ebp+NTFS.fileDataStart]
2857
        xor     edx, edx
2886
        xor     edx, edx
2858
        shl     eax, 1
2887
        shl     eax, 1
2859
        jnc     @f
2888
        jnc     @f
2860
        not     eax
2889
        not     eax
2861
@@:
2890
@@:
2862
        inc     edx
2891
        inc     edx
2863
        shr     eax, 8
2892
        shr     eax, 8
2864
        jnz     @b
2893
        jnz     @b
2865
        mov     eax, [ebp+NTFS.fileDataSize]
2894
        mov     eax, [ebp+NTFS.fileDataSize]
2866
        shl     eax, 1
2895
        shl     eax, 1
2867
        xor     ecx, ecx
2896
        xor     ecx, ecx
2868
@@:
2897
@@:
2869
        inc     ecx
2898
        inc     ecx
2870
        shr     eax, 8
2899
        shr     eax, 8
2871
        jnz     @b
2900
        jnz     @b
2872
        lea     eax, [edi+edx+1]
2901
        lea     eax, [edi+edx+1]
2873
        add     eax, ecx
2902
        add     eax, ecx
2874
        sub     eax, esi
2903
        sub     eax, esi
2875
        sub     eax, [esi+sizeWithHeader]
2904
        sub     eax, [esi+sizeWithHeader]
2876
        jc      @f
2905
        jc      @f
2877
        add     word [esi+sizeWithHeader], 8    ; extend attribute
2906
        add     word [esi+sizeWithHeader], 8    ; extend attribute
2878
        mov     esi, [ebp+NTFS.frs_buffer]
2907
        mov     esi, [ebp+NTFS.frs_buffer]
2879
        mov     eax, [esi+recordRealSize]
2908
        mov     eax, [esi+recordRealSize]
2880
        add     eax, 8
2909
        add     eax, 8
2881
        cmp     [esi+recordAllocatedSize], eax
2910
        cmp     [esi+recordAllocatedSize], eax
2882
        jc      .end    ; no space in the record
2911
        jc      .end    ; no space in the record
2883
        mov     [esi+recordRealSize], eax
2912
        mov     [esi+recordRealSize], eax
2884
        push    ecx edi
2913
        push    ecx edi
2885
        add     esi, eax
2914
        add     esi, eax
2886
        mov     ecx, esi
2915
        mov     ecx, esi
2887
        sub     ecx, edi
2916
        sub     ecx, edi
2888
        sub     ecx, 8
2917
        sub     ecx, 8
2889
        shr     ecx, 2
2918
        shr     ecx, 2
2890
        mov     edi, esi
2919
        mov     edi, esi
2891
        sub     edi, 4
2920
        sub     edi, 4
2892
        sub     esi, 12
2921
        sub     esi, 12
2893
        std
2922
        std
2894
        rep movsd
2923
        rep movsd
2895
        cld
2924
        cld
2896
        pop     edi ecx
2925
        pop     edi ecx
2897
@@:
2926
@@:
2898
        mov     eax, edx
2927
        mov     eax, edx
2899
        shl     eax, 4
2928
        shl     eax, 4
2900
        add     eax, ecx
2929
        add     eax, ecx
2901
        stosb
2930
        stosb
2902
        lea     esi, [ebp+NTFS.fileDataSize]
2931
        lea     esi, [ebp+NTFS.fileDataSize]
2903
        rep movsb
2932
        rep movsb
2904
        lea     esi, [ebp+NTFS.fileDataStart]
2933
        lea     esi, [ebp+NTFS.fileDataStart]
2905
        mov     ecx, edx
2934
        mov     ecx, edx
2906
        rep movsb
2935
        rep movsb
2907
        mov     [edi], cl
2936
        mov     [edi], cl
2908
.end:
2937
.end:
2909
        ret
2938
        ret
2910
 
2939
 
2911
resizeAttribute:
2940
resizeAttribute:
2912
;   in:
2941
;   in:
2913
; [ebp+NTFS.frs_buffer] -> file record
2942
; [ebp+NTFS.frs_buffer] -> file record
2914
; [ebp+NTFS.attr_offs] -> attribute
2943
; [ebp+NTFS.attr_offs] -> attribute
2915
; edx:eax = new size
2944
; edx:eax = new size
2916
;   out:
2945
;   out:
2917
; [ebp+NTFS.fileDataSize] = clusters added (positive)
2946
; [ebp+NTFS.fileDataSize] = clusters added (positive)
2918
; [ebp+NTFS.fileDataStart] = added block
2947
; [ebp+NTFS.fileDataStart] = added block
2919
; CF=1 -> eax = error code
2948
; CF=1 -> eax = error code
2920
        mov     esi, [ebp+NTFS.attr_offs]
2949
        mov     esi, [ebp+NTFS.attr_offs]
2921
        mov     dword [ebp+NTFS.attr_size], eax
2950
        mov     dword [ebp+NTFS.attr_size], eax
2922
        mov     dword [ebp+NTFS.attr_size+4], edx
2951
        mov     dword [ebp+NTFS.attr_size+4], edx
2923
        cmp     byte [esi+nonResidentFlag], 0
2952
        cmp     byte [esi+nonResidentFlag], 0
2924
        jz      .resident
2953
        jz      .resident
2925
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
2954
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
2926
        shl     ecx, 9
2955
        shl     ecx, 9
2927
        mov     [esi+attributeRealSize], eax
2956
        mov     [esi+attributeRealSize], eax
2928
        mov     [esi+attributeRealSize+4], edx
2957
        mov     [esi+attributeRealSize+4], edx
2929
        mov     [esi+initialDataSize], eax
2958
        mov     [esi+initialDataSize], eax
2930
        mov     [esi+initialDataSize+4], edx
2959
        mov     [esi+initialDataSize+4], edx
2931
        sub     eax, 1
2960
        sub     eax, 1
2932
        sbb     edx, 0
2961
        sbb     edx, 0
2933
        jc      .makeResident
2962
        jc      .makeResident
2934
        div     ecx
2963
        div     ecx
2935
        mov     edi, eax
2964
        mov     edi, eax
2936
        inc     eax
2965
        inc     eax
2937
        mul     ecx
2966
        mul     ecx
2938
        mov     [esi+attributeAllocatedSize], eax
2967
        mov     [esi+attributeAllocatedSize], eax
2939
        mov     [esi+attributeAllocatedSize+4], edx
2968
        mov     [esi+attributeAllocatedSize+4], edx
2940
        mov     ecx, [esi+lastVCN]
2969
        mov     ecx, [esi+lastVCN]
2941
        mov     [esi+lastVCN], edi
2970
        mov     [esi+lastVCN], edi
2942
        movzx   eax, byte [esi+dataRunsOffset]
2971
        movzx   eax, byte [esi+dataRunsOffset]
2943
        sub     edi, ecx
2972
        sub     edi, ecx
2944
        mov     [ebp+NTFS.fileDataSize], edi
2973
        mov     [ebp+NTFS.fileDataSize], edi
2945
        jz      .done
2974
        jz      .done
2946
        jc      .shrinkAttribute
2975
        jc      .shrinkAttribute
2947
; extend attribute
2976
; extend attribute
2948
        xor     edi, edi
2977
        xor     edi, edi
2949
        add     esi, eax
2978
        add     esi, eax
2950
        push    edi edi edi edi
2979
        push    edi edi edi edi
2951
@@:
2980
@@:
2952
        mov     edx, eax
2981
        mov     edx, eax
2953
        mov     eax, esi
2982
        mov     eax, esi
2954
        add     edi, [esp+8]
2983
        add     edi, [esp+8]
2955
        call    ntfs_decode_mcb_entry
2984
        call    ntfs_decode_mcb_entry
2956
        jc      @b
2985
        jc      @b
2957
        mov     [esp+4], edx
2986
        mov     [esp+4], edx
2958
        mov     [esp+12], edi
2987
        mov     [esp+12], edi
2959
        add     edi, [esp]
2988
        add     edi, [esp]
2960
        push    edi
2989
        push    edi
2961
        shr     edi, 5
2990
        shr     edi, 5
2962
        shl     edi, 2
2991
        shl     edi, 2
2963
        push    eax
2992
        push    eax
2964
        cmp     [ebp+NTFS.cur_iRecord], 0
2993
        cmp     [ebp+NTFS.cur_iRecord], 0
2965
        jz      @f
2994
        jz      @f
2966
        cmp     edi, [ebp+NTFS.BitmapStart]
2995
        cmp     edi, [ebp+NTFS.BitmapStart]
2967
        jc      .err1
2996
        jc      .err1
2968
@@:
2997
@@:
2969
        call    ntfsSpaceAlloc
2998
        call    ntfsSpaceAlloc
2970
        jc      .err1
2999
        jc      .err1
2971
        mov     eax, [ebp+NTFS.fileDataStart]
3000
        mov     eax, [ebp+NTFS.fileDataStart]
2972
        pop     edi
3001
        pop     edi
2973
        pop     edx
3002
        pop     edx
2974
        cmp     edx, eax
3003
        cmp     edx, eax
2975
        jnz     .newEntry
3004
        jnz     .newEntry
2976
        pop     edx
3005
        pop     edx
2977
        pop     edi
3006
        pop     edi
2978
        pop     [ebp+NTFS.fileDataStart]
3007
        pop     [ebp+NTFS.fileDataStart]
2979
        mov     [esp], eax
3008
        mov     [esp], eax
2980
        push    [ebp+NTFS.fileDataSize]
3009
        push    [ebp+NTFS.fileDataSize]
2981
        add     [ebp+NTFS.fileDataSize], edx
3010
        add     [ebp+NTFS.fileDataSize], edx
2982
        jmp     @f
3011
        jmp     @f
2983
 
3012
 
2984
.newEntry:
3013
.newEntry:
2985
        add     esp, 12
3014
        add     esp, 12
2986
        pop     edx
3015
        pop     edx
2987
        push    eax
3016
        push    eax
2988
        push    [ebp+NTFS.fileDataSize]
3017
        push    [ebp+NTFS.fileDataSize]
2989
        sub     eax, edx
3018
        sub     eax, edx
2990
        mov     [ebp+NTFS.fileDataStart], eax
3019
        mov     [ebp+NTFS.fileDataStart], eax
2991
@@:
3020
@@:
2992
        mov     esi, [ebp+NTFS.attr_offs]
3021
        mov     esi, [ebp+NTFS.attr_offs]
2993
        call    createMcbEntry
3022
        call    createMcbEntry
2994
        pop     [ebp+NTFS.fileDataSize]
3023
        pop     [ebp+NTFS.fileDataSize]
2995
        pop     [ebp+NTFS.fileDataStart]
3024
        pop     [ebp+NTFS.fileDataStart]
2996
        movi    eax, ERROR_UNSUPPORTED_FS
3025
        movi    eax, ERROR_UNSUPPORTED_FS
2997
.done:
3026
.done:
2998
        ret
3027
        ret
2999
 
3028
 
3000
.err1:
3029
.err1:
3001
        add     esp, 24
3030
        add     esp, 24
3002
        stc
3031
        stc
3003
.err2:
3032
.err2:
3004
        movi    eax, ERROR_DISK_FULL
3033
        movi    eax, ERROR_DISK_FULL
3005
        ret
3034
        ret
3006
 
3035
 
3007
.err3:
3036
.err3:
3008
        movi    eax, ERROR_FS_FAIL
3037
        movi    eax, ERROR_FS_FAIL
3009
        add     esp, 20
3038
        add     esp, 20
3010
        stc
3039
        stc
3011
        ret
3040
        ret
3012
 
3041
 
3013
.shrinkAttribute:
3042
.shrinkAttribute:
3014
        add     ecx, edi
3043
        add     ecx, edi
3015
        inc     ecx
3044
        inc     ecx
3016
        add     esi, eax
3045
        add     esi, eax
3017
        xor     edi, edi
3046
        xor     edi, edi
3018
        sub     esp, 20
3047
        sub     esp, 20
3019
@@:
3048
@@:
3020
        mov     [esp+16], esi
3049
        mov     [esp+16], esi
3021
        call    ntfs_decode_mcb_entry
3050
        call    ntfs_decode_mcb_entry
3022
        jnc     .err3
3051
        jnc     .err3
3023
        add     edi, [esp+8]
3052
        add     edi, [esp+8]
3024
        sub     ecx, [esp]
3053
        sub     ecx, [esp]
3025
        jnc     @b
3054
        jnc     @b
3026
        mov     ebx, ecx
3055
        mov     ebx, ecx
3027
        add     ecx, [esp]
3056
        add     ecx, [esp]
3028
        mov     eax, [esp+8]
3057
        mov     eax, [esp+8]
3029
        mov     [ebp+NTFS.fileDataSize], ecx
3058
        mov     [ebp+NTFS.fileDataSize], ecx
3030
        mov     [ebp+NTFS.fileDataStart], eax
3059
        mov     [ebp+NTFS.fileDataStart], eax
3031
        push    edi
3060
        push    edi
3032
        add     edi, ecx
3061
        add     edi, ecx
3033
        neg     ebx
3062
        neg     ebx
3034
        call    ntfsSpaceFree
3063
        call    ntfsSpaceFree
3035
        pop     edi
3064
        pop     edi
3036
        jc      .end
3065
        jc      .end
3037
@@:
3066
@@:
3038
        call    ntfs_decode_mcb_entry
3067
        call    ntfs_decode_mcb_entry
3039
        jnc     .end
3068
        jnc     .end
3040
        cmp     dword[esp+8], 0
3069
        cmp     dword[esp+8], 0
3041
        jz      @b
3070
        jz      @b
3042
        add     edi, [esp+8]
3071
        add     edi, [esp+8]
3043
        mov     ebx, [esp]
3072
        mov     ebx, [esp]
3044
        call    ntfsSpaceFree
3073
        call    ntfsSpaceFree
3045
        jnc     @b
3074
        jnc     @b
3046
.end:
3075
.end:
3047
        add     esp, 16
3076
        add     esp, 16
3048
        pop     edi
3077
        pop     edi
3049
        cmp     [ebp+NTFS.fileDataSize], 0
3078
        cmp     [ebp+NTFS.fileDataSize], 0
3050
        jz      @f
3079
        jz      @f
3051
        mov     esi, [ebp+NTFS.attr_offs]
3080
        mov     esi, [ebp+NTFS.attr_offs]
3052
        call    createMcbEntry
3081
        call    createMcbEntry
3053
        mov     [ebp+NTFS.fileDataSize], 0
3082
        mov     [ebp+NTFS.fileDataSize], 0
3054
@@:
3083
@@:
3055
        ret
3084
        ret
3056
 
3085
 
3057
.resident:
3086
.resident:
3058
        test    edx, edx
3087
        test    edx, edx
3059
        jnz     .nonResident
3088
        jnz     .nonResident
3060
        cmp     eax, 8000h
3089
        cmp     eax, 8000h
3061
        jnc     .nonResident
3090
        jnc     .nonResident
3062
        add     ax, [esi+attributeOffset]
3091
        add     ax, [esi+attributeOffset]
3063
        sub     eax, [esi+sizeWithHeader]
3092
        sub     eax, [esi+sizeWithHeader]
3064
        jc      @f
3093
        jc      @f
3065
        mov     edi, [ebp+NTFS.frs_buffer]
3094
        mov     edi, [ebp+NTFS.frs_buffer]
3066
        mov     ecx, eax
3095
        mov     ecx, eax
3067
        add     ecx, [edi+recordRealSize]
3096
        add     ecx, [edi+recordRealSize]
3068
        cmp     [edi+recordAllocatedSize], ecx
3097
        cmp     [edi+recordAllocatedSize], ecx
3069
        jc      .nonResident
3098
        jc      .nonResident
3070
        add     eax, 7
3099
        add     eax, 7
3071
        and     eax, not 7
3100
        and     eax, not 7
3072
        add     [edi+recordRealSize], eax
3101
        add     [edi+recordRealSize], eax
3073
        add     edi, [edi+recordRealSize]
3102
        add     edi, [edi+recordRealSize]
3074
        add     [esi+sizeWithHeader], eax
3103
        add     [esi+sizeWithHeader], eax
3075
        add     esi, [esi+sizeWithHeader]
3104
        add     esi, [esi+sizeWithHeader]
3076
        mov     ecx, edi
3105
        mov     ecx, edi
3077
        sub     ecx, esi
3106
        sub     ecx, esi
3078
        shr     ecx, 2
3107
        shr     ecx, 2
3079
        sub     edi, 4
3108
        sub     edi, 4
3080
        mov     esi, edi
3109
        mov     esi, edi
3081
        sub     esi, eax
3110
        sub     esi, eax
3082
        std
3111
        std
3083
        rep movsd
3112
        rep movsd
3084
        mov     ecx, eax
3113
        mov     ecx, eax
3085
        shr     ecx, 2
3114
        shr     ecx, 2
3086
        xor     eax, eax
3115
        xor     eax, eax
3087
        rep stosd
3116
        rep stosd
3088
        cld
3117
        cld
3089
        mov     esi, [ebp+NTFS.attr_offs]
3118
        mov     esi, [ebp+NTFS.attr_offs]
3090
@@:
3119
@@:
3091
        mov     eax, dword [ebp+NTFS.attr_size]
3120
        mov     eax, dword [ebp+NTFS.attr_size]
3092
        mov     [esi+sizeWithoutHeader], eax
3121
        mov     [esi+sizeWithoutHeader], eax
3093
        mov     [ebp+NTFS.fileDataSize], 0
3122
        mov     [ebp+NTFS.fileDataSize], 0
3094
        clc
3123
        clc
3095
        ret
3124
        ret
3096
 
3125
 
3097
.nonResident:   ; convert resident to non-resident
3126
.nonResident:   ; convert resident to non-resident
3098
        mov     eax, dword [ebp+NTFS.attr_size]
3127
        mov     eax, dword [ebp+NTFS.attr_size]
3099
        sub     eax, 1
3128
        sub     eax, 1
3100
        sbb     edx, 0
3129
        sbb     edx, 0
3101
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
3130
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
3102
        shl     ecx, 9
3131
        shl     ecx, 9
3103
        div     ecx
3132
        div     ecx
3104
        inc     eax
3133
        inc     eax
3105
        mov     [ebp+NTFS.fileDataSize], eax
3134
        mov     [ebp+NTFS.fileDataSize], eax
3106
        mov     edi, [ebp+NTFS.BitmapStart]
3135
        mov     edi, [ebp+NTFS.BitmapStart]
3107
        push    ecx
3136
        push    ecx
3108
        call    ntfsSpaceAlloc
3137
        call    ntfsSpaceAlloc
3109
        pop     ecx
3138
        pop     ecx
3110
        jc      .err2
3139
        jc      .err2
3111
        mov     esi, [ebp+NTFS.attr_offs]
3140
        mov     esi, [ebp+NTFS.attr_offs]
3112
        xor     eax, eax
3141
        xor     eax, eax
3113
        xor     edx, edx
3142
        xor     edx, edx
3114
@@:
3143
@@:
3115
        add     eax, ecx
3144
        add     eax, ecx
3116
        inc     edx
3145
        inc     edx
3117
        cmp     eax, [esi+sizeWithoutHeader]
3146
        cmp     eax, [esi+sizeWithoutHeader]
3118
        jc      @b
3147
        jc      @b
3119
        push    edx
3148
        push    edx
3120
        push    eax
3149
        push    eax
3121
        stdcall kernel_alloc, eax
3150
        stdcall kernel_alloc, eax
3122
        mov     ecx, [esp]
3151
        mov     ecx, [esp]
3123
        shr     ecx, 2
3152
        shr     ecx, 2
3124
        mov     edi, eax
3153
        mov     edi, eax
3125
        mov     ebx, eax
3154
        mov     ebx, eax
3126
        xor     eax, eax
3155
        xor     eax, eax
3127
        rep stosd
3156
        rep stosd
3128
        mov     al, [esi+attributeOffset]
3157
        mov     al, [esi+attributeOffset]
3129
        mov     ecx, [esi+sizeWithoutHeader]
3158
        mov     ecx, [esi+sizeWithoutHeader]
3130
        add     esi, eax
3159
        add     esi, eax
3131
        mov     edi, ebx
3160
        mov     edi, ebx
3132
        rep movsb
3161
        rep movsb
3133
        mov     eax, [ebp+NTFS.fileDataStart]
3162
        mov     eax, [ebp+NTFS.fileDataStart]
3134
        mul     [ebp+NTFS.sectors_per_cluster]
3163
        mul     [ebp+NTFS.sectors_per_cluster]
3135
        pop     ecx
3164
        pop     ecx
3136
        shr     ecx, 9
3165
        shr     ecx, 9
3137
        call    fs_write64_app
3166
        call    fs_write64_app
3138
        stdcall kernel_free, ebx
3167
        stdcall kernel_free, ebx
3139
        mov     esi, [ebp+NTFS.attr_offs]
3168
        mov     esi, [ebp+NTFS.attr_offs]
3140
        add     esi, [esi+sizeWithHeader]
3169
        add     esi, [esi+sizeWithHeader]
3141
        mov     ecx, [ebp+NTFS.frs_buffer]
3170
        mov     ecx, [ebp+NTFS.frs_buffer]
3142
        add     ecx, [ecx+recordRealSize]
3171
        add     ecx, [ecx+recordRealSize]
3143
        sub     ecx, esi
3172
        sub     ecx, esi
3144
        shr     ecx, 2
3173
        shr     ecx, 2
3145
        lea     edi, [ebp+NTFS.bitmap_buf]
3174
        lea     edi, [ebp+NTFS.bitmap_buf]
3146
        push    ecx
3175
        push    ecx
3147
        rep movsd
3176
        rep movsd
3148
        mov     edi, [ebp+NTFS.attr_offs]
3177
        mov     edi, [ebp+NTFS.attr_offs]
3149
        add     edi, 16
3178
        add     edi, 16
3150
        mov     cl, 6
3179
        mov     cl, 6
3151
        xor     eax, eax
3180
        xor     eax, eax
3152
        rep stosd
3181
        rep stosd
3153
        mov     edi, [ebp+NTFS.attr_offs]
3182
        mov     edi, [ebp+NTFS.attr_offs]
3154
        mov     eax, [ebp+NTFS.fileDataSize]
3183
        mov     eax, [ebp+NTFS.fileDataSize]
3155
        dec     eax
3184
        dec     eax
3156
        mov     [edi+lastVCN], eax
3185
        mov     [edi+lastVCN], eax
3157
        inc     eax
3186
        inc     eax
3158
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
3187
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
3159
        shl     ecx, 9
3188
        shl     ecx, 9
3160
        mul     ecx
3189
        mul     ecx
3161
        mov     byte [edi+sizeWithHeader], 50h
3190
        mov     byte [edi+sizeWithHeader], 50h
3162
        mov     byte [edi+nonResidentFlag], 1
3191
        mov     byte [edi+nonResidentFlag], 1
3163
        mov     byte [edi+dataRunsOffset], 40h
3192
        mov     byte [edi+dataRunsOffset], 40h
3164
        mov     [edi+attributeAllocatedSize], eax
3193
        mov     [edi+attributeAllocatedSize], eax
3165
        mov     [edi+attributeAllocatedSize+4], edx
3194
        mov     [edi+attributeAllocatedSize+4], edx
3166
        mov     eax, dword [ebp+NTFS.attr_size]
3195
        mov     eax, dword [ebp+NTFS.attr_size]
3167
        mov     edx, dword [ebp+NTFS.attr_size+4]
3196
        mov     edx, dword [ebp+NTFS.attr_size+4]
3168
        mov     [edi+attributeRealSize], eax
3197
        mov     [edi+attributeRealSize], eax
3169
        mov     [edi+attributeRealSize+4], edx
3198
        mov     [edi+attributeRealSize+4], edx
3170
        mov     [edi+initialDataSize], eax
3199
        mov     [edi+initialDataSize], eax
3171
        mov     [edi+initialDataSize+4], edx
3200
        mov     [edi+initialDataSize+4], edx
3172
        mov     esi, edi
3201
        mov     esi, edi
3173
        add     edi, 40h
3202
        add     edi, 40h
3174
        call    createMcbEntry
3203
        call    createMcbEntry
3175
        mov     eax, edi
3204
        mov     eax, edi
3176
        mov     edi, [ebp+NTFS.attr_offs]
3205
        mov     edi, [ebp+NTFS.attr_offs]
3177
        sub     eax, edi
3206
        sub     eax, edi
3178
        add     eax, 8
3207
        add     eax, 8
3179
        and     eax, not 7
3208
        and     eax, not 7
3180
        mov     [edi+sizeWithHeader], eax
3209
        mov     [edi+sizeWithHeader], eax
3181
        pop     ecx
3210
        pop     ecx
3182
        lea     esi, [ebp+NTFS.bitmap_buf]
3211
        lea     esi, [ebp+NTFS.bitmap_buf]
3183
        add     edi, eax
3212
        add     edi, eax
3184
        rep movsd
3213
        rep movsd
3185
        mov     esi, [ebp+NTFS.frs_buffer]
3214
        mov     esi, [ebp+NTFS.frs_buffer]
3186
        sub     edi, esi
3215
        sub     edi, esi
3187
        mov     [esi+recordRealSize], edi
3216
        mov     [esi+recordRealSize], edi
3188
        pop     edx
3217
        pop     edx
3189
        sub     [ebp+NTFS.fileDataSize], edx
3218
        sub     [ebp+NTFS.fileDataSize], edx
3190
        add     [ebp+NTFS.fileDataStart], edx
3219
        add     [ebp+NTFS.fileDataStart], edx
3191
        ret
3220
        ret
3192
 
3221
 
3193
.makeResident:  ; convert non-resident to empty resident
3222
.makeResident:  ; convert non-resident to empty resident
3194
        movzx   eax, byte [esi+dataRunsOffset]
3223
        movzx   eax, byte [esi+dataRunsOffset]
3195
        mov     byte [esi+nonResidentFlag], 0
3224
        mov     byte [esi+nonResidentFlag], 0
3196
        mov     dword [esi+sizeWithoutHeader], 0
3225
        mov     dword [esi+sizeWithoutHeader], 0
3197
        mov     dword [esi+attributeOffset], 18h
3226
        mov     dword [esi+attributeOffset], 18h
3198
        add     esi, eax
3227
        add     esi, eax
3199
        xor     edi, edi
3228
        xor     edi, edi
3200
        sub     esp, 16
3229
        sub     esp, 16
3201
@@:
3230
@@:
3202
        call    ntfs_decode_mcb_entry
3231
        call    ntfs_decode_mcb_entry
3203
        jnc     @f
3232
        jnc     @f
3204
        cmp     dword[esp+8], 0
3233
        cmp     dword[esp+8], 0
3205
        jz      @b
3234
        jz      @b
3206
        add     edi, [esp+8]
3235
        add     edi, [esp+8]
3207
        mov     ebx, [esp]
3236
        mov     ebx, [esp]
3208
        call    ntfsSpaceFree
3237
        call    ntfsSpaceFree
3209
        jnc     @b
3238
        jnc     @b
3210
@@:
3239
@@:
3211
        add     esp, 16
3240
        add     esp, 16
3212
        mov     [ebp+NTFS.fileDataSize], 0
3241
        mov     [ebp+NTFS.fileDataSize], 0
3213
        ret
3242
        ret
3214
 
3243
 
3215
ntfsSpaceClean:
3244
ntfsSpaceClean:
3216
; clean up to 16 Mb of disk space
3245
; clean up to 16 Mb of disk space
3217
;   in:
3246
;   in:
3218
; [ebp+NTFS.fileDataStart] = block to clean
3247
; [ebp+NTFS.fileDataStart] = block to clean
3219
; [ebp+NTFS.fileDataSize] = block size
3248
; [ebp+NTFS.fileDataSize] = block size
3220
        mov     eax, [ebp+NTFS.fileDataSize]
3249
        mov     eax, [ebp+NTFS.fileDataSize]
3221
        test    eax, eax
3250
        test    eax, eax
3222
        jz      @f
3251
        jz      @f
3223
        mul     [ebp+NTFS.sectors_per_cluster]
3252
        mul     [ebp+NTFS.sectors_per_cluster]
3224
        cmp     eax, 8001h
3253
        cmp     eax, 8001h
3225
        jnc     @f
3254
        jnc     @f
3226
        push    eax
3255
        push    eax
3227
        shl     eax, 9
3256
        shl     eax, 9
3228
        stdcall kernel_alloc, eax
3257
        stdcall kernel_alloc, eax
3229
        pop     ecx
3258
        pop     ecx
3230
        test    eax, eax
3259
        test    eax, eax
3231
        jz      @f
3260
        jz      @f
3232
        push    ecx
3261
        push    ecx
3233
        shl     ecx, 7
3262
        shl     ecx, 7
3234
        mov     edi, eax
3263
        mov     edi, eax
3235
        mov     ebx, eax
3264
        mov     ebx, eax
3236
        xor     eax, eax
3265
        xor     eax, eax
3237
        rep stosd
3266
        rep stosd
3238
        mov     eax, [ebp+NTFS.fileDataStart]
3267
        mov     eax, [ebp+NTFS.fileDataStart]
3239
        mul     [ebp+NTFS.sectors_per_cluster]
3268
        mul     [ebp+NTFS.sectors_per_cluster]
3240
        mov     [ebp+NTFS.LastRead], eax
3269
        mov     [ebp+NTFS.LastRead], eax
3241
        pop     ecx
3270
        pop     ecx
3242
        call    fs_write64_app
3271
        call    fs_write64_app
3243
        stdcall kernel_free, ebx
3272
        stdcall kernel_free, ebx
3244
@@:
3273
@@:
3245
        ret
3274
        ret
3246
 
3275
 
3247
ntfsSpaceAlloc:
3276
ntfsSpaceAlloc:
3248
; allocate disk space
3277
; allocate disk space
3249
;   in:
3278
;   in:
3250
; edi = offset in bitmap to start search from
3279
; edi = offset in bitmap to start search from
3251
; [ebp+NTFS.fileDataSize] = block size in clusters
3280
; [ebp+NTFS.fileDataSize] = block size in clusters
3252
;   out:
3281
;   out:
3253
; [ebp+NTFS.fileDataStart] = allocated block starting cluster
3282
; [ebp+NTFS.fileDataStart] = allocated block starting cluster
3254
; CF=1 -> disk full
3283
; CF=1 -> disk full
3255
        push    eax
3284
        push    eax
3256
        mov     ecx, [ebp+NTFS.BitmapBuffer]
3285
        mov     ecx, [ebp+NTFS.BitmapBuffer]
3257
        add     edi, ecx
3286
        add     edi, ecx
3258
        add     ecx, [ebp+NTFS.BitmapSize]
3287
        add     ecx, [ebp+NTFS.BitmapSize]
3259
        sub     ecx, edi
3288
        sub     ecx, edi
3260
        jnc     @f
3289
        jnc     @f
3261
        call    bitmapBuffering
3290
        call    bitmapBuffering
3262
        shl     ecx, 2
3291
        shl     ecx, 2
3263
@@:
3292
@@:
3264
        shr     ecx, 2
3293
        shr     ecx, 2
3265
        mov     eax, [ebp+NTFS.fileDataSize]
3294
        mov     eax, [ebp+NTFS.fileDataSize]
3266
        shr     eax, 5
3295
        shr     eax, 5
3267
        jz      .small
3296
        jz      .small
3268
        mov     ebx, eax    ; bitmap dwords
3297
        mov     ebx, eax    ; bitmap dwords
3269
.start:
3298
.start:
3270
        mov     ecx, [ebp+NTFS.BitmapBuffer]
3299
        mov     ecx, [ebp+NTFS.BitmapBuffer]
3271
        add     ecx, [ebp+NTFS.BitmapSize]
3300
        add     ecx, [ebp+NTFS.BitmapSize]
3272
        sub     ecx, edi
3301
        sub     ecx, edi
3273
        shr     ecx, 2
3302
        shr     ecx, 2
3274
@@:
3303
@@:
3275
        xor     eax, eax
3304
        xor     eax, eax
3276
        repnz scasd         ; search for empty dword
3305
        repnz scasd         ; search for empty dword
3277
        jz      @f
3306
        jz      @f
3278
        call    bitmapBuffering
3307
        call    bitmapBuffering
3279
        jmp     @b
3308
        jmp     @b
3280
@@:
3309
@@:
3281
        cmp     ecx, ebx
3310
        cmp     ecx, ebx
3282
        jnc     @f
3311
        jnc     @f
3283
        call    bitmapBuffering
3312
        call    bitmapBuffering
3284
        jmp     @b
3313
        jmp     @b
3285
@@:
3314
@@:
3286
        sub     edi, 4
3315
        sub     edi, 4
3287
        mov     ecx, ebx
3316
        mov     ecx, ebx
3288
        mov     esi, edi
3317
        mov     esi, edi
3289
        xor     eax, eax
3318
        xor     eax, eax
3290
        repz scasd          ; check following dwords
3319
        repz scasd          ; check following dwords
3291
        jnz     .start
3320
        jnz     .start
3292
        sub     esi, 4
3321
        sub     esi, 4
3293
        mov     eax, [esi]
3322
        mov     eax, [esi]
3294
        xor     edx, edx
3323
        xor     edx, edx
3295
        bsr     edx, eax
3324
        bsr     edx, eax
3296
        inc     edx
3325
        inc     edx
3297
        push    edx         ; starting bit
3326
        push    edx         ; starting bit
3298
        push    esi         ; starting dword
3327
        push    esi         ; starting dword
3299
        add     esi, 4
3328
        add     esi, 4
3300
        neg     edx
3329
        neg     edx
3301
        add     edx, 32
3330
        add     edx, 32
3302
        mov     eax, [ebp+NTFS.fileDataSize]
3331
        mov     eax, [ebp+NTFS.fileDataSize]
3303
        sub     eax, edx
3332
        sub     eax, edx
3304
        mov     edx, eax
3333
        mov     edx, eax
3305
        shr     eax, 5
3334
        shr     eax, 5
3306
        shl     eax, 2
3335
        shl     eax, 2
3307
        add     esi, eax
3336
        add     esi, eax
3308
        mov     eax, [esi]
3337
        mov     eax, [esi]
3309
        bsf     ecx, eax    ; check last dword
3338
        bsf     ecx, eax    ; check last dword
3310
        jz      .done
3339
        jz      .done
3311
        and     edx, 31
3340
        and     edx, 31
3312
        cmp     ecx, edx
3341
        cmp     ecx, edx
3313
        jnc     .done
3342
        jnc     .done
3314
        add     esp, 8
3343
        add     esp, 8
3315
        jmp     .start
3344
        jmp     .start
3316
 
3345
 
3317
.small:     ; less than 32 clusters
3346
.small:     ; less than 32 clusters
3318
        mov     eax, -1
3347
        mov     eax, -1
3319
        repz scasd          ; search for zero bits
3348
        repz scasd          ; search for zero bits
3320
        test    ecx, ecx
3349
        test    ecx, ecx
3321
        jnz     @f
3350
        jnz     @f
3322
        call    bitmapBuffering
3351
        call    bitmapBuffering
3323
        jmp     .small
3352
        jmp     .small
3324
@@:
3353
@@:
3325
        sub     edi, 4
3354
        sub     edi, 4
3326
        mov     eax, [edi]
3355
        mov     eax, [edi]
3327
        not     eax
3356
        not     eax
3328
@@:
3357
@@:
3329
        bsf     ebx, eax    ; first 0
3358
        bsf     ebx, eax    ; first 0
3330
        jz      .again
3359
        jz      .again
3331
        not     eax
3360
        not     eax
3332
        shr     eax, cl
3361
        shr     eax, cl
3333
        shl     eax, cl
3362
        shl     eax, cl
3334
        bsf     edx, eax    ; next 1
3363
        bsf     edx, eax    ; next 1
3335
        jz      @f
3364
        jz      @f
3336
        sub     edx, ebx
3365
        sub     edx, ebx
3337
        cmp     edx, [ebp+NTFS.fileDataSize]
3366
        cmp     edx, [ebp+NTFS.fileDataSize]
3338
        jnc     .got        ; fits inside
3367
        jnc     .got        ; fits inside
3339
        bsf     ebx, eax
3368
        bsf     ebx, eax
3340
        not     eax
3369
        not     eax
3341
        shr     eax, cl
3370
        shr     eax, cl
3342
        shl     eax, cl
3371
        shl     eax, cl
3343
        jmp     @b
3372
        jmp     @b
3344
@@:         ; next dword
3373
@@:         ; next dword
3345
        mov     eax, [edi+4]
3374
        mov     eax, [edi+4]
3346
        bsf     edx, eax
3375
        bsf     edx, eax
3347
        jz      .got        ; empty
3376
        jz      .got        ; empty
3348
        add     edx, 32
3377
        add     edx, 32
3349
        sub     edx, ebx
3378
        sub     edx, ebx
3350
        cmp     edx, [ebp+NTFS.fileDataSize]
3379
        cmp     edx, [ebp+NTFS.fileDataSize]
3351
        jnc     .got        ; share between dwords
3380
        jnc     .got        ; share between dwords
3352
.again:
3381
.again:
3353
        add     edi, 4
3382
        add     edi, 4
3354
        jmp     .small
3383
        jmp     .small
3355
 
3384
 
3356
.got:
3385
.got:
3357
        push    ebx         ; starting bit
3386
        push    ebx         ; starting bit
3358
        push    edi         ; starting dword
3387
        push    edi         ; starting dword
3359
.done:      ; mark space
3388
.done:      ; mark space
3360
        mov     ecx, [esp+4]
3389
        mov     ecx, [esp+4]
3361
        cmp     ecx, 32
3390
        cmp     ecx, 32
3362
        jc      @f
3391
        jc      @f
3363
        xor     ecx, ecx
3392
        xor     ecx, ecx
3364
        add     dword [esp], 4
3393
        add     dword [esp], 4
3365
        mov     [esp+4], ecx
3394
        mov     [esp+4], ecx
3366
@@:
3395
@@:
3367
        mov     edi, [esp]
3396
        mov     edi, [esp]
3368
        xor     eax, eax
3397
        xor     eax, eax
3369
        dec     eax
3398
        dec     eax
3370
        shr     eax, cl
3399
        shr     eax, cl
3371
        shl     eax, cl
3400
        shl     eax, cl
3372
        neg     ecx
3401
        neg     ecx
3373
        add     ecx, 32
3402
        add     ecx, 32
3374
        sub     ecx, [ebp+NTFS.fileDataSize]
3403
        sub     ecx, [ebp+NTFS.fileDataSize]
3375
        jc      @f
3404
        jc      @f
3376
        shl     eax, cl     ; fits inside dword
3405
        shl     eax, cl     ; fits inside dword
3377
        shr     eax, cl
3406
        shr     eax, cl
3378
        or      [edi], eax
3407
        or      [edi], eax
3379
        jmp     .end
3408
        jmp     .end
3380
 
3409
 
3381
@@:
3410
@@:
3382
        or      [edi], eax
3411
        or      [edi], eax
3383
        neg     ecx
3412
        neg     ecx
3384
        push    ecx
3413
        push    ecx
3385
        shr     ecx, 5
3414
        shr     ecx, 5
3386
        add     edi, 4
3415
        add     edi, 4
3387
        xor     eax, eax
3416
        xor     eax, eax
3388
        dec     eax
3417
        dec     eax
3389
        rep stosd
3418
        rep stosd
3390
        pop     ecx
3419
        pop     ecx
3391
        and     ecx, 31
3420
        and     ecx, 31
3392
        shr     eax, cl
3421
        shr     eax, cl
3393
        shl     eax, cl
3422
        shl     eax, cl
3394
        not     eax
3423
        not     eax
3395
        or      [edi], eax
3424
        or      [edi], eax
3396
.end:
3425
.end:
3397
        pop     eax
3426
        pop     eax
3398
        pop     ecx
3427
        pop     ecx
3399
        sub     eax, [ebp+NTFS.BitmapBuffer]
3428
        sub     eax, [ebp+NTFS.BitmapBuffer]
3400
        shl     eax, 3
3429
        shl     eax, 3
3401
        add     eax, ecx
3430
        add     eax, ecx
3402
        pop     ecx
3431
        pop     ecx
3403
        mov     ecx, [ebp+NTFS.fileDataSize]
3432
        mov     ecx, [ebp+NTFS.fileDataSize]
3404
        mov     [ebp+NTFS.fileDataStart], eax
3433
        mov     [ebp+NTFS.fileDataStart], eax
3405
        add     ecx, eax
3434
        add     ecx, eax
3406
        add     ecx, 4095
3435
        add     ecx, 4095
3407
        shr     ecx, 3+9
3436
        shr     ecx, 3+9
3408
        shr     eax, 3+9
3437
        shr     eax, 3+9
3409
        sub     ecx, eax
3438
        sub     ecx, eax
3410
        mov     ebx, eax
3439
        mov     ebx, eax
3411
        shl     ebx, 9
3440
        shl     ebx, 9
3412
        add     eax, [ebp+NTFS.BitmapLocation]
3441
        add     eax, [ebp+NTFS.BitmapLocation]
3413
        add     ebx, [ebp+NTFS.BitmapBuffer]
3442
        add     ebx, [ebp+NTFS.BitmapBuffer]
3414
        xor     edx, edx
3443
        xor     edx, edx
3415
        jmp     fs_write64_app
3444
        jmp     fs_write64_app
3416
 
3445
 
3417
ntfsSpaceFree:
3446
ntfsSpaceFree:
3418
; free disk space
3447
; free disk space
3419
;   in:
3448
;   in:
3420
; edi = starting cluster
3449
; edi = starting cluster
3421
; ebx = size in clusters
3450
; ebx = size in clusters
3422
        mov     eax, edi
3451
        mov     eax, edi
3423
        add     eax, ebx
3452
        add     eax, ebx
3424
        shr     eax, 3
3453
        shr     eax, 3
3425
        inc     eax
3454
        inc     eax
3426
        cmp     eax, [ebp+NTFS.BitmapSize]
3455
        cmp     eax, [ebp+NTFS.BitmapSize]
3427
        jc      @f
3456
        jc      @f
3428
        add     eax, [ebp+NTFS.BitmapBuffer]
3457
        add     eax, [ebp+NTFS.BitmapBuffer]
3429
        push    edi
3458
        push    edi
3430
        mov     edi, eax
3459
        mov     edi, eax
3431
        call    bitmapBuffering
3460
        call    bitmapBuffering
3432
        pop     edi
3461
        pop     edi
3433
@@:
3462
@@:
3434
        push    edi
3463
        push    edi
3435
        mov     ecx, edi
3464
        mov     ecx, edi
3436
        shr     edi, 5
3465
        shr     edi, 5
3437
        shl     edi, 2
3466
        shl     edi, 2
3438
        add     edi, [ebp+NTFS.BitmapBuffer]
3467
        add     edi, [ebp+NTFS.BitmapBuffer]
3439
        and     ecx, 31
3468
        and     ecx, 31
3440
        xor     eax, eax
3469
        xor     eax, eax
3441
        dec     eax
3470
        dec     eax
3442
        shr     eax, cl
3471
        shr     eax, cl
3443
        shl     eax, cl
3472
        shl     eax, cl
3444
        neg     ecx
3473
        neg     ecx
3445
        add     ecx, 32
3474
        add     ecx, 32
3446
        sub     ecx, ebx
3475
        sub     ecx, ebx
3447
        jc      @f
3476
        jc      @f
3448
        shl     eax, cl     ; fits inside dword
3477
        shl     eax, cl     ; fits inside dword
3449
        shr     eax, cl
3478
        shr     eax, cl
3450
        not     eax
3479
        not     eax
3451
        and     [edi], eax
3480
        and     [edi], eax
3452
        jmp     .writeBitmap
3481
        jmp     .writeBitmap
3453
 
3482
 
3454
@@:
3483
@@:
3455
        not     eax
3484
        not     eax
3456
        and     [edi], eax
3485
        and     [edi], eax
3457
        neg     ecx
3486
        neg     ecx
3458
        push    ecx
3487
        push    ecx
3459
        shr     ecx, 5
3488
        shr     ecx, 5
3460
        add     edi, 4
3489
        add     edi, 4
3461
        xor     eax, eax
3490
        xor     eax, eax
3462
        rep stosd
3491
        rep stosd
3463
        pop     ecx
3492
        pop     ecx
3464
        and     ecx, 31
3493
        and     ecx, 31
3465
        dec     eax
3494
        dec     eax
3466
        shr     eax, cl
3495
        shr     eax, cl
3467
        shl     eax, cl
3496
        shl     eax, cl
3468
        and     [edi], eax
3497
        and     [edi], eax
3469
.writeBitmap:
3498
.writeBitmap:
3470
        pop     eax
3499
        pop     eax
3471
        mov     edi, eax
3500
        mov     edi, eax
3472
        lea     ecx, [eax+ebx+4095]
3501
        lea     ecx, [eax+ebx+4095]
3473
        shr     eax, 3+9
3502
        shr     eax, 3+9
3474
        shr     ecx, 3+9
3503
        shr     ecx, 3+9
3475
        sub     ecx, eax
3504
        sub     ecx, eax
3476
        mov     ebx, eax
3505
        mov     ebx, eax
3477
        shl     ebx, 9
3506
        shl     ebx, 9
3478
        add     eax, [ebp+NTFS.BitmapLocation]
3507
        add     eax, [ebp+NTFS.BitmapLocation]
3479
        add     ebx, [ebp+NTFS.BitmapBuffer]
3508
        add     ebx, [ebp+NTFS.BitmapBuffer]
3480
        xor     edx, edx
3509
        xor     edx, edx
3481
        jmp     fs_write64_app
3510
        jmp     fs_write64_app
3482
 
3511
 
3483
bitmapBuffering:
3512
bitmapBuffering:
3484
; Extend BitmapBuffer and read next 32kb of bitmap
3513
; Extend BitmapBuffer and read next 32kb of bitmap
3485
; Warning: $Bitmap fragmentation is not foreseen
3514
; Warning: $Bitmap fragmentation is not foreseen
3486
; in: edi -> position in bitmap buffer
3515
; in: edi -> position in bitmap buffer
3487
; out: ecx = number of buffered dwords left
3516
; out: ecx = number of buffered dwords left
3488
        push    ebx
3517
        push    ebx
3489
        mov     eax, [ebp+NTFS.BitmapTotalSize]
3518
        mov     eax, [ebp+NTFS.BitmapTotalSize]
3490
        cmp     eax, [ebp+NTFS.BitmapSize]
3519
        cmp     eax, [ebp+NTFS.BitmapSize]
3491
        jz      .end
3520
        jz      .end
3492
        stdcall alloc_pages, 8
3521
        stdcall alloc_pages, 8
3493
        test    eax, eax
3522
        test    eax, eax
3494
        jz      .end
3523
        jz      .end
3495
        add     eax, 3
3524
        add     eax, 3
3496
        mov     ebx, [ebp+NTFS.BitmapBuffer]
3525
        mov     ebx, [ebp+NTFS.BitmapBuffer]
3497
        add     ebx, [ebp+NTFS.BitmapSize]
3526
        add     ebx, [ebp+NTFS.BitmapSize]
3498
        push    ebx
3527
        push    ebx
3499
        mov     ecx, 8
3528
        mov     ecx, 8
3500
        call    commit_pages
3529
        call    commit_pages
3501
        mov     eax, [ebp+NTFS.BitmapSize]
3530
        mov     eax, [ebp+NTFS.BitmapSize]
3502
        shr     eax, 9
3531
        shr     eax, 9
3503
        add     eax, [ebp+NTFS.BitmapLocation]
3532
        add     eax, [ebp+NTFS.BitmapLocation]
3504
        pop     ebx
3533
        pop     ebx
3505
        mov     ecx, 64
3534
        mov     ecx, 64
3506
        xor     edx, edx
3535
        xor     edx, edx
3507
        call    fs_read64_app
3536
        call    fs_read64_app
3508
        test    eax, eax
3537
        test    eax, eax
3509
        jnz     .err
3538
        jnz     .err
3510
        add     [ebp+NTFS.BitmapSize], 8000h
3539
        add     [ebp+NTFS.BitmapSize], 8000h
3511
        mov     eax, [ebp+NTFS.BitmapTotalSize]
3540
        mov     eax, [ebp+NTFS.BitmapTotalSize]
3512
        cmp     eax, [ebp+NTFS.BitmapSize]
3541
        cmp     eax, [ebp+NTFS.BitmapSize]
3513
        jnc     @f
3542
        jnc     @f
3514
        mov     [ebp+NTFS.BitmapSize], eax
3543
        mov     [ebp+NTFS.BitmapSize], eax
3515
@@:
3544
@@:
3516
        pop     ebx
3545
        pop     ebx
3517
        mov     ecx, [ebp+NTFS.BitmapBuffer]
3546
        mov     ecx, [ebp+NTFS.BitmapBuffer]
3518
        add     ecx, [ebp+NTFS.BitmapSize]
3547
        add     ecx, [ebp+NTFS.BitmapSize]
3519
        sub     ecx, edi
3548
        sub     ecx, edi
3520
        jc      bitmapBuffering
3549
        jc      bitmapBuffering
3521
        shr     ecx, 2
3550
        shr     ecx, 2
3522
        ret
3551
        ret
3523
 
3552
 
3524
.err:
3553
.err:
3525
        mov     eax, [ebp+NTFS.BitmapBuffer]
3554
        mov     eax, [ebp+NTFS.BitmapBuffer]
3526
        add     eax, [ebp+NTFS.BitmapSize]
3555
        add     eax, [ebp+NTFS.BitmapSize]
3527
        mov     ecx, 8
3556
        mov     ecx, 8
3528
        call    release_pages
3557
        call    release_pages
3529
.end:
3558
.end:
3530
        add     esp, 12     ; ret
3559
        add     esp, 12     ; ret
3531
        stc
3560
        stc
3532
        ret
3561
        ret
3533
 
3562
 
3534
;----------------------------------------------------------------
3563
;----------------------------------------------------------------
3535
ntfs_WriteFile:
3564
ntfs_WriteFile:
3536
        cmp     byte [esi], 0
3565
        cmp     byte [esi], 0
3537
        jnz     @f
3566
        jnz     @f
3538
        xor     ebx, ebx
3567
        xor     ebx, ebx
3539
        movi    eax, ERROR_ACCESS_DENIED
3568
        movi    eax, ERROR_ACCESS_DENIED
3540
        ret
3569
        ret
3541
@@:
3570
@@:
3542
        call    ntfs_lock
3571
        call    ntfs_lock
3543
        stdcall ntfs_find_lfn, [esp+4]
3572
        stdcall ntfs_find_lfn, [esp+4]
3544
        jc      ntfsNotFound
3573
        jc      ntfsNotFound
3545
        cmp     [ebp+NTFS.cur_iRecord], 16
3574
        cmp     [ebp+NTFS.cur_iRecord], 16
3546
        jc      ntfsDenied
3575
        jc      ntfsDenied
3547
        test    dword [eax+fileFlags], 10000001h
3576
        test    dword [eax+fileFlags], 10000001h
3548
        jnz     ntfsDenied
3577
        jnz     ntfsDenied
3549
        cmp     [ebp+NTFS.fragmentCount], 1
3578
        cmp     [ebp+NTFS.fragmentCount], 1
3550
        jnz     ntfsUnsupported     ; record fragmented
3579
        jnz     ntfsUnsupported     ; record fragmented
3551
; edit directory node
3580
; edit directory node
3552
        mov     edi, [ebp+NTFS.cur_index_buf]
3581
        mov     edi, [ebp+NTFS.cur_index_buf]
3553
        cmp     dword [edi], 'INDX'
3582
        cmp     dword [edi], 'INDX'
3554
        jz      @f
3583
        jz      @f
3555
        mov     esi, [ebp+NTFS.frs_buffer]
3584
        mov     esi, [ebp+NTFS.frs_buffer]
3556
        mov     ecx, [esi+recordRealSize]
3585
        mov     ecx, [esi+recordRealSize]
3557
        shr     ecx, 2
3586
        shr     ecx, 2
3558
        rep movsd
3587
        rep movsd
3559
        mov     esi, [ebp+NTFS.attr_offs]
3588
        mov     esi, [ebp+NTFS.attr_offs]
3560
        mov     cl, [esi+attributeOffset]
3589
        mov     cl, [esi+attributeOffset]
3561
        sub     esi, [ebp+NTFS.frs_buffer]
3590
        sub     esi, [ebp+NTFS.frs_buffer]
3562
        add     eax, ecx
3591
        add     eax, ecx
3563
        add     eax, esi
3592
        add     eax, esi
3564
@@:
3593
@@:
3565
        mov     edi, eax
3594
        mov     edi, eax
3566
        mov     eax, [ebx+4]
3595
        mov     eax, [ebx+4]
3567
        mov     edx, [ebx+8]
3596
        mov     edx, [ebx+8]
3568
        add     eax, [ebx+12]
3597
        add     eax, [ebx+12]
3569
        adc     edx, 0
3598
        adc     edx, 0
3570
        mov     [edi+fileRealSize], eax
3599
        mov     [edi+fileRealSize], eax
3571
        mov     [edi+fileRealSize+4], edx
3600
        mov     [edi+fileRealSize+4], edx
3572
        push    edx eax ebx
3601
        push    edx eax ebx
3573
        call    ntfsGetTime
3602
        call    ntfsGetTime
3574
        mov     [edi+fileModified], eax
3603
        mov     [edi+fileModified], eax
3575
        mov     [edi+fileModified+4], edx
3604
        mov     [edi+fileModified+4], edx
3576
        mov     [edi+recordModified], eax
3605
        mov     [edi+recordModified], eax
3577
        mov     [edi+recordModified+4], edx
3606
        mov     [edi+recordModified+4], edx
3578
        mov     [edi+fileAccessed], eax
3607
        mov     [edi+fileAccessed], eax
3579
        mov     [edi+fileAccessed+4], edx
3608
        mov     [edi+fileAccessed+4], edx
3580
        pop     ebx ecx edx
3609
        pop     ebx ecx edx
3581
        mov     eax, [ebp+NTFS.LastRead]
3610
        mov     eax, [ebp+NTFS.LastRead]
3582
        mov     [ebp+NTFS.nodeLastRead], eax
3611
        mov     [ebp+NTFS.nodeLastRead], eax
3583
        mov     [ebp+NTFS.cur_attr], 0x80
3612
        mov     [ebp+NTFS.cur_attr], 0x80
3584
        mov     [ebp+NTFS.cur_offs], 0
3613
        mov     [ebp+NTFS.cur_offs], 0
3585
        mov     [ebp+NTFS.cur_size], 0
3614
        mov     [ebp+NTFS.cur_size], 0
3586
        call    ntfs_read_attr
3615
        call    ntfs_read_attr
3587
        jc      ntfsFail
3616
        jc      ntfsFail
3588
        mov     esi, edi
3617
        mov     esi, edi
3589
        mov     edi, [ebp+NTFS.frs_buffer]
3618
        mov     edi, [ebp+NTFS.frs_buffer]
3590
        cmp     word [edi+baseRecordReuse], 0
3619
        cmp     word [edi+baseRecordReuse], 0
3591
        jnz     ntfsUnsupported     ; auxiliary record
3620
        jnz     ntfsUnsupported     ; auxiliary record
3592
        mov     al, [edi+attributeOffset]
3621
        mov     al, [edi+attributeOffset]
3593
        add     edi, eax
3622
        add     edi, eax
3594
        mov     al, [edi+attributeOffset]
3623
        mov     al, [edi+attributeOffset]
3595
        add     edi, eax
3624
        add     edi, eax
3596
        mov     eax, ecx
3625
        mov     eax, ecx
3597
        mov     ecx, 6
3626
        mov     ecx, 6
3598
        add     esi, fileModified
3627
        add     esi, fileModified
3599
        add     edi, 8
3628
        add     edi, 8
3600
        rep movsd
3629
        rep movsd
3601
        mov     ecx, [ebp+NTFS.attr_offs]
3630
        mov     ecx, [ebp+NTFS.attr_offs]
3602
        cmp     word [ecx+attributeFlags], 0
3631
        cmp     word [ecx+attributeFlags], 0
3603
        jnz     ntfsUnsupported
3632
        jnz     ntfsUnsupported
3604
        push    ebx
3633
        push    ebx
3605
        cmp     byte [ecx+nonResidentFlag], 0
3634
        cmp     byte [ecx+nonResidentFlag], 0
3606
        jz      .resizeAttribute
3635
        jz      .resizeAttribute
3607
        cmp     edx, [ecx+attributeRealSize+4]
3636
        cmp     edx, [ecx+attributeRealSize+4]
3608
        jc      .writeNode
3637
        jc      .writeNode
3609
        jnz     .resizeAttribute
3638
        jnz     .resizeAttribute
3610
        cmp     [ecx+attributeRealSize], eax
3639
        cmp     [ecx+attributeRealSize], eax
3611
        jnc     .writeNode
3640
        jnc     .writeNode
3612
.resizeAttribute:
3641
.resizeAttribute:
3613
        call    resizeAttribute
3642
        call    resizeAttribute
3614
        jc      ntfsErrorPop
3643
        jc      ntfsErrorPop
3615
        mov     ecx, [ebp+NTFS.attr_offs]
3644
        mov     ecx, [ebp+NTFS.attr_offs]
3616
        cmp     byte [ecx+nonResidentFlag], 1
3645
        cmp     byte [ecx+nonResidentFlag], 1
3617
        jz      @f
3646
        jz      @f
3618
        mov     ebx, [esp]
3647
        mov     ebx, [esp]
3619
        movzx   edi, byte [ecx+attributeOffset]
3648
        movzx   edi, byte [ecx+attributeOffset]
3620
        add     edi, ecx
3649
        add     edi, ecx
3621
        add     edi, [ebx+4]
3650
        add     edi, [ebx+4]
3622
        mov     ecx, [ebx+12]
3651
        mov     ecx, [ebx+12]
3623
        mov     esi, [ebx+16]
3652
        mov     esi, [ebx+16]
3624
        rep movsb
3653
        rep movsb
3625
@@:
3654
@@:
3626
        mov     ebx, [ebp+NTFS.frs_buffer]
3655
        mov     ebx, [ebp+NTFS.frs_buffer]
3627
        mov     edx, [ebp+NTFS.mftLastRead]
3656
        mov     edx, [ebp+NTFS.mftLastRead]
3628
        call    writeRecord     ; file
3657
        call    writeRecord     ; file
3629
        call    ntfs_restore_usa_frs
3658
        call    ntfs_restore_usa_frs
3630
.writeNode:
3659
.writeNode:
3631
        mov     ebx, [ebp+NTFS.cur_index_buf]
3660
        mov     ebx, [ebp+NTFS.cur_index_buf]
3632
        mov     edx, [ebp+NTFS.nodeLastRead]
3661
        mov     edx, [ebp+NTFS.nodeLastRead]
3633
        call    writeRecord     ; directory
3662
        call    writeRecord     ; directory
3634
        pop     ebx
3663
        pop     ebx
3635
        mov     ecx, [ebp+NTFS.attr_offs]
3664
        mov     ecx, [ebp+NTFS.attr_offs]
3636
        cmp     byte [ecx+nonResidentFlag], 0
3665
        cmp     byte [ecx+nonResidentFlag], 0
3637
        jz      .done
3666
        jz      .done
3638
        mov     ecx, [ebx+12]
3667
        mov     ecx, [ebx+12]
3639
        test    ecx, ecx
3668
        test    ecx, ecx
3640
        jz      .done
3669
        jz      .done
3641
        mov     eax, [ebx+4]
3670
        mov     eax, [ebx+4]
3642
        mov     edx, [ebx+8]
3671
        mov     edx, [ebx+8]
3643
        mov     esi, [ebx+16]
3672
        mov     esi, [ebx+16]
3644
        shrd    eax, edx, 9
3673
        shrd    eax, edx, 9
3645
        test    dword[ebx+4], 1FFh
3674
        test    dword[ebx+4], 1FFh
3646
        jz      .aligned
3675
        jz      .aligned
3647
        mov     [ebp+NTFS.cur_offs], eax
3676
        mov     [ebp+NTFS.cur_offs], eax
3648
        mov     [ebp+NTFS.cur_size], 1
3677
        mov     [ebp+NTFS.cur_size], 1
3649
        lea     edi, [ebp+NTFS.bitmap_buf]
3678
        lea     edi, [ebp+NTFS.bitmap_buf]
3650
        mov     [ebp+NTFS.cur_buf], edi
3679
        mov     [ebp+NTFS.cur_buf], edi
3651
        call    ntfs_read_attr.continue
3680
        call    ntfs_read_attr.continue
3652
        jc      ntfsDevice
3681
        jc      ntfsDevice
3653
        mov     eax, [ebx+4]
3682
        mov     eax, [ebx+4]
3654
        and     eax, 1FFh
3683
        and     eax, 1FFh
3655
        add     edi, eax
3684
        add     edi, eax
3656
        sub     eax, [ebp+NTFS.cur_read]
3685
        sub     eax, [ebp+NTFS.cur_read]
3657
        neg     eax
3686
        neg     eax
3658
        push    ecx
3687
        push    ecx
3659
        cmp     ecx, eax
3688
        cmp     ecx, eax
3660
        jb      @f
3689
        jb      @f
3661
        mov     ecx, eax
3690
        mov     ecx, eax
3662
@@:
3691
@@:
3663
        sub     [esp], ecx
3692
        sub     [esp], ecx
3664
        rep movsb
3693
        rep movsb
3665
        push    ebx
3694
        push    ebx
3666
        mov     eax, [ebp+NTFS.LastRead]
3695
        mov     eax, [ebp+NTFS.LastRead]
3667
        lea     ebx, [ebp+NTFS.bitmap_buf]
3696
        lea     ebx, [ebp+NTFS.bitmap_buf]
3668
        mov     ecx, 1
3697
        mov     ecx, 1
3669
        xor     edx, edx
3698
        xor     edx, edx
3670
        call    fs_write64_app
3699
        call    fs_write64_app
3671
        pop     ebx
3700
        pop     ebx
3672
        pop     ecx
3701
        pop     ecx
3673
        test    ecx, ecx
3702
        test    ecx, ecx
3674
        jz      .done
3703
        jz      .done
3675
        mov     eax, [ebx+4]
3704
        mov     eax, [ebx+4]
3676
        mov     edx, [ebx+8]
3705
        mov     edx, [ebx+8]
3677
        shrd    eax, edx, 9
3706
        shrd    eax, edx, 9
3678
        inc     eax
3707
        inc     eax
3679
.aligned:
3708
.aligned:
3680
        push    ecx
3709
        push    ecx
3681
        shr     ecx, 9
3710
        shr     ecx, 9
3682
        mov     [ebp+NTFS.cur_offs], eax
3711
        mov     [ebp+NTFS.cur_offs], eax
3683
        mov     [ebp+NTFS.cur_size], ecx
3712
        mov     [ebp+NTFS.cur_size], ecx
3684
        mov     [ebp+NTFS.cur_buf], esi
3713
        mov     [ebp+NTFS.cur_buf], esi
3685
        add     eax, ecx
3714
        add     eax, ecx
3686
        push    eax
3715
        push    eax
3687
        mov     [ebp+NTFS.bWriteAttr], 1
3716
        mov     [ebp+NTFS.bWriteAttr], 1
3688
        call    ntfs_read_attr.continue
3717
        call    ntfs_read_attr.continue
3689
        mov     [ebp+NTFS.bWriteAttr], 0
3718
        mov     [ebp+NTFS.bWriteAttr], 0
3690
        pop     [ebp+NTFS.cur_offs]
3719
        pop     [ebp+NTFS.cur_offs]
3691
        pop     ecx
3720
        pop     ecx
3692
        jc      ntfsDevice
3721
        jc      ntfsDevice
3693
        and     ecx, 1FFh
3722
        and     ecx, 1FFh
3694
        jz      .done
3723
        jz      .done
3695
        add     esi, [ebp+NTFS.cur_read]
3724
        add     esi, [ebp+NTFS.cur_read]
3696
        mov     [ebp+NTFS.cur_size], 1
3725
        mov     [ebp+NTFS.cur_size], 1
3697
        lea     edi, [ebp+NTFS.bitmap_buf]
3726
        lea     edi, [ebp+NTFS.bitmap_buf]
3698
        mov     [ebp+NTFS.cur_buf], edi
3727
        mov     [ebp+NTFS.cur_buf], edi
3699
        call    ntfs_read_attr.continue
3728
        call    ntfs_read_attr.continue
3700
        jc      ntfsDevice
3729
        jc      ntfsDevice
3701
        rep movsb
3730
        rep movsb
3702
        push    ebx
3731
        push    ebx
3703
        mov     eax, [ebp+NTFS.LastRead]
3732
        mov     eax, [ebp+NTFS.LastRead]
3704
        lea     ebx, [ebp+NTFS.bitmap_buf]
3733
        lea     ebx, [ebp+NTFS.bitmap_buf]
3705
        mov     ecx, 1
3734
        mov     ecx, 1
3706
        xor     edx, edx
3735
        xor     edx, edx
3707
        call    fs_write64_app
3736
        call    fs_write64_app
3708
        pop     ebx
3737
        pop     ebx
3709
.done:
3738
.done:
3710
        mov     ebx, [ebx+12]
3739
        mov     ebx, [ebx+12]
3711
        jmp     ntfsDone
3740
        jmp     ntfsDone
3712
 
3741
 
3713
;----------------------------------------------------------------
3742
;----------------------------------------------------------------
3714
ntfs_Delete:
3743
ntfs_Delete:
3715
        cmp     byte [esi], 0
3744
        cmp     byte [esi], 0
3716
        jnz     @f
3745
        jnz     @f
3717
        xor     ebx, ebx
3746
        xor     ebx, ebx
3718
        movi    eax, ERROR_ACCESS_DENIED
3747
        movi    eax, ERROR_ACCESS_DENIED
3719
        ret
3748
        ret
3720
 
3749
 
3721
@@:
3750
@@:
3722
        call    ntfs_lock
3751
        call    ntfs_lock
3723
        stdcall ntfs_find_lfn, [esp+4]
3752
        stdcall ntfs_find_lfn, [esp+4]
3724
        jc      ntfsNotFound
3753
        jc      ntfsNotFound
3725
        cmp     [ebp+NTFS.cur_iRecord], 16
3754
        cmp     [ebp+NTFS.cur_iRecord], 16
3726
        jc      ntfsDenied
3755
        jc      ntfsDenied
3727
        test    byte [eax+fileFlags], 1
3756
        test    byte [eax+fileFlags], 1
3728
        jnz     ntfsDenied
3757
        jnz     ntfsDenied
3729
        cmp     [ebp+NTFS.fragmentCount], 1
3758
        cmp     [ebp+NTFS.fragmentCount], 1
3730
        jnz     ntfsUnsupported     ; record fragmented
3759
        jnz     ntfsUnsupported     ; record fragmented
3731
        mov     ebx, [eax+directoryRecordReference]
3760
        mov     ebx, [eax+directoryRecordReference]
3732
        mov     [ebp+NTFS.newRecord], ebx
3761
        mov     [ebp+NTFS.newRecord], ebx
3733
        mov     bx, [eax+fileReferenceReuse]
3762
        mov     bx, [eax+fileReferenceReuse]
3734
        mov     [ebp+NTFS.indexPointer], esi
3763
        mov     [ebp+NTFS.indexPointer], esi
3735
        mov     eax, [ebp+NTFS.cur_iRecord]
3764
        mov     eax, [ebp+NTFS.cur_iRecord]
3736
        shr     eax, 3
3765
        shr     eax, 3
3737
        cmp     eax, [ebp+NTFS.mftBitmapSize]
3766
        cmp     eax, [ebp+NTFS.mftBitmapSize]
3738
        jnc     ntfsUnsupported
3767
        jnc     ntfsUnsupported
3739
; examine file record
3768
; examine file record
3740
        mov     [ebp+NTFS.cur_attr], 0x80   ; file?
3769
        mov     [ebp+NTFS.cur_attr], 0x80   ; file?
3741
        mov     [ebp+NTFS.cur_offs], 0
3770
        mov     [ebp+NTFS.cur_offs], 0
3742
        mov     [ebp+NTFS.cur_size], 0
3771
        mov     [ebp+NTFS.cur_size], 0
3743
        call    ntfs_read_attr
3772
        call    ntfs_read_attr
3744
        jnc     @f
3773
        jnc     @f
3745
        xor     eax, eax
3774
        xor     eax, eax
3746
        push    ebx eax eax eax eax
3775
        push    ebx eax eax eax eax
3747
        mov     [esp+12], esp
3776
        mov     [esp+12], esp
3748
        push    eax
3777
        push    eax
3749
        mov     ebx, esp
3778
        mov     ebx, esp
3750
        mov     [ebp+NTFS.cur_attr], 0x90   ; folder?
3779
        mov     [ebp+NTFS.cur_attr], 0x90   ; folder?
3751
        call    ntfs_ReadFolder.doit
3780
        call    ntfs_ReadFolder.doit
3752
        mov     edx, [esp+12]
3781
        mov     edx, [esp+12]
3753
        add     esp, 20
3782
        add     esp, 20
3754
        pop     ebx
3783
        pop     ebx
3755
        test    eax, eax
3784
        test    eax, eax
3756
        jnz     .ret
3785
        jnz     .ret
3757
        cmp     edx, 2
3786
        cmp     edx, 2
3758
        jnz     ntfsDenied      ; folder is not empty
3787
        jnz     ntfsDenied      ; folder is not empty
3759
        mov     [ebp+NTFS.cur_attr], 0xA0
3788
        mov     [ebp+NTFS.cur_attr], 0xA0
3760
        mov     [ebp+NTFS.cur_offs], 0
3789
        mov     [ebp+NTFS.cur_offs], 0
3761
        mov     [ebp+NTFS.cur_size], 0
3790
        mov     [ebp+NTFS.cur_size], 0
3762
        call    ntfs_read_attr.newAttribute
3791
        call    ntfs_read_attr.newAttribute
3763
        jc      .deleteFileRecord
3792
        jc      .deleteFileRecord
3764
@@:
3793
@@:
3765
        mov     esi, [ebp+NTFS.frs_buffer]
3794
        mov     esi, [ebp+NTFS.frs_buffer]
3766
        cmp     word [esi+baseRecordReuse], 0
3795
        cmp     word [esi+baseRecordReuse], 0
3767
        jnz     ntfsUnsupported     ; auxiliary record
3796
        jnz     ntfsUnsupported     ; auxiliary record
3768
        cmp     word [esi+reuseCounter], bx
3797
        cmp     word [esi+reuseCounter], bx
3769
        jnz     .backToIndex        ; broken index
3798
        jnz     .backToIndex        ; broken index
3770
        test    byte [esi+recordFlags], 1
3799
        test    byte [esi+recordFlags], 1
3771
        jz      .writeBitmapMFT     ; record deleted
3800
        jz      .writeBitmapMFT     ; record deleted
3772
        cmp     byte [esi+hardLinkCounter], 3
3801
        cmp     byte [esi+hardLinkCounter], 3
3773
        jnc     ntfsUnsupported
3802
        jnc     ntfsUnsupported
3774
        mov     esi, [ebp+NTFS.attr_offs]
3803
        mov     esi, [ebp+NTFS.attr_offs]
3775
        cmp     byte [esi+nonResidentFlag], 0
3804
        cmp     byte [esi+nonResidentFlag], 0
3776
        jz      .deleteFileRecord
3805
        jz      .deleteFileRecord
3777
        movzx   eax, byte [esi+dataRunsOffset]
3806
        movzx   eax, byte [esi+dataRunsOffset]
3778
        add     esi, eax
3807
        add     esi, eax
3779
        xor     edi, edi
3808
        xor     edi, edi
3780
        sub     esp, 16
3809
        sub     esp, 16
3781
@@:
3810
@@:
3782
        call    ntfs_decode_mcb_entry
3811
        call    ntfs_decode_mcb_entry
3783
        jnc     @f
3812
        jnc     @f
3784
        cmp     dword[esp+8], 0
3813
        cmp     dword[esp+8], 0
3785
        jz      @b
3814
        jz      @b
3786
        add     edi, [esp+8]
3815
        add     edi, [esp+8]
3787
        mov     ebx, [esp]
3816
        mov     ebx, [esp]
3788
        call    ntfsSpaceFree
3817
        call    ntfsSpaceFree
3789
        jnc     @b
3818
        jnc     @b
3790
@@:
3819
@@:
3791
        add     esp, 16
3820
        add     esp, 16
3792
.deleteFileRecord:
3821
.deleteFileRecord:
3793
        mov     ebx, [ebp+NTFS.frs_buffer]
3822
        mov     ebx, [ebp+NTFS.frs_buffer]
3794
        mov     byte [ebx+recordFlags], 0
3823
        mov     byte [ebx+recordFlags], 0
3795
        mov     edx, [ebp+NTFS.mftLastRead]
3824
        mov     edx, [ebp+NTFS.mftLastRead]
3796
        call    writeRecord
3825
        call    writeRecord
3797
.writeBitmapMFT:
3826
.writeBitmapMFT:
3798
        mov     eax, [ebp+NTFS.cur_iRecord]
3827
        mov     eax, [ebp+NTFS.cur_iRecord]
3799
        mov     ecx, eax
3828
        mov     ecx, eax
3800
        shr     eax, 3
3829
        shr     eax, 3
3801
        and     ecx, 7
3830
        and     ecx, 7
3802
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
3831
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
3803
        btr     [edi+eax], ecx
3832
        btr     [edi+eax], ecx
3804
        shr     eax, 9
3833
        shr     eax, 9
3805
        mov     ebx, eax
3834
        mov     ebx, eax
3806
        shl     ebx, 9
3835
        shl     ebx, 9
3807
        add     eax, [ebp+NTFS.mftBitmapLocation]
3836
        add     eax, [ebp+NTFS.mftBitmapLocation]
3808
        add     ebx, edi
3837
        add     ebx, edi
3809
        mov     ecx, 1
3838
        mov     ecx, 1
3810
        xor     edx, edx
3839
        xor     edx, edx
3811
        call    fs_write64_sys
3840
        call    fs_write64_sys
3812
.backToIndex:
3841
.backToIndex:
3813
        mov     eax, [ebp+NTFS.newRecord]
3842
        mov     eax, [ebp+NTFS.newRecord]
3814
        mov     [ebp+NTFS.cur_iRecord], eax
3843
        mov     [ebp+NTFS.cur_iRecord], eax
3815
        mov     esi, [ebp+NTFS.indexPointer]
3844
        mov     esi, [ebp+NTFS.indexPointer]
3816
        stdcall ntfs_find_lfn.doit2, 0
3845
        stdcall ntfs_find_lfn.doit2, 0
3817
        jc      ntfsFail
3846
        jc      ntfsFail
3818
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
3847
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
3819
        mov     byte [ebx], 0
3848
        mov     byte [ebx], 0
3820
        mov     ebx, [ebp+NTFS.LastRead]
3849
        mov     ebx, [ebp+NTFS.LastRead]
3821
        mov     [ebp+NTFS.nodeLastRead], ebx
3850
        mov     [ebp+NTFS.nodeLastRead], ebx
3822
        xor     ebx, ebx
3851
        xor     ebx, ebx
3823
        test    byte [eax+indexFlags], 1
3852
        test    byte [eax+indexFlags], 1
3824
        jz      .deleteIndex    ; no subnode
3853
        jz      .deleteIndex    ; no subnode
3825
        mov     edi, eax
3854
        mov     edi, eax
3826
        call    .findSubindex
3855
        call    .findSubindex
3827
        jc      ntfsFail
3856
        jc      ntfsFail
3828
        movzx   edx, word [edi+indexAllocatedSize]
3857
        movzx   edx, word [edi+indexAllocatedSize]
3829
        test    esi, esi
3858
        test    esi, esi
3830
        jz      @f
3859
        jz      @f
3831
        sub     edx, eax
3860
        sub     edx, eax
3832
        sub     edx, 8
3861
        sub     edx, 8
3833
@@:
3862
@@:
3834
        mov     eax, edi
3863
        mov     eax, edi
3835
        mov     ebx, esi
3864
        mov     ebx, esi
3836
        jmp     @f
3865
        jmp     @f
3837
 
3866
 
3838
.deleteIndex:
3867
.deleteIndex:
3839
        movzx   edx, word [eax+indexAllocatedSize]
3868
        movzx   edx, word [eax+indexAllocatedSize]
3840
        mov     ecx, [eax+fileRecordReference]
3869
        mov     ecx, [eax+fileRecordReference]
3841
        cmp     [eax+edx+fileRecordReference], ecx
3870
        cmp     [eax+edx+fileRecordReference], ecx
3842
        jnz     @f
3871
        jnz     @f
3843
        add     dx, [eax+edx+indexAllocatedSize]
3872
        add     dx, [eax+edx+indexAllocatedSize]
3844
@@:
3873
@@:
3845
        mov     edi, [ebp+NTFS.cur_index_buf]
3874
        mov     edi, [ebp+NTFS.cur_index_buf]
3846
        cmp     dword [edi], 'INDX'
3875
        cmp     dword [edi], 'INDX'
3847
        jz      .indexRecord
3876
        jz      .indexRecord
3848
        sub     eax, edi
3877
        sub     eax, edi
3849
        mov     edi, [ebp+NTFS.indexRoot]
3878
        mov     edi, [ebp+NTFS.indexRoot]
3850
        sub     [edi+sizeWithHeader], edx
3879
        sub     [edi+sizeWithHeader], edx
3851
        sub     [edi+sizeWithoutHeader], edx
3880
        sub     [edi+sizeWithoutHeader], edx
3852
        movzx   ecx, byte [edi+attributeOffset]
3881
        movzx   ecx, byte [edi+attributeOffset]
3853
        add     edi, ecx
3882
        add     edi, ecx
3854
        add     eax, edi
3883
        add     eax, edi
3855
        sub     [edi+rootNode+nodeRealSize], edx
3884
        sub     [edi+rootNode+nodeRealSize], edx
3856
        sub     [edi+rootNode+nodeAllocatedSize], edx
3885
        sub     [edi+rootNode+nodeAllocatedSize], edx
3857
        mov     edi, [ebp+NTFS.frs_buffer]
3886
        mov     edi, [ebp+NTFS.frs_buffer]
3858
        sub     [edi+recordRealSize], edx
3887
        sub     [edi+recordRealSize], edx
3859
        mov     ecx, [edi+recordRealSize]
3888
        mov     ecx, [edi+recordRealSize]
3860
        cmp     [edi+recordAllocatedSize], ecx
3889
        cmp     [edi+recordAllocatedSize], ecx
3861
        jmp     @f
3890
        jmp     @f
3862
 
3891
 
3863
.indexRecord:
3892
.indexRecord:
3864
        add     edi, recordNode
3893
        add     edi, recordNode
3865
        sub     [edi+nodeRealSize], edx
3894
        sub     [edi+nodeRealSize], edx
3866
        mov     ecx, [edi+nodeRealSize]
3895
        mov     ecx, [edi+nodeRealSize]
3867
        cmp     [edi+nodeAllocatedSize], ecx
3896
        cmp     [edi+nodeAllocatedSize], ecx
3868
@@:
3897
@@:
3869
        jc      ntfsUnsupported
3898
        jc      ntfsUnsupported
3870
        add     ecx, edi
3899
        add     ecx, edi
3871
        sub     ecx, eax
3900
        sub     ecx, eax
3872
        mov     esi, eax
3901
        mov     esi, eax
3873
        add     esi, edx
3902
        add     esi, edx
3874
        mov     edi, eax
3903
        mov     edi, eax
3875
        test    edx, edx
3904
        test    edx, edx
3876
        jns     @f
3905
        jns     @f
3877
        neg     edx
3906
        neg     edx
3878
        add     edx, ecx
3907
        add     edx, ecx
3879
        sub     edx, 4
3908
        sub     edx, 4
3880
        add     esi, edx
3909
        add     esi, edx
3881
        add     edi, edx
3910
        add     edi, edx
3882
        std
3911
        std
3883
@@:
3912
@@:
3884
        jz      @f
3913
        jz      @f
3885
        shr     ecx, 2
3914
        shr     ecx, 2
3886
        rep movsd
3915
        rep movsd
3887
        cld
3916
        cld
3888
@@:
3917
@@:
3889
        test    ebx, ebx
3918
        test    ebx, ebx
3890
        jz      .done
3919
        jz      .done
3891
; copy index from the subnode to replace deleted pointing index
3920
; copy index from the subnode to replace deleted pointing index
3892
        movzx   ecx, word [ebx+indexAllocatedSize]
3921
        movzx   ecx, word [ebx+indexAllocatedSize]
3893
        mov     edx, ecx
3922
        mov     edx, ecx
3894
        test    byte [ebx+indexFlags], 1
3923
        test    byte [ebx+indexFlags], 1
3895
        jz      @f
3924
        jz      @f
3896
        sub     ecx, 8
3925
        sub     ecx, 8
3897
        movzx   edi, word [ebx+edx+indexAllocatedSize]
3926
        movzx   edi, word [ebx+edx+indexAllocatedSize]
3898
        add     edi, edx
3927
        add     edi, edx
3899
        mov     esi, [ebx+ecx]
3928
        mov     esi, [ebx+ecx]
3900
        mov     [ebx+edi-8], esi
3929
        mov     [ebx+edi-8], esi
3901
        mov     [ebx+indexAllocatedSize], cx
3930
        mov     [ebx+indexAllocatedSize], cx
3902
@@:
3931
@@:
3903
        shr     ecx, 2
3932
        shr     ecx, 2
3904
        mov     esi, ebx
3933
        mov     esi, ebx
3905
        mov     edi, eax
3934
        mov     edi, eax
3906
        rep movsd
3935
        rep movsd
3907
        add     word [eax+indexAllocatedSize], 8
3936
        add     word [eax+indexAllocatedSize], 8
3908
        mov     byte [eax+indexFlags], 1
3937
        mov     byte [eax+indexFlags], 1
3909
        mov     edi, [ebp+NTFS.secondIndexBuffer]
3938
        mov     edi, [ebp+NTFS.secondIndexBuffer]
3910
        mov     eax, ebx
3939
        mov     eax, ebx
3911
        xor     ebx, ebx
3940
        xor     ebx, ebx
3912
        jmp     .indexRecord
3941
        jmp     .indexRecord
3913
 
3942
 
3914
.done:
3943
.done:
3915
        mov     ebx, [ebp+NTFS.frs_buffer]
3944
        mov     ebx, [ebp+NTFS.frs_buffer]
3916
        mov     edx, [ebp+NTFS.rootLastRead]
3945
        mov     edx, [ebp+NTFS.rootLastRead]
3917
        call    writeRecord
3946
        call    writeRecord
3918
        mov     ebx, [ebp+NTFS.cur_index_buf]
3947
        mov     ebx, [ebp+NTFS.cur_index_buf]
3919
        cmp     dword [ebx], 'INDX'
3948
        cmp     dword [ebx], 'INDX'
3920
        jnz     @f
3949
        jnz     @f
3921
        mov     edx, [ebp+NTFS.nodeLastRead]
3950
        mov     edx, [ebp+NTFS.nodeLastRead]
3922
        call    writeRecord
3951
        call    writeRecord
3923
@@:
3952
@@:
3924
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
3953
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
3925
        cmp     byte [ebx], 0
3954
        cmp     byte [ebx], 0
3926
        jz      ntfsDone
3955
        jz      ntfsDone
3927
        mov     edx, [ebp+NTFS.LastRead]
3956
        mov     edx, [ebp+NTFS.LastRead]
3928
        call    writeRecord
3957
        call    writeRecord
3929
        jmp     ntfsDone
3958
        jmp     ntfsDone
3930
 
3959
 
3931
.findSubindex:
3960
.findSubindex:
3932
; in: eax -> index
3961
; in: eax -> index
3933
;   out:
3962
;   out:
3934
; CF=1 -> error
3963
; CF=1 -> error
3935
; esi=0 -> subnode deleted
3964
; esi=0 -> subnode deleted
3936
; esi -> replacement index
3965
; esi -> replacement index
3937
; eax = index effective size
3966
; eax = index effective size
3938
        movzx   edx, word [eax+indexAllocatedSize]
3967
        movzx   edx, word [eax+indexAllocatedSize]
3939
        mov     eax, [eax+edx-8]
3968
        mov     eax, [eax+edx-8]
3940
        mov     edx, [ebp+NTFS.cur_size]
3969
        mov     edx, [ebp+NTFS.cur_size]
3941
        push    edx
3970
        push    edx
3942
        cmp     edx, [ebp+NTFS.cur_subnode_size]
3971
        cmp     edx, [ebp+NTFS.cur_subnode_size]
3943
        jz      @f
3972
        jz      @f
3944
        mul     [ebp+NTFS.sectors_per_cluster]
3973
        mul     [ebp+NTFS.sectors_per_cluster]
3945
@@:
3974
@@:
3946
        mov     [ebp+NTFS.cur_attr], 0xA0
3975
        mov     [ebp+NTFS.cur_attr], 0xA0
3947
        mov     [ebp+NTFS.cur_offs], eax
3976
        mov     [ebp+NTFS.cur_offs], eax
3948
        push    eax
3977
        push    eax
3949
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
3978
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
3950
        mov     esi, ebx
3979
        mov     esi, ebx
3951
        mov     [ebp+NTFS.cur_buf], ebx
3980
        mov     [ebp+NTFS.cur_buf], ebx
3952
        call    ntfs_read_attr.newAttribute
3981
        call    ntfs_read_attr.newAttribute
3953
        pop     [ebp+NTFS.cur_offs]
3982
        pop     [ebp+NTFS.cur_offs]
3954
        pop     eax
3983
        pop     eax
3955
        jc      .ret
3984
        jc      .ret
3956
        cmp     dword [esi], 'INDX'
3985
        cmp     dword [esi], 'INDX'
3957
        stc
3986
        stc
3958
        jnz     .ret
3987
        jnz     .ret
3959
        mov     [ebp+NTFS.cur_size], eax
3988
        mov     [ebp+NTFS.cur_size], eax
3960
        shl     eax, 9
3989
        shl     eax, 9
3961
        call    ntfs_restore_usa
3990
        call    ntfs_restore_usa
3962
        jc      .ret
3991
        jc      .ret
3963
        add     esi, recordNode
3992
        add     esi, recordNode
3964
        add     esi, [esi+indexOffset]
3993
        add     esi, [esi+indexOffset]
3965
        test    byte [esi+indexFlags], 2
3994
        test    byte [esi+indexFlags], 2
3966
        jnz     .emptyNode
3995
        jnz     .emptyNode
3967
        cmp     [ebp+NTFS.fragmentCount], 1
3996
        cmp     [ebp+NTFS.fragmentCount], 1
3968
        stc
3997
        stc
3969
        jnz     .ret    ; record fragmented
3998
        jnz     .ret    ; record fragmented
3970
        xor     eax, eax
3999
        xor     eax, eax
3971
@@:
4000
@@:
3972
        add     esi, eax
4001
        add     esi, eax
3973
        mov     ax, [esi+indexAllocatedSize]
4002
        mov     ax, [esi+indexAllocatedSize]
3974
        test    byte [esi+eax+indexFlags], 2
4003
        test    byte [esi+eax+indexFlags], 2
3975
        jz      @b
4004
        jz      @b
3976
        test    byte [esi+indexFlags], 1
4005
        test    byte [esi+indexFlags], 1
3977
        jz      .ret
4006
        jz      .ret
3978
        add     eax, esi
4007
        add     eax, esi
3979
        push    esi
4008
        push    esi
3980
        push    [ebp+NTFS.cur_offs]
4009
        push    [ebp+NTFS.cur_offs]
3981
        call    .findSubindex
4010
        call    .findSubindex
3982
        pop     [ebp+NTFS.cur_offs]
4011
        pop     [ebp+NTFS.cur_offs]
3983
        pop     edx
4012
        pop     edx
3984
        jc      .ret
4013
        jc      .ret
3985
        test    esi, esi
4014
        test    esi, esi
3986
        jnz     .ret
4015
        jnz     .ret
3987
        mov     esi, edx
4016
        mov     esi, edx
3988
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
4017
        mov     ebx, [ebp+NTFS.secondIndexBuffer]
3989
        mov     [ebp+NTFS.cur_buf], ebx
4018
        mov     [ebp+NTFS.cur_buf], ebx
3990
        push    [ebp+NTFS.cur_size]
4019
        push    [ebp+NTFS.cur_size]
3991
        call    ntfs_read_attr.continue
4020
        call    ntfs_read_attr.continue
3992
        pop     eax
4021
        pop     eax
3993
        jc      .ret
4022
        jc      .ret
3994
        shl     eax, 9
4023
        shl     eax, 9
3995
        call    ntfs_restore_usa
4024
        call    ntfs_restore_usa
3996
        jc      .ret
4025
        jc      .ret
3997
        movzx   eax, word [esi+indexAllocatedSize]
4026
        movzx   eax, word [esi+indexAllocatedSize]
3998
        sub     eax, 8
4027
        sub     eax, 8
3999
.ret:
4028
.ret:
4000
        ret
4029
        ret
4001
 
4030
 
4002
.emptyNode:
4031
.emptyNode:
4003
        test    byte [esi+indexFlags], 1
4032
        test    byte [esi+indexFlags], 1
4004
        jz      @f
4033
        jz      @f
4005
        mov     eax, esi
4034
        mov     eax, esi
4006
        push    [ebp+NTFS.cur_offs]
4035
        push    [ebp+NTFS.cur_offs]
4007
        call    .findSubindex
4036
        call    .findSubindex
4008
        pop     [ebp+NTFS.cur_offs]
4037
        pop     [ebp+NTFS.cur_offs]
4009
        jc      .ret
4038
        jc      .ret
4010
        test    esi, esi
4039
        test    esi, esi
4011
        jnz     .ret
4040
        jnz     .ret
4012
@@:         ; delete node
4041
@@:         ; delete node
4013
        mov     esi, [ebp+NTFS.attr_offs]
4042
        mov     esi, [ebp+NTFS.attr_offs]
4014
        add     esi, [esi+sizeWithHeader]
4043
        add     esi, [esi+sizeWithHeader]
4015
        cmp     byte [esi], 0xB0
4044
        cmp     byte [esi], 0xB0
4016
        stc
4045
        stc
4017
        jnz     .ret
4046
        jnz     .ret
4018
        movzx   eax, byte [esi+attributeOffset]
4047
        movzx   eax, byte [esi+attributeOffset]
4019
        add     esi, eax
4048
        add     esi, eax
4020
        mov     eax, [ebp+NTFS.cur_offs]
4049
        mov     eax, [ebp+NTFS.cur_offs]
4021
        xor     edx, edx
4050
        xor     edx, edx
4022
        div     [ebp+NTFS.cur_size]
4051
        div     [ebp+NTFS.cur_size]
4023
        mov     edx, eax
4052
        mov     edx, eax
4024
        shr     eax, 3
4053
        shr     eax, 3
4025
        and     edx, 7
4054
        and     edx, 7
4026
        btr     [esi+eax], edx
4055
        btr     [esi+eax], edx
4027
        mov     esi, [ebp+NTFS.secondIndexBuffer]
4056
        mov     esi, [ebp+NTFS.secondIndexBuffer]
4028
        mov     byte [esi], 0
4057
        mov     byte [esi], 0
4029
        xor     esi, esi
4058
        xor     esi, esi
4030
        ret
4059
        ret
4031
 
4060
 
4032
;----------------------------------------------------------------
4061
;----------------------------------------------------------------
4033
ntfs_SetFileEnd:
4062
ntfs_SetFileEnd:
4034
        cmp     byte [esi], 0
4063
        cmp     byte [esi], 0
4035
        jnz     @f
4064
        jnz     @f
4036
        xor     ebx, ebx
4065
        xor     ebx, ebx
4037
        movi    eax, ERROR_ACCESS_DENIED
4066
        movi    eax, ERROR_ACCESS_DENIED
4038
        ret
4067
        ret
4039
@@:
4068
@@:
4040
        call    ntfs_lock
4069
        call    ntfs_lock
4041
        stdcall ntfs_find_lfn, [esp+4]
4070
        stdcall ntfs_find_lfn, [esp+4]
4042
        jc      ntfsNotFound
4071
        jc      ntfsNotFound
4043
        cmp     [ebp+NTFS.cur_iRecord], 16
4072
        cmp     [ebp+NTFS.cur_iRecord], 16
4044
        jc      ntfsDenied
4073
        jc      ntfsDenied
4045
        test    dword [eax+fileFlags], 10000001h
4074
        test    dword [eax+fileFlags], 10000001h
4046
        jnz     ntfsDenied
4075
        jnz     ntfsDenied
4047
        cmp     [ebp+NTFS.fragmentCount], 1
4076
        cmp     [ebp+NTFS.fragmentCount], 1
4048
        jnz     ntfsUnsupported     ; record fragmented
4077
        jnz     ntfsUnsupported     ; record fragmented
4049
; edit directory node
4078
; edit directory node
4050
        mov     edi, [ebp+NTFS.cur_index_buf]
4079
        mov     edi, [ebp+NTFS.cur_index_buf]
4051
        cmp     dword [edi], 'INDX'
4080
        cmp     dword [edi], 'INDX'
4052
        jz      @f
4081
        jz      @f
4053
        mov     esi, [ebp+NTFS.frs_buffer]
4082
        mov     esi, [ebp+NTFS.frs_buffer]
4054
        mov     ecx, [esi+recordRealSize]
4083
        mov     ecx, [esi+recordRealSize]
4055
        shr     ecx, 2
4084
        shr     ecx, 2
4056
        rep movsd
4085
        rep movsd
4057
        mov     esi, [ebp+NTFS.attr_offs]
4086
        mov     esi, [ebp+NTFS.attr_offs]
4058
        mov     cl, [esi+attributeOffset]
4087
        mov     cl, [esi+attributeOffset]
4059
        sub     esi, [ebp+NTFS.frs_buffer]
4088
        sub     esi, [ebp+NTFS.frs_buffer]
4060
        add     eax, ecx
4089
        add     eax, ecx
4061
        add     eax, esi
4090
        add     eax, esi
4062
@@:
4091
@@:
4063
        mov     edi, eax
4092
        mov     edi, eax
4064
        mov     eax, [ebx+4]
4093
        mov     eax, [ebx+4]
4065
        mov     edx, [ebx+8]
4094
        mov     edx, [ebx+8]
4066
        mov     [edi+fileRealSize], eax
4095
        mov     [edi+fileRealSize], eax
4067
        mov     [edi+fileRealSize+4], edx
4096
        mov     [edi+fileRealSize+4], edx
4068
        push    edx eax ebx
4097
        push    edx eax ebx
4069
        call    ntfsGetTime
4098
        call    ntfsGetTime
4070
        mov     [edi+fileModified], eax
4099
        mov     [edi+fileModified], eax
4071
        mov     [edi+fileModified+4], edx
4100
        mov     [edi+fileModified+4], edx
4072
        mov     [edi+recordModified], eax
4101
        mov     [edi+recordModified], eax
4073
        mov     [edi+recordModified+4], edx
4102
        mov     [edi+recordModified+4], edx
4074
        mov     [edi+fileAccessed], eax
4103
        mov     [edi+fileAccessed], eax
4075
        mov     [edi+fileAccessed+4], edx
4104
        mov     [edi+fileAccessed+4], edx
4076
        pop     ebx ecx edx
4105
        pop     ebx ecx edx
4077
        mov     eax, [ebp+NTFS.LastRead]
4106
        mov     eax, [ebp+NTFS.LastRead]
4078
        mov     [ebp+NTFS.nodeLastRead], eax
4107
        mov     [ebp+NTFS.nodeLastRead], eax
4079
        mov     [ebp+NTFS.cur_attr], 0x80
4108
        mov     [ebp+NTFS.cur_attr], 0x80
4080
        mov     [ebp+NTFS.cur_offs], 0
4109
        mov     [ebp+NTFS.cur_offs], 0
4081
        mov     [ebp+NTFS.cur_size], 0
4110
        mov     [ebp+NTFS.cur_size], 0
4082
        call    ntfs_read_attr
4111
        call    ntfs_read_attr
4083
        jc      ntfsFail
4112
        jc      ntfsFail
4084
        mov     esi, edi
4113
        mov     esi, edi
4085
        mov     edi, [ebp+NTFS.frs_buffer]
4114
        mov     edi, [ebp+NTFS.frs_buffer]
4086
        cmp     word [edi+baseRecordReuse], 0
4115
        cmp     word [edi+baseRecordReuse], 0
4087
        jnz     ntfsUnsupported     ; auxiliary record
4116
        jnz     ntfsUnsupported     ; auxiliary record
4088
        mov     al, [edi+attributeOffset]
4117
        mov     al, [edi+attributeOffset]
4089
        add     edi, eax
4118
        add     edi, eax
4090
        mov     al, [edi+attributeOffset]
4119
        mov     al, [edi+attributeOffset]
4091
        add     edi, eax
4120
        add     edi, eax
4092
        mov     eax, ecx
4121
        mov     eax, ecx
4093
        mov     ecx, 6
4122
        mov     ecx, 6
4094
        add     esi, fileModified
4123
        add     esi, fileModified
4095
        add     edi, 8
4124
        add     edi, 8
4096
        rep movsd
4125
        rep movsd
4097
        mov     ecx, [ebp+NTFS.attr_offs]
4126
        mov     ecx, [ebp+NTFS.attr_offs]
4098
        cmp     word [ecx+attributeFlags], 0
4127
        cmp     word [ecx+attributeFlags], 0
4099
        jnz     ntfsUnsupported
4128
        jnz     ntfsUnsupported
4100
        cmp     byte [ecx+nonResidentFlag], 0
4129
        cmp     byte [ecx+nonResidentFlag], 0
4101
        jz      .resizeAttribute
4130
        jz      .resizeAttribute
4102
        cmp     [ecx+attributeRealSize+4], edx
4131
        cmp     [ecx+attributeRealSize+4], edx
4103
        jnz     .resizeAttribute
4132
        jnz     .resizeAttribute
4104
        cmp     [ecx+attributeRealSize], eax
4133
        cmp     [ecx+attributeRealSize], eax
4105
        jnc     .resizeAttribute
4134
        jnc     .resizeAttribute
4106
        mov     eax, [ecx+attributeRealSize]
4135
        mov     eax, [ecx+attributeRealSize]
4107
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
4136
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
4108
        mov     [ebp+NTFS.cur_size], ecx
4137
        mov     [ebp+NTFS.cur_size], ecx
4109
        shl     ecx, 9
4138
        shl     ecx, 9
4110
        div     ecx
4139
        div     ecx
4111
        test    edx, edx
4140
        test    edx, edx
4112
        jz      .aligned
4141
        jz      .aligned
4113
        push    edx
4142
        push    edx
4114
        push    ecx
4143
        push    ecx
4115
        mul     [ebp+NTFS.sectors_per_cluster]
4144
        mul     [ebp+NTFS.sectors_per_cluster]
4116
        mov     [ebp+NTFS.cur_offs], eax
4145
        mov     [ebp+NTFS.cur_offs], eax
4117
        stdcall kernel_alloc, ecx
4146
        stdcall kernel_alloc, ecx
4118
        pop     ecx
4147
        pop     ecx
4119
        pop     edi
4148
        pop     edi
4120
        mov     esi, eax
4149
        mov     esi, eax
4121
        sub     ecx, edi
4150
        sub     ecx, edi
4122
        add     edi, eax
4151
        add     edi, eax
4123
        mov     [ebp+NTFS.cur_buf], eax
4152
        mov     [ebp+NTFS.cur_buf], eax
4124
        call    ntfs_read_attr.continue
4153
        call    ntfs_read_attr.continue
4125
        jc      @f
4154
        jc      @f
4126
        xor     eax, eax
4155
        xor     eax, eax
4127
        rep stosb
4156
        rep stosb
4128
        push    ebx
4157
        push    ebx
4129
        mov     eax, [ebp+NTFS.LastRead]
4158
        mov     eax, [ebp+NTFS.LastRead]
4130
        mov     ebx, esi
4159
        mov     ebx, esi
4131
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
4160
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
4132
        xor     edx, edx
4161
        xor     edx, edx
4133
        call    fs_write64_app
4162
        call    fs_write64_app
4134
        pop     ebx
4163
        pop     ebx
4135
@@:
4164
@@:
4136
        stdcall kernel_free, esi
4165
        stdcall kernel_free, esi
4137
.aligned:
4166
.aligned:
4138
        mov     eax, [ebx+4]
4167
        mov     eax, [ebx+4]
4139
        mov     edx, [ebx+8]
4168
        mov     edx, [ebx+8]
4140
.resizeAttribute:
4169
.resizeAttribute:
4141
        call    resizeAttribute
4170
        call    resizeAttribute
4142
        jc      ntfsError
4171
        jc      ntfsError
4143
        mov     ebx, [ebp+NTFS.frs_buffer]
4172
        mov     ebx, [ebp+NTFS.frs_buffer]
4144
        mov     edx, [ebp+NTFS.mftLastRead]
4173
        mov     edx, [ebp+NTFS.mftLastRead]
4145
        call    writeRecord     ; file
4174
        call    writeRecord     ; file
4146
        mov     ebx, [ebp+NTFS.cur_index_buf]
4175
        mov     ebx, [ebp+NTFS.cur_index_buf]
4147
        mov     edx, [ebp+NTFS.nodeLastRead]
4176
        mov     edx, [ebp+NTFS.nodeLastRead]
4148
        call    writeRecord     ; directory
4177
        call    writeRecord     ; directory
4149
        call    ntfsSpaceClean
4178
        call    ntfsSpaceClean
4150
        jmp     ntfsDone
4179
        jmp     ntfsDone
4151
 
4180
 
4152
ntfsReadCMOS:
4181
ntfsReadCMOS:
4153
        out     70h, al
4182
        out     70h, al
4154
        in      al, 71h
4183
        in      al, 71h
4155
        xor     ah, ah
4184
        xor     ah, ah
4156
        shl     ax, 4
4185
        shl     ax, 4
4157
        shr     al, 4
4186
        shr     al, 4
4158
        aad
4187
        aad
4159
        ret
4188
        ret
4160
 
4189
 
4161
ntfsGetTime:
4190
ntfsGetTime:
4162
        mov     al, 7
4191
        mov     al, 7
4163
        call    ntfsReadCMOS
4192
        call    ntfsReadCMOS
4164
        ror     eax, 8
4193
        ror     eax, 8
4165
        mov     al, 8
4194
        mov     al, 8
4166
        call    ntfsReadCMOS
4195
        call    ntfsReadCMOS
4167
        ror     eax, 8
4196
        ror     eax, 8
4168
        mov     al, 9
4197
        mov     al, 9
4169
        call    ntfsReadCMOS
4198
        call    ntfsReadCMOS
4170
        add     eax, 2000
4199
        add     eax, 2000
4171
        ror     eax, 16
4200
        ror     eax, 16
4172
        push    eax
4201
        push    eax
4173
        xor     eax, eax
4202
        xor     eax, eax
4174
        call    ntfsReadCMOS
4203
        call    ntfsReadCMOS
4175
        ror     eax, 8
4204
        ror     eax, 8
4176
        mov     al, 2
4205
        mov     al, 2
4177
        call    ntfsReadCMOS
4206
        call    ntfsReadCMOS
4178
        ror     eax, 8
4207
        ror     eax, 8
4179
        mov     al, 4
4208
        mov     al, 4
4180
        call    ntfsReadCMOS
4209
        call    ntfsReadCMOS
4181
        ror     eax, 16
4210
        ror     eax, 16
4182
        push    eax
4211
        push    eax
4183
        mov     esi, esp
4212
        mov     esi, esp
4184
        add     esp, 8
4213
        add     esp, 8
4185
ntfsCalculateTime:
4214
ntfsCalculateTime:
4186
; in: esi -> data block
4215
; in: esi -> data block
4187
; out: edx:eax = time
4216
; out: edx:eax = time
4188
        movzx   eax, word [esi+6]
4217
        movzx   eax, word [esi+6]
4189
        sub     eax, 2001
4218
        sub     eax, 2001
4190
        jnc     @f
4219
        jnc     @f
4191
        xor     eax, eax
4220
        xor     eax, eax
4192
@@:
4221
@@:
4193
        mov     edx, months
4222
        mov     edx, months
4194
        mov     ebx, eax
4223
        mov     ebx, eax
4195
        inc     eax
4224
        inc     eax
4196
        test    eax, 3
4225
        test    eax, 3
4197
        jnz     @f
4226
        jnz     @f
4198
        add     edx, 12
4227
        add     edx, 12
4199
@@:
4228
@@:
4200
        movzx   eax, byte [esi+5]
4229
        movzx   eax, byte [esi+5]
4201
        dec     eax
4230
        dec     eax
4202
        xor     ecx, ecx
4231
        xor     ecx, ecx
4203
@@:
4232
@@:
4204
        dec     eax
4233
        dec     eax
4205
        js      @f
4234
        js      @f
4206
        add     cl, [edx+eax]
4235
        add     cl, [edx+eax]
4207
        adc     ch, 0
4236
        adc     ch, 0
4208
        jmp     @b
4237
        jmp     @b
4209
@@:
4238
@@:
4210
        mov     eax, ebx
4239
        mov     eax, ebx
4211
        mov     edx, 365
4240
        mov     edx, 365
4212
        mul     edx
4241
        mul     edx
4213
        shr     ebx, 2
4242
        shr     ebx, 2
4214
        add     eax, ebx
4243
        add     eax, ebx
4215
        add     eax, ecx
4244
        add     eax, ecx
4216
        mov     bl, [esi+4]
4245
        mov     bl, [esi+4]
4217
        add     eax, ebx
4246
        add     eax, ebx
4218
        add     eax, 400*365+100-4
4247
        add     eax, 400*365+100-4
4219
        mov     dl, 24
4248
        mov     dl, 24
4220
        mul     edx
4249
        mul     edx
4221
        mov     bl, [esi+2]
4250
        mov     bl, [esi+2]
4222
        add     eax, ebx
4251
        add     eax, ebx
4223
        mov     ecx, 60
4252
        mov     ecx, 60
4224
        mul     ecx
4253
        mul     ecx
4225
        mov     bl, [esi+1]
4254
        mov     bl, [esi+1]
4226
        add     eax, ebx
4255
        add     eax, ebx
4227
        mul     ecx
4256
        mul     ecx
4228
        mov     bl, [esi]
4257
        mov     bl, [esi]
4229
        add     ebx, eax
4258
        add     ebx, eax
4230
        mov     eax, edx
4259
        mov     eax, edx
4231
        mov     ecx, 10000000
4260
        mov     ecx, 10000000
4232
        mul     ecx
4261
        mul     ecx
4233
        xchg    eax, ebx
4262
        xchg    eax, ebx
4234
        mul     ecx
4263
        mul     ecx
4235
        add     edx, ebx
4264
        add     edx, ebx
4236
        ret
4265
        ret
4237
 
4266
 
4238
;----------------------------------------------------------------
4267
;----------------------------------------------------------------
4239
ntfs_SetFileInfo:
4268
ntfs_SetFileInfo:
4240
        cmp     byte [esi], 0
4269
        cmp     byte [esi], 0
4241
        jnz     @f
4270
        jnz     @f
4242
        movi    eax, ERROR_UNSUPPORTED_FS
4271
        movi    eax, ERROR_UNSUPPORTED_FS
4243
        ret
4272
        ret
4244
@@:
4273
@@:
4245
        call    ntfs_lock
4274
        call    ntfs_lock
4246
        stdcall ntfs_find_lfn, [esp+4]
4275
        stdcall ntfs_find_lfn, [esp+4]
4247
        jnc     @f
4276
        jnc     @f
4248
        test    eax, eax
4277
        test    eax, eax
4249
        jz      ntfsFail
4278
        jz      ntfsFail
4250
        jmp     ntfsNotFound
4279
        jmp     ntfsNotFound
4251
 
4280
 
4252
@@:
4281
@@:
4253
        cmp     [ebp+NTFS.fragmentCount], 1
4282
        cmp     [ebp+NTFS.fragmentCount], 1
4254
        jnz     ntfsUnsupported     ; record fragmented
4283
        jnz     ntfsUnsupported     ; record fragmented
4255
        mov     esi, [ebp+NTFS.cur_index_buf]
4284
        mov     esi, [ebp+NTFS.cur_index_buf]
4256
        cmp     dword [esi], 'INDX'
4285
        cmp     dword [esi], 'INDX'
4257
        jz      @f
4286
        jz      @f
4258
        sub     eax, esi
4287
        sub     eax, esi
4259
        mov     esi, [ebp+NTFS.indexRoot]
4288
        mov     esi, [ebp+NTFS.indexRoot]
4260
        movzx   edx, byte [esi+attributeOffset]
4289
        movzx   edx, byte [esi+attributeOffset]
4261
        add     eax, esi
4290
        add     eax, esi
4262
        add     eax, edx
4291
        add     eax, edx
4263
@@:
4292
@@:
4264
        mov     esi, [ebx+16]
4293
        mov     esi, [ebx+16]
4265
        mov     edi, eax
4294
        mov     edi, eax
4266
        mov     eax, [esi]
4295
        mov     eax, [esi]
4267
        and     eax, 27h
4296
        and     eax, 27h
4268
        and     byte [edi+fileFlags], -28h
4297
        and     byte [edi+fileFlags], -28h
4269
        or      [edi+fileFlags], al
4298
        or      [edi+fileFlags], al
4270
        add     esi, 8
4299
        add     esi, 8
4271
        call    ntfsCalculateTime
4300
        call    ntfsCalculateTime
4272
        mov     [edi+fileCreated], eax
4301
        mov     [edi+fileCreated], eax
4273
        mov     [edi+fileCreated+4], edx
4302
        mov     [edi+fileCreated+4], edx
4274
        add     esi, 8
4303
        add     esi, 8
4275
        call    ntfsCalculateTime
4304
        call    ntfsCalculateTime
4276
        mov     [edi+fileAccessed], eax
4305
        mov     [edi+fileAccessed], eax
4277
        mov     [edi+fileAccessed+4], edx
4306
        mov     [edi+fileAccessed+4], edx
4278
        add     esi, 8
4307
        add     esi, 8
4279
        call    ntfsCalculateTime
4308
        call    ntfsCalculateTime
4280
        mov     [edi+fileModified], eax
4309
        mov     [edi+fileModified], eax
4281
        mov     [edi+fileModified+4], edx
4310
        mov     [edi+fileModified+4], edx
4282
        mov     ebx, [ebp+NTFS.cur_index_buf]
4311
        mov     ebx, [ebp+NTFS.cur_index_buf]
4283
        cmp     dword [ebx], 'INDX'
4312
        cmp     dword [ebx], 'INDX'
4284
        jz      @f
4313
        jz      @f
4285
        mov     ebx, [ebp+NTFS.frs_buffer]
4314
        mov     ebx, [ebp+NTFS.frs_buffer]
4286
@@:
4315
@@:
4287
        mov     edx, [ebp+NTFS.LastRead]
4316
        mov     edx, [ebp+NTFS.LastRead]
4288
        call    writeRecord
4317
        call    writeRecord
4289
        jmp     ntfsDone
4318
        jmp     ntfsDone
4290
 
4319
 
4291
ntfsUnsupported:
4320
ntfsUnsupported:
4292
        push    ERROR_UNSUPPORTED_FS
4321
        push    ERROR_UNSUPPORTED_FS
4293
        jmp     ntfsOut
4322
        jmp     ntfsOut
4294
ntfsDevice:
4323
ntfsDevice:
4295
        push    ERROR_DEVICE
4324
        push    ERROR_DEVICE
4296
        jmp     ntfsOut
4325
        jmp     ntfsOut
4297
ntfsNotFound:
4326
ntfsNotFound:
4298
        push    ERROR_FILE_NOT_FOUND
4327
        push    ERROR_FILE_NOT_FOUND
4299
        jmp     ntfsOut
4328
        jmp     ntfsOut
4300
ntfsDenied:
4329
ntfsDenied:
4301
        push    ERROR_ACCESS_DENIED
4330
        push    ERROR_ACCESS_DENIED
4302
        jmp     ntfsOut
4331
        jmp     ntfsOut
4303
ntfsFail:
4332
ntfsFail:
4304
        push    ERROR_FS_FAIL
4333
        push    ERROR_FS_FAIL
4305
        jmp     ntfsOut
4334
        jmp     ntfsOut
4306
ntfsDiskFull:
4335
ntfsDiskFull:
4307
        push    ERROR_DISK_FULL
4336
        push    ERROR_DISK_FULL
4308
        jmp     ntfsOut
4337
        jmp     ntfsOut
4309
ntfsErrorPop5:
4338
ntfsErrorPop5:
4310
        pop     ebx
4339
        pop     ebx
4311
        pop     ebx
4340
        pop     ebx
4312
ntfsErrorPop3:
4341
ntfsErrorPop3:
4313
        pop     ebx
4342
        pop     ebx
4314
ntfsErrorPop2:
4343
ntfsErrorPop2:
4315
        pop     ebx
4344
        pop     ebx
4316
ntfsErrorPop:
4345
ntfsErrorPop:
4317
        pop     ebx
4346
        pop     ebx
4318
ntfsError:
4347
ntfsError:
4319
        push    eax
4348
        push    eax
4320
ntfsOut:
4349
ntfsOut:
4321
        call    ntfs_unlock
4350
        call    ntfs_unlock
4322
        xor     ebx, ebx
4351
        xor     ebx, ebx
4323
        pop     eax
4352
        pop     eax
4324
        ret
4353
        ret