Subversion Repositories Kolibri OS

Rev

Rev 1384 | 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: 1387 $
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
 
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
 
1387 turbanoff 112
        push    eax eax eax                             ; 3 kernel_alloc
1378 turbanoff 113
 
114
        mov     eax, edx
115
        mul     edx
116
        mov     [ext2_data.count_pointer_in_block_square], eax
117
 
118
        call    kernel_alloc
1387 turbanoff 119
        mov     [ext2_data.global_desc_table],eax       ; reserve mem for gdt
1378 turbanoff 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
 
1384 turbanoff 125
        movzx   ebp, word [ebx+88]
1378 turbanoff 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
;===================================================================
1387 turbanoff 171
; in:  ecx = номер блока в inode (0..)
1378 turbanoff 172
;      ebp = адрес inode
173
; out: ecx = адрес очередного блока
174
ext2_get_inode_block:
1387 turbanoff 175
        cmp     ecx, 12                                         ; 0..11 - direct block address
176
        jb      .get_direct_block
1378 turbanoff 177
 
178
        sub     ecx, 12
1387 turbanoff 179
        cmp     ecx, [ext2_data.count_pointer_in_block]         ; 12.. - indirect block
180
        jb      .get_indirect_block
1378 turbanoff 181
 
182
        sub     ecx, [ext2_data.count_pointer_in_block]
183
        cmp     ecx, [ext2_data.count_pointer_in_block_square]
1387 turbanoff 184
        jb      .get_double_indirect_block
1378 turbanoff 185
 
1387 turbanoff 186
        sub     ecx, [ext2_data.count_pointer_in_block_square]
1378 turbanoff 187
    ;.get_triple_indirect_block:
188
        push    eax edx ebx
189
 
190
        mov    eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
191
        mov    ebx, [ext2_data.ext2_temp_block]
192
        call    ext2_get_block
193
 
194
        xor     edx, edx
195
        mov     eax, ecx
196
        div     [ext2_data.count_pointer_in_block_square]
197
 
198
    ;eax - номер в полученном блоке   edx - номер дальше
199
        mov    eax, [ebx + eax*4]
1387 turbanoff 200
        call   ext2_get_block
1378 turbanoff 201
 
202
        mov    eax, edx
203
        jmp    @F
204
 
205
    .get_double_indirect_block:
206
        push    eax edx ebx
207
 
208
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
209
        mov     ebx, [ext2_data.ext2_temp_block]
210
        call    ext2_get_block
211
 
212
        mov     eax, ecx
213
      @@:
214
        xor     edx, edx
215
        div     [ext2_data.count_pointer_in_block]
216
 
217
        mov    eax, [ebx + eax*4]
218
        call    ext2_get_block
219
        mov    ecx, [ebx + edx*4]
220
 
221
        pop     ebx edx eax
222
        ret
223
 
224
    .get_indirect_block:
225
        push    eax ebx
226
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
1387 turbanoff 227
        mov     ebx, [ext2_data.ext2_temp_block]
1378 turbanoff 228
        call    ext2_get_block
229
 
230
        mov     ecx, [ebx + ecx*4]
231
        pop     ebx eax
232
        ret
233
 
234
    .get_direct_block:
235
        mov     ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
236
        ret
237
 
238
 
239
;===================================================================
240
;get content inode by num
241
;in:   eax = inode_num
242
;      ebx = address of inode content
243
ext2_get_inode:
244
 
245
    pushad
246
    mov     edi, ebx        ;сохраним адрес inode
247
    dec    eax
248
    xor    edx, edx
249
    div    [ext2_data.inodes_per_group]
250
 
251
        push    edx                             ;locale num
252
 
253
        mov     edx, 32
254
        mul     edx                             ; address block_group in global_desc_table
255
 
256
        add     eax, [ext2_data.global_desc_table]
257
        mov     eax, [eax+8]                    ; номер блока - в терминах ext2
258
 
259
        mov     ecx, [ext2_data.log_block_size]
260
        shl     eax, cl
261
        add     eax, [PARTITION_START]          ; а старт раздела - в терминах hdd (512)
262
 
263
        ;eax - указывает на таблицу inode-ов на hdd
264
        mov     ecx, eax                        ;сохраним его пока в ecx
265
 
266
        ; прибавим локальный адрес inode-а
267
        pop     eax                             ; index
268
        mul     [ext2_data.inode_size]        ; (index * inode_size)
