Subversion Repositories Kolibri OS

Rev

Rev 1378 | 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: 1384 $
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
 
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
 
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
;===================================================================
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                                ;проверим конец ли
1384 turbanoff 331
            jb      .start_rec
1378 turbanoff 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
 
1384 turbanoff 421
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]
422
        mov     [EXT2_counter_blocks], eax
1378 turbanoff 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]              ; проверяем "конец"
1384 turbanoff 452
            jae      .end_block_find_wanted
1378 turbanoff 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
 
1384 turbanoff 465
            mov     edi, edx
466
            push    eax ecx
467
            xor     eax, eax
468
            mov     ecx, 40 / 4
469
            rep     stosd
470
            pop     ecx eax
1378 turbanoff 471
 
1384 turbanoff 472
            cmp     [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;папка или нет
473
            jz      @F
474
 
1378 turbanoff 475
            push    eax                                             ;получим размер, если это файл
476
            mov     eax, [eax + EXT2_DIR_STRUC.inode]
477
            mov     ebx, [ext2_data.ext2_temp_inode]
478
            call    ext2_get_inode
479
            mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
480
            mov     ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
481
            mov     dword [edx+32], eax
482
            mov     dword [edx+36], ebx
483
            xor     dword [edx], FS_FT_DIR          ; для файлов xor - 2 раза
484
            pop     eax
485
          @@:
486
            xor     dword [edx], FS_FT_DIR
1384 turbanoff 487
            or      dword [edx+4], FS_FT_ASCII      ; symbol type in name
1378 turbanoff 488
 
489
            push    ecx esi                         ;copy name
490
            movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
491
            mov     edi, edx
492
            add     edi, 40
493
            lea     esi, [eax + EXT2_DIR_STRUC.name]
494
            rep     movsb
495
            pop     esi ecx
496
            and     byte [edi], 0
497
 
498
            add     edx, 40 + 264                       ; go to next record
499
        .empty_rec:
500
            movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
501
            add     eax, ebx
502
            cmp     eax, [EXT2_end_block]
1384 turbanoff 503
            jae     .end_block_wanted                   ;по хорошему должно быть =, но ччнш
1378 turbanoff 504
            loop    .wanted_cycle
505
 
506
    .wanted_end:                        ;теперь дойдем до конца чтобы узнать сколько файлов в папке
507
        or      ecx, -1                 ;цикл уже есть, просто поставим ему огромный счетчик
508
        jmp     .find_wanted_cycle
509
 
510
    .end_block_find_wanted:                                   ;вылетили из цикла find_wanted
511
        mov     ebx, [ext2_data.count_block_in_block]
512
        sub     [EXT2_counter_blocks], ebx
513
        jz      .end_dir
514
 
515
        ;получаем новый блок
516
        inc     esi
517
        push    ecx
518
        mov     ecx, esi
519
        call    ext2_get_inode_block
520
        mov     eax, ecx
521
        mov     ebx, [ext2_data.ext2_save_block]
522
        call    ext2_get_block
523
        pop     ecx
524
        dec     ecx
525
        mov     eax, ebx
526
        add     ebx, [ext2_data.block_size]
527
        mov     [EXT2_end_block], ebx
528
        jmp     .find_wanted_start
529
 
530
    .end_block_wanted:                                      ;вылетели из цикла wanted
531
        mov     ebx, [ext2_data.count_block_in_block]
532
        sub     [EXT2_counter_blocks], ebx
533
        jz      .end_dir
534
 
535
        inc     esi
536
        push    ecx
537
        mov     ecx, esi
538
        call    ext2_get_inode_block
539
        mov     eax, ecx
540
        mov     ebx, [ext2_data.ext2_save_block]
541
        call    ext2_get_block
542
        pop     ecx
543
        dec     ecx
544
        mov     eax, ebx
545
        add     ebx, [ext2_data.block_size]
546
        mov     [EXT2_end_block], ebx
547
        jmp     .wanted_start
548
 
549
    .end_dir:
550
        pop     edx
551
        mov     ebx, [EXT2_read_in_folder]
552
        mov     ecx, [EXT2_files_in_folder]
553
        mov     dword [edx], 1    ;version
554
        xor     eax, eax
555
        mov     [edx+4], ebx
556
        mov     [edx+8], ecx
557
        lea     edi, [edx + 12]
558
        mov     ecx, 20 / 4
559
        rep     stosd
560
        ret
561
;====================== end ext2_HdReadFolder
562
 
563
;----------------------------------------------------------------
564
;
565
;  ext2_HdRead - read hard disk
566
;
567
;  esi  points to filename
568
;  ebx  pointer to 64-bit number = first wanted byte, 0+
569
;       may be ebx=0 - start from first byte
570
;  ecx  number of bytes to read, 0+
571
;  edx  mem location to return data
572
;
573
;  ret ebx = bytes read or 0xffffffff file not found
574
;      eax = 0 ok read or other = errormsg
575
;
576
;--------------------------------------------------------------
577
ext2_HdRead:
578
        mov     ebp, [ext2_data.root_inode]
579
 
1384 turbanoff 580
        push    ecx edx ebx
1378 turbanoff 581
    .next_folder:
582
        push    esi
583
    @@:
584
            lodsb
585
            test    al, al
586
            jz      .find_end
587
            cmp     al, '/'
588
            jz      .find_folder
589
            jmp     @B
590
 
591
    .find_end:
592
        ;установим флаг что ищем файл или очередную папку
593
        mov     edi, 1
594
        jmp     .find_any
595
    .find_folder:
596
        xor     edi, edi
597
    .find_any:
598
        pop     esi
599
 
600
        cmp     byte [esi], 0
601
        jz      .not_found
602
 
603
        or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
604
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
605
        add     eax, [ext2_data.count_block_in_block]
606
        mov     [EXT2_end_block], eax
607
    .next_block_folder:
608
        mov     eax, [ext2_data.count_block_in_block]
609
        sub     [EXT2_end_block], eax
610
        jz      .not_found
611
        inc     [EXT2_counter_blocks]
612
        mov     ecx, [EXT2_counter_blocks]
613
        call    ext2_get_inode_block
614
 
615
        mov     eax, ecx
616
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
617
        call    ext2_get_block
618
 
619
        mov     eax, esi
620
        call    ext2_test_block_by_name
621
        cmp     eax, esi                                ;нашли имя?
622
        je      .next_block_folder
623
 
624
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_REG_FILE
625
        je      .test_file
626
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
1384 turbanoff 627
        jne     .this_is_nofile
628
 
629
    ;.test_dir:
1378 turbanoff 630
        cmp     edi, 0
1384 turbanoff 631
        jne     .this_is_nofile
1378 turbanoff 632
 
633
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
634
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
635
        call    ext2_get_inode
636
        mov     ebp, ebx
637
        jmp     .next_folder
638
 
639
    .test_file:
640
        cmp     edi, 0
641
        je      .not_found
642
 
643
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
644
        mov     ebx, [ext2_data.ext2_save_inode]
645
        call    ext2_get_inode
646
        jmp     .get_file
647
 
648
    .not_found:
649
    	pop     edx ecx ebx
650
        or      ebx, -1
651
        mov     eax, ERROR_FILE_NOT_FOUND
652
        ret
1384 turbanoff 653
    .this_is_nofile:
1378 turbanoff 654
        pop     edx ecx ebx
655
        or      ebx, -1
656
        mov     eax, ERROR_ACCESS_DENIED
657
    .end_read:
658
        ret
659
 
660
    ;-----------------------------------------------------------------------------final step
661
    .get_file:
662
        mov     ebp ,ebx
663
 
664
        ;pop     eax edi ecx         ; первый_блок память кол-во_байт
665
        mov     esi, [esp]
666
        mov     edi, [esp + 8]      ;edi = нужно считать байт
667
 
668
        ;///// сравним хватит ли нам файла или нет
669
        mov     ebx, [esi+4]
670
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
671
 
672
        mov     edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
673
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]        ;edx : ecx - размер файла
674
 
