Subversion Repositories Kolibri OS

Rev

Rev 6558 | Rev 6643 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6558 Rev 6575
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2013-2016. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2013-2016. All rights reserved. ;;
4
;;  Distributed under terms of the GNU General Public License.  ;;
4
;;  Distributed under terms of the GNU General Public License.  ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 6558 $
8
$Revision: 6575 $
9
 
9
 
10
; EXT external functions
10
; EXT external functions
11
;   in:
11
;   in:
12
; ebx -> parameter structure of sysfunc 70
12
; ebx -> parameter structure of sysfunc 70
13
; ebp -> EXTFS structure
13
; ebp -> EXTFS structure
14
; esi -> path string in UTF-8
14
; esi -> path string in UTF-8
15
;   out:
15
;   out:
16
; eax, ebx = return values for sysfunc 70
16
; eax, ebx = return values for sysfunc 70
17
iglobal
17
iglobal
18
align 4
18
align 4
19
ext_user_functions:
19
ext_user_functions:
20
        dd      ext_free
20
        dd      ext_free
21
        dd      (ext_user_functions_end - ext_user_functions - 4) / 4
21
        dd      (ext_user_functions_end - ext_user_functions - 4) / 4
22
        dd      ext_ReadFile
22
        dd      ext_ReadFile
23
        dd      ext_ReadFolder
23
        dd      ext_ReadFolder
24
        dd      ext_CreateFile
24
        dd      ext_CreateFile
25
        dd      ext_WriteFile
25
        dd      ext_WriteFile
26
        dd      ext_SetFileEnd
26
        dd      ext_SetFileEnd
27
        dd      ext_GetFileInfo
27
        dd      ext_GetFileInfo
28
        dd      ext_SetFileInfo
28
        dd      ext_SetFileInfo
29
        dd      0
29
        dd      0
30
        dd      ext_Delete
30
        dd      ext_Delete
31
        dd      ext_CreateFolder
31
        dd      ext_CreateFolder
32
ext_user_functions_end:
32
ext_user_functions_end:
33
endg
33
endg
34
 
34
 
35
struct DIRENTRY
35
struct DIRENTRY
36
inodeNumber     dd  ?
36
inodeNumber     dd  ?
37
entryLength     dw  ?
37
entryLength     dw  ?
38
nameLength      db  ?
38
nameLength      db  ?
39
fileType        db  ?
39
fileType        db  ?
40
name            db  ?   ; rb [nameLength]
40
name            db  ?   ; rb [nameLength]
41
ends
41
ends
42
 
42
 
43
struct INODE
43
struct INODE
44
accessMode      dw  ?
44
accessMode      dw  ?
45
UID             dw  ?
45
UID             dw  ?
46
fileSize        dd  ?
46
fileSize        dd  ?
47
accessedTime    dd  ?
47
accessedTime    dd  ?
48
inodeModified   dd  ?
48
inodeModified   dd  ?
49
dataModified    dd  ?
49
dataModified    dd  ?
50
deletedTime     dd  ?
50
deletedTime     dd  ?
51
GID             dw  ?
51
GID             dw  ?
52
linksCount      dw  ?
52
linksCount      dw  ?
53
sectorsUsed     dd  ?
53
sectorsUsed     dd  ?
54
featureFlags    dd  ?
54
featureFlags    dd  ?
55
reserved        dd  ?
55
reserved        dd  ?
56
blockNumbers    rd  12
56
blockNumbers    rd  12
57
addressBlock    dd  ?
57
addressBlock    dd  ?
58
doubleAddress   dd  ?
58
doubleAddress   dd  ?
59
tripleAddress   dd  ?
59
tripleAddress   dd  ?
60
generation      dd  ?
60
generation      dd  ?
61
ACL             dd  ?
61
ACL             dd  ?
62
fileSizeHigh    dd  ?
62
fileSizeHigh    dd  ?
63
ends
63
ends
64
 
64
 
65
struct BGDESCR  ; block group descriptor
65
struct BGDESCR  ; block group descriptor
66
blockBitmap         dd  ?
66
blockBitmap         dd  ?
67
inodeBitmap         dd  ?
67
inodeBitmap         dd  ?
68
inodeTable          dd  ?
68
inodeTable          dd  ?
69
blocksFree          dw  ?
69
blocksFree          dw  ?
70
inodesFree          dw  ?
70
inodesFree          dw  ?
71
directoriesCount    dw  ?
71
directoriesCount    dw  ?
72
reserved            rb  14
72
reserved            rb  14
73
ends
73
ends
74
 
74
 
75
struct SUPERBLOCK
75
struct SUPERBLOCK
76
inodesTotal         dd  ?
76
inodesTotal         dd  ?
77
blocksTotal         dd  ?
77
blocksTotal         dd  ?
78
blocksReserved      dd  ?
78
blocksReserved      dd  ?
79
blocksFree          dd  ?
79
blocksFree          dd  ?
80
inodesFree          dd  ?
80
inodesFree          dd  ?
81
firstGroupBlock     dd  ?
81
firstGroupBlock     dd  ?
82
sectorsPerBlockLog  dd  ?   ; shift for 1024
82
sectorsPerBlockLog  dd  ?   ; shift for 1024
83
fragmentSizeLog     dd  ?
83
fragmentSizeLog     dd  ?
84
blocksPerGroup      dd  ?
84
blocksPerGroup      dd  ?
85
fragmentsPerGroup   dd  ?
85
fragmentsPerGroup   dd  ?
86
inodesPerGroup      dd  ?
86
inodesPerGroup      dd  ?
87
lastMountTime       dd  ?
87
lastMountTime       dd  ?
88
lastWriteTime       dd  ?
88
lastWriteTime       dd  ?
89
mountCount          dw  ?
89
mountCount          dw  ?
90
mountMax            dw  ?
90
mountMax            dw  ?
91
magic               dw  ?
91
magic               dw  ?
92
state               dw  ?
92
state               dw  ?
93
errorHandling       dw  ?
93
errorHandling       dw  ?
94
additionalVersion   dw  ?
94
additionalVersion   dw  ?
95
lastCheck           dd  ?
95
lastCheck           dd  ?
96
checkInterval       dd  ?
96
checkInterval       dd  ?
97
creatorOS           dd  ?
97
creatorOS           dd  ?
98
dynamicVersionFlag  dd  ?
98
dynamicVersionFlag  dd  ?
99
reservedUID         dw  ?
99
reservedUID         dw  ?
100
reservedGID         dw  ?
100
reservedGID         dw  ?
101
firstInode          dd  ?
101
firstInode          dd  ?
102
inodeSize           dw  ?
102
inodeSize           dw  ?
103
thisBlockGroup      dw  ?
103
thisBlockGroup      dw  ?
104
compatibleFlags     dd  ?
104
compatibleFlags     dd  ?
105
incompatibleFlags   dd  ?
105
incompatibleFlags   dd  ?
106
RO_compatibleFlags  dd  ?
106
RO_compatibleFlags  dd  ?
107
ends
107
ends
108
 
108
 
109
; ext4 extent tree
109
; ext4 extent tree
110
struct NODEHEADER       ; tree node header
110
struct NODEHEADER       ; tree node header
111
magic           dw  ?   ; 0xF30A
111
magic           dw  ?   ; 0xF30A
112
entriesFolow    dw  ?
112
entriesFolow    dw  ?
113
entriesMax      dw  ?
113
entriesMax      dw  ?
114
currentDepth    dw  ?
114
currentDepth    dw  ?
115
generation      dd  ?
115
generation      dd  ?
116
ends
116
ends
117
 
117
 
118
struct INDEX    ; root/branch
118
struct INDEX    ; root/branch
119
fileBlock       dd  ?
119
fileBlock       dd  ?
120
nodeBlock       dd  ?
120
nodeBlock       dd  ?
121
nodeBlockHigh   dw  ?
121
nodeBlockHigh   dw  ?
122
reserved        dw  ?
122
reserved        dw  ?
123
ends
123
ends
124
 
124
 
125
struct EXTENT   ; leaf
125
struct EXTENT   ; leaf
126
fileBlock       dd  ?
126
fileBlock       dd  ?
127
blocksCount     dw  ?
127
blocksCount     dw  ?
128
fsBlockHigh     dw  ?
128
fsBlockHigh     dw  ?
129
fsBlock         dd  ?
129
fsBlock         dd  ?
130
ends
130
ends
131
 
131
 
132
ROOT_INODE = 2
132
ROOT_INODE = 2
133
PERMISSIONS = 110110110b
133
PERMISSIONS = 110110110b
134
EXTENTS_USED = 80000h
134
EXTENTS_USED = 80000h
135
TYPE_MASK = 0F000h
135
TYPE_MASK = 0F000h
136
FLAG_FILE = 8000h
136
FLAG_FILE = 8000h
137
DIRECTORY = 4000h
137
DIRECTORY = 4000h
138
DIR_FLAG_FILE = 1
138
DIR_FLAG_FILE = 1
139
DIR_DIRECTORY = 2
139
DIR_DIRECTORY = 2
140
KOS_HIDDEN = 2
140
KOS_HIDDEN = 2
141
KOS_DIRECTORY = 10h
141
KOS_DIRECTORY = 10h
142
READ_ONLY = 1
142
READ_ONLY = 1
143
 
143
 
144
; Implemented "incompatible" features:
144
; Implemented "incompatible" features:
145
; 2 = have file type in directory entry
145
; 2 = have file type in directory entry
146
; 40h = extents
146
; 40h = extents
147
; 200h = flexible block groups
147
; 200h = flexible block groups
148
INCOMPATIBLE_SUPPORT = 242h
148
INCOMPATIBLE_SUPPORT = 242h
149
; Read only support for "incompatible" features:
149
; Read only support for "incompatible" features:
150
INCOMPATIBLE_READ_SUPPORT = 240h
150
INCOMPATIBLE_READ_SUPPORT = 240h
151
 
151
 
152
; Implemented "read-only" features:
152
; Implemented "read-only" features:
153
; 1 = sparse superblock
153
; 1 = sparse superblock
154
; 2 = 64-bit file size
154
; 2 = 64-bit file size
155
READ_ONLY_SUPPORT = 3
155
READ_ONLY_SUPPORT = 3
156
 
156
 
157
struct EXTFS PARTITION
157
struct EXTFS PARTITION
158
Lock                MUTEX
158
Lock                MUTEX
159
mountType           dd  ?
159
mountType           dd  ?
160
sectorsPerBlockLog  dd  ?   ; shift for 512
160
sectorsPerBlockLog  dd  ?   ; shift for 512
161
bytesPerBlock       dd  ?
161
bytesPerBlock       dd  ?
162
sectorsPerBlock     dd  ?
162
sectorsPerBlock     dd  ?
163
dwordsPerBlock      dd  ?
163
dwordsPerBlock      dd  ?
164
dwordsPerBranch     dd  ?   ; dwordsPerBlock ^ 2
164
dwordsPerBranch     dd  ?   ; dwordsPerBlock ^ 2
165
mainBlockBuffer     dd  ?
165
mainBlockBuffer     dd  ?
166
tempBlockBuffer     dd  ?
166
tempBlockBuffer     dd  ?
167
align0  rb  200h-EXTFS.align0
167
align0  rb  200h-EXTFS.align0
168
superblock          SUPERBLOCK
168
superblock          SUPERBLOCK
169
align1  rb  400h-EXTFS.align1
169
align1  rb  400h-EXTFS.align1
170
rootInodeBuffer     INODE
170
rootInodeBuffer     INODE
171
align2  rb  600h-EXTFS.align2
171
align2  rb  600h-EXTFS.align2
172
inodeBuffer         INODE
172
inodeBuffer         INODE
173
align3  rb  800h-EXTFS.align3
173
align3  rb  800h-EXTFS.align3
174
ends
174
ends
175
 
175
 
176
; mount if it's a valid EXT partition
176
; mount if it's a valid EXT partition
177
ext2_create_partition:
177
ext2_create_partition:
178
;   in:
178
;   in:
179
; ebp -> PARTITION structure
179
; ebp -> PARTITION structure
180
; ebx -> boot sector
180
; ebx -> boot sector
181
; ebx+512 -> buffer
181
; ebx+512 -> buffer
182
;   out:
182
;   out:
183
; eax -> EXTFS structure, 0 = not EXT
183
; eax -> EXTFS structure, 0 = not EXT
184
        push    ebx
184
        push    ebx
185
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
185
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
186
        jnz     .fail
186
        jnz     .fail
187
        mov     eax, 2
187
        mov     eax, 2
188
        add     ebx, 512
188
        add     ebx, 512
189
        call    fs_read32_sys
189
        call    fs_read32_sys
190
        test    eax, eax
190
        test    eax, eax
191
        jnz     .fail
191
        jnz     .fail
192
        cmp     [ebx+SUPERBLOCK.magic], 0xEF53
192
        cmp     [ebx+SUPERBLOCK.magic], 0xEF53
193
        jne     .fail
193
        jne     .fail
194
        cmp     [ebx+SUPERBLOCK.state], 1
194
        cmp     [ebx+SUPERBLOCK.state], 1
195
        ja      .fail
195
        ja      .fail
196
        test    [ebx+SUPERBLOCK.incompatibleFlags], not INCOMPATIBLE_SUPPORT
196
        test    [ebx+SUPERBLOCK.incompatibleFlags], not INCOMPATIBLE_SUPPORT
197
        jnz     .fail
197
        jnz     .fail
198
        cmp     [ebx+SUPERBLOCK.sectorsPerBlockLog], 6  ; 64KB
198
        cmp     [ebx+SUPERBLOCK.sectorsPerBlockLog], 6  ; 64KB
199
        ja      .fail
199
        ja      .fail
200
        cmp     [ebx+SUPERBLOCK.inodeSize], 1024
200
        cmp     [ebx+SUPERBLOCK.inodeSize], 1024
201
        ja      .fail
201
        ja      .fail
202
        cmp     [ebx+SUPERBLOCK.blocksPerGroup], 0
202
        cmp     [ebx+SUPERBLOCK.blocksPerGroup], 0
203
        je      .fail
203
        je      .fail
204
        cmp     [ebx+SUPERBLOCK.inodesPerGroup], 0
204
        cmp     [ebx+SUPERBLOCK.inodesPerGroup], 0
205
        je      .fail
205
        je      .fail
206
        movi    eax, sizeof.EXTFS
206
        movi    eax, sizeof.EXTFS
207
        call    malloc
207
        call    malloc
208
        test    eax, eax
208
        test    eax, eax
209
        jz      .fail
209
        jz      .fail
210
        mov     ecx, dword [ebp+PARTITION.FirstSector]
210
        mov     ecx, dword [ebp+PARTITION.FirstSector]
211
        mov     dword [eax+EXTFS.FirstSector], ecx
211
        mov     dword [eax+EXTFS.FirstSector], ecx
212
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
212
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
213
        mov     dword [eax+EXTFS.FirstSector+4], ecx
213
        mov     dword [eax+EXTFS.FirstSector+4], ecx
214
        mov     ecx, dword [ebp+PARTITION.Length]
214
        mov     ecx, dword [ebp+PARTITION.Length]
215
        mov     dword [eax+EXTFS.Length], ecx
215
        mov     dword [eax+EXTFS.Length], ecx
216
        mov     ecx, dword [ebp+PARTITION.Length+4]
216
        mov     ecx, dword [ebp+PARTITION.Length+4]
217
        mov     dword [eax+EXTFS.Length+4], ecx
217
        mov     dword [eax+EXTFS.Length+4], ecx
218
        mov     ecx, [ebp+PARTITION.Disk]
218
        mov     ecx, [ebp+PARTITION.Disk]
219
        mov     [eax+EXTFS.Disk], ecx
219
        mov     [eax+EXTFS.Disk], ecx
220
        mov     [eax+EXTFS.FSUserFunctions], ext_user_functions
220
        mov     [eax+EXTFS.FSUserFunctions], ext_user_functions
221
 
221
 
222
        push    ebp esi edi
222
        push    ebp esi edi
223
        mov     ebp, eax
223
        mov     ebp, eax
224
        lea     ecx, [eax+EXTFS.Lock]
224
        lea     ecx, [eax+EXTFS.Lock]
225
        call    mutex_init
225
        call    mutex_init
226
        mov     esi, ebx
226
        mov     esi, ebx
227
        lea     edi, [ebp+EXTFS.superblock]
227
        lea     edi, [ebp+EXTFS.superblock]
228
        mov     ecx, 512/4
228
        mov     ecx, 512/4
229
        rep movsd   ; copy superblock
229
        rep movsd   ; copy superblock
230
        mov     ecx, [ebx+SUPERBLOCK.sectorsPerBlockLog]
230
        mov     ecx, [ebx+SUPERBLOCK.sectorsPerBlockLog]
231
        inc     ecx
231
        inc     ecx
232
        mov     [ebp+EXTFS.sectorsPerBlockLog], ecx
232
        mov     [ebp+EXTFS.sectorsPerBlockLog], ecx
233
        mov     eax, 1
233
        mov     eax, 1
234
        shl     eax, cl
234
        shl     eax, cl
235
        mov     [ebp+EXTFS.sectorsPerBlock], eax
235
        mov     [ebp+EXTFS.sectorsPerBlock], eax
236
        shl     eax, 9
236
        shl     eax, 9
237
        mov     [ebp+EXTFS.bytesPerBlock], eax
237
        mov     [ebp+EXTFS.bytesPerBlock], eax
238
        shl     eax, 1
238
        shl     eax, 1
239
        push    eax
239
        push    eax
240
        shr     eax, 3
240
        shr     eax, 3
241
        mov     [ebp+EXTFS.dwordsPerBlock], eax
241
        mov     [ebp+EXTFS.dwordsPerBlock], eax
242
        mul     eax
242
        mul     eax
243
        mov     [ebp+EXTFS.dwordsPerBranch], eax
243
        mov     [ebp+EXTFS.dwordsPerBranch], eax
244
        call    kernel_alloc
244
        call    kernel_alloc
245
        test    eax, eax
245
        test    eax, eax
246
        jz      .error
246
        jz      .error
247
        mov     [ebp+EXTFS.mainBlockBuffer], eax
247
        mov     [ebp+EXTFS.mainBlockBuffer], eax
248
        add     eax, [ebp+EXTFS.bytesPerBlock]
248
        add     eax, [ebp+EXTFS.bytesPerBlock]
249
        mov     [ebp+EXTFS.tempBlockBuffer], eax
249
        mov     [ebp+EXTFS.tempBlockBuffer], eax
250
        mov     [ebp+EXTFS.mountType], 0
250
        mov     [ebp+EXTFS.mountType], 0
251
        test    [ebx+SUPERBLOCK.RO_compatibleFlags], not READ_ONLY_SUPPORT
251
        test    [ebx+SUPERBLOCK.RO_compatibleFlags], not READ_ONLY_SUPPORT
252
        jnz     .read_only
252
        jnz     .read_only
253
        test    [ebx+SUPERBLOCK.incompatibleFlags], INCOMPATIBLE_READ_SUPPORT
253
        test    [ebx+SUPERBLOCK.incompatibleFlags], INCOMPATIBLE_READ_SUPPORT
254
        jz      @f
254
        jz      @f
255
.read_only:
255
.read_only:
256
        or      [ebp+EXTFS.mountType], READ_ONLY
256
        or      [ebp+EXTFS.mountType], READ_ONLY
257
@@: ; read root inode
257
@@: ; read root inode
258
        lea     ebx, [ebp+EXTFS.rootInodeBuffer]
258
        lea     ebx, [ebp+EXTFS.rootInodeBuffer]
259
        mov     eax, ROOT_INODE
259
        mov     eax, ROOT_INODE
260
        call    readInode
260
        call    readInode
261
        test    eax, eax
261
        test    eax, eax
262
        jnz     @f
262
        jnz     @f
263
        mov     eax, ebp
263
        mov     eax, ebp
264
        pop     edi esi ebp ebx
264
        pop     edi esi ebp ebx
265
        ret
265
        ret
266
 
266
 
267
@@:
267
@@:
268
        stdcall kernel_free, [ebp+EXTFS.mainBlockBuffer]
268
        stdcall kernel_free, [ebp+EXTFS.mainBlockBuffer]
269
.error:
269
.error:
270
        mov     eax, ebp
270
        mov     eax, ebp
271
        call    free
271
        call    free
272
        pop     edi esi ebp
272
        pop     edi esi ebp
273
.fail:
273
.fail:
274
        pop     ebx
274
        pop     ebx
275
        xor     eax, eax
275
        xor     eax, eax
276
        ret
276
        ret
277
 
277
 
278
; unmount EXT partition
278
; unmount EXT partition
279
ext_free:
279
ext_free:
280
; in: eax -> EXTFS structure
280
; in: eax -> EXTFS structure
281
        push    eax
281
        push    eax
282
        stdcall kernel_free, [eax+EXTFS.mainBlockBuffer]
282
        stdcall kernel_free, [eax+EXTFS.mainBlockBuffer]
283
        pop     eax
283
        pop     eax
284
        jmp     free
284
        jmp     free
285
 
285
 
286
extfsWriteBlock:
286
extfsWriteBlock:
287
        push    fs_write64_sys
287
        push    fs_write64_sys
288
        jmp     @f
288
        jmp     @f
289
;   in:
-
 
290
; eax = block number
289
; in: eax = block number, ebx -> buffer
291
; ebx -> buffer
-
 
292
extfsReadBlock:
290
extfsReadBlock:
293
        push    fs_read64_sys
