Subversion Repositories Kolibri OS

Rev

Rev 5565 | Rev 6078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5565 Rev 5984
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 7... Line 7...
7
 
7
 
-
 
8
$Revision: 5984 $
-
 
9
 
-
 
10
; NTFS driver
-
 
11
 
-
 
12
; Basic concepts:
-
 
13
; File is a FileRecord in the $MFT.
-
 
14
; $MFT is a file, that consists of FileRecords and starts with FileRecord of itself.
-
 
15
; FileRecord (FILE) consists of a header and attributes.
-
 
16
; Attribute consists of a header and a body.
-
 
17
; Attribute's body can be inside (resident) or outside of FileRecord.
-
 
18
; File's data is a body of $Data (80h) attribute.
-
 
19
; FileRecords is a data of the $MFT file.
-
 
20
; Directory is a file, that consists of index nodes.
-
 
21
; Resident index node is always located in a body of $IndexRoot (90h) attribute.
-
 
22
; Body of $IndexAllocation (A0h) attribute is always non resident
-
 
23
;  and consists of IndexRecords.
-
 
24
; IndexRecord (INDX) consists of a header and an index node.
-
 
25
; Index node consists of a header and indexes.
-
 
26
; Index consists of a header and a copy of indexed attribute's body.
-
 
27
; Directories index $Filename (30h) attribute of all existing files.
-
 
28
; $IndexRoot and $IndexAllocation attributes of a directory has a name — $I30.
-
 
29
 
-
 
30
; Offsets:
-
 
31
    ; record header
-
 
32
updateSequenceOffset = 4
-
 
33
updateSequenceSize = 6
-
 
34
reuseCounter = 16
-
 
35
hardLinkCounter = 12h
-
 
36
attributeOffset = 14h
-
 
37
recordFlags = 16h
-
 
38
recordRealSize = 18h
-
 
39
recordAllocatedSize = 1ch
-
 
40
newAttributeID = 28h
-
 
41
    ; attribute header
-
 
42
attributeType = 0
-
 
43
sizeWithHeader = 4
-
 
44
nonResidentFlag = 8
-
 
45
nameLength = 9
-
 
46
nameOffset = 10
-
 
47
attributeID = 14
-
 
48
sizeWithoutHeader = 16
-
 
49
attributeFlags = 16h
-
 
50
    ; non resident attribute header
-
 
51
lastVCN = 18h
-
 
52
dataRunsOffset = 20h
-
 
53
attributeAllocatedSize = 28h
-
 
54
attributeRealSize = 30h
-
 
55
initialDataSize = 38h
-
 
56
    ; $IndexRoot
-
 
57
collationRule = 4
-
 
58
indexRecordSize = 8
-
 
59
indexRecordSizeClus = 12
-
 
60
    ; node header
-
 
61
indexOffset = 0
-
 
62
nodeRealSize = 4
-
 
63
nodeAllocatedSize = 8
-
 
64
    ; $Filename index
-
 
65
fileRecordReference = 0
-
 
66
fileReferenceReuse = 6
-
 
67
indexAllocatedSize = 8
-
 
68
indexRawSize = 10
-
 
69
indexFlags = 12
-
 
70
directoryRecordReference = 16
-
 
71
directoryReferenceReuse = 16h
-
 
72
fileAllocatedSize = 38h
-
 
73
fileRealSize = 40h
-
 
74
fileFlags = 48h
Line 8... Line 75...
8
$Revision: 5565 $
75
fileNameLength = 50h
9
 
76
 
10
struct NTFS PARTITION
-
 
11
Lock                    MUTEX ?    ; currently operations with one partition
77
struct NTFS PARTITION
12
                                   ; can not be executed in parallel since the
-
 
13
                                   ; legacy code is not ready; this mutex guards
78
Lock                MUTEX   ?   ; Currently operations with one partition
14
                                   ; all operations
79
; can not be executed in parallel since the legacy code is not ready.
15
sectors_per_cluster     dd      ?
80
sectors_per_cluster     dd  ?
16
mft_cluster             dd      ?
81
mft_cluster             dd  ?   ; location
17
mftmirr_cluster         dd      ?
-
 
18
frs_size                dd      ?       ; FRS size in bytes
82
mftmirr_cluster         dd  ?   ; location
19
iab_size                dd      ?       ; IndexAllocationBuffer size in bytes
-
 
20
frs_buffer              dd      ?
83
frs_size                dd  ?   ; in bytes
21
iab_buffer              dd      ?
84
frs_buffer              dd  ?   ; MFT fileRecord buffer
22
mft_retrieval           dd      ?
85
mft_retrieval           dd  ?
23
mft_retrieval_size      dd      ?
86
mft_retrieval_size      dd  ?
24
mft_retrieval_alloc     dd      ?
87
mft_retrieval_alloc     dd  ?
25
mft_retrieval_end       dd      ?
88
mft_retrieval_end       dd  ?
-
 
89
cur_index_size          dd  ?   ; in sectors
-
 
90
cur_index_buf           dd  ?   ; index node buffer
-
 
91
BitmapBuffer            dd  ?
-
 
92
BitmapTotalSize         dd  ?   ; bytes reserved
-
 
93
BitmapSize              dd  ?   ; bytes readen
-
 
94
BitmapLocation          dd  ?   ; starting sector
-
 
95
BitmapStart             dd  ?   ; first byte after area, reserved for MFT
-
 
96
mftBitmapBuffer         dd  ?   ; one cluster
26
cur_index_size          dd      ?
97
mftBitmapSize           dd  ?   ; bytes readen
27
cur_index_buf           dd      ?
98
mftBitmapLocation       dd  ?   ; starting sector
28
 
99
 
29
ntfs_cur_attr   dd      ?
100
ntfs_cur_attr           dd  ?   ; attribute type
30
ntfs_cur_iRecord dd     ?
101
ntfs_cur_iRecord        dd  ?   ; number of fileRecord in MFT
31
ntfs_cur_offs   dd      ?       ; in sectors
102
ntfs_cur_offs           dd  ?   ; attribute VCN in sectors
32
ntfs_cur_size   dd      ?       ; in sectors
103
ntfs_cur_size           dd  ?   ; max sectors to read
-
 
104
ntfs_cur_buf            dd  ?
-
 
105
ntfs_cur_read           dd  ?   ; bytes readen
-
 
106
ntfsLastRead            dd  ?   ; last readen block of sectors
-
 
107
newMftRecord            dd  ?   ; number of fileRecord in MFT
-
 
108
fileDataStart           dd  ?   ; starting cluster
-
 
109
fileDataSize            dd  ?   ; in clusters
-
 
110
fileRealSize            dd  ?   ; in bytes
33
ntfs_cur_buf    dd      ?
111
indexOffset             dd  ?
-
 
112
nodeLastRead            dd  ?
34
ntfs_cur_read   dd      ?       ; [output]
113
ntfs_bCanContinue       db  ?
-
 
114
ntfsNotFound            db  ?
Line 35... Line 115...
35
ntfs_bCanContinue db    ?
115
ntfsFolder              db  ?
36
                rb      3
116
ntfsFragmentCount       db  ?
37
 
117
 
38
cur_subnode_size        dd      ?
118
cur_subnode_size        dd  ?
Line 46... Line 126...
46
ntfs_attrlist_buf       rb      0x400
126
ntfs_attrlist_buf       rb  0x400
47
ntfs_attrlist_mft_buf   rb      0x400
127
ntfs_attrlist_mft_buf   rb  0x400
48
ntfs_bitmap_buf         rb      0x400
128
ntfs_bitmap_buf         rb  0x400
49
ends
129
ends
Line -... Line 130...
-
 
130
 
-
 
131
; NTFS external functions
-
 
132
;   in:
-
 
133
; ebx -> parameter structure of sysfunc 70
-
 
134
; ebp -> NTFS structure
-
 
135
; [esi]+[esp+4] = name
-
 
136
;   out:
50
 
137
; eax, ebx = return values for sysfunc 70
51
iglobal
138
iglobal
52
align 4
139
align 4
53
ntfs_user_functions:
140
ntfs_user_functions:
54
        dd      ntfs_free
141
        dd      ntfs_free