675
        cmp     edx, ebx
676
        ja      .size_great
677
        jb      .size_less
678
 
679
        cmp     ecx, eax
680
        ja      .size_great
681
 
682
    .size_less:
683
        add     esp, 12
684
        mov     ebx, 0
685
        mov     eax, 6      ;EOF
686
        ret
687
    .size_great:
688
        ;прибавим к старту кол-во байт для чтения
689
        add     eax, edi
690
        jnc     @F
691
        inc     ebx
692
    @@:
693
        cmp     edx, ebx
694
        ja      .size_great_great
695
        jb      .size_great_less
696
        cmp     ecx, eax
697
        jae     .size_great_great
698
        ;jmp      .size_great_less
699
                                                ; а если равно, то не важно куда
700
    .size_great_less:
701
        or      [EXT2_files_in_folder], 1       ;читаем по границе размера
702
        sub     ecx, [esi]
703
        pop     eax edi edx                     ;ecx - не меняем
704
        jmp     @F
705
 
706
    .size_great_great:
707
        and     [EXT2_files_in_folder], 0       ;читаем нормально
708
        pop     eax edi ecx
709
 
710
    @@:
711
        push    ecx                             ;сохраним размер считанных байт в стеке
712
        test    eax, eax
713
        je      .zero_start
714
 