291
        push    fs_read64_sys
294
@@:
292
@@:
295
        push    ecx edx
293
        push    ecx edx
296
        mov     ecx, [ebp+EXTFS.sectorsPerBlock]
294
        mov     ecx, [ebp+EXTFS.sectorsPerBlock]
297
        mul     ecx
295
        mul     ecx
298
        call    dword[esp+8]
296
        call    dword[esp+8]
299
        pop     edx ecx
297
        pop     edx ecx
300
        add     esp, 4
298
        add     esp, 4
301
        test    eax, eax
299
        test    eax, eax
302
        jz      @f
300
        jz      @f
303
        movi    eax, ERROR_DEVICE
301
        movi    eax, ERROR_DEVICE
304
        stc
302
        stc
305
@@:
303
@@:
306
        ret
304
        ret
307
 
305
 
308
extfsReadDescriptor:
306
extfsReadDescriptor:
309
; in: eax = block group number
307
; in: eax = block group number
310
;   out:
308
;   out:
311
; [ebp+EXTFS.tempBlockBuffer] -> relevant block
309
; [ebp+EXTFS.tempBlockBuffer] -> relevant block
312
; eax -> block group descriptor, 0 = error
310
; eax -> block group descriptor, 0 = error
313
        push    edx ebx
311
        push    edx ebx
314
        shl     eax, 5
312
        shl     eax, 5
315
        xor     edx, edx
313
        xor     edx, edx
316
        div     [ebp+EXTFS.bytesPerBlock]
314
        div     [ebp+EXTFS.bytesPerBlock]
317
        add     eax, [ebp+EXTFS.superblock.firstGroupBlock]
315
        add     eax, [ebp+EXTFS.superblock.firstGroupBlock]
318
        inc     eax
316
        inc     eax
319
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
317
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
320
        call    extfsReadBlock
318
        call    extfsReadBlock
321
        jc      .fail
319
        jc      .fail
322
        mov     eax, ebx
320
        mov     eax, ebx
323
        add     eax, edx
321
        add     eax, edx
324
@@:
322
@@:
325
        pop     ebx edx
323
        pop     ebx edx
326
        ret
324
        ret
327
 
325
 
328
.fail:
326
.fail:
329
        xor     eax, eax
327
        xor     eax, eax
330
        stc
328
        stc
331
        jmp     @b
329
        jmp     @b
332
 
330
 
333
extfsWriteDescriptor:
331
extfsWriteDescriptor:
334
;   in:
332
;   in:
335
; eax = block group number
333
; eax = block group number
336
; [ebp+EXTFS.tempBlockBuffer] -> relevant block
334
; [ebp+EXTFS.tempBlockBuffer] -> relevant block
337
        push    edx ebx
335
        push    edx ebx
338
        shl     eax, 5
336
        shl     eax, 5
339
        xor     edx, edx
337
        xor     edx, edx
340
        div     [ebp+EXTFS.bytesPerBlock]
338
        div     [ebp+EXTFS.bytesPerBlock]
341
        add     eax, [ebp+EXTFS.superblock.firstGroupBlock]
339
        add     eax, [ebp+EXTFS.superblock.firstGroupBlock]
342
        inc     eax
340
        inc     eax
343
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
341
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
344
        call    extfsWriteBlock
342
        call    extfsWriteBlock
345
        pop     ebx edx
343
        pop     ebx edx
346
        ret
344
        ret
347
 
345
 
348
extfsResourceFree:
346
extfsResourceFree:
349
;   in:
347
;   in:
350
; ecx=0 -> block, ecx=1 -> inode
348
; ecx=0 -> block, ecx=1 -> inode
351
; eax = block/inode number
349
; eax = block/inode number
352
        push    ebx edx
350
        push    ebx edx
353
        sub     eax, [ebp+EXTFS.superblock.firstGroupBlock]
351
        sub     eax, [ebp+EXTFS.superblock.firstGroupBlock]
354
        xor     edx, edx
352
        xor     edx, edx
355
        div     [ebp+EXTFS.superblock.blocksPerGroup]
353
        div     [ebp+EXTFS.superblock.blocksPerGroup]
356
        push    eax edx
354
        push    edx eax
357
        call    extfsReadDescriptor
355
        call    extfsReadDescriptor
358
        jc      .fail
356
        jc      .fail2
359
        inc     [eax+BGDESCR.blocksFree+ecx*2]
357
        inc     [eax+BGDESCR.blocksFree+ecx*2]
360
        mov     eax, [eax+BGDESCR.blockBitmap+ecx*4]
358
        mov     edx, [eax+BGDESCR.blockBitmap+ecx*4]
-
 
359
        pop     eax
361
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
360
        call    extfsWriteDescriptor
-
 
361
        jc      .fail
362
        mov     edx, eax
362
        mov     eax, edx
-
 
363
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
363
        call    extfsReadBlock
364
        call    extfsReadBlock
364
        jc      .fail
365
        jc      .fail
365
        pop     eax
366
        pop     eax
366
        push    edx
367
        push    edx
367
        mov     edx, eax
368
        mov     edx, eax
368
        and     edx, 31
369
        and     edx, 31
369
        shr     eax, 5
370
        shr     eax, 5
370
        shl     eax, 2
371
        shl     eax, 2
371
        add     eax, [ebp+EXTFS.mainBlockBuffer]
372
        add     eax, [ebp+EXTFS.tempBlockBuffer]
372
        btr     [eax], edx
373
        btr     [eax], edx
373
        pop     eax
374
        pop     eax
374
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
375
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
375
        call    extfsWriteBlock
376
        call    extfsWriteBlock
376
        jc      @f
377
        jc      @f
377
        inc     [ebp+EXTFS.superblock.blocksFree+ecx*4]
378
        inc     [ebp+EXTFS.superblock.blocksFree+ecx*4]
378
        pop     eax
-
 
379
        call    extfsWriteDescriptor
-
 
380
.ret:
379
@@:
381
        pop     edx ebx
380
        pop     edx ebx
382
        ret
381
        ret
383
 
382
 
384
.fail:
383
.fail2:
385
        pop     eax
384
        pop     eax
386
@@:
385
.fail:
387
        pop     eax
386
        pop     eax
388
        movi    eax, ERROR_DEVICE
387
        movi    eax, ERROR_DEVICE
389
        jmp     .ret
388
        jmp     @b
390
 
389
 
391
freeDoublyIndirectBlock:
390
freeDoublyIndirectBlock:
392
; in: eax = doubly-indirect block number
391
; in: eax = doubly-indirect block number
393
; out: eax=1 -> finished
392
; out: eax=1 -> finished
394
        test    eax, eax
393
        test    eax, eax
395
        jz      .complete
394
        jz      .complete
396
        push    eax
395
        push    eax
397
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
396
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
398
        call    extfsReadBlock
397
        call    extfsReadBlock
399
        pop     eax
398
        pop     eax
400
        jc      .ret
399
        jc      .ret
401
        xor     ecx, ecx
400
        xor     ecx, ecx
402
        call    extfsResourceFree
401
        call    extfsResourceFree
403
        mov     edx, ebx
402
        mov     edx, ebx
404
        add     edx, [ebp+EXTFS.bytesPerBlock]
403
        add     edx, [ebp+EXTFS.bytesPerBlock]
405
@@:
404
@@:
406
        mov     eax, [ebx]
405
        mov     eax, [ebx]
407
        test    eax, eax
406
        test    eax, eax
408
        jz      .complete
407
        jz      .complete
409
        call    extfsResourceFree
408
        call    extfsResourceFree
410
        add     ebx, 4
409
        add     ebx, 4
411
        cmp     ebx, edx
410
        cmp     ebx, edx
412
        jb      @b
411
        jb      @b
413
.ret:
412
.ret:
414
        xor     eax, eax
413
        xor     eax, eax
415
        ret
414
        ret
416
 
415
 
417
.complete:
416
.complete:
418
        inc     eax
417
        inc     eax
419
        ret
418
        ret
420
 
419
 
421
inodeBlockAlloc:
420
inodeBlockAlloc:    ; also erases
422
; in: esi -> inode, eax = inode number
421
; in: esi -> inode, eax = inode number
423
; out: ebx = block number
-
 
424
        call    extfsBlockAlloc
-
 
425
        jc      @f
-
 
426
        mov     eax, [ebp+EXTFS.sectorsPerBlock]
-
 
427
        add     [esi+INODE.sectorsUsed], eax
-
 
428
        xor     eax, eax
-
 
429
@@:
-
 
430
        ret
-
 
431
 
-
 
432
extfsBlockAlloc:    ; also erases
-
 
433
; in: eax = inode number
-
 
434
; out: ebx = block number
422
; out: ebx = block number
435
        xor     ebx, ebx
423
        xor     ebx, ebx
436
        call    extfsResourceAlloc
424
        call    extfsResourceAlloc
437
        jc      @f
425
        jc      @f
438
        push    ebx ecx edi
426
        push    ebx ecx edi
439
        mov     ecx, [ebp+EXTFS.dwordsPerBlock]
427
        mov     ecx, [ebp+EXTFS.dwordsPerBlock]
440
        mov     edi, [ebp+EXTFS.tempBlockBuffer]
428
        mov     edi, [ebp+EXTFS.tempBlockBuffer]
441
        mov     ebx, edi
429
        mov     ebx, edi
442
        xor     eax, eax
430
        xor     eax, eax
443
        rep stosd
431
        rep stosd
444
        pop     edi ecx
432
        pop     edi ecx eax
445
        mov     eax, [esp]
433
        push    eax
446
        call    extfsWriteBlock
434
        call    extfsWriteBlock
447
        pop     ebx
435
        pop     ebx
-
 
436
        jc      @f
-
 
437
        mov     eax, [ebp+EXTFS.sectorsPerBlock]
-
 
438
        add     [esi+INODE.sectorsUsed], eax
-
 
439
        xor     eax, eax
448
@@:
440
@@:
449
        ret
441
        ret
450
 
442
 
451
extfsResourceAlloc:
443
extfsResourceAlloc:
452
;   in:
444
;   in:
453
; eax = inode number
445
; eax = inode number
454
; ebx=0 -> block, ebx=1 -> inode
446
; ebx=0 -> block, ebx=1 -> inode
455
;   out:
447
;   out:
456
; ebx = block/inode number
448
; ebx = block/inode number
457
        push    ecx edx esi edi
449
        push    ecx edx esi edi
458
        dec     eax
450
        dec     eax
459
        xor     edx, edx
451
        xor     edx, edx
460
        div     [ebp+EXTFS.superblock.inodesPerGroup]
452
        div     [ebp+EXTFS.superblock.inodesPerGroup]
461
        push    eax eax
453
        push    eax eax
462
        mov     esi, .forward   ; search forward, then backward
454
        mov     esi, .forward   ; search forward, then backward
463
.test_block_group:
455
.test_block_group:
464
        call    extfsReadDescriptor
456
        call    extfsReadDescriptor
465
        jc      .fail
457
        jc      .fail
466
        dec     [eax+BGDESCR.blocksFree+ebx*2]
458
        dec     [eax+BGDESCR.blocksFree+ebx*2]
-
 
459
        js      .next
467
        mov     eax, [eax+BGDESCR.blockBitmap+ebx*4]
460
        mov     edx, [eax+BGDESCR.blockBitmap+ebx*4]
-
 
461
        mov     eax, [esp]
-
 
462
        call    extfsWriteDescriptor
-
 
463
        jc      .fail
468
        push    ebx
464
        push    ebx
469
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
465
        mov     eax, edx
470
        mov     edx, eax
466
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
471
        mov     edi, ebx
467
        mov     edi, ebx
472
        call    extfsReadBlock
468
        call    extfsReadBlock
473
        pop     ebx
469
        pop     ebx
474
        jc      .fail
470
        jc      .fail
475
        mov     ecx, [ebp+EXTFS.superblock.blocksPerGroup+ebx*8]
471
        mov     ecx, [ebp+EXTFS.superblock.blocksPerGroup+ebx*8]
476
        or      eax, -1
472
        or      eax, -1
477
        shr     ecx, 5
473
        shr     ecx, 5
478
        jz      .next
474
        jz      .next
479
        repz scasd
475
        repz scasd
480
        jz      .next
476
        jz      .next
481
        sub     edi, 4
477
        sub     edi, 4
482
        mov     eax, [edi]
478
        mov     eax, [edi]
483
        not     eax
479
        not     eax
484
        bsf     eax, eax
480
        bsf     eax, eax
485
        bts     [edi], eax
481
        bts     [edi], eax
486
        sub     edi, [ebp+EXTFS.mainBlockBuffer]
482
        sub     edi, [ebp+EXTFS.tempBlockBuffer]
487
        shl     edi, 3
483
        shl     edi, 3
488
        add     eax, edi
484
        add     eax, edi
489
        mov     ecx, eax
485
        mov     ecx, eax
490
        mov     eax, edx
486
        mov     eax, edx
491
        push    ebx
487
        push    ebx
492
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
488
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
493
        call    extfsWriteBlock
489
        call    extfsWriteBlock
494
        pop     ebx
490
        pop     ebx
495
        jc      .fail
491
        jc      .fail
496
        mov     eax, [esp]
492
        pop     eax
497
        mul     [ebp+EXTFS.superblock.blocksPerGroup+ebx*8]
493
        mul     [ebp+EXTFS.superblock.blocksPerGroup+ebx*8]
498
        add     eax, ecx
494
        add     eax, ecx
499
        dec     [ebp+EXTFS.superblock.blocksFree+ebx*4]
495
        dec     [ebp+EXTFS.superblock.blocksFree+ebx*4]
500
        mov     ebx, eax
496
        mov     ebx, eax
501
        pop     eax
497
        pop     eax
502
        add     esp, 4
498
        xor     eax, eax
503
        call    extfsWriteDescriptor
-
 
504
@@:
499
@@:
505
        pop     edi esi edx ecx
500
        pop     edi esi edx ecx
506
        ret
501
        ret
507
 
502
 
508
.fail:
503
.fail:
509
        pop     eax eax
504
        pop     eax eax
510
        movi    eax, ERROR_DEVICE
505
        movi    eax, ERROR_DEVICE
511
        jmp     @b
506
        jmp     @b
512
 
507
 
513
.next:
508
.next:
514
        jmp     esi
509
        jmp     esi
515
 
510
 
516
.forward:
511
.forward:
517
        inc     dword[esp]
512
        inc     dword[esp]
518
        mov     eax, [esp]
513
        mov     eax, [esp]
519
        mul     [ebp+EXTFS.superblock.blocksPerGroup+ebx*8]
514
        mul     [ebp+EXTFS.superblock.blocksPerGroup+ebx*8]
520
        neg     ebx
515
        neg     ebx
521
        cmp     eax, [ebp+EXTFS.superblock.blocksTotal+ebx*4]
516
        cmp     eax, [ebp+EXTFS.superblock.blocksTotal+ebx*4]
522
        ja      @f
517
        ja      @f
523
        neg     ebx
518
        neg     ebx
524
        mov     eax, [esp]
519
        mov     eax, [esp]
525
        jmp     .test_block_group
520
        jmp     .test_block_group
526
 
521
 
527
@@:
522
@@:
528
        neg     ebx
523
        neg     ebx
529
        mov     eax, [esp+4]
524
        mov     eax, [esp+4]
530
        mov     [esp], eax
525
        mov     [esp], eax
531
        mov     esi, .backward
526
        mov     esi, .backward
532
.backward:
527
.backward:
533
        sub     dword[esp], 1
528
        sub     dword[esp], 1
534
        jc      .fail
529
        jc      .fail
535
        mov     eax, [esp]
530
        mov     eax, [esp]
536
        jmp     .test_block_group
531
        jmp     .test_block_group
537
 
532
 
538
extfsGetFileBlock:
533
extfsGetFileBlock:
539
;   in:
-
 
540
; ecx = file block number
534
; in: esi -> inode, ecx = file block number
541
; esi -> inode
-
 
542
;   out:
-
 
543
; ecx = block number
535
; out: ecx = block number
544
        test    [esi+INODE.featureFlags], EXTENTS_USED
536
        test    [esi+INODE.featureFlags], EXTENTS_USED
545
        jz      .listTreeSearch
537
        jz      .listTreeSearch
546
        pushad
538
        pushad
547
        add     esi, INODE.blockNumbers
539
        add     esi, INODE.blockNumbers
548
.extentTreeSearch:
540
.extentTreeSearch:
549
        cmp     word [esi+NODEHEADER.magic], 0xF30A
541
        cmp     word [esi+NODEHEADER.magic], 0xF30A
550
        jne     .fail
542
        jne     .fail
551
        movzx   ebx, [esi+NODEHEADER.entriesFolow]
543
        movzx   ebx, [esi+NODEHEADER.entriesFolow]
552
        add     esi, sizeof.NODEHEADER
544
        add     esi, sizeof.NODEHEADER
553
        cmp     word [esi-sizeof.NODEHEADER+NODEHEADER.currentDepth], 0
545
        cmp     word [esi-sizeof.NODEHEADER+NODEHEADER.currentDepth], 0
554
        je      .leaf_block
546
        je      .leaf_block
555
        test    ebx, ebx
547
        test    ebx, ebx
556
        jz      .fail   ; empty
548
        jz      .fail   ; empty
557
@@:
549
@@:
558
        cmp     ebx, 1
550
        cmp     ebx, 1
559
        je      .end_search_index
551
        je      .end_search_index
560
        cmp     ecx, [esi+INDEX.fileBlock]
552
        cmp     ecx, [esi+INDEX.fileBlock]
561
        jb      .fail
553
        jb      .fail
562
        cmp     ecx, [esi+sizeof.INDEX+INDEX.fileBlock]
554
        cmp     ecx, [esi+sizeof.INDEX+INDEX.fileBlock]
563
        jb      .end_search_index
555
        jb      .end_search_index
564
        add     esi, sizeof.INDEX
556
        add     esi, sizeof.INDEX
565
        dec     ebx
557
        dec     ebx
566
        jmp     @b
558
        jmp     @b
567
 
559
 
568
.end_search_index:
560
.end_search_index:
569
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
561
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
570
        mov     eax, [esi+INDEX.nodeBlock]
562
        mov     eax, [esi+INDEX.nodeBlock]
571
        call    extfsReadBlock
563
        call    extfsReadBlock
572
        jc      .fail
564
        jc      .fail
573
        mov     esi, ebx
565
        mov     esi, ebx
574
        jmp     .extentTreeSearch
566
        jmp     .extentTreeSearch
575
 
567
 
576
.leaf_block:
568
.leaf_block:
577
        test    ebx, ebx
569
        test    ebx, ebx
578
        jz      .fail
570
        jz      .fail
579
        mov     edx, [esi+EXTENT.fileBlock]
571
        mov     edx, [esi+EXTENT.fileBlock]
580
        cmp     ecx, edx
572
        cmp     ecx, edx
581
        jb      .fail
573
        jb      .fail
582
        movzx   edi, [esi+EXTENT.blocksCount]
574
        movzx   edi, [esi+EXTENT.blocksCount]
583
        add     edx, edi
575
        add     edx, edi
584
        cmp     ecx, edx
576
        cmp     ecx, edx
585
        jb      .end_search_extent
577
        jb      .end_search_extent
586
        add     esi, sizeof.EXTENT
578
        add     esi, sizeof.EXTENT
587
        dec     ebx
579
        dec     ebx
588
        jmp     .leaf_block
580
        jmp     .leaf_block
589
 
581
 
590
.end_search_extent:
582
.end_search_extent:
591
        sub     ecx, [esi+EXTENT.fileBlock]
583
        sub     ecx, [esi+EXTENT.fileBlock]
592
        add     ecx, [esi+EXTENT.fsBlock]
584
        add     ecx, [esi+EXTENT.fsBlock]
593
        mov     PUSHAD_ECX, ecx
585
        mov     PUSHAD_ECX, ecx
594
        popad
586
        popad
595
        xor     eax, eax
587
        xor     eax, eax
596
        ret
588
        ret
597
 
589
 
598
.fail:
590
.fail:
599
        popad
591
        popad
600
        movi    eax, ERROR_FS_FAIL
592
        movi    eax, ERROR_FS_FAIL
601
        stc
593
        stc
602
        ret
594
        ret
603
 
595
 
604
.get_indirect_block:
596
.get_indirect_block:
605
        mov     eax, [esi+INODE.addressBlock]
597
        mov     eax, [esi+INODE.addressBlock]
606
        test    eax, eax
598
        test    eax, eax
607
        jz      .noBlock
599
        jz      .noBlock
608
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
600
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
609
        call    extfsReadBlock
601
        call    extfsReadBlock
610
        jc      .fail2
602
        jc      .fail2
611
        mov     ecx, [ebx+ecx*4]
603
        mov     ecx, [ebx+ecx*4]
612
        pop     ebx edx
604
        pop     ebx edx
613
        ret
605
        ret
614
 
606
 
615
.get_direct_block:
607
.get_direct_block:
616
        mov     ecx, [esi+INODE.blockNumbers+ecx*4]
608
        mov     ecx, [esi+INODE.blockNumbers+ecx*4]
617
        xor     eax, eax
609
        xor     eax, eax
618
        ret
610
        ret
619
 
611
 
620
.listTreeSearch:
612
.listTreeSearch:
621
        cmp     ecx, 12
613
        cmp     ecx, 12
622
        jb      .get_direct_block
614
        jb      .get_direct_block
