Subversion Repositories Kolibri OS

Rev

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

Rev 4429 Rev 4923
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Contains ext2 structures, and macros.                        ;;
3
;; Contains ext2 structures, and macros.                        ;;
4
;;                                                              ;;
4
;;                                                              ;;
5
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
5
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
6
;; Distributed under the terms of the new BSD license.          ;;
6
;; Distributed under terms of the GNU General Public License    ;;
7
;;                                                              ;;
7
;;                                                              ;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 
9
 
-
 
10
$Revision: 4891 $
-
 
11
 
9
 
12
 
10
; Future jobs for driver, in order of preference:
13
; Future jobs for driver, in order of preference:
11
;     * clean up existing extents support.
14
;     * clean up existing extents support.
12
;     * add b-tree directories support.
15
;     * add b-tree directories support.
13
;     * add long file support.
16
;     * add long file support.
14
;     * add journal support.
17
;     * add journal support.
15
;     * add minor features that come with ext3/4.
18
;     * add minor features that come with ext3/4.
16
 
19
 
17
; Recommended move to some kernel-wide bitmap handling code (with a bit of abstraction, of course).
20
; Recommended move to some kernel-wide bitmap handling code (with a bit of abstraction, of course).
18
 
21
 
19
;---------------------------------------------------------------------
22
;---------------------------------------------------------------------
20
; Clears a bit.
23
; Clears a bit.
21
; Input:        eax = index into bitmap.
24
; Input:        eax = index into bitmap.
22
;               [EXTFS.ext2_save_block] = address of bitmap.
25
;               [EXTFS.ext2_save_block] = address of bitmap.
23
;               ebp = address of EXTFS.
26
;               ebp = address of EXTFS.
24
; Output:       Bit cleared.
27
; Output:       Bit cleared.
25
;               eax = non-zero, if already cleared.
28
;               eax = non-zero, if already cleared.
26
;---------------------------------------------------------------------
29
;---------------------------------------------------------------------
27
bitmap_clear_bit:
30
bitmap_clear_bit:
28
        push    ebx ecx edx
31
        push    ebx ecx edx
29
 
32
 
30
        xor     edx, edx
33
        xor     edx, edx
31
        mov     ecx, 8
34
        mov     ecx, 8
32
        div     ecx
35
        div     ecx
33
 
36
 
34
        add     eax, [ebp + EXTFS.ext2_save_block]
37
        add     eax, [ebp + EXTFS.ext2_save_block]
35
        
38
        
36
        ; Get the mask.
39
        ; Get the mask.
37
        mov     ebx, 1
40
        mov     ebx, 1
38
        mov     ecx, edx
41
        mov     ecx, edx
39
        shl     ebx, cl
42
        shl     ebx, cl
40
 
43
 
41
        test    [eax], ebx
44
        test    [eax], ebx
42
        jz      .cleared
45
        jz      .cleared
43
 
46
 
44
        not     ebx
47
        not     ebx
45
        and     [eax], ebx
48
        and     [eax], ebx
46
 
49
 
47
        xor     eax, eax
50
        xor     eax, eax
48
    .return:
51
    .return:
49
        pop     edx ecx ebx
52
        pop     edx ecx ebx
50
        ret
53
        ret
51
 
54
 
52
    ; Already cleared.
55
    ; Already cleared.
53
    .cleared:
56
    .cleared:
54
        xor     eax, eax
57
        xor     eax, eax
55
        not     eax
58
        not     eax
56
        jmp     .return
59
        jmp     .return
57
 
60
 
58
;---------------------------------------------------------------------
61
;---------------------------------------------------------------------
59
; Finds free bit in the bitmap.
62
; Finds free bit in the bitmap.
60
; Input:        ecx = number of bits in the bitmap.
63
; Input:        ecx = number of bits in the bitmap.
61
;               [EXTFS.ext2_save_block] = address of bitmap.
64
;               [EXTFS.ext2_save_block] = address of bitmap.
62
;               ebp = address of EXTFS.
65
;               ebp = address of EXTFS.
63
; Output:       eax = index of free bit in the bitmap; marked set.
66
; Output:       eax = index of free bit in the bitmap; marked set.
64
;                     0xFFFFFFFF if no free bit found.
67
;                     0xFFFFFFFF if no free bit found.
65
;---------------------------------------------------------------------
68
;---------------------------------------------------------------------
66
ext2_find_free_bit:
69
ext2_find_free_bit:
67
bitmap_find_free_bit:
70
bitmap_find_free_bit:
68
        push    esi ebx ecx edx
71
        push    esi ebx ecx edx
69
        mov     esi, [ebp + EXTFS.ext2_save_block]
72
        mov     esi, [ebp + EXTFS.ext2_save_block]
70
 
73
 
71
        ; Get total DWORDS in eax; total bits in last dword, if any, in edx.
74
        ; Get total DWORDS in eax; total bits in last dword, if any, in edx.
72
        xor     edx, edx
75
        xor     edx, edx
73
        mov     eax, ecx
76
        mov     eax, ecx
74
        mov     ecx, 32
77
        mov     ecx, 32
75
        div     ecx
78
        div     ecx
76
 
79
 
77
        mov     ecx, eax
80
        mov     ecx, eax
78
        xor     eax, eax
81
        xor     eax, eax
79
        push    edx
82
        push    edx
80
 
83
 
81
        test    ecx, ecx
84
        test    ecx, ecx
82
        jz      .last_bits
85
        jz      .last_bits
83
 
86
 
84
    ; Check in the DWORDS.
87
    ; Check in the DWORDS.
85
    .dwords:
88
    .dwords:
86
        mov     ebx, [esi]
89
        mov     ebx, [esi]
87
        not     ebx
90
        not     ebx
88
 
91
 
89
        bsf     edx, ebx
92
        bsf     edx, ebx
90
 
93
 
91
        ; If 0, then the original value would be 0xFFFFFFFF, hence no free bits.
94
        ; If 0, then the original value would be 0xFFFFFFFF, hence no free bits.
92
        jz      @F
95
        jz      @F
93
 
96
 
