Subversion Repositories Kolibri OS

Rev

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