623
        push    edx ebx
615
        push    edx ebx
624
        sub     ecx, 12
616
        sub     ecx, 12
625
        cmp     ecx, [ebp+EXTFS.dwordsPerBlock]
617
        cmp     ecx, [ebp+EXTFS.dwordsPerBlock]
626
        jb      .get_indirect_block
618
        jb      .get_indirect_block
627
        sub     ecx, [ebp+EXTFS.dwordsPerBlock]
619
        sub     ecx, [ebp+EXTFS.dwordsPerBlock]
628
        cmp     ecx, [ebp+EXTFS.dwordsPerBranch]
620
        cmp     ecx, [ebp+EXTFS.dwordsPerBranch]
629
        jb      .get_double_indirect_block
621
        jb      .get_double_indirect_block
630
; triply-indirect blocks
622
; triply-indirect blocks
631
        sub     ecx, [ebp+EXTFS.dwordsPerBranch]
623
        sub     ecx, [ebp+EXTFS.dwordsPerBranch]
632
        mov     eax, [esi+INODE.tripleAddress]
624
        mov     eax, [esi+INODE.tripleAddress]
633
        test    eax, eax
625
        test    eax, eax
634
        jz      .noBlock
626
        jz      .noBlock
635
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
627
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
636
        call    extfsReadBlock
628
        call    extfsReadBlock
637
        jc      .fail2
629
        jc      .fail2
638
        xor     edx, edx
630
        xor     edx, edx
639
        mov     eax, ecx
631
        mov     eax, ecx
640
        div     [ebp+EXTFS.dwordsPerBranch]
632
        div     [ebp+EXTFS.dwordsPerBranch]
641
; eax = number in triply-indirect block, edx = number in branch
633
; eax = number in triply-indirect block, edx = number in branch
642
        mov     eax, [ebx+eax*4]
634
        mov     eax, [ebx+eax*4]
643
        test    eax, eax
635
        test    eax, eax
644
        jz      .noBlock
636
        jz      .noBlock
645
        call    extfsReadBlock
637
        call    extfsReadBlock
646
        jc      .fail2
638
        jc      .fail2
647
        mov     eax, edx
639
        mov     eax, edx
648
        jmp     @f
640
        jmp     @f
649
 
641
 
650
.noBlock:
642
.noBlock:
651
        xor     ecx, ecx
643
        xor     ecx, ecx
652
.fail2:
644
.fail2:
653
        pop     ebx edx
645
        pop     ebx edx
654
        ret
646
        ret
655
 
647
 
656
.get_double_indirect_block:
648
.get_double_indirect_block:
657
        mov     eax, [esi+INODE.doubleAddress]
649
        mov     eax, [esi+INODE.doubleAddress]
658
        test    eax, eax
650
        test    eax, eax
659
        jz      .noBlock
651
        jz      .noBlock
660
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
652
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
661
        call    extfsReadBlock
653
        call    extfsReadBlock
662
        jc      .fail2
654
        jc      .fail2
663
        mov     eax, ecx
655
        mov     eax, ecx
664
@@:
656
@@:
665
        xor     edx, edx
657
        xor     edx, edx
666
        div     [ebp+EXTFS.dwordsPerBlock]
658
        div     [ebp+EXTFS.dwordsPerBlock]
667
; eax = number in doubly-indirect block, edx = number in indirect block
659
; eax = number in doubly-indirect block, edx = number in indirect block
668
        mov     eax, [ebx+eax*4]
660
        mov     eax, [ebx+eax*4]
669
        test    eax, eax
661
        test    eax, eax
670
        jz      .noBlock
662
        jz      .noBlock
671
        call    extfsReadBlock
663
        call    extfsReadBlock
672
        jc      .fail2
664
        jc      .fail2
673
        mov     ecx, [ebx+edx*4]
665
        mov     ecx, [ebx+edx*4]
674
        pop     ebx edx
666
        pop     ebx edx
675
        ret
667
        ret
676
 
668
 
677
extfsSetFileBlock:
669
extfsSetFileBlock:
678
;   in:
670
;   in:
679
; ecx = file block number
671
; ecx = file block number
680
; edi = block number
672
; edi = block number
681
; edx = inode number
673
; edx = inode number
682
; esi -> inode
674
; esi -> inode
683
        push    ebx ecx edx
675
        push    ebx ecx edx
684
        cmp     ecx, 12
676
        cmp     ecx, 12
685
        jb      .direct_block
677
        jb      .direct_block
686
        sub     ecx, 12
678
        sub     ecx, 12
687
        cmp     ecx, [ebp+EXTFS.dwordsPerBlock]
679
        cmp     ecx, [ebp+EXTFS.dwordsPerBlock]
688
        jb      .indirect_block
680
        jb      .indirect_block
689
        sub     ecx, [ebp+EXTFS.dwordsPerBlock]
681
        sub     ecx, [ebp+EXTFS.dwordsPerBlock]
690
        cmp     ecx, [ebp+EXTFS.dwordsPerBranch]
682
        cmp     ecx, [ebp+EXTFS.dwordsPerBranch]
691
        jb      .double_indirect_block
683
        jb      .double_indirect_block
692
; triple indirect blocks
684
; triple indirect blocks
693
        sub     ecx, [ebp+EXTFS.dwordsPerBranch]
685
        sub     ecx, [ebp+EXTFS.dwordsPerBranch]
694
        mov     eax, [esi+INODE.tripleAddress]
686
        mov     eax, [esi+INODE.tripleAddress]
695
        test    eax, eax
687
        test    eax, eax
696
        jnz     @f
688
        jnz     @f
697
        mov     eax, edx
689
        mov     eax, edx
698
        call    inodeBlockAlloc
690
        call    inodeBlockAlloc
699
        jc      .ret
691
        jc      .ret
700
        mov     [esi+INODE.tripleAddress], ebx
692
        mov     [esi+INODE.tripleAddress], ebx
701
        mov     eax, ebx
693
        mov     eax, ebx
702
@@:
694
@@:
703
        push    eax
695
        push    eax
704
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
696
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
705
        call    extfsReadBlock
697
        call    extfsReadBlock
706
        jc      .fail_alloc_4
698
        jc      .fail_alloc_4
707
        xor     edx, edx
699
        xor     edx, edx
708
        mov     eax, ecx
700
        mov     eax, ecx
709
        div     [ebp+EXTFS.dwordsPerBranch]
701
        div     [ebp+EXTFS.dwordsPerBranch]
710
; eax = number in triply-indirect block, edx = number in branch
702
; eax = number in triply-indirect block, edx = number in branch
711
        lea     ecx, [ebx+eax*4]
703
        lea     ecx, [ebx+eax*4]
712
        mov     eax, [ebx+eax*4]
704
        mov     eax, [ebx+eax*4]
713
        test    eax, eax
705
        test    eax, eax
714
        jnz     @f
706
        jnz     @f
715
        mov     eax, [esp+4]
707
        mov     eax, [esp+4]
716
        call    inodeBlockAlloc
708
        call    inodeBlockAlloc
717
        jc      .fail_alloc_4
709
        jc      .fail_alloc_4
718
        mov     [ecx], ebx
710
        mov     [ecx], ebx
719
        mov     eax, [esp]
711
        mov     eax, [esp]
720
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
712
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
721
        call    extfsWriteBlock
713
        call    extfsWriteBlock
722
        jc      .fail_alloc_4
714
        jc      .fail_alloc_4
723
        mov     eax, [ecx]
715
        mov     eax, [ecx]
724
@@:
716
@@:
725
        mov     [esp], eax
717
        mov     [esp], eax
726
        call    extfsReadBlock
718
        call    extfsReadBlock
727
        jc      .fail_alloc_4
719
        jc      .fail_alloc_4
728
        mov     eax, edx
720
        mov     eax, edx
729
        jmp     @f
721
        jmp     @f
730
 
722
 
731
.double_indirect_block:
723
.double_indirect_block:
732
        mov     eax, [esi+INODE.doubleAddress]
724
        mov     eax, [esi+INODE.doubleAddress]
733
        test    eax, eax
725
        test    eax, eax
734
        jnz     .double_indirect_present
726
        jnz     .double_indirect_present
735
        mov     eax, edx
727
        mov     eax, edx
736
        call    inodeBlockAlloc
728
        call    inodeBlockAlloc
737
        jc      .ret
729
        jc      .ret
738
        mov     [esi+INODE.doubleAddress], ebx
730
        mov     [esi+INODE.doubleAddress], ebx
739
        mov     eax, ebx
731
        mov     eax, ebx
740
.double_indirect_present:
732
.double_indirect_present:
741
        push    eax
733
        push    eax
742
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
734
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
743
        call    extfsReadBlock
735
        call    extfsReadBlock
744
        jc      .fail_alloc_4
736
        jc      .fail_alloc_4
745
        mov     eax, ecx
737
        mov     eax, ecx
746
@@:
738
@@:
747
        xor     edx, edx
739
        xor     edx, edx
748
        div     [ebp+EXTFS.dwordsPerBlock]
740
        div     [ebp+EXTFS.dwordsPerBlock]
749
; eax = number in doubly-indirect block, edx = number in indirect block
741
; eax = number in doubly-indirect block, edx = number in indirect block
750
        lea     ecx, [ebx+edx*4]
742
        lea     ecx, [ebx+edx*4]
751
        push    ecx
743
        push    ecx
752
        lea     ecx, [ebx+eax*4]
744
        lea     ecx, [ebx+eax*4]
753
        cmp     dword[ecx], 0
745
        cmp     dword[ecx], 0
754
        jne     @f
746
        jne     @f
755
        mov     eax, [esp+8]
747
        mov     eax, [esp+8]
756
        call    inodeBlockAlloc
748
        call    inodeBlockAlloc
757
        jc      .fail_alloc_8
749
        jc      .fail_alloc_8
758
        mov     [ecx], ebx
750
        mov     [ecx], ebx
759
        mov     eax, [esp+4]
751
        mov     eax, [esp+4]
760
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
752
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
761
        call    extfsWriteBlock
753
        call    extfsWriteBlock
762
        jc      .fail_alloc_8
754
        jc      .fail_alloc_8
763
@@:
755
@@:
764
        mov     eax, [ecx]
756
        mov     eax, [ecx]
765
        push    eax
757
        push    eax
766
        call    extfsReadBlock
758
        call    extfsReadBlock
767
        jc      .fail_alloc_12
759
        jc      .fail_alloc_12
768
        pop     eax ecx edx
760
        pop     eax ecx edx
769
        mov     [ecx], edi
761
        mov     [ecx], edi
770
        call    extfsWriteBlock
762
        call    extfsWriteBlock
771
        jmp     .ret
763
        jmp     .ret
772
 
764
 
773
.indirect_block:
765
.indirect_block:
774
        mov     eax, [esi+INODE.addressBlock]
766
        mov     eax, [esi+INODE.addressBlock]
775
        test    eax, eax
767
        test    eax, eax
776
        jnz     @f
768
        jnz     @f
777
        mov     eax, edx
769
        mov     eax, edx
778
        call    inodeBlockAlloc
770
        call    inodeBlockAlloc
779
        jc      .ret
771
        jc      .ret
780
        mov     [esi+INODE.addressBlock], ebx
772
        mov     [esi+INODE.addressBlock], ebx
781
        mov     eax, ebx
773
        mov     eax, ebx
782
@@:
774
@@:
783
        push    eax
775
        push    eax
784
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
776
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
785
        call    extfsReadBlock
777
        call    extfsReadBlock
786
        jc      .fail_alloc_4
778
        jc      .fail_alloc_4
787
        mov     [ebx+ecx*4], edi
779
        mov     [ebx+ecx*4], edi
788
        pop     eax
780
        pop     eax
789
        call    extfsWriteBlock
781
        call    extfsWriteBlock
790
        jmp     .ret
782
        jmp     .ret
791
 
783
 
792
.direct_block:
784
.direct_block:
793
        mov     [esi+INODE.blockNumbers+ecx*4], edi
785
        mov     [esi+INODE.blockNumbers+ecx*4], edi
794
        xor     eax, eax
786
        xor     eax, eax
795
.ret:
787
.ret:
796
        pop     edx ecx ebx
788
        pop     edx ecx ebx
797
        ret
789
        ret
798
 
790
 
799
.fail_alloc_12:
791
.fail_alloc_12:
800
        pop     ebx
792
        pop     ebx
801
.fail_alloc_8:
793
.fail_alloc_8:
802
        pop     ebx
794
        pop     ebx
803
.fail_alloc_4:
795
.fail_alloc_4:
804
        pop     ebx
796
        pop     ebx
805
        jmp     .ret
797
        jmp     .ret
806
 
798
 
807
extfsEraseFileBlock:    ; also allocates
799
extfsFileBlockAlloc:
-
 
800
;   in:
808
;   in:
801
; esi -> inode
809
; edx = inode number
802
; edx = inode number
810
; eax = file block number
803
; eax = file block number
811
; [ebp+EXTFS.inodeBuffer] = inode
804
;   out:
812
        push    ebx ecx edx edi esi
805
; edi = allocated block number
813
        mov     edi, eax
806
        push    ebx ecx
814
        mov     ecx, eax
-
 
815
        lea     esi, [ebp+EXTFS.inodeBuffer]
-
 
816
        call    extfsGetFileBlock
-
 
817
        jc      @f
-
 
818
        test    ecx, ecx
-
 
819
        jz      .allocate
-
 
820
        mov     edx, ecx
-
 
821
        mov     ecx, [ebp+EXTFS.bytesPerBlock]
-
 
822
        mov     edi, [ebp+EXTFS.tempBlockBuffer]
-
 
823
        xor     eax, eax
-
 
824
        rep stosb
807
        mov     ecx, eax
825
        mov     eax, edx
-
 
826
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
-
 
827
        call    extfsWriteBlock
-
 
828
        jmp     @f
-
 
829
 
-
 
830
.allocate:
808
        mov     eax, edx
831
        mov     eax, edx
809
        xor     ebx, ebx
832
        call    extfsBlockAlloc
810
        call    extfsResourceAlloc
833
        jc      @f
-
 
834
        mov     ecx, edi
811
        jc      @f
835
        mov     edi, ebx
-
 
836
        lea     esi, [ebp+EXTFS.inodeBuffer]
812
        mov     edi, ebx
837
        call    extfsSetFileBlock
813
        call    extfsSetFileBlock
838
        jc      @f
814
        jc      @f
839
        mov     eax, [ebp+EXTFS.sectorsPerBlock]
815
        mov     eax, [ebp+EXTFS.sectorsPerBlock]
840
        add     [esi+INODE.sectorsUsed], eax
816
        add     [esi+INODE.sectorsUsed], eax
841
        xor     eax, eax
817
        xor     eax, eax
842
@@:
818
@@:
843
        pop     esi edi edx ecx ebx
-
 
844
        ret
-
 
845
 
-
 
846
extfsFreeFileBlock:
-
 
847
;   in:
-
 
848
; eax = file block number
-
 
849
; [ebp+EXTFS.inodeBuffer] = inode
-
 
850
        push    ebx ecx edx edi esi
-
 
851
        mov     edi, eax
-
 
852
        mov     ecx, eax
819
        pop     ecx ebx
853
        lea     esi, [ebp+EXTFS.inodeBuffer]
-
 
854
        call    extfsGetFileBlock
-
 
855
        jc      @f
-
 
856
        test    ecx, ecx
-
 
857
        jz      @f
-
 
858
        mov     eax, ecx
-
 
859
        xor     ecx, ecx
-
 
860
        call    extfsResourceFree
-
 
861
        mov     ecx, edi
-
 
862
        xor     edi, edi
-
 
863
        movi    edx, ROOT_INODE
-
 
864
        lea     esi, [ebp+EXTFS.inodeBuffer]
-
 
865
        call    extfsSetFileBlock
-
 
866
        mov     eax, [ebp+EXTFS.sectorsPerBlock]
-
 
867
        sub     [esi+INODE.sectorsUsed], eax
-
 
868
        xor     eax, eax
-
 
869
@@:
-
 
870
        pop     esi edi edx ecx ebx
-
 
871
        ret
820
        ret
872
 
821
 
873
extfsReadFileBlock:
822
extfsReadFileBlock:
874
;   in:
823
;   in:
875
; eax = file block number
824
; eax = file block number
876
; [ebp+EXTFS.inodeBuffer] = inode
825
; [ebp+EXTFS.inodeBuffer] = inode
877
;   out:
826
;   out:
878
; [ebp+EXTFS.mainBlockBuffer] -> block
827
; [ebp+EXTFS.mainBlockBuffer] -> block
879
        push    ebx ecx edx esi
828
        push    ebx ecx edx esi
880
        mov     ecx, eax
829
        mov     ecx, eax
881
        lea     esi, [ebp+EXTFS.inodeBuffer]
830
        lea     esi, [ebp+EXTFS.inodeBuffer]
882
        call    extfsGetFileBlock
831
        call    extfsGetFileBlock
883
        jc      .ret
832
        jc      .ret
884
        test    ecx, ecx
833
        test    ecx, ecx
885
        jz      @f
834
        jz      @f
886
        mov     eax, ecx
835
        mov     eax, ecx
887
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
836
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
888
        call    extfsReadBlock
837
        call    extfsReadBlock
889
.ret:
838
.ret:
890
        pop     esi edx ecx ebx
839
        pop     esi edx ecx ebx
891
        ret
840
        ret
892
 
841
 
893
@@:
842
@@:
894
        movi    eax, ERROR_FS_FAIL
843
        movi    eax, ERROR_FS_FAIL
895
        stc
844
        stc
896
        jmp     .ret
845
        jmp     .ret
897
 
846
 
898
extfsWriteFileBlock:
847
extfsWriteFileBlock:
899
;   in:
848
;   in:
900
; eax = file block number
849
; eax = file block number
-
 
850
; ebx -> data
901
; [ebp+EXTFS.inodeBuffer] = inode
851
; [ebp+EXTFS.inodeBuffer] = inode
902
; [ebp+EXTFS.mainBlockBuffer] -> block to write
-
 
903
        push    ebx ecx edx esi
852
        push    ecx edx esi
904
        mov     ecx, eax
853
        mov     ecx, eax
905
        lea     esi, [ebp+EXTFS.inodeBuffer]
854
        lea     esi, [ebp+EXTFS.inodeBuffer]
906
        call    extfsGetFileBlock
855
        call    extfsGetFileBlock
907
        jc      @f
856
        jc      @f
908
        test    ecx, ecx
857
        test    ecx, ecx
909
        jz      @b
858
        jz      @b
910
        mov     eax, ecx
859
        mov     eax, ecx
911
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
-
 
912
        call    extfsWriteBlock
860
        call    extfsWriteBlock
913
@@:
861
@@:
914
        pop     esi edx ecx ebx
862
        pop     esi edx ecx
915
        ret
863
        ret
916
 
864
 
917
getInodeLocation:
865
getInodeLocation:
918
; in: eax = inode number
866
; in: eax = inode number
919
;   out:
-
 
920
; ebx = inode sector
-
 
921
; edx = offset in sector
867
; out: ebx = inode sector, edx = offset in sector
922
        dec     eax
868
        dec     eax
923
        xor     edx, edx
869
        xor     edx, edx
924
        div     [ebp+EXTFS.superblock.inodesPerGroup]
870
        div     [ebp+EXTFS.superblock.inodesPerGroup]
925
        mov     ecx, edx
871
        mov     ecx, edx
926
        shl     eax, 5
872
        shl     eax, 5
927
        xor     edx, edx
873
        xor     edx, edx
928
        div     [ebp+EXTFS.bytesPerBlock]
874
        div     [ebp+EXTFS.bytesPerBlock]
929
        add     eax, [ebp+EXTFS.superblock.firstGroupBlock]
875
        add     eax, [ebp+EXTFS.superblock.firstGroupBlock]
930
        inc     eax
876
        inc     eax
931
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
877
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
932
        call    extfsReadBlock
878
        call    extfsReadBlock
933
        jc      @f
879
        jc      @f
934
        add     ebx, edx
880
        add     ebx, edx
935
        mov     ebx, [ebx+BGDESCR.inodeTable]
881
        mov     ebx, [ebx+BGDESCR.inodeTable]
936
        mov     eax, ecx
882
        mov     eax, ecx
937
        mov     ecx, [ebp+EXTFS.sectorsPerBlockLog]
883
        mov     ecx, [ebp+EXTFS.sectorsPerBlockLog]
938
        shl     ebx, cl
884
        shl     ebx, cl
939
        mul     [ebp+EXTFS.superblock.inodeSize]
885
        mul     [ebp+EXTFS.superblock.inodeSize]
940
        mov     edx, eax
886
        mov     edx, eax
941
        shr     eax, 9
887
        shr     eax, 9
942
        and     edx, 511
888
        and     edx, 511
943
        add     ebx, eax
889
        add     ebx, eax
944
        xor     eax, eax
890
        xor     eax, eax
945
@@:
891
@@:
946
        ret
892
        ret
947
 
893
 
948
writeInode:
894
writeInode:
949
;   in:
-
 
950
; eax = inode number
895
; in: eax = inode number, ebx -> inode data
951
; ebx -> inode data
-
 
952
        push    edx edi esi ecx ebx eax
896
        push    edx edi esi ecx ebx eax
953
        mov     edi, ebx
897
        mov     edi, ebx
954
        call    fsGetTime
898
        call    fsGetTime
955
        add     eax, 978307200
899
        add     eax, 978307200
