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