94
        ; We found the value. Let's return with it.
97
        ; We found the value. Let's return with it.
95
        add     esp, 4
98
        add     esp, 4
96
 
99
 
97
        add     eax, edx
100
        add     eax, edx
98
        jmp     .return
101
        jmp     .return
99
        
102
        
100
    @@:
103
    @@:
101
        add     esi, 4
104
        add     esi, 4
102
        add     eax, 32
105
        add     eax, 32
103
        loop    .dwords
106
        loop    .dwords
104
 
107
 
105
    .last_bits:
108
    .last_bits:
106
        ; Check in the last few bits.
109
        ; Check in the last few bits.
107
        pop     ecx
110
        pop     ecx
108
        test    ecx, ecx
111
        test    ecx, ecx
109
        jz      @F
112
        jz      @F
110
        
113
        
111
        mov     ebx, [esi]
114
        mov     ebx, [esi]
112
        not     ebx
115
        not     ebx
113
        bsf     ebx, edx
116
        bsf     ebx, edx
114
 
117
 
115
        ; If 0, no free bits.
118
        ; If 0, no free bits.
116
        jz      @F
119
        jz      @F
117
 
120
 
118
        ; If free bit is greater than the last known bit, then error.
121
        ; If free bit is greater than the last known bit, then error.
119
        cmp     edx, ecx
122
        cmp     edx, ecx
120
        jg      @F
123
        jg      @F
121
 
124
 
122
        add     eax, edx
125
        add     eax, edx
123
        jmp     .return
126
        jmp     .return
124
 
127
 
125
    @@:
128
    @@:
126
        ; Didn't find any free bits.
129
        ; Didn't find any free bits.
127
        xor     eax, eax
130
        xor     eax, eax
128
        not     eax
131
        not     eax
129
        jmp     @F
132
        jmp     @F
130
 
133
 
131
    .return:
134
    .return:
132
        mov     ecx, edx
135
        mov     ecx, edx
133
        mov     edx, 1
136
        mov     edx, 1
134
        shl     edx, cl
137
        shl     edx, cl
135
        or      [esi], edx
138
        or      [esi], edx
136
 
139
 
137
    @@:
140
    @@:
138
        pop     edx ecx ebx esi
141
        pop     edx ecx ebx esi
139
        ret
142
        ret
140
 
143
 
141
; Recommended move to some kernel-wide string handling code.
144
; Recommended move to some kernel-wide string handling code.
142
;---------------------------------------------------------------------
145
;---------------------------------------------------------------------
143
; Find the length of a string.
146
; Find the length of a string.
144
; Input:        esi = source.
147
; Input:        esi = source.
145
; Output:       length in ecx
148
; Output:       length in ecx
146
;---------------------------------------------------------------------
149
;---------------------------------------------------------------------
147
strlen:
150
strlen:
148
        push    eax esi
151
        push    eax esi
149
        xor     ecx, ecx
152
        xor     ecx, ecx
150
 
153
 
151
    @@:
154
    @@:
152
        lodsb
155
        lodsb
153
        test    al, al
156
        test    al, al
154
        jz      .ret
157
        jz      .ret
155
 
158
 
156
        inc     ecx
159
        inc     ecx
157
        jmp     @B
160
        jmp     @B
158
 
161
 
159
    .ret:
162
    .ret:
160
        pop     esi eax
163
        pop     esi eax
161
        ret
164
        ret
162
 
165
 
163
;---------------------------------------------------------------------
166
;---------------------------------------------------------------------
164
; Convert UTF-8 string to ASCII-string (codepage 866)
167
; Convert UTF-8 string to ASCII-string (codepage 866)
165
; Input:        esi = source.
168
; Input:        esi = source.
166
;               edi = buffer.
169
;               edi = buffer.
167
;               ecx = length of source.
170
;               ecx = length of source.
168
; Output:       destroys eax, esi, edi
171
; Output:       destroys eax, esi, edi
169
;---------------------------------------------------------------------
172
;---------------------------------------------------------------------
170
utf8_to_cp866:
173
utf8_to_cp866:
171
        ; Check for zero-length string.
174
        ; Check for zero-length string.
172
        jecxz   .return
175
        jecxz   .return
173
 
176
 
174
    .start:
177
    .start:
175
        lodsw
178
        lodsw
176
        cmp     al, 0x80
179
        cmp     al, 0x80
177
        jb      .ascii
180
        jb      .ascii
178
 
181
 
179
        xchg    al, ah                                  ; Big-endian.
182
        xchg    al, ah                                  ; Big-endian.
180
        cmp     ax, 0xd080
183
        cmp     ax, 0xd080
181
        jz      .yo1
184
        jz      .yo1
182
 
185
 
183
        cmp     ax, 0xd191
186
        cmp     ax, 0xd191
184
        jz      .yo2
187
        jz      .yo2
185
 
188
 
186
        cmp     ax, 0xd090
189
        cmp     ax, 0xd090
187
        jb      .unk
190
        jb      .unk
188
 
191
 
189
        cmp     ax, 0xd180
192
        cmp     ax, 0xd180
190
        jb      .rus1
193
        jb      .rus1
191
 
194
 
192
        cmp     ax, 0xd190
195
        cmp     ax, 0xd190
193
        jb      .rus2
196
        jb      .rus2
194
 
197
 
195
    .unk:
198
    .unk:
196
        mov     al, '_'
199
        mov     al, '_'
197
        jmp     .doit
200
        jmp     .doit
198
 
201
 
199
    .yo1:
202
    .yo1:
200
        mov     al, 0xf0                                ; Ё capital.
203
        mov     al, 0xf0                                ; Ё capital.
201
        jmp     .doit
204
        jmp     .doit
202
 
205
 
203
    .yo2:
206
    .yo2:
204
        mov     al, 0xf1                                ; ё small.
207
        mov     al, 0xf1                                ; ё small.
205
        jmp     .doit
208
        jmp     .doit
206
 
209
 
207
    .rus1:
210
    .rus1:
208
        sub     ax, 0xd090 - 0x80
211
        sub     ax, 0xd090 - 0x80
