Subversion Repositories Kolibri OS

Rev

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

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