Subversion Repositories Kolibri OS

Rev

Rev 1397 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1378 turbanoff 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
1384 turbanoff 5
;;   02.02.2010  turbanoff  - support 70.5                      ;;
6
;;   23.01.2010  turbanoff  - support 70.0 70.1                 ;;
1378 turbanoff 7
;;                                                              ;;
8
;;                                                              ;;
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
 
11
$Revision: 1398 $
12
 
13
EXT2_BAD_INO        = 1
14
EXT2_ROOT_INO        = 2
15
EXT2_ACL_IDX_INO    = 3
16
EXT2_ACL_DATA_INO    = 4
17
EXT2_BOOT_LOADER_INO= 5
18
EXT2_UNDEL_DIR_INO    = 6
19
 
20
;type inode
1384 turbanoff 21
EXT2_S_IFREG        = 0x8000
22
EXT2_S_IFDIR        = 0x4000
1378 turbanoff 23
;user inode right's
24
EXT2_S_IRUSR        = 0x0100
25
EXT2_S_IWUSR        = 0x0080
26
EXT2_S_IXUSR        = 0x0040
27
;group inode right's
28
EXT2_S_IRGRP        = 0x0020
29
EXT2_S_IWGRP        = 0x0010
30
EXT2_S_IXGRP        = 0x0008
31
;other inode right's
32
EXT2_S_IROTH        = 0x0004
33
EXT2_S_IROTH        = 0x0002
34
EXT2_S_IROTH        = 0x0001
35
 
36
EXT2_FT_REG_FILE        = 1     ;это файл, запись в родительском каталоге
37
EXT2_FT_DIR             = 2     ;это папка
38
 
39
FS_FT_DIR               = 0x10  ;это папка
40
FS_FT_ASCII             = 0     ;имя в ascii
41
FS_FT_UNICODE           = 1     ;имя в unicode
42
 
1397 turbanoff 43
uglobal
44
    EXT2_files_in_folder    dd ?   ;всего файлов в папке
45
    EXT2_read_in_folder     dd ?   ;сколько файлов "считали"
46
    EXT2_end_block          dd ?   ;конец очередного блока папки
47
    EXT2_counter_blocks     dd ?
48
    EXT2_filename           db 256 dup ?
49
endg
50
 
1378 turbanoff 51
struct EXT2_INODE_STRUC
52
    .i_mode         dw ?
53
    .i_uid          dw ?
54
    .i_size         dd ?
55
    .i_atime        dd ?
56
    .i_ctime        dd ?
57
    .i_mtime        dd ?
58
    .i_dtime        dd ?
59
    .i_gid          dw ?
60
    .i_links_count  dw ?
61
    .i_blocks       dd ?
62
    .i_flags        dd ?
63
    .i_osd1         dd ?
64
    .i_block        dd 15 dup ?
65
    .i_generation   dd ?
66
    .i_file_acl     dd ?
67
    .i_dir_acl      dd ?
68
    .i_faddr        dd ?
69
    .i_osd2         dd ? ; 1..12
70
ends
71
 
72
struct EXT2_DIR_STRUC
73
    .inode          dd ?
74
    .rec_len        dw ?
75
    .name_len       db ?
76
    .file_type      db ?
77
    .name           db ? ; 0..255
78
ends
79
 
80
 
81
ext2_test_superblock:
82
        mov     eax, [PARTITION_START]
83
        add     eax, 2                  ;superblock start at 1024b
84
        call    hd_read
85
 
86
        cmp     [fs_type], 0x83
87
        jne     .no
88
        cmp     dword [ebx+24], 3       ;s_block_size 0,1,2,3
89
        ja      .no
90
        cmp     word [ebx+56], 0xEF53   ;s_magic
91
        jne     .no
92
        cmp     word [ebx+58], 1        ;s_state (EXT_VALID_FS=1)
93
        jne     .no
94
 
95
    ; OK, this is correct EXT2 superblock
96
        clc
97
        ret
98
   .no:
99
    ; No, this superblock isn't EXT2
100
        stc
101
        ret
102
 
103
ext2_setup:
104
        mov     [fs_type], 2
105
        mov     ecx, [ebx+24]
106
        inc     ecx