209
        jmp     .doit
212
        jmp     .doit
210
 
213
 
211
    .rus2:
214
    .rus2:
212
        sub     ax, 0xd18f - 0xEF
215
        sub     ax, 0xd18f - 0xEF
213
    
216
    
214
    .doit:
217
    .doit:
215
        stosb
218
        stosb
216
        sub     ecx, 2
219
        sub     ecx, 2
217
        ja      .start
220
        ja      .start
218
        ret
221
        ret
219
 
222
 
220
    .ascii:
223
    .ascii:
221
        stosb
224
        stosb
222
        dec     esi
225
        dec     esi
223
        dec     ecx
226
        dec     ecx
224
        jnz     .start
227
        jnz     .start
225
 
228
 
226
    .return:
229
    .return:
227
        ret
230
        ret
228
 
231
 
229
; Recommended move to some kernel-wide time handling code.
232
; Recommended move to some kernel-wide time handling code.
230
 
233
 
231
; Total cumulative seconds till each month.
234
; Total cumulative seconds till each month.
232
cumulative_seconds_in_month:
235
cumulative_seconds_in_month:
233
        .january:       dd 0 * (60 * 60 * 24)
236
        .january:       dd 0 * (60 * 60 * 24)
234
        .february:      dd 31 * (60 * 60 * 24)
237
        .february:      dd 31 * (60 * 60 * 24)
235
        .march:         dd 59 * (60 * 60 * 24)
238
        .march:         dd 59 * (60 * 60 * 24)
236
        .april:         dd 90 * (60 * 60 * 24)
239
        .april:         dd 90 * (60 * 60 * 24)
237
        .may:           dd 120 * (60 * 60 * 24)
240
        .may:           dd 120 * (60 * 60 * 24)
238
        .june:          dd 151 * (60 * 60 * 24)
241
        .june:          dd 151 * (60 * 60 * 24)
239
        .july:          dd 181 * (60 * 60 * 24)
242
        .july:          dd 181 * (60 * 60 * 24)
240
        .august:        dd 212 * (60 * 60 * 24)
243
        .august:        dd 212 * (60 * 60 * 24)
241
        .september:     dd 243 * (60 * 60 * 24)
244
        .september:     dd 243 * (60 * 60 * 24)
242
        .october:       dd 273 * (60 * 60 * 24)
245
        .october:       dd 273 * (60 * 60 * 24)
243
        .november:      dd 304 * (60 * 60 * 24)
246
        .november:      dd 304 * (60 * 60 * 24)
244
        .december:      dd 334 * (60 * 60 * 24)
247
        .december:      dd 334 * (60 * 60 * 24)
245
 
248
 
246
current_bdfe_time:
249
current_bdfe_time:
247
        dd 0
250
        dd 0
248
current_bdfe_date:
251
current_bdfe_date:
249
        dd 0
252
        dd 0
250
 
253
 
251
;---------------------------------------------------------------------
254
;---------------------------------------------------------------------
252
; Stores current unix time.
255
; Stores current unix time.
253
; Input:        edi = buffer to output Unix time.
256
; Input:        edi = buffer to output Unix time.
254
;---------------------------------------------------------------------
257
;---------------------------------------------------------------------
255
current_unix_time:
258
current_unix_time:
256
        push    eax esi
259
        push    eax esi
257
        mov     esi, current_bdfe_time
260
        mov     esi, current_bdfe_time
258
        
261
        
259
        ; Just a small observation:
262
        ; Just a small observation:
260
        ; The CMOS is a pretty bad source to get time from. One shouldn't rely on it,
263
        ; The CMOS is a pretty bad source to get time from. One shouldn't rely on it,
261
        ; since it messes up the time by tiny bits. Of course, this is all technical,
264
        ; since it messes up the time by tiny bits. Of course, this is all technical,
262
        ; but one can look it up on the osdev wiki. What is better is to get the time
265
        ; but one can look it up on the osdev wiki. What is better is to get the time
263
        ; from CMOS during boot, then update system time using a more accurate timer.
266
        ; from CMOS during boot, then update system time using a more accurate timer.
264
        ; I'll probably add that after the Summer of Code, so TODO! TODO! TODO!.
267
        ; I'll probably add that after the Summer of Code, so TODO! TODO! TODO!.
265
 
268
 
266
        ; Get time from CMOS.
269
        ; Get time from CMOS.
267
        ; Seconds.
270
        ; Seconds.
268
        mov     al, 0x00
271
        mov     al, 0x00
269
        out     0x70, al
272
        out     0x70, al
270
        in      al, 0x71
273
        in      al, 0x71
271
        call    bcd2bin
274
        call    bcd2bin
272
        mov     [esi + 0], al
275
        mov     [esi + 0], al
273
 
276
 
274
        ; Minute.
277
        ; Minute.
275
        mov     al, 0x02
278
        mov     al, 0x02
276
        out     0x70, al
279
        out     0x70, al
277
        in      al, 0x71
280
        in      al, 0x71
278
        call    bcd2bin
281
        call    bcd2bin
279
        mov     [esi + 1], al
282
        mov     [esi + 1], al
280
 
283
 
281
        ; Hour.
284
        ; Hour.
282
        mov     al, 0x04
285
        mov     al, 0x04
283
        out     0x70, al
286
        out     0x70, al
284
        in      al, 0x71
287
        in      al, 0x71
285
        call    bcd2bin
288
        call    bcd2bin
286
        mov     [esi + 2], al
289
        mov     [esi + 2], al
287
 
290
 
288
        ; Get date.
291
        ; Get date.
289
 
292
 
290
        ; Day.
293
        ; Day.
291
        mov     al, 0x7
294
        mov     al, 0x7
292
        out     0x70, al
295
        out     0x70, al
293
        in      al, 0x71
296
        in      al, 0x71
294
        call    bcd2bin
297
        call    bcd2bin
295
        mov     [esi + 4], al
298
        mov     [esi + 4], al
296
 
299
 
297
        ; Month.
300
        ; Month.
298
        mov     al, 0x8
301
        mov     al, 0x8
299
        out     0x70, al