715
        ;пока делаем п..ц криво =)
716
        mov     edx, [eax+4]
717
        mov     eax, [eax]
718
        div     [ext2_data.block_size]
719
 
720
        mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
721
 
722
        push    ecx
723
        mov     ecx, eax
724
        call    ext2_get_inode_block
725
        mov     ebx , [ext2_data.ext2_save_block]
726
        mov     eax, ecx
727
        call    ext2_get_block
728
        pop     ecx
729
        add     ebx, edx
730
 
731
        neg     edx
732
        add     edx,[ext2_data.block_size]      ;block_size - стартоый блок = сколько байт 1-го блока
733
        cmp     ecx, edx
734
        jbe     .only_one_block
735
 
736
        mov     eax, ecx
737
        sub     eax, edx
738
        mov     ecx, edx
739
 
740
        mov     esi, ebx
741
        rep     movsb                           ;кусок 1-го блока
742
 
743
    .zero_start:
744
        mov     ebx, edi                        ;чтение блока прям в ebx
745
        ;теперь в eax кол-во оставшихся байт для чтения
746
        xor     edx, edx
747
        div     [ext2_data.block_size]
748
        mov     [EXT2_end_block], eax          ;кол-во целых блоков
749
    @@:
750
        cmp     [EXT2_end_block], 0
751
        jz      .finish_block
752
        inc     [EXT2_counter_blocks]
753
        mov     ecx, [EXT2_counter_blocks]
754
        call    ext2_get_inode_block
755
 
756
        mov     eax, ecx            ;а ebx уже забит нужным значением
757
        call    ext2_get_block
758
        add     ebx, [ext2_data.block_size]
759
 
760
        dec     [EXT2_end_block]
761
        jmp     @B
762
 
763
    .finish_block:          ;в edx - кол-во байт в последнем блоке
764
        cmp     edx, 0
765
        je      .end_read
766
 
767
        mov     ecx, [EXT2_counter_blocks]
768
        inc     ecx
769
        call    ext2_get_inode_block
770
 
771
        mov     edi, ebx
772
        mov     eax, ecx
773
        mov     ebx, [ext2_data.ext2_save_block]
774
        call    ext2_get_block
775
 
776
        mov     ecx, edx
777
 
778
    .only_one_block:
779
        mov     esi, ebx
780
        rep     movsb                           ;кусок 1-го блока (последнего)