107
        mov     [ext2_data.log_block_size], ecx    ; 1, 2, 3, 4   equ 1kb, 2kb, 4kb, 8kb
108
 
109
        mov     eax, 1
110
        shl     eax, cl
111
        mov     [ext2_data.count_block_in_block], eax
112
 
113
        shl     eax, 7
114
        mov     [ext2_data.count_pointer_in_block], eax
115
        mov     edx, eax                                ; потом еще квадрат найдем
116
 
117
        shl     eax, 2
118
        mov     [ext2_data.block_size], eax
119
 
1387 turbanoff 120
        push    eax eax eax                             ; 3 kernel_alloc
1378 turbanoff 121
 
122
        mov     eax, edx
123
        mul     edx
124
        mov     [ext2_data.count_pointer_in_block_square], eax
125
 
126
        call    kernel_alloc
1387 turbanoff 127
        mov     [ext2_data.global_desc_table],eax       ; reserve mem for gdt
1378 turbanoff 128
        call    kernel_alloc
129
        mov     [ext2_data.ext2_save_block], eax        ; and for temp block
130
        call    kernel_alloc
131
        mov     [ext2_data.ext2_temp_block], eax        ; and for get_inode proc
132
 
1384 turbanoff 133
        movzx   ebp, word [ebx+88]
1378 turbanoff 134
        mov     ecx, [ebx+32]
135
        mov     edx, [ebx+40]
136
        mov     eax, [ebx+20]                           ; first_data_block
137
 
138
        mov     [ext2_data.inode_size], ebp
139
        mov     [ext2_data.blocks_per_group], ecx
140
        mov     [ext2_data.inodes_per_group], edx
141
 
142
        mov     ebx, [ext2_data.global_desc_table]
143
        inc     eax                                     ; first_data_block + 1 = gdt
144
        call    ext2_get_block                          ; read gtd
145
 
146
        push    ebp ebp ebp                             ;3 kernel_alloc
147
        call    kernel_alloc
148
        mov     [ext2_data.ext2_save_inode], eax
149
        call    kernel_alloc
150
        mov     [ext2_data.ext2_temp_inode], eax
151
        call    kernel_alloc
152
        mov     [ext2_data.root_inode], eax
153
 
154
        mov     ebx, eax
155
        mov     eax, EXT2_ROOT_INO
156
        call    ext2_get_inode                          ; read root inode
157
 
158
        popad
159
        call    free_hd_channel
160
        and     [hd1_status], 0
161
        ret
162
;==================================================================
163
;in: eax = i_block
164
;    ebx = pointer to return memory
165
ext2_get_block:
166
        push    eax ebx ecx
167
        mov     ecx, [ext2_data.log_block_size]
168
        shl     eax, cl
169
        add     eax, [PARTITION_START]
170
        mov     ecx, [ext2_data.count_block_in_block]
171
    @@:
172
        call    hd_read
173
        inc     eax
174
        add     ebx, 512
175
        loop    @B
176
        pop     ecx ebx eax
177
        ret
178
;===================================================================
1387 turbanoff 179
; in:  ecx = номер блока в inode (0..)
1378 turbanoff 180
;      ebp = адрес inode
181
; out: ecx = адрес очередного блока
182
ext2_get_inode_block:
1387 turbanoff 183
        cmp     ecx, 12                                         ; 0..11 - direct block address
184
        jb      .get_direct_block
1378 turbanoff 185
 
186
        sub     ecx, 12
1387 turbanoff 187
        cmp     ecx, [ext2_data.count_pointer_in_block]         ; 12.. - indirect block
188
        jb      .get_indirect_block
1378 turbanoff 189
 
190
        sub     ecx, [ext2_data.count_pointer_in_block]
191
        cmp     ecx, [ext2_data.count_pointer_in_block_square]
1387 turbanoff 192
        jb      .get_double_indirect_block
1378 turbanoff 193
 
1387 turbanoff 194
        sub     ecx, [ext2_data.count_pointer_in_block_square]
1378 turbanoff 195
    ;.get_triple_indirect_block:
196
        push    eax edx ebx
197
 
198
        mov    eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
199
        mov    ebx, [ext2_data.ext2_temp_block]
200
        call    ext2_get_block