956
        mov     [edi+INODE.inodeModified], eax
900
        mov     [edi+INODE.inodeModified], eax
957
        pop     eax
901
        pop     eax
958
        call    getInodeLocation
902
        call    getInodeLocation
959
        jc      .ret
903
        jc      .ret
960
        mov     eax, ebx
904
        mov     eax, ebx
961
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
905
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
962
        mov     ecx, eax
906
        mov     ecx, eax
963
        call    fs_read32_sys
907
        call    fs_read32_sys
964
        test    eax, eax
908
        test    eax, eax
965
        jnz     @f
909
        jnz     @f
966
        mov     eax, ecx
910
        mov     eax, ecx
967
        mov     esi, edi
911
        mov     esi, edi
968
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
912
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
969
        mov     edi, edx
913
        mov     edi, edx
970
        add     edi, ebx
914
        add     edi, ebx
971
        rep movsb
915
        rep movsb
972
        call    fs_write32_sys
916
        call    fs_write32_sys
973
.ret:
917
.ret:
974
        pop     ebx ecx esi edi edx
918
        pop     ebx ecx esi edi edx
975
        ret
919
        ret
976
 
920
 
977
@@:
921
@@:
978
        movi    eax, ERROR_DEVICE
922
        movi    eax, ERROR_DEVICE
979
        stc
923
        stc
980
        jmp     .ret
924
        jmp     .ret
981
 
925
 
982
readInode:
926
readInode:
983
;   in:
-
 
984
; eax = inode number
-
 
985
; ebx -> inode buffer
927
; in: eax = inode number, ebx -> inode buffer
986
        push    edx edi esi ecx ebx
928
        push    edx edi esi ecx ebx
987
        mov     edi, ebx
929
        mov     edi, ebx
988
        call    getInodeLocation
930
        call    getInodeLocation
989
        jc      @f
931
        jc      @f
990
        mov     eax, ebx
932
        mov     eax, ebx
991
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
933
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
992
        call    fs_read32_sys
934
        call    fs_read32_sys
993
        test    eax, eax
935
        test    eax, eax
994
        jnz     @b
936
        jnz     @b
995
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
937
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
996
        mov     esi, edx
938
        mov     esi, edx
997
        add     esi, ebx
939
        add     esi, ebx
998
        rep movsb
940
        rep movsb
999
        xor     eax, eax
941
        xor     eax, eax
1000
@@:
942
@@:
1001
        pop     ebx ecx esi edi edx
943
        pop     ebx ecx esi edi edx
1002
        ret
944
        ret
1003
 
945
 
1004
extfsExtendFile:
946
extfsExtendFile:
1005
;   in:
947
;   in:
1006
; [ebp+EXTFS.inodeBuffer] = inode
948
; [ebp+EXTFS.inodeBuffer] = inode
1007
; eax = inode number
949
; eax = inode number
1008
; ecx = new size
950
; ecx = new size
1009
        push    ebx ecx edx esi edi eax
951
        push    ebx ecx edx esi edi eax
1010
        lea     ebx, [ebp+EXTFS.inodeBuffer]
952
        lea     esi, [ebp+EXTFS.inodeBuffer]
1011
        cmp     [ebx+INODE.fileSize], ecx
-
 
1012
        jnc     .ret
-
 
1013
        mov     eax, [ebx+INODE.fileSize]
953
        mov     eax, [esi+INODE.fileSize]
1014
        push    eax
-
 
1015
        sub     ecx, eax
954
        sub     ecx, eax
-
 
955
        jna     .ret
-
 
956
        mov     ebx, eax
1016
        xor     edx, edx
957
        xor     edx, edx
1017
        div     [ebp+EXTFS.bytesPerBlock]
958
        div     [ebp+EXTFS.bytesPerBlock]
1018
        test    edx, edx
959
        test    edx, edx
1019
        jz      .start_aligned
960
        jz      .start_aligned
1020
        mov     esi, [ebp+EXTFS.bytesPerBlock]
961
        mov     eax, [ebp+EXTFS.bytesPerBlock]
1021
        sub     esi, edx
962
        sub     eax, edx
1022
        cmp     esi, ecx
963
        cmp     eax, ecx
1023
        jbe     @f
964
        jbe     @f
1024
        mov     esi, ecx
965
        mov     eax, ecx
1025
@@: ; clear esi trailing bytes in block number eax
-
 
1026
        push    eax
-
 
1027
        call    extfsReadFileBlock
-
 
1028
        pop     edi
966
@@:
1029
        jc      .error_inode_size
-
 
1030
        push    edi ecx
-
 
1031
        xor     eax, eax
-
 
1032
        mov     ecx, esi
-
 
1033
        mov     edi, ebx
-
 
1034
        add     edi, edx
967
        add     ebx, eax
1035
        rep stosb
-
 
1036
        pop     ecx eax
-
 
1037
        call    extfsWriteFileBlock
-
 
1038
        jc      .error_inode_size
-
 
1039
        add     [esp], esi
-
 
1040
        sub     ecx, esi
968
        sub     ecx, eax
1041
        jz      .done
969
        jz      .done
1042
.start_aligned:
970
.start_aligned:
1043
        cmp     ecx, [ebp+EXTFS.bytesPerBlock]
-
 
1044
        jb      @f
-
 
1045
        mov     eax, [esp]
971
        mov     eax, ebx
1046
        xor     edx, edx
972
        xor     edx, edx
1047
        div     [ebp+EXTFS.bytesPerBlock]
973
        div     [ebp+EXTFS.bytesPerBlock]
1048
        mov     edx, [esp+4]
974
        mov     edx, [esp]
1049
        call    extfsEraseFileBlock
975
        call    extfsFileBlockAlloc
1050
        jc      .error_inode_size
976
        jc      .error
1051
        mov     eax, [ebp+EXTFS.bytesPerBlock]
977
        mov     eax, [ebp+EXTFS.bytesPerBlock]
-
 
978
        add     ebx, eax
1052
        sub     ecx, eax
979
        sub     ecx, eax
1053
        add     [esp], eax
-
 
1054
        jmp     .start_aligned
980
        ja      .start_aligned
1055
 
-
 
1056
@@: ; handle the remaining bytes
-
 
1057
        test    ecx, ecx
-
 
1058
        jz      .done
-
 
1059
        mov     eax, [esp]
-
 
1060
        xor     edx, edx
-
 
1061
        div     [ebp+EXTFS.bytesPerBlock]
-
 
1062
        mov     edx, [esp+4]
-
 
1063
        call    extfsEraseFileBlock
-
 
1064
        jc      .error_inode_size
-
 
1065
        add     [esp], ecx
981
        add     ebx, ecx
1066
.done:
982
.done:
1067
        xor     eax, eax
983
        xor     eax, eax
1068
.error_inode_size:
984
.error:
1069
        lea     ebx, [ebp+EXTFS.inodeBuffer]
-
 
1070
        pop     [ebx+INODE.fileSize]
985
        mov     [esi+INODE.fileSize], ebx
1071
.ret:
986
.ret:
1072
        pop     edi edi esi edx ecx ebx
987
        pop     edi edi esi edx ecx ebx
1073
        ret
988
        ret
1074
 
989
 
1075
extfsTruncateFile:
990
extfsTruncateFile:
1076
;   in:
991
;   in:
1077
; [ebp+EXTFS.inodeBuffer] = inode
992
; [ebp+EXTFS.inodeBuffer] = inode
1078
; ecx = new size
993
; ecx = new size
1079
        push    ebx ecx edx esi edi
994
        push    ebx ecx edx esi edi
1080
        lea     ebx, [ebp+EXTFS.inodeBuffer]
995
        lea     esi, [ebp+EXTFS.inodeBuffer]
1081
        cmp     ecx, [ebx+INODE.fileSize]
-
 
1082
        jnc     .ret
-
 
1083
        mov     eax, [ebx+INODE.fileSize]
996
        mov     eax, [esi+INODE.fileSize]
1084
        push    eax
-
 
1085
        sub     ecx, eax
997
        sub     ecx, eax
1086
        not     ecx
998
        jnc     .ret
1087
        inc     ecx
999
        neg     ecx
-
 
1000
        mov     ebx, eax
1088
        xor     edx, edx
1001
        xor     edx, edx
1089
        div     [ebp+EXTFS.bytesPerBlock]
1002
        div     [ebp+EXTFS.bytesPerBlock]
1090
        test    edx, edx
1003
        test    edx, edx
1091
        jz      .start_aligned
-
 
1092
        mov     esi, edx
-
 
1093
        cmp     esi, ecx
-
 
1094
        jbe     @f
1004
        jnz     @f
1095
; if the size to truncate is smaller than the unaligned bytes
-
 
1096
; we're going to clear neccessary bytes from the EOF
-
 
1097
        push    eax
-
 
1098
        call    extfsReadFileBlock
-
 
1099
        pop     edi
-
 
1100
        jc      .error_inode_size
-
 
1101
        push    edi ecx
-
 
1102
        mov     edi, [ebp+EXTFS.mainBlockBuffer]
-
 
1103
        sub     edx, ecx
-
 
1104
        add     edi, edx
-
 
1105
        xor     eax, eax
-
 
1106
        rep stosb
-
 
1107
        pop     ecx eax
-
 
1108
        call    extfsWriteFileBlock
-
 
1109
        jc      .error_inode_size
-
 
1110
        sub     [esp], ecx
-
 
1111
        jmp     .done
-
 
1112
 
-
 
1113
@@:
-
 
1114
        call    extfsFreeFileBlock
-
 
1115
        sub     [esp], esi
-
 
1116
        sub     ecx, esi
-
 
1117
        jz      .done
-
 
1118
.start_aligned:
1005
.start_aligned:
1119
        cmp     ecx, [ebp+EXTFS.bytesPerBlock]
1006
        mov     edx, [ebp+EXTFS.bytesPerBlock]
1120
        jb      @f
-
 
1121
        mov     eax, [esp]
-
 
1122
        xor     edx, edx
-
 
1123
        div     [ebp+EXTFS.bytesPerBlock]
-
 
1124
        dec     eax
1007
        dec     eax
-
 
1008
@@:
1125
        call    extfsFreeFileBlock
1009
        cmp     ecx, edx
1126
        mov     eax, [ebp+EXTFS.bytesPerBlock]
1010
        jc      .tail
1127
        sub     ecx, eax
1011
        push    ecx edx
1128
        sub     [esp], eax
1012
        mov     edi, eax
1129
        jmp     .start_aligned
1013
        mov     ecx, eax
1130
 
-
 
1131
@@: ; handle the remaining bytes
1014
        call    extfsGetFileBlock
-
 
1015
        jc      .error
1132
        test    ecx, ecx
1016
        test    ecx, ecx
-
 
1017
        jz      @f
-
 
1018
        mov     eax, ecx
-
 
1019
        xor     ecx, ecx
-
 
1020
        call    extfsResourceFree
-
 
1021
        mov     ecx, edi
-
 
1022
        xor     edi, edi
-
 
1023
        movi    edx, ROOT_INODE
-
 
1024
        call    extfsSetFileBlock
-
 
1025
        mov     eax, [ebp+EXTFS.sectorsPerBlock]
-
 
1026
        sub     [esi+INODE.sectorsUsed], eax
-
 
1027
@@:
-
 
1028
        pop     edx ecx
-
 
1029
        sub     ebx, edx
-
 
1030
        sub     ecx, edx
1133
        jz      .done
1031
        jz      .done
1134
        mov     eax, [esp]
1032
        mov     eax, ebx
1135
        xor     edx, edx
1033
        xor     edx, edx
1136
        div     [ebp+EXTFS.bytesPerBlock]
1034
        div     [ebp+EXTFS.bytesPerBlock]
1137
        dec     eax
-
 
1138
        push    eax
-
 
1139
        call    extfsReadFileBlock
1035
        jmp     .start_aligned
1140
        pop     edi
-
 
-
 
1036
 
1141
        jc      .error_inode_size
1037
.tail:      ; handle the remaining bytes
1142
        push    edi ecx
-
 
1143
        mov     edi, [ebp+EXTFS.mainBlockBuffer]
-
 
1144
        mov     edx, [ebp+EXTFS.bytesPerBlock]
-
 
1145
        sub     edx, ecx
1038
        sub     ebx, ecx
1146
        add     edi, edx
-
 
1147
        xor     eax, eax
-
 
1148
        rep stosb
-
 
1149
        pop     ecx eax
-
 
1150
        call    extfsWriteFileBlock
-
 
1151
        jc      .error_inode_size
-
 
1152
        sub     [esp], ecx
-
 
1153
.done:
1039
.done:
1154
        xor     eax, eax
1040
        xor     eax, eax
1155
.error_inode_size:
1041
@@:
1156
        lea     ebx, [ebp+EXTFS.inodeBuffer]
-
 
1157
        pop     [ebx+INODE.fileSize]
1042
        mov     [esi+INODE.fileSize], ebx
1158
.ret:
1043
.ret:
1159
        pop     edi esi edx ecx ebx
1044
        pop     edi esi edx ecx ebx
1160
        ret
1045
        ret
-
 
1046
 
-
 
1047
.error:
-
 
1048
        pop     edx ecx
-
 
1049
        jmp     @b
-
 
1050
 
1161
 
1051
 
1162
linkInode:
1052
linkInode:
1163
;   in:
1053
;   in:
1164
; eax = inode on which to link
1054
; eax = inode on which to link
1165
; ebx = inode to link
1055
; ebx = inode to link
1166
; esi -> name in UTF-8
1056
; esi -> name in UTF-8
1167
;  dl = file type
1057
;  dl = file type
1168
        push    esi edi ebx ecx eax edx
1058
        push    esi edi ebx ecx eax edx
1169
        call    strlen
1059
        call    strlen
1170
        add     ecx, 8  ; directory entry size
1060
        add     ecx, 8  ; directory entry size
1171
        push    esi ebx ecx
1061
        push    esi ebx ecx
1172
        xor     ecx, ecx
1062
        xor     ecx, ecx
1173
        lea     esi, [ebp+EXTFS.inodeBuffer]
1063
        lea     esi, [ebp+EXTFS.inodeBuffer]
1174
        mov     ebx, esi
1064
        mov     ebx, esi
1175
        call    readInode
1065
        call    readInode
1176
        jc      .error_inode_read
1066
        jc      .error_inode_read
1177
        mov     ecx, [ebp+EXTFS.sectorsPerBlockLog]
1067
        mov     ecx, [ebp+EXTFS.sectorsPerBlockLog]
1178
        mov     eax, [esi+INODE.sectorsUsed]
1068
        mov     eax, [esi+INODE.sectorsUsed]
1179
        shr     eax, cl
1069
        shr     eax, cl
1180
        xor     ecx, ecx
1070
        xor     ecx, ecx
1181
.searchBlock:
1071
.searchBlock:
1182
        push    eax     ; blocks total
1072
        push    eax     ; blocks total
1183
        push    ecx     ; current file block number
1073
        push    ecx     ; current file block number
1184
        cmp     eax, ecx
1074
        cmp     eax, ecx
1185
        jz      .alloc_block
1075
        jz      .alloc_block
1186
        call    extfsGetFileBlock
1076
        call    extfsGetFileBlock
1187
        jc      .error_get_inode_block
1077
        jc      .error_get_inode_block
1188
        test    ecx, ecx
1078
        test    ecx, ecx
1189
        jz      .alloc_block
1079
        jz      .alloc_block
1190
        push    ecx
1080
        push    ecx
1191
        mov     eax, ecx
1081
        mov     eax, ecx
1192
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1082
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1193
        call    extfsReadBlock
1083
        call    extfsReadBlock
1194
        jc      .error_block_read
1084
        jc      .error_block_read
1195
        mov     ecx, [esp+12]
1085
        mov     ecx, [esp+12]
1196
        mov     edi, [ebp+EXTFS.tempBlockBuffer]
1086
        mov     edi, [ebp+EXTFS.tempBlockBuffer]
1197
        mov     edx, edi
1087
        mov     edx, edi
1198
        add     edx, [ebp+EXTFS.bytesPerBlock]
1088
        add     edx, [ebp+EXTFS.bytesPerBlock]
1199
.searchSpace:
1089
.searchSpace:
1200
        movzx   eax, [edi+DIRENTRY.entryLength]
1090
        movzx   eax, [edi+DIRENTRY.entryLength]
1201
        test    eax, eax
1091
        test    eax, eax
1202
        jz      .zeroLength
1092
        jz      .zeroLength
1203
        cmp     [edi+DIRENTRY.inodeNumber], 0
1093
        cmp     [edi+DIRENTRY.inodeNumber], 0
1204
        je      .unusedEntry
1094
        je      .unusedEntry
1205
        movzx   ebx, [edi+DIRENTRY.nameLength]
1095
        movzx   ebx, [edi+DIRENTRY.nameLength]
1206
        add     ebx, 8+3
1096
        add     ebx, 8+3
1207
        and     ebx, -4
1097
        and     ebx, -4
1208
        sub     eax, ebx
1098
        sub     eax, ebx
1209
        add     edi, ebx
1099
        add     edi, ebx
1210
        cmp     eax, ecx
1100
        cmp     eax, ecx
1211
        jb      .nextEntry
1101
        jb      .nextEntry
1212
        sub     edi, ebx
1102
        sub     edi, ebx
1213
        mov     [edi+DIRENTRY.entryLength], bx
1103
        mov     [edi+DIRENTRY.entryLength], bx
1214
        add     edi, ebx
1104
        add     edi, ebx
1215
        mov     [edi+DIRENTRY.entryLength], ax
1105
        mov     [edi+DIRENTRY.entryLength], ax
1216
        jmp     .found
1106
        jmp     .found
1217
 
1107
 
1218
.unusedEntry:
1108
.unusedEntry:
1219
        cmp     eax, ecx
1109
        cmp     eax, ecx
1220
        jge     .found
1110
        jge     .found
1221
.nextEntry:
1111
.nextEntry:
1222
        add     edi, eax
1112
        add     edi, eax
1223
        cmp     edi, edx
1113
        cmp     edi, edx
1224
        jb      .searchSpace
1114
        jb      .searchSpace
1225
        pop     ecx ecx eax
1115
        pop     ecx ecx eax
1226
        inc     ecx
1116
        inc     ecx
1227
        jmp     .searchBlock
1117
        jmp     .searchBlock
1228
 
1118
 
1229
.zeroLength:
1119
.zeroLength:
1230
        mov     [edi+DIRENTRY.entryLength], cx
1120
        mov     [edi+DIRENTRY.entryLength], cx
1231
        mov     eax, edx
1121
        mov     eax, edx
1232
        sub     eax, edi
1122
        sub     eax, edi
1233
        cmp     eax, ecx
1123
        cmp     eax, ecx
1234
        jge     .found
1124
        jge     .found
1235
        mov     [edi+DIRENTRY.inodeNumber], 0
1125
        mov     [edi+DIRENTRY.inodeNumber], 0
1236
        mov     [edi+DIRENTRY.entryLength], ax
1126
        mov     [edi+DIRENTRY.entryLength], ax
1237
; this block wasn't linking to the next one, so write it, and use the next block
1127
; this block wasn't linking to the next one, so write it, and use the next block
1238
        pop     eax
1128
        pop     eax
1239
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1129
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1240
        call    extfsWriteBlock
1130
        call    extfsWriteBlock
1241
        jc      .error_get_inode_block
1131
        jc      .error_get_inode_block
1242
        inc     dword[esp]
1132
        inc     dword[esp]
1243
        mov     ecx, [esp]
1133
        mov     ecx, [esp]
1244
        call    extfsGetFileBlock
1134
        call    extfsGetFileBlock
1245
        jc      .error_get_inode_block
1135
        jc      .error_get_inode_block
1246
        test    ecx, ecx
1136
        test    ecx, ecx
1247
        jz      .alloc_block
1137
        jz      .alloc_block
1248
        push    ecx
1138
        push    ecx
1249
        jmp     .prepare_block
1139
        jmp     .prepare_block
1250
 
1140
 
1251
.alloc_block:
1141
.alloc_block:
1252
        mov     eax, [esp+24]
1142
        mov     eax, [esp]
1253
        mov     edx, eax
-
 
1254
        call    extfsBlockAlloc
-
 
1255
        jc      .error_get_inode_block
-
 
1256
        mov     ecx, [esp]
1143
        mov     edx, [esp+24]
1257
        mov     edi, ebx
-
 
1258
        call    extfsSetFileBlock
1144
        call    extfsFileBlockAlloc
1259
        jc      .error_get_inode_block
1145
        jc      .error_get_inode_block
1260
        mov     eax, [ebp+EXTFS.bytesPerBlock]
1146
        mov     eax, [ebp+EXTFS.bytesPerBlock]
1261
        add     [esi+INODE.fileSize], eax
1147
        add     [esi+INODE.fileSize], eax
1262
        mov     eax, [ebp+EXTFS.sectorsPerBlock]
-
 
1263
        add     [esi+INODE.sectorsUsed], eax
-
 
1264
        mov     eax, [esp+24]
1148
        mov     eax, [esp+24]
1265
        mov     ebx, esi
1149
        mov     ebx, esi
1266
        call    writeInode
1150
        call    writeInode
1267
        jc      .error_get_inode_block
1151
        jc      .error_get_inode_block
1268
        push    edi     ; save the block we just allocated
1152
        push    edi     ; save the block we just allocated
1269
.prepare_block:
1153
.prepare_block:
1270
        mov     eax, [esp]
-
 
