Subversion Repositories Kolibri OS

Rev

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