201
 
202
        xor     edx, edx
203
        mov     eax, ecx
204
        div     [ext2_data.count_pointer_in_block_square]
205
 
206
    ;eax - номер в полученном блоке   edx - номер дальше
207
        mov    eax, [ebx + eax*4]
1387 turbanoff 208
        call   ext2_get_block
1378 turbanoff 209
 
210
        mov    eax, edx
211
        jmp    @F
212
 
213
    .get_double_indirect_block:
214
        push    eax edx ebx
215
 
216
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
217
        mov     ebx, [ext2_data.ext2_temp_block]
218
        call    ext2_get_block
219
 
220
        mov     eax, ecx
221
      @@:
222
        xor     edx, edx
223
        div     [ext2_data.count_pointer_in_block]
224
 
225
        mov    eax, [ebx + eax*4]
226
        call    ext2_get_block
227
        mov    ecx, [ebx + edx*4]
228
 
229
        pop     ebx edx eax
230
        ret
231
 
232
    .get_indirect_block:
233
        push    eax ebx
234
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
1387 turbanoff 235
        mov     ebx, [ext2_data.ext2_temp_block]
1378 turbanoff 236
        call    ext2_get_block
237
 
238
        mov     ecx, [ebx + ecx*4]
239
        pop     ebx eax
240
        ret
241
 
242
    .get_direct_block:
243
        mov     ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
244
        ret
245
 
246
 
247
;===================================================================
248
;get content inode by num
249
;in:   eax = inode_num
250
;      ebx = address of inode content
251
ext2_get_inode:
252
 
253
    pushad
254
    mov     edi, ebx        ;сохраним адрес inode
255
    dec    eax
256
    xor    edx, edx
257
    div    [ext2_data.inodes_per_group]
258
 
259
        push    edx                             ;locale num
260
 
261
        mov     edx, 32
262
        mul     edx                             ; address block_group in global_desc_table
263
 
264
        add     eax, [ext2_data.global_desc_table]
265
        mov     eax, [eax+8]                    ; номер блока - в терминах ext2
266
 
267
        mov     ecx, [ext2_data.log_block_size]
268
        shl     eax, cl
269
        add     eax, [PARTITION_START]          ; а старт раздела - в терминах hdd (512)
270
 
271
        ;eax - указывает на таблицу inode-ов на hdd
272
        mov     ecx, eax                        ;сохраним его пока в ecx
273
 
274
        ; прибавим локальный адрес inode-а
275
        pop     eax                             ; index
276
        mul     [ext2_data.inode_size]        ; (index * inode_size)
277
        mov     ebp, 512
278
        div     ebp                             ;поделим на размер блока
279
 
280
        add     eax, ecx                        ;нашли адрес блока для чтения
281
        mov     ebx, [ext2_data.ext2_temp_block]
282
        call    hd_read
283
 
284
        mov     esi, edx                        ;добавим "остаток"
285
        add     esi, ebx                        ;к адресу
286
        mov     ecx, [ext2_data.inode_size]
287
        rep     movsb                           ;копируем inode
288
        popad
289
        ret
290
 
291
;----------------------------------------------------------------
292
; in:  esi -> children
293
;      ebx -> pointer to dir block
294
; out: esi -> name without parent or not_changed
295
;      ebx -> dir_rec of inode children      or trash
296
ext2_test_block_by_name:
297
        push    eax ecx edx edi
298
 
299
        mov        edx, ebx
300
        add        edx, [ext2_data.block_size]    ;запомним конец блока
301
 
302
        .start_rec:
303
            cmp     [ebx + EXT2_DIR_STRUC.inode], 0
304
            jz      .next_rec
305
 
306
            push    esi
307
            movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
1397 turbanoff 308
            mov     edi, EXT2_filename
309
            lea     esi, [ebx + EXT2_DIR_STRUC.name]
1378 turbanoff 310
 
1397 turbanoff 311
            call    utf8toansi_str
312
            mov     ecx, edi
313
            sub     ecx, EXT2_filename      ;кол-во байт в получившейся строке
314
 
315
            mov     edi, EXT2_filename
316
            mov     esi, [esp]
1378 turbanoff 317
          @@:
1397 turbanoff 318
                jecxz   .test_find
