Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2434 | Serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
2465 | Serge | 3 | ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
2434 | Serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; 02.02.2010 turbanoff - support 70.5 ;; |
||
6 | ;; 23.01.2010 turbanoff - support 70.0 70.1 ;; |
||
7 | ;; ;; |
||
8 | ;; ;; |
||
9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
10 | |||
11 | $Revision: 2465 $ |
||
12 | |||
13 | EXT2_BAD_INO = 1 |
||
14 | EXT2_ROOT_INO = 2 |
||
15 | EXT2_ACL_IDX_INO = 3 |
||
16 | EXT2_ACL_DATA_INO = 4 |
||
17 | EXT2_BOOT_LOADER_INO= 5 |
||
18 | EXT2_UNDEL_DIR_INO = 6 |
||
19 | |||
20 | ;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 |
||
33 | EXT2_S_IWOTH = 0x0002 |
||
34 | EXT2_S_IXOTH = 0x0001 |
||
35 | EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \ |
||
36 | EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \ |
||
37 | EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR |
||
38 | |||
39 | EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге |
||
40 | EXT2_FT_DIR = 2 ;это папка |
||
41 | |||
42 | FS_FT_HIDDEN = 2 |
||
43 | FS_FT_DIR = 0x10 ;это папка |
||
44 | FS_FT_ASCII = 0 ;имя в ascii |
||
45 | FS_FT_UNICODE = 1 ;имя в unicode |
||
46 | |||
47 | EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 |
||
48 | |||
49 | uglobal |
||
50 | EXT2_files_in_folder dd ? ;всего файлов в папке |
||
51 | EXT2_read_in_folder dd ? ;сколько файлов "считали" |
||
52 | EXT2_end_block dd ? ;конец очередного блока папки |
||
53 | EXT2_counter_blocks dd ? |
||
54 | EXT2_filename rb 256 |
||
55 | EXT2_parent_name rb 256 |
||
56 | EXT2_name_len dd ? |
||
57 | endg |
||
58 | |||
59 | struct EXT2_INODE_STRUC |
||
60 | i_mode dw ? |
||
61 | i_uid dw ? |
||
62 | i_size dd ? |
||
63 | i_atime dd ? |
||
64 | i_ctime dd ? |
||
65 | i_mtime dd ? |
||
66 | i_dtime dd ? |
||
67 | i_gid dw ? |
||
68 | i_links_count dw ? |
||
69 | i_blocks dd ? |
||
70 | i_flags dd ? |
||
71 | i_osd1 dd ? |
||
72 | i_block rd 15 |
||
73 | i_generation dd ? |
||
74 | i_file_acl dd ? |
||
75 | i_dir_acl dd ? |
||
76 | i_faddr dd ? |
||
77 | i_osd2 dd ? ; 1..12 |
||
78 | ends |
||
79 | |||
80 | struct EXT2_DIR_STRUC |
||
81 | inode dd ? |
||
82 | rec_len dw ? |
||
83 | name_len db ? |
||
84 | file_type db ? |
||
85 | name db ? ; 0..255 |
||
86 | ends |
||
87 | |||
88 | struct EXT2_BLOCK_GROUP_DESC |
||
89 | block_bitmap dd ? |
||
90 | inode_bitmap dd ? |
||
91 | inode_table dd ? |
||
92 | free_blocks_count dw ? |
||
93 | free_inodes_count dw ? |
||
94 | used_dirs_count dw ? |
||
95 | ends |
||
96 | |||
97 | struct EXT2_SB_STRUC |
||
98 | inodes_count dd ? ;+0 |
||
99 | blocks_count dd ? ;+4 |
||
100 | r_block_count dd ? ;+8 |
||
101 | free_block_count dd ? ;+12 |
||
102 | free_inodes_count dd ? ;+16 |
||
103 | first_data_block dd ? ;+20 |
||
104 | log_block_size dd ? ;+24 |
||
105 | log_frag_size dd ? ;+28 |
||
106 | blocks_per_group dd ? ;+32 |
||
107 | frags_per_group dd ? ;+36 |
||
108 | inodes_per_group dd ? ;+40 |
||
109 | mtime dd ? ;+44 |
||
110 | wtime dd ? ;+48 |
||
111 | mnt_count dw ? ;+52 |
||
112 | max_mnt_count dw ? ;+54 |
||
113 | magic dw ? ;+56 |
||
114 | state dw ? ;+58 |
||
115 | errors dw ? ;+60 |
||
116 | minor_rev_level dw ? ;+62 |
||
117 | lastcheck dd ? ;+64 |
||
118 | check_intervals dd ? ;+68 |
||
119 | creator_os dd ? ;+72 |
||
120 | rev_level dd ? ;+76 |
||
121 | def_resuid dw ? ;+80 |
||
122 | def_resgid dw ? ;+82 |
||
123 | first_ino dd ? ;+84 |
||
124 | inode_size dw ? ;+88 |
||
125 | block_group_nr dw ? ;+90 |
||
126 | feature_compat dd ? ;+92 |
||
127 | feature_incompat dd ? ;+96 |
||
128 | feature_ro_compat dd ? ;+100 |
||
129 | uuid rb 16 ;+104 |
||
130 | volume_name rb 16 ;+120 |
||
131 | last_mounted rb 64 ;+136 |
||
132 | algo_bitmap dd ? ;+200 |
||
133 | prealloc_blocks db ? ;+204 |
||
134 | preallock_dir_blocks db ? ;+205 |
||
135 | dw ? ;+206 alignment |
||
136 | journal_uuid rb 16 ;+208 |
||
137 | journal_inum dd ? ;+224 |
||
138 | journal_dev dd ? ;+228 |
||
139 | last_orphan dd ? ;+232 |
||
140 | hash_seed rd 4 ;+236 |
||
141 | def_hash_version db ? ;+252 |
||
142 | rb 3 ;+253 reserved |
||
143 | default_mount_options dd ? ;+256 |
||
144 | first_meta_bg dd ? ;+260 |
||
145 | ends |
||
146 | |||
147 | ext2_test_superblock: |
||
148 | cmp [fs_type], 0x83 |
||
149 | jne .no |
||
150 | |||
151 | mov eax, [PARTITION_START] |
||
152 | add eax, 2 ;superblock start at 1024b |
||
153 | call hd_read |
||
154 | |||
155 | cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3 |
||
156 | ja .no |
||
157 | cmp word [ebx+56], 0xEF53 ;s_magic |
||
158 | jne .no |
||
159 | cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1) |
||
160 | jne .no |
||
161 | mov eax, [ebx+96] |
||
162 | test eax, EXT2_FEATURE_INCOMPAT_FILETYPE |
||
163 | jz .no |
||
164 | test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE |
||
165 | jnz .no |
||
166 | |||
167 | ; OK, this is correct EXT2 superblock |
||
168 | clc |
||
169 | ret |
||
170 | .no: |
||
171 | ; No, this superblock isn't EXT2 |
||
172 | stc |
||
173 | ret |
||
174 | |||
175 | ext2_setup: |
||
176 | mov [fs_type], 2 |
||
177 | |||
178 | push 512 |
||
179 | call kernel_alloc ; mem for superblock |
||
180 | mov esi, ebx |
||
181 | mov edi, eax |
||
182 | mov ecx, 512/4 |
||
183 | rep movsd ; copy sb to reserved mem |
||
184 | mov ebx, eax |
||
185 | mov [ext2_data.sb], eax |
||
186 | |||
187 | mov eax, [ebx + EXT2_SB_STRUC.blocks_count] |
||
188 | sub eax, [ebx + EXT2_SB_STRUC.first_data_block] |
||
189 | dec eax |
||
190 | xor edx, edx |
||
191 | div [ebx + EXT2_SB_STRUC.blocks_per_group] |
||
192 | inc eax |
||
193 | mov [ext2_data.groups_count], eax |
||
194 | |||
195 | mov ecx, [ebx+24] |
||
196 | inc ecx |
||
197 | mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb |
||
198 | |||
199 | mov eax, 1 |
||
200 | shl eax, cl |
||
201 | mov [ext2_data.count_block_in_block], eax |
||
202 | |||
203 | shl eax, 7 |
||
204 | mov [ext2_data.count_pointer_in_block], eax |
||
205 | mov edx, eax ; потом еще квадрат найдем |
||
206 | |||
207 | shl eax, 2 |
||
208 | mov [ext2_data.block_size], eax |
||
209 | |||
210 | push eax eax ; 2 kernel_alloc |
||
211 | |||
212 | mov eax, edx |
||
213 | mul edx |
||
214 | mov [ext2_data.count_pointer_in_block_square], eax |
||
215 | |||
216 | call kernel_alloc |
||
217 | mov [ext2_data.ext2_save_block], eax ; and for temp block |
||
218 | call kernel_alloc |
||
219 | mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc |
||
220 | |||
221 | movzx ebp, word [ebx+88] |
||
222 | mov ecx, [ebx+32] |
||
223 | mov edx, [ebx+40] |
||
224 | |||
225 | mov [ext2_data.inode_size], ebp |
||
226 | mov [ext2_data.blocks_per_group], ecx |
||
227 | mov [ext2_data.inodes_per_group], edx |
||
228 | |||
229 | push ebp ebp ebp ;3 kernel_alloc |
||
230 | call kernel_alloc |
||
231 | mov [ext2_data.ext2_save_inode], eax |
||
232 | call kernel_alloc |
||
233 | mov [ext2_data.ext2_temp_inode], eax |
||
234 | call kernel_alloc |
||
235 | mov [ext2_data.root_inode], eax |
||
236 | |||
237 | mov ebx, eax |
||
238 | mov eax, EXT2_ROOT_INO |
||
239 | call ext2_get_inode ; read root inode |
||
240 | |||
241 | jmp return_from_part_set |
||
242 | |||
243 | ;================================================================== |
||
244 | ;in: eax = i_block |
||
245 | ; ebx = pointer to return memory |
||
246 | ext2_get_block: |
||
247 | push eax ebx ecx |
||
248 | mov ecx, [ext2_data.log_block_size] |
||
249 | shl eax, cl |
||
250 | add eax, [PARTITION_START] |
||
251 | mov ecx, [ext2_data.count_block_in_block] |
||
252 | @@: |
||
253 | call hd_read |
||
254 | inc eax |
||
255 | add ebx, 512 |
||
256 | loop @B |
||
257 | pop ecx ebx eax |
||
258 | ret |
||
259 | ;=================================================================== |
||
260 | ; in: ecx = номер блока в inode (0..) |
||
261 | ; ebp = адрес inode |
||
262 | ; out: ecx = адрес очередного блока |
||
263 | ext2_get_inode_block: |
||
264 | cmp ecx, 12 ; 0..11 - direct block address |
||
265 | jb .get_direct_block |
||
266 | |||
267 | sub ecx, 12 |
||
268 | cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block |
||
269 | jb .get_indirect_block |
||
270 | |||
271 | sub ecx, [ext2_data.count_pointer_in_block] |
||
272 | cmp ecx, [ext2_data.count_pointer_in_block_square] |
||
273 | jb .get_double_indirect_block |
||
274 | |||
275 | sub ecx, [ext2_data.count_pointer_in_block_square] |
||
276 | ;.get_triple_indirect_block: |
||
277 | push eax edx ebx |
||
278 | |||
279 | mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] |
||
280 | mov ebx, [ext2_data.ext2_temp_block] |
||
281 | call ext2_get_block |
||
282 | |||
283 | xor edx, edx |
||
284 | mov eax, ecx |
||
285 | div [ext2_data.count_pointer_in_block_square] |
||
286 | |||
287 | ;eax - номер в полученном блоке edx - номер дальше |
||
288 | mov eax, [ebx + eax*4] |
||
289 | call ext2_get_block |
||
290 | |||
291 | mov eax, edx |
||
292 | jmp @F |
||
293 | |||
294 | .get_double_indirect_block: |
||
295 | push eax edx ebx |
||
296 | |||
297 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] |
||
298 | mov ebx, [ext2_data.ext2_temp_block] |
||
299 | call ext2_get_block |
||
300 | |||
301 | mov eax, ecx |
||
302 | @@: |
||
303 | xor edx, edx |
||
304 | div [ext2_data.count_pointer_in_block] |
||
305 | |||
306 | mov eax, [ebx + eax*4] |
||
307 | call ext2_get_block |
||
308 | mov ecx, [ebx + edx*4] |
||
309 | |||
310 | pop ebx edx eax |
||
311 | ret |
||
312 | |||
313 | .get_indirect_block: |
||
314 | push eax ebx |
||
315 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] |
||
316 | mov ebx, [ext2_data.ext2_temp_block] |
||
317 | call ext2_get_block |
||
318 | |||
319 | mov ecx, [ebx + ecx*4] |
||
320 | pop ebx eax |
||
321 | ret |
||
322 | |||
323 | .get_direct_block: |
||
324 | mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4] |
||
325 | ret |
||
326 | |||
327 | ;=================================================================== |
||
328 | ;get content inode by num |
||
329 | ;in: eax = inode_num |
||
330 | ; ebx = address of inode content |
||
331 | ext2_get_inode: |
||
332 | |||
333 | pushad |
||
334 | mov edi, ebx ;сохраним адрес inode |
||
335 | dec eax |
||
336 | xor edx, edx |
||
337 | div [ext2_data.inodes_per_group] |
||
338 | |||
339 | push edx ;locale num in group |
||
340 | |||
341 | mov edx, 32 |
||
342 | mul edx ; address block_group in global_desc_table |
||
343 | |||
344 | ; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы |
||
345 | ; найдем блок в котором он находится |
||
346 | |||
347 | div [ext2_data.block_size] |
||
348 | mov ecx, [ext2_data.sb] |
||
349 | add eax, [ecx + EXT2_SB_STRUC.first_data_block] |
||
350 | inc eax |
||
351 | mov ebx, [ext2_data.ext2_temp_block] |
||
352 | call ext2_get_block |
||
353 | |||
354 | add ebx, edx ; локальный номер в блоке |
||
355 | mov eax, [ebx+8] ; номер блока - в терминах ext2 |
||
356 | |||
357 | mov ecx, [ext2_data.log_block_size] |
||
358 | shl eax, cl |
||
359 | add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512) |
||
360 | |||
361 | ;eax - указывает на таблицу inode-ов на hdd |
||
362 | mov esi, eax ;сохраним его пока в esi |
||
363 | |||
364 | ; прибавим локальный адрес inode-а |
||
365 | pop eax ; index |
||
366 | mov ecx, [ext2_data.inode_size] |
||
367 | mul ecx ; (index * inode_size) |
||
368 | mov ebp, 512 |
||
369 | div ebp ;поделим на размер блока |
||
370 | |||
371 | add eax, esi ;нашли адрес блока для чтения |
||
372 | mov ebx, [ext2_data.ext2_temp_block] |
||
373 | call hd_read |
||
374 | |||
375 | mov esi, edx ;добавим "остаток" |
||
376 | add esi, ebx ;к адресу |
||
377 | ; mov ecx, [ext2_data.inode_size] |
||
378 | rep movsb ;копируем inode |
||
379 | 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 |
||
441 | |||
442 | ;---------------------------------------------------------------- |
||
443 | ; |
||
444 | ; ext2_HdReadFolder - read disk folder |
||
445 | ; |
||
446 | ; esi points to filename |
||
447 | ; ebx pointer to structure 32-bit number = first wanted block, 0+ |
||
448 | ; & flags (bitfields) |
||
449 | ; flags: bit 0: 0=ANSI names, 1=UNICODE names |
||
450 | ; ecx number of blocks to read, 0+ |
||
451 | ; edx mem location to return data |
||
452 | ; |
||
453 | ; ret ebx = blocks read or 0xffffffff folder not found |
||
454 | ; eax = 0 ok read or other = errormsg |
||
455 | ; |
||
456 | ;-------------------------------------------------------------- |
||
457 | ext2_HdReadFolder: |
||
458 | cmp byte [esi], 0 |
||
459 | jz .doit |
||
460 | |||
461 | push ecx ebx |
||
462 | call ext2_find_lfn |
||
463 | jnc .doit2 |
||
464 | pop ebx |
||
465 | .not_found: |
||
466 | pop ecx |
||
467 | or ebx, -1 |
||
468 | mov eax, ERROR_FILE_NOT_FOUND |
||
469 | ret |
||
470 | |||
471 | .doit: |
||
472 | mov ebp, [ext2_data.root_inode] |
||
473 | push ecx |
||
474 | jmp @F |
||
475 | .doit2: |
||
476 | pop ebx |
||
477 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
||
478 | jz .not_found |
||
479 | @@: |
||
480 | xor eax, eax |
||
481 | 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 | |||
491 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] |
||
492 | mov [EXT2_counter_blocks], eax |
||
493 | |||
494 | add edx, 32 ; (header pointer in stack) edx = current mem for return |
||
495 | xor esi, esi ; esi = номер блока по порядку |
||
496 | |||
497 | .new_block_folder: ;reserved label |
||
498 | mov ecx, esi ; получим номер блока |
||
499 | call ext2_get_inode_block |
||
500 | |||
501 | mov eax, ecx |
||
502 | mov ebx, [ext2_data.ext2_save_block] |
||
503 | call ext2_get_block ; и считываем блок с hdd |
||
504 | |||
505 | mov eax, ebx ; eax = current dir record |
||
506 | add ebx, [ext2_data.block_size] |
||
507 | mov [EXT2_end_block], ebx ; запомним конец очередного блока |
||
508 | |||
509 | pop ecx |
||
510 | mov ecx, [ecx] ; ecx = first wanted (flags ommited) |
||
511 | |||
512 | .find_wanted_start: |
||
513 | jecxz .find_wanted_end |
||
514 | .find_wanted_cycle: |
||
515 | cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
||
516 | jz @F |
||
517 | inc [EXT2_files_in_folder] |
||
518 | dec ecx |
||
519 | @@: |
||
520 | movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] |
||
521 | |||
522 | cmp ebx, 12 ; минимальная длина записи |
||
523 | jb .end_error |
||
524 | test ebx, 0x3 ; длина записи должна делиться на 4 |
||
525 | jnz .end_error |
||
526 | |||
527 | add eax, ebx ; к следующей записи |
||
528 | cmp eax, [EXT2_end_block] ; проверяем "конец" |
||
529 | jb .find_wanted_start |
||
530 | |||
531 | push .find_wanted_start |
||
532 | .end_block: ;вылетили из цикла |
||
533 | mov ebx, [ext2_data.count_block_in_block] |
||
534 | sub [EXT2_counter_blocks], ebx |
||
535 | jbe .end_dir |
||
536 | |||
537 | inc esi ;получаем новый блок |
||
538 | push ecx |
||
539 | mov ecx, esi |
||
540 | call ext2_get_inode_block |
||
541 | mov eax, ecx |
||
542 | mov ebx, [ext2_data.ext2_save_block] |
||
543 | call ext2_get_block |
||
544 | pop ecx |
||
545 | mov eax, ebx |
||
546 | add ebx, [ext2_data.block_size] |
||
547 | mov [EXT2_end_block], ebx |
||
548 | ret ; опять в цикл |
||
549 | |||
550 | .wanted_end: |
||
551 | loop .find_wanted_cycle ; ecx = -1 |
||
552 | |||
553 | .find_wanted_end: |
||
554 | mov ecx, edi |
||
555 | .wanted_start: ; ищем first_wanted+count |
||
556 | jecxz .wanted_end |
||
557 | cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
||
558 | jz .empty_rec |
||
559 | inc [EXT2_files_in_folder] |
||
560 | inc [EXT2_read_in_folder] |
||
561 | |||
562 | mov edi, edx |
||
563 | push eax ecx |
||
564 | xor eax, eax |
||
565 | mov ecx, 40 / 4 |
||
566 | rep stosd |
||
567 | pop ecx eax |
||
568 | |||
569 | push eax esi edx ;получим inode |
||
570 | mov eax, [eax + EXT2_DIR_STRUC.inode] |
||
571 | mov ebx, [ext2_data.ext2_temp_inode] |
||
572 | call ext2_get_inode |
||
573 | |||
574 | lea edi, [edx + 8] |
||
575 | |||
576 | mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат |
||
577 | xor edx, edx |
||
578 | add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600 |
||
579 | adc edx, 2 |
||
580 | call ntfs_datetime_to_bdfe.sec |
||
581 | |||
582 | mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
||
583 | xor edx, edx |
||
584 | add eax, 3054539008 |
||
585 | adc edx, 2 |
||
586 | call ntfs_datetime_to_bdfe.sec |
||
587 | |||
588 | mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
||
589 | xor edx, edx |
||
590 | add eax, 3054539008 |
||
591 | adc edx, 2 |
||
592 | call ntfs_datetime_to_bdfe.sec |
||
593 | |||
594 | pop edx ; пока достаем только буфер |
||
595 | test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер |
||
596 | jnz @F ; не возвращаем |
||
597 | |||
598 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size |
||
599 | stosd |
||
600 | mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size |
||
601 | stosd |
||
602 | xor dword [edx], FS_FT_DIR |
||
603 | @@: |
||
604 | xor dword [edx], FS_FT_DIR |
||
605 | pop esi eax |
||
606 | |||
607 | or dword [edx+4], FS_FT_ASCII ; symbol type in name |
||
608 | |||
609 | ;теперь скопируем имя, сконвертировав из UTF-8 в CP866 |
||
610 | push eax ecx esi |
||
611 | movzx ecx, [eax + EXT2_DIR_STRUC.name_len] |
||
612 | lea edi, [edx + 40] |
||
613 | lea esi, [eax + EXT2_DIR_STRUC.name] |
||
614 | call utf8toansi_str |
||
615 | pop esi ecx eax |
||
616 | and byte [edi], 0 |
||
617 | |||
618 | cmp byte [edx + 40], '.' |
||
619 | jne @F |
||
620 | or dword [edx], FS_FT_HIDDEN |
||
621 | @@: |
||
622 | |||
623 | add edx, 40 + 264 ; go to next record |
||
624 | dec ecx ; если запись пустая ecx не надо уменьшать |
||
625 | .empty_rec: |
||
626 | movzx ebx, [eax + EXT2_DIR_STRUC.rec_len] |
||
627 | cmp ebx, 12 ; минимальная длина записи |
||
628 | jb .end_error |
||
629 | test ebx, 0x3 ; длина записи должна делиться на 4 |
||
630 | jnz .end_error |
||
631 | |||
632 | add eax, ebx |
||
633 | cmp eax, [EXT2_end_block] |
||
634 | jb .wanted_start |
||
635 | |||
636 | push .wanted_start ; дошли до конца очередного блока |
||
637 | jmp .end_block |
||
638 | |||
639 | .end_dir: |
||
640 | pop eax ; мусор (адрес возврата в цикл) |
||
641 | .end_error: |
||
642 | pop edx |
||
643 | mov ebx, [EXT2_read_in_folder] |
||
644 | mov ecx, [EXT2_files_in_folder] |
||
645 | mov dword [edx], 1 ;version |
||
646 | xor eax, eax |
||
647 | mov [edx+4], ebx |
||
648 | mov [edx+8], ecx |
||
649 | lea edi, [edx + 12] |
||
650 | mov ecx, 20 / 4 |
||
651 | rep stosd |
||
652 | ret |
||
653 | ;====================== end ext2_HdReadFolder |
||
654 | utf8toansi_str: |
||
1397 | turbanoff | 655 | ; convert UTF-8 string to ASCII-string (codepage 866) |
656 | ; in: ecx=length source, esi->source, edi->buffer |
||
2434 | Serge | 657 | ; destroys: eax,esi,edi |
658 | jecxz .ret |
||
659 | .start: |
||
660 | lodsw |
||
1397 | turbanoff | 661 | cmp al, 0x80 |
2434 | Serge | 662 | jb .ascii |
663 | |||
664 | xchg al, ah ; big-endian |
||
665 | cmp ax, 0xd080 |
||
666 | jz .yo1 |
||
667 | cmp ax, 0xd191 |
||
668 | jz .yo2 |
||
669 | cmp ax, 0xd090 |
||
1397 | turbanoff | 670 | jb .unk |
671 | cmp ax, 0xd180 |
||
672 | jb .rus1 |
||
673 | cmp ax, 0xd190 |
||
2434 | Serge | 674 | jb .rus2 |
675 | .unk: |
||
676 | mov al, '_' |
||
677 | jmp .doit |
||
678 | .yo1: |
||
679 | mov al, 0xf0 ; Ё capital |
||
680 | jmp .doit |
||
681 | .yo2: |
||
682 | mov al, 0xf1 ; ё small |
||
683 | jmp .doit |
||
684 | .rus1: |
||
685 | sub ax, 0xd090 - 0x80 |
||
686 | jmp .doit |
||
687 | .rus2: |
||
688 | sub ax, 0xd18f - 0xEF |
||
689 | .doit: |
||
690 | stosb |
||
691 | sub ecx, 2 |
||
692 | ja .start |
||
693 | ret |
||
694 | |||
695 | .ascii: |
||
696 | stosb |
||
697 | dec esi |
||
698 | dec ecx |
||
699 | jnz .start |
||
700 | .ret: |
||
701 | ret |
||
702 | |||
1378 | turbanoff | 703 | ;---------------------------------------------------------------- |
704 | ; |
||
705 | ; ext2_HdRead - read hard disk |
||
706 | ; |
||
707 | ; esi points to filename |
||
708 | ; ebx pointer to 64-bit number = first wanted byte, 0+ |
||
709 | ; may be ebx=0 - start from first byte |
||
710 | ; ecx number of bytes to read, 0+ |
||
711 | ; edx mem location to return data |
||
712 | ; |
||
713 | ; ret ebx = bytes read or 0xffffffff file not found |
||
714 | ; eax = 0 ok read or other = errormsg |
||
715 | ; |
||
2434 | Serge | 716 | ;-------------------------------------------------------------- |
717 | ext2_HdRead: |
||
718 | cmp byte [esi], 0 |
||
719 | jnz @F |
||
720 | |||
721 | .this_is_nofile: |
||
722 | or ebx, -1 |
||
723 | mov eax, ERROR_ACCESS_DENIED |
||
724 | ret |
||
725 | |||
726 | @@: |
||
727 | push ecx ebx |
||
728 | call ext2_find_lfn |
||
729 | pop ebx ecx |
||
730 | jnc .doit |
||
731 | ;.not_found: |
||
732 | or ebx, -1 |
||
733 | mov eax, ERROR_FILE_NOT_FOUND |
||
734 | ret |
||
735 | |||
736 | .doit: |
||
737 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG |
||
738 | jz .this_is_nofile |
||
739 | |||
740 | ;-----------------------------------------------------------------------------final step |
||
741 | mov edi, edx ; edi = pointer to return mem |
||
742 | mov esi, ebx ; esi = pointer to first_wanted |
||
743 | |||
744 | ;///// сравним хватит ли нам файла или нет |
||
745 | mov ebx, [esi+4] |
||
746 | mov eax, [esi] ; ebx : eax - стартовый номер байта |
||
747 | |||
748 | cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
||
749 | ja .size_great |
||
750 | jb .size_less |
||
751 | |||
752 | cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
||
753 | ja .size_great |
||
754 | |||
755 | .size_less: |
||
756 | xor ebx, ebx |
||
757 | mov eax, ERROR_END_OF_FILE |
||
758 | ret |
||
759 | .size_great: |
||
760 | add eax, ecx ;add to first_wanted кол-во байт для чтения |
||
761 | adc ebx, 0 |
||
762 | |||
763 | cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
||
764 | ja .size_great_great |
||
765 | jb .size_great_less |
||
766 | cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
||
767 | jae .size_great_great ; а если равно, то не важно куда |
||
768 | |||
769 | .size_great_less: |
||
770 | or [EXT2_files_in_folder], 1 ;читаем по границе размера |
||
771 | mov ecx, [ebp + EXT2_INODE_STRUC.i_size] |
||
772 | sub ecx, [esi] ;(размер - старт) |
||
773 | jmp @F |
||
774 | |||
775 | .size_great_great: |
||
776 | and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили |
||
777 | |||
778 | @@: |
||
779 | push ecx ;save for return |
||
780 | test esi, esi |
||
781 | jz .zero_start |
||
782 | |||
783 | ;пока делаем п..ц криво =) |
||
784 | mov edx, [esi+4] |
||
785 | mov eax, [esi] |
||
786 | div [ext2_data.block_size] |
||
787 | |||
788 | mov [EXT2_counter_blocks], eax ;номер блока запоминаем |
||
789 | |||
790 | push ecx |
||
791 | mov ecx, eax |
||
792 | call ext2_get_inode_block |
||
793 | mov ebx, [ext2_data.ext2_save_block] |
||
794 | mov eax, ecx |
||
795 | call ext2_get_block |
||
796 | pop ecx |
||
797 | add ebx, edx |
||
798 | |||
799 | neg edx |
||
800 | add edx, [ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока |
||
801 | cmp ecx, edx |
||
802 | jbe .only_one_block |
||
803 | |||
804 | mov eax, ecx |
||
805 | sub eax, edx |
||
806 | mov ecx, edx |
||
807 | |||
808 | mov esi, ebx |
||
809 | rep movsb ;кусок 1-го блока |
||
810 | jmp @F |
||
811 | |||
812 | .zero_start: |
||
813 | mov eax, ecx |
||
814 | ;теперь в eax кол-во оставшихся байт для чтения |
||
815 | @@: |
||
816 | mov ebx, edi ;чтение блока прям в ->ebx |
||
817 | xor edx, edx |
||
818 | div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx |
||
819 | mov edi, eax ;кол-во целых блоков в edi |
||
820 | @@: |
||
821 | test edi, edi |
||
822 | jz .finish_block |
||
823 | inc [EXT2_counter_blocks] |
||
824 | mov ecx, [EXT2_counter_blocks] |
||
825 | call ext2_get_inode_block |
||
826 | |||
827 | mov eax, ecx ;а ebx уже забит нужным значением |
||
828 | call ext2_get_block |
||
829 | add ebx, [ext2_data.block_size] |
||
830 | |||
831 | dec edi |
||
832 | jmp @B |
||
833 | |||
834 | .finish_block: ;в edx - кол-во байт в последнем блоке |
||
835 | test edx, edx |
||
836 | jz .end_read |
||
837 | |||
838 | mov ecx, [EXT2_counter_blocks] |
||
839 | inc ecx |
||
840 | call ext2_get_inode_block |
||
841 | |||
842 | mov edi, ebx |
||
843 | mov eax, ecx |
||
844 | mov ebx, [ext2_data.ext2_save_block] |
||
845 | call ext2_get_block |
||
846 | |||
847 | mov ecx, edx |
||
848 | |||
849 | .only_one_block: |
||
850 | mov esi, ebx |
||
851 | rep movsb ;кусок last блока |
||
852 | .end_read: |
||
853 | pop ebx |
||
854 | cmp [EXT2_files_in_folder], 0 |
||
855 | jz @F |
||
856 | |||
857 | mov eax, ERROR_END_OF_FILE |
||
858 | ret |
||
859 | @@: |
||
860 | xor eax, eax |
||
861 | ret |
||
862 | ;======================== |
||
863 | ;in : esi -> name not save: eax ebx ecx |
||
864 | ;out: ebp -> inode cf=0 |
||
865 | ; ebp -> trash cf=1 |
||
866 | ext2_find_lfn: |
||
867 | mov ebp, [ext2_data.root_inode] |
||
868 | .next_folder: |
||
869 | or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode |
||
870 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков |
||
871 | add eax, [ext2_data.count_block_in_block] |
||
872 | mov [EXT2_end_block], eax |
||
873 | .next_block_folder: |
||
874 | mov eax, [ext2_data.count_block_in_block] |
||
875 | sub [EXT2_end_block], eax |
||
876 | jz .not_found |
||
877 | inc [EXT2_counter_blocks] |
||
878 | mov ecx, [EXT2_counter_blocks] |
||
879 | call ext2_get_inode_block |
||
880 | |||
881 | mov eax, ecx |
||
882 | mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
||
883 | call ext2_get_block |
||
884 | |||
885 | mov eax, esi |
||
886 | call ext2_test_block_by_name |
||
887 | cmp eax, esi ;нашли имя? |
||
888 | jz .next_block_folder |
||
889 | |||
890 | cmp byte [esi], 0 |
||
891 | jz .get_inode_ret |
||
892 | |||
893 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR |
||
894 | jne .not_found ;нашли, но это не папка |
||
895 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
896 | mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
||
897 | call ext2_get_inode |
||
898 | mov ebp, ebx |
||
899 | jmp .next_folder |
||
900 | |||
901 | .not_found: |
||
902 | stc |
||
903 | ret |
||
904 | .get_inode_ret: |
||
905 | mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec |
||
906 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
907 | mov ebx, [ext2_data.ext2_save_inode] |
||
908 | call ext2_get_inode |
||
909 | mov ebp, ebx |
||
910 | clc |
||
911 | ret |
||
912 | |||
913 | |||
914 | ;======================== |
||
915 | |||
916 | ext2_HdGetFileInfo: |
||
917 | cmp byte [esi], 0 |
||
918 | jz .doit |
||
919 | |||
920 | call ext2_find_lfn |
||
921 | jnc .doit2 |
||
922 | ;.not_found: |
||
923 | mov eax, ERROR_FILE_NOT_FOUND |
||
924 | ret |
||
925 | |||
926 | .doit: |
||
927 | mov ebp, [ext2_data.root_inode] |
||
928 | mov ebx, .doit ;неважно что лишь бы этому адресу не '.' |
||
929 | jmp @F |
||
930 | .doit2: |
||
931 | mov ebx, [EXT2_end_block] |
||
932 | add ebx, EXT2_DIR_STRUC.name |
||
933 | @@: |
||
934 | xor eax, eax |
||
935 | mov edi, edx |
||
936 | mov ecx, 40/4 |
||
937 | rep stosd ; fill zero |
||
938 | |||
939 | cmp byte [ebx], '.' |
||
940 | jnz @F |
||
941 | or dword [edx], FS_FT_HIDDEN |
||
942 | @@: |
||
943 | |||
944 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
||
945 | jnz @F |
||
946 | mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size |
||
947 | mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size |
||
948 | mov dword [edx+32], eax |
||
949 | mov dword [edx+36], ebx |
||
950 | xor dword [edx], FS_FT_DIR |
||
951 | @@: |
||
952 | xor dword [edx], FS_FT_DIR |
||
953 | |||
954 | lea edi, [edx + 8] |
||
955 | mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] |
||
956 | xor edx, edx |
||
957 | add eax, 3054539008 |
||
958 | adc edx, 2 |
||
959 | call ntfs_datetime_to_bdfe.sec |
||
960 | |||
961 | mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
||
962 | xor edx, edx |
||
963 | add eax, 3054539008 |
||
964 | adc edx, 2 |
||
965 | call ntfs_datetime_to_bdfe.sec |
||
966 | |||
967 | mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
||
968 | xor edx, edx |
||
969 | add eax, 3054539008 |
||
970 | adc edx, 2 |
||
971 | call ntfs_datetime_to_bdfe.sec |
||
972 | |||
973 | xor eax, eax |
||
974 | ret |
||
975 | |||
976 | ext2_HdRewrite: |
||
977 | ext2_HdWrite: |
||
978 | ext2_HdSetFileEnd: |
||
979 | ext2_HdSetFileInfo: |
||
980 | ext2_HdDelete: |
||
981 | ext2_HdCreateFolder: |
||
982 | xor ebx, ebx |
||
983 | mov eax, ERROR_UNSUPPORTED_FS |
||
984 | ret |
||
1419 | turbanoff | 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 | ; |
||
2434 | Serge | 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 |