Rev 1378 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1378 | turbanoff | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
1384 | turbanoff | 5 | ;; 02.02.2010 turbanoff - support 70.5 ;; |
6 | ;; 23.01.2010 turbanoff - support 70.0 70.1 ;; |
||
1378 | turbanoff | 7 | ;; ;; |
8 | ;; ;; |
||
9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
10 | |||
11 | $Revision: 1384 $ |
||
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 |
||
1384 | turbanoff | 21 | EXT2_S_IFREG = 0x8000 |
22 | EXT2_S_IFDIR = 0x4000 |
||
1378 | turbanoff | 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_IROTH = 0x0002 |
||
34 | EXT2_S_IROTH = 0x0001 |
||
35 | |||
36 | EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге |
||
37 | EXT2_FT_DIR = 2 ;это папка |
||
38 | |||
39 | FS_FT_DIR = 0x10 ;это папка |
||
40 | FS_FT_ASCII = 0 ;имя в ascii |
||
41 | FS_FT_UNICODE = 1 ;имя в unicode |
||
42 | |||
43 | struct EXT2_INODE_STRUC |
||
44 | .i_mode dw ? |
||
45 | .i_uid dw ? |
||
46 | .i_size dd ? |
||
47 | .i_atime dd ? |
||
48 | .i_ctime dd ? |
||
49 | .i_mtime dd ? |
||
50 | .i_dtime dd ? |
||
51 | .i_gid dw ? |
||
52 | .i_links_count dw ? |
||
53 | .i_blocks dd ? |
||
54 | .i_flags dd ? |
||
55 | .i_osd1 dd ? |
||
56 | .i_block dd 15 dup ? |
||
57 | .i_generation dd ? |
||
58 | .i_file_acl dd ? |
||
59 | .i_dir_acl dd ? |
||
60 | .i_faddr dd ? |
||
61 | .i_osd2 dd ? ; 1..12 |
||
62 | ends |
||
63 | |||
64 | struct EXT2_DIR_STRUC |
||
65 | .inode dd ? |
||
66 | .rec_len dw ? |
||
67 | .name_len db ? |
||
68 | .file_type db ? |
||
69 | .name db ? ; 0..255 |
||
70 | ends |
||
71 | |||
72 | |||
73 | ext2_test_superblock: |
||
74 | mov eax, [PARTITION_START] |
||
75 | add eax, 2 ;superblock start at 1024b |
||
76 | call hd_read |
||
77 | |||
78 | cmp [fs_type], 0x83 |
||
79 | jne .no |
||
80 | cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3 |
||
81 | ja .no |
||
82 | cmp word [ebx+56], 0xEF53 ;s_magic |
||
83 | jne .no |
||
84 | cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1) |
||
85 | jne .no |
||
86 | |||
87 | ; OK, this is correct EXT2 superblock |
||
88 | clc |
||
89 | ret |
||
90 | .no: |
||
91 | ; No, this superblock isn't EXT2 |
||
92 | stc |
||
93 | ret |
||
94 | |||
95 | ext2_setup: |
||
96 | mov [fs_type], 2 |
||
97 | mov ecx, [ebx+24] |
||
98 | inc ecx |
||
99 | mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb |
||
100 | |||
101 | mov eax, 1 |
||
102 | shl eax, cl |
||
103 | mov [ext2_data.count_block_in_block], eax |
||
104 | |||
105 | shl eax, 7 |
||
106 | mov [ext2_data.count_pointer_in_block], eax |
||
107 | mov edx, eax ; потом еще квадрат найдем |
||
108 | |||
109 | shl eax, 2 |
||
110 | mov [ext2_data.block_size], eax |
||
111 | |||
112 | push eax eax eax ;3 kernel_alloc |
||
113 | |||
114 | mov eax, edx |
||
115 | mul edx |
||
116 | mov [ext2_data.count_pointer_in_block_square], eax |
||
117 | |||
118 | call kernel_alloc |
||
119 | mov [ext2_data.global_desc_table],eax ;reserve mem for gdt |
||
120 | call kernel_alloc |
||
121 | mov [ext2_data.ext2_save_block], eax ; and for temp block |
||
122 | call kernel_alloc |
||
123 | mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc |
||
124 | |||
1384 | turbanoff | 125 | movzx ebp, word [ebx+88] |
1378 | turbanoff | 126 | mov ecx, [ebx+32] |
127 | mov edx, [ebx+40] |
||
128 | mov eax, [ebx+20] ; first_data_block |
||
129 | |||
130 | mov [ext2_data.inode_size], ebp |
||
131 | mov [ext2_data.blocks_per_group], ecx |
||
132 | mov [ext2_data.inodes_per_group], edx |
||
133 | |||
134 | mov ebx, [ext2_data.global_desc_table] |
||
135 | inc eax ; first_data_block + 1 = gdt |
||
136 | call ext2_get_block ; read gtd |
||
137 | |||
138 | push ebp ebp ebp ;3 kernel_alloc |
||
139 | call kernel_alloc |
||
140 | mov [ext2_data.ext2_save_inode], eax |
||
141 | call kernel_alloc |
||
142 | mov [ext2_data.ext2_temp_inode], eax |
||
143 | call kernel_alloc |
||
144 | mov [ext2_data.root_inode], eax |
||
145 | |||
146 | mov ebx, eax |
||
147 | mov eax, EXT2_ROOT_INO |
||
148 | call ext2_get_inode ; read root inode |
||
149 | |||
150 | popad |
||
151 | call free_hd_channel |
||
152 | and [hd1_status], 0 |
||
153 | ret |
||
154 | ;================================================================== |
||
155 | ;in: eax = i_block |
||
156 | ; ebx = pointer to return memory |
||
157 | ext2_get_block: |
||
158 | push eax ebx ecx |
||
159 | mov ecx, [ext2_data.log_block_size] |
||
160 | shl eax, cl |
||
161 | add eax, [PARTITION_START] |
||
162 | mov ecx, [ext2_data.count_block_in_block] |
||
163 | @@: |
||
164 | call hd_read |
||
165 | inc eax |
||
166 | add ebx, 512 |
||
167 | loop @B |
||
168 | pop ecx ebx eax |
||
169 | ret |
||
170 | ;=================================================================== |
||
171 | ; in: ecx = номер блока |
||
172 | ; ebp = адрес inode |
||
173 | ; out: ecx = адрес очередного блока |
||
174 | ext2_get_inode_block: |
||
175 | cmp ecx, 12 |
||
176 | jbe .get_direct_block |
||
177 | |||
178 | sub ecx, 12 |
||
179 | cmp ecx, [ext2_data.count_pointer_in_block] |
||
180 | jbe .get_indirect_block |
||
181 | |||
182 | sub ecx, [ext2_data.count_pointer_in_block] |
||
183 | cmp ecx, [ext2_data.count_pointer_in_block_square] |
||
184 | jbe .get_double_indirect_block |
||
185 | |||
186 | ;.get_triple_indirect_block: |
||
187 | push eax edx ebx |
||
188 | |||
189 | mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] |
||
190 | mov ebx, [ext2_data.ext2_temp_block] |
||
191 | call ext2_get_block |
||
192 | |||
193 | xor edx, edx |
||
194 | mov eax, ecx |
||
195 | div [ext2_data.count_pointer_in_block_square] |
||
196 | |||
197 | ;eax - номер в полученном блоке edx - номер дальше |
||
198 | mov eax, [ebx + eax*4] |
||
199 | call ext2_get_block |
||
200 | |||
201 | mov eax, edx |
||
202 | jmp @F |
||
203 | |||
204 | .get_double_indirect_block: |
||
205 | push eax edx ebx |
||
206 | |||
207 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] |
||
208 | mov ebx, [ext2_data.ext2_temp_block] |
||
209 | call ext2_get_block |
||
210 | |||
211 | mov eax, ecx |
||
212 | @@: |
||
213 | xor edx, edx |
||
214 | div [ext2_data.count_pointer_in_block] |
||
215 | |||
216 | mov eax, [ebx + eax*4] |
||
217 | call ext2_get_block |
||
218 | mov ecx, [ebx + edx*4] |
||
219 | |||
220 | pop ebx edx eax |
||
221 | ret |
||
222 | |||
223 | .get_indirect_block: |
||
224 | push eax ebx |
||
225 | mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] |
||
226 | mov ebx, [ext2_data.ext2_temp_block] |
||
227 | call ext2_get_block |
||
228 | |||
229 | mov ecx, [ebx + ecx*4] |
||
230 | pop ebx eax |
||
231 | ret |
||
232 | |||
233 | .get_direct_block: |
||
234 | mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4] |
||
235 | ret |
||
236 | |||
237 | |||
238 | ;=================================================================== |
||
239 | ;get content inode by num |
||
240 | ;in: eax = inode_num |
||
241 | ; ebx = address of inode content |
||
242 | ext2_get_inode: |
||
243 | |||
244 | pushad |
||
245 | mov edi, ebx ;сохраним адрес inode |
||
246 | dec eax |
||
247 | xor edx, edx |
||
248 | div [ext2_data.inodes_per_group] |
||
249 | |||
250 | push edx ;locale num |
||
251 | |||
252 | mov edx, 32 |
||
253 | mul edx ; address block_group in global_desc_table |
||
254 | |||
255 | add eax, [ext2_data.global_desc_table] |
||
256 | mov eax, [eax+8] ; номер блока - в терминах ext2 |
||
257 | |||
258 | mov ecx, [ext2_data.log_block_size] |
||
259 | shl eax, cl |
||
260 | add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512) |
||
261 | |||
262 | ;eax - указывает на таблицу inode-ов на hdd |
||
263 | mov ecx, eax ;сохраним его пока в ecx |
||
264 | |||
265 | ; прибавим локальный адрес inode-а |
||
266 | pop eax ; index |
||
267 | mul [ext2_data.inode_size] ; (index * inode_size) |
||
268 | mov ebp, 512 |
||
269 | div ebp ;поделим на размер блока |
||
270 | |||
271 | add eax, ecx ;нашли адрес блока для чтения |
||
272 | mov ebx, [ext2_data.ext2_temp_block] |
||
273 | call hd_read |
||
274 | |||
275 | mov esi, edx ;добавим "остаток" |
||
276 | add esi, ebx ;к адресу |
||
277 | mov ecx, [ext2_data.inode_size] |
||
278 | rep movsb ;копируем inode |
||
279 | popad |
||
280 | ret |
||
281 | |||
282 | ;---------------------------------------------------------------- |
||
283 | ext2_upcase: |
||
284 | cmp al, 'a' |
||
285 | jb .ret |
||
286 | cmp al, 'z' |
||
287 | ja .ret |
||
288 | and al, 0xDF ; upcase = clear 0010 0000 |
||
289 | .ret: |
||
290 | ret |
||
291 | ;---------------------------------------------------------------- |
||
292 | ; in: esi -> children |
||
293 | ; ebx -> pointer to dir block |
||
294 | ; out: esi -> name without parent or not_changed |
||
295 | ; ebx -> dir_rec of inode children or trash |
||
296 | ext2_test_block_by_name: |
||
297 | push eax ecx edx edi |
||
298 | |||
299 | mov edx, ebx |
||
300 | add edx, [ext2_data.block_size] ;запомним конец блока |
||
301 | |||
302 | .start_rec: |
||
303 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 |
||
304 | jz .next_rec |
||
305 | ; test [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR |
||
306 | ; jz .next_rec |
||
307 | |||
308 | push esi |
||
309 | movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] |
||
310 | lea edi, [ebx + EXT2_DIR_STRUC.name] |
||
311 | inc ecx |
||
312 | |||
313 | @@: |
||
314 | dec ecx |
||
315 | jecxz .test_find |
||
316 | lodsb |
||
317 | mov ah, [edi] |
||
318 | inc edi |
||
319 | |||
320 | call ext2_upcase |
||
321 | xchg al, ah |
||
322 | call ext2_upcase |
||
323 | cmp al, ah |
||
324 | je @B |
||
325 | @@: ;не подошло |
||
326 | pop esi |
||
327 | .next_rec: |
||
328 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
||
329 | add ebx, eax ;к след. записи |
||
330 | cmp ebx, edx ;проверим конец ли |
||
1384 | turbanoff | 331 | jb .start_rec |
1378 | turbanoff | 332 | jmp .ret |
333 | |||
334 | .test_find: |
||
335 | cmp byte [esi], 0 |
||
336 | je .find ;нашли конец |
||
337 | cmp byte [esi], '/' |
||
338 | jne @B |
||
339 | inc esi |
||
340 | .find: |
||
341 | pop eax ;удаляем из стека сохраненое значение |
||
342 | ; mov ebx, [ebx + EXT2_DIR_STRUC.inode] |
||
343 | .ret: |
||
344 | pop edi edx ecx eax |
||
345 | ret |
||
346 | |||
347 | ;---------------------------------------------------------------- |
||
348 | ; |
||
349 | ; ext2_HdReadFolder - read disk folder |
||
350 | ; |
||
351 | ; esi points to filename |
||
352 | ; ebx pointer to structure 32-bit number = first wanted block, 0+ |
||
353 | ; & flags (bitfields) |
||
354 | ; flags: bit 0: 0=ANSI names, 1=UNICODE names |
||
355 | ; ecx number of blocks to read, 0+ |
||
356 | ; edx mem location to return data |
||
357 | ; |
||
358 | ; ret ebx = blocks read or 0xffffffff folder not found |
||
359 | ; eax = 0 ok read or other = errormsg |
||
360 | ; |
||
361 | ;-------------------------------------------------------------- |
||
362 | uglobal |
||
363 | EXT2_files_in_folder dd ? ;всего файлов в папке |
||
364 | EXT2_read_in_folder dd ? ;сколько файлов "считали" |
||
365 | EXT2_end_block dd ? ;конец очередного блока папки |
||
366 | EXT2_counter_blocks dd ? |
||
367 | endg |
||
368 | |||
369 | ext2_HdReadFolder: |
||
370 | mov ebp, [ext2_data.root_inode] |
||
371 | mov [EXT2_read_in_folder], ebx |
||
372 | mov [EXT2_files_in_folder], ecx ;сохраним регистры |
||
373 | |||
374 | .next_folder: |
||
375 | cmp byte [esi], 0 |
||
376 | jz .get_folder |
||
377 | |||
378 | or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode |
||
379 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков |
||
380 | add eax, [ext2_data.count_block_in_block] |
||
381 | mov [EXT2_end_block], eax |
||
382 | .next_block_folder: |
||
383 | mov eax, [ext2_data.count_block_in_block] |
||
384 | sub [EXT2_end_block], eax |
||
385 | jz .not_found |
||
386 | inc [EXT2_counter_blocks] |
||
387 | mov ecx, [EXT2_counter_blocks] |
||
388 | call ext2_get_inode_block |
||
389 | |||
390 | mov eax, ecx |
||
391 | mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
||
392 | call ext2_get_block |
||
393 | |||
394 | mov eax, esi |
||
395 | call ext2_test_block_by_name |
||
396 | cmp eax, esi ;нашли имя? |
||
397 | je .next_block_folder |
||
398 | |||
399 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR |
||
400 | jne .not_found ;нашли, но это не папка |
||
401 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
402 | mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
||
403 | call ext2_get_inode |
||
404 | mov ebp, ebx |
||
405 | jmp .next_folder |
||
406 | |||
407 | .not_found: |
||
408 | or ebx, -1 |
||
409 | mov eax, ERROR_FILE_NOT_FOUND |
||
410 | ret |
||
411 | ;--------------------------------------------- final step |
||
412 | ; in ebp - pointer to final inode (folder). |
||
413 | .get_folder: |
||
414 | push edx ;заголовок будем заполнять в конце (адрес - в стеке) edx |
||
415 | push [EXT2_read_in_folder] ;сохраненный регистр тоже в стек |
||
416 | |||
417 | mov edi, [EXT2_files_in_folder] ;edi = число блоков для чтения |
||
418 | and [EXT2_read_in_folder], 0 |
||
419 | and [EXT2_files_in_folder], 0 |
||
420 | |||
1384 | turbanoff | 421 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] |
422 | mov [EXT2_counter_blocks], eax |
||
1378 | turbanoff | 423 | |
424 | add edx, 32 ;заголовок будем заполнять в конце (адрес - в стеке) edx = current mem for return |
||
425 | xor esi, esi ;esi = номер блока по порядку |
||
426 | |||
427 | .new_block_folder: ;reserved label |
||
428 | mov ecx, esi ; получим номер блока |
||
429 | call ext2_get_inode_block |
||
430 | |||
431 | mov eax, ecx |
||
432 | mov ebx, [ext2_data.ext2_save_block] |
||
433 | call ext2_get_block ; и считываем блок с hdd |
||
434 | |||
435 | mov eax, ebx ; eax = current dir record |
||
436 | add ebx, [ext2_data.block_size] |
||
437 | mov [EXT2_end_block], ebx ; запомним конец очередного блока |
||
438 | |||
439 | pop ecx |
||
440 | mov ecx, [ecx] ; ecx = first wanted (flags ommited) |
||
441 | |||
442 | .find_wanted_start: |
||
443 | jecxz .find_wanted_end |
||
444 | .find_wanted_cycle: |
||
445 | cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
||
446 | je @F |
||
447 | inc [EXT2_files_in_folder] |
||
448 | @@: |
||
449 | movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] |
||
450 | add eax, ebx ; к следующей записи |
||
451 | cmp eax, [EXT2_end_block] ; проверяем "конец" |
||
1384 | turbanoff | 452 | jae .end_block_find_wanted |
1378 | turbanoff | 453 | loop .find_wanted_cycle |
454 | .find_wanted_end: |
||
455 | |||
456 | mov ecx, edi |
||
457 | .wanted_start: ; ищем first_wanted+count |
||
458 | jecxz .wanted_end |
||
459 | .wanted_cycle: |
||
460 | cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
||
461 | jz .empty_rec |
||
462 | inc [EXT2_files_in_folder] |
||
463 | inc [EXT2_read_in_folder] |
||
464 | |||
1384 | turbanoff | 465 | mov edi, edx |
466 | push eax ecx |
||
467 | xor eax, eax |
||
468 | mov ecx, 40 / 4 |
||
469 | rep stosd |
||
470 | pop ecx eax |
||
1378 | turbanoff | 471 | |
1384 | turbanoff | 472 | cmp [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;папка или нет |
473 | jz @F |
||
474 | |||
1378 | turbanoff | 475 | push eax ;получим размер, если это файл |
476 | mov eax, [eax + EXT2_DIR_STRUC.inode] |
||
477 | mov ebx, [ext2_data.ext2_temp_inode] |
||
478 | call ext2_get_inode |
||
479 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size |
||
480 | mov ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size |
||
481 | mov dword [edx+32], eax |
||
482 | mov dword [edx+36], ebx |
||
483 | xor dword [edx], FS_FT_DIR ; для файлов xor - 2 раза |
||
484 | pop eax |
||
485 | @@: |
||
486 | xor dword [edx], FS_FT_DIR |
||
1384 | turbanoff | 487 | or dword [edx+4], FS_FT_ASCII ; symbol type in name |
1378 | turbanoff | 488 | |
489 | push ecx esi ;copy name |
||
490 | movzx ecx, [eax + EXT2_DIR_STRUC.name_len] |
||
491 | mov edi, edx |
||
492 | add edi, 40 |
||
493 | lea esi, [eax + EXT2_DIR_STRUC.name] |
||
494 | rep movsb |
||
495 | pop esi ecx |
||
496 | and byte [edi], 0 |
||
497 | |||
498 | add edx, 40 + 264 ; go to next record |
||
499 | .empty_rec: |
||
500 | movzx ebx, [eax + EXT2_DIR_STRUC.rec_len] |
||
501 | add eax, ebx |
||
502 | cmp eax, [EXT2_end_block] |
||
1384 | turbanoff | 503 | jae .end_block_wanted ;по хорошему должно быть =, но ччнш |
1378 | turbanoff | 504 | loop .wanted_cycle |
505 | |||
506 | .wanted_end: ;теперь дойдем до конца чтобы узнать сколько файлов в папке |
||
507 | or ecx, -1 ;цикл уже есть, просто поставим ему огромный счетчик |
||
508 | jmp .find_wanted_cycle |
||
509 | |||
510 | .end_block_find_wanted: ;вылетили из цикла find_wanted |
||
511 | mov ebx, [ext2_data.count_block_in_block] |
||
512 | sub [EXT2_counter_blocks], ebx |
||
513 | jz .end_dir |
||
514 | |||
515 | ;получаем новый блок |
||
516 | inc esi |
||
517 | push ecx |
||
518 | mov ecx, esi |
||
519 | call ext2_get_inode_block |
||
520 | mov eax, ecx |
||
521 | mov ebx, [ext2_data.ext2_save_block] |
||
522 | call ext2_get_block |
||
523 | pop ecx |
||
524 | dec ecx |
||
525 | mov eax, ebx |
||
526 | add ebx, [ext2_data.block_size] |
||
527 | mov [EXT2_end_block], ebx |
||
528 | jmp .find_wanted_start |
||
529 | |||
530 | .end_block_wanted: ;вылетели из цикла wanted |
||
531 | mov ebx, [ext2_data.count_block_in_block] |
||
532 | sub [EXT2_counter_blocks], ebx |
||
533 | jz .end_dir |
||
534 | |||
535 | inc esi |
||
536 | push ecx |
||
537 | mov ecx, esi |
||
538 | call ext2_get_inode_block |
||
539 | mov eax, ecx |
||
540 | mov ebx, [ext2_data.ext2_save_block] |
||
541 | call ext2_get_block |
||
542 | pop ecx |
||
543 | dec ecx |
||
544 | mov eax, ebx |
||
545 | add ebx, [ext2_data.block_size] |
||
546 | mov [EXT2_end_block], ebx |
||
547 | jmp .wanted_start |
||
548 | |||
549 | .end_dir: |
||
550 | pop edx |
||
551 | mov ebx, [EXT2_read_in_folder] |
||
552 | mov ecx, [EXT2_files_in_folder] |
||
553 | mov dword [edx], 1 ;version |
||
554 | xor eax, eax |
||
555 | mov [edx+4], ebx |
||
556 | mov [edx+8], ecx |
||
557 | lea edi, [edx + 12] |
||
558 | mov ecx, 20 / 4 |
||
559 | rep stosd |
||
560 | ret |
||
561 | ;====================== end ext2_HdReadFolder |
||
562 | |||
563 | ;---------------------------------------------------------------- |
||
564 | ; |
||
565 | ; ext2_HdRead - read hard disk |
||
566 | ; |
||
567 | ; esi points to filename |
||
568 | ; ebx pointer to 64-bit number = first wanted byte, 0+ |
||
569 | ; may be ebx=0 - start from first byte |
||
570 | ; ecx number of bytes to read, 0+ |
||
571 | ; edx mem location to return data |
||
572 | ; |
||
573 | ; ret ebx = bytes read or 0xffffffff file not found |
||
574 | ; eax = 0 ok read or other = errormsg |
||
575 | ; |
||
576 | ;-------------------------------------------------------------- |
||
577 | ext2_HdRead: |
||
578 | mov ebp, [ext2_data.root_inode] |
||
579 | |||
1384 | turbanoff | 580 | push ecx edx ebx |
1378 | turbanoff | 581 | .next_folder: |
582 | push esi |
||
583 | @@: |
||
584 | lodsb |
||
585 | test al, al |
||
586 | jz .find_end |
||
587 | cmp al, '/' |
||
588 | jz .find_folder |
||
589 | jmp @B |
||
590 | |||
591 | .find_end: |
||
592 | ;установим флаг что ищем файл или очередную папку |
||
593 | mov edi, 1 |
||
594 | jmp .find_any |
||
595 | .find_folder: |
||
596 | xor edi, edi |
||
597 | .find_any: |
||
598 | pop esi |
||
599 | |||
600 | cmp byte [esi], 0 |
||
601 | jz .not_found |
||
602 | |||
603 | or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode |
||
604 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков |
||
605 | add eax, [ext2_data.count_block_in_block] |
||
606 | mov [EXT2_end_block], eax |
||
607 | .next_block_folder: |
||
608 | mov eax, [ext2_data.count_block_in_block] |
||
609 | sub [EXT2_end_block], eax |
||
610 | jz .not_found |
||
611 | inc [EXT2_counter_blocks] |
||
612 | mov ecx, [EXT2_counter_blocks] |
||
613 | call ext2_get_inode_block |
||
614 | |||
615 | mov eax, ecx |
||
616 | mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
||
617 | call ext2_get_block |
||
618 | |||
619 | mov eax, esi |
||
620 | call ext2_test_block_by_name |
||
621 | cmp eax, esi ;нашли имя? |
||
622 | je .next_block_folder |
||
623 | |||
624 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_REG_FILE |
||
625 | je .test_file |
||
626 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR |
||
1384 | turbanoff | 627 | jne .this_is_nofile |
628 | |||
629 | ;.test_dir: |
||
1378 | turbanoff | 630 | cmp edi, 0 |
1384 | turbanoff | 631 | jne .this_is_nofile |
1378 | turbanoff | 632 | |
633 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
634 | mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
||
635 | call ext2_get_inode |
||
636 | mov ebp, ebx |
||
637 | jmp .next_folder |
||
638 | |||
639 | .test_file: |
||
640 | cmp edi, 0 |
||
641 | je .not_found |
||
642 | |||
643 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
644 | mov ebx, [ext2_data.ext2_save_inode] |
||
645 | call ext2_get_inode |
||
646 | jmp .get_file |
||
647 | |||
648 | .not_found: |
||
649 | pop edx ecx ebx |
||
650 | or ebx, -1 |
||
651 | mov eax, ERROR_FILE_NOT_FOUND |
||
652 | ret |
||
1384 | turbanoff | 653 | .this_is_nofile: |
1378 | turbanoff | 654 | pop edx ecx ebx |
655 | or ebx, -1 |
||
656 | mov eax, ERROR_ACCESS_DENIED |
||
657 | .end_read: |
||
658 | ret |
||
659 | |||
660 | ;-----------------------------------------------------------------------------final step |
||
661 | .get_file: |
||
662 | mov ebp ,ebx |
||
663 | |||
664 | ;pop eax edi ecx ; первый_блок память кол-во_байт |
||
665 | mov esi, [esp] |
||
666 | mov edi, [esp + 8] ;edi = нужно считать байт |
||
667 | |||
668 | ;///// сравним хватит ли нам файла или нет |
||
669 | mov ebx, [esi+4] |
||
670 | mov eax, [esi] ; ebx : eax - стартовый номер байта |
||
671 | |||
672 | mov edx, [ebp + EXT2_INODE_STRUC.i_dir_acl] |
||
673 | mov ecx, [ebp + EXT2_INODE_STRUC.i_size] ;edx : ecx - размер файла |
||
674 | |||
675 | cmp edx, ebx |
||
676 | ja .size_great |
||
677 | jb .size_less |
||
678 | |||
679 | cmp ecx, eax |
||
680 | ja .size_great |
||
681 | |||
682 | .size_less: |
||
683 | add esp, 12 |
||
684 | mov ebx, 0 |
||
685 | mov eax, 6 ;EOF |
||
686 | ret |
||
687 | .size_great: |
||
688 | ;прибавим к старту кол-во байт для чтения |
||
689 | add eax, edi |
||
690 | jnc @F |
||
691 | inc ebx |
||
692 | @@: |
||
693 | cmp edx, ebx |
||
694 | ja .size_great_great |
||
695 | jb .size_great_less |
||
696 | cmp ecx, eax |
||
697 | jae .size_great_great |
||
698 | ;jmp .size_great_less |
||
699 | ; а если равно, то не важно куда |
||
700 | .size_great_less: |
||
701 | or [EXT2_files_in_folder], 1 ;читаем по границе размера |
||
702 | sub ecx, [esi] |
||
703 | pop eax edi edx ;ecx - не меняем |
||
704 | jmp @F |
||
705 | |||
706 | .size_great_great: |
||
707 | and [EXT2_files_in_folder], 0 ;читаем нормально |
||
708 | pop eax edi ecx |
||
709 | |||
710 | @@: |
||
711 | push ecx ;сохраним размер считанных байт в стеке |
||
712 | test eax, eax |
||
713 | je .zero_start |
||
714 | |||
715 | ;пока делаем п..ц криво =) |
||
716 | mov edx, [eax+4] |
||
717 | mov eax, [eax] |
||
718 | div [ext2_data.block_size] |
||
719 | |||
720 | mov [EXT2_counter_blocks], eax ;номер блока запоминаем |
||
721 | |||
722 | push ecx |
||
723 | mov ecx, eax |
||
724 | call ext2_get_inode_block |
||
725 | mov ebx , [ext2_data.ext2_save_block] |
||
726 | mov eax, ecx |
||
727 | call ext2_get_block |
||
728 | pop ecx |
||
729 | add ebx, edx |
||
730 | |||
731 | neg edx |
||
732 | add edx,[ext2_data.block_size] ;block_size - стартоый блок = сколько байт 1-го блока |
||
733 | cmp ecx, edx |
||
734 | jbe .only_one_block |
||
735 | |||
736 | mov eax, ecx |
||
737 | sub eax, edx |
||
738 | mov ecx, edx |
||
739 | |||
740 | mov esi, ebx |
||
741 | rep movsb ;кусок 1-го блока |
||
742 | |||
743 | .zero_start: |
||
744 | mov ebx, edi ;чтение блока прям в ebx |
||
745 | ;теперь в eax кол-во оставшихся байт для чтения |
||
746 | xor edx, edx |
||
747 | div [ext2_data.block_size] |
||
748 | mov [EXT2_end_block], eax ;кол-во целых блоков |
||
749 | @@: |
||
750 | cmp [EXT2_end_block], 0 |
||
751 | jz .finish_block |
||
752 | inc [EXT2_counter_blocks] |
||
753 | mov ecx, [EXT2_counter_blocks] |
||
754 | call ext2_get_inode_block |
||
755 | |||
756 | mov eax, ecx ;а ebx уже забит нужным значением |
||
757 | call ext2_get_block |
||
758 | add ebx, [ext2_data.block_size] |
||
759 | |||
760 | dec [EXT2_end_block] |
||
761 | jmp @B |
||
762 | |||
763 | .finish_block: ;в edx - кол-во байт в последнем блоке |
||
764 | cmp edx, 0 |
||
765 | je .end_read |
||
766 | |||
767 | mov ecx, [EXT2_counter_blocks] |
||
768 | inc ecx |
||
769 | call ext2_get_inode_block |
||
770 | |||
771 | mov edi, ebx |
||
772 | mov eax, ecx |
||
773 | mov ebx, [ext2_data.ext2_save_block] |
||
774 | call ext2_get_block |
||
775 | |||
776 | mov ecx, edx |
||
777 | |||
778 | .only_one_block: |
||
779 | mov esi, ebx |
||
780 | rep movsb ;кусок 1-го блока (последнего) |
||
781 | pop ebx |
||
782 | cmp [EXT2_files_in_folder], 0 |
||
783 | jz @F |
||
784 | |||
785 | mov eax, 6 ;EOF |
||
786 | ret |
||
787 | @@: |
||
788 | xor eax, eax |
||
789 | ret |
||
790 | ;======================== |
||
1384 | turbanoff | 791 | ;in : esi -> name not save register |
792 | ;out: ebp -> inode cf=0 |
||
793 | ; ebp -> trash cf=1 |
||
794 | ext2_find_lfn: |
||
795 | mov ebp, [ext2_data.root_inode] |
||
796 | .next_folder: |
||
797 | or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode |
||
798 | mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков |
||
799 | add eax, [ext2_data.count_block_in_block] |
||
800 | mov [EXT2_end_block], eax |
||
801 | .next_block_folder: |
||
802 | mov eax, [ext2_data.count_block_in_block] |
||
803 | sub [EXT2_end_block], eax |
||
804 | jz .not_found |
||
805 | inc [EXT2_counter_blocks] |
||
806 | mov ecx, [EXT2_counter_blocks] |
||
807 | call ext2_get_inode_block |
||
1378 | turbanoff | 808 | |
1384 | turbanoff | 809 | mov eax, ecx |
810 | mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
||
811 | call ext2_get_block |
||
812 | |||
813 | mov eax, esi |
||
814 | call ext2_test_block_by_name |
||
815 | cmp eax, esi ;нашли имя? |
||
816 | jz .next_block_folder |
||
817 | |||
818 | cmp byte [esi],0 |
||
819 | jz .get_inode_ret |
||
820 | |||
821 | cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR |
||
822 | jne .not_found ;нашли, но это не папка |
||
823 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
824 | mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
||
825 | call ext2_get_inode |
||
826 | mov ebp, ebx |
||
827 | jmp .next_folder |
||
828 | |||
829 | .not_found: |
||
830 | stc |
||
831 | ret |
||
832 | .get_inode_ret: |
||
833 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
||
834 | mov ebx, [ext2_data.ext2_save_inode] |
||
835 | call ext2_get_inode |
||
836 | mov ebp, ebx |
||
837 | .ret: |
||
838 | clc |
||
839 | ret |
||
840 | |||
841 | |||
842 | ;======================== |
||
1378 | turbanoff | 843 | ext2_HdRewrite: |
844 | ; xchg bx, bx |
||
845 | xor ebx, ebx |
||
846 | mov eax, ERROR_UNSUPPORTED_FS |
||
847 | ret |
||
848 | |||
849 | ext2_HdWrite: |
||
850 | ; xchg bx, bx |
||
851 | xor ebx, ebx |
||
852 | mov eax, ERROR_UNSUPPORTED_FS |
||
853 | ret |
||
854 | ext2_HdSetFileEnd: |
||
855 | ; xchg bx, bx |
||
856 | xor ebx, ebx |
||
857 | mov eax, ERROR_UNSUPPORTED_FS |
||
858 | ret |
||
1384 | turbanoff | 859 | |
1378 | turbanoff | 860 | ext2_HdGetFileInfo: |
1384 | turbanoff | 861 | cmp byte [esi], 0 |
862 | jz .doit |
||
863 | |||
864 | call ext2_find_lfn |
||
865 | jnc .doit2 |
||
866 | ;.not_found: |
||
867 | mov eax, ERROR_FILE_NOT_FOUND |
||
1378 | turbanoff | 868 | ret |
1384 | turbanoff | 869 | |
870 | .doit: |
||
871 | mov ebp, [ext2_data.root_inode] |
||
872 | .doit2: |
||
873 | xor eax, eax |
||
874 | mov edi, edx |
||
875 | mov ecx, 40/4 |
||
876 | rep stosd ; fill zero |
||
877 | |||
878 | test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
||
879 | jz @F |
||
880 | or dword [edx], FS_FT_DIR |
||
881 | @@: |
||
882 | mov byte [edx+1], FS_FT_ASCII |
||
883 | mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size |
||
884 | mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size |
||
885 | mov dword [edx+32], eax |
||
886 | mov dword [edx+36], ebx |
||
887 | |||
888 | xor eax, eax |
||
889 | ret |
||
890 | |||
1378 | turbanoff | 891 | ext2_HdSetFileInfo: |
892 | ; xchg bx, bx |
||
893 | xor ebx, ebx |
||
894 | mov eax, ERROR_UNSUPPORTED_FS |
||
895 | ret |
||
896 | ext2_HdDelete: |
||
897 | ; xchg bx, bx |
||
898 | xor ebx, ebx |
||
899 | mov eax, ERROR_UNSUPPORTED_FS |
||
900 | ret |
||
901 |