1378 turbanoff 319
                dec     ecx
1397 turbanoff 320
 
1378 turbanoff 321
                lodsb
1397 turbanoff 322
                call    char_toupper
323
 
1378 turbanoff 324
                mov     ah, [edi]
325
                inc     edi
326
                xchg    al, ah
1397 turbanoff 327
                call    char_toupper
1378 turbanoff 328
                cmp     al, ah
329
                je      @B
330
          @@:                           ;не подошло
331
            pop     esi
332
        .next_rec:
333
            movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
334
            add     ebx, eax                                ;к след. записи
335
            cmp     ebx, edx                                ;проверим конец ли
1384 turbanoff 336
            jb      .start_rec
1378 turbanoff 337
            jmp     .ret
338
 
339
    .test_find:
340
        cmp     byte [esi], 0
341
        je      .find               ;нашли конец
342
        cmp     byte [esi], '/'
343
        jne      @B
344
        inc     esi
345
    .find:
346
        pop eax         ;удаляем из стека сохраненое значение
347
    .ret:
348
        pop edi edx ecx eax
349
        ret
350
 
351
;----------------------------------------------------------------
352
;
353
;  ext2_HdReadFolder - read disk folder
354
;
355
;  esi  points to filename
356
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
357
;                          & flags (bitfields)
358
; flags: bit 0: 0=ANSI names, 1=UNICODE names
359
;  ecx  number of blocks to read, 0+
360
;  edx  mem location to return data
361
;
362
;  ret ebx = blocks read or 0xffffffff folder not found
363
;      eax = 0 ok read or other = errormsg
364
;
365
;--------------------------------------------------------------
366
ext2_HdReadFolder:
367
        cmp     byte [esi], 0
1387 turbanoff 368
        jz      .doit
1378 turbanoff 369
 
1387 turbanoff 370
        push    ecx ebx
371
        call    ext2_find_lfn
372
        jnc     .doit2
373
        pop     ebx
1378 turbanoff 374
    .not_found:
1387 turbanoff 375
        pop     ecx
1378 turbanoff 376
        or      ebx, -1
377
        mov     eax, ERROR_FILE_NOT_FOUND
378
        ret
1387 turbanoff 379
 
380
    .doit:
381
        mov     ebp, [ext2_data.root_inode]
382
        push    ecx
383
        jmp     @F
384
    .doit2:
385
        pop     ebx
386
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
387
        jz      .not_found
388
    @@:
389
        xor     eax, eax
390
        mov     edi, edx
391
        mov     ecx, 32/4
392
        rep     stosd                           ; fill header zero
393
        pop     edi                             ; edi = число блоков для чтения
394
        push    edx ebx
395
 
1378 turbanoff 396
     ;--------------------------------------------- final step
397
        and     [EXT2_read_in_folder], 0
398
        and     [EXT2_files_in_folder], 0
399
 
1384 turbanoff 400
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]
401
        mov     [EXT2_counter_blocks], eax
1378 turbanoff 402
 
1397 turbanoff 403
        add     edx, 32                         ; (header pointer in stack) edx = current mem for return
1387 turbanoff 404
        xor     esi, esi                        ; esi = номер блока по порядку
1378 turbanoff 405
 
406
    .new_block_folder:              ;reserved label
407
        mov     ecx, esi                        ; получим номер блока
408
        call    ext2_get_inode_block
409
 
410
        mov     eax, ecx
411
        mov     ebx, [ext2_data.ext2_save_block]
412
        call    ext2_get_block                  ; и считываем блок с hdd
413
 
414
        mov     eax, ebx                        ; eax = current dir record
415
        add     ebx, [ext2_data.block_size]
416
        mov     [EXT2_end_block], ebx           ; запомним конец очередного блока
417
 
418
        pop     ecx
419
        mov     ecx, [ecx]                      ; ecx = first wanted (flags ommited)
420
 
421
    .find_wanted_start:
1398 turbanoff 422
            jecxz   .find_wanted_end
1378 turbanoff 423
    .find_wanted_cycle:
424
            cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
1397 turbanoff 425
            jz      @F
1378 turbanoff 426
            inc     [EXT2_files_in_folder]