1271
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1154
        mov     edi, [ebp+EXTFS.tempBlockBuffer]
1272
        call    extfsReadBlock
-
 
1273
        jc      .error_block_read
-
 
1274
        mov     edi, ebx
-
 
1275
        mov     eax, [ebp+EXTFS.bytesPerBlock]
1155
        mov     eax, [ebp+EXTFS.bytesPerBlock]
1276
        mov     [edi+DIRENTRY.entryLength], ax
1156
        mov     [edi+DIRENTRY.entryLength], ax
1277
.found:
1157
.found:
1278
        pop     edx ecx ecx ecx ebx esi
1158
        pop     edx ecx ecx ecx ebx esi
1279
        push    ebx
1159
        push    ebx
1280
        mov     [edi], ebx  ; save inode
1160
        mov     [edi+DIRENTRY.inodeNumber], ebx
1281
        mov     eax, [esp+4]
1161
        sub     ecx, 8
-
 
1162
        mov     word [edi+DIRENTRY.nameLength], cx
1282
        cmp     [ebp+EXTFS.superblock.dynamicVersionFlag], 0
1163
        cmp     [ebp+EXTFS.superblock.dynamicVersionFlag], 0
1283
        je      .name
1164
        je      .name
-
 
1165
        mov     eax, [esp+4]
1284
        mov     [edi+DIRENTRY.fileType], al
1166
        mov     [edi+DIRENTRY.fileType], al
1285
.name:
1167
.name:
1286
        sub     ecx, 8
-
 
1287
        mov     [edi+DIRENTRY.nameLength], cl
-
 
1288
        add     edi, 8
1168
        add     edi, 8
1289
        rep movsb
1169
        rep movsb
1290
        mov     eax, edx
1170
        mov     eax, edx
1291
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1171
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1292
        call    extfsWriteBlock
1172
        call    extfsWriteBlock
1293
        jc      .error_block_write
1173
        jc      .error_block_write
1294
        mov     eax, [esp]
1174
        mov     eax, [esp]
1295
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1175
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1296
        call    readInode
1176
        call    readInode
1297
        jc      .error_block_write
1177
        jc      .error_block_write
1298
        pop     eax
1178
        pop     eax
1299
        inc     [ebx+INODE.linksCount]
1179
        inc     [ebx+INODE.linksCount]
1300
        call    writeInode
1180
        call    writeInode
1301
        jc      @f
1181
        jc      @f
1302
        xor     eax, eax
1182
        xor     eax, eax
1303
@@:
1183
@@:
1304
        pop     edx ecx ecx ebx edi esi
1184
        pop     edx ecx ecx ebx edi esi
1305
        ret
1185
        ret
1306
 
1186
 
1307
.error_block_read:
1187
.error_block_read:
1308
        pop     ebx
1188
        pop     ebx
1309
.error_get_inode_block:
1189
.error_get_inode_block:
1310
        pop     ebx ebx
1190
        pop     ebx ebx
1311
.error_inode_read:
1191
.error_inode_read:
1312
        pop     ebx ebx
1192
        pop     ebx ebx
1313
.error_block_write:
1193
.error_block_write:
1314
        pop     ebx
1194
        pop     ebx
1315
        jmp     @b
1195
        jmp     @b
1316
 
1196
 
1317
unlinkInode:
1197
unlinkInode:
1318
;   in:
1198
;   in:
1319
; eax = inode from which to unlink
1199
; eax = inode from which to unlink
1320
; ebx = inode to unlink
1200
; ebx = inode to unlink
1321
;   out:
1201
;   out:
1322
; eax = current number of links to inode, -1 = error
1202
; eax = current number of links to inode, -1 = error
1323
        push    edx ebx
1203
        push    edx ebx
1324
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1204
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1325
        call    readInode
1205
        call    readInode
1326
        jc      .fail
1206
        jc      .fail
1327
        push    eax
1207
        push    eax
1328
        lea     esi, [ebp+EXTFS.inodeBuffer]
1208
        lea     esi, [ebp+EXTFS.inodeBuffer]
1329
.loop:
1209
.loop:
1330
        mov     ecx, [esp]
1210
        mov     ecx, [esp]
1331
        call    extfsGetFileBlock
1211
        call    extfsGetFileBlock
1332
        jc      .fail_loop
1212
        jc      .fail_loop
1333
        test    ecx, ecx
1213
        test    ecx, ecx
1334
        jz      .fail_loop
1214
        jz      .fail_loop
1335
        mov     eax, ecx
1215
        mov     eax, ecx
1336
        mov     edi, ecx
1216
        mov     edi, ecx
1337
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1217
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1338
        call    extfsReadBlock
1218
        call    extfsReadBlock
1339
        jc      .fail_loop
1219
        jc      .fail_loop
1340
.first_dir_entry:   ; edi -> block
1220
.first_dir_entry:   ; edi -> block
1341
        mov     eax, [esp+4]
1221
        mov     eax, [esp+4]
1342
        cmp     [ebx+DIRENTRY.inodeNumber], eax
1222
        cmp     [ebx+DIRENTRY.inodeNumber], eax
1343
        jne     @f
1223
        jne     @f
1344
        mov     [ebx+DIRENTRY.inodeNumber], 0
1224
        mov     [ebx+DIRENTRY.inodeNumber], 0
1345
        mov     word [ebx+DIRENTRY.nameLength], 0   ; fileType = 0
1225
        mov     word [ebx+DIRENTRY.nameLength], 0   ; fileType = 0
1346
        jmp     .write_block
1226
        jmp     .write_block
1347
 
1227
 
1348
@@:
1228
@@:
1349
        mov     edx, ebx
1229
        mov     edx, ebx
1350
        add     edx, [ebp+EXTFS.bytesPerBlock]
1230
        add     edx, [ebp+EXTFS.bytesPerBlock]
1351
        push    edx
1231
        push    edx
1352
        mov     edx, ebx
1232
        mov     edx, ebx
1353
        movzx   ecx, [ebx+DIRENTRY.entryLength]
1233
        movzx   ecx, [ebx+DIRENTRY.entryLength]
1354
        add     ebx, ecx
1234
        add     ebx, ecx
1355
.dir_entry:
1235
.dir_entry:
1356
        cmp     [ebx+DIRENTRY.inodeNumber], eax
1236
        cmp     [ebx+DIRENTRY.inodeNumber], eax
1357
        jne     @f
1237
        jne     @f
1358
        mov     cx, [ebx+DIRENTRY.entryLength]
1238
        mov     cx, [ebx+DIRENTRY.entryLength]
1359
        add     [edx+DIRENTRY.entryLength], cx
1239
        add     [edx+DIRENTRY.entryLength], cx
1360
        pop     eax
1240
        pop     eax
1361
        jmp     .write_block
1241
        jmp     .write_block
1362
 
1242
 
1363
@@:
1243
@@:
1364
        mov     edx, ebx
1244
        mov     edx, ebx
1365
        movzx   ecx, [ebx+DIRENTRY.entryLength]
1245
        movzx   ecx, [ebx+DIRENTRY.entryLength]
1366
        test    ecx, ecx
1246
        test    ecx, ecx
1367
        jz      .fail_inode
1247
        jz      .fail_inode
1368
        add     ebx, ecx
1248
        add     ebx, ecx
1369
        cmp     ebx, [esp]
1249
        cmp     ebx, [esp]
1370
        jb      .dir_entry
1250
        jb      .dir_entry
1371
        pop     ecx
1251
        pop     ecx
1372
        inc     dword[esp]
1252
        inc     dword[esp]
1373
        jmp     .loop
1253
        jmp     .loop
1374
 
1254
 
1375
.fail_inode:
1255
.fail_inode:
1376
        pop     eax
1256
        pop     eax
1377
.fail_loop:
1257
.fail_loop:
1378
        pop     eax
1258
        pop     eax
1379
.fail:
1259
.fail:
1380
        or      eax, -1
1260
        or      eax, -1
1381
        jmp     @f
1261
        jmp     @f
1382
 
1262
 
1383
.write_block:
1263
.write_block:
1384
        pop     eax
1264
        pop     eax
1385
        mov     eax, edi
1265
        mov     eax, edi
1386
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1266
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1387
        call    extfsWriteBlock
1267
        call    extfsWriteBlock
1388
        jc      .fail
1268
        jc      .fail
1389
        mov     eax, [esp]
1269
        mov     eax, [esp]
1390
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1270
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1391
        call    readInode
1271
        call    readInode
1392
        jc      .fail
1272
        jc      .fail
1393
        dec     word [ebx+INODE.linksCount]
1273
        dec     word [ebx+INODE.linksCount]
1394
        mov     eax, [esp]
1274
        mov     eax, [esp]
1395
        call    writeInode
1275
        call    writeInode
1396
        jc      .fail
1276
        jc      .fail
1397
        movzx   eax, word [ebx+INODE.linksCount]
1277
        movzx   eax, word [ebx+INODE.linksCount]
1398
@@:
1278
@@:
1399
        pop     ebx edx
1279
        pop     ebx edx
1400
        ret
1280
        ret
1401
 
1281
 
1402
findInode:
1282
findInode:
1403
; in: esi -> path string in UTF-8
1283
; in: esi -> path string in UTF-8
1404
;   out:
1284
;   out:
1405
; edi -> file name in UTF-8
1285
; edi -> file name in UTF-8
1406
; esi = last inode number
1286
; esi = last inode number
1407
; [ebp+EXTFS.inodeBuffer] = last inode
1287
; [ebp+EXTFS.inodeBuffer] = last inode
1408
; ecx = parent inode number
1288
; ecx = parent inode number
1409
; CF=1 -> file not found, edi=0 -> error
1289
; CF=1 -> file not found, edi=0 -> error
1410
        push    esi
1290
        push    esi
1411
        lea     esi, [ebp+EXTFS.rootInodeBuffer]
1291
        lea     esi, [ebp+EXTFS.rootInodeBuffer]
1412
        lea     edi, [ebp+EXTFS.inodeBuffer]
1292
        lea     edi, [ebp+EXTFS.inodeBuffer]
1413
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
1293
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
1414
        mov     edx, esi
1294
        mov     edx, esi
1415
        rep movsb
1295
        rep movsb
1416
        pop     esi
1296
        pop     esi
1417
        pushd   0 ROOT_INODE
1297
        pushd   0 ROOT_INODE
1418
        mov     edi, esi
1298
        mov     edi, esi
1419
        cmp     [edx+INODE.sectorsUsed], 0
1299
        cmp     [edx+INODE.sectorsUsed], 0
1420
        jz      .not_found
1300
        jz      .not_found
1421
        cmp     byte [esi], 0
1301
        cmp     byte [esi], 0
1422
        jnz     .next_path_part
1302
        jnz     .next_path_part
1423
        xor     eax, eax
1303
        xor     eax, eax
1424
        pop     esi ecx
1304
        pop     esi ecx
1425
        ret
1305
        ret
1426
 
1306
 
1427
@@:
1307
@@:
1428
        pop     esi esi
1308
        pop     esi esi
1429
.error:
1309
.error:
1430
        pop     esi ecx
1310
        pop     esi ecx
1431
        xor     edi, edi
1311
        xor     edi, edi
1432
        stc
1312
        stc
1433
        ret
1313
        ret
1434
 
1314
 
1435
.next_path_part:
1315
.next_path_part:
1436
        push    [edx+INODE.sectorsUsed]
1316
        push    [edx+INODE.sectorsUsed]
1437
        xor     ecx, ecx
1317
        xor     ecx, ecx
1438
.folder_block_cycle:
1318
.folder_block_cycle:
1439
        push    ecx
1319
        push    ecx
1440
        xchg    esi, edx
1320
        xchg    esi, edx
1441
        call    extfsGetFileBlock
1321
        call    extfsGetFileBlock
1442
        jc      @b
1322
        jc      @b
1443
        xchg    esi, edx
1323
        xchg    esi, edx
1444
        mov     eax, ecx
1324
        mov     eax, ecx
1445
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1325
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1446
        call    extfsReadBlock
1326
        call    extfsReadBlock
1447
        jc      @b
1327
        jc      @b
1448
        push    esi edx
1328
        push    esi edx
1449
        mov     edx, ebx
1329
        mov     edx, ebx
1450
        add     edx, [ebp+EXTFS.bytesPerBlock]
1330
        add     edx, [ebp+EXTFS.bytesPerBlock]
1451
.start_rec:
1331
.start_rec:
1452
        cmp     [ebx+DIRENTRY.inodeNumber], 0
1332
        cmp     [ebx+DIRENTRY.inodeNumber], 0
1453
        jz      .next_rec
1333
        jz      .next_rec
1454
        push    esi
1334
        push    esi
1455
        movzx   ecx, [ebx+DIRENTRY.nameLength]
1335
        movzx   ecx, [ebx+DIRENTRY.nameLength]
1456
        lea     edi, [ebx+DIRENTRY.name]
1336
        lea     edi, [ebx+DIRENTRY.name]
1457
        repz cmpsb
1337
        repz cmpsb
1458
        jz      .test_find
1338
        jz      .test_find
1459
@@: ; doesn't match
1339
@@: ; doesn't match
1460
        pop     esi
1340
        pop     esi
1461
.next_rec:
1341
.next_rec:
1462
        movzx   eax, [ebx+DIRENTRY.entryLength]
1342
        movzx   eax, [ebx+DIRENTRY.entryLength]
1463
        add     ebx, eax
1343
        add     ebx, eax
1464
        cmp     ebx, edx
1344
        cmp     ebx, edx
1465
        jb      .start_rec
1345
        jb      .start_rec
1466
        push    eax
1346
        push    eax
1467
        jmp     @f
1347
        jmp     @f
1468
 
1348
 
1469
.test_find:
1349
.test_find:
1470
        cmp     byte [esi], 0
1350
        cmp     byte [esi], 0
1471
        je      @f
1351
        je      @f
1472
        cmp     byte [esi], '/'
1352
        cmp     byte [esi], '/'
1473
        jne     @b
1353
        jne     @b
1474
        inc     esi
1354
        inc     esi
1475
@@:
1355
@@:
1476
        pop     edx edx edi ecx eax
1356
        pop     edx edx edi ecx eax
1477
; ebx -> matched directory entry, esi -> name without parent, or not changed
1357
; ebx -> matched directory entry, esi -> name without parent, or not changed
1478
        cmp     edi, esi
1358
        cmp     edi, esi
1479
        jnz     @f
1359
        jnz     @f
1480
        sub     eax, [ebp+EXTFS.sectorsPerBlock]
1360
        sub     eax, [ebp+EXTFS.sectorsPerBlock]
1481
        jle     .not_found
1361
        jle     .not_found
1482
        push    eax
1362
        push    eax
1483
        inc     ecx
1363
        inc     ecx
1484
        jmp     .folder_block_cycle
1364
        jmp     .folder_block_cycle
1485
 
1365
 
1486
@@:
1366
@@:
1487
        pop     eax
1367
        pop     eax
1488
        mov     [esp], eax
1368
        mov     [esp], eax
1489
        mov     eax, [ebx+DIRENTRY.inodeNumber]
1369
        mov     eax, [ebx+DIRENTRY.inodeNumber]
1490
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1370
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1491
        push    eax
1371
        push    eax
1492
        call    readInode
1372
        call    readInode
1493
        jc      .error
1373
        jc      .error
1494
        cmp     byte [esi], 0
1374
        cmp     byte [esi], 0
1495
        je      .ret
1375
        je      .ret
1496
        mov     edx, ebx
1376
        mov     edx, ebx
1497
        movzx   eax, [ebx+INODE.accessMode]
1377
        movzx   eax, [ebx+INODE.accessMode]
1498
        and     eax, TYPE_MASK
1378
        and     eax, TYPE_MASK
1499
        cmp     eax, DIRECTORY
1379
        cmp     eax, DIRECTORY
1500
        jz      .next_path_part
1380
        jz      .next_path_part
1501
        xor     edi, edi    ; path folder is a file
1381
        xor     edi, edi    ; path folder is a file
1502
        jmp     @f
1382
        jmp     @f
1503
 
1383
 
1504
.not_found:
1384
.not_found:
1505
        mov     esi, edi
1385
        mov     esi, edi
1506
        call    strlen
1386
        call    strlen
1507
        mov     al, '/'
1387
        mov     al, '/'
1508
        repnz scasb
1388
        repnz scasb
1509
        mov     edi, esi
1389
        mov     edi, esi
1510
        jnz     @f
1390
        jnz     @f
1511
        xor     edi, edi    ; path folder not found
1391
        xor     edi, edi    ; path folder not found
1512
@@:
1392
@@:
1513
        movi    eax, ERROR_FILE_NOT_FOUND
1393
        movi    eax, ERROR_FILE_NOT_FOUND
1514
        stc
1394
        stc
1515
.ret:
1395
.ret:
1516
        pop     esi ecx
1396
        pop     esi ecx
1517
        ret
1397
        ret
1518
 
1398
 
1519
writeSuperblock:
1399
writeSuperblock:
1520
        push    ebx
1400
        push    ebx
1521
        mov     eax, 2
1401
        mov     eax, 2
1522
        lea     ebx, [ebp+EXTFS.superblock]
1402
        lea     ebx, [ebp+EXTFS.superblock]
1523
        call    fs_write32_sys
1403
        call    fs_write32_sys
1524
        pop     ebx
1404
        pop     ebx
1525
        ret
1405
        ret
1526
 
1406
 
1527
extfsWritingInit:
1407
extfsWritingInit:
1528
        movi    eax, ERROR_ACCESS_DENIED
1408
        movi    eax, ERROR_ACCESS_DENIED
1529
        cmp     byte [esi], 0
1409
        cmp     byte [esi], 0
1530
        jz      @f
1410
        jz      @f
1531
        movi    eax, ERROR_UNSUPPORTED_FS
1411
        movi    eax, ERROR_UNSUPPORTED_FS
1532
        test    [ebp+EXTFS.mountType], READ_ONLY
1412
        test    [ebp+EXTFS.mountType], READ_ONLY
1533
        jnz     @f
1413
        jnz     @f
1534
ext_lock:
1414
ext_lock:
1535
        lea     ecx, [ebp+EXTFS.Lock]
1415
        lea     ecx, [ebp+EXTFS.Lock]
1536
        jmp     mutex_lock
1416
        jmp     mutex_lock
1537
 
1417
 
1538
@@:
1418
@@:
1539
        pop     ebx
1419
        pop     ebx
1540
        xor     ebx, ebx
1420
        xor     ebx, ebx
1541
        ret
1421
        ret
1542
 
1422
 
1543
ext_unlock:
1423
ext_unlock:
1544
        lea     ecx, [ebp+EXTFS.Lock]
1424
        lea     ecx, [ebp+EXTFS.Lock]
1545
        jmp     mutex_unlock
1425
        jmp     mutex_unlock
1546
 
1426
 
1547
;----------------------------------------------------------------
1427
;----------------------------------------------------------------
1548
ext_ReadFolder:
1428
ext_ReadFolder:
1549
        call    ext_lock
1429
        call    ext_lock
1550
        cmp     byte [esi], 0
1430
        cmp     byte [esi], 0
1551
        jz      .root_folder
1431
        jz      .root_folder
1552
        push    ebx
1432
        push    ebx
1553
        call    findInode
1433
        call    findInode
1554
        pop     ebx
1434
        pop     ebx
1555
        jc      .error_ret
1435
        jc      .error_ret
1556
        lea     esi, [ebp+EXTFS.inodeBuffer]
1436
        lea     esi, [ebp+EXTFS.inodeBuffer]
1557
        test    [esi+INODE.accessMode], FLAG_FILE
1437
        test    [esi+INODE.accessMode], FLAG_FILE
1558
        jnz     .error_not_found
1438
        jnz     .error_not_found
1559
        jmp     @f
1439
        jmp     @f
1560
 
1440
 
1561
.root_folder:
1441
.root_folder:
1562
        lea     esi, [ebp+EXTFS.rootInodeBuffer]
1442
        lea     esi, [ebp+EXTFS.rootInodeBuffer]
1563
        lea     edi, [ebp+EXTFS.inodeBuffer]
1443
        lea     edi, [ebp+EXTFS.inodeBuffer]
1564
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
1444
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
1565
        shr     ecx, 2
1445
        shr     ecx, 2
1566
        push    edi
1446
        push    edi
1567
        rep movsd
1447
        rep movsd
1568
        pop     esi
1448
        pop     esi
1569
@@:
1449
@@:
1570
        cmp     [esi+INODE.fileSize], 0
1450
        cmp     [esi+INODE.fileSize], 0
1571
        je      .error_empty_dir
1451
        je      .error_empty_dir
1572
        mov     edx, [ebx+16]
1452
        mov     edx, [ebx+16]
1573
        push    edx         ; [edi+28] result buffer
1453
        push    edx         ; [edi+28] result buffer
1574
        push    0           ; [edi+24] end of the current block in folder
1454
        push    0           ; [edi+24] end of the current block in folder
1575
        pushd   [ebx+12]    ; [edi+20] files to read
1455
        pushd   [ebx+12]    ; [edi+20] files to read
1576
        pushd   [ebx+4]     ; [edi+16] first wanted file
1456
        pushd   [ebx+4]     ; [edi+16] first wanted file
1577
        pushd   [ebx+8]     ; [edi+12] flags
1457
        pushd   [ebx+8]     ; [edi+12] flags
1578
        push    0           ; [edi+8]  read files
1458
        push    0           ; [edi+8]  read files