781
        pop     ebx
782
        cmp     [EXT2_files_in_folder], 0
783
        jz      @F
784
 
785
        mov     eax, 6      ;EOF
786
        ret
787
    @@:
788
        xor     eax, eax
789
        ret
790
;========================
1384 turbanoff 791
;in : esi -> name           not save register
792
;out: ebp -> inode cf=0
793
;     ebp -> trash cf=1
794
ext2_find_lfn:
795
        mov     ebp, [ext2_data.root_inode]
796
    .next_folder:
797
        or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
798
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
799
        add     eax, [ext2_data.count_block_in_block]
800
        mov     [EXT2_end_block], eax
801
    .next_block_folder:
802
        mov     eax, [ext2_data.count_block_in_block]
803
        sub     [EXT2_end_block], eax
804
        jz      .not_found
805
        inc     [EXT2_counter_blocks]
806
        mov     ecx, [EXT2_counter_blocks]
807
        call    ext2_get_inode_block
1378 turbanoff 808
 
1384 turbanoff 809
        mov     eax, ecx
810
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
811
        call    ext2_get_block
812
 
813
        mov     eax, esi
814
        call    ext2_test_block_by_name
815
        cmp     eax, esi                                ;нашли имя?
816
        jz      .next_block_folder
817
 
818
        cmp     byte [esi],0
819
        jz      .get_inode_ret
820
 
821
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
822
        jne     .not_found                                      ;нашли, но это не папка
823
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
824
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
825
        call    ext2_get_inode
826
        mov     ebp, ebx
827
        jmp     .next_folder
828
 
829
    .not_found:
830
        stc
831
        ret
832
    .get_inode_ret:
833
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
834
        mov     ebx, [ext2_data.ext2_save_inode]
835
        call    ext2_get_inode
836
        mov     ebp, ebx
837
    .ret:
838
        clc
839
        ret
840
 
841
 
842
;========================
1378 turbanoff 843
ext2_HdRewrite:
844
;    xchg    bx, bx
845
        xor     ebx, ebx
846
        mov     eax, ERROR_UNSUPPORTED_FS
847
        ret
848
 
849
ext2_HdWrite:
850
;    xchg    bx, bx
851
        xor     ebx, ebx
852
        mov     eax, ERROR_UNSUPPORTED_FS
853
        ret
854
ext2_HdSetFileEnd:
855
;    xchg    bx, bx
856
        xor     ebx, ebx
857
        mov     eax, ERROR_UNSUPPORTED_FS
858
        ret
1384 turbanoff 859
 
1378 turbanoff 860
ext2_HdGetFileInfo:
1384 turbanoff 861
        cmp     byte [esi], 0
862
        jz      .doit
863
 
864
        call    ext2_find_lfn
865
        jnc     .doit2
866
    ;.not_found:
867
        mov     eax, ERROR_FILE_NOT_FOUND
1378 turbanoff 868
        ret
1384 turbanoff 869
 
870
    .doit:
871
        mov     ebp, [ext2_data.root_inode]
872
    .doit2:
873
        xor     eax, eax
874
        mov     edi, edx
875
        mov     ecx, 40/4
876
        rep stosd               ; fill zero
877
 
878
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
879
        jz      @F
880
        or      dword [edx], FS_FT_DIR
881
    @@:
882
        mov     byte [edx+1], FS_FT_ASCII
883
        mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
884
        mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
885
        mov     dword [edx+32], eax
886
        mov     dword [edx+36], ebx
887
 
888
        xor     eax, eax
889
        ret
890
 
1378 turbanoff 891
ext2_HdSetFileInfo:
892
;    xchg    bx, bx
893
        xor     ebx, ebx
894
        mov     eax, ERROR_UNSUPPORTED_FS
895
        ret
896
ext2_HdDelete:
897
;    xchg    bx, bx
898
        xor     ebx, ebx
899
        mov     eax, ERROR_UNSUPPORTED_FS
900
        ret
901