1398 turbanoff 427
            dec     ecx
1378 turbanoff 428
          @@:
429
            movzx   ebx, [eax+EXT2_DIR_STRUC.rec_len]
430
            add     eax, ebx                            ; к следующей записи
431
            cmp     eax, [EXT2_end_block]              ; проверяем "конец"
1398 turbanoff 432
            jb      .find_wanted_start
433
 
434
   .end_block_find_wanted:                                   ;вылетили из цикла find_wanted
435
        mov     ebx, [ext2_data.count_block_in_block]
436
        sub     [EXT2_counter_blocks], ebx
437
        jz      .end_dir
438
 
439
        ;получаем новый блок
440
        inc     esi
441
        push    ecx
442
        mov     ecx, esi
443
        call    ext2_get_inode_block
444
        mov     eax, ecx
445
        mov     ebx, [ext2_data.ext2_save_block]
446
        call    ext2_get_block
447
        pop     ecx
448
        dec     ecx
449
        mov     eax, ebx
450
        add     ebx, [ext2_data.block_size]
451
        mov     [EXT2_end_block], ebx
452
        jmp     .find_wanted_start
453
 
1378 turbanoff 454
    .find_wanted_end:
1398 turbanoff 455
        mov     ecx, edi
1378 turbanoff 456
 
457
    .wanted_start:                                      ; ищем first_wanted+count
1397 turbanoff 458
            jecxz   .find_wanted_cycle                  ; ecx=0 => огромный цикл до конца папки
1378 turbanoff 459
            cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
460
            jz      .empty_rec
461
            inc     [EXT2_files_in_folder]
462
            inc     [EXT2_read_in_folder]
463
 
1384 turbanoff 464
            mov     edi, edx
465
            push    eax ecx
466
            xor     eax, eax
467
            mov     ecx, 40 / 4
468
            rep     stosd
469
            pop     ecx eax
1378 turbanoff 470
 
