Subversion Repositories Kolibri OS

Rev

Rev 6880 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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