Subversion Repositories Kolibri OS

Rev

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

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