1384 turbanoff 471
            cmp     [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;папка или нет
472
            jz      @F
473
 
1378 turbanoff 474
            push    eax                                             ;получим размер, если это файл
475
            mov     eax, [eax + EXT2_DIR_STRUC.inode]
476
            mov     ebx, [ext2_data.ext2_temp_inode]
477
            call    ext2_get_inode
478
            mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
479
            mov     ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
480
            mov     dword [edx+32], eax
481
            mov     dword [edx+36], ebx
482
            xor     dword [edx], FS_FT_DIR          ; для файлов xor - 2 раза
483
            pop     eax
484
          @@:
485
            xor     dword [edx], FS_FT_DIR
1384 turbanoff 486
            or      dword [edx+4], FS_FT_ASCII      ; symbol type in name
1378 turbanoff 487
 
1397 turbanoff 488
            ;теперь скопируем название, сконвертировав из UTF-8 в CP866
489
            push    eax ecx esi
1378 turbanoff 490
            movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
1397 turbanoff 491
            lea     edi, [edx + 40]
1378 turbanoff 492
            lea     esi, [eax + EXT2_DIR_STRUC.name]
1397 turbanoff 493
            call    utf8toansi_str
494
            pop     esi ecx eax
1378 turbanoff 495
            and     byte [edi], 0
496
 
497
            add     edx, 40 + 264                       ; go to next record
1397 turbanoff 498
 
499
            dec     ecx                                 ; если запись пустая ecx не надо уменьшать
1378 turbanoff 500
        .empty_rec:
501
            movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
502
            add     eax, ebx
503
            cmp     eax, [EXT2_end_block]
1397 turbanoff 504
            jb      .wanted_start
1378 turbanoff 505
 
1397 turbanoff 506
    .end_block_wanted:                                      ;вылетели из цикла wanted
1378 turbanoff 507
        mov     ebx, [ext2_data.count_block_in_block]
508
        sub     [EXT2_counter_blocks], ebx
509
        jz      .end_dir
510
 
511
        inc     esi
512
        push    ecx
513
        mov     ecx, esi
514
        call    ext2_get_inode_block
515
        mov     eax, ecx
516
        mov     ebx, [ext2_data.ext2_save_block]
517
        call    ext2_get_block
518
        pop     ecx
519
        dec     ecx
520
        mov     eax, ebx
521
        add     ebx, [ext2_data.block_size]
522
        mov     [EXT2_end_block], ebx
1397 turbanoff 523
        jmp     .wanted_start
1378 turbanoff 524
 
1398 turbanoff 525
    .wanted_end:
526
    	dec     ecx
527
    	jmp     .find_wanted_cycle
1378 turbanoff 528
 
529
    .end_dir:
530
        pop     edx
531
        mov     ebx, [EXT2_read_in_folder]
532
        mov     ecx, [EXT2_files_in_folder]
533
        mov     dword [edx], 1    ;version
534
        xor     eax, eax
535
        mov     [edx+4], ebx
536
        mov     [edx+8], ecx
537
        lea     edi, [edx + 12]
538
        mov     ecx, 20 / 4
539
        rep     stosd
540
        ret
541
;====================== end ext2_HdReadFolder
1397 turbanoff 542
utf8toansi_str:
543
; convert UTF-8 string to ASCII-string (codepage 866)
544
; in: ecx=length source, esi->source, edi->buffer
545
; destroys: eax,esi,edi
546
        jecxz   .ret
547
    .start:
548
        lodsw
549
        cmp     al, 0x80
550
        jb      .ascii
1378 turbanoff 551
 
1397 turbanoff 552
        xchg    al, ah
553
        cmp     ax, 0xd080
554
        jz      .yo1
555
        cmp     ax, 0xd191
556
        jz      .yo2
557
        cmp     ax, 0xd090
558
        jb      .unk
559
        cmp     ax, 0xd180
560
        jb      .rus1
561
        cmp     ax, 0xd190
562
        jb      .rus2
563
    .unk:
564
        mov     al, '_'
565
        jmp     .doit
566
    .yo1:
567
        mov     al, 0xf0    ; Ё capital
568
        jmp     .doit
569
    .yo2:
570
        mov     al, 0xf1    ; ё small
571
        jmp     .doit
572
    .rus1:
573
        sub     ax, 0xd090 - 0x80
574
        jmp     .doit
575
    .rus2:
576
        sub     ax, 0xd18f - 0xEF
577
    .doit:
578
        stosb
579
        sub     ecx, 2
580
        ja      .start
581
        ret
582
 
583
    .ascii:
584
        stosb
585
        dec     esi
586
        dec     ecx
587
        jnz     .start
588
    .ret:
589
        ret
590
 
1378 turbanoff 591
;----------------------------------------------------------------
592
;
593
;  ext2_HdRead - read hard disk
594
;
595
;  esi  points to filename
596
;  ebx  pointer to 64-bit number = first wanted byte, 0+
597
;       may be ebx=0 - start from first byte
598
;  ecx  number of bytes to read, 0+
599
;  edx  mem location to return data
600
;
601
;  ret ebx = bytes read or 0xffffffff file not found
602
;      eax = 0 ok read or other = errormsg
603
;
604
;--------------------------------------------------------------
605
ext2_HdRead:
606
        cmp     byte [esi], 0
1397 turbanoff 607
        jnz     @F
1378 turbanoff 608
 
1384 turbanoff 609
    .this_is_nofile:
1378 turbanoff 610
        or      ebx, -1
611
        mov     eax, ERROR_ACCESS_DENIED
612
        ret
613
 
1397 turbanoff 614
    @@:
615
        push    ecx ebx
616
        call    ext2_find_lfn
617
        pop     ebx ecx
618
        jnc     .doit
619
    ;.not_found:
620
        or      ebx, -1
621
        mov     eax, ERROR_FILE_NOT_FOUND
622
        ret
623
 
624
    .doit:
625
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
626
        jz      .this_is_nofile
627
 
1378 turbanoff 628
    ;-----------------------------------------------------------------------------final step
629
 
1397 turbanoff 630
        mov     edi, edx            ; edi = pointer to return mem
631
        mov     esi, ebx            ; esi = pointer to first_wanted
1378 turbanoff 632
 
633
        ;///// сравним хватит ли нам файла или нет
634
        mov     ebx, [esi+4]
635
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
636
 
1397 turbanoff 637
   ;    mov     edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
638
   ;    mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]        ;edx : ecx - размер файла
