Subversion Repositories Kolibri OS

Rev

Rev 6292 | Rev 6340 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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