302
        out     0x70, al
300
        in      al, 0x71
303
        in      al, 0x71
301
        call    bcd2bin
304
        call    bcd2bin
302
        mov     [esi + 5], al
305
        mov     [esi + 5], al
303
 
306
 
304
        ; Year.
307
        ; Year.
305
        mov     al, 0x9
308
        mov     al, 0x9
306
        out     0x70, al
309
        out     0x70, al
307
        in      al, 0x71
310
        in      al, 0x71
308
        call    bcd2bin
311
        call    bcd2bin
309
        add     ax, 2000        ; CMOS only returns last two digits.
312
        add     ax, 2000        ; CMOS only returns last two digits.
310
                                ; Note that everywhere in KolibriOS this is used.
313
                                ; Note that everywhere in KolibriOS this is used.
311
                                ; This is hacky, since the RTC can be incorrectly set
314
                                ; This is hacky, since the RTC can be incorrectly set
312
                                ; to something before 2000.
315
                                ; to something before 2000.
313
        mov     [esi + 6], ax
316
        mov     [esi + 6], ax
314
 
317
 
315
        call    bdfe_to_unix_time
318
        call    bdfe_to_unix_time
316
        pop     esi eax
319
        pop     esi eax
317
        ret
320
        ret
318
 
321
 
319
;---------------------------------------------------------------------
322
;---------------------------------------------------------------------
320
; Convert time+date from BDFE to Unix time.
323
; Convert time+date from BDFE to Unix time.
321
; Input:        esi = pointer to BDFE time+date.
324
; Input:        esi = pointer to BDFE time+date.
322
;               edi = buffer to output Unix time.
325
;               edi = buffer to output Unix time.
323
;---------------------------------------------------------------------
326
;---------------------------------------------------------------------
324
bdfe_to_unix_time:
327
bdfe_to_unix_time:
325
        push    eax ebx ecx edx
328
        push    eax ebx ecx edx
326
        mov     dword[edi], 0x00000000
329
        mov     dword[edi], 0x00000000
327
     
330
     
328
        ; The minimum representable time is 1901-12-13.
331
        ; The minimum representable time is 1901-12-13.
329
        cmp     word[esi + 6], 1901
332
        cmp     word[esi + 6], 1901
330
        jb      .ret
333
        jb      .ret
331
        jg      .max
334
        jg      .max
332
 
335
 
333
        cmp     byte[esi + 5], 12
336
        cmp     byte[esi + 5], 12
334
        jb      .ret
337
        jb      .ret
335
 
338
 
336
        cmp     byte[esi + 4], 13
339
        cmp     byte[esi + 4], 13
337
        jbe     .ret
340
        jbe     .ret
338
        jg      .convert
341
        jg      .convert
339
 
342
 
340
    ; Check if it is more than the maximum representable time.
343
    ; Check if it is more than the maximum representable time.
341
    .max:
344
    .max:
342
        ; The maximum representable time is 2038-01-19.
345
        ; The maximum representable time is 2038-01-19.
343
        cmp     word[esi + 6], 2038
346
        cmp     word[esi + 6], 2038
344
        jg      .ret
347
        jg      .ret
345
        jb      .convert
348
        jb      .convert
346
 
349
 
347
        cmp     byte[esi + 5], 1
350
        cmp     byte[esi + 5], 1
348
        jg      .ret
351
        jg      .ret
349
 
352
 
350
        cmp     byte[esi + 4], 19
353
        cmp     byte[esi + 4], 19
351
        jge     .ret
354
        jge     .ret
352
 
355
 
353
    ; Convert the time.
356
    ; Convert the time.
354
    .convert:
357
    .convert:
355
        ; Get if current year is leap year in ECX.
358
        ; Get if current year is leap year in ECX.
356
        xor     ecx, ecx
359
        xor     ecx, ecx
357
        mov     ebx, 4
360
        mov     ebx, 4
358
        xor     edx, edx
361
        xor     edx, edx
359
 
362
 
360
        cmp     word[esi + 6], 1970
363
        cmp     word[esi + 6], 1970
361
        jb      .negative
364
        jb      .negative
362
 
365
 
363
        movzx   eax, word[esi + 6]              ; Year.
366
        movzx   eax, word[esi + 6]              ; Year.
364
        cmp     byte[esi + 5], 3                ; If the month is less than March, than that year doesn't matter.
367
        cmp     byte[esi + 5], 3                ; If the month is less than March, than that year doesn't matter.
365
        jge     @F
368
        jge     @F
366
 
369
 
367
        test    eax, 3
370
        test    eax, 3
368
        ; Not a leap year.
371
        ; Not a leap year.
369
        jnz     @F
372
        jnz     @F
370
 
373
 
371
        inc     ecx
374
        inc     ecx
372
    @@:
375
    @@:
373
        ; Number of leap years between two years = ((end date - 1)/4) - (1970/4)
376
        ; Number of leap years between two years = ((end date - 1)/4) - (1970/4)
374
        dec     eax
377
        dec     eax
375
        div     ebx
378
        div     ebx
376
        sub     eax, 1970/4
379
        sub     eax, 1970/4
377
 
380
 
378
        ; EAX is the number of leap years.
381
        ; EAX is the number of leap years.
379
        add     eax, ecx
382
        add     eax, ecx
380
        mov     ecx, (60 * 60 * 24)             ; Seconds in a day.
383
        mov     ecx, (60 * 60 * 24)             ; Seconds in a day.
381
        mul     ecx
384
        mul     ecx
382
 
385
 
383
        ; Account for leap years, i.e., one day extra for each.
386
        ; Account for leap years, i.e., one day extra for each.
384
        add     [edi], eax
387
        add     [edi], eax
385
 
388
 
386
        ; Get total days in EAX.
389
        ; Get total days in EAX.
387
        movzx   eax, byte[esi + 4]
390
        movzx   eax, byte[esi + 4]
388
        dec     eax
391
        dec     eax
389
        mul     ecx
392
        mul     ecx
390
 
393
 
391
        ; Account for days.
394
        ; Account for days.
392
        add     [edi], eax