1378 turbanoff 639
 
1397 turbanoff 640
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
1378 turbanoff 641
        ja      .size_great
642
        jb      .size_less
643
 
1397 turbanoff 644
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
1378 turbanoff 645
        ja      .size_great
646
 
647
    .size_less:
1397 turbanoff 648
        pop     ecx
649
        xor     ebx, ebx
1378 turbanoff 650
        mov     eax, 6      ;EOF
651
        ret
652
    .size_great:
1397 turbanoff 653
        add     eax, ecx                  ;add to first_wanted кол-во байт для чтения
654
        adc     ebx, 0
655
 
656
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
1378 turbanoff 657
        ja      .size_great_great
658
        jb      .size_great_less
1397 turbanoff 659
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
660
        jae     .size_great_great               ; а если равно, то не важно куда
661
 
1378 turbanoff 662
    .size_great_less:
663
        or      [EXT2_files_in_folder], 1       ;читаем по границе размера
1397 turbanoff 664
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]
665
        sub     ecx, [esi]                      ;(размер - старт)
1378 turbanoff 666
        jmp     @F
667
 
668
    .size_great_great:
1397 turbanoff 669
        and     [EXT2_files_in_folder], 0       ;читаем столько сколько запросили
1378 turbanoff 670
 
671
    @@:
1397 turbanoff 672
        push    ecx                             ;save for return
673
        test    esi, esi
674
        jz      .zero_start
1378 turbanoff 675
 
676
        ;пока делаем п..ц криво =)
1397 turbanoff 677
        mov     edx, [esi+4]
678
        mov     eax, [esi]
1378 turbanoff 679
        div     [ext2_data.block_size]
680
 
681
        mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
682
 
683
        push    ecx
684
        mov     ecx, eax
685
        call    ext2_get_inode_block
1397 turbanoff 686
        mov     ebx, [ext2_data.ext2_save_block]
1378 turbanoff 687
        mov     eax, ecx
688
        call    ext2_get_block
689
        pop     ecx
690
        add     ebx, edx
691
 
692
        neg     edx
1397 turbanoff 693
        add     edx,[ext2_data.block_size]      ;block_size - стартовый байт = сколько байт 1-го блока
1378 turbanoff 694
        cmp     ecx, edx
695
        jbe     .only_one_block
696
 
697
        mov     eax, ecx
698
        sub     eax, edx
699
        mov     ecx, edx
700
 
701
        mov     esi, ebx
702
        rep     movsb                           ;кусок 1-го блока
1389 turbanoff 703
        jmp     @F
1378 turbanoff 704
 
705
    .zero_start:
1389 turbanoff 706
        mov     eax, ecx
1378 turbanoff 707
        ;теперь в eax кол-во оставшихся байт для чтения
1389 turbanoff 708
    @@:
1397 turbanoff 709
        mov     ebx, edi                        ;чтение блока прям в ->ebx
1378 turbanoff 710
        xor     edx, edx
1389 turbanoff 711
        div     [ext2_data.block_size]          ;кол-во байт в последнем блоке (остаток) в edx
1397 turbanoff 712
        mov     edi, eax                        ;кол-во целых блоков в edi
1378 turbanoff 713
    @@:
1397 turbanoff 714
        test     edi, edi
1378 turbanoff 715
        jz      .finish_block
716
        inc     [EXT2_counter_blocks]
717
        mov     ecx, [EXT2_counter_blocks]
718
        call    ext2_get_inode_block
719
 
1397 turbanoff 720
        mov     eax, ecx                        ;а ebx уже забит нужным значением
1378 turbanoff 721
        call    ext2_get_block
722
        add     ebx, [ext2_data.block_size]
723
 
1397 turbanoff 724
        dec     edi
1378 turbanoff 725
        jmp     @B
726
 
727
    .finish_block:          ;в edx - кол-во байт в последнем блоке
1397 turbanoff 728
        test    edx, edx
729
        jz      .end_read
1378 turbanoff 730
 
731
        mov     ecx, [EXT2_counter_blocks]
732
        inc     ecx
733
        call    ext2_get_inode_block
734
 
735
        mov     edi, ebx
736
        mov     eax, ecx
737
        mov     ebx, [ext2_data.ext2_save_block]
