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