1579
        push    0           ; [edi+4]  files in folder
1459
        push    0           ; [edi+4]  files in folder
1580
        push    0           ; [edi]    current block index
1460
        push    0           ; [edi]    current block index
1581
        mov     edi, esp    ; edi -> local variables
1461
        mov     edi, esp    ; edi -> local variables
1582
        add     edx, 32
1462
        add     edx, 32
1583
        xor     ecx, ecx
1463
        xor     ecx, ecx
1584
        call    extfsGetFileBlock
1464
        call    extfsGetFileBlock
1585
        jc      .error_get_block
1465
        jc      .error_get_block
1586
        mov     eax, ecx
1466
        mov     eax, ecx
1587
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1467
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1588
        call    extfsReadBlock
1468
        call    extfsReadBlock
1589
        jc      .error_get_block
1469
        jc      .error_get_block
1590
        mov     eax, ebx
1470
        mov     eax, ebx
1591
        add     eax, [ebp+EXTFS.bytesPerBlock]
1471
        add     eax, [ebp+EXTFS.bytesPerBlock]
1592
        mov     [edi+24], eax
1472
        mov     [edi+24], eax
1593
        mov     ecx, [edi+16]
1473
        mov     ecx, [edi+16]
1594
.find_wanted_start:
1474
.find_wanted_start:
1595
        jecxz   .find_wanted_end
1475
        jecxz   .find_wanted_end
1596
.find_wanted_cycle:
1476
.find_wanted_cycle:
1597
        cmp     [ebx+DIRENTRY.inodeNumber], 0
1477
        cmp     [ebx+DIRENTRY.inodeNumber], 0
1598
        jz      @f
1478
        jz      @f
1599
        inc     dword [edi+4]
1479
        inc     dword [edi+4]
1600
        dec     ecx
1480
        dec     ecx
1601
@@:
1481
@@:
1602
        movzx   eax, [ebx+DIRENTRY.entryLength]
1482
        movzx   eax, [ebx+DIRENTRY.entryLength]
1603
        cmp     eax, 12     ; minimum entry length
1483
        cmp     eax, 12     ; minimum entry length
1604
        jb      .error_bad_len
1484
        jb      .error_bad_len
1605
        test    eax, 3      ; length must be aligned
1485
        test    eax, 3      ; length must be aligned
1606
        jnz     .error_bad_len
1486
        jnz     .error_bad_len
1607
        sub     [esi+INODE.fileSize], eax
1487
        sub     [esi+INODE.fileSize], eax
1608
        add     ebx, eax
1488
        add     ebx, eax
1609
        cmp     ebx, [edi+24]
1489
        cmp     ebx, [edi+24]
1610
        jb      .find_wanted_start
1490
        jb      .find_wanted_start
1611
        push    .find_wanted_start
1491
        push    .find_wanted_start
1612
.end_block: ; read next block
1492
.end_block: ; read next block
1613
        cmp     [esi+INODE.fileSize], 0
1493
        cmp     [esi+INODE.fileSize], 0
1614
        jle     .end_dir
1494
        jle     .end_dir
1615
        inc     dword [edi]
1495
        inc     dword [edi]
1616
        push    ecx
1496
        push    ecx
1617
        mov     ecx, [edi]
1497
        mov     ecx, [edi]
1618
        call    extfsGetFileBlock
1498
        call    extfsGetFileBlock
1619
        jc      .error_get_block
1499
        jc      .error_get_block
1620
        mov     eax, ecx
1500
        mov     eax, ecx
1621
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1501
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1622
        call    extfsReadBlock
1502
        call    extfsReadBlock
1623
        jc      .error_get_block
1503
        jc      .error_get_block
1624
        pop     ecx
1504
        pop     ecx
1625
        mov     eax, ebx
1505
        mov     eax, ebx
1626
        add     eax, [ebp+EXTFS.bytesPerBlock]
1506
        add     eax, [ebp+EXTFS.bytesPerBlock]
1627
        mov     [edi+24], eax
1507
        mov     [edi+24], eax
1628
        ret
1508
        ret
1629
 
1509
 
1630
.wanted_end:
1510
.wanted_end:
1631
        loop    .find_wanted_cycle
1511
        loop    .find_wanted_cycle
1632
.find_wanted_end:
1512
.find_wanted_end:
1633
        mov     ecx, [edi+20]
1513
        mov     ecx, [edi+20]
1634
.wanted_start:
1514
.wanted_start:
1635
        jecxz   .wanted_end
1515
        jecxz   .wanted_end
1636
        cmp     [ebx+DIRENTRY.inodeNumber], 0
1516
        cmp     [ebx+DIRENTRY.inodeNumber], 0
1637
        jz      .empty_rec
1517
        jz      .empty_rec
1638
        inc     dword [edi+8]
1518
        inc     dword [edi+8]
1639
        inc     dword [edi+4]
1519
        inc     dword [edi+4]
1640
        push    ebx edi ecx esi edx edi
1520
        push    ebx edi ecx esi edx edi
1641
        pushd   [edi+12]
1521
        pushd   [edi+12]
1642
        mov     edi, edx
1522
        mov     edi, edx
1643
        xor     eax, eax
1523
        xor     eax, eax
1644
        mov     ecx, 40 / 4
1524
        mov     ecx, 40 / 4
1645
        rep stosd
1525
        rep stosd
1646
        popd    [edx+4] edi
1526
        popd    [edx+4] edi
1647
        mov     eax, [ebx+DIRENTRY.inodeNumber]
1527
        mov     eax, [ebx+DIRENTRY.inodeNumber]
1648
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1528
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1649
        call    readInode
1529
        call    readInode
1650
        jc      .error_read_subinode
1530
        jc      .error_read_subinode
1651
        mov     esi, ebx
1531
        mov     esi, ebx
1652
        lea     edi, [edx+8]
1532
        lea     edi, [edx+8]
1653
        mov     eax, [ebx+INODE.inodeModified]
1533
        mov     eax, [ebx+INODE.inodeModified]
1654
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1534
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1655
        call    fsTime2bdfe
1535
        call    fsTime2bdfe
1656
 
1536
 
1657
        mov     eax, [esi+INODE.accessedTime]
1537
        mov     eax, [esi+INODE.accessedTime]
1658
        sub     eax, 978307200
1538
        sub     eax, 978307200
1659
        call    fsTime2bdfe
1539
        call    fsTime2bdfe
1660
 
1540
 
1661
        mov     eax, [esi+INODE.dataModified]
1541
        mov     eax, [esi+INODE.dataModified]
1662
        sub     eax, 978307200
1542
        sub     eax, 978307200
1663
        call    fsTime2bdfe
1543
        call    fsTime2bdfe
1664
        pop     edx
1544
        pop     edx
1665
        or      dword [edx], KOS_DIRECTORY
1545
        or      dword [edx], KOS_DIRECTORY
1666
        test    [esi+INODE.accessMode], FLAG_FILE
1546
        test    [esi+INODE.accessMode], FLAG_FILE
1667
        jz      @f
1547
        jz      @f
1668
        xor     dword [edx], KOS_DIRECTORY  ; mark as file
1548
        xor     dword [edx], KOS_DIRECTORY  ; mark as file
1669
        mov     eax, [esi+INODE.fileSize]
1549
        mov     eax, [esi+INODE.fileSize]
1670
        stosd
1550
        stosd
1671
        mov     eax, [esi+INODE.fileSizeHigh]
1551
        mov     eax, [esi+INODE.fileSizeHigh]
1672
        stosd
1552
        stosd
1673
@@:
1553
@@:
1674
        mov     esi, [esp+12]
1554
        mov     esi, [esp+12]
1675
        movzx   ecx, [esi+DIRENTRY.nameLength]
1555
        movzx   ecx, [esi+DIRENTRY.nameLength]
1676
        lea     esi, [esi+DIRENTRY.name]
1556
        lea     esi, [esi+DIRENTRY.name]
1677
        add     ecx, esi
1557
        add     ecx, esi
1678
        cmp     byte [esi], '.'
1558
        cmp     byte [esi], '.'
1679
        jnz     @f
1559
        jnz     @f
1680
        or      byte [edx], KOS_HIDDEN
1560
        or      byte [edx], KOS_HIDDEN
1681
@@:
1561
@@:
1682
        lea     edi, [edx+40]
1562
        lea     edi, [edx+40]
1683
        cmp     byte [edx+4], 1
1563
        cmp     byte [edx+4], 1
1684
        jz      .utf16
1564
        jz      .utf16
1685
@@:
1565
@@:
1686
        call    utf8to16
1566
        call    utf8to16
1687
        call    uni2ansi_char
1567
        call    uni2ansi_char
1688
        stosb
1568
        stosb
1689
        cmp     esi, ecx
1569
        cmp     esi, ecx
1690
        jc      @b
1570
        jc      @b
1691
        and     byte [edi], 0
1571
        and     byte [edi], 0
1692
        add     edx, 40+264
1572
        add     edx, 40+264
1693
@@:
1573
@@:
1694
        pop     esi ecx edi ebx
1574
        pop     esi ecx edi ebx
1695
        dec     ecx
1575
        dec     ecx
1696
.empty_rec:
1576
.empty_rec:
1697
        movzx   eax, [ebx+DIRENTRY.entryLength]
1577
        movzx   eax, [ebx+DIRENTRY.entryLength]
1698
        cmp     eax, 12
1578
        cmp     eax, 12
1699
        jb      .error_bad_len
1579
        jb      .error_bad_len
1700
        test    eax, 3
1580
        test    eax, 3
1701
        jnz     .error_bad_len
1581
        jnz     .error_bad_len
1702
        sub     [esi+INODE.fileSize], eax
1582
        sub     [esi+INODE.fileSize], eax
1703
        add     ebx, eax
1583
        add     ebx, eax
1704
        cmp     ebx, [edi+24]
1584
        cmp     ebx, [edi+24]
1705
        jb      .wanted_start
1585
        jb      .wanted_start
1706
        push    .wanted_start
1586
        push    .wanted_start
1707
        jmp     .end_block
1587
        jmp     .end_block
1708
 
1588
 
1709
.utf16:
1589
.utf16:
1710
        call    utf8to16
1590
        call    utf8to16
1711
        stosw
1591
        stosw
1712
        cmp     esi, ecx
1592
        cmp     esi, ecx
1713
        jc      .utf16
1593
        jc      .utf16
1714
        and     word [edi], 0
1594
        and     word [edi], 0
1715
        add     edx, 40+520
1595
        add     edx, 40+520
1716
        jmp     @b
1596
        jmp     @b
1717
 
1597
 
1718
.end_dir:
1598
.end_dir:
1719
        call    ext_unlock
1599
        call    ext_unlock
1720
        mov     edx, [edi+28]
1600
        mov     edx, [edi+28]
1721
        mov     ebx, [edi+8]
1601
        mov     ebx, [edi+8]
1722
        mov     ecx, [edi+4]
1602
        mov     ecx, [edi+4]
1723
        mov     dword [edx], 1  ; version
1603
        mov     dword [edx], 1  ; version
1724
        mov     [edx+4], ebx
1604
        mov     [edx+4], ebx
1725
        mov     [edx+8], ecx
1605
        mov     [edx+8], ecx
1726
        lea     esp, [edi+32]
1606
        lea     esp, [edi+32]
1727
        mov     ecx, 20/4
1607
        mov     ecx, 20/4
1728
        lea     edi, [edx+12]
1608
        lea     edi, [edx+12]
1729
        xor     eax, eax
1609
        xor     eax, eax
1730
        rep stosd
1610
        rep stosd
1731
        ret
1611
        ret
1732
 
1612
 
1733
.error_bad_len:
1613
.error_bad_len:
1734
        movi    eax, ERROR_FS_FAIL
1614
        movi    eax, ERROR_FS_FAIL
1735
.error_read_subinode:
1615
.error_read_subinode:
1736
.error_get_block:
1616
.error_get_block:
1737
        lea     esp, [edi+32]
1617
        lea     esp, [edi+32]
1738
.error_ret:
1618
.error_ret:
1739
        or      ebx, -1
1619
        or      ebx, -1
1740
        push    eax
1620
        push    eax
1741
        call    ext_unlock
1621
        call    ext_unlock
1742
        pop     eax
1622
        pop     eax
1743
        ret
1623
        ret
1744
 
1624
 
1745
.error_empty_dir:
1625
.error_empty_dir:
1746
        movi    eax, ERROR_FS_FAIL
1626
        movi    eax, ERROR_FS_FAIL
1747
        jmp     .error_ret
1627
        jmp     .error_ret
1748
 
1628
 
1749
.error_not_found:
1629
.error_not_found:
1750
        movi    eax, ERROR_FILE_NOT_FOUND
1630
        movi    eax, ERROR_FILE_NOT_FOUND
1751
        jmp     .error_ret
1631
        jmp     .error_ret
1752
 
1632
 
1753
;----------------------------------------------------------------
1633
;----------------------------------------------------------------
1754
ext_ReadFile:
1634
ext_ReadFile:
1755
        call    ext_lock
1635
        call    ext_lock
1756
        push    ERROR_ACCESS_DENIED
1636
        push    ERROR_ACCESS_DENIED
1757
        cmp     byte [esi], 0
1637
        cmp     byte [esi], 0
1758
        jz      .error  ; root
1638
        jz      .error  ; root
1759
        mov     [esp], ebx
1639
        mov     [esp], ebx
1760
        call    findInode
1640
        call    findInode
1761
        pop     ebx
1641
        pop     ebx
1762
        jc      .error_eax
1642
        jc      .error_eax
1763
        push    ERROR_ACCESS_DENIED
1643
        push    ERROR_ACCESS_DENIED
1764
        lea     esi, [ebp+EXTFS.inodeBuffer]
1644
        lea     esi, [ebp+EXTFS.inodeBuffer]
1765
        mov     ax, [esi+INODE.accessMode]
1645
        mov     ax, [esi+INODE.accessMode]
1766
        and     ax, TYPE_MASK
1646
        and     ax, TYPE_MASK
1767
        cmp     ax, FLAG_FILE
1647
        cmp     ax, FLAG_FILE
1768
        jnz     .error  ; not a file
1648
        jnz     .error  ; not a file
1769
        pop     eax
1649
        pop     eax
1770
        mov     edi, [ebx+16]
1650
        mov     edi, [ebx+16]
1771
        mov     ecx, [ebx+12]
1651
        mov     ecx, [ebx+12]
1772
        mov     eax, [ebx+4]
1652
        mov     eax, [ebx+4]
1773
        mov     edx, [ebx+8]
1653
        mov     edx, [ebx+8]
1774
        push    ERROR_END_OF_FILE
1654
        push    ERROR_END_OF_FILE
1775
        cmp     [esi+INODE.fileSizeHigh], edx
1655
        cmp     [esi+INODE.fileSizeHigh], edx
1776
        ja      @f
1656
        ja      @f
1777
        jb      .error
1657
        jb      .error
1778
        cmp     [esi+INODE.fileSize], eax
1658
        cmp     [esi+INODE.fileSize], eax
1779
        jna     .error
1659
        jna     .error
1780
@@:
1660
@@:
1781
        add     esp, 4
1661
        add     esp, 4
1782
        add     eax, ecx
1662
        add     eax, ecx
1783
        adc     edx, 0
1663
        adc     edx, 0
1784
        cmp     [esi+INODE.fileSizeHigh], edx
1664
        cmp     [esi+INODE.fileSizeHigh], edx
1785
        ja      .read_till_requested
1665
        ja      .read_till_requested
1786
        jb      .read_whole_file
1666
        jb      .read_whole_file
1787
        cmp     [esi+INODE.fileSize], eax
1667
        cmp     [esi+INODE.fileSize], eax
1788
        jae     .read_till_requested
1668
        jae     .read_till_requested
1789
.read_whole_file:
1669
.read_whole_file:
1790
        push    1   ; read till the end of file
1670
        push    1   ; read till the end of file
1791
        mov     ecx, [esi+INODE.fileSize]
1671
        mov     ecx, [esi+INODE.fileSize]
1792
        sub     ecx, [ebx+4]
1672
        sub     ecx, [ebx+4]
1793
        jmp     @f
1673
        jmp     @f
1794
 
1674
 
1795
.read_till_requested:
1675
.read_till_requested:
1796
        push    0   ; read as much as requested
1676
        push    0   ; read as much as requested
1797
@@: ; ecx = bytes to read, edi -> buffer
1677
@@: ; ecx = bytes to read, edi -> buffer
1798
        push    ecx
1678
        push    ecx
1799
; read part of the first block
1679
; read part of the first block
1800
        mov     edx, [ebx+8]
1680
        mov     edx, [ebx+8]
1801
        mov     eax, [ebx+4]
1681
        mov     eax, [ebx+4]
1802
        div     [ebp+EXTFS.bytesPerBlock]
1682
        div     [ebp+EXTFS.bytesPerBlock]
1803
        push    eax
1683
        push    eax
1804
        push    ecx
1684
        push    ecx
1805
        mov     ecx, eax
1685
        mov     ecx, eax
1806
        call    extfsGetFileBlock
1686
        call    extfsGetFileBlock
1807
        jc      .error_at_first_block
1687
        jc      .error_at_first_block
1808
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1688
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1809
        mov     eax, ecx
1689
        mov     eax, ecx
1810
        call    extfsReadBlock
1690
        call    extfsReadBlock
1811
        jc      .error_at_first_block
1691
        jc      .error_at_first_block
1812
        pop     ecx
1692
        pop     ecx
1813
        add     ebx, edx
1693
        add     ebx, edx
1814
        neg     edx
1694
        neg     edx
1815
        add     edx, [ebp+EXTFS.bytesPerBlock]
1695
        add     edx, [ebp+EXTFS.bytesPerBlock]
1816
        cmp     ecx, edx
1696
        cmp     ecx, edx
1817
        jbe     .only_one_block
1697
        jbe     .only_one_block
1818
        mov     eax, ecx
1698
        mov     eax, ecx
1819
        sub     eax, edx    ; bytes to read
1699
        sub     eax, edx    ; bytes to read
1820
        mov     ecx, edx
1700
        mov     ecx, edx
1821
        push    esi
1701
        push    esi
1822
        mov     esi, ebx
1702
        mov     esi, ebx
1823
        rep movsb
1703
        rep movsb
1824
        pop     esi
1704
        pop     esi
1825
        mov     ebx, edi
1705
        mov     ebx, edi
1826
        xor     edx, edx
1706
        xor     edx, edx
1827
        div     [ebp+EXTFS.bytesPerBlock]
1707
        div     [ebp+EXTFS.bytesPerBlock]
1828
        mov     edi, eax
1708
        mov     edi, eax
1829
@@:
1709
@@:
1830
        test    edi, edi
1710
        test    edi, edi
1831
        jz      .finish_block
1711
        jz      .finish_block
1832
        inc     dword [esp]
1712
        inc     dword [esp]
1833
        mov     ecx, [esp]
1713
        mov     ecx, [esp]
1834
        call    extfsGetFileBlock
1714
        call    extfsGetFileBlock
1835
        jc      .error_at_read_cycle
1715
        jc      .error_at_read_cycle
1836
        mov     eax, ecx
1716
        mov     eax, ecx
1837
        call    extfsReadBlock
1717
        call    extfsReadBlock
1838
        jc      .error_at_read_cycle
1718
        jc      .error_at_read_cycle
1839
        add     ebx, [ebp+EXTFS.bytesPerBlock]
1719
        add     ebx, [ebp+EXTFS.bytesPerBlock]
1840
        dec     edi
1720
        dec     edi
1841
        jmp     @b
1721
        jmp     @b
1842
 
1722
 
1843
.finish_block:  ; edx = number of bytes in the last block
1723
.finish_block:  ; edx = number of bytes in the last block
1844
        test    edx, edx
1724
        test    edx, edx
1845
        jz      .end_read
1725
        jz      .end_read
1846
        pop     ecx     ; block counter
1726
        pop     ecx     ; block counter
1847
        inc     ecx
1727
        inc     ecx
1848
        call    extfsGetFileBlock
1728
        call    extfsGetFileBlock
1849
        jc      .error_at_finish_block
1729
        jc      .error_at_finish_block
1850
        mov     edi, ebx
1730
        mov     edi, ebx
1851
        mov     eax, ecx
1731
        mov     eax, ecx
1852
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1732
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
1853
        call    extfsReadBlock
1733
        call    extfsReadBlock
1854
        jc      .error_at_finish_block
1734
        jc      .error_at_finish_block
1855
        push    eax
1735
        push    eax
1856
        mov     ecx, edx
1736
        mov     ecx, edx
1857
.only_one_block:
1737
.only_one_block:
1858
        mov     esi, ebx
1738
        mov     esi, ebx
1859
        rep movsb
1739
        rep movsb
1860
.end_read:
1740
.end_read:
1861
        call    ext_unlock
1741
        call    ext_unlock
1862
        pop     eax ebx eax
1742
        pop     eax ebx eax
1863
        test    eax, eax
1743
        test    eax, eax
1864
        jz      @f
1744
        jz      @f
1865
        movi    eax, ERROR_END_OF_FILE
1745
        movi    eax, ERROR_END_OF_FILE
1866
@@:
1746
@@:
1867
        ret
1747
        ret
1868
 
1748
 
1869
.error_at_first_block:
1749
.error_at_first_block:
1870
        pop     ebx
1750
        pop     ebx
1871
.error_at_read_cycle:
1751
.error_at_read_cycle:
1872
        pop     ebx