738
        call    ext2_get_block
739
 
740
        mov     ecx, edx
741
 
742
    .only_one_block:
743
        mov     esi, ebx
1389 turbanoff 744
        rep     movsb                           ;кусок last блока
745
    .end_read:
1378 turbanoff 746
        pop     ebx
747
        cmp     [EXT2_files_in_folder], 0
748
        jz      @F
749
 
750
        mov     eax, 6      ;EOF
751
        ret
752
    @@:
753
        xor     eax, eax
754
        ret
755
;========================
1384 turbanoff 756
;in : esi -> name           not save register
757
;out: ebp -> inode cf=0
758
;     ebp -> trash cf=1
759
ext2_find_lfn:
760
        mov     ebp, [ext2_data.root_inode]
761
    .next_folder:
762
        or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
763
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
764
        add     eax, [ext2_data.count_block_in_block]
765
        mov     [EXT2_end_block], eax
766
    .next_block_folder:
767
        mov     eax, [ext2_data.count_block_in_block]
768
        sub     [EXT2_end_block], eax
769
        jz      .not_found
770
        inc     [EXT2_counter_blocks]
771
        mov     ecx, [EXT2_counter_blocks]
772
        call    ext2_get_inode_block
1378 turbanoff 773
 
1384 turbanoff 774
        mov     eax, ecx
775
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
776
        call    ext2_get_block
777
 
778
        mov     eax, esi
779
        call    ext2_test_block_by_name
780
        cmp     eax, esi                                ;нашли имя?
781
        jz      .next_block_folder
782
 
783
        cmp     byte [esi],0
784
        jz      .get_inode_ret
785
 
786
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
787
        jne     .not_found                                      ;нашли, но это не папка
788
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
789
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
790
        call    ext2_get_inode
791
        mov     ebp, ebx
792
        jmp     .next_folder
793
 
794
    .not_found:
795
        stc
796
        ret
797
    .get_inode_ret:
798
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
799
        mov     ebx, [ext2_data.ext2_save_inode]
800
        call    ext2_get_inode
801
        mov     ebp, ebx
802
        clc
803
        ret
804
 
805
 
806
;========================
1378 turbanoff 807
ext2_HdRewrite:
808
;    xchg    bx, bx
809
        xor     ebx, ebx
810
        mov     eax, ERROR_UNSUPPORTED_FS
811
        ret
812
 
813
ext2_HdWrite:
814
;    xchg    bx, bx
815
        xor     ebx, ebx
816
        mov     eax, ERROR_UNSUPPORTED_FS
817
        ret
818
ext2_HdSetFileEnd:
819
;    xchg    bx, bx
820
        xor     ebx, ebx
821
        mov     eax, ERROR_UNSUPPORTED_FS
822
        ret
1384 turbanoff 823
 
1378 turbanoff 824
ext2_HdGetFileInfo:
1384 turbanoff 825
        cmp     byte [esi], 0
826
        jz      .doit
827
 
828
        call    ext2_find_lfn
829
        jnc     .doit2
830
    ;.not_found:
831
        mov     eax, ERROR_FILE_NOT_FOUND
1378 turbanoff 832
        ret
1384 turbanoff 833
 
834
    .doit:
835
        mov     ebp, [ext2_data.root_inode]
836
    .doit2:
837
        xor     eax, eax
838
        mov     edi, edx
839
        mov     ecx, 40/4
840
        rep stosd               ; fill zero
841
 
842
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
843
        jz      @F
844
        or      dword [edx], FS_FT_DIR
845
    @@:
846
        mov     byte [edx+1], FS_FT_ASCII
847
        mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
848
        mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
849
        mov     dword [edx+32], eax
850
        mov     dword [edx+36], ebx
851
 
852
        xor     eax, eax
853
        ret
854
 
1378 turbanoff 855
ext2_HdSetFileInfo:
856
;    xchg    bx, bx
857
        xor     ebx, ebx
858
        mov     eax, ERROR_UNSUPPORTED_FS
859
        ret
860
ext2_HdDelete:
861
;    xchg    bx, bx
862
        xor     ebx, ebx
863
        mov     eax, ERROR_UNSUPPORTED_FS
864
        ret
865