395
        add     [edi], eax
393
 
396
 
394
        ; Account for month.
397
        ; Account for month.
395
        movzx   eax, byte[esi + 5]
398
        movzx   eax, byte[esi + 5]
396
        dec     eax
399
        dec     eax
397
        mov     eax, [cumulative_seconds_in_month + (eax * 4)]
400
        mov     eax, [cumulative_seconds_in_month + (eax * 4)]
398
        add     [edi], eax
401
        add     [edi], eax
399
 
402
 
400
        ; Account for year.
403
        ; Account for year.
401
        movzx   eax, word[esi + 6]
404
        movzx   eax, word[esi + 6]
402
        sub     eax, 1970
405
        sub     eax, 1970
403
        mov     ecx, (60 * 60 * 24) * 365       ; Seconds in a year.
406
        mov     ecx, (60 * 60 * 24) * 365       ; Seconds in a year.
404
        mul     ecx
407
        mul     ecx
405
        add     [edi], eax
408
        add     [edi], eax
406
 
409
 
407
        ; Seconds.
410
        ; Seconds.
408
        movzx   eax, byte[esi + 0]
411
        movzx   eax, byte[esi + 0]
409
        add     [edi], eax        
412
        add     [edi], eax        
410
 
413
 
411
        ; Minutes.
414
        ; Minutes.
412
        movzx   eax, byte[esi + 1]
415
        movzx   eax, byte[esi + 1]
413
        mov     ecx, 60
416
        mov     ecx, 60
414
        mul     ecx
417
        mul     ecx
415
        add     [edi], eax
418
        add     [edi], eax
416
 
419
 
417
        ; Hours.
420
        ; Hours.
418
        movzx   eax, byte[esi + 2]
421
        movzx   eax, byte[esi + 2]
419
        mov     ecx, (60 * 60)
422
        mov     ecx, (60 * 60)
420
        mul     ecx
423
        mul     ecx
421
        add     [edi], eax  
424
        add     [edi], eax  
422
 
425
 
423
    ; The time wanted is before the epoch; handle it here.
426
    ; The time wanted is before the epoch; handle it here.
424
    .negative:
427
    .negative:
425
        ; TODO.
428
        ; TODO.
426
 
429
 
427
    .ret:
430
    .ret:
428
        pop     edx ecx ebx eax
431
        pop     edx ecx ebx eax
429
        ret
432
        ret
430
 
433
 
431
; Recommended move to some kernel-wide alloc handling code.
434
; Recommended move to some kernel-wide alloc handling code.
432
macro KERNEL_ALLOC store, label
435
macro KERNEL_ALLOC store, label
433
{
436
{
434
        call    kernel_alloc
437
        call    kernel_alloc
435
        mov     store, eax
438
        mov     store, eax
436
        test    eax, eax    
439
        test    eax, eax    
437
        jz      label   
440
        jz      label   
438
}
441
}
439
 
442
 
440
macro KERNEL_FREE data, label
443
macro KERNEL_FREE data, label
441
{
444
{
442
        cmp     data, 0
445
        cmp     data, 0
443
        jz      label
446
        jz      label
444
        push    data
447
        push    data
445
        call    kernel_free
448
        call    kernel_free
446
}
449
}
447
 
450
 
448
struct EXTFS PARTITION
451
struct EXTFS PARTITION
449
        lock MUTEX
452
        lock MUTEX
450
        partition_flags                dd ?
453
        partition_flags                dd ?
451
        log_block_size                 dd ?
454
        log_block_size                 dd ?
452
        block_size                     dd ?
455
        block_size                     dd ?
453
        count_block_in_block           dd ?
456
        count_block_in_block           dd ?
454
        blocks_per_group               dd ?
457
        blocks_per_group               dd ?
455
        global_desc_table              dd ?
458
        global_desc_table              dd ?
456
        root_inode                     dd ?         ; Pointer to root inode in memory.
459
        root_inode                     dd ?         ; Pointer to root inode in memory.
457
        inode_size                     dd ?
460
        inode_size                     dd ?
458
        count_pointer_in_block         dd ?         ; (block_size / 4)
461
        count_pointer_in_block         dd ?         ; (block_size / 4)
459
        count_pointer_in_block_square  dd ?         ; (block_size / 4)**2
462
        count_pointer_in_block_square  dd ?         ; (block_size / 4)**2
460
        ext2_save_block                dd ?         ; Block for 1 global procedure.
463
        ext2_save_block                dd ?         ; Block for 1 global procedure.
461
        ext2_temp_block                dd ?         ; Block for small procedures.
464
        ext2_temp_block                dd ?         ; Block for small procedures.
462
        ext2_save_inode                dd ?         ; inode for global procedures.
465
        ext2_save_inode                dd ?         ; inode for global procedures.
463
        ext2_temp_inode                dd ?         ; inode for small procedures.
466
        ext2_temp_inode                dd ?         ; inode for small procedures.
464
        groups_count                   dd ?
467
        groups_count                   dd ?
465
        superblock                     rd 1024/4
468
        superblock                     rd 1024/4
466
ends
469
ends
467
 
470
 
468
; EXT2 revisions.
471
; EXT2 revisions.
469
EXT2_GOOD_OLD_REV    = 0
472
EXT2_GOOD_OLD_REV    = 0
470
 
473
 
471
; For fs_type.
474
; For fs_type.
472
FS_TYPE_UNDEFINED    = 0
475
FS_TYPE_UNDEFINED    = 0
473
FS_TYPE_EXT          = 2
476
FS_TYPE_EXT          = 2
474
 
477
 
475
; Some set inodes.
478
; Some set inodes.
476
EXT2_BAD_INO         = 1
479
EXT2_BAD_INO         = 1
477
EXT2_ROOT_INO        = 2
480
EXT2_ROOT_INO        = 2
478
EXT2_ACL_IDX_INO     = 3
481
EXT2_ACL_IDX_INO     = 3
479
EXT2_ACL_DATA_INO    = 4
482
EXT2_ACL_DATA_INO    = 4
480
EXT2_BOOT_LOADER_INO = 5
483
EXT2_BOOT_LOADER_INO = 5
481
EXT2_UNDEL_DIR_INO   = 6
484
EXT2_UNDEL_DIR_INO   = 6
482
 
