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