Subversion Repositories Kolibri OS

Rev

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

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