Subversion Repositories Kolibri OS

Rev

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

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