Subversion Repositories Kolibri OS

Rev

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

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