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