Rev 2465 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2465 | Rev 2987 | ||
---|---|---|---|
Line 6... | Line 6... | ||
6 | ;; 23.01.2010 turbanoff - support 70.0 70.1 ;; |
6 | ;; 23.01.2010 turbanoff - support 70.0 70.1 ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; ;; |
8 | ;; ;; |
9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 10... | Line 10... | ||
10 | 10 | ||
Line 11... | Line 11... | ||
11 | $Revision: 2465 $ |
11 | $Revision: 2987 $ |
12 | 12 | ||
13 | EXT2_BAD_INO = 1 |
13 | EXT2_BAD_INO = 1 |
14 | EXT2_ROOT_INO = 2 |
14 | EXT2_ROOT_INO = 2 |
15 | EXT2_ACL_IDX_INO = 3 |
15 | EXT2_ACL_IDX_INO = 3 |
16 | EXT2_ACL_DATA_INO = 4 |
16 | EXT2_ACL_DATA_INO = 4 |
Line 17... | Line 17... | ||
17 | EXT2_BOOT_LOADER_INO= 5 |
17 | EXT2_BOOT_LOADER_INO = 5 |
18 | EXT2_UNDEL_DIR_INO = 6 |
18 | EXT2_UNDEL_DIR_INO = 6 |
19 | 19 | ||
20 | ;type inode |
- | |
21 | EXT2_S_IFREG = 0x8000 |
- | |
22 | EXT2_S_IFDIR = 0x4000 |
- | |
23 | ;user inode right's |
- | |
24 | EXT2_S_IRUSR = 0x0100 |
- | |
25 | EXT2_S_IWUSR = 0x0080 |
- | |
26 | EXT2_S_IXUSR = 0x0040 |
- | |
27 | ;group inode right's |
- | |
28 | EXT2_S_IRGRP = 0x0020 |
- | |
29 | EXT2_S_IWGRP = 0x0010 |
- | |
30 | EXT2_S_IXGRP = 0x0008 |
- | |
31 | ;other inode right's |
- | |
32 | EXT2_S_IROTH = 0x0004 |
20 | ;флаги, указываемый в inode файла |
33 | EXT2_S_IWOTH = 0x0002 |
- | |
34 | EXT2_S_IXOTH = 0x0001 |
- | |
Line -... | Line 21... | ||
- | 21 | EXT2_S_IFREG = 0x8000 |
|
35 | EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \ |
22 | EXT2_S_IFDIR = 0x4000 |
36 | EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \ |
23 | EXT2_S_IFMT = 0xF000 ;маска для типа файла |
Line -... | Line 24... | ||
- | 24 | ||
37 | EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR |
25 | ;флаги, указываемые в linked list родительской папки |
38 | 26 | EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге |
|
39 | EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге |
27 | EXT2_FT_DIR = 2 ;это папка |
40 | EXT2_FT_DIR = 2 ;это папка |
28 | |
Line -... | Line 29... | ||
- | 29 | ;флаги используемые KolibriOS |
|
41 | 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 ;тип файла должен указываться в директории |
|
Line 42... | Line 36... | ||
42 | FS_FT_HIDDEN = 2 |
36 | EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;экстенты |
43 | FS_FT_DIR = 0x10 ;это папка |
37 | EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;гибкие группы блоков |
44 | FS_FT_ASCII = 0 ;имя в ascii |
- | |
45 | FS_FT_UNICODE = 1 ;имя в unicode |
- | |
46 | - | ||
47 | EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 |
38 | ;реализованные ext[234] features |
48 | - | ||
49 | uglobal |
- | |
50 | EXT2_files_in_folder dd ? ;всего файлов в папке |
- | |
Line 51... | Line 39... | ||
51 | EXT2_read_in_folder dd ? ;сколько файлов "считали" |
39 | EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \ |
52 | EXT2_end_block dd ? ;конец очередного блока папки |
40 | or EXT4_FEATURE_INCOMPAT_EXTENTS \ |
53 | EXT2_counter_blocks dd ? |
41 | or EXT4_FEATURE_INCOMPAT_FLEX_BG |
54 | EXT2_filename rb 256 |
42 | |
Line 84... | Line 72... | ||
84 | file_type db ? |
72 | file_type db ? |
85 | name db ? ; 0..255 |
73 | name db ? ; 0..255 |
86 | ends |
74 | ends |
Line 87... | Line 75... | ||
87 | 75 | ||
88 | struct EXT2_BLOCK_GROUP_DESC |
76 | struct EXT2_BLOCK_GROUP_DESC |
89 | block_bitmap dd ? |
77 | block_bitmap dd ? ;+0 |
90 | inode_bitmap dd ? |
78 | inode_bitmap dd ? ;+4 |
91 | inode_table dd ? |
79 | inode_table dd ? ;+8 |
92 | free_blocks_count dw ? |
80 | free_blocks_count dw ? ;+12 |
93 | free_inodes_count dw ? |
81 | free_inodes_count dw ? ;+14 |
- | 82 | used_dirs_count dw ? ;+16 |
|
- | 83 | pad dw ? ;+18 |
|
94 | used_dirs_count dw ? |
84 | reserved rb 12;+20 |
Line 95... | Line 85... | ||
95 | ends |
85 | ends |
96 | 86 | ||
97 | struct EXT2_SB_STRUC |
87 | struct EXT2_SB_STRUC |
Line 130... | Line 120... | ||
130 | volume_name rb 16 ;+120 |
120 | volume_name rb 16 ;+120 |
131 | last_mounted rb 64 ;+136 |
121 | last_mounted rb 64 ;+136 |
132 | algo_bitmap dd ? ;+200 |
122 | algo_bitmap dd ? ;+200 |
133 | prealloc_blocks db ? ;+204 |
123 | prealloc_blocks db ? ;+204 |
134 | preallock_dir_blocks db ? ;+205 |
124 | preallock_dir_blocks db ? ;+205 |
135 | dw ? ;+206 alignment |
125 | reserved_gdt_blocks dw ? ;+206 |
136 | journal_uuid rb 16 ;+208 |
126 | journal_uuid rb 16 ;+208 |
137 | journal_inum dd ? ;+224 |
127 | journal_inum dd ? ;+224 |
138 | journal_dev dd ? ;+228 |
128 | journal_dev dd ? ;+228 |
139 | last_orphan dd ? ;+232 |
129 | last_orphan dd ? ;+232 |
140 | hash_seed rd 4 ;+236 |
130 | hash_seed rd 4 ;+236 |
141 | def_hash_version db ? ;+252 |
131 | def_hash_version db ? ;+252 |
142 | rb 3 ;+253 reserved |
132 | rb 3 ;+253 reserved |
143 | default_mount_options dd ? ;+256 |
133 | default_mount_options dd ? ;+256 |
144 | first_meta_bg dd ? ;+260 |
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 |
|
- | 149 | ||
- | 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 ? ;зарезервировано |
|
145 | ends |
170 | ends |
Line 146... | Line 171... | ||
146 | 171 | ||
147 | ext2_test_superblock: |
172 | ext2_test_superblock: |
148 | cmp [fs_type], 0x83 |
173 | cmp [fs_type], 0x83 |
Line 149... | Line 174... | ||
149 | jne .no |
174 | jne .no |
150 | 175 | ||
151 | mov eax, [PARTITION_START] |
176 | mov eax, [PARTITION_START] |
Line 152... | Line 177... | ||
152 | add eax, 2 ;superblock start at 1024b |
177 | add eax, 2 ;superblock start at 1024b |
153 | call hd_read |
178 | call hd_read |
154 | 179 | ||
155 | cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3 |
180 | cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 ;0,1,2,3 |
156 | ja .no |
181 | ja .no |
157 | cmp word [ebx+56], 0xEF53 ;s_magic |
182 | cmp [ebx + EXT2_SB_STRUC.magic], 0xEF53 |
- | 183 | jne .no |
|
158 | 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 |
|
159 | cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1) |
187 | je .no |
160 | jne .no |
188 | |
161 | mov eax, [ebx+96] |
189 | mov eax, [ebx + EXT2_SB_STRUC.feature_incompat] |
162 | test eax, EXT2_FEATURE_INCOMPAT_FILETYPE |
190 | test eax, EXT2_FEATURE_INCOMPAT_FILETYPE |
Line 163... | Line 191... | ||
163 | jz .no |
191 | jz .no |
164 | test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE |
192 | test eax, not EXT4_FEATURE_INCOMPAT_SUPP |
165 | jnz .no |
193 | jnz .no |
Line 190... | Line 218... | ||
190 | xor edx, edx |
218 | xor edx, edx |
191 | div [ebx + EXT2_SB_STRUC.blocks_per_group] |
219 | div [ebx + EXT2_SB_STRUC.blocks_per_group] |
192 | inc eax |
220 | inc eax |
193 | mov [ext2_data.groups_count], eax |
221 | mov [ext2_data.groups_count], eax |
Line 194... | Line 222... | ||
194 | 222 | ||
195 | mov ecx, [ebx+24] |
223 | mov ecx, [ebx + EXT2_SB_STRUC.log_block_size] |
196 | inc ecx |
224 | inc ecx |
Line 197... | Line 225... | ||
197 | mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb |
225 | mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb |
198 | 226 | ||
Line 216... | Line 244... | ||
216 | call kernel_alloc |
244 | call kernel_alloc |
217 | mov [ext2_data.ext2_save_block], eax ; and for temp block |
245 | mov [ext2_data.ext2_save_block], eax ; and for temp block |
218 | call kernel_alloc |
246 | call kernel_alloc |
219 | mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc |
247 | mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc |
Line 220... | Line 248... | ||
220 | 248 | ||
221 | movzx ebp, word [ebx+88] |
249 | movzx ebp, word [ebx + EXT2_SB_STRUC.inode_size] |
222 | mov ecx, [ebx+32] |
- | |
Line 223... | Line 250... | ||
223 | mov edx, [ebx+40] |
250 | mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group] |
224 | 251 | ||
225 | mov [ext2_data.inode_size], ebp |
- | |
Line 226... | Line 252... | ||
226 | mov [ext2_data.blocks_per_group], ecx |
252 | mov [ext2_data.inode_size], ebp |
227 | mov [ext2_data.inodes_per_group], edx |
253 | mov [ext2_data.blocks_per_group], ecx |
228 | 254 | ||
229 | push ebp ebp ebp ;3 kernel_alloc |
255 | push ebp ebp ebp ;3 kernel_alloc |
Line 239... | Line 265... | ||
239 | call ext2_get_inode ; read root inode |
265 | call ext2_get_inode ; read root inode |
Line 240... | Line 266... | ||
240 | 266 | ||
Line 241... | Line 267... | ||
241 | jmp return_from_part_set |
267 | jmp return_from_part_set |
- | 268 | ||
242 | 269 | ;================================================================== |
|
243 | ;================================================================== |
270 | ;read ext2 block form FS to memory |
- | 271 | ;in: eax = i_block (address of block in ext2 terms) |
|
244 | ;in: eax = i_block |
272 | ; ebx = pointer to return memory |
245 | ; ebx = pointer to return memory |
273 | ;out: eax - error code (0 = no_error) |
246 | ext2_get_block: |
274 | ext2_get_block: |
247 | push eax ebx ecx |
275 | push ebx ecx |
248 | mov ecx, [ext2_data.log_block_size] |
276 | mov ecx, [ext2_data.log_block_size] |
249 | shl eax, cl |
277 | shl eax, cl |
250 | add eax, [PARTITION_START] |
278 | add eax, [PARTITION_START] |
251 | mov ecx, [ext2_data.count_block_in_block] |
279 | mov ecx, [ext2_data.count_block_in_block] |
- | 280 | @@: |
|
- | 281 | call hd_read |
|
252 | @@: |
282 | cmp [hd_error], 0 |
253 | call hd_read |
283 | jnz .fail |
254 | inc eax |
284 | inc eax |
- | 285 | add ebx, 512 |
|
- | 286 | loop @B |
|
255 | add ebx, 512 |
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 блоках |
|
256 | loop @B |
362 | add ecx, edx |
- | 363 | xor eax, eax |
|
- | 364 | ret |
|
- | 365 | ||
- | 366 | .fail: |
|
- | 367 | mov eax, ERROR_FS_FAIL |
|
257 | pop ecx ebx eax |
368 | ret |
- | 369 | ||
258 | ret |
370 | ;=================================================================== |
259 | ;=================================================================== |
371 | ;получает адрес ext2 блока из inode с определнным номером |
260 | ; in: ecx = номер блока в inode (0..) |
372 | ;in: ecx = номер блока в inode (0..) |
- | 373 | ; ebp = адрес inode |
|
261 | ; 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 |
|
262 | ; out: ecx = адрес очередного блока |
387 | |
263 | ext2_get_inode_block: |
388 | @@: |
Line 264... | Line 389... | ||
264 | cmp ecx, 12 ; 0..11 - direct block address |
389 | cmp ecx, 12 ; 0..11 - direct block address |
265 | jb .get_direct_block |
390 | jb .get_direct_block |
266 | 391 | ||
Line 267... | Line 392... | ||
267 | sub ecx, 12 |
392 | sub ecx, 12 |
268 | cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block |
393 | cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect blocks |
269 | jb .get_indirect_block |
394 | jb .get_indirect_block |
Line 270... | Line 395... | ||
270 | 395 | ||
271 | sub ecx, [ext2_data.count_pointer_in_block] |
396 | sub ecx, [ext2_data.count_pointer_in_block] |
272 | cmp ecx, [ext2_data.count_pointer_in_block_square] |
397 | cmp ecx, [ext2_data.count_pointer_in_block_square] |
Line 273... | Line 398... | ||
273 | jb .get_double_indirect_block |
398 | jb .get_double_indirect_block |
274 | 399 | ||
275 | sub ecx, [ext2_data.count_pointer_in_block_square] |
400 | sub ecx, [ext2_data.count_pointer_in_block_square] |
- | 401 | ;triple indirect block |
|
- | 402 | push edx ebx |
|
Line 276... | Line 403... | ||
276 | ;.get_triple_indirect_block: |
403 | |
277 | push eax edx ebx |
404 | mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] |
278 | 405 | mov ebx, [ext2_data.ext2_temp_block] |
|
Line 279... | Line 406... | ||
279 | mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] |
406 | call ext2_get_block |
280 | mov ebx, [ext2_data.ext2_temp_block] |
407 | test eax, eax |
281 | call ext2_get_block |
408 | jnz .fail |
- | 409 | ||
- | 410 | xor edx, edx |
|
Line 282... | Line 411... | ||
282 | 411 | mov eax, ecx |
|
283 | xor edx, edx |
412 | div [ext2_data.count_pointer_in_block_square] |
Line 284... | Line 413... | ||
284 | mov eax, ecx |
413 | |
285 | div [ext2_data.count_pointer_in_block_square] |
414 | ;eax - номер в полученном блоке edx - номер дальше |
Line 286... | Line 415... | ||
286 | 415 | mov eax, [ebx + eax*4] |
|
287 | ;eax - номер в полученном блоке edx - номер дальше |
416 | call ext2_get_block |
288 | mov eax, [ebx + eax*4] |
417 | test eax, eax |
- | 418 | jnz .fail |
|
- | 419 | ||
Line 289... | Line 420... | ||
289 | call ext2_get_block |
420 | mov eax, edx |
290 | 421 | jmp @F |
|
291 | mov eax, edx |
422 | |
292 | jmp @F |
423 | .get_double_indirect_block: |
Line 293... | Line 424... | ||
293 | 424 | push edx ebx |
|
294 | .get_double_indirect_block: |
425 | |
295 | push eax edx ebx |
426 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] |
- | 427 | mov ebx, [ext2_data.ext2_temp_block] |
|
Line -... | Line 428... | ||
- | 428 | call ext2_get_block |
|
- | 429 | test eax, eax |
|
296 | 430 | jnz .fail |
|
297 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] |
431 | |
Line 298... | Line 432... | ||
298 | mov ebx, [ext2_data.ext2_temp_block] |
432 | mov eax, ecx |
299 | call ext2_get_block |
433 | @@: |
300 | 434 | xor edx, edx |
|
301 | mov eax, ecx |
435 | div [ext2_data.count_pointer_in_block] |
302 | @@: |
436 | |
- | 437 | mov eax, [ebx + eax*4] |
|
- | 438 | call ext2_get_block |
|
Line 303... | Line 439... | ||
303 | xor edx, edx |
439 | test eax, eax |
- | 440 | jnz .fail |
|
304 | div [ext2_data.count_pointer_in_block] |
441 | |
305 | 442 | mov ecx, [ebx + edx*4] |
|
Line 306... | Line 443... | ||
306 | mov eax, [ebx + eax*4] |
443 | .fail: |
307 | call ext2_get_block |
444 | pop ebx edx |
- | 445 | ret |
|
308 | mov ecx, [ebx + edx*4] |
446 | |
Line 309... | Line 447... | ||
309 | 447 | .get_indirect_block: |
|
310 | pop ebx edx eax |
448 | push ebx |
311 | ret |
449 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] |
312 | 450 | mov ebx, [ext2_data.ext2_temp_block] |
|
- | 451 | call ext2_get_block |
|
313 | .get_indirect_block: |
452 | test eax, eax |
314 | push eax ebx |
- | |
315 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] |
453 | jz @F ;если не было ошибки |
316 | mov ebx, [ext2_data.ext2_temp_block] |
454 | |
317 | call ext2_get_block |
455 | mov ecx, [ebx + ecx*4] ;заносим результат |
318 | 456 | @@: |
|
- | 457 | pop ebx |
|
- | 458 | ret |
|
319 | mov ecx, [ebx + ecx*4] |
459 | |
Line 320... | Line 460... | ||
320 | pop ebx eax |
460 | .get_direct_block: |
Line 321... | Line 461... | ||
321 | ret |
461 | mov ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4] |
322 | 462 | xor eax, eax |
|
Line 323... | Line 463... | ||
323 | .get_direct_block: |
463 | ret |
324 | mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4] |
464 | |
325 | ret |
- | |
326 | 465 | ;=================================================================== |
|
327 | ;=================================================================== |
- | |
328 | ;get content inode by num |
466 | ;get content inode by num |
329 | ;in: eax = inode_num |
467 | ;in: eax = inode_num |
330 | ; ebx = address of inode content |
468 | ; ebx = address of inode content |
331 | ext2_get_inode: |
469 | ;out: eax - error code |
- | 470 | ext2_get_inode: |
|
- | 471 | pushad |
|
Line 332... | Line 472... | ||
332 | 472 | mov edi, ebx ;сохраним адрес inode |
|
333 | pushad |
473 | dec eax |
Line 334... | Line 474... | ||
334 | mov edi, ebx ;сохраним адрес inode |
474 | xor edx, edx |
335 | dec eax |
475 | |
336 | xor edx, edx |
476 | mov ecx, [ext2_data.sb] |
Line 369... | Line 509... | ||
369 | div ebp ;поделим на размер блока |
509 | div ebp ;поделим на размер блока |
Line 370... | Line 510... | ||
370 | 510 | ||
371 | add eax, esi ;нашли адрес блока для чтения |
511 | add eax, esi ;нашли адрес блока для чтения |
372 | mov ebx, [ext2_data.ext2_temp_block] |
512 | mov ebx, [ext2_data.ext2_temp_block] |
- | 513 | call hd_read |
|
- | 514 | cmp [hd_error], 0 |
|
Line 373... | Line 515... | ||
373 | call hd_read |
515 | jnz .fail |
374 | 516 | ||
375 | mov esi, edx ;добавим "остаток" |
- | |
376 | add esi, ebx ;к адресу |
517 | mov esi, edx ;добавим "остаток" |
- | 518 | add esi, ebx ;к адресу |
|
- | 519 | rep movsb ;копируем inode |
|
- | 520 | xor eax, eax |
|
377 | ; mov ecx, [ext2_data.inode_size] |
521 | .fail: |
378 | rep movsb ;копируем inode |
522 | mov PUSHAD_EAX, eax |
Line 379... | Line 523... | ||
379 | popad |
523 | popad |
380 | ret |
- | |
381 | - | ||
382 | ;---------------------------------------------------------------- |
- | |
383 | ; in: esi -> children |
- | |
384 | ; ebx -> pointer to dir block |
- | |
385 | ; out: esi -> name without parent or not_changed |
- | |
386 | ; ebx -> dir_rec of inode children or trash |
- | |
387 | ext2_test_block_by_name: |
- | |
388 | push eax ecx edx edi |
- | |
389 | - | ||
390 | mov edx, ebx |
- | |
391 | add edx, [ext2_data.block_size] ;запомним конец блока |
- | |
392 | - | ||
393 | .start_rec: |
- | |
394 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 |
- | |
395 | jz .next_rec |
- | |
396 | - | ||
397 | push esi |
- | |
398 | movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] |
- | |
399 | mov edi, EXT2_filename |
- | |
400 | lea esi, [ebx + EXT2_DIR_STRUC.name] |
- | |
401 | - | ||
402 | call utf8toansi_str |
- | |
403 | mov ecx, edi |
- | |
404 | sub ecx, EXT2_filename ;кол-во байт в получившейся строке |
- | |
405 | - | ||
406 | mov edi, EXT2_filename |
- | |
407 | mov esi, [esp] |
- | |
408 | @@: |
- | |
409 | jecxz .test_find |
- | |
410 | dec ecx |
- | |
411 | - | ||
412 | lodsb |
- | |
413 | call char_toupper |
- | |
414 | - | ||
415 | mov ah, [edi] |
- | |
416 | inc edi |
- | |
417 | xchg al, ah |
- | |
418 | call char_toupper |
- | |
419 | cmp al, ah |
- | |
420 | je @B |
- | |
421 | @@: ;не подошло |
- | |
422 | pop esi |
- | |
423 | .next_rec: |
- | |
424 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
- | |
425 | add ebx, eax ;к след. записи |
- | |
426 | cmp ebx, edx ;проверим конец ли |
- | |
427 | jb .start_rec |
- | |
428 | jmp .ret |
- | |
429 | - | ||
430 | .test_find: |
- | |
431 | cmp byte [esi], 0 |
- | |
432 | je .find ;нашли конец |
- | |
433 | cmp byte [esi], '/' |
- | |
434 | jne @B |
- | |
435 | inc esi |
- | |
436 | .find: |
- | |
437 | pop eax ;удаляем из стека сохраненое значение |
- | |
438 | .ret: |
- | |
439 | pop edi edx ecx eax |
- | |
440 | ret |
524 | ret |
441 | 525 | ||
442 | ;---------------------------------------------------------------- |
526 | ;---------------------------------------------------------------- |
443 | ; |
527 | ; |
444 | ; ext2_HdReadFolder - read disk folder |
528 | ; ext2_HdReadFolder - read disk folder |
Line 454... | Line 538... | ||
454 | ; eax = 0 ok read or other = errormsg |
538 | ; eax = 0 ok read or other = errormsg |
455 | ; |
539 | ; |
456 | ;-------------------------------------------------------------- |
540 | ;-------------------------------------------------------------- |
457 | ext2_HdReadFolder: |
541 | ext2_HdReadFolder: |
458 | cmp byte [esi], 0 |
542 | cmp byte [esi], 0 |
459 | jz .doit |
543 | jz .root_folder |
Line 460... | Line 544... | ||
460 | 544 | ||
461 | push ecx ebx |
545 | push ebx ecx edx |
462 | call ext2_find_lfn |
546 | call ext2_find_lfn ;вернет в ebp адрес inode |
463 | jnc .doit2 |
547 | pop edx ecx ebx |
464 | pop ebx |
- | |
465 | .not_found: |
548 | test eax, eax |
466 | pop ecx |
549 | jnz .error_ret |
467 | or ebx, -1 |
550 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
468 | mov eax, ERROR_FILE_NOT_FOUND |
551 | jz .error_not_found |
Line 469... | Line 552... | ||
469 | ret |
552 | jmp @F |
470 | 553 | ||
471 | .doit: |
- | |
472 | mov ebp, [ext2_data.root_inode] |
- | |
473 | push ecx |
- | |
474 | jmp @F |
- | |
475 | .doit2: |
554 | .root_folder: |
476 | pop ebx |
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 |
|
477 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
565 | rep movsd |
- | 566 | pop ecx |
|
478 | jz .not_found |
567 | @@: |
- | 568 | cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0 ;папка пуста |
|
- | 569 | je .error_empty_dir |
|
- | 570 | ||
- | 571 | push edx ;адрес результата [edi + 28] |
|
- | 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] |
|
479 | @@: |
578 | push 0 ;номер блока по порядку [edi] |
480 | xor eax, eax |
579 | |
481 | mov edi, edx |
580 | mov edi, edx |
482 | mov ecx, 32/4 |
- | |
483 | rep stosd ; fill header zero |
- | |
484 | pop edi ; edi = число блоков для чтения |
- | |
485 | push edx ebx |
- | |
486 | - | ||
487 | ;--------------------------------------------- final step |
- | |
488 | and [EXT2_read_in_folder], 0 |
- | |
489 | and [EXT2_files_in_folder], 0 |
- | |
490 | - | ||
Line 491... | Line 581... | ||
491 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] |
581 | mov ecx, 32/4 |
492 | mov [EXT2_counter_blocks], eax |
582 | rep stosd ; fill header zero |
Line 493... | Line -... | ||
493 | - | ||
494 | add edx, 32 ; (header pointer in stack) edx = current mem for return |
583 | |
495 | xor esi, esi ; esi = номер блока по порядку |
584 | mov edi, esp ; edi - указатель на локальные переменные |
- | 585 | add edx, 32 ; edx = current mem for return |
|
- | 586 | ||
Line 496... | Line 587... | ||
496 | 587 | xor ecx, ecx ; получим номер первого блока |
|
497 | .new_block_folder: ;reserved label |
588 | call ext2_get_inode_block |
498 | mov ecx, esi ; получим номер блока |
589 | test eax, eax |
- | 590 | jnz .error_get_block |
|
- | 591 | ||
Line 499... | Line 592... | ||
499 | call ext2_get_inode_block |
592 | mov eax, ecx |
500 | 593 | mov ebx, [ext2_data.ext2_save_block] |
|
501 | mov eax, ecx |
594 | call ext2_get_block ; и считываем блок с hdd |
Line 502... | Line -... | ||
502 | mov ebx, [ext2_data.ext2_save_block] |
- | |
503 | call ext2_get_block ; и считываем блок с hdd |
595 | test eax, eax |
Line 504... | Line 596... | ||
504 | 596 | jnz .error_get_block |
|
505 | mov eax, ebx ; eax = current dir record |
597 | |
506 | add ebx, [ext2_data.block_size] |
598 | mov esi, ebx ; esi = current dir record |
507 | mov [EXT2_end_block], ebx ; запомним конец очередного блока |
599 | add ebx, [ext2_data.block_size] |
508 | 600 | mov [edi + 24], ebx ; запомним конец очередного блока |
|
509 | pop ecx |
601 | |
510 | mov ecx, [ecx] ; ecx = first wanted (flags ommited) |
602 | mov ecx, [edi + 16] ; ecx = first wanted (flags ommited) |
511 | 603 | ||
512 | .find_wanted_start: |
604 | .find_wanted_start: |
Line 513... | Line 605... | ||
513 | jecxz .find_wanted_end |
605 | jecxz .find_wanted_end |
514 | .find_wanted_cycle: |
606 | .find_wanted_cycle: |
515 | cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
607 | cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
516 | jz @F |
608 | jz @F |
Line 517... | Line 609... | ||
517 | inc [EXT2_files_in_folder] |
609 | inc dword [edi + 4] ; EXT2_files_in_folder |
518 | dec ecx |
610 | dec ecx |
519 | @@: |
611 | @@: |
Line 520... | Line 612... | ||
520 | movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] |
612 | movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] |
521 | 613 | ||
522 | cmp ebx, 12 ; минимальная длина записи |
614 | cmp ebx, 12 ; минимальная длина записи |
523 | jb .end_error |
615 | jb .error_bad_len |
524 | test ebx, 0x3 ; длина записи должна делиться на 4 |
616 | test ebx, 0x3 ; длина записи должна делиться на 4 |
Line 525... | Line 617... | ||
525 | jnz .end_error |
617 | jnz .error_bad_len |
526 | 618 | ||
527 | add eax, ebx ; к следующей записи |
619 | add esi, ebx ; к следующей записи |
528 | cmp eax, [EXT2_end_block] ; проверяем "конец" |
620 | cmp esi, [edi + 24] ; сравниваем с концом блока |
- | 621 | jb .find_wanted_start |
|
- | 622 | ||
- | 623 | push .find_wanted_start |
|
529 | jb .find_wanted_start |
624 | .end_block: ;вылетели из цикла |
530 | 625 | mov ebx, [ext2_data.count_block_in_block] |
|
531 | push .find_wanted_start |
626 | sub [ebp + EXT2_INODE_STRUC.i_blocks], ebx ;вычитаем напрямую из структуры inode |
- | 627 | jle .end_dir |
|
- | 628 | ||
- | 629 | inc dword [edi] ;получаем новый блок |
|
532 | .end_block: ;вылетили из цикла |
630 | push ecx |
533 | mov ebx, [ext2_data.count_block_in_block] |
631 | mov ecx, [edi] |
534 | sub [EXT2_counter_blocks], ebx |
632 | call ext2_get_inode_block |
535 | jbe .end_dir |
633 | test eax, eax |
536 | 634 | jnz .error_get_block |
|
Line 537... | Line 635... | ||
537 | inc esi ;получаем новый блок |
635 | |
538 | push ecx |
636 | mov eax, ecx |
Line -... | Line 637... | ||
- | 637 | mov ebx, [ext2_data.ext2_save_block] |
|
539 | mov ecx, esi |
638 | call ext2_get_block |
540 | call ext2_get_inode_block |
639 | test eax, eax |
541 | mov eax, ecx |
640 | jnz .error_get_block |
542 | mov ebx, [ext2_data.ext2_save_block] |
641 | |
543 | call ext2_get_block |
642 | pop ecx |
544 | pop ecx |
643 | mov esi, ebx |
545 | mov eax, ebx |
644 | add ebx, [ext2_data.block_size] |
546 | add ebx, [ext2_data.block_size] |
645 | mov [edi + 24], ebx ;запомним конец блока |
Line 547... | Line -... | ||
547 | mov [EXT2_end_block], ebx |
- | |
548 | ret ; опять в цикл |
646 | ret ; опять в цикл |
- | 647 | ||
549 | 648 | .wanted_end: |
|
550 | .wanted_end: |
649 | loop .find_wanted_cycle ; ecx 0 => -1 нужно посчитать сколько файлов |
551 | loop .find_wanted_cycle ; ecx = -1 |
650 | |
552 | 651 | ;дошли до первого "нужного" файла |
|
Line 553... | Line 652... | ||
553 | .find_wanted_end: |
652 | .find_wanted_end: |
554 | mov ecx, edi |
653 | mov ecx, [edi + 20] |
555 | .wanted_start: ; ищем first_wanted+count |
654 | .wanted_start: ; ищем first_wanted+count |
556 | jecxz .wanted_end |
655 | jecxz .wanted_end |
- | 656 | cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
|
- | 657 | jz .empty_rec |
|
Line 557... | Line 658... | ||
557 | cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
658 | inc dword [edi + 8] |
Line 558... | Line 659... | ||
558 | jz .empty_rec |
659 | inc dword [edi + 4] |
559 | inc [EXT2_files_in_folder] |
660 | |
Line 597... | Line 698... | ||
597 | 698 | ||
598 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size |
699 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size |
599 | stosd |
700 | stosd |
600 | mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size |
701 | mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size |
601 | stosd |
702 | stosd |
602 | xor dword [edx], FS_FT_DIR |
703 | xor dword [edx], FS_FT_DIR ;помечаем, что это файл(2 раза xor) |
603 | @@: |
- | |
604 | xor dword [edx], FS_FT_DIR |
- | |
605 | pop esi eax |
- | |
606 | 704 | @@: |
|
Line 607... | Line 705... | ||
607 | or dword [edx+4], FS_FT_ASCII ; symbol type in name |
705 | xor dword [edx], FS_FT_DIR ;помечаем, что это файл |
608 | 706 | ||
609 | ;теперь скопируем имя, сконвертировав из UTF-8 в CP866 |
707 | ;теперь скопируем имя, сконвертировав из UTF-8 в CP866 |
610 | push eax ecx esi |
708 | push ecx ;edi и esi уже сохранены в стеке |
611 | movzx ecx, [eax + EXT2_DIR_STRUC.name_len] |
709 | movzx ecx, [esi + EXT2_DIR_STRUC.name_len] |
612 | lea edi, [edx + 40] |
710 | lea edi, [edx + 40] |
613 | lea esi, [eax + EXT2_DIR_STRUC.name] |
- | |
614 | call utf8toansi_str |
711 | lea esi, [esi + EXT2_DIR_STRUC.name] |
- | 712 | call utf8_to_cp866 |
|
Line 615... | Line 713... | ||
615 | pop esi ecx eax |
713 | and byte [edi], 0 |
616 | and byte [edi], 0 |
714 | pop ecx edi esi |
617 | 715 | ||
618 | cmp byte [edx + 40], '.' |
716 | cmp byte [edx + 40], '.' ; в linux файл, начинающийся с точки - скрытый |
Line 619... | Line 717... | ||
619 | jne @F |
717 | jne @F |
620 | or dword [edx], FS_FT_HIDDEN |
718 | or dword [edx], FS_FT_HIDDEN |
621 | @@: |
719 | @@: |
622 | 720 | ||
623 | add edx, 40 + 264 ; go to next record |
721 | add edx, 40 + 264 ; go to next record |
624 | dec ecx ; если запись пустая ecx не надо уменьшать |
722 | dec ecx ; если запись пустая ecx не надо уменьшать |
625 | .empty_rec: |
723 | .empty_rec: |
626 | movzx ebx, [eax + EXT2_DIR_STRUC.rec_len] |
724 | movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] |
Line 627... | Line 725... | ||
627 | cmp ebx, 12 ; минимальная длина записи |
725 | cmp ebx, 12 ; минимальная длина записи |
628 | jb .end_error |
726 | jb .error_bad_len |
629 | test ebx, 0x3 ; длина записи должна делиться на 4 |
727 | test ebx, 0x3 ; длина записи должна делиться на 4 |
Line 630... | Line 728... | ||
630 | jnz .end_error |
728 | jnz .error_bad_len |
631 | 729 | ||
Line 632... | Line -... | ||
632 | add eax, ebx |
- | |
633 | cmp eax, [EXT2_end_block] |
730 | add esi, ebx |
634 | jb .wanted_start |
- | |
635 | 731 | cmp esi, [edi + 24] ;дошли ли до конца блока? |
|
636 | push .wanted_start ; дошли до конца очередного блока |
732 | jb .wanted_start |
637 | jmp .end_block |
733 | |
638 | 734 | push .wanted_start ; дошли |
|
639 | .end_dir: |
- | |
640 | pop eax ; мусор (адрес возврата в цикл) |
735 | jmp .end_block |
641 | .end_error: |
736 | |
- | 737 | .end_dir: ;конец папки, когда еще не дошли до нужного файла |
|
- | 738 | mov edx, [edi + 28] ;адрес структуры результата |
|
- | 739 | mov ebx, [edi + 8] ;EXT2_read_in_folder |
|
- | 740 | mov ecx, [edi + 4] ;EXT2_files_in_folder |
|
642 | pop edx |
741 | mov dword [edx], 1 ;version |
643 | mov ebx, [EXT2_read_in_folder] |
742 | mov [edx + 4], ebx |
644 | mov ecx, [EXT2_files_in_folder] |
743 | mov [edx + 8], ecx |
645 | mov dword [edx], 1 ;version |
744 | |
- | 745 | lea esp, [edi + 32] |
|
- | 746 | ||
646 | xor eax, eax |
747 | xor eax, eax ;зарезервировано: нули в текущей реализации |
- | 748 | lea edi, [edx + 12] |
|
- | 749 | mov ecx, 20 / 4 |
|
- | 750 | rep stosd |
|
647 | mov [edx+4], ebx |
751 | ret |
- | 752 | ||
- | 753 | .error_bad_len: |
|
- | 754 | mov eax, ERROR_FS_FAIL |
|
- | 755 | .error_read_subinode: |
|
- | 756 | .error_get_block: |
|
- | 757 | lea esp, [edi + 32] |
|
- | 758 | .error_ret: |
|
- | 759 | or ebx, -1 |
|
- | 760 | ret |
|
- | 761 | ||
- | 762 | .error_empty_dir: ;inode папки без блоков |
|
- | 763 | .error_root: ;root - не папка |
|
- | 764 | mov eax, ERROR_FS_FAIL |
|
648 | mov [edx+8], ecx |
765 | jmp .error_ret |
649 | lea edi, [edx + 12] |
766 | |
- | 767 | .error_not_found: ;файл не найден |
|
- | 768 | mov eax, ERROR_FILE_NOT_FOUND |
|
650 | mov ecx, 20 / 4 |
769 | jmp .error_ret |
- | 770 | ||
651 | rep stosd |
771 | ;============================================ |
652 | ret |
772 | ;convert UTF-8 string to ASCII-string (codepage 866) |
653 | ;====================== end ext2_HdReadFolder |
773 | ;in: ecx = length source |
654 | utf8toansi_str: |
774 | ; esi = source |
655 | ; convert UTF-8 string to ASCII-string (codepage 866) |
775 | ; edi = buffer |
Line 710... | Line 830... | ||
710 | ; ecx number of bytes to read, 0+ |
830 | ; ecx number of bytes to read, 0+ |
711 | ; edx mem location to return data |
831 | ; edx mem location to return data |
712 | ; |
832 | ; |
713 | ; ret ebx = bytes read or 0xffffffff file not found |
833 | ; ret ebx = bytes read or 0xffffffff file not found |
714 | ; eax = 0 ok read or other = errormsg |
834 | ; eax = 0 ok read or other = errormsg |
715 | ; |
835 | |
716 | ;-------------------------------------------------------------- |
836 | ;-------------------------------------------------------------- |
717 | ext2_HdRead: |
837 | ext2_HdRead: |
718 | cmp byte [esi], 0 |
838 | cmp byte [esi], 0 |
719 | jnz @F |
839 | jnz @F |
Line 722... | Line 842... | ||
722 | or ebx, -1 |
842 | or ebx, -1 |
723 | mov eax, ERROR_ACCESS_DENIED |
843 | mov eax, ERROR_ACCESS_DENIED |
724 | ret |
844 | ret |
Line 725... | Line 845... | ||
725 | 845 | ||
726 | @@: |
846 | @@: |
727 | push ecx ebx |
847 | push ecx ebx edx |
728 | call ext2_find_lfn |
848 | call ext2_find_lfn |
729 | pop ebx ecx |
849 | pop edx ebx ecx |
730 | jnc .doit |
850 | test eax, eax |
- | 851 | jz @F |
|
731 | ;.not_found: |
852 | |
732 | or ebx, -1 |
853 | or ebx, -1 |
733 | mov eax, ERROR_FILE_NOT_FOUND |
854 | mov eax, ERROR_FILE_NOT_FOUND |
Line 734... | Line 855... | ||
734 | ret |
855 | ret |
735 | 856 | ||
- | 857 | @@: |
|
- | 858 | mov ax, [ebp + EXT2_INODE_STRUC.i_mode] |
|
736 | .doit: |
859 | and ax, EXT2_S_IFMT ;оставляем только тип inode в ax |
Line 737... | Line -... | ||
737 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG |
- | |
738 | jz .this_is_nofile |
860 | cmp ax, EXT2_S_IFREG |
739 | - | ||
Line -... | Line 861... | ||
- | 861 | jne .this_is_nofile |
|
- | 862 | ||
740 | ;-----------------------------------------------------------------------------final step |
863 | mov edi, edx ; edi = pointer to return mem |
741 | mov edi, edx ; edi = pointer to return mem |
864 | |
742 | mov esi, ebx ; esi = pointer to first_wanted |
865 | test ebx, ebx |
Line -... | Line 866... | ||
- | 866 | jz @F |
|
743 | 867 | mov esi, ebx ; esi = pointer to first_wanted |
|
744 | ;///// сравним хватит ли нам файла или нет |
868 | mov ebx, [esi+4] |
745 | mov ebx, [esi+4] |
869 | mov eax, [esi] ; ebx : eax - стартовый номер байта |
Line 746... | Line 870... | ||
746 | mov eax, [esi] ; ebx : eax - стартовый номер байта |
870 | |
Line 754... | Line 878... | ||
754 | 878 | ||
755 | .size_less: |
879 | .size_less: |
756 | xor ebx, ebx |
880 | xor ebx, ebx |
757 | mov eax, ERROR_END_OF_FILE |
881 | mov eax, ERROR_END_OF_FILE |
- | 882 | ret |
|
- | 883 | ||
- | 884 | @@: |
|
- | 885 | xor ebx, ebx |
|
758 | ret |
886 | xor eax, eax |
759 | .size_great: |
887 | .size_great: |
760 | add eax, ecx ;add to first_wanted кол-во байт для чтения |
888 | add eax, ecx ;add to first_wanted кол-во байт для чтения |
Line 761... | Line 889... | ||
761 | adc ebx, 0 |
889 | adc ebx, 0 |
762 | 890 | ||
763 | cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
891 | cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
764 | ja .size_great_great |
892 | ja .size_great_great |
765 | jb .size_great_less |
893 | jb .size_great_less |
Line 766... | Line 894... | ||
766 | cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
894 | cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
- | 895 | jae .size_great_great |
|
767 | jae .size_great_great ; а если равно, то не важно куда |
896 | |
768 | 897 | .size_great_less: |
|
769 | .size_great_less: |
898 | push 1 |
770 | or [EXT2_files_in_folder], 1 ;читаем по границе размера |
899 | ; or [EXT2_files_in_folder], 1 ;читаем по границе размера |
Line 771... | Line 900... | ||
771 | mov ecx, [ebp + EXT2_INODE_STRUC.i_size] |
900 | mov ecx, [ebp + EXT2_INODE_STRUC.i_size] |
- | 901 | sub ecx, [esi] ;(размер - старт) = сколько читать |
|
772 | sub ecx, [esi] ;(размер - старт) |
902 | jmp @F |
Line 773... | Line 903... | ||
773 | jmp @F |
903 | |
- | 904 | .size_great_great: |
|
- | 905 | push 0 |
|
- | 906 | ; and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили |
|
- | 907 | ||
774 | 908 | @@: |
|
775 | .size_great_great: |
909 | ;здесь мы точно знаем сколько байт читать - ecx |
776 | and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили |
910 | ;edi - return memory |
Line 777... | Line 911... | ||
777 | 911 | ;esi -> first wanted |
|
778 | @@: |
912 | |
779 | push ecx ;save for return |
913 | push ecx ;количество считанных байт |
780 | test esi, esi |
914 | test esi, esi |
Line 781... | Line 915... | ||
781 | jz .zero_start |
915 | jz .zero_start |
Line 782... | Line 916... | ||
782 | 916 | ||
783 | ;пока делаем п..ц криво =) |
917 | ;получим кусок из первого блока |
784 | mov edx, [esi+4] |
918 | mov edx, [esi+4] |
- | 919 | mov eax, [esi] |
|
- | 920 | div [ext2_data.block_size] |
|
785 | mov eax, [esi] |
921 | |
786 | div [ext2_data.block_size] |
922 | push eax ;номер блока запоминаем |
787 | 923 | ||
- | 924 | push ecx |
|
- | 925 | mov ecx, eax |
|
788 | mov [EXT2_counter_blocks], eax ;номер блока запоминаем |
926 | call ext2_get_inode_block |
789 | 927 | test eax, eax |
|
Line 790... | Line 928... | ||
790 | push ecx |
928 | jnz .error_at_first_block |
791 | mov ecx, eax |
929 | mov ebx, [ext2_data.ext2_save_block] |
Line 805... | Line 943... | ||
805 | sub eax, edx |
943 | sub eax, edx |
806 | mov ecx, edx |
944 | mov ecx, edx |
Line 807... | Line 945... | ||
807 | 945 | ||
808 | mov esi, ebx |
946 | mov esi, ebx |
809 | rep movsb ;кусок 1-го блока |
947 | rep movsb ;кусок 1-го блока |
Line 810... | Line 948... | ||
810 | jmp @F |
948 | jmp .calc_blocks_count |
811 | 949 | ||
- | 950 | .zero_start: |
|
812 | .zero_start: |
951 | mov eax, ecx |
813 | mov eax, ecx |
952 | push 0 ;счетчик блоков |
814 | ;теперь в eax кол-во оставшихся байт для чтения |
953 | ;теперь в eax кол-во оставшихся байт для чтения |
815 | @@: |
954 | .calc_blocks_count: |
816 | mov ebx, edi ;чтение блока прям в ->ebx |
955 | mov ebx, edi ;чтение блока прям в ->ebx |
817 | xor edx, edx |
956 | xor edx, edx |
818 | div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx |
957 | div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx |
819 | mov edi, eax ;кол-во целых блоков в edi |
958 | mov edi, eax ;кол-во целых блоков в edi |
820 | @@: |
959 | @@: |
821 | test edi, edi |
960 | test edi, edi |
822 | jz .finish_block |
961 | jz .finish_block |
823 | inc [EXT2_counter_blocks] |
962 | inc dword [esp] |
- | 963 | mov ecx, [esp] |
|
- | 964 | call ext2_get_inode_block |
|
Line 824... | Line 965... | ||
824 | mov ecx, [EXT2_counter_blocks] |
965 | test eax, eax |
825 | call ext2_get_inode_block |
966 | jnz .error_at_read_cycle |
- | 967 | ||
- | 968 | mov eax, ecx ;а ebx уже забит нужным значением |
|
826 | 969 | call ext2_get_block |
|
Line 827... | Line 970... | ||
827 | mov eax, ecx ;а ebx уже забит нужным значением |
970 | test eax, eax |
828 | call ext2_get_block |
971 | jnz .error_at_read_cycle |
Line 829... | Line 972... | ||
829 | add ebx, [ext2_data.block_size] |
972 | add ebx, [ext2_data.block_size] |
830 | 973 | ||
831 | dec edi |
974 | dec edi |
Line 832... | Line 975... | ||
832 | jmp @B |
975 | jmp @B |
833 | 976 | ||
834 | .finish_block: ;в edx - кол-во байт в последнем блоке |
977 | .finish_block: ;в edx - кол-во байт в последнем блоке |
- | 978 | test edx, edx |
|
- | 979 | jz .end_read |
|
Line 835... | Line 980... | ||
835 | test edx, edx |
980 | |
836 | jz .end_read |
981 | pop ecx ;счетчик блоков -> ecx |
837 | 982 | inc ecx |
|
838 | mov ecx, [EXT2_counter_blocks] |
983 | call ext2_get_inode_block |
- | 984 | test eax, eax |
|
- | 985 | jz .error_at_finish_block |
|
Line 839... | Line 986... | ||
839 | inc ecx |
986 | |
840 | call ext2_get_inode_block |
- | |
841 | - | ||
842 | mov edi, ebx |
987 | mov edi, ebx |
843 | mov eax, ecx |
988 | mov eax, ecx |
844 | mov ebx, [ext2_data.ext2_save_block] |
989 | mov ebx, [ext2_data.ext2_save_block] |
845 | call ext2_get_block |
990 | call ext2_get_block |
- | 991 | test eax, eax |
|
846 | 992 | jnz .error_at_finish_block |
|
847 | mov ecx, edx |
993 | |
Line 848... | Line 994... | ||
848 | 994 | mov ecx, edx |
|
849 | .only_one_block: |
995 | mov esi, ebx |
850 | mov esi, ebx |
996 | rep movsb ;кусок last блока |
851 | rep movsb ;кусок last блока |
997 | .end_read: |
852 | .end_read: |
998 | pop ebx |
- | 999 | pop eax |
|
- | 1000 | test eax, eax |
|
- | 1001 | jz @F |
|
- | 1002 | ||
- | 1003 | mov eax, ERROR_END_OF_FILE |
|
- | 1004 | ret |
|
- | 1005 | @@: |
|
- | 1006 | xor eax, eax |
|
- | 1007 | ret |
|
- | 1008 | ||
- | 1009 | .only_one_block: |
|
- | 1010 | mov esi, ebx |
|
- | 1011 | rep movsb ;кусок last блока |
|
- | 1012 | pop eax |
|
- | 1013 | jmp .end_read |
|
- | 1014 | ||
- | 1015 | .error_at_first_block: |
|
- | 1016 | pop edx |
|
- | 1017 | .error_at_read_cycle: |
|
- | 1018 | pop ebx |
|
- | 1019 | .error_at_finish_block: |
|
- | 1020 | pop ecx edx |
|
- | 1021 | or ebx, -1 |
|
- | 1022 | ret |
|
- | 1023 | ||
- | 1024 | ;---------------------------------------------------------------- |
|
- | 1025 | ; in: esi = file path |
|
- | 1026 | ; ebx = pointer to dir block |
|
- | 1027 | ; out: esi - name without parent or not_changed |
|
- | 1028 | ; ebx - dir_rec of inode children |
|
- | 1029 | ext2_test_block_by_name: |
|
- | 1030 | sub esp, 256 ;EXT2_filename |
|
- | 1031 | mov edx, ebx |
|
- | 1032 | add edx, [ext2_data.block_size] ;запомним конец блока |
|
- | 1033 | ||
- | 1034 | .start_rec: |
|
- | 1035 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 |
|
- | 1036 | jz .next_rec |
|
- | 1037 | ||
- | 1038 | mov edi, esp |
|
- | 1039 | push esi |
|
- | 1040 | movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] |
|
- | 1041 | lea esi, [ebx + EXT2_DIR_STRUC.name] |
|
- | 1042 | call utf8_to_cp866 |
|
- | 1043 | ||
- | 1044 | mov ecx, edi |
|
- | 1045 | lea edi, [esp + 4] |
|
- | 1046 | sub ecx, edi ;кол-во байт в получившейся строке |
|
- | 1047 | ||
- | 1048 | mov esi, [esp] |
|
- | 1049 | @@: |
|
- | 1050 | jecxz .test_find |
|
- | 1051 | dec ecx |
|
- | 1052 | ||
- | 1053 | lodsb |
|
- | 1054 | call char_toupper |
|
- | 1055 | ||
- | 1056 | mov ah, [edi] |
|
- | 1057 | inc edi |
|
- | 1058 | xchg al, ah |
|
- | 1059 | call char_toupper |
|
- | 1060 | cmp al, ah |
|
- | 1061 | je @B |
|
- | 1062 | @@: ;не подошло |
|
- | 1063 | pop esi |
|
- | 1064 | .next_rec: |
|
- | 1065 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
|
- | 1066 | add ebx, eax ;к след. записи |
|
- | 1067 | cmp ebx, edx ;проверим конец ли |
|
- | 1068 | jb .start_rec |
|
- | 1069 | add esp, 256 |
|
- | 1070 | ret |
|
- | 1071 | ||
- | 1072 | .test_find: |
|
853 | pop ebx |
1073 | cmp byte [esi], 0 |
854 | cmp [EXT2_files_in_folder], 0 |
1074 | je .ret ;нашли конец |
- | 1075 | cmp byte [esi], '/' |
|
855 | jz @F |
1076 | jne @B |
856 | 1077 | inc esi |
|
- | 1078 | .ret: |
|
857 | mov eax, ERROR_END_OF_FILE |
1079 | add esp, 256 + 4 |
858 | ret |
1080 | ret |
859 | @@: |
- | |
860 | xor eax, eax |
- | |
861 | ret |
- | |
862 | ;======================== |
1081 | |
863 | ;in : esi -> name not save: eax ebx ecx |
1082 | ;======================== |
- | 1083 | ;Ищет inode по строке пути |
|
864 | ;out: ebp -> inode cf=0 |
1084 | ;in: esi = name |
865 | ; ebp -> trash cf=1 |
1085 | ;out: eax - error code |
866 | ext2_find_lfn: |
1086 | ; ebp = inode |
867 | mov ebp, [ext2_data.root_inode] |
1087 | ; dl - первый байт из имени файла/папки |
868 | .next_folder: |
- | |
869 | or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode |
- | |
870 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков |
1088 | ext2_find_lfn: |
- | 1089 | mov ebp, [ext2_data.root_inode] |
|
- | 1090 | cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0 |
|
Line 871... | Line 1091... | ||
871 | add eax, [ext2_data.count_block_in_block] |
1091 | je .error_empty_root |
872 | mov [EXT2_end_block], eax |
1092 | |
873 | .next_block_folder: |
1093 | .next_path_part: |
- | 1094 | push [ebp + EXT2_INODE_STRUC.i_blocks] |
|
- | 1095 | xor ecx, ecx |
|
Line 874... | Line 1096... | ||
874 | mov eax, [ext2_data.count_block_in_block] |
1096 | .folder_block_cycle: |
875 | sub [EXT2_end_block], eax |
1097 | call ext2_get_inode_block |
876 | jz .not_found |
- | |
877 | inc [EXT2_counter_blocks] |
1098 | test eax, eax |
Line 878... | Line 1099... | ||
878 | mov ecx, [EXT2_counter_blocks] |
1099 | jnz .error_get_inode_block |
- | 1100 | ||
- | 1101 | mov eax, ecx |
|
- | 1102 | mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
|
879 | call ext2_get_inode_block |
1103 | call ext2_get_block |
Line 880... | Line 1104... | ||
880 | 1104 | test eax, eax |
|
881 | mov eax, ecx |
1105 | jnz .error_get_block |
- | 1106 | ||
882 | mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
1107 | push esi |
883 | call ext2_get_block |
1108 | call ext2_test_block_by_name |
884 | 1109 | pop edi |
|
- | 1110 | ||
- | 1111 | cmp edi, esi ;нашли имя? |
|
- | 1112 | je .next_folder_block ;не нашли -> к след. блоку |
|
885 | mov eax, esi |
1113 | |
886 | call ext2_test_block_by_name |
1114 | cmp byte [esi], 0 ;дошли до "конца" пути -> возваращаемся |
- | 1115 | jz .get_inode_ret |
|
- | 1116 | ||
- | 1117 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;нашли, но это не папка |
|
- | 1118 | jne .not_found |
|
- | 1119 | ||
- | 1120 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
|
- | 1121 | mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
|
- | 1122 | call ext2_get_inode |
|
- | 1123 | test eax, eax |
|
Line 887... | Line 1124... | ||
887 | cmp eax, esi ;нашли имя? |
1124 | jnz .error_get_inode |
888 | jz .next_block_folder |
1125 | pop ecx ;в стеке лежит кол-во блоков |
- | 1126 | mov ebp, ebx |
|
889 | 1127 | jmp .next_path_part |
|
- | 1128 | ||
890 | cmp byte [esi], 0 |
1129 | .next_folder_block: |
891 | jz .get_inode_ret |
1130 | ;к следующему блоку в текущей папке |
- | 1131 | pop eax ;счетчик блоков |
|
892 | 1132 | sub eax, [ext2_data.count_block_in_block] |
|
893 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR |
1133 | jle .not_found |
894 | jne .not_found ;нашли, но это не папка |
1134 | |
895 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
1135 | inc ecx |
896 | mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
1136 | jmp .folder_block_cycle |
897 | call ext2_get_inode |
1137 | |
Line -... | Line 1138... | ||
- | 1138 | .not_found: |
|
- | 1139 | pop ebx |
|
- | 1140 | mov eax, ERROR_FILE_NOT_FOUND |
|
- | 1141 | ret |
|
- | 1142 | ||
- | 1143 | .get_inode_ret: |
|
- | 1144 | pop ecx ;в стеке лежит кол-во блоков |
|
Line -... | Line 1145... | ||
- | 1145 | mov dl, [ebx + EXT2_DIR_STRUC.name] ;в dl - первый символ () |
|
898 | mov ebp, ebx |
1146 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
899 | jmp .next_folder |
1147 | mov ebx, [ext2_data.ext2_save_inode] |
- | 1148 | call ext2_get_inode |
|
- | 1149 | mov ebp, ebx |
|
- | 1150 | xor eax, eax |
|
900 | 1151 | ret |
|
- | 1152 | ||
901 | .not_found: |
1153 | .error_get_inode_block: |
902 | stc |
1154 | .error_get_block: |
Line -... | Line 1155... | ||
- | 1155 | .error_get_inode: |
|
903 | ret |
1156 | pop ebx |
904 | .get_inode_ret: |
1157 | .error_empty_root: |
905 | mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec |
1158 | mov eax, ERROR_FS_FAIL |
906 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
1159 | ret |
- | 1160 | ||
907 | mov ebx, [ext2_data.ext2_save_inode] |
1161 | ;---------------------------------------------------------------- |
Line 908... | Line 1162... | ||
908 | call ext2_get_inode |
1162 | ;ext2_HdGetFileInfo - read file info from block device |
- | 1163 | ; |
|
909 | mov ebp, ebx |
1164 | ;in: esi points to filename |
910 | clc |
- | |
911 | ret |
- | |
912 | - | ||
913 | - | ||
914 | ;======================== |
- | |
915 | 1165 | ; edx mem location to return data |
|
916 | ext2_HdGetFileInfo: |
1166 | ;-------------------------------------------------------------- |
917 | cmp byte [esi], 0 |
1167 | ext2_HdGetFileInfo: |
918 | jz .doit |
1168 | xchg bx, bx |
919 | 1169 | cmp byte [esi], 0 |
|
Line 920... | Line 1170... | ||
920 | call ext2_find_lfn |
1170 | jz .is_root |
921 | jnc .doit2 |
1171 | |
922 | ;.not_found: |
1172 | push edx |
923 | mov eax, ERROR_FILE_NOT_FOUND |
1173 | call ext2_find_lfn |
Line 924... | Line 1174... | ||
924 | ret |
1174 | mov ebx, edx |
925 | 1175 | pop edx |
|
Line 950... | Line 1200... | ||
950 | xor dword [edx], FS_FT_DIR |
1200 | xor dword [edx], FS_FT_DIR |
951 | @@: |
1201 | @@: |
952 | xor dword [edx], FS_FT_DIR |
1202 | xor dword [edx], FS_FT_DIR |
Line 953... | Line 1203... | ||
953 | 1203 | ||
954 | lea edi, [edx + 8] |
1204 | lea edi, [edx + 8] |
955 | mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] |
1205 | mov eax, [ebp + EXT2_INODE_STRUC.i_ctime] |
956 | xor edx, edx |
1206 | xor edx, edx |
957 | add eax, 3054539008 |
1207 | add eax, 3054539008 |
958 | adc edx, 2 |
1208 | adc edx, 2 |
Line 959... | Line 1209... | ||
959 | call ntfs_datetime_to_bdfe.sec |
1209 | call ntfs_datetime_to_bdfe.sec |
960 | 1210 | ||
961 | mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
1211 | mov eax, [ebp + EXT2_INODE_STRUC.i_atime] |
962 | xor edx, edx |
1212 | xor edx, edx |
963 | add eax, 3054539008 |
1213 | add eax, 3054539008 |
Line 964... | Line 1214... | ||
964 | adc edx, 2 |
1214 | adc edx, 2 |
965 | call ntfs_datetime_to_bdfe.sec |
1215 | call ntfs_datetime_to_bdfe.sec |
966 | 1216 | ||
967 | mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
1217 | mov eax, [ebp + EXT2_INODE_STRUC.i_mtime] |
968 | xor edx, edx |
1218 | xor edx, edx |
Line 980... | Line 1230... | ||
980 | ext2_HdDelete: |
1230 | ext2_HdDelete: |
981 | ext2_HdCreateFolder: |
1231 | ext2_HdCreateFolder: |
982 | xor ebx, ebx |
1232 | xor ebx, ebx |
983 | mov eax, ERROR_UNSUPPORTED_FS |
1233 | mov eax, ERROR_UNSUPPORTED_FS |
984 | ret |
1234 | ret |
985 | ;---------------------------------------------------------------- |
- | |
986 | ; |
- | |
987 | ; ext2_HdCreateFolder - create new folder |
- | |
988 | ; |
- | |
989 | ; esi points to filename |
- | |
990 | ; |
- | |
991 | ; ret eax = 0 ok read or other = errormsg |
- | |
992 | ; |
- | |
993 | ;-------------------------------------------------------------- |
- | |
994 | cmp byte [esi], 0 |
- | |
995 | jz .not_found |
- | |
996 | cmp byte [esi], '/' |
- | |
997 | jz .not_found |
- | |
998 | - | ||
999 | mov ebx, esi ; save source pointer |
- | |
1000 | xor edi, edi ; slah pointer |
- | |
1001 | @@: |
- | |
1002 | lodsb |
- | |
1003 | cmp al, 0 |
- | |
1004 | jz .zero |
- | |
1005 | cmp al, '/' |
- | |
1006 | jz .slash |
- | |
1007 | jmp @B |
- | |
1008 | - | ||
1009 | .slash: |
- | |
1010 | lodsb |
- | |
1011 | cmp al, 0 |
- | |
1012 | jz .zero ; уберем слеш из имени |
- | |
1013 | cmp al, '/' |
- | |
1014 | jz .not_found |
- | |
1015 | mov edi, esi ; edi -> next symbol after '/' |
- | |
1016 | dec edi |
- | |
1017 | jmp @B |
- | |
1018 | - | ||
1019 | .zero: |
- | |
1020 | dec esi |
- | |
1021 | test edi, edi |
- | |
1022 | jz .doit |
- | |
1023 | - | ||
1024 | ;слеш был |
- | |
1025 | mov eax, esi |
- | |
1026 | sub eax, edi |
- | |
1027 | mov [EXT2_name_len], eax |
- | |
1028 | - | ||
1029 | mov ecx, edi |
- | |
1030 | sub ecx, ebx |
- | |
1031 | dec ecx ;выкинули '/' из имени ролителя |
- | |
1032 | mov esi, ebx |
- | |
1033 | mov edi, EXT2_parent_name |
- | |
1034 | rep movsb |
- | |
1035 | ; esi - pointer to last slash |
- | |
1036 | - | ||
1037 | mov edx, esi |
- | |
1038 | mov esi, EXT2_parent_name |
- | |
1039 | call ext2_find_lfn |
- | |
1040 | jnc .doit2 |
- | |
1041 | .not_found: |
- | |
1042 | or ebx, -1 |
- | |
1043 | mov eax, ERROR_FILE_NOT_FOUND |
- | |
1044 | ret |
- | |
1045 | - | ||
1046 | .doit: |
- | |
1047 | mov ebp, [ext2_data.root_inode] |
- | |
1048 | mov edx, ebx ; имя создаваемой папки |
- | |
1049 | sub esi, ebx |
- | |
1050 | mov [EXT2_name_len], esi |
- | |
1051 | .doit2: |
- | |
1052 | ;ebp -> parent_inode ebx->name_new_folder [EXT2_name_len]=length of name |
- | |
1053 | ; стратегия выбора группы для нового inode: (так делает линукс) |
- | |
1054 | ; 1) Ищем группу в которой меньше всего папок и в есть свободное место |
- | |
1055 | ; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места |
- | |
1056 | - | ||
1057 | - | ||
1058 | - | ||
1059 | - | ||
1060 | call ext2_balloc |
- | |
1061 | jmp ext2_HdDelete |
- | |
1062 | - | ||
1063 | push ebx |
- | |
1064 | push ebp |
- | |
1065 | - | ||
1066 | mov ecx, [ext2_data.sb] |
- | |
1067 | cmp [ecx + EXT2_SB_STRUC.free_inodes_count], 0 ; есть ли место для inode |
- | |
1068 | jz .no_space |
- | |
1069 | mov eax, [ecx + EXT2_SB_STRUC.free_block_count] |
- | |
1070 | sub eax, [ecx + EXT2_SB_STRUC.r_block_count] |
- | |
1071 | cmp eax, 2 ; и как минимум на 2 блока |
- | |
1072 | jb .no_space |
- | |
1073 | - | ||
1074 | mov ecx, [ext2_data.groups_count] |
- | |
1075 | mov esi, [ext2_data.global_desc_table] |
- | |
1076 | mov edi, -1 ;указатель на лучшую группу |
- | |
1077 | mov edx, 0 |
- | |
1078 | .find_group_dir: |
- | |
1079 | jecxz .end_find_group_dir |
- | |
1080 | movzx eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count] |
- | |
1081 | cmp eax, edx |
- | |
1082 | jbe @F |
- | |
1083 | cmp [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0 |
- | |
1084 | jz @F |
- | |
1085 | mov edi, esi |
- | |
1086 | movzx edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count] |
- | |
1087 | @@: |
- | |
1088 | dec ecx |
- | |
1089 | add esi, 32 ;размер структуры |
- | |
1090 | jmp .find_group_dir |
- | |
1091 | .end_find_group_dir: |
- | |
1092 | cmp edx, 0 |
- | |
1093 | jz .no_space |
- | |
1094 | - | ||
1095 | ;нашли группу, получим битовую карту inode-ов (найдем locale number) |
- | |
1096 | mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap] |
- | |
1097 | mov ebx, [ext2_data.ext2_save_block] |
- | |
1098 | call ext2_get_block |
- | |
1099 | - | ||
1100 | ;теперь цикл по всем битам |
- | |
1101 | mov esi, ebx |
- | |
1102 | mov ecx, [ext2_data.inodes_per_group] |
- | |
1103 | shr ecx, 5 ;делим на 32 |
- | |
1104 | mov ebp, ecx ; всего сохраним в ebp |
- | |
1105 | or eax, -1 ; ищем первый свободный inode (!= -1) |
- | |
1106 | repne scasd |
- | |
1107 | jnz .test_last_dword ;нашли или нет |
- | |
1108 | mov eax, [esi-4] |
- | |
1109 | - | ||
1110 | sub ebp, ecx |
- | |
1111 | dec ebp |
- | |
1112 | shl ebp, 5 ; глобальный номер локального номера |
- | |
1113 | - | ||
1114 | mov ecx, 32 |
- | |
1115 | @@: |
- | |
1116 | test eax, 1 |
- | |
1117 | jz @F |
- | |
1118 | shr eax, 1 |
- | |
1119 | loop @B |
- | |
1120 | @@: |
- | |
1121 | mov eax, 32 |
- | |
1122 | sub eax, ecx |
- | |
1123 | - | ||
1124 | add ebp, eax ; locale num of inode |
- | |
1125 | - | ||
1126 | mov eax, [esi-4] |
- | |
1127 | ;устанавливаем в eax крайний справа нулевой бит в 1 |
- | |
1128 | mov ecx, eax |
- | |
1129 | inc ecx |
- | |
1130 | or eax, ecx ; x | (x+1) |
- | |
1131 | mov [esi-4], eax |
- | |
1132 | mov ebx, [ext2_data.ext2_save_block] |
- | |
1133 | mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap] |
- | |
1134 | call ext2_set_block |
- | |
1135 | ;считаем таблицу inode |
- | |
1136 | sub edi, [ext2_data.global_desc_table] |
- | |
1137 | shr edi, 5 |
- | |
1138 | - | ||
1139 | mov eax, edi |
- | |
1140 | mul [ext2_data.inodes_per_group] |
- | |
1141 | add eax, ebp |
- | |
1142 | inc eax ; теперь в eax (ebp) номер inode-а |
- | |
1143 | mov ebp, eax |
- | |
1144 | ;call ext2_get_inode_address |
- | |
1145 | - | ||
1146 | mov ebx, [ext2_data.ext2_save_block] |
- | |
1147 | call hd_read |
- | |
1148 | add edx, ebx ; в edx адрес нужного inode |
- | |
1149 | - | ||
1150 | ;забьем 0 для начала |
- | |
1151 | mov edi, edx |
- | |
1152 | mov ecx, [ext2_data.inode_size] |
- | |
1153 | shr ecx, 2 |
- | |
1154 | xor eax, eax |
- | |
1155 | rep stosd |
- | |
1156 | - | ||
1157 | mov edi, edx |
- | |
1158 | mov eax, EXT2_S_IFDIR or EXT2_777_MODE |
- | |
1159 | stosd ; i_mode |
- | |
1160 | xor eax, eax |
- | |
1161 | stosd ; i_uid |
- | |
1162 | mov eax, [ext2_data.block_size] |
- | |
1163 | stosd ; i_size |
- | |
1164 | xor eax, eax |
- | |
1165 | stosd ; i_atime |
- | |
1166 | stosd ; i_ctime |
- | |
1167 | stosd ; i_mtime |
- | |
1168 | stosd ; i_dtime |
- | |
1169 | stosd ; i_gid |
- | |
1170 | inc eax |
- | |
1171 | stosd ; i_links_count |
- | |
1172 | mov eax, [ext2_data.count_block_in_block] |
- | |
1173 | stosd ; i_blocks |
- | |
1174 | - | ||
1175 | - | ||
1176 | - | ||
1177 | - | ||
1178 | .test_last_dword: |
- | |
1179 | - | ||
1180 | xor ebx, ebx |
- | |
1181 | mov eax, ERROR_UNSUPPORTED_FS |
- | |
1182 | ret |
- | |
1183 | - | ||
1184 | - | ||
1185 | - | ||
1186 | .no_space: |
- | |
1187 | or ebx, -1 |
- | |
1188 | mov eax, ERROR_DISK_FULL |
- | |
1189 | ret |
- | |
1190 | - | ||
1191 | ;выделяет новый блок, если это можно |
- | |
1192 | ;иначе возвращает eax=0 |
- | |
1193 | ext2_balloc: |
- | |
1194 | mov ecx, [ext2_data.sb] |
- | |
1195 | mov eax, [ecx + EXT2_SB_STRUC.free_block_count] |
- | |
1196 | sub eax, [ecx + EXT2_SB_STRUC.r_block_count] |
- | |
1197 | jbe .no_space |
- | |
1198 | - | ||
1199 | mov ecx, [ext2_data.groups_count] |
- | |
1200 | mov edi, [ext2_data.global_desc_table] |
- | |
1201 | ;mov esi, -1 ;указатель на лучшую группу |
- | |
1202 | mov edx, 0 |
- | |
1203 | .find_group: |
- | |
1204 | jecxz .end_find_group |
- | |
1205 | movzx eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count] |
- | |
1206 | cmp eax, edx |
- | |
1207 | jbe @F |
- | |
1208 | mov esi, edi |
- | |
1209 | mov edx, eax |
- | |
1210 | @@: |
- | |
1211 | dec ecx |
- | |
1212 | add edi, 32 ;размер структуры |
- | |
1213 | jmp .find_group |
- | |
1214 | .end_find_group: |
- | |
1215 | cmp edx, 0 |
- | |
1216 | jz .no_space |
- | |
1217 | - | ||
1218 | ;нашли группу, получим битовую карту block-ов |
- | |
1219 | mov eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap] |
- | |
1220 | mov ebx, [ext2_data.ext2_save_block] |
- | |
1221 | call ext2_get_block |
- | |
1222 | - | ||
1223 | ;теперь цикл по всем битам |
- | |
1224 | mov edi, ebx |
- | |
1225 | mov ecx, [ext2_data.blocks_per_group] |
- | |
1226 | shr ecx, 5 ;делим на 32 |
- | |
1227 | mov ebp, ecx ;всего сохраним в ebp |
- | |
1228 | or eax, -1 ;ищем первый свободный inode (!= -1) |
- | |
1229 | repe scasd |
- | |
1230 | jz .test_last_dword ;нашли или нет |
- | |
1231 | - | ||
1232 | mov eax, [edi-4] |
- | |
1233 | sub ebp, ecx |
- | |
1234 | dec ebp |
- | |
1235 | shl ebp, 5 ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32) |
- | |
1236 | - | ||
1237 | mov ecx, 32 |
- | |
1238 | @@: |
- | |
1239 | test eax, 1 |
- | |
1240 | jz @F |
- | |
1241 | shr eax, 1 |
- | |
1242 | loop @B |
- | |
1243 | @@: |
- | |
1244 | mov eax, 32 |
- | |
1245 | sub eax, ecx |
- | |
1246 | - | ||
1247 | add ebp, eax ; ebp = номер блока в группе |
- | |
1248 | - | ||
1249 | mov eax, [edi-4] |
- | |
1250 | mov ecx, eax |
- | |
1251 | inc ecx |
- | |
1252 | or eax, ecx ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used) |
- | |
1253 | mov [edi-4], eax |
- | |
1254 | - | ||
1255 | mov ebx, [ext2_data.ext2_save_block] |
- | |
1256 | mov eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap] |
- | |
1257 | ; call ext2_set_block ; и пишем на hdd новую битовую маску |
- | |
1258 | - | ||
1259 | ;============== тут получаем номер блока |
- | |
1260 | mov eax, [ext2_data.blocks_per_group] |
- | |
1261 | sub esi, [ext2_data.global_desc_table] |
- | |
1262 | shr esi, 5 ;esi - номер группы |
- | |
1263 | mul esi |
- | |
1264 | add ebp, eax ;(номер_группы) * (blocks_per_group) + локальный номер в группе |
- | |
1265 | mov eax, [ext2_data.sb] |
- | |
1266 | add ebp, [eax + EXT2_SB_STRUC.first_data_block] |
- | |
1267 | - | ||
1268 | ;теперь поправим глобальную дескрипторную таблицу и суперблок |
- | |
1269 | mov ebx, [ext2_data.sb] |
- | |
1270 | dec [ebx + EXT2_SB_STRUC.free_block_count] |
- | |
1271 | mov eax, 2 |
- | |
1272 | add eax, [PARTITION_START] |
- | |
1273 | call hd_write |
- | |
1274 | mov eax, [ebx + EXT2_SB_STRUC.first_data_block] |
- | |
1275 | inc eax |
- | |
1276 | dec [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок |
- | |
1277 | call ext2_set_block |
- | |
1278 | - | ||
1279 | mov eax, ebx |
- | |
1280 | ret |
- | |
1281 | - | ||
1282 | .test_last_dword: |
- | |
1283 | lodsd |
- | |
1284 | mov ecx, [ext2_data.blocks_per_group] |
- | |
1285 | and ecx, not (32-1) ;обнуляем все кроме последних 5 бит |
- | |
1286 | mov edx, ecx |
- | |
1287 | mov ebx, 1 |
- | |
1288 | @@: |
- | |
1289 | jecxz .no_space |
- | |
1290 | mov edx, ebx |
- | |
1291 | or edx, eax ; тестируем очередной бит |
- | |
1292 | shl ebx, 1 |
- | |
1293 | jmp @B |
- | |
1294 | @@: |
- | |
1295 | sub edx, ecx |
- | |
1296 | dec edx ;номер в последнем блоке |
- | |
1297 | - | ||
1298 | - | ||
1299 | .no_space: |
- | |
1300 | xor eax, eax |
- | |
1301 | ret |
- | |
1302 | - | ||
1303 | ;in: eax = i_block |
- | |
1304 | ; ebx = pointer to memory |
- | |
1305 | ext2_set_block: |
- | |
1306 | push eax ebx ecx |
- | |
1307 | mov ecx, [ext2_data.log_block_size] |
- | |
1308 | shl eax, cl |
- | |
1309 | add eax, [PARTITION_START] |
- | |
1310 | mov ecx, [ext2_data.count_block_in_block] |
- | |
1311 | @@: |
- | |
1312 | call hd_write |
- | |
1313 | inc eax |
- | |
1314 | add ebx, 512 |
- | |
1315 | loop @B |
- | |
1316 | pop ecx ebx eax |
- | |
1317 | ret |
- | |
1318 | - |