269
        mov     ebp, 512
270
        div     ebp                             ;поделим на размер блока
271
 
272
        add     eax, ecx                        ;нашли адрес блока для чтения
273
        mov     ebx, [ext2_data.ext2_temp_block]
274
        call    hd_read
275
 
276
        mov     esi, edx                        ;добавим "остаток"
277
        add     esi, ebx                        ;к адресу
278
        mov     ecx, [ext2_data.inode_size]
279
        rep     movsb                           ;копируем inode
280
        popad
281
        ret
282
 
283
;----------------------------------------------------------------
284
ext2_upcase:
285
        cmp     al, 'a'
286
        jb      .ret
287
        cmp     al, 'z'
288
        ja      .ret
289
        and     al, 0xDF        ; upcase = clear 0010 0000
290
    .ret:
291
        ret
292
;----------------------------------------------------------------
293
; in:  esi -> children
294
;      ebx -> pointer to dir block
295
; out: esi -> name without parent or not_changed
296
;      ebx -> dir_rec of inode children      or trash
297
ext2_test_block_by_name:
298
        push    eax ecx edx edi
299
 
300
        mov        edx, ebx
301
        add        edx, [ext2_data.block_size]    ;запомним конец блока
302
 
303
        .start_rec:
304
            cmp     [ebx + EXT2_DIR_STRUC.inode], 0
305
            jz      .next_rec
306
;            test    [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
307
;            jz      .next_rec
308
 
309
            push    esi
310
            movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
311
            lea     edi, [ebx + EXT2_DIR_STRUC.name]
312
            inc     ecx
313
 
314
          @@:
315
                dec     ecx
316
                jecxz   .test_find
317
                lodsb
318
                mov     ah, [edi]
319
                inc     edi
320
 
321
                call    ext2_upcase
322
                xchg    al, ah
323
                call    ext2_upcase
324
                cmp     al, ah
325
                je      @B
326
          @@:                           ;не подошло
327
            pop     esi
328
        .next_rec:
329
            movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
330
            add     ebx, eax                                ;к след. записи
331
            cmp     ebx, edx                                ;проверим конец ли
1384 turbanoff 332
            jb      .start_rec
1378 turbanoff 333
            jmp     .ret
334
 
335
    .test_find:
336
        cmp     byte [esi], 0
337
        je      .find               ;нашли конец
338
        cmp     byte [esi], '/'
339
        jne      @B
340
        inc     esi
341
    .find:
342
        pop eax         ;удаляем из стека сохраненое значение
343
       ; mov ebx, [ebx + EXT2_DIR_STRUC.inode]
344
    .ret:
345
        pop edi edx ecx eax
346
        ret
347
 
348
;----------------------------------------------------------------
349
;
350
;  ext2_HdReadFolder - read disk folder
351
;
352
;  esi  points to filename
353
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
354
;                          & flags (bitfields)
355
; flags: bit 0: 0=ANSI names, 1=UNICODE names
356
;  ecx  number of blocks to read, 0+
357
;  edx  mem location to return data
358
;
359
;  ret ebx = blocks read or 0xffffffff folder not found
360
;      eax = 0 ok read or other = errormsg
361
;
362
;--------------------------------------------------------------
363
uglobal
364
    EXT2_files_in_folder    dd ?   ;всего файлов в папке
365
    EXT2_read_in_folder     dd ?   ;сколько файлов "считали"
366
    EXT2_end_block          dd ?   ;конец очередного блока папки
367
    EXT2_counter_blocks     dd ?
368
endg
369
 
370
ext2_HdReadFolder:
371
        cmp     byte [esi], 0
1387 turbanoff 372
        jz      .doit
1378 turbanoff 373
 
1387 turbanoff 374
        push    ecx ebx
375
        call    ext2_find_lfn
376
        jnc     .doit2
377
        pop     ebx
1378 turbanoff 378
    .not_found:
1387 turbanoff 379
        pop     ecx
1378 turbanoff 380
        or      ebx, -1
381
        mov     eax, ERROR_FILE_NOT_FOUND
382
        ret
1387 turbanoff 383
 
384
    .doit:
385
        mov     ebp, [ext2_data.root_inode]
386
        push    ecx
387
        jmp     @F
388
    .doit2:
389
        pop     ebx
390
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
391
        jz      .not_found
392
    @@:
393
        xor     eax, eax
394
        mov     edi, edx
395
        mov     ecx, 32/4
396
        rep     stosd                           ; fill header zero
397
        pop     edi                             ; edi = число блоков для чтения
398
        push    edx ebx
399
 
1378 turbanoff 400
     ;--------------------------------------------- final step
401
        and     [EXT2_read_in_folder], 0
402
        and     [EXT2_files_in_folder], 0
403
 
1384 turbanoff 404
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]
405
        mov     [EXT2_counter_blocks], eax