485
 
483
; EXT2_SUPER_MAGIC.
486
; EXT2_SUPER_MAGIC.
484
EXT2_SUPER_MAGIC     = 0xEF53
487
EXT2_SUPER_MAGIC     = 0xEF53
485
EXT2_VALID_FS        = 1
488
EXT2_VALID_FS        = 1
486
 
489
 
487
; Flags defining i_mode values.
490
; Flags defining i_mode values.
488
EXT2_S_IFMT          = 0xF000           ; Mask for file type.
491
EXT2_S_IFMT          = 0xF000           ; Mask for file type.
489
 
492
 
490
EXT2_S_IFREG         = 0x8000           ; Regular file.
493
EXT2_S_IFREG         = 0x8000           ; Regular file.
491
EXT2_S_IFDIR         = 0x4000           ; Directory.
494
EXT2_S_IFDIR         = 0x4000           ; Directory.
492
 
495
 
493
EXT2_S_IRUSR         = 0x0100           ; User read
496
EXT2_S_IRUSR         = 0x0100           ; User read
494
EXT2_S_IWUSR         = 0x0080           ; User write
497
EXT2_S_IWUSR         = 0x0080           ; User write
495
EXT2_S_IXUSR         = 0x0040           ; User execute
498
EXT2_S_IXUSR         = 0x0040           ; User execute
496
EXT2_S_IRGRP         = 0x0020           ; Group read
499
EXT2_S_IRGRP         = 0x0020           ; Group read
497
EXT2_S_IWGRP         = 0x0010           ; Group write
500
EXT2_S_IWGRP         = 0x0010           ; Group write
498
EXT2_S_IXGRP         = 0x0008           ; Group execute
501
EXT2_S_IXGRP         = 0x0008           ; Group execute
499
EXT2_S_IROTH         = 0x0004           ; Others read
502
EXT2_S_IROTH         = 0x0004           ; Others read
500
EXT2_S_IWOTH         = 0x0002           ; Others write
503
EXT2_S_IWOTH         = 0x0002           ; Others write
501
EXT2_S_IXOTH         = 0x0001           ; Others execute
504
EXT2_S_IXOTH         = 0x0001           ; Others execute
502
 
505
 
503
PERMISSIONS          = EXT2_S_IRUSR or EXT2_S_IWUSR \
506
PERMISSIONS          = EXT2_S_IRUSR or EXT2_S_IWUSR \
504
                       or EXT2_S_IRGRP or EXT2_S_IWGRP \
507
                       or EXT2_S_IRGRP or EXT2_S_IWGRP \
505
                       or EXT2_S_IROTH or EXT2_S_IWOTH
508
                       or EXT2_S_IROTH or EXT2_S_IWOTH
506
 
509
 
507
; File type defining values in directory entry.
510
; File type defining values in directory entry.
508
EXT2_FT_REG_FILE     = 1                ; Regular file.
511
EXT2_FT_REG_FILE     = 1                ; Regular file.
509
EXT2_FT_DIR          = 2                ; Directory.
512
EXT2_FT_DIR          = 2                ; Directory.
510
 
513
 
511
; Flags used by KolibriOS.
514
; Flags used by KolibriOS.
512
FS_FT_HIDDEN         = 2
515
FS_FT_HIDDEN         = 2
513
FS_FT_DIR            = 0x10             ; Directory.
516
FS_FT_DIR            = 0x10             ; Directory.
514
 
517
 
515
; ext2 partition flags.
518
; ext2 partition flags.
516
EXT2_RO              = 0x01
519
EXT2_RO              = 0x01
517
 
520
 
518
FS_FT_ASCII          = 0                ; Name in ASCII.
521
FS_FT_ASCII          = 0                ; Name in ASCII.
519
FS_FT_UNICODE        = 1                ; Name in Unicode.
522
FS_FT_UNICODE        = 1                ; Name in Unicode.
520
 
523
 
521
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ; Have file type in directory entry.
524
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ; Have file type in directory entry.
522
EXT4_FEATURE_INCOMPAT_EXTENTS  = 0x0040 ; Extents.
525
EXT4_FEATURE_INCOMPAT_EXTENTS  = 0x0040 ; Extents.
523
EXT4_FEATURE_INCOMPAT_FLEX_BG  = 0x0200 ; Flexible block groups.
526
EXT4_FEATURE_INCOMPAT_FLEX_BG  = 0x0200 ; Flexible block groups.
524
 
527
 
525
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x0001 ; Sparse Superblock
528
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x0001 ; Sparse Superblock
526
EXT2_FEATURE_RO_COMPAT_LARGE_FILE   = 0x0002 ; Large file support (64-bit file size)
529
EXT2_FEATURE_RO_COMPAT_LARGE_FILE   = 0x0002 ; Large file support (64-bit file size)
527
 
530
 
528
; Implemented ext[2,3,4] features.
531
; Implemented ext[2,3,4] features.
529
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
532
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
530
                             or EXT4_FEATURE_INCOMPAT_EXTENTS \
533
                             or EXT4_FEATURE_INCOMPAT_EXTENTS \
531
                             or EXT4_FEATURE_INCOMPAT_FLEX_BG
534
                             or EXT4_FEATURE_INCOMPAT_FLEX_BG
532
 
535
 
533
; Implemented features which otherwise require "read-only" mount.
536
; Implemented features which otherwise require "read-only" mount.
534
EXT2_FEATURE_RO_COMPAT_SUPP = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER \
537
EXT2_FEATURE_RO_COMPAT_SUPP = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER \
535
                              or EXT2_FEATURE_RO_COMPAT_LARGE_FILE
538
                              or EXT2_FEATURE_RO_COMPAT_LARGE_FILE
536
 
539
 