1752
        pop     ebx
1873
.error_at_finish_block:
1753
.error_at_finish_block:
1874
        pop     ebx ebx
1754
        pop     ebx ebx
1875
.error_eax:
1755
.error_eax:
1876
        push    eax
1756
        push    eax
1877
.error:
1757
.error:
1878
        call    ext_unlock
1758
        call    ext_unlock
1879
        xor     ebx, ebx
1759
        xor     ebx, ebx
1880
        pop     eax
1760
        pop     eax
1881
        ret
1761
        ret
1882
 
1762
 
1883
;----------------------------------------------------------------
1763
;----------------------------------------------------------------
1884
ext_GetFileInfo:
1764
ext_GetFileInfo:
1885
        call    ext_lock
1765
        call    ext_lock
1886
        mov     edx, [ebx+16]
1766
        mov     edx, [ebx+16]
1887
        cmp     byte [esi], 0
1767
        cmp     byte [esi], 0
1888
        jz      .is_root
1768
        jz      .is_root
1889
        push    edx
1769
        push    edx
1890
        call    findInode
1770
        call    findInode
1891
        pop     edx
1771
        pop     edx
1892
        lea     esi, [ebp+EXTFS.inodeBuffer]
1772
        lea     esi, [ebp+EXTFS.inodeBuffer]
1893
        jnc     @f
1773
        jnc     @f
1894
        push    eax
1774
        push    eax
1895
        call    ext_unlock
1775
        call    ext_unlock
1896
        pop     eax
1776
        pop     eax
1897
        ret
1777
        ret
1898
 
1778
 
1899
.is_root:
1779
.is_root:
1900
        mov     edi, esi
1780
        mov     edi, esi
1901
        lea     esi, [ebp+EXTFS.rootInodeBuffer]
1781
        lea     esi, [ebp+EXTFS.rootInodeBuffer]
1902
@@:
1782
@@:
1903
        mov     bl, [edi]
1783
        mov     bl, [edi]
1904
        xor     eax, eax
1784
        xor     eax, eax
1905
        mov     edi, edx
1785
        mov     edi, edx
1906
        mov     ecx, 40/4
1786
        mov     ecx, 40/4
1907
        rep stosd
1787
        rep stosd
1908
        cmp     bl, '.'
1788
        cmp     bl, '.'
1909
        jne     @f
1789
        jne     @f
1910
        or      dword [edx], KOS_HIDDEN
1790
        or      dword [edx], KOS_HIDDEN
1911
@@:
1791
@@:
1912
        or      dword [edx], KOS_DIRECTORY
1792
        or      dword [edx], KOS_DIRECTORY
1913
        test    [esi+INODE.accessMode], FLAG_FILE
1793
        test    [esi+INODE.accessMode], FLAG_FILE
1914
        jz      @f
1794
        jz      @f
1915
        xor     dword [edx], KOS_DIRECTORY  ; mark as file
1795
        xor     dword [edx], KOS_DIRECTORY  ; mark as file
1916
        mov     eax, [esi+INODE.fileSize]
1796
        mov     eax, [esi+INODE.fileSize]
1917
        mov     ebx, [esi+INODE.fileSizeHigh]
1797
        mov     ebx, [esi+INODE.fileSizeHigh]
1918
        mov     dword [edx+32], eax
1798
        mov     dword [edx+32], eax
1919
        mov     dword [edx+36], ebx
1799
        mov     dword [edx+36], ebx
1920
@@:
1800
@@:
1921
        lea     edi, [edx+8]
1801
        lea     edi, [edx+8]
1922
        mov     eax, [esi+INODE.inodeModified]
1802
        mov     eax, [esi+INODE.inodeModified]
1923
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1803
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1924
        call    fsTime2bdfe
1804
        call    fsTime2bdfe
1925
 
1805
 
1926
        mov     eax, [esi+INODE.accessedTime]
1806
        mov     eax, [esi+INODE.accessedTime]
1927
        sub     eax, 978307200
1807
        sub     eax, 978307200
1928
        call    fsTime2bdfe
1808
        call    fsTime2bdfe
1929
 
1809
 
1930
        mov     eax, [esi+INODE.dataModified]
1810
        mov     eax, [esi+INODE.dataModified]
1931
        sub     eax, 978307200
1811
        sub     eax, 978307200
1932
        call    fsTime2bdfe
1812
        call    fsTime2bdfe
1933
        call    ext_unlock
1813
        call    ext_unlock
1934
        xor     eax, eax
1814
        xor     eax, eax
1935
        ret
1815
        ret
1936
 
1816
 
1937
;----------------------------------------------------------------
1817
;----------------------------------------------------------------
1938
ext_SetFileInfo:
1818
ext_SetFileInfo:
1939
        call    extfsWritingInit
1819
        call    extfsWritingInit
1940
        pushd   [ebx+16]
1820
        pushd   [ebx+16]
1941
        call    findInode
1821
        call    findInode
1942
        pop     edx
1822
        pop     edx
1943
        jc      @f
1823
        jc      @f
1944
        push    esi     ; inode number
1824
        push    esi     ; inode number
1945
        lea     esi, [edx+16]
1825
        lea     esi, [edx+16]
1946
        lea     edi, [ebp+EXTFS.inodeBuffer]
1826
        lea     edi, [ebp+EXTFS.inodeBuffer]
1947
        call    fsCalculateTime
1827
        call    fsCalculateTime
1948
        add     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1828
        add     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1949
        mov     [edi+INODE.accessedTime], eax
1829
        mov     [edi+INODE.accessedTime], eax
1950
 
1830
 
1951
        add     esi, 8
1831
        add     esi, 8
1952
        call    fsCalculateTime
1832
        call    fsCalculateTime
1953
        add     eax, 978307200
1833
        add     eax, 978307200
1954
        mov     [edi+INODE.dataModified], eax
1834
        mov     [edi+INODE.dataModified], eax
1955
        mov     ebx, edi
1835
        mov     ebx, edi
1956
        pop     eax
1836
        pop     eax
1957
        call    writeInode
1837
        call    writeInode
1958
@@:
1838
@@:
1959
        push    eax
1839
        push    eax
1960
        jc      @f
1840
        jc      @f
1961
        call    writeSuperblock
1841
        call    writeSuperblock
1962
        mov     esi, [ebp+PARTITION.Disk]
1842
        mov     esi, [ebp+PARTITION.Disk]
1963
        call    disk_sync
1843
        call    disk_sync
1964
@@:
1844
@@:
1965
        call    ext_unlock
1845
        call    ext_unlock
1966
        pop     eax
1846
        pop     eax
1967
        ret
1847
        ret
1968
 
1848
 
1969
;----------------------------------------------------------------
1849
;----------------------------------------------------------------
1970
ext_Delete:
1850
ext_Delete:
1971
        call    extfsWritingInit
1851
        call    extfsWritingInit
1972
        call    findInode
1852
        call    findInode
1973
        mov     ebx, esi
1853
        mov     ebx, esi
1974
        push    eax
1854
        push    eax
1975
        jc      .ret
1855
        jc      .ret
1976
        pop     eax
1856
        pop     eax
1977
        lea     edx, [ebp+EXTFS.inodeBuffer]
1857
        lea     edx, [ebp+EXTFS.inodeBuffer]
1978
        movzx   edx, [edx+INODE.accessMode]
1858
        movzx   edx, [edx+INODE.accessMode]
1979
        and     edx, TYPE_MASK
1859
        and     edx, TYPE_MASK
1980
        cmp     edx, DIRECTORY
1860
        cmp     edx, DIRECTORY
1981
        jne     .file
1861
        jne     .file
1982
        push    ebx ecx edx 0
1862
        push    ebx ecx edx 0
1983
        lea     esi, [ebp+EXTFS.inodeBuffer]
1863
        lea     esi, [ebp+EXTFS.inodeBuffer]
1984
.checkDirectory:
1864
.checkDirectory:
1985
        mov     ecx, [esp]
1865
        mov     ecx, [esp]
1986
        call    extfsGetFileBlock
1866
        call    extfsGetFileBlock
1987
        jc      .not_empty_eax
1867
        jc      .not_empty_eax
1988
        test    ecx, ecx
1868
        test    ecx, ecx
1989
        jz      .empty
1869
        jz      .empty
1990
        mov     eax, ecx
1870
        mov     eax, ecx
1991
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1871
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1992
        call    extfsReadBlock
1872
        call    extfsReadBlock
1993
        jc      .not_empty_eax
1873
        jc      .not_empty_eax
1994
        mov     edx, ebx
1874
        mov     edx, ebx
1995
        add     edx, [ebp+EXTFS.bytesPerBlock]
1875
        add     edx, [ebp+EXTFS.bytesPerBlock]
1996
        movzx   ecx, [ebx+DIRENTRY.entryLength]
1876
        movzx   ecx, [ebx+DIRENTRY.entryLength]
1997
        add     ebx, ecx
1877
        add     ebx, ecx
1998
.dir_entry:
1878
.dir_entry:
1999
        cmp     byte [ebx+DIRENTRY.nameLength], 1
1879
        cmp     byte [ebx+DIRENTRY.nameLength], 1
2000
        jne     @f
1880
        jne     @f
2001
        cmp     byte [ebx+DIRENTRY.name], '.'
1881
        cmp     byte [ebx+DIRENTRY.name], '.'
2002
        jne     .not_empty
1882
        jne     .not_empty
2003
@@:
1883
@@:
2004
        cmp     byte [ebx+DIRENTRY.nameLength], 2
1884
        cmp     byte [ebx+DIRENTRY.nameLength], 2
2005
        jne     .not_empty
1885
        jne     .not_empty
2006
        cmp     word [ebx+DIRENTRY.name], '..'
1886
        cmp     word [ebx+DIRENTRY.name], '..'
2007
        jne     .not_empty
1887
        jne     .not_empty
2008
        movzx   ecx, [ebx+DIRENTRY.entryLength]
1888
        movzx   ecx, [ebx+DIRENTRY.entryLength]
2009
        add     ebx, ecx
1889
        add     ebx, ecx
2010
        cmp     ebx, edx
1890
        cmp     ebx, edx
2011
        jb      .dir_entry
1891
        jb      .dir_entry
2012
        inc     dword[esp]
1892
        inc     dword[esp]
2013
        jmp     .checkDirectory
1893
        jmp     .checkDirectory
2014
 
1894
 
2015
.empty:
1895
.empty:
2016
        pop     edx edx ecx ebx
1896
        pop     edx edx ecx ebx
2017
.file:
1897
.file:
2018
        mov     eax, ecx
1898
        mov     eax, ecx
2019
        push    ebx ecx
1899
        push    ebx ecx
2020
        call    unlinkInode
1900
        call    unlinkInode
2021
        cmp     eax, -1
1901
        cmp     eax, -1
2022
        je      .error_stack8
1902
        je      .error_stack8
2023
        pop     ebx
1903
        pop     ebx
2024
        test    eax, eax
1904
        test    eax, eax
2025
        jz      @f
1905
        jz      @f
2026
        xor     eax, eax
1906
        xor     eax, eax
2027
        cmp     edx, DIRECTORY
1907
        cmp     edx, DIRECTORY
2028
        jnz     .error_stack4_eax   ; hardlinks
1908
        jnz     .error_stack4_eax   ; hardlinks
2029
        mov     eax, [esp]
1909
        mov     eax, [esp]
2030
        call    unlinkInode
1910
        call    unlinkInode
2031
@@:
1911
@@:
2032
        mov     eax, [esp]
1912
        mov     eax, [esp]
2033
        lea     ebx, [ebp+EXTFS.inodeBuffer]
1913
        lea     ebx, [ebp+EXTFS.inodeBuffer]
2034
        call    readInode
1914
        call    readInode
2035
        jc      .error_stack4_eax
1915
        jc      .error_stack4_eax
2036
; free file's data
1916
; free file's data
2037
        lea     esi, [ebp+EXTFS.inodeBuffer]
1917
        lea     esi, [ebp+EXTFS.inodeBuffer]
2038
        xor     ecx, ecx
1918
        xor     ecx, ecx
2039
@@:
1919
@@:
2040
        push    ecx
1920
        push    ecx
2041
        call    extfsGetFileBlock
1921
        call    extfsGetFileBlock
2042
        jc      .error_stack8_eax
1922
        jc      .error_stack8_eax
2043
        mov     eax, ecx
1923
        mov     eax, ecx
2044
        test    eax, eax
1924
        test    eax, eax
2045
        jz      @f
1925
        jz      @f
2046
        xor     ecx, ecx
1926
        xor     ecx, ecx
2047
        call    extfsResourceFree
1927
        call    extfsResourceFree
2048
        pop     ecx
1928
        pop     ecx
2049
        inc     ecx
1929
        inc     ecx
2050
        jmp     @b
1930
        jmp     @b
2051
 
1931
 
2052
@@: ; free indirect blocks
1932
@@: ; free indirect blocks
2053
        pop     ecx
1933
        pop     ecx
2054
        push    edx
1934
        push    edx
2055
        lea     edi, [ebp+EXTFS.inodeBuffer]
1935
        lea     edi, [ebp+EXTFS.inodeBuffer]
2056
        mov     eax, [edi+INODE.addressBlock]
1936
        mov     eax, [edi+INODE.addressBlock]
2057
        test    eax, eax
1937
        test    eax, eax
2058
        jz      .success
1938
        jz      .success
2059
        xor     ecx, ecx
1939
        xor     ecx, ecx
2060
        call    extfsResourceFree
1940
        call    extfsResourceFree
2061
        mov     eax, [edi+INODE.doubleAddress]
1941
        mov     eax, [edi+INODE.doubleAddress]
2062
        call    freeDoublyIndirectBlock
1942
        call    freeDoublyIndirectBlock
2063
        cmp     eax, 1
1943
        cmp     eax, 1
2064
        je      .success
1944
        je      .success
2065
        mov     eax, [edi+INODE.tripleAddress]
1945
        mov     eax, [edi+INODE.tripleAddress]
2066
        test    eax, eax
1946
        test    eax, eax
2067
        jz      .success
1947
        jz      .success
-
 
1948
        xor     edx, edx
-
 
1949
        mov     ecx, eax
-
 
1950
@@:
2068
        push    eax
1951
        mov     eax, ecx
2069
        mov     ebx, [ebp+EXTFS.tempBlockBuffer]
1952
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
2070
        call    extfsReadBlock
1953
        call    extfsReadBlock
2071
        pop     ecx
-
 
2072
        jc      .error_stack8_eax
1954
        jc      .error_stack8_eax
2073
        mov     eax, ecx
-
 
2074
        xor     ecx, ecx
-
 
2075
        call    extfsResourceFree
-
 
2076
        mov     edx, ebx
-
 
2077
        add     edx, [ebp+EXTFS.bytesPerBlock]
-
 
2078
@@:
-
 
2079
        mov     eax, [ebx]
1955
        mov     eax, [ebx+edx]
2080
        test    eax, eax
1956
        test    eax, eax
2081
        jz      .success
1957
        jz      @f
2082
        push    ebx edx
1958
        push    ecx edx
2083
        call    freeDoublyIndirectBlock
1959
        call    freeDoublyIndirectBlock
2084
        pop     edx ebx
1960
        pop     edx ecx
2085
        cmp     eax, 1
1961
        cmp     eax, 1
2086
        je      .success
1962
        je      @f
2087
        add     ebx, 4
1963
        add     edx, 4
2088
        cmp     ebx, edx
1964
        cmp     edx, [ebp+EXTFS.bytesPerBlock]
2089
        jb      @b
1965
        jb      @b
-
 
1966
@@:
-
 
1967
        mov     eax, ecx
-
 
1968
        xor     ecx, ecx
-
 
1969
        call    extfsResourceFree
2090
.success:   ; clear the inode, and add deletion time
1970
.success:   ; clear the inode, and add deletion time
2091
        xor     eax, eax
1971
        xor     eax, eax
2092
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
1972
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
2093
        rep stosb
1973
        rep stosb
2094
        lea     edi, [ebp+EXTFS.inodeBuffer]
1974
        lea     edi, [ebp+EXTFS.inodeBuffer]
2095
        call    fsGetTime
1975
        call    fsGetTime
2096
        pop     edx
1976
        pop     edx
2097
        add     eax, 978307200
1977
        add     eax, 978307200
2098
        mov     [edi+INODE.deletedTime], eax
1978
        mov     [edi+INODE.deletedTime], eax
2099
        mov     eax, [esp]
1979
        mov     eax, [esp]
2100
        mov     ebx, edi
1980
        mov     ebx, edi
2101
        call    writeInode
1981
        call    writeInode
2102
        jc      .error_stack4_eax
1982
        jc      .error_stack4_eax
2103
        cmp     edx, DIRECTORY
1983
        cmp     edx, DIRECTORY
2104
        jne     @f
1984
        jne     @f
2105
        mov     eax, [esp]
1985
        mov     eax, [esp]
2106
        dec     eax
1986
        dec     eax
2107
        xor     edx, edx
1987
        xor     edx, edx
2108
        div     [ebp+EXTFS.superblock.inodesPerGroup]
1988
        div     [ebp+EXTFS.superblock.inodesPerGroup]
2109
        push    eax
1989
        push    eax
2110
        call    extfsReadDescriptor
1990
        call    extfsReadDescriptor
2111
        jc      .error_stack8
1991
        jc      .error_stack8
2112
        dec     [eax+BGDESCR.directoriesCount]
1992
        dec     [eax+BGDESCR.directoriesCount]
2113
        pop     eax
1993
        pop     eax
2114
        call    extfsWriteDescriptor
1994
        call    extfsWriteDescriptor
2115
@@: ; free inode
1995
@@: ; free inode
2116
        pop     eax
1996
        pop     eax
2117
        dec     eax
1997
        dec     eax
2118
        xor     ecx, ecx
1998
        xor     ecx, ecx
2119
        inc     ecx
1999
        inc     ecx
2120
        call    extfsResourceFree
2000
        call    extfsResourceFree
2121
        push    eax
2001
        push    eax
2122
.disk_sync:
2002
.disk_sync:
2123
        call    writeSuperblock
2003
        call    writeSuperblock
2124
        mov     esi, [ebp+PARTITION.Disk]
2004
        mov     esi, [ebp+PARTITION.Disk]
2125
        call    disk_sync
2005
        call    disk_sync
2126
.ret:
2006
.ret:
2127
        call    ext_unlock
2007
        call    ext_unlock
2128
        xor     ebx, ebx
2008
        xor     ebx, ebx
2129
        pop     eax
2009
        pop     eax
2130
        ret
2010
        ret
2131
 
2011
 
2132
.not_empty:
2012
.not_empty:
2133
        pop     eax
2013
        pop     eax
2134
.error_stack8:
2014
.error_stack8:
2135
        pop     eax eax
2015
        pop     eax eax
2136
        push    ERROR_ACCESS_DENIED
2016
        push    ERROR_ACCESS_DENIED
2137
        jmp     .disk_sync
2017
        jmp     .disk_sync
2138
 
2018
 
2139
.not_empty_eax:
2019
.not_empty_eax:
2140
        pop     ebx
2020
        pop     ebx
2141
.error_stack8_eax:
2021
.error_stack8_eax:
2142
        pop     ebx
2022
        pop     ebx
2143
.error_stack4_eax:
2023
.error_stack4_eax:
2144
        pop     ebx
2024
        pop     ebx
2145
.error:
2025
.error:
2146
        push    eax
2026
        push    eax
2147
        jmp     .disk_sync
2027
        jmp     .disk_sync
2148
 
2028
 
2149
;----------------------------------------------------------------
2029
;----------------------------------------------------------------
2150
ext_CreateFolder:
2030
ext_CreateFolder:
2151
        call    extfsWritingInit
2031
        call    extfsWritingInit
2152
        call    findInode
2032
        call    findInode
2153
        jnc     .success    ; exist
2033
        jnc     .success    ; exist
2154
        test    edi, edi
2034
        test    edi, edi
2155
        jz      .error
2035
        jz      .error
2156
        mov     eax, esi
2036
        mov     eax, esi
2157
        xor     ebx, ebx
2037
        xor     ebx, ebx
2158
        inc     ebx
2038
        inc     ebx
2159
        call    extfsResourceAlloc
2039
        call    extfsResourceAlloc
2160
        jc      .error
2040
        jc      .error
2161
        inc     ebx
2041
        inc     ebx
2162
        push    ebx esi edi
2042
        push    ebx esi edi
2163
        xor     al, al
2043
        xor     al, al
2164
        lea     edi, [ebp+EXTFS.inodeBuffer]
2044
        lea     edi, [ebp+EXTFS.inodeBuffer]
2165
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
2045
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
2166
        rep stosb
2046
        rep stosb
2167
        lea     edi, [ebp+EXTFS.inodeBuffer]
2047
        lea     edi, [ebp+EXTFS.inodeBuffer]
2168
        call    fsGetTime
2048
        call    fsGetTime
2169
        add     eax, 978307200
2049
        add     eax, 978307200
2170
        mov     [edi+INODE.accessedTime], eax
2050
        mov     [edi+INODE.accessedTime], eax
2171
        mov     [edi+INODE.dataModified], eax
2051
        mov     [edi+INODE.dataModified], eax
2172
        mov     ebx, edi
2052
        mov     ebx, edi
2173
        pop     edi esi edx
2053
        pop     edi esi edx
