Rev 4923 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4923 | Rev 5116 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Contains ext2 initialization, plus syscall handling code. ;; |
3 | ;; Contains ext2 initialization, plus syscall handling code. ;; |
4 | ;; ;; |
4 | ;; ;; |
5 | ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;; |
5 | ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;; |
6 | ;; Distributed under terms of the GNU General Public License ;; |
6 | ;; Distributed under terms of the GNU General Public License ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
9 | 9 | ||
10 | $Revision: 4891 $ |
10 | $Revision: 5089 $ |
11 | 11 | ||
12 | 12 | ||
13 | include 'ext2.inc' |
13 | include 'ext2.inc' |
14 | include 'blocks.inc' |
14 | include 'blocks.inc' |
15 | include 'inode.inc' |
15 | include 'inode.inc' |
16 | include 'resource.inc' |
16 | include 'resource.inc' |
17 | 17 | ||
18 | iglobal |
18 | iglobal |
19 | align 4 |
19 | align 4 |
20 | ext2_user_functions: |
20 | ext2_user_functions: |
21 | dd ext2_free |
21 | dd ext2_free |
22 | dd (ext2_user_functions_end - ext2_user_functions - 4) / 4 |
22 | dd (ext2_user_functions_end - ext2_user_functions - 4) / 4 |
23 | dd ext2_Read |
23 | dd ext2_Read |
24 | dd ext2_ReadFolder |
24 | dd ext2_ReadFolder |
25 | dd ext2_Rewrite |
25 | dd ext2_Rewrite |
26 | dd ext2_Write |
26 | dd ext2_Write |
27 | dd ext2_SetFileEnd |
27 | dd ext2_SetFileEnd |
28 | dd ext2_GetFileInfo |
28 | dd ext2_GetFileInfo |
29 | dd ext2_SetFileInfo |
29 | dd ext2_SetFileInfo |
30 | dd 0 |
30 | dd 0 |
31 | dd ext2_Delete |
31 | dd ext2_Delete |
32 | dd ext2_CreateFolder |
32 | dd ext2_CreateFolder |
33 | ext2_user_functions_end: |
33 | ext2_user_functions_end: |
34 | endg |
34 | endg |
35 | 35 | ||
36 | ;--------------------------------------------------------------------- |
36 | ;--------------------------------------------------------------------- |
37 | ; Locks up an ext2 partition. |
37 | ; Locks up an ext2 partition. |
38 | ; Input: ebp = pointer to EXTFS. |
38 | ; Input: ebp = pointer to EXTFS. |
39 | ;--------------------------------------------------------------------- |
39 | ;--------------------------------------------------------------------- |
40 | proc ext2_lock |
40 | proc ext2_lock |
41 | lea ecx, [ebp + EXTFS.lock] |
41 | lea ecx, [ebp + EXTFS.lock] |
42 | jmp mutex_lock |
42 | jmp mutex_lock |
43 | endp |
43 | endp |
44 | 44 | ||
45 | ;--------------------------------------------------------------------- |
45 | ;--------------------------------------------------------------------- |
46 | ; Unlocks up an ext2 partition. |
46 | ; Unlocks up an ext2 partition. |
47 | ; Input: ebp = pointer to EXTFS. |
47 | ; Input: ebp = pointer to EXTFS. |
48 | ;--------------------------------------------------------------------- |
48 | ;--------------------------------------------------------------------- |
49 | proc ext2_unlock |
49 | proc ext2_unlock |
50 | lea ecx, [ebp + EXTFS.lock] |
50 | lea ecx, [ebp + EXTFS.lock] |
51 | jmp mutex_unlock |
51 | jmp mutex_unlock |
52 | endp |
52 | endp |
53 | 53 | ||
54 | ;--------------------------------------------------------------------- |
54 | ;--------------------------------------------------------------------- |
55 | ; Check if it's a valid ext* superblock. |
55 | ; Check if it's a valid ext* superblock. |
56 | ; Input: ebp: first three fields of PARTITION structure. |
56 | ; Input: ebp: first three fields of PARTITION structure. |
57 | ; ebx + 512: points to 512-bytes buffer that can be used for anything. |
57 | ; ebx + 512: points to 512-bytes buffer that can be used for anything. |
58 | ; Output: eax: clear if can't create partition; set to EXTFS otherwise. |
58 | ; Output: eax: clear if can't create partition; set to EXTFS otherwise. |
59 | ;--------------------------------------------------------------------- |
59 | ;--------------------------------------------------------------------- |
60 | proc ext2_create_partition |
60 | proc ext2_create_partition |
61 | push ebx |
61 | push ebx |
- | 62 | cmp dword [esi+DISK.MediaInfo.SectorSize], 512 |
|
- | 63 | jnz .fail |
|
62 | 64 | ||
63 | mov eax, 2 ; Superblock starts at 1024-bytes. |
65 | mov eax, 2 ; Superblock starts at 1024-bytes. |
64 | add ebx, 512 ; Get pointer to fs-specific buffer. |
66 | add ebx, 512 ; Get pointer to fs-specific buffer. |
65 | call fs_read32_sys |
67 | call fs_read32_sys |
66 | test eax, eax |
68 | test eax, eax |
67 | jnz .fail |
69 | jnz .fail |
68 | 70 | ||
69 | ; Allowed 1KiB, 2KiB, 4KiB, 8KiB. |
71 | ; Allowed 1KiB, 2KiB, 4KiB, 8KiB. |
70 | cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 |
72 | cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 |
71 | ja .fail |
73 | ja .fail |
72 | 74 | ||
73 | cmp [ebx + EXT2_SB_STRUC.magic], EXT2_SUPER_MAGIC |
75 | cmp [ebx + EXT2_SB_STRUC.magic], EXT2_SUPER_MAGIC |
74 | jne .fail |
76 | jne .fail |
75 | 77 | ||
76 | cmp [ebx + EXT2_SB_STRUC.state], EXT2_VALID_FS |
78 | cmp [ebx + EXT2_SB_STRUC.state], EXT2_VALID_FS |
77 | jne .fail |
79 | jne .fail |
78 | 80 | ||
79 | ; Can't have no inodes per group. |
81 | ; Can't have no inodes per group. |
80 | cmp [ebx + EXT2_SB_STRUC.inodes_per_group], 0 |
82 | cmp [ebx + EXT2_SB_STRUC.inodes_per_group], 0 |
81 | je .fail |
83 | je .fail |
82 | 84 | ||
83 | ; If incompatible features required, unusable superblock. |
85 | ; If incompatible features required, unusable superblock. |
84 | mov eax, [ebx + EXT2_SB_STRUC.feature_incompat] |
86 | mov eax, [ebx + EXT2_SB_STRUC.feature_incompat] |
85 | test eax, not EXT4_FEATURE_INCOMPAT_SUPP |
87 | test eax, not EXT4_FEATURE_INCOMPAT_SUPP |
86 | jz .setup |
88 | jz .setup |
87 | 89 | ||
88 | .fail: |
90 | .fail: |
89 | ; Not a (valid/usable) EXT2 superblock. |
91 | ; Not a (valid/usable) EXT2 superblock. |
90 | pop ebx |
92 | pop ebx |
91 | xor eax, eax |
93 | xor eax, eax |
92 | ret |
94 | ret |
93 | 95 | ||
94 | .setup: |
96 | .setup: |
95 | movi eax, sizeof.EXTFS |
97 | movi eax, sizeof.EXTFS |
96 | call malloc |
98 | call malloc |
97 | test eax, eax |
99 | test eax, eax |
98 | jz ext2_create_partition.fail |
100 | jz ext2_create_partition.fail |
99 | 101 | ||
100 | ; Store the first sector field. |
102 | ; Store the first sector field. |
101 | mov ecx, dword[ebp + PARTITION.FirstSector] |
103 | mov ecx, dword[ebp + PARTITION.FirstSector] |
102 | mov dword[eax + EXTFS.FirstSector], ecx |
104 | mov dword[eax + EXTFS.FirstSector], ecx |
103 | mov ecx, dword [ebp + PARTITION.FirstSector+4] |
105 | mov ecx, dword [ebp + PARTITION.FirstSector+4] |
104 | mov dword [eax + EXTFS.FirstSector+4], ecx |
106 | mov dword [eax + EXTFS.FirstSector+4], ecx |
105 | 107 | ||
106 | ; The length field. |
108 | ; The length field. |
107 | mov ecx, dword[ebp + PARTITION.Length] |
109 | mov ecx, dword[ebp + PARTITION.Length] |
108 | mov dword[eax + EXTFS.Length], ecx |
110 | mov dword[eax + EXTFS.Length], ecx |
109 | mov ecx, dword[ebp + PARTITION.Length+4] |
111 | mov ecx, dword[ebp + PARTITION.Length+4] |
110 | mov dword[eax + EXTFS.Length+4], ecx |
112 | mov dword[eax + EXTFS.Length+4], ecx |
111 | 113 | ||
112 | ; The disk field. |
114 | ; The disk field. |
113 | mov ecx, [ebp + PARTITION.Disk] |
115 | mov ecx, [ebp + PARTITION.Disk] |
114 | mov [eax + EXTFS.Disk], ecx |
116 | mov [eax + EXTFS.Disk], ecx |
115 | 117 | ||
116 | mov [eax + EXTFS.FSUserFunctions], ext2_user_functions |
118 | mov [eax + EXTFS.FSUserFunctions], ext2_user_functions |
117 | 119 | ||
118 | push ebp esi edi |
120 | push ebp esi edi |
119 | 121 | ||
120 | mov ebp, eax |
122 | mov ebp, eax |
121 | lea ecx, [eax + EXTFS.lock] |
123 | lea ecx, [eax + EXTFS.lock] |
122 | call mutex_init |
124 | call mutex_init |
123 | 125 | ||
124 | ; Copy superblock from buffer to reserved memory. |
126 | ; Copy superblock from buffer to reserved memory. |
125 | mov esi, ebx |
127 | mov esi, ebx |
126 | lea edi, [ebp + EXTFS.superblock] |
128 | lea edi, [ebp + EXTFS.superblock] |
127 | mov ecx, 512/4 |
129 | mov ecx, 512/4 |
128 | rep movsd |
130 | rep movsd |
129 | 131 | ||
130 | ; Get total groups. |
132 | ; Get total groups. |
131 | mov eax, [ebx + EXT2_SB_STRUC.blocks_count] |
133 | mov eax, [ebx + EXT2_SB_STRUC.blocks_count] |
132 | sub eax, [ebx + EXT2_SB_STRUC.first_data_block] |
134 | sub eax, [ebx + EXT2_SB_STRUC.first_data_block] |
133 | dec eax |
135 | dec eax |
134 | xor edx, edx |
136 | xor edx, edx |
135 | div [ebx + EXT2_SB_STRUC.blocks_per_group] |
137 | div [ebx + EXT2_SB_STRUC.blocks_per_group] |
136 | inc eax |
138 | inc eax |
137 | mov [ebp + EXTFS.groups_count], eax |
139 | mov [ebp + EXTFS.groups_count], eax |
138 | 140 | ||
139 | ; Get log(block_size), such that 1,2,3,4 equ 1KiB,2KiB,4KiB,8KiB. |
141 | ; Get log(block_size), such that 1,2,3,4 equ 1KiB,2KiB,4KiB,8KiB. |
140 | mov ecx, [ebx + EXT2_SB_STRUC.log_block_size] |
142 | mov ecx, [ebx + EXT2_SB_STRUC.log_block_size] |
141 | inc ecx |
143 | inc ecx |
142 | mov [ebp + EXTFS.log_block_size], ecx |
144 | mov [ebp + EXTFS.log_block_size], ecx |
143 | 145 | ||
144 | ; 512-byte blocks in ext2 blocks. |
146 | ; 512-byte blocks in ext2 blocks. |
145 | mov eax, 1 |
147 | mov eax, 1 |
146 | shl eax, cl |
148 | shl eax, cl |
147 | mov [ebp + EXTFS.count_block_in_block], eax |
149 | mov [ebp + EXTFS.count_block_in_block], eax |
148 | 150 | ||
149 | ; Get block_size/4 (we'll find square later). |
151 | ; Get block_size/4 (we'll find square later). |
150 | shl eax, 7 |
152 | shl eax, 7 |
151 | mov [ebp + EXTFS.count_pointer_in_block], eax |
153 | mov [ebp + EXTFS.count_pointer_in_block], eax |
152 | mov edx, eax |
154 | mov edx, eax |
153 | 155 | ||
154 | ; Get block size. |
156 | ; Get block size. |
155 | shl eax, 2 |
157 | shl eax, 2 |
156 | mov [ebp + EXTFS.block_size], eax |
158 | mov [ebp + EXTFS.block_size], eax |
157 | 159 | ||
158 | ; Save block size for 2 kernel_alloc calls. |
160 | ; Save block size for 2 kernel_alloc calls. |
159 | push eax eax |
161 | push eax eax |
160 | 162 | ||
161 | mov eax, edx |
163 | mov eax, edx |
162 | mul edx |
164 | mul edx |
163 | mov [ebp + EXTFS.count_pointer_in_block_square], eax |
165 | mov [ebp + EXTFS.count_pointer_in_block_square], eax |
164 | 166 | ||
165 | ; Have temporary block storage for get_inode procedure, and one for global procedure. |
167 | ; Have temporary block storage for get_inode procedure, and one for global procedure. |
166 | KERNEL_ALLOC [ebp + EXTFS.ext2_save_block], .error |
168 | KERNEL_ALLOC [ebp + EXTFS.ext2_save_block], .error |
167 | KERNEL_ALLOC [ebp + EXTFS.ext2_temp_block], .error |
169 | KERNEL_ALLOC [ebp + EXTFS.ext2_temp_block], .error |
168 | 170 | ||
169 | mov [ebp + EXTFS.partition_flags], 0x00000000 |
171 | mov [ebp + EXTFS.partition_flags], 0x00000000 |
170 | mov eax, [ebx + EXT2_SB_STRUC.feature_ro_compat] |
172 | mov eax, [ebx + EXT2_SB_STRUC.feature_ro_compat] |
171 | and eax, not EXT2_FEATURE_RO_COMPAT_SUPP |
173 | and eax, not EXT2_FEATURE_RO_COMPAT_SUPP |
172 | jnz .read_only |
174 | jnz .read_only |
173 | 175 | ||
174 | mov eax, [ebx + EXT2_SB_STRUC.feature_incompat] |
176 | mov eax, [ebx + EXT2_SB_STRUC.feature_incompat] |
175 | and eax, EXT4_FEATURE_INCOMPAT_W_NOT_SUPP |
177 | and eax, EXT4_FEATURE_INCOMPAT_W_NOT_SUPP |
176 | jz @F |
178 | jz @F |
177 | 179 | ||
178 | .read_only: |
180 | .read_only: |
179 | ; Mark as read-only. |
181 | ; Mark as read-only. |
180 | or [ebp + EXTFS.partition_flags], EXT2_RO |
182 | or [ebp + EXTFS.partition_flags], EXT2_RO |
181 | @@: |
183 | @@: |
182 | mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group] |
184 | mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group] |
183 | mov [ebp + EXTFS.blocks_per_group], ecx |
185 | mov [ebp + EXTFS.blocks_per_group], ecx |
184 | 186 | ||
185 | movzx ecx, word[ebx + EXT2_SB_STRUC.inode_size] |
187 | movzx ecx, word[ebx + EXT2_SB_STRUC.inode_size] |
186 | mov [ebp + EXTFS.inode_size], ecx |
188 | mov [ebp + EXTFS.inode_size], ecx |
187 | 189 | ||
188 | ; Allocate for three inodes (loop would be overkill). |
190 | ; Allocate for three inodes (loop would be overkill). |
189 | push ecx ecx ecx |
191 | push ecx ecx ecx |
190 | 192 | ||
191 | KERNEL_ALLOC [ebp + EXTFS.ext2_save_inode], .error |
193 | KERNEL_ALLOC [ebp + EXTFS.ext2_save_inode], .error |
192 | KERNEL_ALLOC [ebp + EXTFS.ext2_temp_inode], .error |
194 | KERNEL_ALLOC [ebp + EXTFS.ext2_temp_inode], .error |
193 | KERNEL_ALLOC [ebp + EXTFS.root_inode], .error |
195 | KERNEL_ALLOC [ebp + EXTFS.root_inode], .error |
194 | 196 | ||
195 | ; Read root inode. |
197 | ; Read root inode. |
196 | mov ebx, eax |
198 | mov ebx, eax |
197 | mov eax, EXT2_ROOT_INO |
199 | mov eax, EXT2_ROOT_INO |
198 | call ext2_inode_read |
200 | call ext2_inode_read |
199 | 201 | ||
200 | test eax, eax |
202 | test eax, eax |
201 | jnz .error |
203 | jnz .error |
202 | 204 | ||
203 | ;call ext2_sb_update |
205 | ;call ext2_sb_update |
204 | ; Sync the disk. |
206 | ; Sync the disk. |
205 | ;mov esi, [ebp + PARTITION.Disk] |
207 | ;mov esi, [ebp + PARTITION.Disk] |
206 | ;call disk_sync ; eax contains error code, if any. |
208 | ;call disk_sync ; eax contains error code, if any. |
207 | 209 | ||
208 | mov eax, ebp ; Return pointer to EXTFS. |
210 | mov eax, ebp ; Return pointer to EXTFS. |
209 | pop edi esi ebp ebx |
211 | pop edi esi ebp ebx |
210 | ret |
212 | ret |
211 | 213 | ||
212 | ; Error in setting up. |
214 | ; Error in setting up. |
213 | .error: |
215 | .error: |
214 | ; Free save block. |
216 | ; Free save block. |
215 | KERNEL_FREE [ebp + EXTFS.ext2_save_block], .fail |
217 | KERNEL_FREE [ebp + EXTFS.ext2_save_block], .fail |
216 | 218 | ||
217 | ; Temporary block. |
219 | ; Temporary block. |
218 | KERNEL_FREE [ebp + EXTFS.ext2_temp_block], .fail |
220 | KERNEL_FREE [ebp + EXTFS.ext2_temp_block], .fail |
219 | 221 | ||
220 | ; All inodes. |
222 | ; All inodes. |
221 | KERNEL_FREE [ebp + EXTFS.ext2_save_inode], .fail |
223 | KERNEL_FREE [ebp + EXTFS.ext2_save_inode], .fail |
222 | KERNEL_FREE [ebp + EXTFS.ext2_temp_inode], .fail |
224 | KERNEL_FREE [ebp + EXTFS.ext2_temp_inode], .fail |
223 | KERNEL_FREE [ebp + EXTFS.root_inode], .fail |
225 | KERNEL_FREE [ebp + EXTFS.root_inode], .fail |
224 | 226 | ||
225 | mov eax, ebp |
227 | mov eax, ebp |
226 | call free |
228 | call free |
227 | 229 | ||
228 | jmp .fail |
230 | jmp .fail |
229 | endp |
231 | endp |
230 | 232 | ||
231 | ; FUNCTIONS PROVIDED BY SYSCALLS. |
233 | ; FUNCTIONS PROVIDED BY SYSCALLS. |
232 | 234 | ||
233 | ;--------------------------------------------------------------------- |
235 | ;--------------------------------------------------------------------- |
234 | ; Frees up all ext2 structures. |
236 | ; Frees up all ext2 structures. |
235 | ; Input: eax = pointer to EXTFS. |
237 | ; Input: eax = pointer to EXTFS. |
236 | ;--------------------------------------------------------------------- |
238 | ;--------------------------------------------------------------------- |
237 | proc ext2_free |
239 | proc ext2_free |
238 | push ebp |
240 | push ebp |
239 | 241 | ||
240 | xchg ebp, eax |
242 | xchg ebp, eax |
241 | stdcall kernel_free, [ebp+EXTFS.ext2_save_block] |
243 | stdcall kernel_free, [ebp+EXTFS.ext2_save_block] |
242 | stdcall kernel_free, [ebp+EXTFS.ext2_temp_block] |
244 | stdcall kernel_free, [ebp+EXTFS.ext2_temp_block] |
243 | stdcall kernel_free, [ebp+EXTFS.ext2_save_inode] |
245 | stdcall kernel_free, [ebp+EXTFS.ext2_save_inode] |
244 | stdcall kernel_free, [ebp+EXTFS.ext2_temp_inode] |
246 | stdcall kernel_free, [ebp+EXTFS.ext2_temp_inode] |
245 | stdcall kernel_free, [ebp+EXTFS.root_inode] |
247 | stdcall kernel_free, [ebp+EXTFS.root_inode] |
246 | 248 | ||
247 | xchg ebp, eax |
249 | xchg ebp, eax |
248 | call free |
250 | call free |
249 | 251 | ||
250 | pop ebp |
252 | pop ebp |
251 | ret |
253 | ret |
252 | endp |
254 | endp |
253 | 255 | ||
254 | ;--------------------------------------------------------------------- |
256 | ;--------------------------------------------------------------------- |
255 | ; Read disk folder. |
257 | ; Read disk folder. |
256 | ; Input: ebp = pointer to EXTFS structure. |
258 | ; Input: ebp = pointer to EXTFS structure. |
257 | ; esi + [esp + 4] = file name. |
259 | ; esi + [esp + 4] = file name. |
258 | ; ebx = pointer to parameters from sysfunc 70. |
260 | ; ebx = pointer to parameters from sysfunc 70. |
259 | ; Output: ebx = blocks read (or 0xFFFFFFFF, folder not found) |
261 | ; Output: ebx = blocks read (or 0xFFFFFFFF, folder not found) |
260 | ; eax = error code (0 implies no error) |
262 | ; eax = error code (0 implies no error) |
261 | ;--------------------------------------------------------------------- |
263 | ;--------------------------------------------------------------------- |
262 | ext2_ReadFolder: |
264 | ext2_ReadFolder: |
263 | ;DEBUGF 1, "Reading folder.\n" |
265 | ;DEBUGF 1, "Reading folder.\n" |
264 | call ext2_lock |
266 | call ext2_lock |
265 | cmp byte [esi], 0 |
267 | cmp byte [esi], 0 |
266 | jz .root_folder |
268 | jz .root_folder |
267 | 269 | ||
268 | push ebx |
270 | push ebx |
269 | stdcall ext2_inode_find, [esp + 4 + 4] ; Get inode. |
271 | stdcall ext2_inode_find, [esp + 4 + 4] ; Get inode. |
270 | pop ebx |
272 | pop ebx |
271 | 273 | ||
272 | mov esi, [ebp + EXTFS.ext2_save_inode] |
274 | mov esi, [ebp + EXTFS.ext2_save_inode] |
273 | test eax, eax |
275 | test eax, eax |
274 | jnz .error_ret |
276 | jnz .error_ret |
275 | 277 | ||
276 | ; If not a directory, then return with error. |
278 | ; If not a directory, then return with error. |
277 | test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
279 | test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
278 | jz .error_not_found |
280 | jz .error_not_found |
279 | jmp @F |
281 | jmp @F |
280 | 282 | ||
281 | .root_folder: |
283 | .root_folder: |
282 | mov esi, [ebp + EXTFS.root_inode] |
284 | mov esi, [ebp + EXTFS.root_inode] |
283 | test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
285 | test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
284 | jz .error_root |
286 | jz .error_root |
285 | 287 | ||
286 | ; Copy the inode. |
288 | ; Copy the inode. |
287 | mov edi, [ebp + EXTFS.ext2_save_inode] |
289 | mov edi, [ebp + EXTFS.ext2_save_inode] |
288 | mov ecx, [ebp + EXTFS.inode_size] |
290 | mov ecx, [ebp + EXTFS.inode_size] |
289 | shr ecx, 2 |
291 | shr ecx, 2 |
290 | 292 | ||
291 | push edi |
293 | push edi |
292 | rep movsd |
294 | rep movsd |
293 | pop esi |
295 | pop esi |
294 | 296 | ||
295 | @@: |
297 | @@: |
296 | cmp [esi + EXT2_INODE_STRUC.i_size], 0 ; Folder is empty. |
298 | cmp [esi + EXT2_INODE_STRUC.i_size], 0 ; Folder is empty. |
297 | je .error_empty_dir |
299 | je .error_empty_dir |
298 | 300 | ||
299 | mov edx, [ebx + 16] |
301 | mov edx, [ebx + 16] |
300 | push edx ; Result address [edi + 28]. |
302 | push edx ; Result address [edi + 28]. |
301 | push 0 ; End of the current block in folder [edi + 24] |
303 | push 0 ; End of the current block in folder [edi + 24] |
302 | push dword[ebx + 12] ; Blocks to read [edi + 20] |
304 | push dword[ebx + 12] ; Blocks to read [edi + 20] |
303 | push dword[ebx + 4] ; The first wanted file [edi + 16] |
305 | push dword[ebx + 4] ; The first wanted file [edi + 16] |
304 | push dword[ebx + 8] ; Flags [edi + 12] |
306 | push dword[ebx + 8] ; Flags [edi + 12] |
305 | push 0 ; Read files [edi + 8] |
307 | push 0 ; Read files [edi + 8] |
306 | push 0 ; Files in folder [edi + 4] |
308 | push 0 ; Files in folder [edi + 4] |
307 | push 0 ; Number of blocks read in dir (and current block index) [edi] |
309 | push 0 ; Number of blocks read in dir (and current block index) [edi] |
308 | 310 | ||
309 | ; Fill header with zeroes. |
311 | ; Fill header with zeroes. |
310 | mov edi, edx |
312 | mov edi, edx |
311 | mov ecx, 32/4 |
313 | mov ecx, 32/4 |
312 | rep stosd |
314 | rep stosd |
313 | 315 | ||
314 | mov edi, esp ; edi = pointer to local variables. |
316 | mov edi, esp ; edi = pointer to local variables. |
315 | add edx, 32 ; edx = mem to return. |
317 | add edx, 32 ; edx = mem to return. |
316 | 318 | ||
317 | xor ecx, ecx ; Get number of first block. |
319 | xor ecx, ecx ; Get number of first block. |
318 | call ext2_inode_get_block |
320 | call ext2_inode_get_block |
319 | test eax, eax |
321 | test eax, eax |
320 | jnz .error_get_block |
322 | jnz .error_get_block |
321 | 323 | ||
322 | mov eax, ecx |
324 | mov eax, ecx |
323 | mov ebx, [ebp + EXTFS.ext2_save_block] |
325 | mov ebx, [ebp + EXTFS.ext2_save_block] |
324 | call ext2_block_read ; Read the block. |
326 | call ext2_block_read ; Read the block. |
325 | test eax, eax |
327 | test eax, eax |
326 | jnz .error_get_block |
328 | jnz .error_get_block |
327 | 329 | ||
328 | mov eax, ebx ; esi: current directory record |
330 | mov eax, ebx ; esi: current directory record |
329 | add eax, [ebp + EXTFS.block_size] |
331 | add eax, [ebp + EXTFS.block_size] |
330 | 332 | ||
331 | mov [edi + 24], eax |
333 | mov [edi + 24], eax |
332 | 334 | ||
333 | mov ecx, [edi + 16] ; ecx = first wanted (flags ommited) |
335 | mov ecx, [edi + 16] ; ecx = first wanted (flags ommited) |
334 | 336 | ||
335 | .find_wanted_start: |
337 | .find_wanted_start: |
336 | jecxz .find_wanted_end |
338 | jecxz .find_wanted_end |
337 | 339 | ||
338 | .find_wanted_cycle: |
340 | .find_wanted_cycle: |
339 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; Don't count unused inode in total files. |
341 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; Don't count unused inode in total files. |
340 | jz @F |
342 | jz @F |
341 | 343 | ||
342 | inc dword [edi + 4] ; EXT2 files in folder. |
344 | inc dword [edi + 4] ; EXT2 files in folder. |
343 | dec ecx |
345 | dec ecx |
344 | @@: |
346 | @@: |
345 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
347 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
346 | 348 | ||
347 | cmp eax, 12 ; Minimum record length. |
349 | cmp eax, 12 ; Minimum record length. |
348 | jb .error_bad_len |
350 | jb .error_bad_len |
349 | test eax, 0x3 ; Record length must be divisible by four. |
351 | test eax, 0x3 ; Record length must be divisible by four. |
350 | jnz .error_bad_len |
352 | jnz .error_bad_len |
351 | 353 | ||
352 | sub [esi + EXT2_INODE_STRUC.i_size], eax ; Subtract "processed record" length directly from inode. |
354 | sub [esi + EXT2_INODE_STRUC.i_size], eax ; Subtract "processed record" length directly from inode. |
353 | add ebx, eax ; Go to next record. |
355 | add ebx, eax ; Go to next record. |
354 | cmp ebx, [edi + 24] ; If not reached the next block, continue. |
356 | cmp ebx, [edi + 24] ; If not reached the next block, continue. |
355 | jb .find_wanted_start |
357 | jb .find_wanted_start |
356 | 358 | ||
357 | push .find_wanted_start |
359 | push .find_wanted_start |
358 | .end_block: ; Get the next block. |
360 | .end_block: ; Get the next block. |
359 | cmp [esi + EXT2_INODE_STRUC.i_size], 0 |
361 | cmp [esi + EXT2_INODE_STRUC.i_size], 0 |
360 | jle .end_dir |
362 | jle .end_dir |
361 | 363 | ||
362 | inc dword [edi] ; Number of blocks read. |
364 | inc dword [edi] ; Number of blocks read. |
363 | 365 | ||
364 | ; Read the next block. |
366 | ; Read the next block. |
365 | push ecx |
367 | push ecx |
366 | mov ecx, [edi] |
368 | mov ecx, [edi] |
367 | call ext2_inode_get_block |
369 | call ext2_inode_get_block |
368 | test eax, eax |
370 | test eax, eax |
369 | jnz .error_get_block |
371 | jnz .error_get_block |
370 | 372 | ||
371 | mov eax, ecx |
373 | mov eax, ecx |
372 | mov ebx, [ebp + EXTFS.ext2_save_block] |
374 | mov ebx, [ebp + EXTFS.ext2_save_block] |
373 | call ext2_block_read |
375 | call ext2_block_read |
374 | test eax, eax |
376 | test eax, eax |
375 | jnz .error_get_block |
377 | jnz .error_get_block |
376 | pop ecx |
378 | pop ecx |
377 | 379 | ||
378 | mov eax, ebx |
380 | mov eax, ebx |
379 | add eax, [ebp + EXTFS.block_size] |
381 | add eax, [ebp + EXTFS.block_size] |
380 | mov [edi + 24], eax ; Update the end of the current block variable. |
382 | mov [edi + 24], eax ; Update the end of the current block variable. |
381 | ret |
383 | ret |
382 | 384 | ||
383 | .wanted_end: |
385 | .wanted_end: |
384 | loop .find_wanted_cycle ; Skip files till we reach wanted one. |
386 | loop .find_wanted_cycle ; Skip files till we reach wanted one. |
385 | 387 | ||
386 | ; First requisite file. |
388 | ; First requisite file. |
387 | .find_wanted_end: |
389 | .find_wanted_end: |
388 | mov ecx, [edi + 20] |
390 | mov ecx, [edi + 20] |
389 | .wanted_start: ; Look for first_wanted + count. |
391 | .wanted_start: ; Look for first_wanted + count. |
390 | jecxz .wanted_end |
392 | jecxz .wanted_end |
391 | 393 | ||
392 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode == 0): not used; |
394 | cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode == 0): not used; |
393 | jz .empty_rec |
395 | jz .empty_rec |
394 | 396 | ||
395 | ; Increment "files in dir" and "read files" count. |
397 | ; Increment "files in dir" and "read files" count. |
396 | inc dword [edi + 8] |
398 | inc dword [edi + 8] |
397 | inc dword [edi + 4] |
399 | inc dword [edi + 4] |
398 | 400 | ||
399 | push edi ecx |
401 | push edi ecx |
400 | mov edi, edx ; Zero out till the name field. |
402 | mov edi, edx ; Zero out till the name field. |
401 | xor eax, eax |
403 | xor eax, eax |
402 | mov ecx, 40 / 4 |
404 | mov ecx, 40 / 4 |
403 | rep stosd |
405 | rep stosd |
404 | pop ecx edi |
406 | pop ecx edi |
405 | 407 | ||
406 | push ebx edi edx |
408 | push ebx edi edx |
407 | mov eax, [ebx + EXT2_DIR_STRUC.inode] ; Get the child inode. |
409 | mov eax, [ebx + EXT2_DIR_STRUC.inode] ; Get the child inode. |
408 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
410 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
409 | call ext2_inode_read |
411 | call ext2_inode_read |
410 | test eax, eax |
412 | test eax, eax |
411 | jnz .error_read_subinode |
413 | jnz .error_read_subinode |
412 | 414 | ||
413 | lea edi, [edx + 8] |
415 | lea edi, [edx + 8] |
414 | 416 | ||
415 | mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; Convert time in NTFS format. |
417 | mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; Convert time in NTFS format. |
416 | xor edx, edx |
418 | xor edx, edx |
417 | add eax, 3054539008 ; (369 * 365 + 89) * 24 * 3600 |
419 | add eax, 3054539008 ; (369 * 365 + 89) * 24 * 3600 |
418 | adc edx, 2 |
420 | adc edx, 2 |
419 | call ntfs_datetime_to_bdfe.sec |
421 | call ntfs_datetime_to_bdfe.sec |
420 | 422 | ||
421 | mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
423 | mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
422 | xor edx, edx |
424 | xor edx, edx |
423 | add eax, 3054539008 |
425 | add eax, 3054539008 |
424 | adc edx, 2 |
426 | adc edx, 2 |
425 | call ntfs_datetime_to_bdfe.sec |
427 | call ntfs_datetime_to_bdfe.sec |
426 | 428 | ||
427 | mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
429 | mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
428 | xor edx, edx |
430 | xor edx, edx |
429 | add eax, 3054539008 |
431 | add eax, 3054539008 |
430 | adc edx, 2 |
432 | adc edx, 2 |
431 | call ntfs_datetime_to_bdfe.sec |
433 | call ntfs_datetime_to_bdfe.sec |
432 | 434 | ||
433 | pop edx |
435 | pop edx |
434 | test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; If folder, don't report size. |
436 | test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; If folder, don't report size. |
435 | jnz @F |
437 | jnz @F |
436 | 438 | ||
437 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] ; Low size |
439 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] ; Low size |
438 | stosd |
440 | stosd |
439 | mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ; High size |
441 | mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ; High size |
440 | stosd |
442 | stosd |
441 | 443 | ||
442 | xor dword [edx], FS_FT_DIR ; Mark as file. |
444 | xor dword [edx], FS_FT_DIR ; Mark as file. |
443 | @@: |
445 | @@: |
444 | xor dword [edx], FS_FT_DIR ; Mark as directory. |
446 | xor dword [edx], FS_FT_DIR ; Mark as directory. |
445 | 447 | ||
446 | ; Copy name after converting from UTF-8 to CP866. |
448 | ; Copy name after converting from UTF-8 to CP866. |
447 | push ecx esi |
449 | push ecx esi |
448 | mov esi, [esp + 12] |
450 | mov esi, [esp + 12] |
449 | movzx ecx, [esi + EXT2_DIR_STRUC.name_len] |
451 | movzx ecx, [esi + EXT2_DIR_STRUC.name_len] |
450 | lea edi, [edx + 40] |
452 | lea edi, [edx + 40] |
451 | lea esi, [esi + EXT2_DIR_STRUC.name] |
453 | lea esi, [esi + EXT2_DIR_STRUC.name] |
452 | call utf8_to_cp866 |
454 | call utf8_to_cp866 |
453 | and byte [edi], 0 |
455 | and byte [edi], 0 |
454 | pop esi ecx edi ebx |
456 | pop esi ecx edi ebx |
455 | 457 | ||
456 | cmp byte [edx + 40], '.' ; If it begins with ".", mark it as hidden. |
458 | cmp byte [edx + 40], '.' ; If it begins with ".", mark it as hidden. |
457 | jne @F |
459 | jne @F |
458 | or dword [edx], FS_FT_HIDDEN |
460 | or dword [edx], FS_FT_HIDDEN |
459 | 461 | ||
460 | @@: |
462 | @@: |
461 | add edx, 40 + 264 ; Go to next record. |
463 | add edx, 40 + 264 ; Go to next record. |
462 | dec ecx |
464 | dec ecx |
463 | .empty_rec: |
465 | .empty_rec: |
464 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
466 | movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
465 | 467 | ||
466 | cmp eax, 12 ; Illegal length. |
468 | cmp eax, 12 ; Illegal length. |
467 | jb .error_bad_len |
469 | jb .error_bad_len |
468 | test eax, 0x3 ; Not a multiple of four. |
470 | test eax, 0x3 ; Not a multiple of four. |
469 | jnz .error_bad_len |
471 | jnz .error_bad_len |
470 | 472 | ||
471 | sub [esi + EXT2_INODE_STRUC.i_size], eax ; Subtract directly from the inode. |
473 | sub [esi + EXT2_INODE_STRUC.i_size], eax ; Subtract directly from the inode. |
472 | add ebx, eax |
474 | add ebx, eax |
473 | cmp ebx, [edi + 24] ; Are we at the end of the block? |
475 | cmp ebx, [edi + 24] ; Are we at the end of the block? |
474 | jb .wanted_start |
476 | jb .wanted_start |
475 | 477 | ||
476 | push .wanted_start |
478 | push .wanted_start |
477 | jmp .end_block |
479 | jmp .end_block |
478 | 480 | ||
479 | .end_dir: ; End of the directory. |
481 | .end_dir: ; End of the directory. |
480 | call ext2_unlock |
482 | call ext2_unlock |
481 | mov edx, [edi + 28] ; Address of where to return data. |
483 | mov edx, [edi + 28] ; Address of where to return data. |
482 | mov ebx, [edi + 8] ; EXT2_read_in_folder |
484 | mov ebx, [edi + 8] ; EXT2_read_in_folder |
483 | mov ecx, [edi + 4] ; EXT2_files_in_folder |
485 | mov ecx, [edi + 4] ; EXT2_files_in_folder |
484 | mov dword [edx], 1 ; Version |
486 | mov dword [edx], 1 ; Version |
485 | mov [edx + 4], ebx |
487 | mov [edx + 4], ebx |
486 | mov [edx + 8], ecx |
488 | mov [edx + 8], ecx |
487 | 489 | ||
488 | lea esp, [edi + 32] |
490 | lea esp, [edi + 32] |
489 | 491 | ||
490 | xor eax, eax ; Reserved in current implementation. |
492 | xor eax, eax ; Reserved in current implementation. |
491 | lea edi, [edx + 12] |
493 | lea edi, [edx + 12] |
492 | mov ecx, 20 / 4 |
494 | mov ecx, 20 / 4 |
493 | rep stosd |
495 | rep stosd |
494 | 496 | ||
495 | ;DEBUGF 1, "Returning with: %x.\n", eax |
497 | ;DEBUGF 1, "Returning with: %x.\n", eax |
496 | ret |
498 | ret |
497 | 499 | ||
498 | .error_bad_len: |
500 | .error_bad_len: |
499 | mov eax, ERROR_FS_FAIL |
501 | mov eax, ERROR_FS_FAIL |
500 | 502 | ||
501 | .error_read_subinode: |
503 | .error_read_subinode: |
502 | .error_get_block: |
504 | .error_get_block: |
503 | ; Fix the stack. |
505 | ; Fix the stack. |
504 | lea esp, [edi + 32] |
506 | lea esp, [edi + 32] |
505 | 507 | ||
506 | .error_ret: |
508 | .error_ret: |
507 | or ebx, -1 |
509 | or ebx, -1 |
508 | push eax |
510 | push eax |
509 | call ext2_unlock |
511 | call ext2_unlock |
510 | pop eax |
512 | pop eax |
511 | ;DEBUGF 1, "Returning with: %x.\n", eax |
513 | ;DEBUGF 1, "Returning with: %x.\n", eax |
512 | ret |
514 | ret |
513 | 515 | ||
514 | .error_empty_dir: ; inode of folder without blocks. |
516 | .error_empty_dir: ; inode of folder without blocks. |
515 | .error_root: ; Root has to be a folder. |
517 | .error_root: ; Root has to be a folder. |
516 | mov eax, ERROR_FS_FAIL |
518 | mov eax, ERROR_FS_FAIL |
517 | jmp .error_ret |
519 | jmp .error_ret |
518 | 520 | ||
519 | .error_not_found: ; Directory not found. |
521 | .error_not_found: ; Directory not found. |
520 | mov eax, ERROR_FILE_NOT_FOUND |
522 | mov eax, ERROR_FILE_NOT_FOUND |
521 | jmp .error_ret |
523 | jmp .error_ret |
522 | 524 | ||
523 | ;--------------------------------------------------------------------- |
525 | ;--------------------------------------------------------------------- |
524 | ; Read file from the hard disk. |
526 | ; Read file from the hard disk. |
525 | ; Input: esi + [esp + 4] = points to file name. |
527 | ; Input: esi + [esp + 4] = points to file name. |
526 | ; ebx = pointer to paramteres from sysfunc 70. |
528 | ; ebx = pointer to paramteres from sysfunc 70. |
527 | ; ebp = pointer to EXTFS structure. |
529 | ; ebp = pointer to EXTFS structure. |
528 | ; Output: ebx = bytes read (0xFFFFFFFF -> file not found) |
530 | ; Output: ebx = bytes read (0xFFFFFFFF -> file not found) |
529 | ; eax = error code (0 implies no error) |
531 | ; eax = error code (0 implies no error) |
530 | ;--------------------------------------------------------------------- |
532 | ;--------------------------------------------------------------------- |
531 | ext2_Read: |
533 | ext2_Read: |
532 | ;DEBUGF 1, "Attempting read.\n" |
534 | ;DEBUGF 1, "Attempting read.\n" |
533 | call ext2_lock |
535 | call ext2_lock |
534 | cmp byte [esi], 0 |
536 | cmp byte [esi], 0 |
535 | jnz @F |
537 | jnz @F |
536 | 538 | ||
537 | .this_is_nofile: |
539 | .this_is_nofile: |
538 | call ext2_unlock |
540 | call ext2_unlock |
539 | or ebx, -1 |
541 | or ebx, -1 |
540 | mov eax, ERROR_ACCESS_DENIED |
542 | mov eax, ERROR_ACCESS_DENIED |
541 | ret |
543 | ret |
542 | 544 | ||
543 | @@: |
545 | @@: |
544 | push ebx |
546 | push ebx |
545 | stdcall ext2_inode_find, [esp + 4 + 4] |
547 | stdcall ext2_inode_find, [esp + 4 + 4] |
546 | pop ebx |
548 | pop ebx |
547 | 549 | ||
548 | mov esi, [ebp + EXTFS.ext2_save_inode] |
550 | mov esi, [ebp + EXTFS.ext2_save_inode] |
549 | test eax, eax |
551 | test eax, eax |
550 | jz @F |
552 | jz @F |
551 | 553 | ||
552 | call ext2_unlock |
554 | call ext2_unlock |
553 | or ebx, -1 |
555 | or ebx, -1 |
554 | mov eax, ERROR_FILE_NOT_FOUND |
556 | mov eax, ERROR_FILE_NOT_FOUND |
555 | ret |
557 | ret |
556 | 558 | ||
557 | @@: |
559 | @@: |
558 | mov ax, [esi + EXT2_INODE_STRUC.i_mode] |
560 | mov ax, [esi + EXT2_INODE_STRUC.i_mode] |
559 | and ax, EXT2_S_IFMT ; Leave the file format in AX. |
561 | and ax, EXT2_S_IFMT ; Leave the file format in AX. |
560 | 562 | ||
561 | ; Check if file. |
563 | ; Check if file. |
562 | cmp ax, EXT2_S_IFREG |
564 | cmp ax, EXT2_S_IFREG |
563 | jne .this_is_nofile |
565 | jne .this_is_nofile |
564 | 566 | ||
565 | mov edi, [ebx + 16] |
567 | mov edi, [ebx + 16] |
566 | mov ecx, [ebx + 12] |
568 | mov ecx, [ebx + 12] |
567 | 569 | ||
568 | mov eax, [ebx + 4] |
570 | mov eax, [ebx + 4] |
569 | mov edx, [ebx + 8] ; edx:eax = start byte number. |
571 | mov edx, [ebx + 8] ; edx:eax = start byte number. |
570 | 572 | ||
571 | ; Check if file is big enough for us. |
573 | ; Check if file is big enough for us. |
572 | cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx |
574 | cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx |
573 | ja .size_greater |
575 | ja .size_greater |
574 | jb .size_less |
576 | jb .size_less |
575 | 577 | ||
576 | cmp [esi + EXT2_INODE_STRUC.i_size], eax |
578 | cmp [esi + EXT2_INODE_STRUC.i_size], eax |
577 | ja .size_greater |
579 | ja .size_greater |
578 | 580 | ||
579 | .size_less: |
581 | .size_less: |
580 | call ext2_unlock |
582 | call ext2_unlock |
581 | xor ebx, ebx |
583 | xor ebx, ebx |
582 | mov eax, ERROR_END_OF_FILE |
584 | mov eax, ERROR_END_OF_FILE |
583 | ret |
585 | ret |
584 | 586 | ||
585 | @@: |
587 | @@: |
586 | .size_greater: |
588 | .size_greater: |
587 | add eax, ecx ; Get last byte. |
589 | add eax, ecx ; Get last byte. |
588 | adc edx, 0 |
590 | adc edx, 0 |
589 | 591 | ||
590 | ; Check if we've to read whole file, or till requested. |
592 | ; Check if we've to read whole file, or till requested. |
591 | cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx |
593 | cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx |
592 | ja .read_till_requested |
594 | ja .read_till_requested |
593 | jb .read_whole_file |
595 | jb .read_whole_file |
594 | cmp [esi + EXT2_INODE_STRUC.i_size], eax |
596 | cmp [esi + EXT2_INODE_STRUC.i_size], eax |
595 | jae .read_till_requested |
597 | jae .read_till_requested |
596 | 598 | ||
597 | .read_whole_file: |
599 | .read_whole_file: |
598 | push 1 ; Read till the end of file. |
600 | push 1 ; Read till the end of file. |
599 | mov ecx, [esi + EXT2_INODE_STRUC.i_size] |
601 | mov ecx, [esi + EXT2_INODE_STRUC.i_size] |
600 | sub ecx, [ebx + 4] ; To read = (size - starting byte) |
602 | sub ecx, [ebx + 4] ; To read = (size - starting byte) |
601 | jmp @F |
603 | jmp @F |
602 | 604 | ||
603 | .read_till_requested: |
605 | .read_till_requested: |
604 | push 0 ; Read as much as requested. |
606 | push 0 ; Read as much as requested. |
605 | 607 | ||
606 | @@: |
608 | @@: |
607 | ; ecx = bytes to read. |
609 | ; ecx = bytes to read. |
608 | ; edi = return memory |
610 | ; edi = return memory |
609 | ; [esi] = starting byte. |
611 | ; [esi] = starting byte. |
610 | 612 | ||
611 | push ecx ; Number of bytes to read. |
613 | push ecx ; Number of bytes to read. |
612 | 614 | ||
613 | ; Get part of the first block. |
615 | ; Get part of the first block. |
614 | mov edx, [ebx + 8] |
616 | mov edx, [ebx + 8] |
615 | mov eax, [ebx + 4] |
617 | mov eax, [ebx + 4] |
616 | div [ebp + EXTFS.block_size] |
618 | div [ebp + EXTFS.block_size] |
617 | 619 | ||
618 | push eax ; Save block counter to stack. |
620 | push eax ; Save block counter to stack. |
619 | 621 | ||
620 | push ecx |
622 | push ecx |
621 | mov ecx, eax |
623 | mov ecx, eax |
622 | call ext2_inode_get_block |
624 | call ext2_inode_get_block |
623 | test eax, eax |
625 | test eax, eax |
624 | jnz .error_at_first_block |
626 | jnz .error_at_first_block |
625 | 627 | ||
626 | mov ebx, [ebp + EXTFS.ext2_save_block] |
628 | mov ebx, [ebp + EXTFS.ext2_save_block] |
627 | mov eax, ecx |
629 | mov eax, ecx |
628 | call ext2_block_read |
630 | call ext2_block_read |
629 | test eax, eax |
631 | test eax, eax |
630 | jnz .error_at_first_block |
632 | jnz .error_at_first_block |
631 | 633 | ||
632 | pop ecx |
634 | pop ecx |
633 | ; Get index inside block. |
635 | ; Get index inside block. |
634 | add ebx, edx |
636 | add ebx, edx |
635 | 637 | ||
636 | neg edx |
638 | neg edx |
637 | add edx, [ebp + EXTFS.block_size] ; Get number of bytes in this block. |
639 | add edx, [ebp + EXTFS.block_size] ; Get number of bytes in this block. |
638 | 640 | ||
639 | ; If it's smaller than total bytes to read, then only one block. |
641 | ; If it's smaller than total bytes to read, then only one block. |
640 | cmp ecx, edx |
642 | cmp ecx, edx |
641 | jbe .only_one_block |
643 | jbe .only_one_block |
642 | 644 | ||
643 | mov eax, ecx |
645 | mov eax, ecx |
644 | sub eax, edx |
646 | sub eax, edx |
645 | mov ecx, edx |
647 | mov ecx, edx |
646 | 648 | ||
647 | push esi |
649 | push esi |
648 | mov esi, ebx |
650 | mov esi, ebx |
649 | rep movsb ; Copy part of 1st block. |
651 | rep movsb ; Copy part of 1st block. |
650 | pop esi |
652 | pop esi |
651 | 653 | ||
652 | ; eax -> bytes to read. |
654 | ; eax -> bytes to read. |
653 | .calc_blocks_count: |
655 | .calc_blocks_count: |
654 | mov ebx, edi ; Read the block in ebx. |
656 | mov ebx, edi ; Read the block in ebx. |
655 | xor edx, edx |
657 | xor edx, edx |
656 | div [ebp + EXTFS.block_size] ; Get number of bytes in last block in edx. |
658 | div [ebp + EXTFS.block_size] ; Get number of bytes in last block in edx. |
657 | mov edi, eax ; Get number of blocks in edi. |
659 | mov edi, eax ; Get number of blocks in edi. |
658 | 660 | ||
659 | @@: |
661 | @@: |
660 | ; Test if all blocks are done. |
662 | ; Test if all blocks are done. |
661 | test edi, edi |
663 | test edi, edi |
662 | jz .finish_block |
664 | jz .finish_block |
663 | 665 | ||
664 | inc dword [esp] |
666 | inc dword [esp] |
665 | mov ecx, [esp] |
667 | mov ecx, [esp] |
666 | call ext2_inode_get_block |
668 | call ext2_inode_get_block |
667 | 669 | ||
668 | test eax, eax |
670 | test eax, eax |
669 | jnz .error_at_read_cycle |
671 | jnz .error_at_read_cycle |
670 | 672 | ||
671 | mov eax, ecx ; ebx already contains desired values. |
673 | mov eax, ecx ; ebx already contains desired values. |
672 | call ext2_block_read |
674 | call ext2_block_read |
673 | 675 | ||
674 | test eax, eax |
676 | test eax, eax |
675 | jnz .error_at_read_cycle |
677 | jnz .error_at_read_cycle |
676 | 678 | ||
677 | add ebx, [ebp + EXTFS.block_size] |
679 | add ebx, [ebp + EXTFS.block_size] |
678 | 680 | ||
679 | dec edi |
681 | dec edi |
680 | jmp @B |
682 | jmp @B |
681 | 683 | ||
682 | ; In edx -- number of bytes in the last block. |
684 | ; In edx -- number of bytes in the last block. |
683 | .finish_block: |
685 | .finish_block: |
684 | test edx, edx |
686 | test edx, edx |
685 | jz .end_read |
687 | jz .end_read |
686 | 688 | ||
687 | pop ecx ; Pop block counter in ECX. |
689 | pop ecx ; Pop block counter in ECX. |
688 | inc ecx |
690 | inc ecx |
689 | call ext2_inode_get_block |
691 | call ext2_inode_get_block |
690 | 692 | ||
691 | test eax, eax |
693 | test eax, eax |
692 | jnz .error_at_finish_block |
694 | jnz .error_at_finish_block |
693 | 695 | ||
694 | mov edi, ebx |
696 | mov edi, ebx |
695 | mov eax, ecx |
697 | mov eax, ecx |
696 | mov ebx, [ebp + EXTFS.ext2_save_block] |
698 | mov ebx, [ebp + EXTFS.ext2_save_block] |
697 | call ext2_block_read |
699 | call ext2_block_read |
698 | 700 | ||
699 | test eax, eax |
701 | test eax, eax |
700 | jnz .error_at_finish_block |
702 | jnz .error_at_finish_block |
701 | 703 | ||
702 | mov ecx, edx |
704 | mov ecx, edx |
703 | mov esi, ebx |
705 | mov esi, ebx |
704 | rep movsb ; Copy last piece of block. |
706 | rep movsb ; Copy last piece of block. |
705 | jmp @F |
707 | jmp @F |
706 | 708 | ||
707 | .end_read: |
709 | .end_read: |
708 | pop ecx ; Pop block counter in ECX. |
710 | pop ecx ; Pop block counter in ECX. |
709 | @@: |
711 | @@: |
710 | pop ebx ; Number of bytes read. |
712 | pop ebx ; Number of bytes read. |
711 | call ext2_unlock |
713 | call ext2_unlock |
712 | pop eax ; If we were asked to read more, say EOF. |
714 | pop eax ; If we were asked to read more, say EOF. |
713 | test eax, eax |
715 | test eax, eax |
714 | jz @F |
716 | jz @F |
715 | 717 | ||
716 | mov eax, ERROR_END_OF_FILE |
718 | mov eax, ERROR_END_OF_FILE |
717 | ret |
719 | ret |
718 | @@: |
720 | @@: |
719 | xor eax, eax |
721 | xor eax, eax |
720 | ;DEBUGF 1, "Returning with: %x.\n", eax |
722 | ;DEBUGF 1, "Returning with: %x.\n", eax |
721 | ret |
723 | ret |
722 | 724 | ||
723 | .only_one_block: |
725 | .only_one_block: |
724 | mov esi, ebx |
726 | mov esi, ebx |
725 | rep movsb ; Copy last piece of block. |
727 | rep movsb ; Copy last piece of block. |
726 | jmp .end_read |
728 | jmp .end_read |
727 | 729 | ||
728 | .error_at_first_block: |
730 | .error_at_first_block: |
729 | pop edx |
731 | pop edx |
730 | .error_at_read_cycle: |
732 | .error_at_read_cycle: |
731 | pop ebx |
733 | pop ebx |
732 | .error_at_finish_block: |
734 | .error_at_finish_block: |
733 | pop ecx edx |
735 | pop ecx edx |
734 | or ebx, -1 |
736 | or ebx, -1 |
735 | push eax |
737 | push eax |
736 | call ext2_unlock |
738 | call ext2_unlock |
737 | pop eax |
739 | pop eax |
738 | 740 | ||
739 | ;DEBUGF 1, "Returning with: %x.\n", eax |
741 | ;DEBUGF 1, "Returning with: %x.\n", eax |
740 | ret |
742 | ret |
741 | 743 | ||
742 | ;--------------------------------------------------------------------- |
744 | ;--------------------------------------------------------------------- |
743 | ; Read file information from block device. |
745 | ; Read file information from block device. |
744 | ; Input: esi + [esp + 4] = file name. |
746 | ; Input: esi + [esp + 4] = file name. |
745 | ; ebx = pointer to paramteres from sysfunc 70. |
747 | ; ebx = pointer to paramteres from sysfunc 70. |
746 | ; ebp = pointer to EXTFS structure. |
748 | ; ebp = pointer to EXTFS structure. |
747 | ; Output: eax = error code. |
749 | ; Output: eax = error code. |
748 | ;--------------------------------------------------------------------- |
750 | ;--------------------------------------------------------------------- |
749 | ext2_GetFileInfo: |
751 | ext2_GetFileInfo: |
750 | ;DEBUGF 1, "Calling for file info, for: %s.\n", esi |
752 | ;DEBUGF 1, "Calling for file info, for: %s.\n", esi |
751 | call ext2_lock |
753 | call ext2_lock |
752 | mov edx, [ebx + 16] |
754 | mov edx, [ebx + 16] |
753 | cmp byte [esi], 0 |
755 | cmp byte [esi], 0 |
754 | jz .is_root |
756 | jz .is_root |
755 | 757 | ||
756 | push edx |
758 | push edx |
757 | stdcall ext2_inode_find, [esp + 4 + 4] |
759 | stdcall ext2_inode_find, [esp + 4 + 4] |
758 | mov ebx, edx |
760 | mov ebx, edx |
759 | pop edx |
761 | pop edx |
760 | 762 | ||
761 | mov esi, [ebp + EXTFS.ext2_save_inode] |
763 | mov esi, [ebp + EXTFS.ext2_save_inode] |
762 | test eax, eax |
764 | test eax, eax |
763 | jz @F |
765 | jz @F |
764 | 766 | ||
765 | push eax |
767 | push eax |
766 | call ext2_unlock |
768 | call ext2_unlock |
767 | pop eax |
769 | pop eax |
768 | ;DEBUGF 1, "Returning with: %x.\n", eax |
770 | ;DEBUGF 1, "Returning with: %x.\n", eax |
769 | ret |
771 | ret |
770 | 772 | ||
771 | .is_root: |
773 | .is_root: |
772 | xor ebx, ebx ; Clear out first char, since we don't want to set hidden flag on root. |
774 | xor ebx, ebx ; Clear out first char, since we don't want to set hidden flag on root. |
773 | mov esi, [ebp + EXTFS.root_inode] |
775 | mov esi, [ebp + EXTFS.root_inode] |
774 | 776 | ||
775 | @@: |
777 | @@: |
776 | xor eax, eax |
778 | xor eax, eax |
777 | mov edi, edx |
779 | mov edi, edx |
778 | mov ecx, 40/4 |
780 | mov ecx, 40/4 |
779 | rep stosd ; Zero fill buffer. |
781 | rep stosd ; Zero fill buffer. |
780 | 782 | ||
781 | cmp bl, '.' |
783 | cmp bl, '.' |
782 | jne @F |
784 | jne @F |
783 | or dword [edx], FS_FT_HIDDEN |
785 | or dword [edx], FS_FT_HIDDEN |
784 | 786 | ||
785 | @@: |
787 | @@: |
786 | test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
788 | test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
787 | jnz @F ; If a directory, don't put in file size. |
789 | jnz @F ; If a directory, don't put in file size. |
788 | 790 | ||
789 | mov eax, [esi + EXT2_INODE_STRUC.i_size] ; Low file size. |
791 | mov eax, [esi + EXT2_INODE_STRUC.i_size] ; Low file size. |
790 | mov ebx, [esi + EXT2_INODE_STRUC.i_dir_acl] ; High file size. |
792 | mov ebx, [esi + EXT2_INODE_STRUC.i_dir_acl] ; High file size. |
791 | mov dword [edx+32], eax |
793 | mov dword [edx+32], eax |
792 | mov dword [edx+36], ebx |
794 | mov dword [edx+36], ebx |
793 | 795 | ||
794 | xor dword [edx], FS_FT_DIR ; Next XOR will clean this, to mark it as a file. |
796 | xor dword [edx], FS_FT_DIR ; Next XOR will clean this, to mark it as a file. |
795 | @@: |
797 | @@: |
796 | xor dword [edx], FS_FT_DIR ; Mark as directory. |
798 | xor dword [edx], FS_FT_DIR ; Mark as directory. |
797 | 799 | ||
798 | lea edi, [edx + 8] |
800 | lea edi, [edx + 8] |
799 | 801 | ||
800 | ; Store all time. |
802 | ; Store all time. |
801 | mov eax, [esi + EXT2_INODE_STRUC.i_ctime] |
803 | mov eax, [esi + EXT2_INODE_STRUC.i_ctime] |
802 | xor edx, edx |
804 | xor edx, edx |
803 | add eax, 3054539008 |
805 | add eax, 3054539008 |
804 | adc edx, 2 |
806 | adc edx, 2 |
805 | call ntfs_datetime_to_bdfe.sec |
807 | call ntfs_datetime_to_bdfe.sec |
806 | 808 | ||
807 | mov eax, [esi + EXT2_INODE_STRUC.i_atime] |
809 | mov eax, [esi + EXT2_INODE_STRUC.i_atime] |
808 | xor edx, edx |
810 | xor edx, edx |
809 | add eax, 3054539008 |
811 | add eax, 3054539008 |
810 | adc edx, 2 |
812 | adc edx, 2 |
811 | call ntfs_datetime_to_bdfe.sec |
813 | call ntfs_datetime_to_bdfe.sec |
812 | 814 | ||
813 | mov eax, [esi + EXT2_INODE_STRUC.i_mtime] |
815 | mov eax, [esi + EXT2_INODE_STRUC.i_mtime] |
814 | xor edx, edx |
816 | xor edx, edx |
815 | add eax, 3054539008 |
817 | add eax, 3054539008 |
816 | adc edx, 2 |
818 | adc edx, 2 |
817 | call ntfs_datetime_to_bdfe.sec |
819 | call ntfs_datetime_to_bdfe.sec |
818 | 820 | ||
819 | call ext2_unlock |
821 | call ext2_unlock |
820 | xor eax, eax |
822 | xor eax, eax |
821 | ;DEBUGF 1, "Returning with: %x.\n", eax |
823 | ;DEBUGF 1, "Returning with: %x.\n", eax |
822 | ret |
824 | ret |
823 | 825 | ||
824 | ;--------------------------------------------------------------------- |
826 | ;--------------------------------------------------------------------- |
825 | ; Set file information for block device. |
827 | ; Set file information for block device. |
826 | ; Input: esi + [esp + 4] = file name. |
828 | ; Input: esi + [esp + 4] = file name. |
827 | ; ebx = pointer to paramteres from sysfunc 70. |
829 | ; ebx = pointer to paramteres from sysfunc 70. |
828 | ; ebp = pointer to EXTFS structure. |
830 | ; ebp = pointer to EXTFS structure. |
829 | ; Output: eax = error code. |
831 | ; Output: eax = error code. |
830 | ;--------------------------------------------------------------------- |
832 | ;--------------------------------------------------------------------- |
831 | ext2_SetFileInfo: |
833 | ext2_SetFileInfo: |
832 | test [ebp + EXTFS.partition_flags], EXT2_RO |
834 | test [ebp + EXTFS.partition_flags], EXT2_RO |
833 | jz @F |
835 | jz @F |
834 | 836 | ||
835 | mov eax, ERROR_UNSUPPORTED_FS |
837 | mov eax, ERROR_UNSUPPORTED_FS |
836 | ret |
838 | ret |
837 | 839 | ||
838 | @@: |
840 | @@: |
839 | push edx esi edi ebx |
841 | push edx esi edi ebx |
840 | call ext2_lock |
842 | call ext2_lock |
841 | mov edx, [ebx + 16] |
843 | mov edx, [ebx + 16] |
842 | 844 | ||
843 | ; Is this read-only? |
845 | ; Is this read-only? |
844 | test [ebp + EXTFS.partition_flags], EXT2_RO |
846 | test [ebp + EXTFS.partition_flags], EXT2_RO |
845 | jnz .fail |
847 | jnz .fail |
846 | 848 | ||
847 | ; Not supported for root. |
849 | ; Not supported for root. |
848 | cmp byte [esi], 0 |
850 | cmp byte [esi], 0 |
849 | je .fail |
851 | je .fail |
850 | 852 | ||
851 | .get_inode: |
853 | .get_inode: |
852 | push edx |
854 | push edx |
853 | stdcall ext2_inode_find, [esp + 4 + 20] |
855 | stdcall ext2_inode_find, [esp + 4 + 20] |
854 | pop edx |
856 | pop edx |
855 | 857 | ||
856 | test eax, eax |
858 | test eax, eax |
857 | jnz @F |
859 | jnz @F |
858 | 860 | ||
859 | ; Save inode number. |
861 | ; Save inode number. |
860 | push esi |
862 | push esi |
861 | mov esi, [ebp + EXTFS.ext2_save_inode] |
863 | mov esi, [ebp + EXTFS.ext2_save_inode] |
862 | 864 | ||
863 | ; From the BDFE, we ignore read-only file flags, hidden file flags; |
865 | ; From the BDFE, we ignore read-only file flags, hidden file flags; |
864 | ; We ignore system file flags, file was archived or not. |
866 | ; We ignore system file flags, file was archived or not. |
865 | 867 | ||
866 | ; Also ignored is file creation time. ext2 stores "inode modification" |
868 | ; Also ignored is file creation time. ext2 stores "inode modification" |
867 | ; time in the ctime field, which is updated by the respective inode_write |
869 | ; time in the ctime field, which is updated by the respective inode_write |
868 | ; procedure, and any writes on it would be overwritten anyway. |
870 | ; procedure, and any writes on it would be overwritten anyway. |
869 | 871 | ||
870 | ; Access time. |
872 | ; Access time. |
871 | lea edi, [esi + EXT2_INODE_STRUC.i_atime] |
873 | lea edi, [esi + EXT2_INODE_STRUC.i_atime] |
872 | lea esi, [edx + 16] |
874 | lea esi, [edx + 16] |
873 | call bdfe_to_unix_time |
875 | call bdfe_to_unix_time |
874 | 876 | ||
875 | ; Modification time. |
877 | ; Modification time. |
876 | add esi, 8 |
878 | add esi, 8 |
877 | add edi, 8 |
879 | add edi, 8 |
878 | call bdfe_to_unix_time |
880 | call bdfe_to_unix_time |
879 | 881 | ||
880 | mov ebx, [ebp + EXTFS.ext2_save_inode] ; Get address of inode into ebx. |
882 | mov ebx, [ebp + EXTFS.ext2_save_inode] ; Get address of inode into ebx. |
881 | pop eax ; Get inode number in eax. |
883 | pop eax ; Get inode number in eax. |
882 | call ext2_inode_write ; eax contains error code, if any. |
884 | call ext2_inode_write ; eax contains error code, if any. |
883 | test eax, eax |
885 | test eax, eax |
884 | jnz @F |
886 | jnz @F |
885 | 887 | ||
886 | call ext2_sb_update |
888 | call ext2_sb_update |
887 | ; Sync the disk. |
889 | ; Sync the disk. |
888 | mov esi, [ebp + PARTITION.Disk] |
890 | mov esi, [ebp + PARTITION.Disk] |
889 | call disk_sync ; eax contains error code, if any. |
891 | call disk_sync ; eax contains error code, if any. |
890 | 892 | ||
891 | @@: |
893 | @@: |
892 | push eax |
894 | push eax |
893 | call ext2_unlock |
895 | call ext2_unlock |
894 | pop eax |
896 | pop eax |
895 | 897 | ||
896 | pop ebx edi esi edx |
898 | pop ebx edi esi edx |
897 | ret |
899 | ret |
898 | 900 | ||
899 | .fail: |
901 | .fail: |
900 | call ext2_sb_update |
902 | call ext2_sb_update |
901 | ; Sync the disk. |
903 | ; Sync the disk. |
902 | mov esi, [ebp + PARTITION.Disk] |
904 | mov esi, [ebp + PARTITION.Disk] |
903 | call disk_sync ; eax contains error code, if any. |
905 | call disk_sync ; eax contains error code, if any. |
904 | 906 | ||
905 | mov eax, ERROR_UNSUPPORTED_FS |
907 | mov eax, ERROR_UNSUPPORTED_FS |
906 | jmp @B |
908 | jmp @B |
907 | 909 | ||
908 | ;--------------------------------------------------------------------- |
910 | ;--------------------------------------------------------------------- |
909 | ; Set file information for block device. |
911 | ; Set file information for block device. |
910 | ; Input: esi + [esp + 4] = file name. |
912 | ; Input: esi + [esp + 4] = file name. |
911 | ; ebx = pointer to paramteres from sysfunc 70. |
913 | ; ebx = pointer to paramteres from sysfunc 70. |
912 | ; ebp = pointer to EXTFS structure. |
914 | ; ebp = pointer to EXTFS structure. |
913 | ; Output: eax = error code. |
915 | ; Output: eax = error code. |
914 | ;--------------------------------------------------------------------- |
916 | ;--------------------------------------------------------------------- |
915 | ext2_Delete: |
917 | ext2_Delete: |
916 | ;DEBUGF 1, "Attempting Delete.\n" |
918 | ;DEBUGF 1, "Attempting Delete.\n" |
917 | test [ebp + EXTFS.partition_flags], EXT2_RO |
919 | test [ebp + EXTFS.partition_flags], EXT2_RO |
918 | jz @F |
920 | jz @F |
919 | 921 | ||
920 | mov eax, ERROR_UNSUPPORTED_FS |
922 | mov eax, ERROR_UNSUPPORTED_FS |
921 | ret |
923 | ret |
922 | 924 | ||
923 | @@: |
925 | @@: |
924 | push ebx ecx edx esi edi |
926 | push ebx ecx edx esi edi |
925 | call ext2_lock |
927 | call ext2_lock |
926 | 928 | ||
927 | add esi, [esp + 20 + 4] |
929 | add esi, [esp + 20 + 4] |
928 | 930 | ||
929 | ; Can't delete root. |
931 | ; Can't delete root. |
930 | cmp byte [esi], 0 |
932 | cmp byte [esi], 0 |
931 | jz .error_access_denied |
933 | jz .error_access_denied |
932 | 934 | ||
933 | push esi |
935 | push esi |
934 | stdcall ext2_inode_find, 0 |
936 | stdcall ext2_inode_find, 0 |
935 | mov ebx, esi |
937 | mov ebx, esi |
936 | pop esi |
938 | pop esi |
937 | 939 | ||
938 | test eax, eax |
940 | test eax, eax |
939 | jnz .error_access_denied |
941 | jnz .error_access_denied |
940 | 942 | ||
941 | mov edx, [ebp + EXTFS.ext2_save_inode] |
943 | mov edx, [ebp + EXTFS.ext2_save_inode] |
942 | movzx edx, [edx + EXT2_INODE_STRUC.i_mode] |
944 | movzx edx, [edx + EXT2_INODE_STRUC.i_mode] |
943 | and edx, EXT2_S_IFMT ; Get the mask. |
945 | and edx, EXT2_S_IFMT ; Get the mask. |
944 | cmp edx, EXT2_S_IFDIR |
946 | cmp edx, EXT2_S_IFDIR |
945 | jne @F ; If not a directory, we don't need to check if it's empty. |
947 | jne @F ; If not a directory, we don't need to check if it's empty. |
946 | 948 | ||
947 | call ext2_dir_empty ; 0 means directory is empty. |
949 | call ext2_dir_empty ; 0 means directory is empty. |
948 | 950 | ||
949 | test eax, eax |
951 | test eax, eax |
950 | jnz .error_access_denied |
952 | jnz .error_access_denied |
951 | 953 | ||
952 | @@: |
954 | @@: |
953 | ; Find parent. |
955 | ; Find parent. |
954 | call ext2_inode_find_parent |
956 | call ext2_inode_find_parent |
955 | test eax, eax |
957 | test eax, eax |
956 | jnz .error_access_denied |
958 | jnz .error_access_denied |
957 | mov eax, esi |
959 | mov eax, esi |
958 | 960 | ||
959 | ; Save file/dir & parent inode. |
961 | ; Save file/dir & parent inode. |
960 | push ebx eax |
962 | push ebx eax |
961 | 963 | ||
962 | cmp edx, EXT2_S_IFDIR |
964 | cmp edx, EXT2_S_IFDIR |
963 | jne @F |
965 | jne @F |
964 | 966 | ||
965 | ; Unlink '.' |
967 | ; Unlink '.' |
966 | mov eax, [esp + 4] |
968 | mov eax, [esp + 4] |
967 | call ext2_inode_unlink |
969 | call ext2_inode_unlink |
968 | cmp eax, 0xFFFFFFFF |
970 | cmp eax, 0xFFFFFFFF |
969 | je .error_stack8 |
971 | je .error_stack8 |
970 | 972 | ||
971 | ; Unlink '..' |
973 | ; Unlink '..' |
972 | mov eax, [esp + 4] |
974 | mov eax, [esp + 4] |
973 | mov ebx, [esp] |
975 | mov ebx, [esp] |
974 | call ext2_inode_unlink |
976 | call ext2_inode_unlink |
975 | cmp eax, 0xFFFFFFFF |
977 | cmp eax, 0xFFFFFFFF |
976 | je .error_stack8 |
978 | je .error_stack8 |
977 | 979 | ||
978 | @@: |
980 | @@: |
979 | pop eax |
981 | pop eax |
980 | mov ebx, [esp] |
982 | mov ebx, [esp] |
981 | ; Unlink the inode. |
983 | ; Unlink the inode. |
982 | call ext2_inode_unlink |
984 | call ext2_inode_unlink |
983 | cmp eax, 0xFFFFFFFF |
985 | cmp eax, 0xFFFFFFFF |
984 | je .error_stack4 |
986 | je .error_stack4 |
985 | 987 | ||
986 | ; If hardlinks aren't zero, shouldn't completely free. |
988 | ; If hardlinks aren't zero, shouldn't completely free. |
987 | test eax, eax |
989 | test eax, eax |
988 | jz @F |
990 | jz @F |
989 | 991 | ||
990 | add esp, 4 |
992 | add esp, 4 |
991 | jmp .disk_sync |
993 | jmp .disk_sync |
992 | 994 | ||
993 | @@: |
995 | @@: |
994 | ; Read the inode. |
996 | ; Read the inode. |
995 | mov eax, [esp] |
997 | mov eax, [esp] |
996 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
998 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
997 | call ext2_inode_read |
999 | call ext2_inode_read |
998 | test eax, eax |
1000 | test eax, eax |
999 | jnz .error_stack4 |
1001 | jnz .error_stack4 |
1000 | 1002 | ||
1001 | ; Free inode data. |
1003 | ; Free inode data. |
1002 | mov esi, [ebp + EXTFS.ext2_save_inode] |
1004 | mov esi, [ebp + EXTFS.ext2_save_inode] |
1003 | xor ecx, ecx |
1005 | xor ecx, ecx |
1004 | 1006 | ||
1005 | @@: |
1007 | @@: |
1006 | push ecx |
1008 | push ecx |
1007 | call ext2_inode_get_block |
1009 | call ext2_inode_get_block |
1008 | test eax, eax |
1010 | test eax, eax |
1009 | jnz .error_stack8 |
1011 | jnz .error_stack8 |
1010 | mov eax, ecx |
1012 | mov eax, ecx |
1011 | pop ecx |
1013 | pop ecx |
1012 | 1014 | ||
1013 | ; If 0, we're done. |
1015 | ; If 0, we're done. |
1014 | test eax, eax |
1016 | test eax, eax |
1015 | jz @F |
1017 | jz @F |
1016 | 1018 | ||
1017 | call ext2_block_free |
1019 | call ext2_block_free |
1018 | test eax, eax |
1020 | test eax, eax |
1019 | jnz .error_stack4 |
1021 | jnz .error_stack4 |
1020 | 1022 | ||
1021 | inc ecx |
1023 | inc ecx |
1022 | jmp @B |
1024 | jmp @B |
1023 | 1025 | ||
1024 | @@: |
1026 | @@: |
1025 | ; Free indirect blocks. |
1027 | ; Free indirect blocks. |
1026 | call ext2_inode_free_indirect_blocks |
1028 | call ext2_inode_free_indirect_blocks |
1027 | test eax, eax |
1029 | test eax, eax |
1028 | jnz .error_stack4 |
1030 | jnz .error_stack4 |
1029 | 1031 | ||
1030 | ; Clear the inode, and add deletion time. |
1032 | ; Clear the inode, and add deletion time. |
1031 | mov edi, [ebp + EXTFS.ext2_save_inode] |
1033 | mov edi, [ebp + EXTFS.ext2_save_inode] |
1032 | xor eax, eax |
1034 | xor eax, eax |
1033 | mov ecx, [ebp + EXTFS.inode_size] |
1035 | mov ecx, [ebp + EXTFS.inode_size] |
1034 | rep stosb |
1036 | rep stosb |
1035 | 1037 | ||
1036 | mov edi, [ebp + EXTFS.ext2_save_inode] |
1038 | mov edi, [ebp + EXTFS.ext2_save_inode] |
1037 | add edi, EXT2_INODE_STRUC.i_dtime |
1039 | add edi, EXT2_INODE_STRUC.i_dtime |
1038 | call current_unix_time |
1040 | call current_unix_time |
1039 | 1041 | ||
1040 | ; Write the inode. |
1042 | ; Write the inode. |
1041 | mov eax, [esp] |
1043 | mov eax, [esp] |
1042 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
1044 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
1043 | call ext2_inode_write |
1045 | call ext2_inode_write |
1044 | test eax, eax |
1046 | test eax, eax |
1045 | jnz .error_stack4 |
1047 | jnz .error_stack4 |
1046 | 1048 | ||
1047 | ; Check if directory. |
1049 | ; Check if directory. |
1048 | cmp edx, EXT2_S_IFDIR |
1050 | cmp edx, EXT2_S_IFDIR |
1049 | jne @F |
1051 | jne @F |
1050 | 1052 | ||
1051 | ; If it is, decrement used_dirs_count. |
1053 | ; If it is, decrement used_dirs_count. |
1052 | 1054 | ||
1053 | ; Get block group. |
1055 | ; Get block group. |
1054 | mov eax, [esp] |
1056 | mov eax, [esp] |
1055 | dec eax |
1057 | dec eax |
1056 | xor edx, edx |
1058 | xor edx, edx |
1057 | div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
1059 | div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
1058 | 1060 | ||
1059 | push eax |
1061 | push eax |
1060 | call ext2_bg_read_desc |
1062 | call ext2_bg_read_desc |
1061 | test eax, eax |
1063 | test eax, eax |
1062 | jz .error_stack8 |
1064 | jz .error_stack8 |
1063 | 1065 | ||
1064 | dec [eax + EXT2_BLOCK_GROUP_DESC.used_dirs_count] |
1066 | dec [eax + EXT2_BLOCK_GROUP_DESC.used_dirs_count] |
1065 | 1067 | ||
1066 | pop eax |
1068 | pop eax |
1067 | call ext2_bg_write_desc |
1069 | call ext2_bg_write_desc |
1068 | 1070 | ||
1069 | @@: |
1071 | @@: |
1070 | pop eax |
1072 | pop eax |
1071 | call ext2_inode_free |
1073 | call ext2_inode_free |
1072 | test eax, eax |
1074 | test eax, eax |
1073 | jnz .error_access_denied |
1075 | jnz .error_access_denied |
1074 | 1076 | ||
1075 | .disk_sync: |
1077 | .disk_sync: |
1076 | call ext2_sb_update |
1078 | call ext2_sb_update |
1077 | 1079 | ||
1078 | ; Sync the disk. |
1080 | ; Sync the disk. |
1079 | mov esi, [ebp + PARTITION.Disk] |
1081 | mov esi, [ebp + PARTITION.Disk] |
1080 | call disk_sync ; eax contains error code, if any. |
1082 | call disk_sync ; eax contains error code, if any. |
1081 | 1083 | ||
1082 | .return: |
1084 | .return: |
1083 | push eax |
1085 | push eax |
1084 | call ext2_unlock |
1086 | call ext2_unlock |
1085 | pop eax |
1087 | pop eax |
1086 | 1088 | ||
1087 | pop edi esi edx ecx ebx |
1089 | pop edi esi edx ecx ebx |
1088 | ;DEBUGF 1, "And returning with: %x.\n", eax |
1090 | ;DEBUGF 1, "And returning with: %x.\n", eax |
1089 | ret |
1091 | ret |
1090 | 1092 | ||
1091 | .error_stack8: |
1093 | .error_stack8: |
1092 | add esp, 4 |
1094 | add esp, 4 |
1093 | .error_stack4: |
1095 | .error_stack4: |
1094 | add esp, 4 |
1096 | add esp, 4 |
1095 | .error_access_denied: |
1097 | .error_access_denied: |
1096 | call ext2_sb_update |
1098 | call ext2_sb_update |
1097 | 1099 | ||
1098 | ; Sync the disk. |
1100 | ; Sync the disk. |
1099 | mov esi, [ebp + PARTITION.Disk] |
1101 | mov esi, [ebp + PARTITION.Disk] |
1100 | call disk_sync ; eax contains error code, if any. |
1102 | call disk_sync ; eax contains error code, if any. |
1101 | 1103 | ||
1102 | mov eax, ERROR_ACCESS_DENIED |
1104 | mov eax, ERROR_ACCESS_DENIED |
1103 | jmp .return |
1105 | jmp .return |
1104 | 1106 | ||
1105 | ;--------------------------------------------------------------------- |
1107 | ;--------------------------------------------------------------------- |
1106 | ; Set file information for block device. |
1108 | ; Set file information for block device. |
1107 | ; Input: esi + [esp + 4] = file name. |
1109 | ; Input: esi + [esp + 4] = file name. |
1108 | ; ebx = pointer to paramteres from sysfunc 70. |
1110 | ; ebx = pointer to paramteres from sysfunc 70. |
1109 | ; ebp = pointer to EXTFS structure. |
1111 | ; ebp = pointer to EXTFS structure. |
1110 | ; Output: eax = error code. |
1112 | ; Output: eax = error code. |
1111 | ;--------------------------------------------------------------------- |
1113 | ;--------------------------------------------------------------------- |
1112 | ext2_CreateFolder: |
1114 | ext2_CreateFolder: |
1113 | ;DEBUGF 1, "Attempting to create folder.\n" |
1115 | ;DEBUGF 1, "Attempting to create folder.\n" |
1114 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1116 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1115 | jz @F |
1117 | jz @F |
1116 | 1118 | ||
1117 | mov eax, ERROR_UNSUPPORTED_FS |
1119 | mov eax, ERROR_UNSUPPORTED_FS |
1118 | ret |
1120 | ret |
1119 | 1121 | ||
1120 | @@: |
1122 | @@: |
1121 | push ebx ecx edx esi edi |
1123 | push ebx ecx edx esi edi |
1122 | call ext2_lock |
1124 | call ext2_lock |
1123 | 1125 | ||
1124 | add esi, [esp + 20 + 4] |
1126 | add esi, [esp + 20 + 4] |
1125 | 1127 | ||
1126 | ; Can't create root, but for CreateFolder already existing directory is success. |
1128 | ; Can't create root, but for CreateFolder already existing directory is success. |
1127 | cmp byte [esi], 0 |
1129 | cmp byte [esi], 0 |
1128 | jz .success |
1130 | jz .success |
1129 | 1131 | ||
1130 | push esi |
1132 | push esi |
1131 | stdcall ext2_inode_find, 0 |
1133 | stdcall ext2_inode_find, 0 |
1132 | pop esi |
1134 | pop esi |
1133 | 1135 | ||
1134 | ; If the directory is there, we've succeeded. |
1136 | ; If the directory is there, we've succeeded. |
1135 | test eax, eax |
1137 | test eax, eax |
1136 | jz .success |
1138 | jz .success |
1137 | 1139 | ||
1138 | ; Find parent. |
1140 | ; Find parent. |
1139 | call ext2_inode_find_parent |
1141 | call ext2_inode_find_parent |
1140 | test eax, eax |
1142 | test eax, eax |
1141 | jnz .error |
1143 | jnz .error |
1142 | 1144 | ||
1143 | ; Inode ID for preference. |
1145 | ; Inode ID for preference. |
1144 | mov eax, esi |
1146 | mov eax, esi |
1145 | call ext2_inode_alloc |
1147 | call ext2_inode_alloc |
1146 | test eax, eax |
1148 | test eax, eax |
1147 | jnz .error_full |
1149 | jnz .error_full |
1148 | 1150 | ||
1149 | ; Save allocated inode in EDX; filename is in EDI; parent ID in ESI. |
1151 | ; Save allocated inode in EDX; filename is in EDI; parent ID in ESI. |
1150 | mov edx, ebx |
1152 | mov edx, ebx |
1151 | 1153 | ||
1152 | push edi |
1154 | push edi |
1153 | 1155 | ||
1154 | xor al, al |
1156 | xor al, al |
1155 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1157 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1156 | mov ecx, [ebp + EXTFS.inode_size] |
1158 | mov ecx, [ebp + EXTFS.inode_size] |
1157 | rep stosb |
1159 | rep stosb |
1158 | 1160 | ||
1159 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1161 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1160 | add edi, EXT2_INODE_STRUC.i_atime |
1162 | add edi, EXT2_INODE_STRUC.i_atime |
1161 | call current_unix_time |
1163 | call current_unix_time |
1162 | 1164 | ||
1163 | add edi, 8 |
1165 | add edi, 8 |
1164 | call current_unix_time |
1166 | call current_unix_time |
1165 | 1167 | ||
1166 | pop edi |
1168 | pop edi |
1167 | 1169 | ||
1168 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1170 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1169 | mov [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR or PERMISSIONS |
1171 | mov [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR or PERMISSIONS |
1170 | mov eax, edx |
1172 | mov eax, edx |
1171 | call ext2_inode_write |
1173 | call ext2_inode_write |
1172 | test eax, eax |
1174 | test eax, eax |
1173 | jnz .error |
1175 | jnz .error |
1174 | 1176 | ||
1175 | ; Link to self. |
1177 | ; Link to self. |
1176 | push edx esi |
1178 | push edx esi |
1177 | 1179 | ||
1178 | mov eax, edx |
1180 | mov eax, edx |
1179 | mov ebx, eax |
1181 | mov ebx, eax |
1180 | mov dl, EXT2_FT_DIR |
1182 | mov dl, EXT2_FT_DIR |
1181 | mov esi, self_link |
1183 | mov esi, self_link |
1182 | call ext2_inode_link |
1184 | call ext2_inode_link |
1183 | 1185 | ||
1184 | pop esi edx |
1186 | pop esi edx |
1185 | 1187 | ||
1186 | test eax, eax |
1188 | test eax, eax |
1187 | jnz .error |
1189 | jnz .error |
1188 | 1190 | ||
1189 | ; Link to parent. |
1191 | ; Link to parent. |
1190 | push edx esi |
1192 | push edx esi |
1191 | 1193 | ||
1192 | mov eax, ebx |
1194 | mov eax, ebx |
1193 | mov ebx, esi |
1195 | mov ebx, esi |
1194 | mov dl, EXT2_FT_DIR |
1196 | mov dl, EXT2_FT_DIR |
1195 | mov esi, parent_link |
1197 | mov esi, parent_link |
1196 | call ext2_inode_link |
1198 | call ext2_inode_link |
1197 | 1199 | ||
1198 | pop esi edx |
1200 | pop esi edx |
1199 | 1201 | ||
1200 | test eax, eax |
1202 | test eax, eax |
1201 | jnz .error |
1203 | jnz .error |
1202 | 1204 | ||
1203 | ; Link parent to child. |
1205 | ; Link parent to child. |
1204 | mov eax, esi |
1206 | mov eax, esi |
1205 | mov ebx, edx |
1207 | mov ebx, edx |
1206 | mov esi, edi |
1208 | mov esi, edi |
1207 | mov dl, EXT2_FT_DIR |
1209 | mov dl, EXT2_FT_DIR |
1208 | call ext2_inode_link |
1210 | call ext2_inode_link |
1209 | test eax, eax |
1211 | test eax, eax |
1210 | jnz .error |
1212 | jnz .error |
1211 | 1213 | ||
1212 | ; Get block group descriptor for allocated inode's block. |
1214 | ; Get block group descriptor for allocated inode's block. |
1213 | mov eax, ebx |
1215 | mov eax, ebx |
1214 | dec eax |
1216 | dec eax |
1215 | xor edx, edx |
1217 | xor edx, edx |
1216 | 1218 | ||
1217 | ; EAX = block group. |
1219 | ; EAX = block group. |
1218 | div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
1220 | div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
1219 | mov edx, eax |
1221 | mov edx, eax |
1220 | 1222 | ||
1221 | call ext2_bg_read_desc |
1223 | call ext2_bg_read_desc |
1222 | test eax, eax |
1224 | test eax, eax |
1223 | jz .error |
1225 | jz .error |
1224 | 1226 | ||
1225 | inc [eax + EXT2_BLOCK_GROUP_DESC.used_dirs_count] |
1227 | inc [eax + EXT2_BLOCK_GROUP_DESC.used_dirs_count] |
1226 | mov eax, edx |
1228 | mov eax, edx |
1227 | call ext2_bg_write_desc |
1229 | call ext2_bg_write_desc |
1228 | test eax, eax |
1230 | test eax, eax |
1229 | jnz .error |
1231 | jnz .error |
1230 | 1232 | ||
1231 | .success: |
1233 | .success: |
1232 | call ext2_sb_update |
1234 | call ext2_sb_update |
1233 | 1235 | ||
1234 | ; Sync the disk. |
1236 | ; Sync the disk. |
1235 | mov esi, [ebp + PARTITION.Disk] |
1237 | mov esi, [ebp + PARTITION.Disk] |
1236 | call disk_sync ; eax contains error code, if any. |
1238 | call disk_sync ; eax contains error code, if any. |
1237 | 1239 | ||
1238 | .return: |
1240 | .return: |
1239 | push eax |
1241 | push eax |
1240 | call ext2_unlock |
1242 | call ext2_unlock |
1241 | pop eax |
1243 | pop eax |
1242 | 1244 | ||
1243 | pop edi esi edx ecx ebx |
1245 | pop edi esi edx ecx ebx |
1244 | ;DEBUGF 1, "Returning with: %x.\n", eax |
1246 | ;DEBUGF 1, "Returning with: %x.\n", eax |
1245 | ret |
1247 | ret |
1246 | 1248 | ||
1247 | .error: |
1249 | .error: |
1248 | call ext2_sb_update |
1250 | call ext2_sb_update |
1249 | 1251 | ||
1250 | ; Sync the disk. |
1252 | ; Sync the disk. |
1251 | mov esi, [ebp + PARTITION.Disk] |
1253 | mov esi, [ebp + PARTITION.Disk] |
1252 | call disk_sync ; eax contains error code, if any. |
1254 | call disk_sync ; eax contains error code, if any. |
1253 | 1255 | ||
1254 | mov eax, ERROR_ACCESS_DENIED |
1256 | mov eax, ERROR_ACCESS_DENIED |
1255 | jmp .return |
1257 | jmp .return |
1256 | 1258 | ||
1257 | .error_full: |
1259 | .error_full: |
1258 | mov eax, ERROR_DISK_FULL |
1260 | mov eax, ERROR_DISK_FULL |
1259 | jmp .return |
1261 | jmp .return |
1260 | 1262 | ||
1261 | self_link db ".", 0 |
1263 | self_link db ".", 0 |
1262 | parent_link db "..", 0 |
1264 | parent_link db "..", 0 |
1263 | 1265 | ||
1264 | ;--------------------------------------------------------------------- |
1266 | ;--------------------------------------------------------------------- |
1265 | ; Rewrite a file. |
1267 | ; Rewrite a file. |
1266 | ; Input: esi + [esp + 4] = file name. |
1268 | ; Input: esi + [esp + 4] = file name. |
1267 | ; ebx = pointer to paramteres from sysfunc 70. |
1269 | ; ebx = pointer to paramteres from sysfunc 70. |
1268 | ; ebp = pointer to EXTFS structure. |
1270 | ; ebp = pointer to EXTFS structure. |
1269 | ; Output: eax = error code. |
1271 | ; Output: eax = error code. |
1270 | ; ebx = bytes written. |
1272 | ; ebx = bytes written. |
1271 | ;--------------------------------------------------------------------- |
1273 | ;--------------------------------------------------------------------- |
1272 | ext2_Rewrite: |
1274 | ext2_Rewrite: |
1273 | ;DEBUGF 1, "Attempting Rewrite.\n" |
1275 | ;DEBUGF 1, "Attempting Rewrite.\n" |
1274 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1276 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1275 | jz @F |
1277 | jz @F |
1276 | 1278 | ||
1277 | mov eax, ERROR_UNSUPPORTED_FS |
1279 | mov eax, ERROR_UNSUPPORTED_FS |
1278 | ret |
1280 | ret |
1279 | 1281 | ||
1280 | @@: |
1282 | @@: |
1281 | push ecx edx esi edi |
1283 | push ecx edx esi edi |
1282 | pushad |
1284 | pushad |
1283 | 1285 | ||
1284 | call ext2_lock |
1286 | call ext2_lock |
1285 | 1287 | ||
1286 | add esi, [esp + 16 + 32 + 4] |
1288 | add esi, [esp + 16 + 32 + 4] |
1287 | ; Can't create root. |
1289 | ; Can't create root. |
1288 | cmp byte [esi], 0 |
1290 | cmp byte [esi], 0 |
1289 | jz .error_access_denied |
1291 | jz .error_access_denied |
1290 | 1292 | ||
1291 | push esi |
1293 | push esi |
1292 | stdcall ext2_inode_find, 0 |
1294 | stdcall ext2_inode_find, 0 |
1293 | pop esi |
1295 | pop esi |
1294 | 1296 | ||
1295 | ; If the file is there, delete it. |
1297 | ; If the file is there, delete it. |
1296 | test eax, eax |
1298 | test eax, eax |
1297 | jnz @F |
1299 | jnz @F |
1298 | 1300 | ||
1299 | pushad |
1301 | pushad |
1300 | 1302 | ||
1301 | push eax |
1303 | push eax |
1302 | call ext2_unlock |
1304 | call ext2_unlock |
1303 | pop eax |
1305 | pop eax |
1304 | 1306 | ||
1305 | push dword 0x00000000 |
1307 | push dword 0x00000000 |
1306 | call ext2_Delete |
1308 | call ext2_Delete |
1307 | add esp, 4 |
1309 | add esp, 4 |
1308 | 1310 | ||
1309 | push eax |
1311 | push eax |
1310 | call ext2_lock |
1312 | call ext2_lock |
1311 | pop eax |
1313 | pop eax |
1312 | 1314 | ||
1313 | test eax, eax |
1315 | test eax, eax |
1314 | jnz .error_access_denied_delete |
1316 | jnz .error_access_denied_delete |
1315 | 1317 | ||
1316 | popad |
1318 | popad |
1317 | @@: |
1319 | @@: |
1318 | ; Find parent. |
1320 | ; Find parent. |
1319 | call ext2_inode_find_parent |
1321 | call ext2_inode_find_parent |
1320 | test eax, eax |
1322 | test eax, eax |
1321 | jnz .error_access_denied |
1323 | jnz .error_access_denied |
1322 | 1324 | ||
1323 | ; Inode ID for preference. |
1325 | ; Inode ID for preference. |
1324 | mov eax, esi |
1326 | mov eax, esi |
1325 | call ext2_inode_alloc |
1327 | call ext2_inode_alloc |
1326 | test eax, eax |
1328 | test eax, eax |
1327 | jnz .error_full |
1329 | jnz .error_full |
1328 | 1330 | ||
1329 | ; Save allocated inode in EDX; filename is in EDI; parent ID in ESI. |
1331 | ; Save allocated inode in EDX; filename is in EDI; parent ID in ESI. |
1330 | mov edx, ebx |
1332 | mov edx, ebx |
1331 | 1333 | ||
1332 | push edi |
1334 | push edi |
1333 | 1335 | ||
1334 | xor al, al |
1336 | xor al, al |
1335 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1337 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1336 | mov ecx, [ebp + EXTFS.inode_size] |
1338 | mov ecx, [ebp + EXTFS.inode_size] |
1337 | rep stosb |
1339 | rep stosb |
1338 | 1340 | ||
1339 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1341 | mov edi, [ebp + EXTFS.ext2_temp_inode] |
1340 | add edi, EXT2_INODE_STRUC.i_atime |
1342 | add edi, EXT2_INODE_STRUC.i_atime |
1341 | call current_unix_time |
1343 | call current_unix_time |
1342 | 1344 | ||
1343 | add edi, 8 |
1345 | add edi, 8 |
1344 | call current_unix_time |
1346 | call current_unix_time |
1345 | 1347 | ||
1346 | pop edi |
1348 | pop edi |
1347 | 1349 | ||
1348 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1350 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1349 | mov [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG or PERMISSIONS |
1351 | mov [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG or PERMISSIONS |
1350 | mov eax, edx |
1352 | mov eax, edx |
1351 | call ext2_inode_write |
1353 | call ext2_inode_write |
1352 | test eax, eax |
1354 | test eax, eax |
1353 | jnz .error |
1355 | jnz .error |
1354 | 1356 | ||
1355 | ; Link parent to child. |
1357 | ; Link parent to child. |
1356 | mov eax, esi |
1358 | mov eax, esi |
1357 | mov ebx, edx |
1359 | mov ebx, edx |
1358 | mov esi, edi |
1360 | mov esi, edi |
1359 | mov dl, EXT2_FT_REG_FILE |
1361 | mov dl, EXT2_FT_REG_FILE |
1360 | call ext2_inode_link |
1362 | call ext2_inode_link |
1361 | test eax, eax |
1363 | test eax, eax |
1362 | jnz .error |
1364 | jnz .error |
1363 | 1365 | ||
1364 | popad |
1366 | popad |
1365 | push eax |
1367 | push eax |
1366 | call ext2_unlock |
1368 | call ext2_unlock |
1367 | pop eax |
1369 | pop eax |
1368 | 1370 | ||
1369 | push dword 0x00000000 |
1371 | push dword 0x00000000 |
1370 | call ext2_Write |
1372 | call ext2_Write |
1371 | add esp, 4 |
1373 | add esp, 4 |
1372 | 1374 | ||
1373 | push eax |
1375 | push eax |
1374 | call ext2_lock |
1376 | call ext2_lock |
1375 | pop eax |
1377 | pop eax |
1376 | 1378 | ||
1377 | .success: |
1379 | .success: |
1378 | push eax |
1380 | push eax |
1379 | call ext2_sb_update |
1381 | call ext2_sb_update |
1380 | 1382 | ||
1381 | ; Sync the disk. |
1383 | ; Sync the disk. |
1382 | mov esi, [ebp + PARTITION.Disk] |
1384 | mov esi, [ebp + PARTITION.Disk] |
1383 | call disk_sync ; eax contains error code, if any. |
1385 | call disk_sync ; eax contains error code, if any. |
1384 | pop eax |
1386 | pop eax |
1385 | 1387 | ||
1386 | .return: |
1388 | .return: |
1387 | push eax |
1389 | push eax |
1388 | call ext2_unlock |
1390 | call ext2_unlock |
1389 | pop eax |
1391 | pop eax |
1390 | 1392 | ||
1391 | pop edi esi edx ecx |
1393 | pop edi esi edx ecx |
1392 | 1394 | ||
1393 | ;DEBUGF 1, "And returning with: %x.\n", eax |
1395 | ;DEBUGF 1, "And returning with: %x.\n", eax |
1394 | ret |
1396 | ret |
1395 | 1397 | ||
1396 | .error: |
1398 | .error: |
1397 | mov eax, ERROR_ACCESS_DENIED |
1399 | mov eax, ERROR_ACCESS_DENIED |
1398 | jmp .success |
1400 | jmp .success |
1399 | 1401 | ||
1400 | .error_access_denied_delete: |
1402 | .error_access_denied_delete: |
1401 | popad |
1403 | popad |
1402 | 1404 | ||
1403 | .error_access_denied: |
1405 | .error_access_denied: |
1404 | popad |
1406 | popad |
1405 | xor ebx, ebx |
1407 | xor ebx, ebx |
1406 | 1408 | ||
1407 | mov eax, ERROR_ACCESS_DENIED |
1409 | mov eax, ERROR_ACCESS_DENIED |
1408 | jmp .return |
1410 | jmp .return |
1409 | 1411 | ||
1410 | .error_full: |
1412 | .error_full: |
1411 | popad |
1413 | popad |
1412 | xor ebx, ebx |
1414 | xor ebx, ebx |
1413 | 1415 | ||
1414 | mov eax, ERROR_DISK_FULL |
1416 | mov eax, ERROR_DISK_FULL |
1415 | jmp .return |
1417 | jmp .return |
1416 | 1418 | ||
1417 | ;--------------------------------------------------------------------- |
1419 | ;--------------------------------------------------------------------- |
1418 | ; Write to a file. |
1420 | ; Write to a file. |
1419 | ; Input: esi + [esp + 4] = file name. |
1421 | ; Input: esi + [esp + 4] = file name. |
1420 | ; ebx = pointer to paramteres from sysfunc 70. |
1422 | ; ebx = pointer to paramteres from sysfunc 70. |
1421 | ; ebp = pointer to EXTFS structure. |
1423 | ; ebp = pointer to EXTFS structure. |
1422 | ; Output: eax = error code. |
1424 | ; Output: eax = error code. |
1423 | ; ebx = number of bytes written. |
1425 | ; ebx = number of bytes written. |
1424 | ;--------------------------------------------------------------------- |
1426 | ;--------------------------------------------------------------------- |
1425 | ext2_Write: |
1427 | ext2_Write: |
1426 | ;DEBUGF 1, "Attempting write, " |
1428 | ;DEBUGF 1, "Attempting write, " |
1427 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1429 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1428 | jz @F |
1430 | jz @F |
1429 | 1431 | ||
1430 | mov eax, ERROR_UNSUPPORTED_FS |
1432 | mov eax, ERROR_UNSUPPORTED_FS |
1431 | ret |
1433 | ret |
1432 | 1434 | ||
1433 | @@: |
1435 | @@: |
1434 | push ecx edx esi edi |
1436 | push ecx edx esi edi |
1435 | call ext2_lock |
1437 | call ext2_lock |
1436 | 1438 | ||
1437 | add esi, [esp + 16 + 4] |
1439 | add esi, [esp + 16 + 4] |
1438 | 1440 | ||
1439 | ; Can't write to root. |
1441 | ; Can't write to root. |
1440 | cmp byte [esi], 0 |
1442 | cmp byte [esi], 0 |
1441 | jz .error |
1443 | jz .error |
1442 | 1444 | ||
1443 | push ebx ecx edx |
1445 | push ebx ecx edx |
1444 | stdcall ext2_inode_find, 0 |
1446 | stdcall ext2_inode_find, 0 |
1445 | pop edx ecx ebx |
1447 | pop edx ecx ebx |
1446 | ; If file not there, error. |
1448 | ; If file not there, error. |
1447 | xor ecx, ecx |
1449 | xor ecx, ecx |
1448 | test eax, eax |
1450 | test eax, eax |
1449 | jnz .error_file_not_found |
1451 | jnz .error_file_not_found |
1450 | 1452 | ||
1451 | ; Save the inode. |
1453 | ; Save the inode. |
1452 | push esi |
1454 | push esi |
1453 | 1455 | ||
1454 | ; Check if it's a file. |
1456 | ; Check if it's a file. |
1455 | mov edx, [ebp + EXTFS.ext2_save_inode] |
1457 | mov edx, [ebp + EXTFS.ext2_save_inode] |
1456 | test [edx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG |
1458 | test [edx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG |
1457 | jz .error |
1459 | jz .error |
1458 | 1460 | ||
1459 | mov eax, esi |
1461 | mov eax, esi |
1460 | mov ecx, [ebx + 4] |
1462 | mov ecx, [ebx + 4] |
1461 | 1463 | ||
1462 | call ext2_inode_extend |
1464 | call ext2_inode_extend |
1463 | xor ecx, ecx |
1465 | xor ecx, ecx |
1464 | test eax, eax |
1466 | test eax, eax |
1465 | jnz .error_device |
1467 | jnz .error_device |
1466 | 1468 | ||
1467 | ; ECX contains the size to write, and ESI points to it. |
1469 | ; ECX contains the size to write, and ESI points to it. |
1468 | mov ecx, [ebx + 0x0C] |
1470 | mov ecx, [ebx + 0x0C] |
1469 | mov esi, [ebx + 0x10] |
1471 | mov esi, [ebx + 0x10] |
1470 | 1472 | ||
1471 | ; Save the size of the inode. |
1473 | ; Save the size of the inode. |
1472 | mov eax, [edx + EXT2_INODE_STRUC.i_size] |
1474 | mov eax, [edx + EXT2_INODE_STRUC.i_size] |
1473 | push eax |
1475 | push eax |
1474 | 1476 | ||
1475 | xor edx, edx |
1477 | xor edx, edx |
1476 | div [ebp + EXTFS.block_size] |
1478 | div [ebp + EXTFS.block_size] |
1477 | 1479 | ||
1478 | test edx, edx |
1480 | test edx, edx |
1479 | jz .start_aligned |
1481 | jz .start_aligned |
1480 | 1482 | ||
1481 | ; Start isn't aligned, so deal with the non-aligned bytes. |
1483 | ; Start isn't aligned, so deal with the non-aligned bytes. |
1482 | mov ebx, [ebp + EXTFS.block_size] |
1484 | mov ebx, [ebp + EXTFS.block_size] |
1483 | sub ebx, edx |
1485 | sub ebx, edx |
1484 | 1486 | ||
1485 | cmp ebx, ecx |
1487 | cmp ebx, ecx |
1486 | jbe @F |
1488 | jbe @F |
1487 | 1489 | ||
1488 | ; If the size to copy fits in current block, limit to that, instead of the entire block. |
1490 | ; If the size to copy fits in current block, limit to that, instead of the entire block. |
1489 | mov ebx, ecx |
1491 | mov ebx, ecx |
1490 | 1492 | ||
1491 | @@: |
1493 | @@: |
1492 | ; Copy EBX bytes, in EAX indexed block. |
1494 | ; Copy EBX bytes, in EAX indexed block. |
1493 | push eax |
1495 | push eax |
1494 | call ext2_inode_read_entry |
1496 | call ext2_inode_read_entry |
1495 | test eax, eax |
1497 | test eax, eax |
1496 | pop eax |
1498 | pop eax |
1497 | jnz .error_inode_size |
1499 | jnz .error_inode_size |
1498 | 1500 | ||
1499 | push ecx |
1501 | push ecx |
1500 | 1502 | ||
1501 | mov ecx, ebx |
1503 | mov ecx, ebx |
1502 | mov edi, ebx |
1504 | mov edi, ebx |
1503 | add edi, edx |
1505 | add edi, edx |
1504 | rep movsb |
1506 | rep movsb |
1505 | 1507 | ||
1506 | pop ecx |
1508 | pop ecx |
1507 | 1509 | ||
1508 | ; Write the block. |
1510 | ; Write the block. |
1509 | call ext2_inode_write_entry |
1511 | call ext2_inode_write_entry |
1510 | test eax, eax |
1512 | test eax, eax |
1511 | jnz .error_inode_size |
1513 | jnz .error_inode_size |
1512 | 1514 | ||
1513 | add [esp], ebx |
1515 | add [esp], ebx |
1514 | sub ecx, ebx |
1516 | sub ecx, ebx |
1515 | jz .write_inode |
1517 | jz .write_inode |
1516 | 1518 | ||
1517 | .start_aligned: |
1519 | .start_aligned: |
1518 | cmp ecx, [ebp + EXTFS.block_size] |
1520 | cmp ecx, [ebp + EXTFS.block_size] |
1519 | jb @F |
1521 | jb @F |
1520 | 1522 | ||
1521 | mov eax, [esp] |
1523 | mov eax, [esp] |
1522 | xor edx, edx |
1524 | xor edx, edx |
1523 | div [ebp + EXTFS.block_size] |
1525 | div [ebp + EXTFS.block_size] |
1524 | 1526 | ||
1525 | push eax |
1527 | push eax |
1526 | mov edx, [esp + 8] |
1528 | mov edx, [esp + 8] |
1527 | call ext2_inode_blank_entry |
1529 | call ext2_inode_blank_entry |
1528 | test eax, eax |
1530 | test eax, eax |
1529 | pop eax |
1531 | pop eax |
1530 | jnz .error_inode_size |
1532 | jnz .error_inode_size |
1531 | 1533 | ||
1532 | push ecx |
1534 | push ecx |
1533 | 1535 | ||
1534 | mov ecx, [ebp + EXTFS.block_size] |
1536 | mov ecx, [ebp + EXTFS.block_size] |
1535 | mov edi, [ebp + EXTFS.ext2_save_block] |
1537 | mov edi, [ebp + EXTFS.ext2_save_block] |
1536 | rep movsb |
1538 | rep movsb |
1537 | 1539 | ||
1538 | pop ecx |
1540 | pop ecx |
1539 | 1541 | ||
1540 | call ext2_inode_write_entry |
1542 | call ext2_inode_write_entry |
1541 | test eax, eax |
1543 | test eax, eax |
1542 | jnz .error_inode_size |
1544 | jnz .error_inode_size |
1543 | 1545 | ||
1544 | mov eax, [ebp + EXTFS.block_size] |
1546 | mov eax, [ebp + EXTFS.block_size] |
1545 | sub ecx, eax |
1547 | sub ecx, eax |
1546 | add [esp], eax |
1548 | add [esp], eax |
1547 | jmp .start_aligned |
1549 | jmp .start_aligned |
1548 | 1550 | ||
1549 | ; Handle the remaining bytes. |
1551 | ; Handle the remaining bytes. |
1550 | @@: |
1552 | @@: |
1551 | test ecx, ecx |
1553 | test ecx, ecx |
1552 | jz .write_inode |
1554 | jz .write_inode |
1553 | 1555 | ||
1554 | mov eax, [esp] |
1556 | mov eax, [esp] |
1555 | xor edx, edx |
1557 | xor edx, edx |
1556 | div [ebp + EXTFS.block_size] |
1558 | div [ebp + EXTFS.block_size] |
1557 | 1559 | ||
1558 | push eax |
1560 | push eax |
1559 | call ext2_inode_read_entry |
1561 | call ext2_inode_read_entry |
1560 | test eax, eax |
1562 | test eax, eax |
1561 | pop eax |
1563 | pop eax |
1562 | jz @F |
1564 | jz @F |
1563 | 1565 | ||
1564 | push eax |
1566 | push eax |
1565 | mov edx, [esp + 8] |
1567 | mov edx, [esp + 8] |
1566 | 1568 | ||
1567 | call ext2_inode_blank_entry |
1569 | call ext2_inode_blank_entry |
1568 | test eax, eax |
1570 | test eax, eax |
1569 | pop eax |
1571 | pop eax |
1570 | jnz .error_inode_size |
1572 | jnz .error_inode_size |
1571 | 1573 | ||
1572 | @@: |
1574 | @@: |
1573 | push ecx |
1575 | push ecx |
1574 | mov edi, [ebp + EXTFS.ext2_save_block] |
1576 | mov edi, [ebp + EXTFS.ext2_save_block] |
1575 | rep movsb |
1577 | rep movsb |
1576 | pop ecx |
1578 | pop ecx |
1577 | 1579 | ||
1578 | call ext2_inode_write_entry |
1580 | call ext2_inode_write_entry |
1579 | test eax, eax |
1581 | test eax, eax |
1580 | jnz .error_inode_size |
1582 | jnz .error_inode_size |
1581 | 1583 | ||
1582 | add [esp], ecx |
1584 | add [esp], ecx |
1583 | xor ecx, ecx |
1585 | xor ecx, ecx |
1584 | 1586 | ||
1585 | .write_inode: |
1587 | .write_inode: |
1586 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1588 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1587 | pop eax |
1589 | pop eax |
1588 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1590 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1589 | mov eax, [esp] |
1591 | mov eax, [esp] |
1590 | 1592 | ||
1591 | call ext2_inode_write |
1593 | call ext2_inode_write |
1592 | test eax, eax |
1594 | test eax, eax |
1593 | jnz .error_device |
1595 | jnz .error_device |
1594 | 1596 | ||
1595 | .success: |
1597 | .success: |
1596 | call ext2_sb_update |
1598 | call ext2_sb_update |
1597 | 1599 | ||
1598 | ; Sync the disk. |
1600 | ; Sync the disk. |
1599 | mov esi, [ebp + PARTITION.Disk] |
1601 | mov esi, [ebp + PARTITION.Disk] |
1600 | call disk_sync ; eax contains error code, if any. |
1602 | call disk_sync ; eax contains error code, if any. |
1601 | 1603 | ||
1602 | .return: |
1604 | .return: |
1603 | push eax |
1605 | push eax |
1604 | call ext2_unlock |
1606 | call ext2_unlock |
1605 | pop eax |
1607 | pop eax |
1606 | 1608 | ||
1607 | add esp, 4 |
1609 | add esp, 4 |
1608 | 1610 | ||
1609 | mov ebx, [esp + 12] |
1611 | mov ebx, [esp + 12] |
1610 | sub ebx, ecx |
1612 | sub ebx, ecx |
1611 | pop edi esi edx ecx |
1613 | pop edi esi edx ecx |
1612 | 1614 | ||
1613 | ;DEBUGF 1, "and returning with: %x.\n", eax |
1615 | ;DEBUGF 1, "and returning with: %x.\n", eax |
1614 | ret |
1616 | ret |
1615 | 1617 | ||
1616 | .error: |
1618 | .error: |
1617 | mov eax, ERROR_ACCESS_DENIED |
1619 | mov eax, ERROR_ACCESS_DENIED |
1618 | jmp .return |
1620 | jmp .return |
1619 | 1621 | ||
1620 | .error_file_not_found: |
1622 | .error_file_not_found: |
1621 | mov eax, ERROR_FILE_NOT_FOUND |
1623 | mov eax, ERROR_FILE_NOT_FOUND |
1622 | jmp .return |
1624 | jmp .return |
1623 | 1625 | ||
1624 | .error_inode_size: |
1626 | .error_inode_size: |
1625 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1627 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1626 | pop eax |
1628 | pop eax |
1627 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1629 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1628 | mov eax, [esp] |
1630 | mov eax, [esp] |
1629 | 1631 | ||
1630 | call ext2_inode_write |
1632 | call ext2_inode_write |
1631 | 1633 | ||
1632 | .error_device: |
1634 | .error_device: |
1633 | call ext2_sb_update |
1635 | call ext2_sb_update |
1634 | 1636 | ||
1635 | ; Sync the disk. |
1637 | ; Sync the disk. |
1636 | mov esi, [ebp + PARTITION.Disk] |
1638 | mov esi, [ebp + PARTITION.Disk] |
1637 | call disk_sync ; eax contains error code, if any. |
1639 | call disk_sync ; eax contains error code, if any. |
1638 | 1640 | ||
1639 | mov eax, ERROR_DEVICE |
1641 | mov eax, ERROR_DEVICE |
1640 | jmp .return |
1642 | jmp .return |
1641 | 1643 | ||
1642 | ;--------------------------------------------------------------------- |
1644 | ;--------------------------------------------------------------------- |
1643 | ; Set the end of a file. |
1645 | ; Set the end of a file. |
1644 | ; Input: esi + [esp + 4] = file name. |
1646 | ; Input: esi + [esp + 4] = file name. |
1645 | ; ebx = pointer to paramteres from sysfunc 70. |
1647 | ; ebx = pointer to paramteres from sysfunc 70. |
1646 | ; ebp = pointer to EXTFS structure. |
1648 | ; ebp = pointer to EXTFS structure. |
1647 | ; Output: eax = error code. |
1649 | ; Output: eax = error code. |
1648 | ;--------------------------------------------------------------------- |
1650 | ;--------------------------------------------------------------------- |
1649 | ext2_SetFileEnd: |
1651 | ext2_SetFileEnd: |
1650 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1652 | test [ebp + EXTFS.partition_flags], EXT2_RO |
1651 | jz @F |
1653 | jz @F |
1652 | 1654 | ||
1653 | mov eax, ERROR_UNSUPPORTED_FS |
1655 | mov eax, ERROR_UNSUPPORTED_FS |
1654 | ret |
1656 | ret |
1655 | 1657 | ||
1656 | @@: |
1658 | @@: |
1657 | push ebx ecx edx esi edi |
1659 | push ebx ecx edx esi edi |
1658 | call ext2_lock |
1660 | call ext2_lock |
1659 | 1661 | ||
1660 | add esi, [esp + 20 + 4] |
1662 | add esi, [esp + 20 + 4] |
1661 | 1663 | ||
1662 | ; Can't write to root. |
1664 | ; Can't write to root. |
1663 | cmp byte [esi], 0 |
1665 | cmp byte [esi], 0 |
1664 | jz .error |
1666 | jz .error |
1665 | 1667 | ||
1666 | stdcall ext2_inode_find, 0 |
1668 | stdcall ext2_inode_find, 0 |
1667 | ; If file not there, error. |
1669 | ; If file not there, error. |
1668 | test eax, eax |
1670 | test eax, eax |
1669 | jnz .error_file_not_found |
1671 | jnz .error_file_not_found |
1670 | 1672 | ||
1671 | ; Check if it's a file. |
1673 | ; Check if it's a file. |
1672 | mov edx, [ebp + EXTFS.ext2_save_inode] |
1674 | mov edx, [ebp + EXTFS.ext2_save_inode] |
1673 | cmp [edx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG |
1675 | cmp [edx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG |
1674 | jne .error |
1676 | jne .error |
1675 | 1677 | ||
1676 | mov eax, esi |
1678 | mov eax, esi |
1677 | mov ecx, [ebx + 4] |
1679 | mov ecx, [ebx + 4] |
1678 | call ext2_inode_extend |
1680 | call ext2_inode_extend |
1679 | test eax, eax |
1681 | test eax, eax |
1680 | jnz .error_disk_full |
1682 | jnz .error_disk_full |
1681 | 1683 | ||
1682 | mov eax, esi |
1684 | mov eax, esi |
1683 | call ext2_inode_truncate |
1685 | call ext2_inode_truncate |
1684 | test eax, eax |
1686 | test eax, eax |
1685 | jnz .error_disk_full |
1687 | jnz .error_disk_full |
1686 | 1688 | ||
1687 | mov eax, esi |
1689 | mov eax, esi |
1688 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1690 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1689 | call ext2_inode_write |
1691 | call ext2_inode_write |
1690 | 1692 | ||
1691 | call ext2_sb_update |
1693 | call ext2_sb_update |
1692 | 1694 | ||
1693 | ; Sync the disk. |
1695 | ; Sync the disk. |
1694 | mov esi, [ebp + PARTITION.Disk] |
1696 | mov esi, [ebp + PARTITION.Disk] |
1695 | call disk_sync ; eax contains error code, if any. |
1697 | call disk_sync ; eax contains error code, if any. |
1696 | 1698 | ||
1697 | .return: |
1699 | .return: |
1698 | push eax |
1700 | push eax |
1699 | call ext2_unlock |
1701 | call ext2_unlock |
1700 | pop eax |
1702 | pop eax |
1701 | 1703 | ||
1702 | pop edi esi edx ecx ebx |
1704 | pop edi esi edx ecx ebx |
1703 | ret |
1705 | ret |
1704 | 1706 | ||
1705 | .error: |
1707 | .error: |
1706 | mov eax, ERROR_ACCESS_DENIED |
1708 | mov eax, ERROR_ACCESS_DENIED |
1707 | jmp .return |
1709 | jmp .return |
1708 | 1710 | ||
1709 | .error_file_not_found: |
1711 | .error_file_not_found: |
1710 | mov eax, ERROR_FILE_NOT_FOUND |
1712 | mov eax, ERROR_FILE_NOT_FOUND |
1711 | jmp .return |
1713 | jmp .return |
1712 | 1714 | ||
1713 | .error_disk_full: |
1715 | .error_disk_full: |
1714 | call ext2_sb_update |
1716 | call ext2_sb_update |
1715 | 1717 | ||
1716 | ; Sync the disk. |
1718 | ; Sync the disk. |
1717 | mov esi, [ebp + PARTITION.Disk] |
1719 | mov esi, [ebp + PARTITION.Disk] |
1718 | call disk_sync ; eax contains error code, if any. |
1720 | call disk_sync ; eax contains error code, if any. |
1719 | 1721 | ||
1720 | mov eax, ERROR_DISK_FULL |
1722 | mov eax, ERROR_DISK_FULL |
1721 | jmp .return |
1723 | jmp .return |