537
; ext4 features not support for write.
540
; ext4 features not support for write.
538
EXT4_FEATURE_INCOMPAT_W_NOT_SUPP = EXT4_FEATURE_INCOMPAT_EXTENTS \
541
EXT4_FEATURE_INCOMPAT_W_NOT_SUPP = EXT4_FEATURE_INCOMPAT_EXTENTS \
539
                                   or EXT4_FEATURE_INCOMPAT_FLEX_BG
542
                                   or EXT4_FEATURE_INCOMPAT_FLEX_BG
540
 
543
 
541
; Flags specified in i_flags.
544
; Flags specified in i_flags.
542
EXT2_EXTENTS_FL      = 0x00080000       ; Extents.
545
EXT2_EXTENTS_FL      = 0x00080000       ; Extents.
543
 
546
 
544
struct  EXT2_INODE_STRUC
547
struct  EXT2_INODE_STRUC
545
        i_mode          dw ?
548
        i_mode          dw ?
546
        i_uid           dw ?
549
        i_uid           dw ?
547
        i_size          dd ?
550
        i_size          dd ?
548
        i_atime         dd ?
551
        i_atime         dd ?
549
        i_ctime         dd ?
552
        i_ctime         dd ?
550
        i_mtime         dd ?
553
        i_mtime         dd ?
551
        i_dtime         dd ?
554
        i_dtime         dd ?
552
        i_gid           dw ?
555
        i_gid           dw ?
553
        i_links_count   dw ?
556
        i_links_count   dw ?
554
        i_blocks        dd ?
557
        i_blocks        dd ?
555
        i_flags         dd ?
558
        i_flags         dd ?
556
        i_osd1          dd ?
559
        i_osd1          dd ?
557
        i_block         rd 15
560
        i_block         rd 15
558
        i_generation    dd ?
561
        i_generation    dd ?
559
        i_file_acl      dd ?
562
        i_file_acl      dd ?
560
        i_dir_acl       dd ?
563
        i_dir_acl       dd ?
561
        i_faddr         dd ?
564
        i_faddr         dd ?
562
        i_osd2          dd ?        ; 12 bytes.
565
        i_osd2          dd ?        ; 12 bytes.
563
ends
566
ends
564
 
567
 
565
struct  EXT2_DIR_STRUC
568
struct  EXT2_DIR_STRUC
566
        inode           dd ?
569
        inode           dd ?
567
        rec_len         dw ?
570
        rec_len         dw ?
568
        name_len        db ?
571
        name_len        db ?
569
        file_type       db ?
572
        file_type       db ?
570
        name            db ?         ; 255 (max) bytes.
573
        name            db ?         ; 255 (max) bytes.
571
ends
574
ends
572
 
575
 
573
struct  EXT2_BLOCK_GROUP_DESC
576
struct  EXT2_BLOCK_GROUP_DESC
574
        block_bitmap            dd ?         ; +0
577
        block_bitmap            dd ?         ; +0
575
        inode_bitmap            dd ?         ; +4
578
        inode_bitmap            dd ?         ; +4
576
        inode_table             dd ?         ; +8
579
        inode_table             dd ?         ; +8
577
        free_blocks_count       dw ?         ; +12
580
        free_blocks_count       dw ?         ; +12
578
        free_inodes_count       dw ?         ; +14
581
        free_inodes_count       dw ?         ; +14
579
        used_dirs_count         dw ?         ; +16
582
        used_dirs_count         dw ?         ; +16
580
        pad                     dw ?         ; +18
583
        pad                     dw ?         ; +18
581
        reserved                rb 12        ; +20
584
        reserved                rb 12        ; +20
582
ends
585
ends
583
 
586
 
584
struct  EXT2_SB_STRUC
587
struct  EXT2_SB_STRUC
585
        inodes_count            dd ?         ; +0
588
        inodes_count            dd ?         ; +0
586
        blocks_count            dd ?         ; +4
589
        blocks_count            dd ?         ; +4
587
        r_block_count           dd ?         ; +8
590
        r_block_count           dd ?         ; +8
588
        free_block_count        dd ?         ; +12
591
        free_block_count        dd ?         ; +12
589
        free_inodes_count       dd ?         ; +16
592
        free_inodes_count       dd ?         ; +16
590
        first_data_block        dd ?         ; +20
593
        first_data_block        dd ?         ; +20
591
        log_block_size          dd ?         ; +24
594
        log_block_size          dd ?         ; +24
592
        log_frag_size           dd ?         ; +28
595
        log_frag_size           dd ?         ; +28
593
        blocks_per_group        dd ?         ; +32
596
        blocks_per_group        dd ?         ; +32
594
        frags_per_group         dd ?         ; +36
597
        frags_per_group         dd ?         ; +36
595
        inodes_per_group        dd ?         ; +40
598
        inodes_per_group        dd ?         ; +40
596
        mtime                   dd ?         ; +44
599
        mtime                   dd ?         ; +44
597
        wtime                   dd ?         ; +48
600
        wtime                   dd ?         ; +48
598
        mnt_count               dw ?         ; +52
601
        mnt_count               dw ?         ; +52
599
        max_mnt_count           dw ?         ; +54
602
        max_mnt_count           dw ?         ; +54
600
        magic                   dw ?         ; +56
603
        magic                   dw ?         ; +56
601
        state                   dw ?         ; +58
604
        state                   dw ?         ; +58
602
        errors                  dw ?         ; +60
605
        errors                  dw ?         ; +60
603
        minor_rev_level         dw ?         ; +62
606
        minor_rev_level         dw ?         ; +62
604
        lastcheck               dd ?         ; +64
607
        lastcheck               dd ?         ; +64
605
        check_intervals         dd ?         ; +68
608
        check_intervals         dd ?         ; +68
606
        creator_os              dd ?         ; +72
609
        creator_os              dd ?         ; +72
607
        rev_level               dd ?         ; +76
610
        rev_level               dd ?         ; +76
608
        def_resuid              dw ?         ; +80
611
        def_resuid              dw ?         ; +80
609
        def_resgid              dw ?         ; +82
612
        def_resgid              dw ?         ; +82
610
        first_ino               dd ?         ; +84
613
        first_ino               dd ?         ; +84
611
        inode_size              dw ?         ; +88
614
        inode_size              dw ?         ; +88