1378 turbanoff 406
 
1387 turbanoff 407
        add     edx, 32                         ; заголовок будем заполнять в конце (адрес - в стеке) edx = current mem for return
408
        xor     esi, esi                        ; esi = номер блока по порядку
1378 turbanoff 409
 
410
    .new_block_folder:              ;reserved label
411
        mov     ecx, esi                        ; получим номер блока
412
        call    ext2_get_inode_block
413
 
414
        mov     eax, ecx
415
        mov     ebx, [ext2_data.ext2_save_block]
416
        call    ext2_get_block                  ; и считываем блок с hdd
417
 
418
        mov     eax, ebx                        ; eax = current dir record
419
        add     ebx, [ext2_data.block_size]
420
        mov     [EXT2_end_block], ebx           ; запомним конец очередного блока
421
 
422
        pop     ecx
423
        mov     ecx, [ecx]                      ; ecx = first wanted (flags ommited)
424
 
425
    .find_wanted_start:
426
        jecxz   .find_wanted_end
427
    .find_wanted_cycle:
428
            cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
429
            je      @F
430
            inc     [EXT2_files_in_folder]
431
          @@:
432
            movzx   ebx, [eax+EXT2_DIR_STRUC.rec_len]
433
            add     eax, ebx                            ; к следующей записи
434
            cmp     eax, [EXT2_end_block]              ; проверяем "конец"
1384 turbanoff 435
            jae      .end_block_find_wanted
1378 turbanoff 436
            loop    .find_wanted_cycle
437
    .find_wanted_end:
438
 
439
        mov     ecx, edi
440
    .wanted_start:                                      ; ищем first_wanted+count
441
        jecxz   .wanted_end
442
    .wanted_cycle:
443
            cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
444
            jz      .empty_rec
445
            inc     [EXT2_files_in_folder]
446
            inc     [EXT2_read_in_folder]
447
 
1384 turbanoff 448
            mov     edi, edx
449
            push    eax ecx
450
            xor     eax, eax
451
            mov     ecx, 40 / 4
452
            rep     stosd
453
            pop     ecx eax
1378 turbanoff 454
 
