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