55
        dd      (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
142
        dd      (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
56
        dd      ntfs_Read
143
        dd      ntfs_ReadFile
57
        dd      ntfs_ReadFolder
144
        dd      ntfs_ReadFolder
58
        dd      ntfs_Rewrite
145
        dd      ntfs_CreateFile
59
        dd      ntfs_Write
146
        dd      ntfs_Write
60
        dd      ntfs_SetFileEnd
147
        dd      ntfs_SetFileEnd
61
        dd      ntfs_GetFileInfo
148
        dd      ntfs_GetFileInfo
62
        dd      ntfs_SetFileInfo
149
        dd      ntfs_SetFileInfo
Line 66... Line 153...
66
ntfs_user_functions_end:
153
ntfs_user_functions_end:
67
endg
154
endg
Line 68... Line 155...
68
 
155
 
69
ntfs_test_bootsec:
156
ntfs_test_bootsec:
70
; in: ebx->buffer, edx=size of partition
157
; in: ebx -> buffer, edx = size of partition
71
; out: CF set <=> invalid
158
; out: CF=1 -> invalid
72
; 1. Name=='NTFS    '
159
; 1. Name=='NTFS    '
73
        cmp     dword [ebx+3], 'NTFS'
160
        cmp     dword [ebx+3], 'NTFS'
74
        jnz     .no
161
        jnz     .no
75
        cmp     dword [ebx+7], '    '
162
        cmp     dword [ebx+7], '    '
Line 119... Line 206...
119
        test    edx, edx
206
        test    edx, edx
120
        pop     edx
207
        pop     edx
121
        jnz     .no
208
        jnz     .no
122
        cmp     eax, edx
209
        cmp     eax, edx
123
        ja      .no
210
        ja      .no
124
; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2
211
; 7. Clusters per FRS must be either power of 2 or between -31 and -9
125
        movsx   eax, byte [ebx+0x40]
212
        movsx   eax, byte [ebx+0x40]
126
        cmp     al, -31
213
        cmp     al, -31
127
        jl      .no
214
        jl      .no
128
        cmp     al, -9
215
        cmp     al, -9
129
        jle     @f
216
        jle     @f
130
        dec     eax
217
        dec     eax
131
        js      .no
218
        js      .no
132
        test    [ebx+0x40], al
219
        test    [ebx+0x40], al
133
        jnz     .no
220
        jnz     .no
134
@@:
-
 
135
; 8. Same for clusters per IndexAllocationBuffer
221
@@:         ; 8. Same for clusters per IndexAllocationBuffer
136
        movsx   eax, byte [ebx+0x44]
222
        movsx   eax, byte [ebx+0x44]
137
        cmp     al, -31
223
        cmp     al, -31
138
        jl      .no
224
        jl      .no
139
        cmp     al, -9
225
        cmp     al, -9
140
        jle     @f
226
        jle     @f
141
        dec     eax
227
        dec     eax
142
        js      .no
228
        js      .no
143
        test    [ebx+0x44], al
229
        test    [ebx+0x44], al
144
        jnz     .no
230
        jnz     .no
145
@@:
-
 
146
; OK, this is correct NTFS bootsector
231
@@:         ; OK, this is correct NTFS bootsector
147
        clc
232
        clc
148
        ret
233
        ret
149
.no:
-
 
150
; No, this bootsector isn't NTFS
234
.no:        ; No, this bootsector isn't NTFS
151
        stc
235
        stc
152
        ret
236
        ret
Line 153... Line 237...
153
 
237
 
154
proc ntfs_create_partition
238
ntfs_create_partition:
155
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
239
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
156
        jnz     .nope
240
        jnz     .nope
157
        mov     edx, dword [ebp+PARTITION.Length]
241
        mov     edx, dword [ebp+PARTITION.Length]
158
        cmp     dword [esp+4], 0
242
        cmp     dword [esp+4], 0
Line 167... Line 251...
167
@@:
251
@@:
168
        mov     eax, edx
252
        mov     eax, edx
169
        shr     eax, 1
253
        shr     eax, 1
170
        call    fs_read32_sys
254
        call    fs_read32_sys
171
        test    eax, eax
255
        test    eax, eax
172
        jnz     .nope                   ; no chance...
256
        jnz     .nope
173
.boot_read_ok:
257
.boot_read_ok:
174
        call    ntfs_test_bootsec
258
        call    ntfs_test_bootsec
175
        jnc     .ntfs_setup
259
        jnc     .ntfs_setup
176
.nope:
260
.nope:
177
        xor     eax, eax
261
        xor     eax, eax
178
        jmp     .exit
262
        jmp     .exit
179
 
-
 
180
.ntfs_setup:
-
 
181
; By given bootsector, initialize some NTFS variables
263
; By given bootsector, initialize some NTFS variables
-
 
264
.ntfs_setup:
182
        movi    eax, sizeof.NTFS
265
        movi    eax, sizeof.NTFS
183
        call    malloc
266
        call    malloc
184
        test    eax, eax
267
        test    eax, eax
185
        jz      .exit
268
        jz      .exit
186
        mov     ecx, dword [ebp+PARTITION.FirstSector]
269
        mov     ecx, dword [ebp+PARTITION.FirstSector]
Line 192... Line 275...
192
        mov     ecx, dword [ebp+PARTITION.Length+4]
275
        mov     ecx, dword [ebp+PARTITION.Length+4]
193
        mov     dword [eax+NTFS.Length+4], ecx
276
        mov     dword [eax+NTFS.Length+4], ecx
194
        mov     ecx, [ebp+PARTITION.Disk]
277
        mov     ecx, [ebp+PARTITION.Disk]
195
        mov     [eax+NTFS.Disk], ecx
278
        mov     [eax+NTFS.Disk], ecx
196
        mov     [eax+NTFS.FSUserFunctions], ntfs_user_functions
279
        mov     [eax+NTFS.FSUserFunctions], ntfs_user_functions
-
 
280
 
197
        push    ebx ebp esi
281
        push    ebx ebp esi
198
        mov     ebp, eax
282
        mov     ebp, eax
199
 
-
 
200
        lea     ecx, [ebp+NTFS.Lock]
283
        lea     ecx, [ebp+NTFS.Lock]
201
        call    mutex_init
284
        call    mutex_init
202
 
-
 
203
        movzx   eax, byte [ebx+13]
285
        movzx   eax, byte [ebx+13]
204
        mov     [ebp+NTFS.sectors_per_cluster], eax
286
        mov     [ebp+NTFS.sectors_per_cluster], eax
205
        mov     eax, [ebx+0x28]
287
        mov     eax, [ebx+0x28]
206
        mov     dword [ebp+NTFS.Length], eax
288
        mov     dword [ebp+NTFS.Length], eax
207
        and     dword [ebp+NTFS.Length+4], 0
289
        and     dword [ebp+NTFS.Length+4], 0
Line 209... Line 291...
209
        mov     [ebp+NTFS.mft_cluster], eax
291
        mov     [ebp+NTFS.mft_cluster], eax
210
        mov     eax, [ebx+0x38]
292
        mov     eax, [ebx+0x38]
211
        mov     [ebp+NTFS.mftmirr_cluster], eax
293
        mov     [ebp+NTFS.mftmirr_cluster], eax
212
        movsx   eax, byte [ebx+0x40]
294
        movsx   eax, byte [ebx+0x40]
213
        test    eax, eax
295
        test    eax, eax
214
        js      .1
296
        js      @f
215
        mul     [ebp+NTFS.sectors_per_cluster]
297
        mul     [ebp+NTFS.sectors_per_cluster]
216
        shl     eax, 9
298
        shl     eax, 9
217
        jmp     .2
299
        jmp     .1
218
.1:
300
@@:
219
        neg     eax
301
        neg     eax
220
        mov     ecx, eax
302
        mov     ecx, eax
221
        mov     eax, 1
303
        mov     eax, 1
222
        shl     eax, cl
304
        shl     eax, cl
223
.2:
305
.1:
224
        mov     [ebp+NTFS.frs_size], eax
306
        mov     [ebp+NTFS.frs_size], eax
225
        movsx   eax, byte [ebx+0x44]
-
 
226
        test    eax, eax
-
 
227
        js      .3
-
 
228
        mul     [ebp+NTFS.sectors_per_cluster]
-
 
229
        shl     eax, 9
-
 
230
        jmp     .4
-
 
231
.3:
-
 
232
        neg     eax
-
 
233
        mov     ecx, eax
-
 
234
        mov     eax, 1
-
 
235
        shl     eax, cl
-
 
236
.4:
-
 
237
        mov     [ebp+NTFS.iab_size], eax
-
 
238
; allocate space for buffers
-
 
239
        add     eax, [ebp+NTFS.frs_size]
-
 
240
        push    eax
-
 
241
        call    kernel_alloc
307
        stdcall kernel_alloc, eax
242
        test    eax, eax
308
        test    eax, eax
243
        jz      .fail_free
309
        jz      .fail_free
244
        mov     [ebp+NTFS.frs_buffer], eax
310
        mov     [ebp+NTFS.frs_buffer], eax
245
        add     eax, [ebp+NTFS.frs_size]
-
 
246
        mov     [ebp+NTFS.iab_buffer], eax
-
 
247
; read $MFT disposition
311
; read $MFT disposition
248
        mov     eax, [ebp+NTFS.mft_cluster]
312
        mov     eax, [ebp+NTFS.mft_cluster]
249
        mul     [ebp+NTFS.sectors_per_cluster]
313
        mul     [ebp+NTFS.sectors_per_cluster]
250
        call    ntfs_read_frs_sector
314
        call    ntfs_read_frs_sector
251
        test    eax, eax
315
        test    eax, eax
Line 257... Line 321...
257
.usemirr:
321
.usemirr:
258
        mov     eax, [ebp+NTFS.mftmirr_cluster]
322
        mov     eax, [ebp+NTFS.mftmirr_cluster]
259
        mul     [ebp+NTFS.sectors_per_cluster]
323
        mul     [ebp+NTFS.sectors_per_cluster]
260
        call    ntfs_read_frs_sector
324
        call    ntfs_read_frs_sector
261
        test    eax, eax
325
        test    eax, eax
262
        jnz     @f
326
        jnz     .fail_free_frs
263
        cmp     dword [ebx], 'FILE'
327
        cmp     dword [ebx], 'FILE'
264
        jnz     @f
328
        jnz     .fail_free_frs
265
        call    ntfs_restore_usa_frs
329
        call    ntfs_restore_usa_frs
266
        jnc     .mftok
-
 
267
@@:
-
 
268
; $MFT and $MFTMirr invalid!
-
 
269
.fail_free_frs:
-
 
270
        push    [ebp+NTFS.frs_buffer]
-
 
271
        call    kernel_free
-
 
272
.fail_free:
-
 
273
        mov     eax, ebp
-
 
274
        call    free
-
 
275
        xor     eax, eax
-
 
276
.pop_exit:
-
 
277
        pop     esi ebp ebx
-
 
278
.exit:
-
 
279
        cmp     dword [esp+4], 0
-
 
280
        jz      @f
-
 
281
        sub     ebx, 512
-
 
282
@@:
-
 
283
        ret
-
 
284
.fail_free_mft:
-
 
285
        push    [ebp+NTFS.mft_retrieval]
-
 
286
        call    kernel_free
-
 
287
        jmp     .fail_free_frs
330
        jc      .fail_free_frs
288
.mftok:
331
.mftok:
289
; read $MFT table retrieval information
332
; read $MFT table retrieval information
290
; start with one page, increase if not enough (when MFT too fragmented)
333
; start with one page, increase if not enough (when MFT too fragmented)
291
        push    ebx
334
        push    ebx
292
        push    0x1000
-
 
293
        call    kernel_alloc
335
        stdcall kernel_alloc, 0x1000
294
        pop     ebx
336
        pop     ebx
295
        test    eax, eax
337
        test    eax, eax
296
        jz      .fail_free_frs
338
        jz      .fail_free_frs
297
        mov     [ebp+NTFS.mft_retrieval], eax
339
        mov     [ebp+NTFS.mft_retrieval], eax
298
        and     [ebp+NTFS.mft_retrieval_size], 0
340
        and     [ebp+NTFS.mft_retrieval_size], 0
Line 332... Line 374...
332
        jmp     .scanmcb
374
        jmp     .scanmcb
333
.scanmcbend:
375
.scanmcbend:
334
        add     esp, 10h
376
        add     esp, 10h
335
; there may be other portions of $DATA attribute in auxiliary records;
377
; there may be other portions of $DATA attribute in auxiliary records;
336
; if they will be needed, they will be loaded later
378
; if they will be needed, they will be loaded later
337
 
-
 
338
        mov     [ebp+NTFS.cur_index_size], 0x1000/0x200
379
        mov     [ebp+NTFS.cur_index_size], 0x1000/0x200
339
        push    0x1000
-
 
340
        call    kernel_alloc
380
        stdcall kernel_alloc, 0x1000
341
        test    eax, eax
381
        test    eax, eax
342
        jz      .fail_free_mft
382
        jz      .fail_free_mft
343
        mov     [ebp+NTFS.cur_index_buf], eax
383
        mov     [ebp+NTFS.cur_index_buf], eax
-
 
384
; reserve adress space for bitmap buffer and load some part of bitmap
-
 
385
        mov     eax, dword [ebp+NTFS.Length]
-
 
386
        xor     edx, edx
-
 
387
        div     [ebp+NTFS.sectors_per_cluster]
-
 
388
        shr     eax, 3
-
 
389
        mov     [ebp+NTFS.BitmapTotalSize], eax
-
 
390
        add     eax, 7FFFh
-
 
391
        and     eax, not 7FFFh
-
 
392
        push    eax
-
 
393
        call    alloc_kernel_space
-
 
394
        test    eax, eax
-
 
395
        jz      .failFreeIndex
-
 
396
        mov     [ebp+NTFS.BitmapBuffer], eax
-
 
397
        mov     [ebp+NTFS.ntfs_cur_buf], eax
-
 
398
        mov     eax, [ebp+NTFS.BitmapTotalSize]
-
 
399
        add     eax, [ebp+NTFS.mft_cluster]
-
 
400
        shr     eax, 3+2        ; reserve 1/8 of partition for $MFT
-
 
401
        shl     eax, 2
-
 
402
        mov     [ebp+NTFS.BitmapStart], eax
-
 
403
        shr     eax, 15
-
 
404
        inc     eax
-
 
405
        shl     eax, 3
-
 
406
        push    eax
-
 
407
        push    eax
-
 
408
        shl     eax, 3
-
 
409
        mov     [ebp+NTFS.ntfs_cur_size], eax
-
 
410
        call    alloc_pages
-
 
411
        test    eax, eax
-
 
412
        pop     ecx
-
 
413
        jz      .failFreeBitmap
-
 
414
        add     eax, 3
-
 
415
        mov     ebx, [ebp+NTFS.BitmapBuffer]
-
 
416
        call    commit_pages
-
 
417
        mov     [ebp+NTFS.ntfs_cur_iRecord], 6
-
 
418
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
-
 
419
        mov     [ebp+NTFS.ntfs_cur_offs], 0
-
 
420
        call    ntfs_read_attr
-
 
421
        jc      .failFreeBitmap
-
 
422
        mov     eax, [ebp+NTFS.ntfs_cur_read]
-
 
423
        mov     [ebp+NTFS.BitmapSize], eax
-
 
424
        mov     eax, [ebp+NTFS.ntfsLastRead]
-
 
425
        mov     [ebp+NTFS.BitmapLocation], eax
-
 
426
; read MFT $BITMAP attribute
-
 
427
        mov     eax, [ebp+NTFS.sectors_per_cluster]
-
 
428
        mov     [ebp+NTFS.ntfs_cur_size], eax
-
 
429
        shl     eax, 9
-
 
430
        stdcall kernel_alloc, eax
-
 
431
        test    eax, eax
-
 
432
        jz      .failFreeBitmap
-
 
433
        mov     [ebp+NTFS.mftBitmapBuffer], eax
-
 
434
        mov     [ebp+NTFS.ntfs_cur_buf], eax
-
 
435
        mov     [ebp+NTFS.ntfs_cur_iRecord], 0
-
 
436
        mov     [ebp+NTFS.ntfs_cur_attr], 0xB0
-
 
437
        mov     [ebp+NTFS.ntfs_cur_offs], 0
-
 
438
        call    ntfs_read_attr
-
 
439
        mov     eax, [ebp+NTFS.ntfs_cur_read]
-
 
440
        cmp     eax, 4
-
 
441
        jc      .failFreeBitmapMFT
-
 
442
        mov     [ebp+NTFS.mftBitmapSize], eax
-
 
443
        mov     eax, [ebp+NTFS.ntfsLastRead]
-
 
444
        mov     [ebp+NTFS.mftBitmapLocation], eax
Line 344... Line 445...
344
 
445
 
-
 
446
        mov     eax, ebp
-
 
447
.pop_exit:
-
 
448
        pop     esi ebp ebx
-
 
449
.exit:
-
 
450
        cmp     dword [esp+4], 0
-
 
451
        jz      @f
-
 
452
        sub     ebx, 512
-
 
453
@@:
-
 
454
        ret
-
 
455
 
-
 
456
.failFreeBitmapMFT:
-
 
457
        stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
-
 
458
.failFreeBitmap:
-
 
459
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
-
 
460
.failFreeIndex:
-
 
461
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
-
 
462
.fail_free_mft:
-
 
463
        stdcall kernel_free, [ebp+NTFS.mft_retrieval]
-
 
464
.fail_free_frs:
-
 
465
        stdcall kernel_free, [ebp+NTFS.frs_buffer]
-
 
466
.fail_free:
-
 
467
        mov     eax, ebp
-
 
468
        call    free
345
        mov     eax, ebp
469
        xor     eax, eax
346
        jmp     .pop_exit
-
 
Line 347... Line 470...
347
endp
470
        jmp     .pop_exit
348
 
471
 
349
.get_mft_retrieval_ptr:
472
.get_mft_retrieval_ptr:
350
        pushad
473
        pushad
351
        mov     eax, [ebp+NTFS.mft_retrieval_size]
474
        mov     eax, [ebp+NTFS.mft_retrieval_size]
352
        cmp     eax, [ebp+NTFS.mft_retrieval_alloc]
475
        cmp     eax, [ebp+NTFS.mft_retrieval_alloc]
353
        jnz     .ok
476
        jnz     .ok
354
        add     eax, 0x1000/8
477
        add     eax, 0x1000/8
355
        mov     [ebp+NTFS.mft_retrieval_alloc], eax
-
 
356
        shl     eax, 3
478
        mov     [ebp+NTFS.mft_retrieval_alloc], eax
357
        push    eax
479
        shl     eax, 3
358
        call    kernel_alloc
480
        stdcall kernel_alloc, eax
359
        test    eax, eax
481
        test    eax, eax
360
        jnz     @f
482
        jnz     @f
361
        popad
483
        popad
Line 376... Line 498...
376
        add     eax, [ebp+NTFS.mft_retrieval]
498
        add     eax, [ebp+NTFS.mft_retrieval]
377
        mov     [esp+28], eax
499
        mov     [esp+28], eax
378
        popad
500
        popad
379
        ret
501
        ret
Line 380... Line 502...
380
 
502
 
381
proc ntfs_free
503
ntfs_free:
382
        push    ebx
504
        push    ebx
383
        xchg    ebx, eax
505
        mov     ebx, eax
384
        stdcall kernel_free, [ebx+NTFS.frs_buffer]
506
        stdcall kernel_free, [ebx+NTFS.frs_buffer]
385
        stdcall kernel_free, [ebx+NTFS.mft_retrieval]
507
        stdcall kernel_free, [ebx+NTFS.mft_retrieval]
-
 
508
        stdcall kernel_free, [ebx+NTFS.cur_index_buf]
386
        stdcall kernel_free, [ebx+NTFS.cur_index_buf]
509
        stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
387
        xchg    ebx, eax
510
        stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
388
        call    free
511
        mov     eax, ebx
389
        pop     ebx
512
        pop     ebx
390
        ret
-
 
Line 391... Line 513...
391
endp
513
        jmp     free
392
 
514
 
393
proc ntfs_lock
515
ntfs_lock:
394
        lea     ecx, [ebp+NTFS.Lock]
-
 
Line 395... Line 516...
395
        jmp     mutex_lock
516
        lea     ecx, [ebp+NTFS.Lock]
396
endp
517
        jmp     mutex_lock
397
 
518
 
398
proc ntfs_unlock
-
 
Line 399... Line 519...
399
        lea     ecx, [ebp+NTFS.Lock]
519
ntfs_unlock:
400
        jmp     mutex_unlock
520
        lea     ecx, [ebp+NTFS.Lock]
401
endp
521
        jmp     mutex_unlock
402
 
522
 
Line 422... Line 542...
422
        pop     ebx
542
        pop     ebx
423
        pop     ecx
543
        pop     ecx
424
        ret
544
        ret
Line 425... Line 545...
425
 
545
 
-
 
546
ntfs_read_attr:
-
 
547
;   in:
426
ntfs_read_attr:
548
; [ebp+NTFS.ntfs_cur_iRecord] = number of fileRecord
-
 
549
; [ebp+NTFS.ntfs_cur_attr] = attribute type
-
 
550
; [ebp+NTFS.ntfs_cur_offs] = attribute VCN in sectors
-
 
551
; [ebp+NTFS.ntfs_cur_buf] -> buffer for data
-
 
552
; [ebp+NTFS.ntfs_cur_size] = max sectors to read
427
; in: variables in ebp+NTFS.*
553
;   out:
428
; out: [ebp+NTFS.ntfs_cur_read]
554
; [ebp+NTFS.ntfs_cur_read] = bytes readen
429
; out: CF=1 => notfound, in this case eax=0 => disk ok, otherwise eax=disk error code
555
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
430
        xor     eax, eax
556
        xor     eax, eax
431
        pushad
557
        pushad
432
        and     [ebp+NTFS.ntfs_cur_read], 0
558
        and     [ebp+NTFS.ntfs_cur_read], 0
433
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
559
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
Line 473... Line 599...
473
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
599
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
474
        pop     ecx
600
        pop     ecx
475
        neg     ecx
601
        neg     ecx
476
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
602
        imul    ecx, [ebp+NTFS.sectors_per_cluster]
477
        sub     ecx, edx
603
        sub     ecx, edx
-
 
604
        mov     [ebp+NTFS.ntfsLastRead], eax
478
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
605
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
479
        jb      @f
606
        jb      @f
480
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
607
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
481
@@:
608
@@:
482
; ecx = number of sequential sectors to read
609
; ecx = number of sequential sectors to read
Line 867... Line 994...
867
; eax = cluster, edx = starting sector
994
; eax = cluster, edx = starting sector
868
        sub     esp, 10h
995
        sub     esp, 10h
869
        movzx   esi, word [ecx+20h]     ; mcb_info_ofs
996
        movzx   esi, word [ecx+20h]     ; mcb_info_ofs
870
        add     esi, ecx
997
        add     esi, ecx
871
        xor     edi, edi
998
        xor     edi, edi
-
 
999
        mov     [ebp+NTFS.ntfsFragmentCount], 0
872
.readloop:
1000
.readloop:
873
        call    ntfs_decode_mcb_entry
1001
        call    ntfs_decode_mcb_entry
874
        jnc     .break
1002
        jnc     .break
875
        add     edi, [esp+8]
1003
        add     edi, [esp+8]
876
        sub     eax, [esp]
1004
        sub     eax, [esp]
Line 888... Line 1016...
888
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
1016
        cmp     ecx, [ebp+NTFS.ntfs_cur_size]
889
        jb      @f
1017
        jb      @f
890
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
1018
        mov     ecx, [ebp+NTFS.ntfs_cur_size]
891
@@:
1019
@@:
892
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
1020
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
893
@@:
-
 
-
 
1021
        mov     [ebp+NTFS.ntfsLastRead], eax
894
        push    eax
1022
        push    ecx
-
 
1023
        xor     edx, edx
895
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
1024
        cmp     [ebp+NTFS.ntfs_cur_attr], 0x80
896
        jnz     .sys
1025
        jnz     .sys
897
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
1026
        cmp     [ebp+NTFS.ntfs_cur_iRecord], 0
898
        jz      .sys
1027
        jz      .sys
899
        call    fs_read32_app
1028
        call    fs_read64_app
900
        jmp     .appsys
1029
        jmp     .appsys
901
.sys:
1030
.sys:
902
        call    fs_read32_sys
1031
        call    fs_read64_sys
903
.appsys:
1032
.appsys:
904
        pop     edx
1033
        pop     ecx
905
        test    eax, eax
1034
        test    eax, eax
906
        jnz     .errread2
1035
        jnz     .errread2
907
        add     ebx, 0x200
1036
        sub     [ebp+NTFS.ntfs_cur_size], ecx
908
        mov     [ebp+NTFS.ntfs_cur_buf], ebx
1037
        add     [ebp+NTFS.ntfs_cur_offs], ecx
909
        lea     eax, [edx+1]
1038
        shl     ecx, 9
910
        add     [ebp+NTFS.ntfs_cur_read], 0x200
1039
        add     [ebp+NTFS.ntfs_cur_read], ecx
911
        dec     [ebp+NTFS.ntfs_cur_size]
1040
        add     [ebp+NTFS.ntfs_cur_buf], ecx
912
        inc     [ebp+NTFS.ntfs_cur_offs]
1041
        inc     [ebp+NTFS.ntfsFragmentCount]
913
        loop    @b
-
 
914
        pop     ecx
1042
        pop     ecx
915
        xor     eax, eax
1043
        xor     eax, eax
916
        xor     edx, edx
1044
        xor     edx, edx
917
        cmp     [ebp+NTFS.ntfs_cur_size], 0
1045
        cmp     [ebp+NTFS.ntfs_cur_size], 0
918
        jnz     .readloop
1046
        jnz     .readloop
Line 935... Line 1063...
935
        mov     [ebp+NTFS.ntfs_bCanContinue], 1
1063
        mov     [ebp+NTFS.ntfs_bCanContinue], 1
936
        ret
1064
        ret
Line 937... Line 1065...
937
 
1065
 
938
ntfs_read_file_record:
1066
ntfs_read_file_record:
939
; in: eax=iRecord
1067
; in: eax = iRecord
940
; out: [ebp+NTFS.frs_buffer] contains information
1068
; out: [ebp+NTFS.frs_buffer] = record data
941
;      CF=1 - failed, in this case eax=0 => something with FS, eax nonzero => disk error
1069
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
942
; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
1070
    ; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
943
        push    ecx edx
1071
        push    ecx edx
944
        mov     ecx, [ebp+NTFS.frs_size]
1072
        mov     ecx, [ebp+NTFS.frs_size]
945
        mul     ecx
1073
        mul     ecx
Line 1078... Line 1206...
1078
.unk:
1206
.unk:
1079
        pop     eax
1207
        pop     eax
1080
        ret
1208
        ret
Line 1081... Line 1209...
1081
 
1209
 
1082
ntfs_find_lfn:
1210
ntfs_find_lfn:
1083
; in: esi+[esp+4] -> name
1211
; in: [esi]+[esp+4] = name
1084
; out: CF=1 - file not found
1212
;   out:
-
 
1213
; [ebp+NTFS.ntfs_cur_iRecord] = number of MFT fileRecord
-
 
1214
; eax = pointer in parent index node
1085
;      else CF=0, [ebp+NTFS.ntfs_cur_iRecord] valid, eax->record in parent directory
1215
; CF=1 -> file not found (or just error)
1086
        mov     [ebp+NTFS.ntfs_cur_iRecord], 5   ; start parse from root cluster
1216
        mov     [ebp+NTFS.ntfs_cur_iRecord], 5   ; start parse from root cluster
1087
.doit2:
1217
.doit2:
1088
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1218
        mov     [ebp+NTFS.ntfs_cur_attr], 0x90   ; $INDEX_ROOT
1089
        and     [ebp+NTFS.ntfs_cur_offs], 0
1219
        and     [ebp+NTFS.ntfs_cur_offs], 0
Line 1114... Line 1244...
1114
        stc
1244
        stc
1115
        ret     4
1245
        ret     4
1116
@@:
1246
@@:
1117
; reallocate
1247
; reallocate
1118
        push    eax
1248
        push    eax
1119
        push    [ebp+NTFS.cur_index_buf]
1249
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1120
        call    kernel_free
-
 
1121
        pop     eax
1250
        pop     eax
1122
        mov     [ebp+NTFS.cur_index_size], eax
1251
        mov     [ebp+NTFS.cur_index_size], eax
1123
        push    eax
-
 
1124
        call    kernel_alloc
1252
        stdcall kernel_alloc, eax
1125
        test    eax, eax
1253
        test    eax, eax
1126
        jnz     @f
1254
        jnz     @f
1127
        and     [ebp+NTFS.cur_index_size], 0
1255
        and     [ebp+NTFS.cur_index_size], 0
1128
        and     [ebp+NTFS.cur_index_buf], 0
1256
        and     [ebp+NTFS.cur_index_buf], 0
1129
        jmp     .stc_ret
1257
        jmp     .stc_ret
Line 1135... Line 1263...
1135
        mov     edx, [esi+8]    ; subnode_size
1263
        mov     edx, [esi+8]    ; subnode_size
1136
        shr     edx, 9
1264
        shr     edx, 9
1137
        cmp     edx, [ebp+NTFS.cur_index_size]
1265
        cmp     edx, [ebp+NTFS.cur_index_size]
1138
        jbe     .ok2
1266
        jbe     .ok2
1139
        push    esi edx
1267
        push    esi edx
1140
        push    edx
-
 
1141
        call    kernel_alloc
1268
        stdcall kernel_alloc, edx
1142
        pop     edx esi
1269
        pop     edx esi
1143
        test    eax, eax
1270
        test    eax, eax
1144
        jz      .stc_ret
1271
        jz      .stc_ret
1145
        mov     edi, eax
1272
        mov     edi, eax
1146
        mov     ecx, [ebp+NTFS.cur_index_size]
1273
        mov     ecx, [ebp+NTFS.cur_index_size]
1147
        shl     ecx, 9-2
1274
        shl     ecx, 9-2
1148
        rep movsd
1275
        rep movsd
1149
        mov     esi, eax
1276
        mov     esi, eax
1150
        mov     [ebp+NTFS.cur_index_size], edx
1277
        mov     [ebp+NTFS.cur_index_size], edx
1151
        push    esi edx
1278
        push    esi edx
1152
        push    [ebp+NTFS.cur_index_buf]
1279
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1153
        call    kernel_free
-
 
1154
        pop     edx esi
1280
        pop     edx esi
1155
        mov     [ebp+NTFS.cur_index_buf], esi
1281
        mov     [ebp+NTFS.cur_index_buf], esi
1156
.ok2:
1282
.ok2:
1157
        add     esi, 10h
1283
        add     esi, 10h
1158
        mov     edi, [esp+4]
1284
        mov     edi, [esp+4]
Line 1207... Line 1333...
1207
        call    ntfs_read_attr
1333
        call    ntfs_read_attr
1208
        pop     edx
1334
        pop     edx
1209
        mov     eax, edx
1335
        mov     eax, edx
1210
        shl     eax, 9
1336
        shl     eax, 9
1211
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1337
        cmp     [ebp+NTFS.ntfs_cur_read], eax
1212
        jnz     .notfound
1338
        jnz     .err
1213
        cmp     dword [esi], 'INDX'
1339
        cmp     dword [esi], 'INDX'
1214
        jnz     .notfound
1340
        jnz     .err
-
 
1341
        mov     [ebp+NTFS.ntfs_cur_buf], esi
1215
        mov     ebx, esi
1342
        mov     ebx, esi
1216
        call    ntfs_restore_usa
1343
        call    ntfs_restore_usa
1217
        jc      .notfound
1344
        jc      .err
1218
        add     esi, 0x18
1345
        add     esi, 0x18
1219
        jmp     .scanloop
1346
        jmp     .scanloop
1220
.notfound:
1347
.notfound:
-
 
1348
        mov     [ebp+NTFS.ntfsNotFound], 1
-
 
1349
        mov     [esp+1Ch], esi
-
 
1350
.err:
1221
        popad
1351
        popad
1222
        stc
1352
        stc
1223
        ret     4
1353
        ret     4
1224
.found:
1354
.found:
1225
        cmp     byte [edi], 0
1355
        cmp     byte [edi], 0
Line 1248... Line 1378...
1248
        jmp     .doit2
1378
        jmp     .doit2
1249
@@:
1379
@@:
1250
        ret     4
1380
        ret     4
Line 1251... Line 1381...
1251
 
1381
 
1252
;----------------------------------------------------------------
-
 
1253
; ntfs_Read - NTFS implementation of reading a file
-
 
1254
; in:  ebp = pointer to NTFS structure
-
 
1255
; in:  esi+[esp+4] = name
-
 
1256
; in:  ebx = pointer to parameters from sysfunc 70
-
 
1257
; out: eax, ebx = return values for sysfunc 70
-
 
1258
;----------------------------------------------------------------
1382
;----------------------------------------------------------------
1259
ntfs_Read:
1383
ntfs_ReadFile:
1260
        cmp     byte [esi], 0
1384
        cmp     byte [esi], 0
1261
        jnz     @f
1385
        jnz     @f
1262
        or      ebx, -1
1386
        or      ebx, -1
1263
        movi    eax, ERROR_ACCESS_DENIED
1387
        movi    eax, ERROR_ACCESS_DENIED
Line 1288... Line 1412...
1288
        jb      @f
1412
        jb      @f
1289
.eof0:
1413
.eof0:
1290
        popad
1414
        popad
1291
        xor     ebx, ebx
1415
        xor     ebx, ebx
1292
.eof:
1416
.eof:
1293
        movi    eax, ERROR_END_OF_FILE
1417
        push    ERROR_END_OF_FILE
1294
        push    eax
-
 
1295
        call    ntfs_unlock
1418
        call    ntfs_unlock
1296
        pop     eax
1419
        pop     eax
1297
        ret
1420
        ret
1298
@@:
1421
@@:
1299
        mov     ecx, [ebx+12]
1422
        mov     ecx, [ebx+12]
Line 1390... Line 1513...
1390
        call    ntfs_unlock
1513
        call    ntfs_unlock
1391
        popad
1514
        popad
1392
        ret
1515
        ret
Line 1393... Line 1516...
1393
 
1516
 
1394
;----------------------------------------------------------------
-
 
1395
; ntfs_ReadFolder - NTFS implementation of reading a folder
-
 
1396
; in:  ebp = pointer to NTFS structure
-
 
1397
; in:  esi+[esp+4] = name
-
 
1398
; in:  ebx = pointer to parameters from sysfunc 70
-
 
1399
; out: eax, ebx = return values for sysfunc 70
-
 
1400
;----------------------------------------------------------------
1517
;----------------------------------------------------------------
1401
ntfs_ReadFolder:
1518
ntfs_ReadFolder:
1402
        call    ntfs_lock
1519
        call    ntfs_lock
1403
        mov     eax, 5          ; root cluster
1520
        mov     eax, 5          ; root cluster
1404
        cmp     byte [esi], 0
1521
        cmp     byte [esi], 0
Line 1456... Line 1573...
1456
        popad
1573
        popad
1457
        jmp     .fserr
1574
        jmp     .fserr
1458
@@:
1575
@@:
1459
; reallocate
1576
; reallocate
1460
        push    eax
1577
        push    eax
1461
        push    [ebp+NTFS.cur_index_buf]
1578
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1462
        call    kernel_free
-
 
1463
        pop     eax
1579
        pop     eax
1464
        mov     [ebp+NTFS.cur_index_size], eax
1580
        mov     [ebp+NTFS.cur_index_size], eax
1465
        push    eax
-
 
1466
        call    kernel_alloc
1581
        stdcall kernel_alloc, eax
1467
        test    eax, eax
1582
        test    eax, eax
1468
        jnz     @f
1583
        jnz     @f
1469
        and     [ebp+NTFS.cur_index_size], 0
1584
        and     [ebp+NTFS.cur_index_size], 0
1470
        and     [ebp+NTFS.cur_index_buf], 0
1585
        and     [ebp+NTFS.cur_index_buf], 0
1471
.nomem:
1586
.nomem:
Line 1483... Line 1598...
1483
        shr     edx, 9
1598
        shr     edx, 9
1484
        mov     [ebp+NTFS.cur_subnode_size], edx
1599
        mov     [ebp+NTFS.cur_subnode_size], edx
1485
        cmp     edx, [ebp+NTFS.cur_index_size]
1600
        cmp     edx, [ebp+NTFS.cur_index_size]
1486
        jbe     .ok2
1601
        jbe     .ok2
1487
        push    esi edx
1602
        push    esi edx
1488
        push    edx
-
 
1489
        call    kernel_alloc
1603
        stdcall kernel_alloc, edx
1490
        pop     edx esi
1604
        pop     edx esi
1491
        test    eax, eax
1605
        test    eax, eax
1492
        jz      .nomem
1606
        jz      .nomem
1493
        mov     edi, eax
1607
        mov     edi, eax
1494
        mov     ecx, [ebp+NTFS.cur_index_size]
1608
        mov     ecx, [ebp+NTFS.cur_index_size]
1495
        shl     ecx, 9-2
1609
        shl     ecx, 9-2
1496
        rep movsd
1610
        rep movsd
1497
        mov     esi, eax
1611
        mov     esi, eax
1498
        mov     [ebp+NTFS.cur_index_size], edx
1612
        mov     [ebp+NTFS.cur_index_size], edx
1499
        push    [ebp+NTFS.cur_index_buf]
1613
        stdcall kernel_free, [ebp+NTFS.cur_index_buf]
1500
        call    kernel_free
-
 
1501
        mov     [ebp+NTFS.cur_index_buf], esi
1614
        mov     [ebp+NTFS.cur_index_buf], esi
1502
.ok2:
1615
.ok2:
1503
        add     esi, 10h
1616
        add     esi, 10h
1504
        mov     edx, [ebx+16]
1617
        mov     edx, [ebx+16]
1505
        push    dword [ebx+8]   ; read ANSI/UNICODE name
1618
        push    dword [ebx+8]   ; read ANSI/UNICODE name
Line 1858... Line 1971...
1858
        mov     [edi+5], al
1971
        mov     [edi+5], al
1859
        add     edi, 8
1972
        add     edi, 8
1860
        ret
1973
        ret
Line 1861... Line 1974...
1861
 
1974
 
1862
;----------------------------------------------------------------
-
 
1863
; ntfs_Rewrite - NTFS implementation of creating a new file
-
 
1864
; in:  ebp = pointer to NTFS structure
-
 
1865
; in:  esi+[esp+4] = name
-
 
1866
; in:  ebx = pointer to parameters from sysfunc 70
-
 
1867
; out: eax, ebx = return values for sysfunc 70
-
 
1868
;----------------------------------------------------------------
-
 
1869
ntfs_Rewrite:
1975
;----------------------------------------------------------------
-
 
1976
ntfs_CreateFolder:
-
 
1977
        mov     [ebp+NTFS.ntfsFolder], 1
-
 
1978
        jmp     @f
-
 
1979
ntfs_CreateFile:
-
 
1980
        mov     [ebp+NTFS.ntfsFolder], 0
-
 
1981
@@:
-
 
1982
        cmp     byte [esi], 0
1870
ntfs_CreateFolder:
1983
        jnz     @f
-
 
1984
        xor     ebx, ebx
-
 
1985
        movi    eax, ERROR_ACCESS_DENIED    ; root directory itself
-
 
1986
        ret
-
 
1987
@@: ; 1. Search file
-
 
1988
        call    ntfs_lock
-
 
1989
        mov     [ebp+NTFS.ntfsNotFound], 0
-
 
1990
        stdcall ntfs_find_lfn, [esp+4]
-
 
1991
        jnc     @f      ; found; rewrite
-
 
1992
        cmp     [ebp+NTFS.ntfsFragmentCount], 1
-
 
1993
        jnz     @f      ; record fragmented
-
 
1994
        cmp     [ebp+NTFS.ntfsNotFound], 1
-
 
1995
        jz      .notFound
-
 
1996
        push    ERROR_FS_FAIL
-
 
1997
        jmp     ntfsError
1871
        xor     ebx, ebx
1998
@@:
-
 
1999
        push    ERROR_UNSUPPORTED_FS
-
 
2000
        jmp     ntfsError
-
 
2001
.notFound:  ; create; check name
-
 
2002
        cmp     dword [esp+4], 0
-
 
2003
        jnz     .bad
-
 
2004
        cmp     byte [esi], 0
-
 
2005
        jnz     @f
-
 
2006
.bad:       ; path folder not found
-
 
2007
        push    ERROR_FILE_NOT_FOUND
-
 
2008
        jmp     ntfsError
-
 
2009
@@: ; 2. Prepair directory record
-
 
2010
        mov     ecx, esi
-
 
2011
@@:         ; count characters
-
 
2012
        inc     ecx
-
 
2013
        cmp     byte [ecx], '/'
-
 
2014
        jz      .bad
-
 
2015
        cmp     byte [ecx], 0
-
 
2016
        jnz     @b
-
 
2017
        sub     ecx, esi
-
 
2018
        push    ecx
-
 
2019
        lea     ecx, [ecx*2+52h]    ; precalculate index length
-
 
2020
        add     ecx, 7              ; align 8
-
 
2021
        and     ecx, not 7
-
 
2022
        mov     edi, [ebp+NTFS.cur_index_buf]
-
 
2023
        push    esi
-
 
2024
        push    ecx
-
 
2025
        cmp     dword [edi], 'INDX'         ; where are we?
-
 
2026
        jz      .indexRecord
-
 
2027
        mov     esi, [ebp+NTFS.frs_buffer]  ; mftRecord
-
 
2028
        mov     edx, [esi+recordRealSize]
-
 
2029
        add     edx, ecx
-
 
2030
        cmp     [esi+recordAllocatedSize], edx
-
 
2031
        jnc     @f
-
 
2032
        add     esp, 12
-
 
2033
        push    ERROR_UNSUPPORTED_FS    ; indexAllocation required
-
 
2034
        jmp     ntfsError
-
 
2035
@@:         ; index fits in the indexRoot
-
 
2036
        mov     [esi+recordRealSize], edx
-
 
2037
        mov     ecx, edx
-
 
2038
        shr     ecx, 2
-
 
2039
        rep movsd
-
 
2040
        mov     edi, [ebp+NTFS.ntfs_attr_offs]
-
 
2041
        sub     edi, [ebp+NTFS.frs_buffer]
-
 
2042
        add     edi, [ebp+NTFS.cur_index_buf]
-
 
2043
        mov     esi, [esp]
-
 
2044
        add     [edi+sizeWithHeader], esi
-
 
2045
        add     [edi+sizeWithoutHeader], esi
-
 
2046
        mov     cx, [edi+attributeOffset]
-
 
2047
        add     edi, ecx
-
 
2048
        add     [edi+16+nodeRealSize], esi
-
 
2049
        add     [edi+16+nodeAllocatedSize], esi
-
 
2050
        sub     eax, [ebp+NTFS.cur_index_buf]
-
 
2051
        add     eax, edi
-
 
2052
        mov     edi, [ebp+NTFS.cur_index_buf]
-
 
2053
        add     edi, edx
-
 
2054
        sub     edi, 4
-
 
2055
        jmp     .common
-
 
2056
 
-
 
2057
.indexRecord:
-
 
2058
        mov     edx, [edi+1ch]
-
 
2059
        add     edx, ecx
-
 
2060
        cmp     [edi+20h], edx
-
 
2061
        jnc     @f
-
 
2062
        add     esp, 12
-
 
2063
        push    ERROR_UNSUPPORTED_FS    ; new node required
-
 
2064
        jmp     ntfsError
-
 
2065
@@:         ; index fits in the node
-
 
2066
        mov     [edi+1ch], edx
-
 
2067
        lea     edi, [edi+edx+14h]
-
 
2068
.common:
-
 
2069
        mov     esi, edi
-
 
2070
        sub     esi, [esp]
-
 
2071
        mov     ecx, esi
-
 
2072
        sub     ecx, eax    ; eax = pointer in the node
-
 
2073
        shr     ecx, 2
-
 
2074
        inc     ecx
-
 
2075
        std
-
 
2076
        rep movsd           ; move forward, make space
-
 
2077
        mov     ecx, [esp]
-
 
2078
        shr     ecx, 2
-
 
2079
        xor     eax, eax
-
 
2080
        rep stosd
-
 
2081
        cld
-
 
2082
        add     edi, 4
-
 
2083
        pop     eax
-
 
2084
        pop     esi
-
 
2085
        mov     [edi+indexAllocatedSize], ax     ; fill index with data
-
 
2086
        mov     eax, [esp]
-
 
2087
        lea     eax, [eax*2+42h]
-
 
2088
        mov     [edi+indexRawSize], ax
-
 
2089
        mov     eax, [ebp+NTFS.ntfs_attr_iRecord]
-
 
2090
        mov     [edi+directoryRecordReference], eax
-
 
2091
        mov     eax, [ebp+NTFS.frs_buffer]
-
 
2092
        mov     eax, [eax+reuseCounter]
-
 
2093
        mov     [edi+directoryReferenceReuse], ax
-
 
2094
        mov     eax, [ebx+12]
-
 
2095
        mov     [ebp+NTFS.fileRealSize], eax
-
 
2096
        mov     [edi+fileRealSize], eax
-
 
2097
        mov     ecx, [ebp+NTFS.sectors_per_cluster]
-
 
2098
        shl     ecx, 9
-
 
2099
        add     eax, ecx
-
 
2100
        dec     eax
-
 
2101
        xor     edx, edx
-
 
2102
        div     ecx
-
 
2103
        mov     [ebp+NTFS.fileDataSize], eax
-
 
2104
        mul     ecx
-
 
2105
        mov     [edi+fileAllocatedSize], eax
-
 
2106
        pop     ecx
-
 
2107
        mov     [ebp+NTFS.indexOffset], edi
-
 
2108
        mov     [edi+fileNameLength], cl
-
 
2109
        add     edi, 52h
-
 
2110
@@:         ; record filename
-
 
2111
        lodsb
-
 
2112
        call    ansi2uni_char
-
 
2113
        stosw
-
 
2114
        dec     ecx
-
 
2115
        jnz     @b
-
 
2116
        mov     eax, [ebp+NTFS.ntfsLastRead]
-
 
2117
        mov     [ebp+NTFS.nodeLastRead], eax
-
 
2118
        cmp     [ebp+NTFS.ntfsFolder], 0
-
 
2119
        jz      @f
-
 
2120
        mov     edi, [ebp+NTFS.indexOffset]
-
 
2121
        mov     byte [edi+fileFlags+3], 16
-
 
2122
        jmp     .mftBitmap
-
 
2123
 
-
 
2124
@@: ; 3. File data
-
 
2125
        cmp     [ebp+NTFS.fileRealSize], 0
-
 
2126
        jz      .mftBitmap
-
 
2127
    ; One piece free space bitmap search engine
-
 
2128
        mov     edi, [ebp+NTFS.BitmapBuffer]
-
 
2129
        add     edi, [ebp+NTFS.BitmapStart]
-
 
2130
        mov     eax, [ebp+NTFS.fileDataSize]
-
 
2131
        shr     eax, 5
-
 
2132
        jz      .small
-
 
2133
        push    eax         ; bitmap dwords
-
 
2134
        add     edi, 4
-
 
2135
        xor     edx, edx
-
 
2136
.start:
-
 
2137
        mov     ecx, [ebp+NTFS.BitmapSize]
-
 
2138
        mov     eax, edi
-
 
2139
        sub     eax, [ebp+NTFS.BitmapBuffer]
-
 
2140
        sub     ecx, eax
-
 
2141
        shr     ecx, 2
-
 
2142
@@:
-
 
2143
        xor     eax, eax
-
 
2144
        repnz scasd         ; search for empty dword
-
 
2145
        jz      @f
-
 
2146
        call    bitmapBuffering
-
 
2147
        jmp     @b
-
 
2148
@@:
-
 
2149
        cmp     ecx, [esp]
-
 
2150
        jnc     @f
-
 
2151
        call    bitmapBuffering
-
 
2152
        jmp     @b
-
 
2153
@@:
-
 
2154
        sub     edi, 4
-
 
2155
        mov     ecx, [esp]
-
 
2156
        mov     esi, edi
-
 
2157
        xor     eax, eax
-
 
2158
        repz scasd          ; check following dwords
-
 
2159
        jnz     .start
-
 
2160
        sub     esi, 4
-
 
2161
        mov     eax, [esi]
-
 
2162
        bsr     edx, eax
-
 
2163
        inc     edx
-
 
2164
        push    edx         ; starting bit
-
 
2165
        push    esi         ; starting dword
-
 
2166
        add     esi, 4
-
 
2167
        neg     edx
-
 
2168
        add     edx, 32
-
 
2169
        mov     eax, [ebp+NTFS.fileDataSize]
-
 
2170
        sub     eax, edx
-
 
2171
        mov     edx, eax
-
 
2172
        shr     eax, 5
-
 
2173
        shl     eax, 2
-
 
2174
        add     esi, eax
-
 
2175
        mov     eax, [esi]
-
 
2176
        bsf     ecx, eax    ; last dword
-
 
2177
        jz      .done
-
 
2178
        and     edx, 31
-
 
2179
        cmp     ecx, edx
-
 
2180
        jnc     .done
-
 
2181
        add     esp, 8
-
 
2182
        jmp     .start
-
 
2183
 
-
 
2184
.small:     ; less than 32 clusters
-
 
2185
        mov     ecx, [ebp+NTFS.BitmapSize]
-
 
2186
        sub     ecx, [ebp+NTFS.BitmapStart]
-
 
2187
        shr     ecx, 2
-
 
2188
.smStart:
-
 
2189
        mov     eax, -1
-
 
2190
        repz scasd          ; search for zero bits
-
 
2191
        push    ecx
-
 
2192
        test    ecx, ecx
-
 
2193
        jnz     @f
-
 
2194
        call    bitmapBuffering
-
 
2195
        pop     eax
-
 
2196
        jmp     .smStart
-
 
2197
@@:
-
 
2198
        sub     edi, 4
-
 
2199
        mov     eax, [edi]
-
 
2200
        not     eax
-
 
2201
@@:
-
 
2202
        bsf     ecx, eax    ; first 0
-
 
2203
        jz      .again
-
 
2204
        not     eax
-
 
2205
        shr     eax, cl
-
 
2206
        shl     eax, cl
-
 
2207
        bsf     edx, eax    ; next 1
-
 
2208
        jz      @f
-
 
2209
        sub     edx, ecx
-
 
2210
        cmp     edx, [ebp+NTFS.fileDataSize]
-
 
2211
        jnc     .got        ; fits inside
-
 
2212
        bsf     ecx, eax
-
 
2213
        not     eax
-
 
2214
        shr     eax, cl
-
 
2215
        shl     eax, cl
-
 
2216
        jmp     @b
-
 
2217
@@:         ; next dword
-
 
2218
        mov     eax, [edi+4]
-
 
2219
        bsf     edx, eax
-
 
2220
        jz      .got        ; empty
-
 
2221
        add     edx, 32
-
 
2222
        sub     edx, ecx
-
 
2223
        cmp     edx, [ebp+NTFS.fileDataSize]
-
 
2224
        jnc     .got        ; share between dwords
-
 
2225
.again:
-
 
2226
        add     edi, 4
-
 
2227
        pop     ecx
-
 
2228
        jmp     .smStart
-
 
2229
 
-
 
2230
.got:
-
 
2231
        push    ecx         ; starting bit
-
 
2232
        push    edi         ; starting dword
-
 
2233
.done:      ; mark space
-
 
2234
        mov     ecx, [esp+4]
-
 
2235
        cmp     ecx, 32
-
 
2236
        jc      @f
-
 
2237
        xor     ecx, ecx
-
 
2238
        add     dword [esp], 4
-
 
2239
        mov     [esp+4], ecx
-
 
2240
@@:
-
 
2241
        mov     edi, [esp]
-
 
2242
        mov     esi, [ebp+NTFS.fileDataSize]
-
 
2243
        mov     edx, [edi]
-
 
2244
        ror     edx, cl
-
 
2245
        neg     ecx
-
 
2246
        add     ecx, 32
-
 
2247
        mov     eax, -1
-
 
2248
        sub     esi, ecx
-
 
2249
        jnc     @f
-
 
2250
        mov     esi, ecx    ; fits inside
-
 
2251
        mov     ecx, [ebp+NTFS.fileDataSize]
-
 
2252
        shrd    edx, eax, cl
-
 
2253
        sub     esi, ecx
-
 
2254
        mov     ecx, esi
-
 
2255
        ror     edx, cl
-
 
2256
        mov     [edi], edx
-
 
2257
        jmp     .writeData
-
 
2258
 
-
 
2259
@@:
-
 
2260
        shrd    edx, eax, cl
-
 
2261
        mov     [edi], edx
-
 
2262
        mov     ecx, esi
-
 
2263
        shr     ecx, 5
-
 
2264
        add     edi, 4
-
 
2265
        rep stosd
-
 
2266
        mov     ecx, esi
-
 
2267
        and     ecx, 31
-
 
2268
        mov     edx, [edi]
-
 
2269
        shr     edx, cl
-
 
2270
        shld    edx, eax, cl
-
 
2271
        mov     [edi], edx
-
 
2272
.writeData:
-
 
2273
        pop     edx
-
 
2274
        sub     edx, [ebp+NTFS.BitmapBuffer]
-
 
2275
        shl     edx, 3
-
 
2276
        pop     eax
-
 
2277
        add     eax, edx
-
 
2278
        pop     edx
-
 
2279
        mov     [ebp+NTFS.fileDataStart], eax
-
 
2280
        mul     [ebp+NTFS.sectors_per_cluster]
-
 
2281
        mov     ecx, [ebp+NTFS.fileRealSize]
-
 
2282
        add     ecx, 511
-
 
2283
        shr     ecx, 9
-
 
2284
        mov     ebx, [ebx+16]
-
 
2285
        call    fs_write64_app
-
 
2286
        test    eax, eax
-
 
2287
        jz      .mftBitmap
-
 
2288
        push    11
-
 
2289
        jmp     ntfsError
-
 
2290
 
-
 
2291
    ; 4. MFT record
-
 
2292
.mftBitmap: ; search for free record
-
 
2293
        mov     edi, [ebp+NTFS.mftBitmapBuffer]
-
 
2294
        mov     ecx, [ebp+NTFS.mftBitmapSize]
-
 
2295
        mov     al, -1
-
 
2296
        add     edi, 3
-
 
2297
        sub     ecx, 3
-
 
2298
        repz scasb
-
 
2299
        dec     edi
-
 
2300
        movzx   eax, byte [edi]
-
 
2301
        not     al
-
 
2302
        bsf     ecx, eax
-
 
2303
        jnz     @f
-
 
2304
        push    ERROR_UNSUPPORTED_FS    ; no free records
-
 
2305
        jmp     ntfsError
-
 
2306
@@:         ; mark record
-
 
2307
        mov     al, [edi]
-
 
2308
        bts     eax, ecx
-
 
2309
        mov     [edi], al
-
 
2310
    ; get record location
-
 
2311
        sub     edi, [ebp+NTFS.mftBitmapBuffer]
-
 
2312
        shl     edi, 3
-
 
2313
        add     edi, ecx
-
 
2314
        mov     [ebp+NTFS.newMftRecord], edi
-
 
2315
        mov     eax, [ebp+NTFS.frs_size]
-
 
2316
        shr     eax, 9
-
 
2317
        mul     edi
-
 
2318
        mov     [ebp+NTFS.ntfs_cur_iRecord], 0
-
 
2319
        mov     [ebp+NTFS.ntfs_cur_attr], 0x80
-
 
2320
        mov     [ebp+NTFS.ntfs_cur_offs], eax
-
 
2321
        mov     [ebp+NTFS.ntfs_cur_size], 1
-
 
2322
        mov     eax, [ebp+NTFS.frs_buffer]
-
 
2323
        mov     [ebp+NTFS.ntfs_cur_buf], eax
-
 
2324
        call    ntfs_read_attr
-
 
2325
        cmp     [ebp+NTFS.ntfs_cur_read], 0
-
 
2326
        jnz     .mftRecord
-
 
2327
    ; extend MFT $DATA
-
 
2328
        mov     eax, [ebp+NTFS.mft_cluster]
-
 
2329
        mul     [ebp+NTFS.sectors_per_cluster]
-
 
2330
        push    ERROR_UNSUPPORTED_FS
-
 
2331
        cmp     eax, [ebp+NTFS.ntfsLastRead]
-
 
2332
        jnz     ntfsError       ; auxiliary record
-
 
2333
        mov     edi, [ebp+NTFS.ntfs_attr_offs]
-
 
2334
        mov     ebx, [ebp+NTFS.sectors_per_cluster]
-
 
2335
        shl     ebx, 9+3
-
 
2336
        add     dword [edi+lastVCN], 8
-
 
2337
        add     [edi+attributeAllocatedSize], ebx
-
 
2338
        add     [edi+attributeRealSize], ebx
-
 
2339
        add     [edi+initialDataSize], ebx
-
 
2340
        add     edi, [edi+dataRunsOffset]
-
 
2341
        movzx   eax, byte [edi]
-
 
2342
        inc     edi
-
 
2343
        shl     eax, 4
-
 
2344
        shr     al, 4
-
 
2345
        mov     cl, 4
-
 
2346
        sub     cl, al
-
 
2347
        shl     cl, 3
-
 
2348
        add     ah, al
-
 
2349
        shr     eax, 8
-
 
2350
        cmp     byte [edi+eax], 0
-
 
2351
        jnz     ntfsError       ; $MFT fragmented
-
 
2352
        mov     al, 8
-
 
2353
        mov     edx, [edi]
-
 
2354
        rol     eax, cl
-
 
2355
        rol     edx, cl
-
 
2356
        add     eax, edx
-
 
2357
        jc      ntfsError
-
 
2358
        ror     eax, cl
-
 
2359
        shr     edx, cl
-
 
2360
        mov     [edi], eax
-
 
2361
        add     edx, [ebp+NTFS.mft_cluster]
-
 
2362
        mov     esi, edx
-
 
2363
        mov     ecx, edx
-
 
2364
        and     ecx, 7
-
 
2365
        shr     edx, 3
-
 
2366
        add     edx, [ebp+NTFS.BitmapBuffer]
-
 
2367
        movzx   eax, word [edx]
-
 
2368
        shr     eax, cl
-
 
2369
        jnz     ntfsError
-
 
2370
        mov     al, -1
-
 
2371
        xchg    [edx], al
-
 
2372
        mov     [edx+1], al
-
 
2373
        pop     eax
-
 
2374
        push    12
-
 
2375
        stdcall kernel_alloc, ebx
-
 
2376
        test    eax, eax
-
 
2377
        jz      ntfsError
-
 
2378
        mov     ecx, ebx
-
 
2379
        shr     ecx, 2
-
 
2380
        mov     edi, eax
-
 
2381
        push    ebx
-
 
2382
        mov     ebx, eax
-
 
2383
        xor     eax, eax
-
 
2384
        rep stosd
-
 
2385
        mov     eax, esi
-
 
2386
        mul     [ebp+NTFS.sectors_per_cluster]
-
 
2387
        pop     ecx
-
 
2388
        shr     ecx, 9
-
 
2389
        call    fs_write64_sys  ; clear new records
-
 
2390
        stdcall kernel_free, ebx
-
 
2391
        pop     eax
-
 
2392
        push    11
-
 
2393
        mov     eax, esi
-
 
2394
        shr     eax, 3+9
-
 
2395
        mov     ebx, eax
-
 
2396
        shl     ebx, 9
-
 
2397
        add     ebx, [ebp+NTFS.BitmapBuffer]
-
 
2398
        add     eax, [ebp+NTFS.BitmapLocation]
-
 
2399
        mov     ecx, 1
-
 
2400
        xor     edx, edx
-
 
2401
        call    fs_write64_app  ; partition bitmap
-
 
2402
        test    eax, eax
-
 
2403
        jnz     ntfsError
-
 
2404
        mov     eax, [ebp+NTFS.frs_buffer]
-
 
2405
        mov     [ebp+NTFS.ntfs_cur_buf], eax
-
 
2406
        call    writeRecord     ; $MFT
-
 
2407
        test    eax, eax
-
 
2408
        jnz     ntfsError
-
 
2409
        mov     eax, [ebp+NTFS.mftmirr_cluster]
-
 
2410
        mul     [ebp+NTFS.sectors_per_cluster]
-
 
2411
        mov     ebx, [ebp+NTFS.frs_buffer]
-
 
2412
        movzx   ecx, word [ebx+updateSequenceSize]
-
 
2413
        dec     ecx
-
 
2414
        call    fs_write64_sys  ; $MFTMirr
-
 
2415
        test    eax, eax
-
 
2416
        jnz     ntfsError
-
 
2417
        pop     eax
-
 
2418
        mov     eax, [ebp+NTFS.ntfs_cur_offs]
-
 
2419
        add     [ebp+NTFS.ntfsLastRead], eax
-
 
2420
.mftRecord:
-
 
2421
        mov     esi, [ebp+NTFS.indexOffset]
-
 
2422
        mov     edi, [ebp+NTFS.frs_buffer]
-
 
2423
        xor     eax, eax
-
 
2424
        movzx   ecx, word [esi+indexAllocatedSize]
-
 
2425
        add     ecx, 8+30h+48h+50h+8
-
 
2426
        push    ecx
-
 
2427
        shr     ecx, 2
-
 
2428
        rep stosd
-
 
2429
        mov     edi, [ebp+NTFS.frs_buffer]
-
 
2430
    ; record header
-
 
2431
        mov     dword[edi], 'FILE'
-
 
2432
        mov     byte [edi+updateSequenceOffset], 2ah
-
 
2433
        mov     byte [edi+updateSequenceSize], 3
-
 
2434
        mov     byte [edi+hardLinkCounter], 1
-
 
2435
        mov     byte [edi+attributeOffset], 30h
-
 
2436
        pop     dword[edi+recordRealSize]
-
 
2437
        mov     word [edi+recordAllocatedSize], 1024
-
 
2438
        mov     byte [edi+newAttributeID], 3
-
 
2439
        rdtsc
-
 
2440
        mov     [edi+2ah], ax
-
 
2441
        add     edi, 30h
-
 
2442
    ; $StandardInformation
-
 
2443
        mov     byte [edi+attributeType], 10h
-
 
2444
        mov     byte [edi+sizeWithHeader], 48h
-
 
2445
        mov     byte [edi+sizeWithoutHeader], 30h
-
 
2446
        mov     byte [edi+attributeOffset], 18h
-
 
2447
        add     edi, 48h
-
 
2448
    ; $FileName
-
 
2449
        mov     byte [edi+attributeType], 30h
-
 
2450
        mov     byte [edi+attributeID], 1
-
 
2451
        mov     cx, [esi+indexRawSize]
-
 
2452
        mov     [edi+sizeWithoutHeader], ecx
-
 
2453
        mov     cx, [esi+indexAllocatedSize]
-
 
2454
        add     ecx, 8
-
 
2455
        mov     [edi+sizeWithHeader], ecx
-
 
2456
        mov     byte [edi+attributeOffset], 18h
-
 
2457
        mov     byte [edi+attributeFlags], 1
-
 
2458
        add     edi, 18h
-
 
2459
        add     esi, 16
-
 
2460
        sub     ecx, 18h
-
 
2461
        shr     ecx, 2
-
 
2462
        rep movsd
-
 
2463
        cmp     [ebp+NTFS.ntfsFolder], 0
-
 
2464
        jnz     @f
-
 
2465
    ; $Data
-
 
2466
        mov     byte [edi+attributeType], 80h
-
 
2467
        cmp     [ebp+NTFS.fileRealSize], 0
-
 
2468
        jz      .zeroSize
-
 
2469
        mov     esi, [ebp+NTFS.indexOffset]
-
 
2470
        mov     byte [edi+nonResidentFlag], 1
-
 
2471
        mov     byte [edi+dataRunsOffset], 40h
-
 
2472
        mov     eax, [esi+fileAllocatedSize]
-
 
2473
        mov     [edi+attributeAllocatedSize], eax
-
 
2474
        mov     eax, [esi+fileRealSize]
-
 
2475
        mov     [edi+attributeRealSize], eax
-
 
2476
        mov     [edi+initialDataSize], eax
-
 
2477
        mov     byte [edi+40h], 44h
-
 
2478
        mov     eax, [ebp+NTFS.fileDataSize]
-
 
2479
        mov     [edi+41h], eax
-
 
2480
        dec     eax
-
 
2481
        mov     [edi+lastVCN], eax
-
 
2482
        mov     eax, [ebp+NTFS.fileDataStart]
-
 
2483
        mov     [edi+45h], eax
-
 
2484
        mov     al, 1
-
 
2485
        jmp     .writeMftRecord
-
 
2486
 
-
 
2487
.zeroSize:
-
 
2488
        mov     byte [edi+attributeOffset], 18h
-
 
2489
        mov     al, 1
-
 
2490
        jmp     .writeMftRecord
-
 
2491
 
-
 
2492
@@: ; $IndexRoot
-
 
2493
        mov     byte [edi+attributeType], 90h
-
 
2494
        mov     byte [edi+nameLength], 4
-
 
2495
        mov     byte [edi+nameOffset], 18h
-
 
2496
        mov     byte [edi+sizeWithoutHeader], 30h
-
 
2497
        mov     byte [edi+attributeOffset], 20h
-
 
2498
        mov     dword[edi+18h], 490024h     ; unicode $I30
-
 
2499
        mov     dword[edi+18h+4], 300033h
-
 
2500
        add     edi, 20h
-
 
2501
        mov     byte [edi+attributeType], 30h
-
 
2502
        mov     byte [edi+collationRule], 1
-
 
2503
        mov     eax, [ebp+NTFS.sectors_per_cluster]
-
 
2504
        shl     eax, 9
-
 
2505
        mov     [edi+indexRecordSize], eax
-
 
2506
        mov     byte [edi+indexRecordSizeClus], 1
-
 
2507
        mov     byte [edi+16+indexOffset], 16
-
 
2508
        mov     byte [edi+16+nodeRealSize], 32
-
 
2509
        mov     byte [edi+16+nodeAllocatedSize], 32
-
 
2510
        mov     byte [edi+32+indexAllocatedSize], 16
-
 
2511
        mov     byte [edi+32+indexFlags], 2
-
 
2512
        sub     edi, 20h
-
 
2513
        mov     al, 3
-
 
2514
.writeMftRecord:
-
 
2515
        mov     byte [edi+sizeWithHeader], 50h
-
 
2516
        mov     byte [edi+attributeID], 2
-
 
2517
        mov     dword[edi+50h], -1      ; $End
-
 
2518
        mov     edi, [ebp+NTFS.frs_buffer]
-
 
2519
        mov     [edi+recordFlags], al
-
 
2520
        mov     [ebp+NTFS.ntfs_cur_buf], edi
-
 
2521
        call    writeRecord
-
 
2522
        test    eax, eax
-
 
2523
        jz      @f
-
 
2524
        push    11
-
 
2525
        jmp     ntfsError
-
 
2526
@@:
-
 
2527
        mov     esi, [ebp+PARTITION.Disk]
-
 
2528
        call    disk_sync
-
 
2529
    ; write MFT bitmap
-
 
2530
        mov     eax, [ebp+NTFS.newMftRecord]
-
 
2531
        shr     eax, 3+9
-
 
2532
        mov     ebx, eax
-
 
2533
        shl     ebx, 9
-
 
2534
        add     eax, [ebp+NTFS.mftBitmapLocation]
-
 
2535
        add     ebx, [ebp+NTFS.mftBitmapBuffer]
-
 
2536
        mov     ecx, 1
-
 
2537
        xor     edx, edx
-
 
2538
        call    fs_write64_sys
-
 
2539
        test    eax, eax
-
 
2540
        jz      @f
-
 
2541
        push    11
-
 
2542
        jmp     ntfsError
-
 
2543
@@: ; 5. Write partition bitmap
-
 
2544
        cmp     [ebp+NTFS.ntfsFolder], 0
-
 
2545
        jnz     @f
-
 
2546
        cmp     [ebp+NTFS.fileRealSize], 0
-
 
2547
        jz      @f
-
 
2548
        mov     ecx, [ebp+NTFS.fileDataStart]
-
 
2549
        mov     eax, ecx
-
 
2550
        add     ecx, [ebp+NTFS.fileDataSize]
-
 
2551
        add     ecx, 4095
-
 
2552
        shr     ecx, 3+9
-
 
2553
        shr     eax, 3+9
-
 
2554
        sub     ecx, eax
-
 
2555
        mov     ebx, eax
-
 
2556
        shl     ebx, 9
-
 
2557
        add     eax, [ebp+NTFS.BitmapLocation]
-
 
2558
        add     ebx, [ebp+NTFS.BitmapBuffer]
-
 
2559
        xor     edx, edx
-
 
2560
        call    fs_write64_app
-
 
2561
        test    eax, eax
-
 
2562
        jz      @f
-
 
2563
        push    11
-
 
2564
        jmp     ntfsError
-
 
2565
@@:
-
 
2566
        mov     esi, [ebp+PARTITION.Disk]
-
 
2567
        call    disk_sync
-
 
2568
        mov     edi, [ebp+NTFS.indexOffset]
-
 
2569
        mov     eax, [ebp+NTFS.newMftRecord]
-
 
2570
        mov     [edi+fileRecordReference], eax
-
 
2571
    ; 6. Write directory node
-
 
2572
        mov     eax, [ebp+NTFS.nodeLastRead]
-
 
2573
        mov     [ebp+NTFS.ntfsLastRead], eax
-
 
2574
        mov     eax, [ebp+NTFS.cur_index_buf]
-
 
2575
        mov     [ebp+NTFS.ntfs_cur_buf], eax
-
 
2576
        call    writeRecord
-
 
2577
        push    eax
-
 
2578
        mov     esi, [ebp+PARTITION.Disk]
-
 
2579
        call    disk_sync
-
 
2580
        call    ntfs_unlock
-
 
2581
        pop     eax
1872
        mov     eax, ERROR_UNSUPPORTED_FS
2582
        mov     ebx, [ebp+NTFS.fileRealSize]
Line -... Line 2583...
-
 
2583
        ret
-
 
2584
 
-
 
2585
writeRecord:
-
 
2586
;   in:
-
 
2587
; [ebp+NTFS.ntfs_cur_buf] = record
-
 
2588
; [ebp+NTFS.ntfsLastRead] = partition sector
-
 
2589
    ; making updateSequence
1873
        ret
2590
        mov     esi, [ebp+NTFS.ntfs_cur_buf]
-
 
2591
        mov     edi, esi
-
 
2592
        movzx   ecx, word [esi+updateSequenceOffset]
-
 
2593
        add     edi, ecx
-
 
2594
        mov     ax, [edi]
-
 
2595
        add     edi, 2
-
 
2596
        mov     cx, [esi+updateSequenceSize]
-
 
2597
        dec     ecx
-
 
2598
        push    ecx
-
 
2599
@@:
-
 
2600
        add     esi, 510
-
 
2601
        movsw
-
 
2602
        mov     [esi-2], ax
-
 
2603
        dec     ecx
-
 
2604
        jnz     @b
-
 
2605
    ; writing to disk
-
 
2606
        mov     eax, [ebp+NTFS.ntfsLastRead]
-
 
2607
        mov     ebx, [ebp+NTFS.ntfs_cur_buf]
-
 
2608
        pop     ecx
-
 
2609
        xor     edx, edx
-
 
2610
        jmp     fs_write64_sys
-
 
2611
 
1874
 
2612
bitmapBuffering:
-
 
2613
; Extend BitmapBuffer and read next 32kb of bitmap
-
 
2614
; Warning: $Bitmap fragmentation is not foreseen
-
 
2615
        push    ebx
-
 
2616
        mov     eax, [ebp+NTFS.BitmapTotalSize]
-
 
2617
        cmp     eax, [ebp+NTFS.BitmapSize]
-
 
2618
        jz      .end
-
 
2619
        stdcall alloc_pages, 8
-
 
2620
        test    eax, eax
-
 
2621
        jz      .end
-
 
2622
        add     eax, 3
-
 
2623
        mov     ebx, [ebp+NTFS.BitmapBuffer]
-
 
2624
        add     ebx, [ebp+NTFS.BitmapSize]
-
 
2625
        push    ebx
-
 
2626
        mov     ecx, 8
-
 
2627
        call    commit_pages
-
 
2628
        mov     eax, [ebp+NTFS.BitmapSize]
-
 
2629
        shr     eax, 9
-
 
2630
        add     eax, [ebp+NTFS.BitmapLocation]
-
 
2631
        pop     ebx
-
 
2632
        mov     ecx, 64
-
 
2633
        xor     edx, edx
-
 
2634
        call    fs_read64_app
-
 
2635
        test    eax, eax
-
 
2636
        jnz     .err
1875
;----------------------------------------------------------------
2637
        add     [ebp+NTFS.BitmapSize], 8000h
-
 
2638
        mov     eax, [ebp+NTFS.BitmapTotalSize]
-
 
2639
        cmp     eax, [ebp+NTFS.BitmapSize]
-
 
2640
        jnc     @f
-
 
2641
        mov     [ebp+NTFS.BitmapSize], eax
-
 
2642
@@:
-
 
2643
        mov     ecx, [ebp+NTFS.BitmapSize]
1876
; ntfs_Write - NTFS implementation of writing to file
2644
        mov     eax, edi
-
 
2645
        sub     eax, [ebp+NTFS.BitmapBuffer]
-
 
2646
        sub     ecx, eax
-
 
2647
        shr     ecx, 2
-
 
2648
        pop     ebx
-
 
2649
        ret
1877
; in:  ebp = pointer to NTFS structure
2650
 
-
 
2651
.err:
-
 
2652
        mov     eax, [ebp+NTFS.BitmapBuffer]
-
 
2653
        add     eax, [ebp+NTFS.BitmapSize]
-
 
2654
        mov     ecx, 8
1878
; in:  esi+[esp+4] = name
2655
        call    release_pages
-
 
2656
.end:
-
 
2657
        add     esp, 12     ; double ret
-
 
2658
        push    ERROR_DISK_FULL
1879
; in:  ebx = pointer to parameters from sysfunc 70
2659
        jmp     ntfsError
1880
; out: eax, ebx = return values for sysfunc 70
2660
 
1881
;----------------------------------------------------------------
2661
;----------------------------------------------------------------
1882
ntfs_Write:
2662
ntfs_Write:
1883
        xor     ebx, ebx
2663
        xor     ebx, ebx
Line -... Line 2664...
-
 
2664
        mov     eax, ERROR_UNSUPPORTED_FS
1884
        mov     eax, ERROR_UNSUPPORTED_FS
2665
        ret
1885
        ret
2666
 
1886
 
2667
;----------------------------------------------------------------
1887
ntfs_SetFileEnd:
2668
ntfs_SetFileEnd:
1888
ntfs_SetFileInfo:
2669
ntfs_SetFileInfo:
Line 1889... Line 2670...
1889
ntfs_Delete:
2670
ntfs_Delete:
1890
        mov     eax, ERROR_UNSUPPORTED_FS
-
 
1891
        ret
-
 
1892
 
-
 
1893
;----------------------------------------------------------------
-
 
1894
; ntfs_GetFileInfo - NTFS implementation of getting file info
-
 
1895
; in:  ebp = pointer to NTFS structure
-
 
1896
; in:  esi+[esp+4] = name
2671
        mov     eax, ERROR_UNSUPPORTED_FS
1897
; in:  ebx = pointer to parameters from sysfunc 70
2672
        ret
1898
; out: eax, ebx = return values for sysfunc 70
2673
 
1899
;----------------------------------------------------------------
2674
;----------------------------------------------------------------
1900
ntfs_GetFileInfo:
2675
ntfs_GetFileInfo:
1901
        cmp     byte [esi], 0
2676
        cmp     byte [esi], 0
1902
        jnz     @f
2677
        jnz     @f
1903
        movi    eax, 2
2678
        movi    eax, 2
1904
        ret
2679
        ret
1905
@@:
2680
@@:
1906
        call    ntfs_lock
2681
        call    ntfs_lock
1907
        stdcall ntfs_find_lfn, [esp+4]
2682
        stdcall ntfs_find_lfn, [esp+4]
1908
        jnc     .doit
-
 
1909
        test    eax, eax
-
 
1910
        movi    eax, ERROR_FILE_NOT_FOUND
-
 
1911
        jz      @f
-
 
1912
        mov     al, 11
2683
        jnc     .doit
1913
@@:
2684
        test    eax, eax
-
 
2685
        push    ERROR_FILE_NOT_FOUND
1914
        push    eax
2686
        jz      ntfsError
1915
        call    ntfs_unlock
2687
        pop     eax
1916
        pop     eax
2688
        push    11
1917
        ret
2689
        jmp     ntfsError
1918
.doit:
2690
.doit:
Line 1924... Line 2696...
1924
        pop     edi esi
2696
        pop     edi esi
1925
        call    ntfs_unlock
2697
        call    ntfs_unlock
1926
        xor     eax, eax
2698
        xor     eax, eax
1927
        ret
2699
        ret
Line -... Line 2700...
-
 
2700
 
-
 
2701
ntfsError:
-
 
2702
        call    ntfs_unlock
-
 
2703
        xor     ebx, ebx
-
 
2704
        pop     eax