1384 turbanoff 455
            cmp     [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;папка или нет
456
            jz      @F
457
 
1378 turbanoff 458
            push    eax                                             ;получим размер, если это файл
459
            mov     eax, [eax + EXT2_DIR_STRUC.inode]
460
            mov     ebx, [ext2_data.ext2_temp_inode]
461
            call    ext2_get_inode
462
            mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
463
            mov     ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
464
            mov     dword [edx+32], eax
465
            mov     dword [edx+36], ebx
466
            xor     dword [edx], FS_FT_DIR          ; для файлов xor - 2 раза
467
            pop     eax
468
          @@:
469
            xor     dword [edx], FS_FT_DIR
1384 turbanoff 470
            or      dword [edx+4], FS_FT_ASCII      ; symbol type in name
1378 turbanoff 471
 
472
            push    ecx esi                         ;copy name
473
            movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
474
            mov     edi, edx
475
            add     edi, 40
476
            lea     esi, [eax + EXT2_DIR_STRUC.name]
477
            rep     movsb
478
            pop     esi ecx
479
            and     byte [edi], 0
480
 
481
            add     edx, 40 + 264                       ; go to next record
482
        .empty_rec:
483
            movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
484
            add     eax, ebx
485
            cmp     eax, [EXT2_end_block]
1384 turbanoff 486
            jae     .end_block_wanted                   ;по хорошему должно быть =, но ччнш
1378 turbanoff 487
            loop    .wanted_cycle
488
 
489
    .wanted_end:                        ;теперь дойдем до конца чтобы узнать сколько файлов в папке
490
        or      ecx, -1                 ;цикл уже есть, просто поставим ему огромный счетчик
491
        jmp     .find_wanted_cycle
492
 
493
    .end_block_find_wanted:                                   ;вылетили из цикла find_wanted
494
        mov     ebx, [ext2_data.count_block_in_block]
495
        sub     [EXT2_counter_blocks], ebx
496
        jz      .end_dir
497
 
498
        ;получаем новый блок
499
        inc     esi
500
        push    ecx
501
        mov     ecx, esi
502
        call    ext2_get_inode_block
503
        mov     eax, ecx
504
        mov     ebx, [ext2_data.ext2_save_block]
505
        call    ext2_get_block
506
        pop     ecx
507
        dec     ecx
508
        mov     eax, ebx
509
        add     ebx, [ext2_data.block_size]
510
        mov     [EXT2_end_block], ebx
511
        jmp     .find_wanted_start
512
 
513
    .end_block_wanted:                                      ;вылетели из цикла wanted
514
        mov     ebx, [ext2_data.count_block_in_block]
515
        sub     [EXT2_counter_blocks], ebx
516
        jz      .end_dir
517
 
518
        inc     esi
519
        push    ecx
520
        mov     ecx, esi
521
        call    ext2_get_inode_block
522
        mov     eax, ecx
523
        mov     ebx, [ext2_data.ext2_save_block]
524
        call    ext2_get_block
525
        pop     ecx
526
        dec     ecx
527
        mov     eax, ebx
528
        add     ebx, [ext2_data.block_size]
529
        mov     [EXT2_end_block], ebx
530
        jmp     .wanted_start
531
 
532
    .end_dir:
533
        pop     edx
534
        mov     ebx, [EXT2_read_in_folder]
535
        mov     ecx, [EXT2_files_in_folder]
536
        mov     dword [edx], 1    ;version
537
        xor     eax, eax
538
        mov     [edx+4], ebx
539
        mov     [edx+8], ecx
540
        lea     edi, [edx + 12]
541
        mov     ecx, 20 / 4
542
        rep     stosd
543
        ret
544
;====================== end ext2_HdReadFolder
545
 
546
;----------------------------------------------------------------
547
;
548
;  ext2_HdRead - read hard disk
549
;
550
;  esi  points to filename
551
;  ebx  pointer to 64-bit number = first wanted byte, 0+
552
;       may be ebx=0 - start from first byte
553
;  ecx  number of bytes to read, 0+
554
;  edx  mem location to return data
555
;
556
;  ret ebx = bytes read or 0xffffffff file not found
557
;      eax = 0 ok read or other = errormsg
558
;
559
;--------------------------------------------------------------
560
ext2_HdRead:
561
        mov     ebp, [ext2_data.root_inode]
562
 
1384 turbanoff 563
        push    ecx edx ebx
1378 turbanoff 564
    .next_folder:
565
        push    esi
566
    @@:
567
            lodsb
568
            test    al, al
569
            jz      .find_end
570
            cmp     al, '/'
571
            jz      .find_folder
572
            jmp     @B
573
 
574
    .find_end:
575
        ;установим флаг что ищем файл или очередную папку
576
        mov     edi, 1
577
        jmp     .find_any
578
    .find_folder:
579
        xor     edi, edi
580
    .find_any:
581
        pop     esi
582
 
583
        cmp     byte [esi], 0
584
        jz      .not_found
585
 
586
        or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
587
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
588
        add     eax, [ext2_data.count_block_in_block]
589
        mov     [EXT2_end_block], eax
590
    .next_block_folder:
591
        mov     eax, [ext2_data.count_block_in_block]
592
        sub     [EXT2_end_block], eax
593
        jz      .not_found
594
        inc     [EXT2_counter_blocks]
595
        mov     ecx, [EXT2_counter_blocks]
596
        call    ext2_get_inode_block
597
 
598
        mov     eax, ecx
599
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
600
        call    ext2_get_block
601
 
602
        mov     eax, esi
603
        call    ext2_test_block_by_name
604
        cmp     eax, esi                                ;нашли имя?
605
        je      .next_block_folder
606
 
607
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_REG_FILE
608
        je      .test_file
609
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
1384 turbanoff 610
        jne     .this_is_nofile
611
 
612
    ;.test_dir:
1378 turbanoff 613
        cmp     edi, 0
1384 turbanoff 614
        jne     .this_is_nofile
1378 turbanoff 615
 
616
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
617
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
618
        call    ext2_get_inode
619
        mov     ebp, ebx
620
        jmp     .next_folder
621
 
622
    .test_file:
623
        cmp     edi, 0
624
        je      .not_found
625
 
626
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
627
        mov     ebx, [ext2_data.ext2_save_inode]
628
        call    ext2_get_inode
629
        jmp     .get_file
630
 
631
    .not_found:
632
    	pop     edx ecx ebx
633
        or      ebx, -1
634
        mov     eax, ERROR_FILE_NOT_FOUND
635
        ret
1384 turbanoff 636
    .this_is_nofile:
1378 turbanoff 637
        pop     edx ecx ebx
638
        or      ebx, -1
639
        mov     eax, ERROR_ACCESS_DENIED
640
    .end_read:
641
        ret
642
 
643
    ;-----------------------------------------------------------------------------final step
644
    .get_file:
645
        mov     ebp ,ebx
646
 
647
        ;pop     eax edi ecx         ; первый_блок память кол-во_байт
648
        mov     esi, [esp]
649
        mov     edi, [esp + 8]      ;edi = нужно считать байт
650
 
651
        ;///// сравним хватит ли нам файла или нет
652
        mov     ebx, [esi+4]
653
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
654
 
655
        mov     edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
656
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]        ;edx : ecx - размер файла
657
 