2174
; edx = allocated inode number, edi -> filename, esi = parent inode number
2054
; edx = allocated inode number, edi -> filename, esi = parent inode number
2175
        mov     [ebx+INODE.accessMode], DIRECTORY or PERMISSIONS
2055
        mov     [ebx+INODE.accessMode], DIRECTORY or PERMISSIONS
2176
        mov     eax, edx
2056
        mov     eax, edx
2177
        call    writeInode
2057
        call    writeInode
2178
        jc      .error
2058
        jc      .error
2179
; link to self
2059
; link to self
2180
        push    edx esi
2060
        push    edx esi
2181
        mov     eax, edx
2061
        mov     eax, edx
2182
        mov     ebx, eax
2062
        mov     ebx, eax
2183
        mov     dl, DIR_DIRECTORY
2063
        mov     dl, DIR_DIRECTORY
2184
        mov     esi, self_link
2064
        mov     esi, self_link
2185
        call    linkInode
2065
        call    linkInode
2186
        pop     esi edx
2066
        pop     esi edx
2187
        jc      .error
2067
        jc      .error
2188
; link to parent
2068
; link to parent
2189
        push    edx esi
2069
        push    edx esi
2190
        mov     eax, ebx
2070
        mov     eax, ebx
2191
        mov     ebx, esi
2071
        mov     ebx, esi
2192
        mov     dl, DIR_DIRECTORY
2072
        mov     dl, DIR_DIRECTORY
2193
        mov     esi, parent_link
2073
        mov     esi, parent_link
2194
        call    linkInode
2074
        call    linkInode
2195
        pop     esi edx
2075
        pop     esi edx
2196
        jc      .error
2076
        jc      .error
2197
; link parent to child
2077
; link parent to child
2198
        mov     eax, esi
2078
        mov     eax, esi
2199
        mov     ebx, edx
2079
        mov     ebx, edx
2200
        mov     esi, edi
2080
        mov     esi, edi
2201
        mov     dl, DIR_DIRECTORY
2081
        mov     dl, DIR_DIRECTORY
2202
        call    linkInode
2082
        call    linkInode
2203
        jc      .error
2083
        jc      .error
2204
        mov     eax, ebx
2084
        mov     eax, ebx
2205
        dec     eax
2085
        dec     eax
2206
        xor     edx, edx
2086
        xor     edx, edx
2207
        div     [ebp+EXTFS.superblock.inodesPerGroup]
2087
        div     [ebp+EXTFS.superblock.inodesPerGroup]
2208
        mov     edx, eax
2088
        mov     edx, eax
2209
        call    extfsReadDescriptor
2089
        call    extfsReadDescriptor
2210
        jc      @f
2090
        jc      @f
2211
        inc     [eax+BGDESCR.directoriesCount]
2091
        inc     [eax+BGDESCR.directoriesCount]
2212
        mov     eax, edx
2092
        mov     eax, edx
2213
        call    extfsWriteDescriptor
2093
        call    extfsWriteDescriptor
2214
.success:
2094
.success:
2215
.error:
2095
.error:
2216
        push    eax
2096
        push    eax
2217
        call    writeSuperblock
2097
        call    writeSuperblock
2218
        mov     esi, [ebp+PARTITION.Disk]
2098
        mov     esi, [ebp+PARTITION.Disk]
2219
        call    disk_sync
2099
        call    disk_sync
2220
        call    ext_unlock
2100
        call    ext_unlock
2221
        pop     eax
2101
        pop     eax
2222
        ret
2102
        ret
2223
 
2103
 
2224
@@:
2104
@@:
2225
        movi    eax, ERROR_DEVICE
2105
        movi    eax, ERROR_DEVICE
2226
        jmp     .error
2106
        jmp     .error
2227
 
2107
 
2228
self_link   db ".", 0
2108
self_link   db ".", 0
2229
parent_link db "..", 0
2109
parent_link db "..", 0
2230
 
2110
 
2231
;----------------------------------------------------------------
2111
;----------------------------------------------------------------
2232
ext_CreateFile:
2112
ext_CreateFile:
2233
        call    extfsWritingInit
2113
        call    extfsWritingInit
2234
        push    0 ebx
2114
        push    0 ebx
2235
        call    findInode
2115
        call    findInode
2236
        jnc     .exist
2116
        jnc     .exist
2237
        test    edi, edi
2117
        test    edi, edi
2238
        jz      .error
2118
        jz      .error
2239
        mov     eax, esi
2119
        mov     eax, esi
2240
        xor     ebx, ebx
2120
        xor     ebx, ebx
2241
        inc     ebx
2121
        inc     ebx
2242
        call    extfsResourceAlloc
2122
        call    extfsResourceAlloc
2243
        jc      .error
2123
        jc      .error
2244
        inc     ebx
2124
        inc     ebx
2245
        push    ebx ebx esi edi
2125
        push    ebx ebx esi edi
2246
        xor     al, al
2126
        xor     al, al
2247
        lea     edi, [ebp+EXTFS.inodeBuffer]
2127
        lea     edi, [ebp+EXTFS.inodeBuffer]
2248
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
2128
        movzx   ecx, [ebp+EXTFS.superblock.inodeSize]
2249
        rep stosb
2129
        rep stosb
2250
        lea     edi, [ebp+EXTFS.inodeBuffer]
2130
        lea     edi, [ebp+EXTFS.inodeBuffer]
2251
        call    fsGetTime
2131
        call    fsGetTime
2252
        add     eax, 978307200
2132
        add     eax, 978307200
2253
        mov     [edi+INODE.accessedTime], eax
2133
        mov     [edi+INODE.accessedTime], eax
2254
        mov     [edi+INODE.dataModified], eax
2134
        mov     [edi+INODE.dataModified], eax
2255
        mov     ebx, edi
2135
        mov     ebx, edi
2256
        pop     edi esi edx
2136
        pop     edi esi edx
2257
; edx = allocated inode number, edi -> filename, esi = parent inode number
2137
; edx = allocated inode number, edi -> filename, esi = parent inode number
2258
        mov     [ebx+INODE.accessMode], FLAG_FILE or PERMISSIONS
2138
        mov     [ebx+INODE.accessMode], FLAG_FILE or PERMISSIONS
2259
        mov     eax, edx
2139
        mov     eax, edx
2260
        call    writeInode
2140
        call    writeInode
2261
        jc      .error2
2141
        jc      .error2
2262
; link parent to child
2142
; link parent to child
2263
        mov     eax, esi
2143
        mov     eax, esi
2264
        mov     ebx, edx
2144
        mov     ebx, edx
2265
        mov     esi, edi
2145
        mov     esi, edi
2266
        mov     dl, DIR_FLAG_FILE
2146
        mov     dl, DIR_FLAG_FILE
2267
        call    linkInode
2147
        call    linkInode
2268
        jc      .error2
2148
        jc      .error2
2269
        pop     esi ebx
2149
        pop     esi ebx
2270
        push    ebx esi
2150
        push    ebx esi
2271
        mov     ecx, [ebx+12]
2151
        mov     ecx, [ebx+12]
2272
        jmp     ext_WriteFile.start
2152
        jmp     ext_WriteFile.start
2273
 
2153
 
2274
.exist:
2154
.exist:
2275
        lea     edx, [ebp+EXTFS.inodeBuffer]
2155
        lea     edx, [ebp+EXTFS.inodeBuffer]
2276
        movi    eax, ERROR_ACCESS_DENIED
2156
        movi    eax, ERROR_ACCESS_DENIED
2277
        test    [edx+INODE.accessMode], FLAG_FILE
2157
        test    [edx+INODE.accessMode], FLAG_FILE
2278
        jz      .error  ; not a file
2158
        jz      .error  ; not a file
2279
        pop     ebx
2159
        pop     ebx
2280
        push    ebx esi
2160
        push    ebx esi
2281
        mov     ecx, [ebx+12]
2161
        mov     ecx, [ebx+12]
2282
        call    extfsTruncateFile
2162
        call    extfsTruncateFile
2283
        jnc     ext_WriteFile.start
2163
        jnc     ext_WriteFile.start
2284
.error2:
2164
.error2:
2285
        pop     ebx
2165
        pop     ebx
2286
.error:
2166
.error:
2287
        push    eax
2167
        push    eax
2288
        call    ext_unlock
2168
        call    ext_unlock
2289
        pop     eax ebx ebx
2169
        pop     eax ebx ebx
2290
        xor     ebx, ebx
2170
        xor     ebx, ebx
2291
        ret
2171
        ret
2292
 
2172
 
2293
;----------------------------------------------------------------
2173
;----------------------------------------------------------------
2294
ext_WriteFile:
2174
ext_WriteFile:
2295
        call    extfsWritingInit
2175
        call    extfsWritingInit
2296
        push    0 ebx
2176
        push    0 ebx
2297
        call    findInode
2177
        call    findInode
2298
        pop     ebx
2178
        pop     ebx
2299
        push    ebx esi
2179
        push    ebx esi
2300
        jc      .error
2180
        jc      .error
2301
        lea     edx, [ebp+EXTFS.inodeBuffer]
2181
        lea     edx, [ebp+EXTFS.inodeBuffer]
2302
        movi    eax, ERROR_ACCESS_DENIED
2182
        movi    eax, ERROR_ACCESS_DENIED
2303
        test    [edx+INODE.accessMode], FLAG_FILE
2183
        test    [edx+INODE.accessMode], FLAG_FILE
2304
        jz      .error  ; not a file
2184
        jz      .error  ; not a file
2305
        mov     ecx, [ebx+4]
2185
        mov     ecx, [ebx+4]
2306
        add     ecx, [ebx+12]
2186
        add     ecx, [ebx+12]
2307
.start:
2187
.start:
2308
        mov     eax, esi
2188
        mov     eax, esi
2309
        call    extfsExtendFile
2189
        call    extfsExtendFile
2310
        jc      .error
2190
        jc      .error
2311
        mov     eax, [ebx+4]
2191
        mov     eax, [ebx+4]
2312
        mov     ecx, [ebx+12]
2192
        mov     ecx, [ebx+12]
2313
        mov     esi, [ebx+16]
2193
        mov     ebx, [ebx+16]
2314
        push    eax
2194
        push    eax
2315
        xor     edx, edx
2195
        xor     edx, edx
2316
        div     [ebp+EXTFS.bytesPerBlock]
2196
        div     [ebp+EXTFS.bytesPerBlock]
2317
        test    edx, edx
2197
        test    edx, edx
2318
        jz      .start_aligned
2198
        jz      .start_aligned
2319
        mov     ebx, [ebp+EXTFS.bytesPerBlock]
2199
        mov     esi, [ebp+EXTFS.bytesPerBlock]
2320
        sub     ebx, edx
2200
        sub     esi, edx
2321
        cmp     ebx, ecx
2201
        cmp     esi, ecx
2322
        jbe     @f
2202
        jbe     @f
2323
        mov     ebx, ecx
2203
        mov     esi, ecx
2324
@@:
2204
@@:
2325
        push    eax
2205
        mov     edi, eax
2326
        call    extfsReadFileBlock
2206
        call    extfsReadFileBlock
2327
        pop     edi
-
 
2328
        jc      .error_inode_size
2207
        jc      .error_inode_size
2329
        mov     eax, edi
2208
        mov     eax, edi
2330
        push    ecx
2209
        push    ebx ecx
2331
        mov     ecx, ebx
2210
        mov     ecx, esi
-
 
2211
        mov     edi, [ebp+EXTFS.mainBlockBuffer]
2332
        mov     edi, ebx
2212
        mov     esi, ebx
-
 
2213
        mov     ebx, edi
2333
        add     edi, edx
2214
        add     edi, edx
-
 
2215
        mov     edx, ecx
2334
        rep movsb
2216
        rep movsb
2335
        pop     ecx
-
 
2336
        call    extfsWriteFileBlock
2217
        call    extfsWriteFileBlock
-
 
2218
        pop     ecx ebx
2337
        jc      .error_inode_size
2219
        jc      .error_inode_size
2338
        add     [esp], ebx
2220
        add     [esp], edx
-
 
2221
        add     ebx, edx
2339
        sub     ecx, ebx
2222
        sub     ecx, edx
2340
        jz      .write_inode
2223
        jz      .write_inode
2341
.start_aligned:
2224
.start_aligned:
2342
        cmp     ecx, [ebp+EXTFS.bytesPerBlock]
2225
        cmp     ecx, [ebp+EXTFS.bytesPerBlock]
2343
        jb      @f
2226
        jb      @f
2344
        mov     eax, [esp]
2227
        mov     eax, [esp]
2345
        xor     edx, edx
2228
        xor     edx, edx
2346
        div     [ebp+EXTFS.bytesPerBlock]
2229
        div     [ebp+EXTFS.bytesPerBlock]
2347
        mov     edx, [esp+4]
-
 
2348
        push    eax
-
 
2349
        call    extfsEraseFileBlock
-
 
2350
        pop     edi
-
 
2351
        jc      .error_inode_size
-
 
2352
        mov     eax, edi
-
 
2353
        push    ecx
-
 
2354
        mov     ecx, [ebp+EXTFS.bytesPerBlock]
-
 
2355
        mov     edi, [ebp+EXTFS.mainBlockBuffer]
-
 
2356
        rep movsb
-
 
2357
        pop     ecx
-
 
2358
        call    extfsWriteFileBlock
2230
        call    extfsWriteFileBlock
2359
        jc      .error_inode_size
2231
        jc      .error_inode_size
2360
        mov     eax, [ebp+EXTFS.bytesPerBlock]
2232
        mov     eax, [ebp+EXTFS.bytesPerBlock]
2361
        sub     ecx, eax
2233
        sub     ecx, eax
-
 
2234
        add     ebx, eax
2362
        add     [esp], eax
2235
        add     [esp], eax
2363
        jmp     .start_aligned
2236
        jmp     .start_aligned
-
 
2237
 
2364
@@:         ; Handle the remaining bytes.
2238
@@: ; handle the remaining bytes
2365
        test    ecx, ecx
2239
        test    ecx, ecx
2366
        jz      .write_inode
2240
        jz      .write_inode
2367
        mov     eax, [esp]
2241
        mov     eax, [esp]
2368
        xor     edx, edx
2242
        xor     edx, edx
2369
        div     [ebp+EXTFS.bytesPerBlock]
2243
        div     [ebp+EXTFS.bytesPerBlock]
2370
        push    eax
-
 
2371
        call    extfsReadFileBlock
-
 
2372
        pop     eax
-
 
2373
        jnc     @f
-
 
2374
        mov     edx, [esp+4]
-
 
2375
        push    eax
-
 
2376
        call    extfsEraseFileBlock
-
 
2377
        pop     edi
-
 
2378
        jc      .error_inode_size
-
 
2379
        mov     eax, edi
-
 
2380
@@:
-
 
2381
        push    ecx
2244
        push    ecx
-
 
2245
        mov     esi, ebx
2382
        mov     edi, [ebp+EXTFS.mainBlockBuffer]
2246
        mov     edi, [ebp+EXTFS.mainBlockBuffer]
-
 
2247
        mov     ebx, edi
2383
        rep movsb
2248
        rep movsb
2384
        pop     ecx
2249
        pop     ecx
2385
        call    extfsWriteFileBlock
2250
        call    extfsWriteFileBlock
2386
        jc      .error_inode_size
2251
        jc      .error_inode_size
2387
        add     [esp], ecx
-
 
2388
        xor     ecx, ecx
2252
        xor     ecx, ecx
2389
.error_inode_size:
2253
.error_inode_size:
2390
        mov     [esp+12], eax
2254
        mov     [esp+12], eax
2391
.write_inode:
2255
.write_inode:
2392
        lea     ebx, [ebp+EXTFS.inodeBuffer]
2256
        lea     ebx, [ebp+EXTFS.inodeBuffer]
2393
        pop     eax eax
2257
        pop     eax eax
2394
        call    writeInode
2258
        call    writeInode
2395
        pop     ebx
2259
        pop     ebx
2396
        mov     ebx, [ebx+12]
2260
        mov     ebx, [ebx+12]
2397
        sub     ebx, ecx
2261
        sub     ebx, ecx
2398
        test    eax, eax
2262
        test    eax, eax
2399
        jz      @f
2263
        jz      @f
2400
        mov     [esp], eax
2264
        mov     [esp], eax
2401
@@:
2265
@@:
2402
        call    writeSuperblock
2266
        call    writeSuperblock
2403
        mov     esi, [ebp+PARTITION.Disk]
2267
        mov     esi, [ebp+PARTITION.Disk]
2404
        call    disk_sync
2268
        call    disk_sync
2405
@@:
2269
@@:
2406
        call    ext_unlock
2270
        call    ext_unlock
2407
        pop     eax
2271
        pop     eax
2408
        ret
2272
        ret
2409
 
2273
 
2410
.error:
2274
.error:
2411
        pop     ebx ebx ebx
2275
        pop     ebx ebx ebx
2412
        push    eax
2276
        push    eax
2413
        jmp     @b
2277
        jmp     @b
2414
 
2278
 
2415
;----------------------------------------------------------------
2279
;----------------------------------------------------------------
2416
ext_SetFileEnd:
2280
ext_SetFileEnd:
2417
        call    extfsWritingInit
2281
        call    extfsWritingInit
2418
        pushd   [ebx+4]
2282
        pushd   [ebx+4]
2419
        call    findInode
2283
        call    findInode
2420
        pop     ecx
-
 
2421
        jc      @f
2284
        jc      .error
2422
        lea     edx, [ebp+EXTFS.inodeBuffer]
2285
        lea     edi, [ebp+EXTFS.inodeBuffer]
2423
        movi    eax, ERROR_ACCESS_DENIED
2286
        movi    eax, ERROR_ACCESS_DENIED
2424
        cmp     [edx+INODE.accessMode], FLAG_FILE
2287
        cmp     [edi+INODE.accessMode], FLAG_FILE
2425
        jnz     @f      ; not a file
2288
        jnz     .error  ; not a file
-
 
2289
        pop     ecx
-
 
2290
        push    esi
-
 
2291
        mov     ebx, [edi+INODE.fileSize]
2426
        mov     eax, esi
2292
        mov     eax, esi
2427
        call    extfsExtendFile
2293
        cmp     ebx, ecx
2428
        jc      @f
2294
        jc      @f
2429
        call    extfsTruncateFile
2295
        call    extfsTruncateFile
-
 
2296
        jc      .error
-
 
2297
        jmp     .done
-
 
2298
 
-
 
2299
@@:
-
 
2300
        call    extfsExtendFile
-
 
2301
        jc      .error
-
 
2302
        sub     ecx, ebx
-
 
2303
        mov     eax, ebx
-
 
2304
        xor     edx, edx
-
 
2305
        div     [ebp+EXTFS.bytesPerBlock]
-
 
2306
        mov     edi, eax
-
 
2307
        test    edx, edx
-
 
2308
        jz      .start_aligned
-
 
2309
        call    extfsReadFileBlock
-
 
2310
        jc      .error
-
 
2311
        mov     eax, [ebp+EXTFS.bytesPerBlock]
-
 
2312
        sub     eax, edx
-
 
2313
        cmp     eax, ecx
2430
        jc      @f
2314
        jbe     @f
-
 
2315
        mov     eax, ecx
-
 
2316
@@:
-
 
2317
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
-
 
2318
        push    edi ecx
-
 
2319
        mov     ecx, eax
-
 
2320
        mov     edi, ebx
-
 
2321
        add     edi, edx
-
 
2322
        xor     eax, eax
-
 
2323
        mov     edx, ecx
-
 
2324
        rep stosb
-
 
2325
        pop     ecx edi
-
 
2326
        mov     eax, edi
-
 
2327
        call    extfsWriteFileBlock
-
 
2328
        jc      .error
-
 
2329
        sub     ecx, edx
-
 
2330
        jz      .done
-
 
2331
        inc     edi
-
 
2332
.start_aligned:
-
 
2333
        mov     eax, ecx
-
 
2334
        mov     ecx, [ebp+EXTFS.bytesPerBlock]
-
 
2335
        dec     eax
-
 
2336
        xor     edx, edx
-
 
2337
        div     ecx
-
 
2338
        inc     eax
-
 
2339
        mov     ebx, [ebp+EXTFS.mainBlockBuffer]
-
 
2340
        push    eax edi
-
 
2341
        mov     edi, ebx
-
 
2342
        xor     eax, eax
-
 
2343
        rep stosb
-
 
2344
        pop     edi ecx
-
 
2345
@@:
2431
        mov     eax, esi
2346
        mov     eax, edi
-
 
2347
        call    extfsWriteFileBlock
-
 
2348
        jc      .error
-
 
2349
        inc     edi
-
 
2350
        loop    @b
-
 
2351
.done:
-
 
2352
        mov     eax, [esp]
2432
        lea     ebx, [ebp+EXTFS.inodeBuffer]
2353
        lea     ebx, [ebp+EXTFS.inodeBuffer]
2433
        call    writeInode
2354
        call    writeInode
2434
@@:
-
 
2435
        push    eax
2355
        jc      .error
2436
        call    writeSuperblock
2356
        call    writeSuperblock
2437
        mov     esi, [ebp+PARTITION.Disk]
2357
        mov     esi, [ebp+PARTITION.Disk]
2438
        call    disk_sync
2358
        call    disk_sync
-
 
2359
        xor     eax, eax
-
 
2360
.error:
-
 
2361
        mov     [esp], eax
2439
        call    ext_unlock
2362
        call    ext_unlock
2440
        pop     eax
2363
        pop     eax
2441
        ret
2364
        ret