Rev 3359 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3359 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2382 | hidnplayr | 2 | ;; ;; |
3359 | hidnplayr | 3 | ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; 02.02.2010 turbanoff - support 70.5 ;; |
||
6 | ;; 23.01.2010 turbanoff - support 70.0 70.1 ;; |
||
2382 | hidnplayr | 7 | ;; ;; |
3359 | hidnplayr | 8 | ;; ;; |
2382 | hidnplayr | 9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
10 | |||
11 | $Revision: 2381 $ |
||
3359 | hidnplayr | 12 | |
13 | EXT2_BAD_INO = 1 |
||
14 | EXT2_ROOT_INO = 2 |
||
15 | EXT2_ACL_IDX_INO = 3 |
||
16 | EXT2_ACL_DATA_INO = 4 |
||
17 | EXT2_BOOT_LOADER_INO = 5 |
||
18 | EXT2_UNDEL_DIR_INO = 6 |
||
19 | |||
20 | ;флаги, указываемый в inode файла |
||
21 | EXT2_S_IFREG = 0x8000 |
||
22 | EXT2_S_IFDIR = 0x4000 |
||
23 | EXT2_S_IFMT = 0xF000 ;маска для типа файла |
||
24 | |||
25 | ;флаги, указываемые в linked list родительской папки |
||
26 | EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге |
||
27 | EXT2_FT_DIR = 2 ;это папка |
||
28 | |||
29 | ;флаги используемые KolibriOS |
||
30 | FS_FT_HIDDEN = 2 |
||
31 | FS_FT_DIR = 0x10 ;это папка |
||
32 | FS_FT_ASCII = 0 ;имя в ascii |
||
33 | FS_FT_UNICODE = 1 ;имя в unicode |
||
34 | |||
35 | EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;тип файла должен указываться в директории |
||
36 | EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;экстенты |
||
37 | EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;гибкие группы блоков |
||
38 | ;реализованные ext[234] features |
||
39 | EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \ |
||
40 | or EXT4_FEATURE_INCOMPAT_EXTENTS \ |
||
41 | or EXT4_FEATURE_INCOMPAT_FLEX_BG |
||
42 | |||
43 | |||
44 | ;флаги, указываемые для inode в i_flags |
||
45 | EXT2_EXTENTS_FL = 0x00080000 |
||
46 | |||
47 | struct EXT2_INODE_STRUC |
||
2382 | hidnplayr | 48 | i_mode dw ? |
49 | i_uid dw ? |
||
50 | i_size dd ? |
||
51 | i_atime dd ? |
||
52 | i_ctime dd ? |
||
53 | i_mtime dd ? |
||
54 | i_dtime dd ? |
||
55 | i_gid dw ? |
||
56 | i_links_count dw ? |
||
57 | i_blocks dd ? |
||
58 | i_flags dd ? |
||
59 | i_osd1 dd ? |
||
60 | i_block rd 15 |
||
61 | i_generation dd ? |
||
62 | i_file_acl dd ? |
||
63 | i_dir_acl dd ? |
||
64 | i_faddr dd ? |
||
65 | i_osd2 dd ? ; 1..12 |
||
66 | ends |
||
67 | |||
68 | struct EXT2_DIR_STRUC |
||
69 | inode dd ? |
||
70 | rec_len dw ? |
||
71 | name_len db ? |
||
72 | file_type db ? |
||
73 | name db ? ; 0..255 |
||
3359 | hidnplayr | 74 | ends |
75 | |||
76 | struct EXT2_BLOCK_GROUP_DESC |
||
77 | block_bitmap dd ? ;+0 |
||
78 | inode_bitmap dd ? ;+4 |
||
79 | inode_table dd ? ;+8 |
||
80 | free_blocks_count dw ? ;+12 |
||
81 | free_inodes_count dw ? ;+14 |
||
82 | used_dirs_count dw ? ;+16 |
||
83 | pad dw ? ;+18 |
||
84 | reserved rb 12;+20 |
||
85 | ends |
||
86 | |||
87 | struct EXT2_SB_STRUC |
||
2382 | hidnplayr | 88 | inodes_count dd ? ;+0 |
89 | blocks_count dd ? ;+4 |
||
90 | r_block_count dd ? ;+8 |
||
91 | free_block_count dd ? ;+12 |
||
92 | free_inodes_count dd ? ;+16 |
||
93 | first_data_block dd ? ;+20 |
||
94 | log_block_size dd ? ;+24 |
||
95 | log_frag_size dd ? ;+28 |
||
96 | blocks_per_group dd ? ;+32 |
||
97 | frags_per_group dd ? ;+36 |
||
98 | inodes_per_group dd ? ;+40 |
||
99 | mtime dd ? ;+44 |
||
100 | wtime dd ? ;+48 |
||
101 | mnt_count dw ? ;+52 |
||
102 | max_mnt_count dw ? ;+54 |
||
103 | magic dw ? ;+56 |
||
104 | state dw ? ;+58 |
||
105 | errors dw ? ;+60 |
||
106 | minor_rev_level dw ? ;+62 |
||
107 | lastcheck dd ? ;+64 |
||
108 | check_intervals dd ? ;+68 |
||
109 | creator_os dd ? ;+72 |
||
110 | rev_level dd ? ;+76 |
||
111 | def_resuid dw ? ;+80 |
||
112 | def_resgid dw ? ;+82 |
||
113 | first_ino dd ? ;+84 |
||
114 | inode_size dw ? ;+88 |
||
115 | block_group_nr dw ? ;+90 |
||
116 | feature_compat dd ? ;+92 |
||
117 | feature_incompat dd ? ;+96 |
||
118 | feature_ro_compat dd ? ;+100 |
||
119 | uuid rb 16 ;+104 |
||
120 | volume_name rb 16 ;+120 |
||
121 | last_mounted rb 64 ;+136 |
||
3359 | hidnplayr | 122 | algo_bitmap dd ? ;+200 |
123 | prealloc_blocks db ? ;+204 |
||
124 | preallock_dir_blocks db ? ;+205 |
||
125 | reserved_gdt_blocks dw ? ;+206 |
||
126 | journal_uuid rb 16 ;+208 |
||
127 | journal_inum dd ? ;+224 |
||
128 | journal_dev dd ? ;+228 |
||
2382 | hidnplayr | 129 | last_orphan dd ? ;+232 |
130 | hash_seed rd 4 ;+236 |
||
131 | def_hash_version db ? ;+252 |
||
3359 | hidnplayr | 132 | rb 3 ;+253 reserved |
133 | default_mount_options dd ? ;+256 |
||
134 | first_meta_bg dd ? ;+260 |
||
135 | mkfs_time dd ? ;+264 |
||
136 | jnl_blocks rd 17 ;+268 |
||
137 | blocks_count_hi dd ? ;+336 |
||
138 | r_blocks_count_hi dd ? ;+340 |
||
139 | free_blocks_count_hi dd ? ;+344 |
||
140 | min_extra_isize dw ? ;+348 |
||
141 | want_extra_isize dw ? ;+350 |
||
142 | flags dd ? ;+352 |
||
143 | raid_stride dw ? ;+356 |
||
144 | mmp_interval dw ? ;+358 |
||
145 | mmp_block dq ? ;+360 |
||
146 | raid_stripe_width dd ? ;+368 |
||
147 | log_groups_per_flex db ? ;+372 |
||
148 | ends |
||
2382 | hidnplayr | 149 | |
3359 | hidnplayr | 150 | struct EXT4_EXTENT_HEADER ;заголовок блока экстентов/индексов |
151 | eh_magic dw ? ;в текущей реализации ext4 должно быть 0xF30A |
||
152 | eh_entries dw ? ;количество экстентов/индексов в блоке |
||
153 | eh_max dw ? ;max количество (используется при записи) |
||
154 | eh_depth dw ? ;глубина дерева (0, если это блок экстентов) |
||
155 | eh_generation dd ? ;??? |
||
156 | ends |
||
157 | |||
158 | struct EXT4_EXTENT ;экстент |
||
159 | ee_block dd ? ;номер ext4 блока |
||
160 | ee_len dw ? ;длина экстента |
||
161 | ee_start_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS) |
||
162 | ee_start_lo dd ? ;младшие 32 бита 48-битного адреса |
||
163 | ends |
||
164 | |||
165 | struct EXT4_EXTENT_IDX ;индес - указатель на блок с экстентами/индексами |
||
166 | ei_block dd ? ;номер ext4 блока |
||
167 | ei_leaf_lo dd ? ;младшие 32 бит 48-битного адреса |
||
168 | ei_leaf_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS) |
||
169 | ei_unused dw ? ;зарезервировано |
||
170 | ends |
||
171 | |||
172 | ext2_test_superblock: |
||
173 | cmp [fs_type], 0x83 |
||
174 | jne .no |
||
175 | |||
2382 | hidnplayr | 176 | mov eax, [PARTITION_START] |
3359 | hidnplayr | 177 | add eax, 2 ;superblock start at 1024b |
178 | call hd_read |
||
179 | |||
180 | cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 ;0,1,2,3 |
||
181 | ja .no |
||
182 | cmp [ebx + EXT2_SB_STRUC.magic], 0xEF53 |
||
183 | jne .no |
||
184 | cmp [ebx + EXT2_SB_STRUC.state], 1 ;EXT_VALID_FS=1 |
||
185 | jne .no |
||
186 | cmp [ebx + EXT2_SB_STRUC.inodes_per_group], 0 |
||
187 | je .no |
||
188 | |||
189 | mov eax, [ebx + EXT2_SB_STRUC.feature_incompat] |
||
190 | test eax, EXT2_FEATURE_INCOMPAT_FILETYPE |
||
191 | jz .no |
||
192 | test eax, not EXT4_FEATURE_INCOMPAT_SUPP |
||
193 | jnz .no |
||
194 | |||
195 | ; OK, this is correct EXT2 superblock |
||
2382 | hidnplayr | 196 | clc |
197 | ret |
||
198 | .no: |
||
199 | ; No, this superblock isn't EXT2 |
||
200 | stc |
||
201 | ret |
||
202 | |||
203 | ext2_setup: |
||
204 | mov [fs_type], 2 |
||
205 | |||
206 | push 512 |
||
207 | call kernel_alloc ; mem for superblock |
||
208 | mov esi, ebx |
||
209 | mov edi, eax |
||
210 | mov ecx, 512/4 |
||
211 | rep movsd ; copy sb to reserved mem |
||
212 | mov ebx, eax |
||
213 | mov [ext2_data.sb], eax |
||
214 | |||
215 | mov eax, [ebx + EXT2_SB_STRUC.blocks_count] |
||
216 | sub eax, [ebx + EXT2_SB_STRUC.first_data_block] |
||
217 | dec eax |
||
218 | xor edx, edx |
||
219 | div [ebx + EXT2_SB_STRUC.blocks_per_group] |
||
3359 | hidnplayr | 220 | inc eax |
221 | mov [ext2_data.groups_count], eax |
||
222 | |||
223 | mov ecx, [ebx + EXT2_SB_STRUC.log_block_size] |
||
224 | inc ecx |
||
225 | mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb |
||
226 | |||
2382 | hidnplayr | 227 | mov eax, 1 |
228 | shl eax, cl |
||
229 | mov [ext2_data.count_block_in_block], eax |
||
230 | |||
231 | shl eax, 7 |
||
232 | mov [ext2_data.count_pointer_in_block], eax |
||
233 | mov edx, eax ; потом еще квадрат найдем |
||
234 | |||
235 | shl eax, 2 |
||
236 | mov [ext2_data.block_size], eax |
||
237 | |||
238 | push eax eax ; 2 kernel_alloc |
||
239 | |||
240 | mov eax, edx |
||
241 | mul edx |
||
242 | mov [ext2_data.count_pointer_in_block_square], eax |
||
243 | |||
244 | call kernel_alloc |
||
245 | mov [ext2_data.ext2_save_block], eax ; and for temp block |
||
3359 | hidnplayr | 246 | call kernel_alloc |
247 | mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc |
||
248 | |||
249 | movzx ebp, word [ebx + EXT2_SB_STRUC.inode_size] |
||
250 | mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group] |
||
251 | |||
252 | mov [ext2_data.inode_size], ebp |
||
253 | mov [ext2_data.blocks_per_group], ecx |
||
254 | |||
255 | push ebp ebp ebp ;3 kernel_alloc |
||
256 | call kernel_alloc |
||
2382 | hidnplayr | 257 | mov [ext2_data.ext2_save_inode], eax |
258 | call kernel_alloc |
||
259 | mov [ext2_data.ext2_temp_inode], eax |
||
260 | call kernel_alloc |
||
261 | mov [ext2_data.root_inode], eax |
||
262 | |||
263 | mov ebx, eax |
||
264 | mov eax, EXT2_ROOT_INO |
||
265 | call ext2_get_inode ; read root inode |
||
266 | |||
3359 | hidnplayr | 267 | jmp return_from_part_set |
268 | |||
269 | ;================================================================== |
||
270 | ;read ext2 block form FS to memory |
||
271 | ;in: eax = i_block (address of block in ext2 terms) |
||
272 | ; ebx = pointer to return memory |
||
273 | ;out: eax - error code (0 = no_error) |
||
274 | ext2_get_block: |
||
275 | push ebx ecx |
||
276 | mov ecx, [ext2_data.log_block_size] |
||
277 | shl eax, cl |
||
278 | add eax, [PARTITION_START] |
||
279 | mov ecx, [ext2_data.count_block_in_block] |
||
280 | @@: |
||
281 | call hd_read |
||
282 | cmp [hd_error], 0 |
||
283 | jnz .fail |
||
284 | inc eax |
||
285 | add ebx, 512 |
||
286 | loop @B |
||
287 | xor eax, eax |
||
288 | @@: |
||
289 | pop ecx ebx |
||
290 | ret |
||
291 | .fail: |
||
292 | mov eax, ERROR_DEVICE |
||
293 | jmp @B |
||
294 | |||
295 | |||
296 | ;=================================================================== |
||
297 | ;получает номер блока из extent inode |
||
298 | ;in: ecx = номер блока по порядку |
||
299 | ; ebp = адрес extent header`а |
||
300 | ;out: ecx - адрес очередного блока в случае успеха |
||
301 | ; eax - номер ошибки (если равно 0, то ошибки нет) |
||
302 | ext4_block_recursive_search: |
||
303 | cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC |
||
304 | jne .fail |
||
305 | |||
306 | movzx ebx, [ebp + EXT4_EXTENT_HEADER.eh_entries] |
||
307 | add ebp, sizeof.EXT4_EXTENT_HEADER |
||
308 | cmp word [ebp - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0 |
||
309 | je .leaf_block ;листовой ли это блок? |
||
310 | |||
311 | ;не листовой блок, а индексный ; eax - ext4_extent_idx |
||
312 | test ebx, ebx |
||
313 | jz .fail ;пустой индексный блок -> ошибка |
||
314 | |||
315 | ;цикл по индексам экстентов |
||
316 | @@: |
||
317 | cmp ebx, 1 ;у индексов не хранится длина, |
||
318 | je .end_search_index ;поэтому, если остался последний - то это нужный |
||
319 | |||
320 | cmp ecx, [ebp + EXT4_EXTENT_IDX.ei_block] |
||
321 | jb .fail |
||
322 | |||
323 | cmp ecx, [ebp + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса |
||
324 | jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен |
||
325 | |||
326 | add ebp, sizeof.EXT4_EXTENT_IDX |
||
327 | dec ebx |
||
328 | jmp @B |
||
329 | |||
330 | .end_search_index: |
||
331 | ;ebp указывает на нужный extent_idx, считываем следующий блок |
||
332 | mov ebx, [ext2_data.ext2_temp_block] |
||
333 | mov eax, [ebp + EXT4_EXTENT_IDX.ei_leaf_lo] |
||
334 | call ext2_get_block |
||
335 | test eax, eax |
||
336 | jnz .fail |
||
337 | mov ebp, ebx |
||
338 | jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало |
||
339 | |||
340 | .leaf_block: ;листовой блок ebp - ext4_extent |
||
341 | ;цикл по экстентам |
||
342 | @@: |
||
343 | test ebx, ebx |
||
344 | jz .fail ;ни один узел не подошел - ошибка |
||
345 | |||
346 | mov edx, [ebp + EXT4_EXTENT.ee_block] |
||
347 | cmp ecx, edx |
||
348 | jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка |
||
349 | |||
350 | movzx edi, [ebp + EXT4_EXTENT.ee_len] |
||
351 | add edx, edi |
||
352 | cmp ecx, edx |
||
353 | jb .end_search_extent ;нашли нужный блок |
||
354 | |||
355 | add ebp, sizeof.EXT4_EXTENT |
||
356 | dec ebx |
||
357 | jmp @B |
||
358 | |||
359 | .end_search_extent: |
||
360 | mov edx, [ebp + EXT4_EXTENT.ee_start_lo] |
||
361 | sub ecx, [ebp + EXT4_EXTENT.ee_block] ;разница в ext4 блоках |
||
362 | add ecx, edx |
||
363 | xor eax, eax |
||
364 | ret |
||
365 | |||
366 | .fail: |
||
367 | mov eax, ERROR_FS_FAIL |
||
368 | ret |
||
369 | |||
370 | ;=================================================================== |
||
371 | ;получает адрес ext2 блока из inode с определнным номером |
||
372 | ;in: ecx = номер блока в inode (0..) |
||
373 | ; ebp = адрес inode |
||
374 | ;out: ecx = адрес очередного блока |
||
375 | ; eax - error code |
||
376 | ext2_get_inode_block: |
||
377 | test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL |
||
378 | jz @F |
||
379 | |||
380 | pushad |
||
381 | add ebp, EXT2_INODE_STRUC.i_block ;ebp - extent_header |
||
382 | call ext4_block_recursive_search |
||
383 | mov PUSHAD_ECX, ecx |
||
384 | mov PUSHAD_EAX, eax |
||
385 | popad |
||
386 | ret |
||
387 | |||
388 | @@: |
||
389 | cmp ecx, 12 ; 0..11 - direct block address |
||
390 | jb .get_direct_block |
||
391 | |||
392 | sub ecx, 12 |
||
393 | cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect blocks |
||
394 | jb .get_indirect_block |
||
395 | |||
396 | sub ecx, [ext2_data.count_pointer_in_block] |
||
2382 | hidnplayr | 397 | cmp ecx, [ext2_data.count_pointer_in_block_square] |
3359 | hidnplayr | 398 | jb .get_double_indirect_block |
399 | |||
400 | sub ecx, [ext2_data.count_pointer_in_block_square] |
||
401 | ;triple indirect block |
||
402 | push edx ebx |
||
403 | |||
404 | mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] |
||
405 | mov ebx, [ext2_data.ext2_temp_block] |
||
406 | call ext2_get_block |
||
407 | test eax, eax |
||
408 | jnz .fail |
||
409 | |||
410 | xor edx, edx |
||
411 | mov eax, ecx |
||
2382 | hidnplayr | 412 | div [ext2_data.count_pointer_in_block_square] |
413 | |||
3359 | hidnplayr | 414 | ;eax - номер в полученном блоке edx - номер дальше |
415 | mov eax, [ebx + eax*4] |
||
416 | call ext2_get_block |
||
417 | test eax, eax |
||
418 | jnz .fail |
||
419 | |||
420 | mov eax, edx |
||
421 | jmp @F |
||
422 | |||
423 | .get_double_indirect_block: |
||
424 | push edx ebx |
||
425 | |||
426 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] |
||
427 | mov ebx, [ext2_data.ext2_temp_block] |
||
428 | call ext2_get_block |
||
429 | test eax, eax |
||
430 | jnz .fail |
||
431 | |||
432 | mov eax, ecx |
||
433 | @@: |
||
434 | xor edx, edx |
||
435 | div [ext2_data.count_pointer_in_block] |
||
436 | |||
437 | mov eax, [ebx + eax*4] |
||
438 | call ext2_get_block |
||
439 | test eax, eax |
||
440 | jnz .fail |
||
441 | |||
442 | mov ecx, [ebx + edx*4] |
||
443 | .fail: |
||
444 | pop ebx edx |
||
445 | ret |
||
446 | |||
447 | .get_indirect_block: |
||
448 | push ebx |
||
449 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] |
||
450 | mov ebx, [ext2_data.ext2_temp_block] |
||
451 | call ext2_get_block |
||
452 | test eax, eax |
||
453 | jnz @F ;если не было ошибки |
||
454 | |||
455 | mov ecx, [ebx + ecx*4] ;заносим результат |
||
456 | @@: |
||
457 | pop ebx |
||
458 | ret |
||
459 | |||
460 | .get_direct_block: |
||
461 | mov ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4] |
||
462 | xor eax, eax |
||
463 | ret |
||
464 | |||
465 | ;=================================================================== |
||
466 | ;get content inode by num |
||
467 | ;in: eax = inode_num |
||
468 | ; ebx = address of inode content |
||
469 | ;out: eax - error code |
||
470 | ext2_get_inode: |
||
471 | pushad |
||
472 | mov edi, ebx ;сохраним адрес inode |
||
473 | dec eax |
||
474 | xor edx, edx |
||
475 | |||
476 | mov ecx, [ext2_data.sb] |
||
477 | div [ecx + EXT2_SB_STRUC.inodes_per_group] |
||
478 | |||
479 | push edx ;locale num in group |
||
480 | |||
2382 | hidnplayr | 481 | mov edx, 32 |
482 | mul edx ; address block_group in global_desc_table |
||
483 | |||
3359 | hidnplayr | 484 | ; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы |
485 | ; найдем блок в котором он находится |
||
486 | div [ext2_data.block_size] |
||
487 | add eax, [ecx + EXT2_SB_STRUC.first_data_block] |
||
488 | inc eax |
||
489 | mov ebx, [ext2_data.ext2_temp_block] |
||
490 | call ext2_get_block |
||
491 | test eax, eax |
||
492 | jnz .fail |
||
493 | |||
494 | add ebx, edx ; локальный номер в блоке |
||
495 | mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]; номер блока - в терминах ext2 |
||
496 | |||
497 | mov ecx, [ext2_data.log_block_size] |
||
498 | shl eax, cl |
||
499 | add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512) |
||
500 | |||
501 | ;eax - указывает на таблицу inode-ов на hdd |
||
502 | mov esi, eax ;сохраним его пока в esi |
||
503 | |||
2382 | hidnplayr | 504 | ; прибавим локальный адрес inode-а |
505 | pop eax ; index |
||
506 | mov ecx, [ext2_data.inode_size] |
||
507 | mul ecx ; (index * inode_size) |
||
508 | mov ebp, 512 |
||
509 | div ebp ;поделим на размер блока |
||
510 | |||
3359 | hidnplayr | 511 | add eax, esi ;нашли адрес блока для чтения |
512 | mov ebx, [ext2_data.ext2_temp_block] |
||
513 | call hd_read |
||
514 | cmp [hd_error], 0 |
||
515 | jnz .fail |
||
516 | |||
517 | mov esi, edx ;добавим "остаток" |
||
518 | add esi, ebx ;к адресу |
||
519 | rep movsb ;копируем inode |
||
520 | xor eax, eax |
||
521 | .fail: |
||
522 | mov PUSHAD_EAX, eax |
||
523 | popad |
||
524 | ret |
||
525 | |||
526 | ;---------------------------------------------------------------- |
||
527 | ; |
||
528 | ; ext2_HdReadFolder - read disk folder |
||
529 | ; |
||
2382 | hidnplayr | 530 | ; esi points to filename |
531 | ; ebx pointer to structure 32-bit number = first wanted block, 0+ |
||
532 | ; & flags (bitfields) |
||
533 | ; flags: bit 0: 0=ANSI names, 1=UNICODE names |
||
534 | ; ecx number of blocks to read, 0+ |
||
535 | ; edx mem location to return data |
||
536 | ; |
||
537 | ; ret ebx = blocks read or 0xffffffff folder not found |
||
538 | ; eax = 0 ok read or other = errormsg |
||
539 | ; |
||
3359 | hidnplayr | 540 | ;-------------------------------------------------------------- |
541 | ext2_HdReadFolder: |
||
542 | cmp byte [esi], 0 |
||
543 | jz .root_folder |
||
544 | |||
545 | push ebx ecx edx |
||
546 | call ext2_find_lfn ;вернет в ebp адрес inode |
||
547 | pop edx ecx ebx |
||
548 | test eax, eax |
||
549 | jnz .error_ret |
||
550 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
||
551 | jz .error_not_found |
||
552 | jmp @F |
||
553 | |||
554 | .root_folder: |
||
555 | mov ebp, [ext2_data.root_inode] |
||
556 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
||
557 | jz .error_root |
||
558 | ;придется копировать inode |
||
559 | push ecx |
||
560 | mov esi, ebp |
||
561 | mov edi, [ext2_data.ext2_save_inode] |
||
562 | mov ecx, [ext2_data.inode_size] |
||
563 | shr ecx, 2 |
||
564 | mov ebp, edi |
||
3405 | hidnplayr | 565 | rep movsd |
566 | pop ecx |
||
567 | @@: |
||
568 | cmp [ebp + EXT2_INODE_STRUC.i_size], 0 ;папка пуста |
||
569 | je .error_empty_dir |
||
570 | |||
571 | push edx ;адрес результата [edi + 28] |
||
3359 | hidnplayr | 572 | push 0 ;конец очередного блока папки [edi + 24] |
573 | push ecx ;сколько файлов нужно прочитать [edi + 20] |
||
574 | push dword [ebx] ;первый "нужный" файл [edi + 16] |
||
575 | push dword [ebx + 4];флаги [edi + 12] |
||
576 | push 0 ;[EXT2_read_in_folder] [edi + 8] |
||
577 | push 0 ;[EXT2_files_in_folder] [edi + 4] |
||
578 | push 0 ;номер блока по порядку [edi] |
||
579 | |||
580 | mov edi, edx |
||
581 | mov ecx, 32/4 |
||
582 | rep stosd ; fill header zero |
||
583 | |||
584 | mov edi, esp ; edi - указатель на локальные переменные |
||
585 | add edx, 32 ; edx = current mem for return |
||
586 | |||
587 | xor ecx, ecx ; получим номер первого блока |
||
588 | call ext2_get_inode_block |
||
589 | test eax, eax |
||
590 | jnz .error_get_block |
||
591 | |||
592 | mov eax, ecx |
||
593 | mov ebx, [ext2_data.ext2_save_block] |
||
594 | call ext2_get_block ; и считываем блок с hdd |
||
595 | test eax, eax |
||
596 | jnz .error_get_block |
||
597 | |||
598 | mov esi, ebx ; esi = current dir record |
||
599 | add ebx, [ext2_data.block_size] |
||
600 | mov [edi + 24], ebx ; запомним конец очередного блока |
||
601 | |||
602 | mov ecx, [edi + 16] ; ecx = first wanted (flags ommited) |
||
603 | |||
604 | .find_wanted_start: |
||
605 | jecxz .find_wanted_end |
||
606 | .find_wanted_cycle: |
||
607 | cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
||
608 | jz @F |
||
609 | inc dword [edi + 4] ; EXT2_files_in_folder |
||
610 | dec ecx |
||
611 | @@: |
||
612 | movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] |
||
613 | |||
614 | cmp ebx, 12 ; минимальная длина записи |
||
615 | jb .error_bad_len |
||
3405 | hidnplayr | 616 | test ebx, 0x3 ; длина записи должна делиться на 4 |
617 | jnz .error_bad_len |
||
618 | |||
619 | sub [ebp + EXT2_INODE_STRUC.i_size], ebx ;вычитаем напрямую из структуры inode |
||
620 | add esi, ebx ; к следующей записи |
||
621 | cmp esi, [edi + 24] ; сравниваем с концом блока |
||
622 | jb .find_wanted_start |
||
623 | |||
624 | push .find_wanted_start |
||
625 | .end_block: ;вылетели из цикла |
||
626 | cmp [ebp + EXT2_INODE_STRUC.i_size], 0 |
||
627 | jle .end_dir |
||
628 | |||
629 | inc dword [edi] ;получаем новый блок |
||
3359 | hidnplayr | 630 | push ecx |
631 | mov ecx, [edi] |
||
632 | call ext2_get_inode_block |
||
633 | test eax, eax |
||
634 | jnz .error_get_block |
||
635 | |||
636 | mov eax, ecx |
||
637 | mov ebx, [ext2_data.ext2_save_block] |
||
638 | call ext2_get_block |
||
639 | test eax, eax |
||
640 | jnz .error_get_block |
||
641 | |||
642 | pop ecx |
||
643 | mov esi, ebx |
||
644 | add ebx, [ext2_data.block_size] |
||
645 | mov [edi + 24], ebx ;запомним конец блока |
||
646 | ret ; опять в цикл |
||
647 | |||
648 | .wanted_end: |
||
649 | loop .find_wanted_cycle ; ecx 0 => -1 нужно посчитать сколько файлов |
||
650 | |||
651 | ;дошли до первого "нужного" файла |
||
652 | .find_wanted_end: |
||
653 | mov ecx, [edi + 20] |
||
654 | .wanted_start: ; ищем first_wanted+count |
||
655 | jecxz .wanted_end |
||
656 | cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
||
657 | jz .empty_rec |
||
658 | inc dword [edi + 8] |
||
659 | inc dword [edi + 4] |
||
660 | |||
661 | push edi ecx |
||
662 | mov edi, edx ;обнуляем место под очереное имя файла/папки |
||
663 | xor eax, eax |
||
664 | mov ecx, 40 / 4 |
||
665 | rep stosd |
||
666 | pop ecx edi |
||
667 | |||
668 | push esi edi edx |
||
669 | mov eax, [esi + EXT2_DIR_STRUC.inode] ;получим дочерний inode |
||
670 | mov ebx, [ext2_data.ext2_temp_inode] |
||
671 | call ext2_get_inode |
||
672 | test eax, eax |
||
673 | jnz .error_read_subinode |
||
674 | |||
675 | lea edi, [edx + 8] |
||
676 | |||
677 | mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат |
||
678 | xor edx, edx |
||
679 | add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600 |
||
680 | adc edx, 2 |
||
2382 | hidnplayr | 681 | call ntfs_datetime_to_bdfe.sec |
682 | |||
683 | mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
||
684 | xor edx, edx |
||
685 | add eax, 3054539008 |
||
686 | adc edx, 2 |
||
687 | call ntfs_datetime_to_bdfe.sec |
||
688 | |||
689 | mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
||
690 | xor edx, edx |
||
691 | add eax, 3054539008 |
||
692 | adc edx, 2 |
||
3359 | hidnplayr | 693 | call ntfs_datetime_to_bdfe.sec |
694 | |||
695 | pop edx ; пока достаем только буфер |
||
696 | test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер |
||
697 | jnz @F ; не возвращаем |
||
698 | |||
699 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size |
||
700 | stosd |
||
701 | mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size |
||
702 | stosd |
||
703 | xor dword [edx], FS_FT_DIR ;помечаем, что это файл(2 раза xor) |
||
704 | @@: |
||
705 | xor dword [edx], FS_FT_DIR ;помечаем, что это файл |
||
706 | |||
707 | ;теперь скопируем имя, сконвертировав из UTF-8 в CP866 |
||
708 | push ecx ;edi и esi уже сохранены в стеке |
||
709 | movzx ecx, [esi + EXT2_DIR_STRUC.name_len] |
||
710 | lea edi, [edx + 40] |
||
711 | lea esi, [esi + EXT2_DIR_STRUC.name] |
||
712 | call utf8_to_cp866 |
||
713 | and byte [edi], 0 |
||
714 | pop ecx edi esi |
||
715 | |||
716 | cmp byte [edx + 40], '.' ; в linux файл, начинающийся с точки - скрытый |
||
717 | jne @F |
||
718 | or dword [edx], FS_FT_HIDDEN |
||
719 | @@: |
||
720 | |||
721 | add edx, 40 + 264 ; go to next record |
||
722 | dec ecx ; если запись пустая ecx не надо уменьшать |
||
723 | .empty_rec: |
||
724 | movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] |
||
725 | cmp ebx, 12 ; минимальная длина записи |
||
726 | jb .error_bad_len |
||
3405 | hidnplayr | 727 | test ebx, 0x3 ; длина записи должна делиться на 4 |
728 | jnz .error_bad_len |
||
729 | |||
730 | sub [ebp + EXT2_INODE_STRUC.i_size], ebx ;вычитаем напрямую из структуры inode |
||
731 | add esi, ebx |
||
732 | cmp esi, [edi + 24] ;дошли ли до конца блока? |
||
733 | jb .wanted_start |
||
3359 | hidnplayr | 734 | |
735 | push .wanted_start ; дошли |
||
736 | jmp .end_block |
||
737 | |||
738 | .end_dir: ;конец папки, когда еще не дошли до нужного файла |
||
739 | mov edx, [edi + 28] ;адрес структуры результата |
||
740 | mov ebx, [edi + 8] ;EXT2_read_in_folder |
||
741 | mov ecx, [edi + 4] ;EXT2_files_in_folder |
||
742 | mov dword [edx], 1 ;version |
||
743 | mov [edx + 4], ebx |
||
744 | mov [edx + 8], ecx |
||
745 | |||
746 | lea esp, [edi + 32] |
||
747 | |||
748 | xor eax, eax ;зарезервировано: нули в текущей реализации |
||
749 | lea edi, [edx + 12] |
||
750 | mov ecx, 20 / 4 |
||
751 | rep stosd |
||
752 | ret |
||
753 | |||
754 | .error_bad_len: |
||
755 | mov eax, ERROR_FS_FAIL |
||
756 | .error_read_subinode: |
||
757 | .error_get_block: |
||
758 | lea esp, [edi + 32] |
||
759 | .error_ret: |
||
760 | or ebx, -1 |
||
761 | ret |
||
762 | |||
763 | .error_empty_dir: ;inode папки без блоков |
||
764 | .error_root: ;root - не папка |
||
765 | mov eax, ERROR_FS_FAIL |
||
766 | jmp .error_ret |
||
767 | |||
768 | .error_not_found: ;файл не найден |
||
769 | mov eax, ERROR_FILE_NOT_FOUND |
||
770 | jmp .error_ret |
||
771 | |||
772 | ;============================================ |
||
773 | ;convert UTF-8 string to ASCII-string (codepage 866) |
||
774 | ;in: ecx = length source |
||
775 | ; esi = source |
||
776 | ; edi = buffer |
||
777 | ; destroys: eax,esi,edi |
||
778 | utf8_to_cp866: |
||
779 | jecxz .ret |
||
780 | .start: |
||
781 | lodsw |
||
2382 | hidnplayr | 782 | cmp al, 0x80 |
783 | jb .ascii |
||
784 | |||
785 | xchg al, ah ; big-endian |
||
786 | cmp ax, 0xd080 |
||
787 | jz .yo1 |
||
788 | cmp ax, 0xd191 |
||
789 | jz .yo2 |
||
790 | cmp ax, 0xd090 |
||
791 | jb .unk |
||
792 | cmp ax, 0xd180 |
||
793 | jb .rus1 |
||
794 | cmp ax, 0xd190 |
||
795 | jb .rus2 |
||
796 | .unk: |
||
797 | mov al, '_' |
||
798 | jmp .doit |
||
799 | .yo1: |
||
800 | mov al, 0xf0 ; Ё capital |
||
801 | jmp .doit |
||
802 | .yo2: |
||
803 | mov al, 0xf1 ; ё small |
||
804 | jmp .doit |
||
805 | .rus1: |
||
806 | sub ax, 0xd090 - 0x80 |
||
807 | jmp .doit |
||
808 | .rus2: |
||
809 | sub ax, 0xd18f - 0xEF |
||
810 | .doit: |
||
811 | stosb |
||
812 | sub ecx, 2 |
||
813 | ja .start |
||
814 | ret |
||
815 | |||
816 | .ascii: |
||
817 | stosb |
||
818 | dec esi |
||
819 | dec ecx |
||
820 | jnz .start |
||
821 | .ret: |
||
822 | ret |
||
823 | |||
824 | ;---------------------------------------------------------------- |
||
825 | ; |
||
826 | ; ext2_HdRead - read hard disk |
||
827 | ; |
||
828 | ; esi points to filename |
||
829 | ; ebx pointer to 64-bit number = first wanted byte, 0+ |
||
830 | ; may be ebx=0 - start from first byte |
||
831 | ; ecx number of bytes to read, 0+ |
||
832 | ; edx mem location to return data |
||
3359 | hidnplayr | 833 | ; |
834 | ; ret ebx = bytes read or 0xffffffff file not found |
||
835 | ; eax = 0 ok read or other = errormsg |
||
836 | |||
837 | ;-------------------------------------------------------------- |
||
838 | ext2_HdRead: |
||
839 | cmp byte [esi], 0 |
||
2382 | hidnplayr | 840 | jnz @F |
841 | |||
842 | .this_is_nofile: |
||
843 | or ebx, -1 |
||
844 | mov eax, ERROR_ACCESS_DENIED |
||
3359 | hidnplayr | 845 | ret |
2382 | hidnplayr | 846 | |
3359 | hidnplayr | 847 | @@: |
848 | push ecx ebx edx |
||
849 | call ext2_find_lfn |
||
850 | pop edx ebx ecx |
||
851 | test eax, eax |
||
852 | jz @F |
||
853 | |||
854 | or ebx, -1 |
||
855 | mov eax, ERROR_FILE_NOT_FOUND |
||
856 | ret |
||
857 | |||
858 | @@: |
||
859 | mov ax, [ebp + EXT2_INODE_STRUC.i_mode] |
||
860 | and ax, EXT2_S_IFMT ;оставляем только тип inode в ax |
||
861 | cmp ax, EXT2_S_IFREG |
||
862 | jne .this_is_nofile |
||
863 | |||
864 | mov edi, edx ; edi = pointer to return mem |
||
865 | |||
866 | test ebx, ebx |
||
867 | jz @F |
||
868 | mov esi, ebx ; esi = pointer to first_wanted |
||
869 | mov ebx, [esi+4] |
||
870 | mov eax, [esi] ; ebx : eax - стартовый номер байта |
||
871 | |||
872 | ;///// сравним хватит ли нам файла или нет |
||
873 | cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
||
874 | ja .size_great |
||
875 | jb .size_less |
||
876 | |||
2382 | hidnplayr | 877 | cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
878 | ja .size_great |
||
879 | |||
880 | .size_less: |
||
3359 | hidnplayr | 881 | xor ebx, ebx |
882 | mov eax, ERROR_END_OF_FILE |
||
883 | ret |
||
884 | |||
885 | @@: |
||
886 | xor ebx, ebx |
||
887 | xor eax, eax |
||
888 | .size_great: |
||
889 | add eax, ecx ;add to first_wanted кол-во байт для чтения |
||
890 | adc ebx, 0 |
||
2382 | hidnplayr | 891 | |
892 | cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
||
3359 | hidnplayr | 893 | ja .size_great_great |
894 | jb .size_great_less |
||
895 | cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
||
896 | jae .size_great_great |
||
897 | |||
898 | .size_great_less: |
||
899 | push 1 ;читаем по границе размера |
||
900 | mov ecx, [ebp + EXT2_INODE_STRUC.i_size] |
||
901 | sub ecx, [esi] ;(размер - старт) = сколько читать |
||
902 | jmp @F |
||
903 | |||
904 | .size_great_great: |
||
905 | push 0 ;читаем столько сколько запросили |
||
906 | |||
907 | @@: |
||
908 | ;здесь мы точно знаем сколько байт читать - ecx |
||
909 | ;edi - return memory |
||
910 | ;esi -> first wanted |
||
911 | |||
912 | push ecx ;количество считанных байт |
||
913 | test esi, esi |
||
914 | jz .zero_start |
||
915 | |||
916 | ;получим кусок из первого блока |
||
917 | mov edx, [esi+4] |
||
918 | mov eax, [esi] |
||
919 | div [ext2_data.block_size] |
||
920 | |||
921 | push eax ;счетчик блоков ложим в стек |
||
922 | |||
923 | push ecx |
||
924 | mov ecx, eax |
||
925 | call ext2_get_inode_block |
||
926 | test eax, eax |
||
927 | jnz .error_at_first_block |
||
928 | mov ebx, [ext2_data.ext2_save_block] |
||
929 | mov eax, ecx |
||
930 | call ext2_get_block |
||
931 | test eax, eax |
||
932 | jnz .error_at_first_block |
||
933 | pop ecx |
||
934 | add ebx, edx |
||
935 | |||
2382 | hidnplayr | 936 | neg edx |
937 | add edx, [ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока |
||
938 | cmp ecx, edx |
||
939 | jbe .only_one_block |
||
940 | |||
941 | mov eax, ecx |
||
942 | sub eax, edx |
||
943 | mov ecx, edx |
||
3359 | hidnplayr | 944 | |
945 | mov esi, ebx |
||
946 | rep movsb ;кусок 1-го блока |
||
947 | jmp .calc_blocks_count |
||
948 | |||
949 | .zero_start: |
||
950 | mov eax, ecx |
||
951 | push 0 ;счетчик блоков ложим в стек |
||
952 | ;теперь в eax кол-во оставшихся байт для чтения |
||
953 | .calc_blocks_count: |
||
954 | mov ebx, edi ;чтение блока прям в ->ebx |
||
955 | xor edx, edx |
||
956 | div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx |
||
957 | mov edi, eax ;кол-во целых блоков в edi |
||
958 | @@: |
||
959 | test edi, edi |
||
960 | jz .finish_block |
||
961 | inc dword [esp] |
||
962 | mov ecx, [esp] |
||
963 | call ext2_get_inode_block |
||
964 | test eax, eax |
||
965 | jnz .error_at_read_cycle |
||
966 | |||
967 | mov eax, ecx ;а ebx уже забит нужным значением |
||
968 | call ext2_get_block |
||
969 | test eax, eax |
||
970 | jnz .error_at_read_cycle |
||
971 | add ebx, [ext2_data.block_size] |
||
972 | |||
973 | dec edi |
||
2382 | hidnplayr | 974 | jmp @B |
975 | |||
976 | .finish_block: ;в edx - кол-во байт в последнем блоке |
||
3359 | hidnplayr | 977 | test edx, edx |
978 | jz .end_read |
||
979 | |||
980 | pop ecx ;счетчик блоков -> ecx |
||
981 | inc ecx |
||
982 | call ext2_get_inode_block |
||
983 | test eax, eax |
||
984 | jnz .error_at_finish_block |
||
985 | |||
986 | mov edi, ebx |
||
987 | mov eax, ecx |
||
988 | mov ebx, [ext2_data.ext2_save_block] |
||
989 | call ext2_get_block |
||
990 | test eax, eax |
||
991 | jnz .error_at_finish_block |
||
992 | |||
993 | mov ecx, edx |
||
994 | mov esi, ebx |
||
995 | rep movsb ;кусок last блока |
||
996 | jmp @F |
||
997 | |||
998 | .end_read: |
||
999 | pop ecx ;счетчик блоков, который хранился в стеке |
||
1000 | @@: |
||
1001 | pop ebx ;количество считанных байт |
||
1002 | pop eax ; 1 или 0 - достигли ли конца файла |
||
1003 | test eax, eax |
||
1004 | jz @F |
||
1005 | |||
1006 | mov eax, ERROR_END_OF_FILE |
||
2382 | hidnplayr | 1007 | ret |
3359 | hidnplayr | 1008 | @@: |
1009 | xor eax, eax |
||
1010 | ret |
||
1011 | |||
1012 | .only_one_block: |
||
1013 | mov esi, ebx |
||
1014 | rep movsb ;кусок last блока |
||
1015 | jmp .end_read |
||
1016 | |||
1017 | .error_at_first_block: |
||
1018 | pop edx |
||
1019 | .error_at_read_cycle: |
||
1020 | pop ebx |
||
1021 | .error_at_finish_block: |
||
1022 | pop ecx edx |
||
1023 | or ebx, -1 |
||
1024 | ret |
||
1025 | |||
1026 | ;---------------------------------------------------------------- |
||
1027 | ; in: esi = file path |
||
1028 | ; ebx = pointer to dir block |
||
1029 | ; out: esi - name without parent or not_changed |
||
1030 | ; ebx - dir_rec of inode children |
||
1031 | ext2_test_block_by_name: |
||
1032 | sub esp, 256 ;EXT2_filename |
||
1033 | mov edx, ebx |
||
1034 | add edx, [ext2_data.block_size] ;запомним конец блока |
||
1035 | |||
1036 | .start_rec: |
||
1037 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 |
||
1038 | jz .next_rec |
||
1039 | |||
1040 | mov edi, esp |
||
1041 | push esi |
||
1042 | movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] |
||
1043 | lea esi, [ebx + EXT2_DIR_STRUC.name] |
||
1044 | call utf8_to_cp866 |
||
1045 | |||
1046 | mov ecx, edi |
||
1047 | lea edi, [esp + 4] |
||
1048 | sub ecx, edi ;кол-во байт в получившейся строке |
||
1049 | |||
1050 | mov esi, [esp] |
||
1051 | @@: |
||
1052 | jecxz .test_find |
||
1053 | dec ecx |
||
1054 | |||
1055 | lodsb |
||
1056 | call char_toupper |
||
1057 | |||
1058 | mov ah, [edi] |
||
1059 | inc edi |
||
1060 | xchg al, ah |
||
1061 | call char_toupper |
||
1062 | cmp al, ah |
||
1063 | je @B |
||
1064 | @@: ;не подошло |
||
1065 | pop esi |
||
1066 | .next_rec: |
||
1067 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
||
1068 | add ebx, eax ;к след. записи |
||
1069 | cmp ebx, edx ;проверим конец ли |
||
1070 | jb .start_rec |
||
1071 | add esp, 256 |
||
1072 | ret |
||
1073 | |||
1074 | .test_find: |
||
1075 | cmp byte [esi], 0 |
||
1076 | je .ret ;нашли конец |
||
1077 | cmp byte [esi], '/' |
||
1078 | jne @B |
||
1079 | inc esi |
||
1080 | .ret: |
||
1081 | add esp, 256 + 4 |
||
1082 | ret |
||
1083 | |||
1084 | ;======================== |
||
1085 | ;Ищет inode по строке пути |
||
1086 | ;in: esi = name |
||
1087 | ;out: eax - error code |
||
1088 | ; ebp = inode |
||
1089 | ; dl - первый байт из имени файла/папки |
||
1090 | ext2_find_lfn: |
||
1091 | mov ebp, [ext2_data.root_inode] |
||
1092 | cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0 |
||
1093 | je .error_empty_root |
||
1094 | |||
1095 | .next_path_part: |
||
3405 | hidnplayr | 1096 | push [ebp + EXT2_INODE_STRUC.i_blocks] |
1097 | xor ecx, ecx |
||
1098 | .folder_block_cycle: |
||
1099 | push ecx |
||
1100 | call ext2_get_inode_block |
||
1101 | test eax, eax |
||
1102 | jnz .error_get_inode_block |
||
3359 | hidnplayr | 1103 | |
1104 | mov eax, ecx |
||
1105 | mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
||
1106 | call ext2_get_block |
||
1107 | test eax, eax |
||
1108 | jnz .error_get_block |
||
3405 | hidnplayr | 1109 | |
1110 | push esi |
||
1111 | call ext2_test_block_by_name |
||
1112 | pop edi ecx |
||
1113 | |||
1114 | cmp edi, esi ;нашли имя? |
||
1115 | je .next_folder_block ;не нашли -> к след. блоку |
||
3359 | hidnplayr | 1116 | |
1117 | cmp byte [esi], 0 ;дошли до "конца" пути -> возваращаемся |
||
1118 | jz .get_inode_ret |
||
1119 | |||
1120 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;нашли, но это не папка |
||
1121 | jne .not_found |
||
1122 | |||
1123 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
1124 | mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
||
1125 | call ext2_get_inode |
||
1126 | test eax, eax |
||
1127 | jnz .error_get_inode |
||
1128 | pop ecx ;в стеке лежит кол-во блоков |
||
1129 | mov ebp, ebx |
||
1130 | jmp .next_path_part |
||
1131 | |||
1132 | .next_folder_block: |
||
1133 | ;к следующему блоку в текущей папке |
||
1134 | pop eax ;счетчик блоков |
||
1135 | sub eax, [ext2_data.count_block_in_block] |
||
1136 | jle .not_found |
||
1137 | |||
1138 | push eax |
||
1139 | inc ecx |
||
1140 | jmp .folder_block_cycle |
||
1141 | |||
1142 | .not_found: |
||
1143 | mov eax, ERROR_FILE_NOT_FOUND |
||
1144 | ret |
||
1145 | |||
1146 | .get_inode_ret: |
||
1147 | pop ecx ;в стеке лежит кол-во блоков |
||
1148 | mov dl, [ebx + EXT2_DIR_STRUC.name] ;в dl - первый символ () |
||
1149 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
1150 | mov ebx, [ext2_data.ext2_save_inode] |
||
1151 | call ext2_get_inode |
||
1152 | mov ebp, ebx |
||
1153 | xor eax, eax |
||
1154 | ret |
||
3405 | hidnplayr | 1155 | |
1156 | .error_get_inode_block: |
||
1157 | .error_get_block: |
||
1158 | pop ecx |
||
1159 | .error_get_inode: |
||
1160 | pop ebx |
||
1161 | .error_empty_root: |
||
3359 | hidnplayr | 1162 | mov eax, ERROR_FS_FAIL |
1163 | ret |
||
1164 | |||
1165 | ;---------------------------------------------------------------- |
||
1166 | ;ext2_HdGetFileInfo - read file info from block device |
||
1167 | ; |
||
1168 | ;in: esi points to filename |
||
1169 | ; edx mem location to return data |
||
1170 | ;-------------------------------------------------------------- |
||
1171 | ext2_HdGetFileInfo: |
||
1172 | xchg bx, bx |
||
1173 | cmp byte [esi], 0 |
||
1174 | jz .is_root |
||
1175 | |||
1176 | push edx |
||
1177 | call ext2_find_lfn |
||
1178 | mov ebx, edx |
||
1179 | pop edx |
||
1180 | test eax, eax |
||
1181 | jz @F |
||
1182 | ret |
||
1183 | |||
1184 | .is_root: |
||
1185 | xor ebx, ebx ;root не может быть скрытым |
||
1186 | mov ebp, [ext2_data.root_inode] |
||
1187 | @@: |
||
1188 | xor eax, eax |
||
1189 | mov edi, edx |
||
1190 | mov ecx, 40/4 |
||
1191 | rep stosd ; fill zero |
||
1192 | |||
1193 | cmp bl, '.' |
||
1194 | jne @F |
||
1195 | or dword [edx], FS_FT_HIDDEN |
||
1196 | @@: |
||
1197 | |||
2382 | hidnplayr | 1198 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
1199 | jnz @F |
||
1200 | mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size |
||
1201 | mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size |
||
1202 | mov dword [edx+32], eax |
||
1203 | mov dword [edx+36], ebx |
||
1204 | xor dword [edx], FS_FT_DIR |
||
1205 | @@: |
||
3359 | hidnplayr | 1206 | xor dword [edx], FS_FT_DIR |
1207 | |||
1208 | lea edi, [edx + 8] |
||
1209 | mov eax, [ebp + EXT2_INODE_STRUC.i_ctime] |
||
1210 | xor edx, edx |
||
1211 | add eax, 3054539008 |
||
1212 | adc edx, 2 |
||
2382 | hidnplayr | 1213 | call ntfs_datetime_to_bdfe.sec |
1214 | |||
3359 | hidnplayr | 1215 | mov eax, [ebp + EXT2_INODE_STRUC.i_atime] |
1216 | xor edx, edx |
||
1217 | add eax, 3054539008 |
||
1218 | adc edx, 2 |
||
1219 | call ntfs_datetime_to_bdfe.sec |
||
1220 | |||
1221 | mov eax, [ebp + EXT2_INODE_STRUC.i_mtime] |
||
1222 | xor edx, edx |
||
1223 | add eax, 3054539008 |
||
1224 | adc edx, 2 |
||
1225 | call ntfs_datetime_to_bdfe.sec |
||
1226 | |||
2382 | hidnplayr | 1227 | xor eax, eax |
1228 | ret |
||
1229 | |||
1230 | ext2_HdRewrite: |
||
1231 | ext2_HdWrite: |
||
1232 | ext2_HdSetFileEnd: |
||
1233 | ext2_HdSetFileInfo: |
||
1234 | ext2_HdDelete: |
||
1235 | ext2_HdCreateFolder: |
||
3359 | hidnplayr | 1236 | xor ebx, ebx |
1237 | mov eax, ERROR_UNSUPPORTED_FS |
||
1238 | ret |