658
        cmp     edx, ebx
659
        ja      .size_great
660
        jb      .size_less
661
 
662
        cmp     ecx, eax
663
        ja      .size_great
664
 
665
    .size_less:
666
        add     esp, 12
667
        mov     ebx, 0
668
        mov     eax, 6      ;EOF
669
        ret
670
    .size_great:
671
        ;прибавим к старту кол-во байт для чтения
672
        add     eax, edi
673
        jnc     @F
674
        inc     ebx
675
    @@:
676
        cmp     edx, ebx
677
        ja      .size_great_great
678
        jb      .size_great_less
679
        cmp     ecx, eax
680
        jae     .size_great_great
681
        ;jmp      .size_great_less
682
                                                ; а если равно, то не важно куда
683
    .size_great_less:
684
        or      [EXT2_files_in_folder], 1       ;читаем по границе размера
685
        sub     ecx, [esi]
686
        pop     eax edi edx                     ;ecx - не меняем
687
        jmp     @F
688
 
689
    .size_great_great:
690
        and     [EXT2_files_in_folder], 0       ;читаем нормально
691
        pop     eax edi ecx
692
 
693
    @@:
694
        push    ecx                             ;сохраним размер считанных байт в стеке
695
        test    eax, eax
696
        je      .zero_start
697
 
698
        ;пока делаем п..ц криво =)
699
        mov     edx, [eax+4]
700
        mov     eax, [eax]
701
        div     [ext2_data.block_size]
702
 
703
        mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
704
 
705
        push    ecx
706
        mov     ecx, eax
707
        call    ext2_get_inode_block
708
        mov     ebx , [ext2_data.ext2_save_block]
709
        mov     eax, ecx
710
        call    ext2_get_block
711
        pop     ecx
712
        add     ebx, edx
713
 
714
        neg     edx
715
        add     edx,[ext2_data.block_size]      ;block_size - стартоый блок = сколько байт 1-го блока
716
        cmp     ecx, edx
717
        jbe     .only_one_block
718
 
719
        mov     eax, ecx
720
        sub     eax, edx
721
        mov     ecx, edx
722
 
723
        mov     esi, ebx
724
        rep     movsb                           ;кусок 1-го блока
725
 
726
    .zero_start:
727
        mov     ebx, edi                        ;чтение блока прям в ebx
728
        ;теперь в eax кол-во оставшихся байт для чтения
729
        xor     edx, edx
730
        div     [ext2_data.block_size]
731
        mov     [EXT2_end_block], eax          ;кол-во целых блоков
732
    @@:
733
        cmp     [EXT2_end_block], 0
734
        jz      .finish_block
735
        inc     [EXT2_counter_blocks]
736
        mov     ecx, [EXT2_counter_blocks]
737
        call    ext2_get_inode_block
738
 
739
        mov     eax, ecx            ;а ebx уже забит нужным значением
740
        call    ext2_get_block
741
        add     ebx, [ext2_data.block_size]
742
 
743
        dec     [EXT2_end_block]
744
        jmp     @B
745
 
746
    .finish_block:          ;в edx - кол-во байт в последнем блоке
747
        cmp     edx, 0
748
        je      .end_read
749
 
750
        mov     ecx, [EXT2_counter_blocks]