612
        block_group_nr          dw ?         ; +90
615
        block_group_nr          dw ?         ; +90
613
        feature_compat          dd ?         ; +92
616
        feature_compat          dd ?         ; +92
614
        feature_incompat        dd ?         ; +96
617
        feature_incompat        dd ?         ; +96
615
        feature_ro_compat       dd ?         ; +100
618
        feature_ro_compat       dd ?         ; +100
616
        uuid                    rb 16        ; +104
619
        uuid                    rb 16        ; +104
617
        volume_name             rb 16        ; +120
620
        volume_name             rb 16        ; +120
618
        last_mounted            rb 64        ; +136
621
        last_mounted            rb 64        ; +136
619
        algo_bitmap             dd ?         ; +200
622
        algo_bitmap             dd ?         ; +200
620
        prealloc_blocks         db ?         ; +204
623
        prealloc_blocks         db ?         ; +204
621
        preallock_dir_blocks    db ?         ; +205
624
        preallock_dir_blocks    db ?         ; +205
622
        reserved_gdt_blocks     dw ?         ; +206
625
        reserved_gdt_blocks     dw ?         ; +206
623
        journal_uuid            rb 16        ; +208
626
        journal_uuid            rb 16        ; +208
624
        journal_inum            dd ?         ; +224
627
        journal_inum            dd ?         ; +224
625
        journal_dev             dd ?         ; +228
628
        journal_dev             dd ?         ; +228
626
        last_orphan             dd ?         ; +232
629
        last_orphan             dd ?         ; +232
627
        hash_seed               rd 4         ; +236
630
        hash_seed               rd 4         ; +236
628
        def_hash_version        db ?         ; +252
631
        def_hash_version        db ?         ; +252
629
        reserved                rb 3         ; +253 (reserved)
632
        reserved                rb 3         ; +253 (reserved)
630
        default_mount_options   dd ?         ; +256
633
        default_mount_options   dd ?         ; +256
631
        first_meta_bg           dd ?         ; +260
634
        first_meta_bg           dd ?         ; +260
632
        mkfs_time               dd ?         ; +264
635
        mkfs_time               dd ?         ; +264
633
        jnl_blocks              rd 17        ; +268
636
        jnl_blocks              rd 17        ; +268
634
        blocks_count_hi         dd ?         ; +336
637
        blocks_count_hi         dd ?         ; +336
635
        r_blocks_count_hi       dd ?         ; +340
638
        r_blocks_count_hi       dd ?         ; +340
636
        free_blocks_count_hi    dd ?         ; +344
639
        free_blocks_count_hi    dd ?         ; +344
637
        min_extra_isize         dw ?         ; +348
640
        min_extra_isize         dw ?         ; +348
638
        want_extra_isize        dw ?         ; +350
641
        want_extra_isize        dw ?         ; +350
639
        flags                   dd ?         ; +352
642
        flags                   dd ?         ; +352
640
        raid_stride             dw ?         ; +356
643
        raid_stride             dw ?         ; +356
641
        mmp_interval            dw ?         ; +358
644
        mmp_interval            dw ?         ; +358
642
        mmp_block               dq ?         ; +360
645
        mmp_block               dq ?         ; +360
643
        raid_stripe_width       dd ?         ; +368
646
        raid_stripe_width       dd ?         ; +368
644
        log_groups_per_flex     db ?         ; +372
647
        log_groups_per_flex     db ?         ; +372
645
ends
648
ends
646
 
649
 
647
; Header block extents.
650
; Header block extents.
648
struct EXT4_EXTENT_HEADER
651
struct EXT4_EXTENT_HEADER
649
        eh_magic        dw ?    ; Magic value of 0xF30A, for ext4.
652
        eh_magic        dw ?    ; Magic value of 0xF30A, for ext4.
650
        eh_entries      dw ?    ; Number of blocks covered by the extent.
653
        eh_entries      dw ?    ; Number of blocks covered by the extent.
651
        eh_max          dw ?    ; Capacity of entries.
654
        eh_max          dw ?    ; Capacity of entries.
652
        eh_depth        dw ?    ; Tree depth (if 0, extents in the array are not extent indexes)
655
        eh_depth        dw ?    ; Tree depth (if 0, extents in the array are not extent indexes)
653
        eh_generation   dd ?    ; ???
656
        eh_generation   dd ?    ; ???
654
ends
657
ends
655
 
658
 
656
; Extent.
659
; Extent.
657
struct EXT4_EXTENT
660
struct EXT4_EXTENT
658
        ee_block        dd ?    ; First logical block extent covers.
661
        ee_block        dd ?    ; First logical block extent covers.
659
        ee_len          dw ?    ; Number of blocks covered by extent.
662
        ee_len          dw ?    ; Number of blocks covered by extent.
660
        ee_start_hi     dw ?    ; Upper 16 bits of 48-bit address (unused in KOS)
663
        ee_start_hi     dw ?    ; Upper 16 bits of 48-bit address (unused in KOS)
661
        ee_start_lo     dd ?    ; Lower 32 bits of 48-bit address.
664
        ee_start_lo     dd ?    ; Lower 32 bits of 48-bit address.
662
ends
665
ends
663
 
666
 
664
; Index on-disk structure; pointer to block of extents/indexes.
667
; Index on-disk structure; pointer to block of extents/indexes.
665
struct EXT4_EXTENT_IDX
668
struct EXT4_EXTENT_IDX
666
        ei_block        dd ?    ; Covers logical blocks from here.
669
        ei_block        dd ?    ; Covers logical blocks from here.
667
        ei_leaf_lo      dd ?    ; Lower 32-bits of pointer to the physical block of the next level. 
670
        ei_leaf_lo      dd ?    ; Lower 32-bits of pointer to the physical block of the next level. 
668
        ei_leaf_hi      dw ?    ; Higher 16-bits (unused in KOS).
671
        ei_leaf_hi      dw ?    ; Higher 16-bits (unused in KOS).
669
        ei_unused       dw ?    ; Reserved.
672
        ei_unused       dw ?    ; Reserved.
670
ends
673
ends