751
        inc     ecx
752
        call    ext2_get_inode_block
753
 
754
        mov     edi, ebx
755
        mov     eax, ecx
756
        mov     ebx, [ext2_data.ext2_save_block]
757
        call    ext2_get_block
758
 
759
        mov     ecx, edx
760
 
761
    .only_one_block:
762
        mov     esi, ebx
763
        rep     movsb                           ;кусок 1-го блока (последнего)
764
        pop     ebx
765
        cmp     [EXT2_files_in_folder], 0
766
        jz      @F
767
 
768
        mov     eax, 6      ;EOF
769
        ret
770
    @@:
771
        xor     eax, eax
772
        ret
773
;========================
1384 turbanoff 774
;in : esi -> name           not save register
775
;out: ebp -> inode cf=0
776
;     ebp -> trash cf=1
777
ext2_find_lfn:
778
        mov     ebp, [ext2_data.root_inode]
779
    .next_folder:
780
        or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
781
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
782
        add     eax, [ext2_data.count_block_in_block]
783
        mov     [EXT2_end_block], eax
784
    .next_block_folder:
785
        mov     eax, [ext2_data.count_block_in_block]
786
        sub     [EXT2_end_block], eax
787
        jz      .not_found
788
        inc     [EXT2_counter_blocks]
789
        mov     ecx, [EXT2_counter_blocks]
790
        call    ext2_get_inode_block
1378 turbanoff 791
 
1384 turbanoff 792
        mov     eax, ecx
793
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
794
        call    ext2_get_block
795
 
796
        mov     eax, esi
797
        call    ext2_test_block_by_name
798
        cmp     eax, esi                                ;нашли имя?
799
        jz      .next_block_folder
800
 
801
        cmp     byte [esi],0
802
        jz      .get_inode_ret
803
 
804
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
805
        jne     .not_found                                      ;нашли, но это не папка
806
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
807
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
808
        call    ext2_get_inode
809
        mov     ebp, ebx
810
        jmp     .next_folder
811
 
812
    .not_found:
813
        stc
814
        ret
815
    .get_inode_ret:
816
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
817
        mov     ebx, [ext2_data.ext2_save_inode]
818
        call    ext2_get_inode
819
        mov     ebp, ebx
820
    .ret:
821
        clc
822
        ret
823
 
824
 
825
;========================
1378 turbanoff 826
ext2_HdRewrite:
827
;    xchg    bx, bx
828
        xor     ebx, ebx
829
        mov     eax, ERROR_UNSUPPORTED_FS
830
        ret
831
 
832
ext2_HdWrite:
833
;    xchg    bx, bx
834
        xor     ebx, ebx
835
        mov     eax, ERROR_UNSUPPORTED_FS
836
        ret
837
ext2_HdSetFileEnd:
838
;    xchg    bx, bx
839
        xor     ebx, ebx
840
        mov     eax, ERROR_UNSUPPORTED_FS
841
        ret
1384 turbanoff 842
 
1378 turbanoff 843
ext2_HdGetFileInfo:
1384 turbanoff 844
        cmp     byte [esi], 0
845
        jz      .doit
846
 
847
        call    ext2_find_lfn
848
        jnc     .doit2
849
    ;.not_found:
850
        mov     eax, ERROR_FILE_NOT_FOUND
1378 turbanoff 851
        ret
1384 turbanoff 852
 
853
    .doit:
854
        mov     ebp, [ext2_data.root_inode]
855
    .doit2:
856
        xor     eax, eax
857
        mov     edi, edx
858
        mov     ecx, 40/4
859
        rep stosd               ; fill zero
860
 
861
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
862
        jz      @F
863
        or      dword [edx], FS_FT_DIR
864
    @@:
865
        mov     byte [edx+1], FS_FT_ASCII
866
        mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
867
        mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
868
        mov     dword [edx+32], eax
869
        mov     dword [edx+36], ebx
870
 
871
        xor     eax, eax
872
        ret
873
 
1378 turbanoff 874
ext2_HdSetFileInfo:
875
;    xchg    bx, bx
876
        xor     ebx, ebx
877
        mov     eax, ERROR_UNSUPPORTED_FS
878
        ret
879
ext2_HdDelete:
880
;    xchg    bx, bx
881
        xor     ebx, ebx
882
        mov     eax, ERROR_UNSUPPORTED_FS
883
        ret
884