Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2434 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
2434 Serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;   02.02.2010  turbanoff  - support 70.5                      ;;
6
;;   23.01.2010  turbanoff  - support 70.0 70.1                 ;;
7
;;                                                              ;;
8
;;                                                              ;;
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
 
11
$Revision: 3500 $
12
 
3500 Serge 13
EXT2_BAD_INO         = 1
2434 Serge 14
EXT2_ROOT_INO        = 2
3500 Serge 15
EXT2_ACL_IDX_INO     = 3
2434 Serge 16
EXT2_ACL_DATA_INO    = 4
2987 Serge 17
EXT2_BOOT_LOADER_INO = 5
3500 Serge 18
EXT2_UNDEL_DIR_INO   = 6
2434 Serge 19
 
2987 Serge 20
;флаги, указываемый в inode файла
3500 Serge 21
EXT2_S_IFREG         = 0x8000
22
EXT2_S_IFDIR         = 0x4000
2987 Serge 23
EXT2_S_IFMT          = 0xF000 ;маска для типа файла
2434 Serge 24
 
2987 Serge 25
;флаги, указываемые в linked list родительской папки
3500 Serge 26
EXT2_FT_REG_FILE     = 1     ;это файл, запись в родительском каталоге
27
EXT2_FT_DIR          = 2     ;это папка
2434 Serge 28
 
2987 Serge 29
;флаги используемые KolibriOS
3500 Serge 30
FS_FT_HIDDEN         = 2
31
FS_FT_DIR            = 0x10  ;это папка
32
FS_FT_ASCII          = 0     ;имя в ascii
33
FS_FT_UNICODE        = 1     ;имя в unicode
2434 Serge 34
 
2987 Serge 35
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;тип файла должен указываться в директории
36
EXT4_FEATURE_INCOMPAT_EXTENTS  = 0x0040 ;экстенты
37
EXT4_FEATURE_INCOMPAT_FLEX_BG  = 0x0200 ;гибкие группы блоков
38
;реализованные ext[234] features
39
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
40
                          or EXT4_FEATURE_INCOMPAT_EXTENTS \
41
                          or EXT4_FEATURE_INCOMPAT_FLEX_BG
2434 Serge 42
 
43
 
2987 Serge 44
;флаги, указываемые для inode в i_flags
45
EXT2_EXTENTS_FL      = 0x00080000
46
 
2434 Serge 47
struct  EXT2_INODE_STRUC
48
        i_mode          dw ?
49
        i_uid           dw ?
50
        i_size          dd ?
51
        i_atime         dd ?
52
        i_ctime         dd ?
53
        i_mtime         dd ?
54
        i_dtime         dd ?
55
        i_gid           dw ?
56
        i_links_count   dw ?
57
        i_blocks        dd ?
58
        i_flags         dd ?
59
        i_osd1          dd ?
60
        i_block         rd 15
61
        i_generation    dd ?
62
        i_file_acl      dd ?
63
        i_dir_acl       dd ?
64
        i_faddr         dd ?
65
        i_osd2          dd ? ; 1..12
66
ends
67
 
68
struct  EXT2_DIR_STRUC
69
        inode           dd ?
70
        rec_len         dw ?
71
        name_len        db ?
72
        file_type       db ?
73
        name            db ? ; 0..255
74
ends
75
 
76
struct  EXT2_BLOCK_GROUP_DESC
2987 Serge 77
        block_bitmap            dd ? ;+0
78
        inode_bitmap            dd ? ;+4
79
        inode_table             dd ? ;+8
80
        free_blocks_count       dw ? ;+12
81
        free_inodes_count       dw ? ;+14
82
        used_dirs_count         dw ? ;+16
83
        pad                     dw ? ;+18
84
        reserved                rb 12;+20
2434 Serge 85
ends
86
 
87
struct  EXT2_SB_STRUC
88
        inodes_count            dd ? ;+0
89
        blocks_count            dd ? ;+4
90
        r_block_count           dd ? ;+8
91
        free_block_count        dd ? ;+12
92
        free_inodes_count       dd ? ;+16
93
        first_data_block        dd ? ;+20
94
        log_block_size          dd ? ;+24
95
        log_frag_size           dd ? ;+28
96
        blocks_per_group        dd ? ;+32
97
        frags_per_group         dd ? ;+36
98
        inodes_per_group        dd ? ;+40
99
        mtime                   dd ? ;+44
100
        wtime                   dd ? ;+48
101
        mnt_count               dw ? ;+52
102
        max_mnt_count           dw ? ;+54
103
        magic                   dw ? ;+56
104
        state                   dw ? ;+58
105
        errors                  dw ? ;+60
106
        minor_rev_level         dw ? ;+62
107
        lastcheck               dd ? ;+64
108
        check_intervals         dd ? ;+68
109
        creator_os              dd ? ;+72
110
        rev_level               dd ? ;+76
111
        def_resuid              dw ? ;+80
112
        def_resgid              dw ? ;+82
113
        first_ino               dd ? ;+84
114
        inode_size              dw ? ;+88
115
        block_group_nr          dw ? ;+90
116
        feature_compat          dd ? ;+92
117
        feature_incompat        dd ? ;+96
118
        feature_ro_compat       dd ? ;+100
119
        uuid                    rb 16 ;+104
120
        volume_name             rb 16 ;+120
121
        last_mounted            rb 64 ;+136
122
        algo_bitmap             dd ? ;+200
123
        prealloc_blocks         db ? ;+204
124
        preallock_dir_blocks    db ? ;+205
2987 Serge 125
        reserved_gdt_blocks     dw ? ;+206
2434 Serge 126
        journal_uuid            rb 16 ;+208
127
        journal_inum            dd ? ;+224
128
        journal_dev             dd ? ;+228
129
        last_orphan             dd ? ;+232
130
        hash_seed               rd 4 ;+236
131
        def_hash_version        db ? ;+252
132
                                rb 3 ;+253 reserved
133
        default_mount_options   dd ? ;+256
134
        first_meta_bg           dd ? ;+260
2987 Serge 135
        mkfs_time               dd ? ;+264
136
        jnl_blocks              rd 17 ;+268
137
        blocks_count_hi         dd ? ;+336
138
        r_blocks_count_hi       dd ? ;+340
139
        free_blocks_count_hi    dd ? ;+344
140
        min_extra_isize         dw ? ;+348
141
        want_extra_isize        dw ? ;+350
142
        flags                   dd ? ;+352
143
        raid_stride             dw ? ;+356
144
        mmp_interval            dw ? ;+358
145
        mmp_block               dq ? ;+360
146
        raid_stripe_width       dd ? ;+368
147
        log_groups_per_flex     db ? ;+372
2434 Serge 148
ends
149
 
2987 Serge 150
struct EXT4_EXTENT_HEADER       ;заголовок блока экстентов/индексов
151
        eh_magic        dw ?    ;в текущей реализации ext4 должно быть 0xF30A
152
        eh_entries      dw ?    ;количество экстентов/индексов в блоке
153
        eh_max          dw ?    ;max количество (используется при записи)
154
        eh_depth        dw ?    ;глубина дерева (0, если это блок экстентов)
155
        eh_generation   dd ?    ;???
156
ends
157
 
158
struct EXT4_EXTENT              ;экстент
159
        ee_block        dd ?    ;номер ext4 блока
160
        ee_len          dw ?    ;длина экстента
161
        ee_start_hi     dw ?    ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
162
        ee_start_lo     dd ?    ;младшие 32 бита 48-битного адреса
163
ends
164
 
165
struct EXT4_EXTENT_IDX          ;индес - указатель на блок с экстентами/индексами
166
        ei_block        dd ?    ;номер ext4 блока
167
        ei_leaf_lo      dd ?    ;младшие 32 бит 48-битного адреса
168
        ei_leaf_hi      dw ?    ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
169
        ei_unused       dw ?    ;зарезервировано
170
ends
171
 
2434 Serge 172
ext2_test_superblock:
173
        cmp     [fs_type], 0x83
174
        jne     .no
175
 
176
        mov     eax, [PARTITION_START]
177
        add     eax, 2                  ;superblock start at 1024b
178
        call    hd_read
179
 
2987 Serge 180
        cmp     [ebx + EXT2_SB_STRUC.log_block_size], 3  ;0,1,2,3
2434 Serge 181
        ja      .no
2987 Serge 182
        cmp     [ebx + EXT2_SB_STRUC.magic], 0xEF53
2434 Serge 183
        jne     .no
2987 Serge 184
        cmp     [ebx + EXT2_SB_STRUC.state], 1        ;EXT_VALID_FS=1
2434 Serge 185
        jne     .no
2987 Serge 186
        cmp     [ebx + EXT2_SB_STRUC.inodes_per_group], 0
187
        je      .no
188
 
189
        mov     eax, [ebx + EXT2_SB_STRUC.feature_incompat]
2434 Serge 190
        test    eax, EXT2_FEATURE_INCOMPAT_FILETYPE
191
        jz      .no
2987 Serge 192
        test    eax, not EXT4_FEATURE_INCOMPAT_SUPP
2434 Serge 193
        jnz     .no
194
 
195
    ; OK, this is correct EXT2 superblock
196
        clc
197
        ret
198
   .no:
199
    ; No, this superblock isn't EXT2
200
        stc
201
        ret
202
 
203
ext2_setup:
204
        mov     [fs_type], 2
205
 
206
        push    512
207
        call    kernel_alloc                            ; mem for superblock
208
        mov     esi, ebx
209
        mov     edi, eax
210
        mov     ecx, 512/4
211
        rep movsd                                       ; copy sb to reserved mem
212
        mov     ebx, eax
213
        mov     [ext2_data.sb], eax
214
 
215
        mov     eax, [ebx + EXT2_SB_STRUC.blocks_count]
216
        sub     eax, [ebx + EXT2_SB_STRUC.first_data_block]
217
        dec     eax
218
        xor     edx, edx
219
        div     [ebx + EXT2_SB_STRUC.blocks_per_group]
220
        inc     eax
221
        mov     [ext2_data.groups_count], eax
222
 
2987 Serge 223
        mov     ecx, [ebx + EXT2_SB_STRUC.log_block_size]
2434 Serge 224
        inc     ecx
225
        mov     [ext2_data.log_block_size], ecx    ; 1, 2, 3, 4   equ 1kb, 2kb, 4kb, 8kb
226
 
227
        mov     eax, 1
228
        shl     eax, cl
229
        mov     [ext2_data.count_block_in_block], eax
230
 
231
        shl     eax, 7
232
        mov     [ext2_data.count_pointer_in_block], eax
233
        mov     edx, eax                                ; потом еще квадрат найдем
234
 
235
        shl     eax, 2
236
        mov     [ext2_data.block_size], eax
237
 
238
        push    eax eax                                 ; 2 kernel_alloc
239
 
240
        mov     eax, edx
241
        mul     edx
242
        mov     [ext2_data.count_pointer_in_block_square], eax
243
 
244
        call    kernel_alloc
245
        mov     [ext2_data.ext2_save_block], eax        ; and for temp block
246
        call    kernel_alloc
247
        mov     [ext2_data.ext2_temp_block], eax        ; and for get_inode proc
248
 
2987 Serge 249
        movzx   ebp, word [ebx + EXT2_SB_STRUC.inode_size]
250
        mov     ecx, [ebx + EXT2_SB_STRUC.blocks_per_group]
2434 Serge 251
 
252
        mov     [ext2_data.inode_size], ebp
253
        mov     [ext2_data.blocks_per_group], ecx
254
 
255
        push    ebp ebp ebp                             ;3 kernel_alloc
256
        call    kernel_alloc
257
        mov     [ext2_data.ext2_save_inode], eax
258
        call    kernel_alloc
259
        mov     [ext2_data.ext2_temp_inode], eax
260
        call    kernel_alloc
261
        mov     [ext2_data.root_inode], eax
262
 
263
        mov     ebx, eax
264
        mov     eax, EXT2_ROOT_INO
265
        call    ext2_get_inode                          ; read root inode
266
 
267
        jmp     return_from_part_set
268
 
269
;==================================================================
2987 Serge 270
;read ext2 block form FS to memory
271
;in:  eax = i_block (address of block in ext2 terms)
3500 Serge 272
;     ebx = pointer to return memory
2987 Serge 273
;out: eax - error code (0 = no_error)
2434 Serge 274
ext2_get_block:
2987 Serge 275
        push    ebx ecx
2434 Serge 276
        mov     ecx, [ext2_data.log_block_size]
277
        shl     eax, cl
278
        add     eax, [PARTITION_START]
279
        mov     ecx, [ext2_data.count_block_in_block]
280
    @@:
281
        call    hd_read
2987 Serge 282
        cmp     [hd_error], 0
283
        jnz     .fail
2434 Serge 284
        inc     eax
285
        add     ebx, 512
286
        loop    @B
2987 Serge 287
        xor     eax, eax
288
    @@:
289
        pop     ecx ebx
2434 Serge 290
        ret
2987 Serge 291
    .fail:
292
        mov     eax, ERROR_DEVICE
293
        jmp     @B
294
 
295
 
2434 Serge 296
;===================================================================
2987 Serge 297
;получает номер блока из extent inode
298
;in:  ecx = номер блока по порядку
299
;     ebp = адрес extent header`а
300
;out: ecx - адрес очередного блока в случае успеха
301
;     eax - номер ошибки (если равно 0, то ошибки нет)
302
ext4_block_recursive_search:
303
        cmp     word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
304
        jne     .fail
305
 
306
        movzx   ebx, [ebp + EXT4_EXTENT_HEADER.eh_entries]
307
        add     ebp, sizeof.EXT4_EXTENT_HEADER
308
        cmp     word [ebp - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0
309
        je      .leaf_block     ;листовой ли это блок?
310
 
311
        ;не листовой блок, а индексный ; eax - ext4_extent_idx
312
        test    ebx, ebx
313
        jz      .fail               ;пустой индексный блок -> ошибка
314
 
315
        ;цикл по индексам экстентов
316
    @@:
317
        cmp     ebx, 1              ;у индексов не хранится длина,
318
        je      .end_search_index   ;поэтому, если остался последний - то это нужный
319
 
320
        cmp     ecx, [ebp + EXT4_EXTENT_IDX.ei_block]
321
        jb      .fail
322
 
323
        cmp     ecx, [ebp + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса
324
        jb      .end_search_index ;следующий дальше - значит текущий, то что нам нужен
325
 
326
        add     ebp, sizeof.EXT4_EXTENT_IDX
327
        dec     ebx
328
        jmp     @B
329
 
330
    .end_search_index:
331
        ;ebp указывает на нужный extent_idx, считываем следующий блок
332
        mov     ebx, [ext2_data.ext2_temp_block]
333
        mov     eax, [ebp + EXT4_EXTENT_IDX.ei_leaf_lo]
334
        call    ext2_get_block
335
        test    eax, eax
336
        jnz     .fail
337
        mov     ebp, ebx
338
        jmp     ext4_block_recursive_search ;рекурсивно прыгаем в начало
339
 
340
    .leaf_block:    ;листовой блок ebp - ext4_extent
341
        ;цикл по экстентам
342
    @@:
343
        test    ebx, ebx
344
        jz      .fail       ;ни один узел не подошел - ошибка
345
 
346
        mov     edx, [ebp + EXT4_EXTENT.ee_block]
347
        cmp     ecx, edx
348
        jb      .fail       ;если меньше, значит он был в предыдущих блоках -> ошибка
349
 
350
        movzx   edi, [ebp + EXT4_EXTENT.ee_len]
351
        add     edx, edi
352
        cmp     ecx, edx
353
        jb      .end_search_extent     ;нашли нужный блок
354
 
355
        add     ebp, sizeof.EXT4_EXTENT
356
        dec     ebx
357
        jmp     @B
358
 
359
    .end_search_extent:
360
        mov     edx, [ebp + EXT4_EXTENT.ee_start_lo]
361
        sub     ecx, [ebp + EXT4_EXTENT.ee_block] ;разница в ext4 блоках
362
        add     ecx, edx
363
        xor     eax, eax
364
        ret
365
 
366
    .fail:
367
        mov     eax, ERROR_FS_FAIL
368
        ret
369
 
370
;===================================================================
371
;получает адрес ext2 блока из inode с определнным номером
372
;in:  ecx = номер блока в inode (0..)
3500 Serge 373
;     ebp = адрес inode
2987 Serge 374
;out: ecx = адрес очередного блока
375
;     eax - error code
2434 Serge 376
ext2_get_inode_block:
2987 Serge 377
        test    [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
378
        jz      @F
379
 
380
        pushad
381
        add     ebp, EXT2_INODE_STRUC.i_block             ;ebp - extent_header
382
        call    ext4_block_recursive_search
383
        mov     PUSHAD_ECX, ecx
384
        mov     PUSHAD_EAX, eax
385
        popad
386
        ret
387
 
388
    @@:
2434 Serge 389
        cmp     ecx, 12                                         ; 0..11 - direct block address
390
        jb      .get_direct_block
391
 
392
        sub     ecx, 12
2987 Serge 393
        cmp     ecx, [ext2_data.count_pointer_in_block]         ; 12.. - indirect blocks
2434 Serge 394
        jb      .get_indirect_block
395
 
396
        sub     ecx, [ext2_data.count_pointer_in_block]
397
        cmp     ecx, [ext2_data.count_pointer_in_block_square]
398
        jb      .get_double_indirect_block
399
 
400
        sub     ecx, [ext2_data.count_pointer_in_block_square]
2987 Serge 401
    ;triple indirect block
402
        push    edx ebx
2434 Serge 403
 
404
        mov     eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
405
        mov     ebx, [ext2_data.ext2_temp_block]
406
        call    ext2_get_block
2987 Serge 407
        test    eax, eax
408
        jnz     .fail
2434 Serge 409
 
410
        xor     edx, edx
411
        mov     eax, ecx
412
        div     [ext2_data.count_pointer_in_block_square]
413
 
414
    ;eax - номер в полученном блоке   edx - номер дальше
415
        mov     eax, [ebx + eax*4]
416
        call    ext2_get_block
2987 Serge 417
        test    eax, eax
418
        jnz     .fail
2434 Serge 419
 
420
        mov     eax, edx
421
        jmp     @F
422
 
423
    .get_double_indirect_block:
2987 Serge 424
        push    edx ebx
2434 Serge 425
 
426
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
427
        mov     ebx, [ext2_data.ext2_temp_block]
428
        call    ext2_get_block
2987 Serge 429
        test    eax, eax
430
        jnz     .fail
2434 Serge 431
 
432
        mov     eax, ecx
3500 Serge 433
    @@:
2434 Serge 434
        xor     edx, edx
435
        div     [ext2_data.count_pointer_in_block]
436
 
437
        mov     eax, [ebx + eax*4]
438
        call    ext2_get_block
2987 Serge 439
        test    eax, eax
440
        jnz     .fail
441
 
2434 Serge 442
        mov     ecx, [ebx + edx*4]
2987 Serge 443
    .fail:
444
        pop     ebx edx
2434 Serge 445
        ret
446
 
447
    .get_indirect_block:
2987 Serge 448
        push    ebx
2434 Serge 449
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
450
        mov     ebx, [ext2_data.ext2_temp_block]
451
        call    ext2_get_block
2987 Serge 452
        test    eax, eax
3500 Serge 453
        jnz     @F                      ;если не было ошибки
2434 Serge 454
 
2987 Serge 455
        mov     ecx, [ebx + ecx*4]    ;заносим результат
456
    @@:
457
        pop     ebx
2434 Serge 458
        ret
459
 
460
    .get_direct_block:
2987 Serge 461
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
462
        xor     eax, eax
2434 Serge 463
        ret
464
 
465
;===================================================================
466
;get content inode by num
3500 Serge 467
;in:  eax = inode_num
468
;     ebx = address of inode content
2987 Serge 469
;out: eax - error code
2434 Serge 470
ext2_get_inode:
471
        pushad
472
        mov     edi, ebx   ;сохраним адрес inode
473
        dec     eax
474
        xor     edx, edx
2987 Serge 475
 
476
        mov     ecx, [ext2_data.sb]
477
        div     [ecx + EXT2_SB_STRUC.inodes_per_group]
2434 Serge 478
 
479
        push    edx                             ;locale num in group
480
 
481
        mov     edx, 32
482
        mul     edx                             ; address block_group in global_desc_table
483
 
484
        ; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
485
        ; найдем блок в котором он находится
486
        div     [ext2_data.block_size]
487
        add     eax, [ecx + EXT2_SB_STRUC.first_data_block]
488
        inc     eax
489
        mov     ebx, [ext2_data.ext2_temp_block]
490
        call    ext2_get_block
2987 Serge 491
        test    eax, eax
492
        jnz     .fail
2434 Serge 493
 
494
        add     ebx, edx                        ; локальный номер в блоке
2987 Serge 495
        mov     eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]; номер блока - в терминах ext2
2434 Serge 496
 
497
        mov     ecx, [ext2_data.log_block_size]
498
        shl     eax, cl
3500 Serge 499
        add     eax, [PARTITION_START]        ; а старт раздела - в терминах hdd (512)
2434 Serge 500
 
501
        ;eax - указывает на таблицу inode-ов на hdd
502
        mov     esi, eax                        ;сохраним его пока в esi
503
 
504
        ; прибавим локальный адрес inode-а
505
        pop     eax                             ; index
506
        mov     ecx, [ext2_data.inode_size]
507
        mul     ecx                             ; (index * inode_size)
508
        mov     ebp, 512
509
        div     ebp                             ;поделим на размер блока
510
 
511
        add     eax, esi                        ;нашли адрес блока для чтения
512
        mov     ebx, [ext2_data.ext2_temp_block]
513
        call    hd_read
2987 Serge 514
        cmp     [hd_error], 0
515
        jnz     .fail
2434 Serge 516
 
517
        mov     esi, edx                        ;добавим "остаток"
518
        add     esi, ebx                        ;к адресу
519
        rep movsb                               ;копируем inode
2987 Serge 520
        xor     eax, eax
521
    .fail:
522
        mov     PUSHAD_EAX, eax
2434 Serge 523
        popad
524
        ret
525
 
526
;----------------------------------------------------------------
527
;
528
;  ext2_HdReadFolder - read disk folder
529
;
530
;  esi  points to filename
531
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
532
;                          & flags (bitfields)
533
; flags: bit 0: 0=ANSI names, 1=UNICODE names
534
;  ecx  number of blocks to read, 0+
535
;  edx  mem location to return data
536
;
537
;  ret ebx = blocks read or 0xffffffff folder not found
538
;      eax = 0 ok read or other = errormsg
539
;
540
;--------------------------------------------------------------
541
ext2_HdReadFolder:
542
        cmp     byte [esi], 0
2987 Serge 543
        jz      .root_folder
2434 Serge 544
 
2987 Serge 545
        push    ebx ecx edx
546
        call    ext2_find_lfn               ;вернет в ebp адрес inode
547
        pop     edx ecx ebx
548
        test    eax, eax
549
        jnz     .error_ret
550
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
551
        jz      .error_not_found
552
        jmp     @F
2434 Serge 553
 
2987 Serge 554
    .root_folder:
2434 Serge 555
        mov     ebp, [ext2_data.root_inode]
2987 Serge 556
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
557
        jz      .error_root
558
        ;придется копировать inode
2434 Serge 559
        push    ecx
2987 Serge 560
        mov     esi, ebp
561
        mov     edi, [ext2_data.ext2_save_inode]
562
        mov     ecx, [ext2_data.inode_size]
563
        shr     ecx, 2
564
        mov     ebp, edi
565
        rep movsd
566
        pop     ecx
2434 Serge 567
    @@:
3500 Serge 568
        cmp     [ebp + EXT2_INODE_STRUC.i_size], 0 ;папка пуста
2987 Serge 569
        je      .error_empty_dir
570
 
571
        push    edx      ;адрес результата              [edi + 28]
572
        push    0        ;конец очередного блока папки   [edi + 24]
573
        push    ecx      ;сколько файлов нужно прочитать [edi + 20]
574
        push    dword [ebx]   ;первый "нужный" файл           [edi + 16]
575
        push    dword [ebx + 4];флаги                        [edi + 12]
576
        push    0       ;[EXT2_read_in_folder]     [edi + 8]
577
        push    0       ;[EXT2_files_in_folder]    [edi + 4]
578
        push    0       ;номер блока по порядку    [edi]
579
 
2434 Serge 580
        mov     edi, edx
581
        mov     ecx, 32/4
582
        rep stosd                               ; fill header zero
3500 Serge 583
 
2987 Serge 584
        mov     edi, esp                        ; edi - указатель на локальные переменные
585
        add     edx, 32                         ; edx = current mem for return
2434 Serge 586
 
2987 Serge 587
        xor     ecx, ecx                        ; получим номер первого блока
2434 Serge 588
        call    ext2_get_inode_block
2987 Serge 589
        test    eax, eax
590
        jnz     .error_get_block
2434 Serge 591
 
592
        mov     eax, ecx
593
        mov     ebx, [ext2_data.ext2_save_block]
594
        call    ext2_get_block                  ; и считываем блок с hdd
2987 Serge 595
        test    eax, eax
596
        jnz     .error_get_block
2434 Serge 597
 
2987 Serge 598
        mov     esi, ebx                         ; esi = current dir record
2434 Serge 599
        add     ebx, [ext2_data.block_size]
2987 Serge 600
        mov     [edi + 24], ebx               ; запомним конец очередного блока
2434 Serge 601
 
2987 Serge 602
        mov     ecx, [edi + 16]                        ; ecx = first wanted (flags ommited)
2434 Serge 603
 
604
    .find_wanted_start:
605
        jecxz   .find_wanted_end
606
    .find_wanted_cycle:
2987 Serge 607
        cmp     [esi + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
2434 Serge 608
        jz      @F
2987 Serge 609
        inc     dword [edi + 4]                        ; EXT2_files_in_folder
2434 Serge 610
        dec     ecx
3500 Serge 611
    @@:
2987 Serge 612
        movzx   ebx, [esi + EXT2_DIR_STRUC.rec_len]
2434 Serge 613
 
614
        cmp     ebx, 12                                 ; минимальная длина записи
2987 Serge 615
        jb      .error_bad_len
2434 Serge 616
        test    ebx, 0x3                                ; длина записи должна делиться на 4
2987 Serge 617
        jnz     .error_bad_len
2434 Serge 618
 
3500 Serge 619
        sub     [ebp + EXT2_INODE_STRUC.i_size], ebx    ;вычитаем напрямую из структуры inode
2987 Serge 620
        add     esi, ebx                                ; к следующей записи
621
        cmp     esi, [edi + 24]                        ; сравниваем с концом блока
2434 Serge 622
        jb      .find_wanted_start
623
 
624
        push    .find_wanted_start
2987 Serge 625
   .end_block:                                              ;вылетели из цикла
3500 Serge 626
        cmp     [ebp + EXT2_INODE_STRUC.i_size], 0
2987 Serge 627
        jle     .end_dir
2434 Serge 628
 
2987 Serge 629
        inc     dword [edi]                                 ;получаем новый блок
2434 Serge 630
        push    ecx
2987 Serge 631
        mov     ecx, [edi]
2434 Serge 632
        call    ext2_get_inode_block
2987 Serge 633
        test    eax, eax
634
        jnz     .error_get_block
635
 
2434 Serge 636
        mov     eax, ecx
637
        mov     ebx, [ext2_data.ext2_save_block]
638
        call    ext2_get_block
2987 Serge 639
        test    eax, eax
640
        jnz     .error_get_block
641
 
2434 Serge 642
        pop     ecx
2987 Serge 643
        mov     esi, ebx
2434 Serge 644
        add     ebx, [ext2_data.block_size]
2987 Serge 645
        mov     [edi + 24], ebx                            ;запомним конец блока
3500 Serge 646
        ret                                                 ; опять в цикл
2434 Serge 647
 
648
    .wanted_end:
2987 Serge 649
        loop    .find_wanted_cycle                          ; ecx 0 => -1 нужно посчитать сколько файлов
2434 Serge 650
 
2987 Serge 651
    ;дошли до первого "нужного" файла
2434 Serge 652
    .find_wanted_end:
2987 Serge 653
        mov     ecx, [edi + 20]
3500 Serge 654
    .wanted_start:                                          ; ищем first_wanted+count
2434 Serge 655
        jecxz   .wanted_end
2987 Serge 656
        cmp     [esi + EXT2_DIR_STRUC.inode], 0         ; if (inode = 0) => not used
2434 Serge 657
        jz      .empty_rec
2987 Serge 658
        inc     dword [edi + 8]
659
        inc     dword [edi + 4]
2434 Serge 660
 
2987 Serge 661
        push    edi ecx
662
        mov     edi, edx                            ;обнуляем место под очереное имя файла/папки
2434 Serge 663
        xor     eax, eax
664
        mov     ecx, 40 / 4
665
        rep stosd
2987 Serge 666
        pop     ecx edi
2434 Serge 667
 
2987 Serge 668
        push    esi edi edx
669
        mov     eax, [esi + EXT2_DIR_STRUC.inode]             ;получим дочерний inode
2434 Serge 670
        mov     ebx, [ext2_data.ext2_temp_inode]
671
        call    ext2_get_inode
2987 Serge 672
        test    eax, eax
673
        jnz     .error_read_subinode
2434 Serge 674
 
675
        lea     edi, [edx + 8]
676
 
3500 Serge 677
        mov     eax, [ebx + EXT2_INODE_STRUC.i_ctime]           ; переведем время в ntfs формат
2434 Serge 678
        xor     edx, edx
679
        add     eax, 3054539008                                     ;(369 * 365 + 89) * 24 * 3600
680
        adc     edx, 2
681
        call    ntfs_datetime_to_bdfe.sec
682
 
683
        mov     eax, [ebx + EXT2_INODE_STRUC.i_atime]
684
        xor     edx, edx
685
        add     eax, 3054539008
686
        adc     edx, 2
687
        call    ntfs_datetime_to_bdfe.sec
688
 
689
        mov     eax, [ebx + EXT2_INODE_STRUC.i_mtime]
690
        xor     edx, edx
691
        add     eax, 3054539008
692
        adc     edx, 2
693
        call    ntfs_datetime_to_bdfe.sec
694
 
695
        pop     edx                                                 ; пока достаем только буфер
3500 Serge 696
        test    [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR   ; для папки размер
2434 Serge 697
        jnz     @F                                                  ; не возвращаем
698
 
3500 Serge 699
        mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
2434 Serge 700
        stosd
3500 Serge 701
        mov     eax, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
2434 Serge 702
        stosd
2987 Serge 703
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл(2 раза xor)
3500 Serge 704
    @@:
2987 Serge 705
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл
2434 Serge 706
 
3500 Serge 707
        ;теперь скопируем имя, сконвертировав из UTF-8 в CP866
2987 Serge 708
        push    ecx  ;edi и esi уже сохранены в стеке
709
        movzx   ecx, [esi + EXT2_DIR_STRUC.name_len]
2434 Serge 710
        lea     edi, [edx + 40]
2987 Serge 711
        lea     esi, [esi + EXT2_DIR_STRUC.name]
712
        call    utf8_to_cp866
2434 Serge 713
        and     byte [edi], 0
2987 Serge 714
        pop     ecx edi esi
2434 Serge 715
 
2987 Serge 716
        cmp     byte [edx + 40], '.'                    ; в linux файл, начинающийся с точки - скрытый
2434 Serge 717
        jne     @F
718
        or      dword [edx], FS_FT_HIDDEN
3500 Serge 719
    @@:
2434 Serge 720
 
721
        add     edx, 40 + 264                           ; go to next record
722
        dec     ecx                                     ; если запись пустая ecx не надо уменьшать
3500 Serge 723
    .empty_rec:
2987 Serge 724
        movzx   ebx, [esi + EXT2_DIR_STRUC.rec_len]
2434 Serge 725
        cmp     ebx, 12                                 ; минимальная длина записи
2987 Serge 726
        jb      .error_bad_len
2434 Serge 727
        test    ebx, 0x3                                ; длина записи должна делиться на 4
2987 Serge 728
        jnz     .error_bad_len
2434 Serge 729
 
3500 Serge 730
        sub     [ebp + EXT2_INODE_STRUC.i_size], ebx    ;вычитаем напрямую из структуры inode
2987 Serge 731
        add     esi, ebx
732
        cmp     esi, [edi + 24]                         ;дошли ли до конца блока?
2434 Serge 733
        jb      .wanted_start
734
 
2987 Serge 735
        push    .wanted_start                           ; дошли
2434 Serge 736
        jmp     .end_block
737
 
2987 Serge 738
    .end_dir:   ;конец папки, когда еще не дошли до нужного файла
739
        mov     edx, [edi + 28] ;адрес структуры результата
740
        mov     ebx, [edi + 8] ;EXT2_read_in_folder
741
        mov     ecx, [edi + 4] ;EXT2_files_in_folder
2434 Serge 742
        mov     dword [edx], 1    ;version
2987 Serge 743
        mov     [edx + 4], ebx
744
        mov     [edx + 8], ecx
745
 
746
        lea     esp, [edi + 32]
747
 
748
        xor     eax, eax            ;зарезервировано: нули в текущей реализации
2434 Serge 749
        lea     edi, [edx + 12]
750
        mov     ecx, 20 / 4
751
        rep stosd
752
        ret
2987 Serge 753
 
754
    .error_bad_len:
755
        mov     eax, ERROR_FS_FAIL
756
    .error_read_subinode:
757
    .error_get_block:
758
        lea     esp, [edi + 32]
759
    .error_ret:
760
        or      ebx, -1
761
        ret
762
 
763
    .error_empty_dir:               ;inode папки без блоков
764
    .error_root:                    ;root - не папка
765
        mov     eax, ERROR_FS_FAIL
766
        jmp     .error_ret
767
 
768
    .error_not_found:               ;файл не найден
769
        mov     eax, ERROR_FILE_NOT_FOUND
770
        jmp     .error_ret
771
 
772
;============================================
773
;convert UTF-8 string to ASCII-string (codepage 866)
774
;in:  ecx = length source
775
;     esi = source
776
;     edi = buffer
2434 Serge 777
; destroys: eax,esi,edi
2987 Serge 778
utf8_to_cp866:
2434 Serge 779
        jecxz   .ret
780
    .start:
781
        lodsw
1397 turbanoff 782
        cmp     al, 0x80
2434 Serge 783
        jb      .ascii
784
 
785
        xchg    al, ah              ; big-endian
786
        cmp     ax, 0xd080
787
        jz      .yo1
788
        cmp     ax, 0xd191
789
        jz      .yo2
790
        cmp     ax, 0xd090
1397 turbanoff 791
        jb      .unk
792
        cmp     ax, 0xd180
793
        jb      .rus1
794
        cmp     ax, 0xd190
2434 Serge 795
        jb      .rus2
796
    .unk:
797
        mov     al, '_'
798
        jmp     .doit
799
    .yo1:
800
        mov     al, 0xf0    ; Ё capital
801
        jmp     .doit
802
    .yo2:
803
        mov     al, 0xf1    ; ё small
804
        jmp     .doit
805
    .rus1:
806
        sub     ax, 0xd090 - 0x80
807
        jmp     .doit
808
    .rus2:
809
        sub     ax, 0xd18f - 0xEF
810
    .doit:
811
        stosb
812
        sub     ecx, 2
813
        ja      .start
814
        ret
815
 
816
    .ascii:
817
        stosb
818
        dec     esi
819
        dec     ecx
820
        jnz     .start
821
    .ret:
822
        ret
823
 
1378 turbanoff 824
;----------------------------------------------------------------
825
;
826
;  ext2_HdRead - read hard disk
827
;
828
;  esi  points to filename
829
;  ebx  pointer to 64-bit number = first wanted byte, 0+
830
;       may be ebx=0 - start from first byte
831
;  ecx  number of bytes to read, 0+
832
;  edx  mem location to return data
833
;
834
;  ret ebx = bytes read or 0xffffffff file not found
835
;      eax = 0 ok read or other = errormsg
2987 Serge 836
 
2434 Serge 837
;--------------------------------------------------------------
838
ext2_HdRead:
839
        cmp     byte [esi], 0
840
        jnz     @F
841
 
842
    .this_is_nofile:
843
        or      ebx, -1
844
        mov     eax, ERROR_ACCESS_DENIED
845
        ret
846
 
847
    @@:
2987 Serge 848
        push    ecx ebx edx
2434 Serge 849
        call    ext2_find_lfn
2987 Serge 850
        pop     edx ebx ecx
851
        test    eax, eax
852
        jz      @F
853
 
2434 Serge 854
        or      ebx, -1
855
        mov     eax, ERROR_FILE_NOT_FOUND
856
        ret
857
 
2987 Serge 858
    @@:
859
        mov     ax, [ebp + EXT2_INODE_STRUC.i_mode]
860
        and     ax, EXT2_S_IFMT     ;оставляем только тип inode в ax
861
        cmp     ax, EXT2_S_IFREG
862
        jne     .this_is_nofile
2434 Serge 863
 
864
        mov     edi, edx            ; edi = pointer to return mem
2987 Serge 865
 
866
        test    ebx, ebx
867
        jz      @F
2434 Serge 868
        mov     esi, ebx            ; esi = pointer to first_wanted
869
        mov     ebx, [esi+4]
870
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
871
 
2987 Serge 872
        ;///// сравним хватит ли нам файла или нет
2434 Serge 873
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
874
        ja      .size_great
875
        jb      .size_less
876
 
877
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
878
        ja      .size_great
879
 
880
    .size_less:
881
        xor     ebx, ebx
882
        mov     eax, ERROR_END_OF_FILE
883
        ret
2987 Serge 884
 
885
    @@:
886
        xor     ebx, ebx
887
        xor     eax, eax
2434 Serge 888
    .size_great:
889
        add     eax, ecx                  ;add to first_wanted кол-во байт для чтения
890
        adc     ebx, 0
891
 
892
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
893
        ja      .size_great_great
894
        jb      .size_great_less
895
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
2987 Serge 896
        jae     .size_great_great
2434 Serge 897
 
898
    .size_great_less:
3500 Serge 899
        push    1                                ;читаем по границе размера
2434 Serge 900
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]
2987 Serge 901
        sub     ecx, [esi]                      ;(размер - старт) = сколько читать
2434 Serge 902
        jmp     @F
903
 
904
    .size_great_great:
3500 Serge 905
        push    0                                ;читаем столько сколько запросили
2434 Serge 906
 
907
    @@:
2987 Serge 908
        ;здесь мы точно знаем сколько байт читать - ecx
909
        ;edi - return memory
910
        ;esi -> first wanted
911
 
912
        push    ecx                             ;количество считанных байт
2434 Serge 913
        test    esi, esi
914
        jz      .zero_start
915
 
2987 Serge 916
        ;получим кусок из первого блока
2434 Serge 917
        mov     edx, [esi+4]
918
        mov     eax, [esi]
919
        div     [ext2_data.block_size]
920
 
3500 Serge 921
        push    eax       ;счетчик блоков ложим в стек
922
 
2434 Serge 923
        push    ecx
924
        mov     ecx, eax
925
        call    ext2_get_inode_block
2987 Serge 926
        test    eax, eax
927
        jnz     .error_at_first_block
2434 Serge 928
        mov     ebx, [ext2_data.ext2_save_block]
929
        mov     eax, ecx
930
        call    ext2_get_block
2987 Serge 931
        test    eax, eax
932
        jnz     .error_at_first_block
2434 Serge 933
        pop     ecx
934
        add     ebx, edx
935
 
936
        neg     edx
937
        add     edx, [ext2_data.block_size]     ;block_size - стартовый байт = сколько байт 1-го блока
938
        cmp     ecx, edx
939
        jbe     .only_one_block
940
 
941
        mov     eax, ecx
942
        sub     eax, edx
943
        mov     ecx, edx
944
 
945
        mov     esi, ebx
946
        rep movsb                               ;кусок 1-го блока
2987 Serge 947
        jmp     .calc_blocks_count
2434 Serge 948
 
949
    .zero_start:
950
        mov     eax, ecx
3500 Serge 951
        push    0                               ;счетчик блоков ложим в стек
2434 Serge 952
        ;теперь в eax кол-во оставшихся байт для чтения
2987 Serge 953
    .calc_blocks_count:
2434 Serge 954
        mov     ebx, edi                        ;чтение блока прям в ->ebx
955
        xor     edx, edx
3500 Serge 956
        div     [ext2_data.block_size]       ;кол-во байт в последнем блоке (остаток) в edx
2434 Serge 957
        mov     edi, eax                        ;кол-во целых блоков в edi
958
    @@:
959
        test    edi, edi
960
        jz      .finish_block
2987 Serge 961
        inc     dword [esp]
962
        mov     ecx, [esp]
2434 Serge 963
        call    ext2_get_inode_block
2987 Serge 964
        test    eax, eax
965
        jnz     .error_at_read_cycle
2434 Serge 966
 
967
        mov     eax, ecx                        ;а ebx уже забит нужным значением
968
        call    ext2_get_block
2987 Serge 969
        test    eax, eax
970
        jnz     .error_at_read_cycle
2434 Serge 971
        add     ebx, [ext2_data.block_size]
972
 
973
        dec     edi
974
        jmp     @B
975
 
976
    .finish_block:          ;в edx - кол-во байт в последнем блоке
977
        test    edx, edx
978
        jz      .end_read
979
 
2987 Serge 980
        pop     ecx         ;счетчик блоков -> ecx
2434 Serge 981
        inc     ecx
982
        call    ext2_get_inode_block
2987 Serge 983
        test    eax, eax
3500 Serge 984
        jnz     .error_at_finish_block
2434 Serge 985
 
986
        mov     edi, ebx
987
        mov     eax, ecx
988
        mov     ebx, [ext2_data.ext2_save_block]
989
        call    ext2_get_block
2987 Serge 990
        test    eax, eax
991
        jnz     .error_at_finish_block
2434 Serge 992
 
3500 Serge 993
        mov     ecx, edx
2434 Serge 994
        mov     esi, ebx
995
        rep movsb                               ;кусок last блока
3500 Serge 996
        jmp     @F
997
 
2434 Serge 998
    .end_read:
3500 Serge 999
        pop     ecx                             ;счетчик блоков, который хранился в стеке
1000
    @@:
1001
        pop     ebx                             ;количество считанных байт
1002
        pop     eax                             ; 1 или 0 - достигли ли конца файла
2987 Serge 1003
        test    eax, eax
2434 Serge 1004
        jz      @F
1005
 
1006
        mov     eax, ERROR_END_OF_FILE
1007
        ret
1008
    @@:
1009
        xor     eax, eax
1010
        ret
2987 Serge 1011
 
1012
    .only_one_block:
1013
        mov     esi, ebx
1014
        rep movsb                               ;кусок last блока
1015
        jmp     .end_read
1016
 
1017
   .error_at_first_block:
1018
        pop     edx
1019
   .error_at_read_cycle:
1020
        pop     ebx
1021
   .error_at_finish_block:
1022
        pop     ecx edx
1023
        or      ebx, -1
1024
        ret
1025
 
1026
;----------------------------------------------------------------
1027
; in:  esi = file path
1028
;      ebx = pointer to dir block
1029
; out: esi - name without parent or not_changed
1030
;      ebx - dir_rec of inode children
1031
ext2_test_block_by_name:
1032
        sub     esp, 256        ;EXT2_filename
1033
        mov     edx, ebx
1034
        add     edx, [ext2_data.block_size]       ;запомним конец блока
1035
 
1036
    .start_rec:
1037
        cmp     [ebx + EXT2_DIR_STRUC.inode], 0
1038
        jz      .next_rec
1039
 
1040
        mov     edi, esp
1041
        push    esi
1042
        movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
1043
        lea     esi, [ebx + EXT2_DIR_STRUC.name]
1044
        call    utf8_to_cp866
1045
 
1046
        mov     ecx, edi
1047
        lea     edi, [esp + 4]
1048
        sub     ecx, edi          ;кол-во байт в получившейся строке
1049
 
1050
        mov     esi, [esp]
1051
    @@:
1052
        jecxz   .test_find
1053
        dec     ecx
1054
 
1055
        lodsb
1056
        call    char_toupper
1057
 
1058
        mov     ah, [edi]
1059
        inc     edi
1060
        xchg    al, ah
1061
        call    char_toupper
1062
        cmp     al, ah
1063
        je      @B
1064
    @@:                           ;не подошло
1065
        pop     esi
1066
    .next_rec:
1067
        movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
1068
        add     ebx, eax                                    ;к след. записи
1069
        cmp     ebx, edx                                    ;проверим конец ли
1070
        jb      .start_rec
1071
        add     esp, 256
1072
        ret
1073
 
1074
    .test_find:
1075
        cmp     byte [esi], 0
1076
        je      .ret                ;нашли конец
1077
        cmp     byte [esi], '/'
1078
        jne     @B
1079
        inc     esi
1080
    .ret:
1081
        add     esp, 256 + 4
1082
        ret
1083
 
2434 Serge 1084
;========================
2987 Serge 1085
;Ищет inode по строке пути
1086
;in:  esi = name
1087
;out: eax - error code
1088
;     ebp = inode
1089
;      dl - первый байт из имени файла/папки
2434 Serge 1090
ext2_find_lfn:
1091
        mov     ebp, [ext2_data.root_inode]
2987 Serge 1092
        cmp     [ebp + EXT2_INODE_STRUC.i_blocks], 0
1093
        je      .error_empty_root
1094
 
1095
    .next_path_part:
1096
        push    [ebp + EXT2_INODE_STRUC.i_blocks]
1097
        xor     ecx, ecx
1098
    .folder_block_cycle:
3500 Serge 1099
        push    ecx
2434 Serge 1100
        call    ext2_get_inode_block
2987 Serge 1101
        test    eax, eax
1102
        jnz     .error_get_inode_block
3500 Serge 1103
 
2434 Serge 1104
        mov     eax, ecx
1105
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
1106
        call    ext2_get_block
2987 Serge 1107
        test    eax, eax
1108
        jnz     .error_get_block
3500 Serge 1109
 
2987 Serge 1110
        push    esi
2434 Serge 1111
        call    ext2_test_block_by_name
3500 Serge 1112
        pop     edi ecx
2434 Serge 1113
 
2987 Serge 1114
        cmp     edi, esi                                ;нашли имя?
1115
        je      .next_folder_block                      ;не нашли -> к след. блоку
3500 Serge 1116
 
2987 Serge 1117
        cmp     byte [esi], 0                           ;дошли до "конца" пути -> возваращаемся
2434 Serge 1118
        jz      .get_inode_ret
1119
 
2987 Serge 1120
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;нашли, но это не папка
1121
        jne     .not_found
1122
 
2434 Serge 1123
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
1124
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
1125
        call    ext2_get_inode
2987 Serge 1126
        test    eax, eax
1127
        jnz     .error_get_inode
1128
        pop     ecx                                     ;в стеке лежит кол-во блоков
2434 Serge 1129
        mov     ebp, ebx
2987 Serge 1130
        jmp     .next_path_part
1131
 
1132
    .next_folder_block:
1133
        ;к следующему блоку в текущей папке
1134
        pop     eax                                     ;счетчик блоков
1135
        sub     eax, [ext2_data.count_block_in_block]
1136
        jle     .not_found
1137
 
3500 Serge 1138
        push    eax
2987 Serge 1139
        inc     ecx
1140
        jmp     .folder_block_cycle
2434 Serge 1141
 
1142
    .not_found:
2987 Serge 1143
        mov     eax, ERROR_FILE_NOT_FOUND
2434 Serge 1144
        ret
2987 Serge 1145
 
2434 Serge 1146
    .get_inode_ret:
2987 Serge 1147
        pop     ecx                                     ;в стеке лежит кол-во блоков
1148
        mov     dl, [ebx + EXT2_DIR_STRUC.name]     ;в dl - первый символ ()
2434 Serge 1149
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
1150
        mov     ebx, [ext2_data.ext2_save_inode]
1151
        call    ext2_get_inode
1152
        mov     ebp, ebx
2987 Serge 1153
        xor     eax, eax
2434 Serge 1154
        ret
1155
 
2987 Serge 1156
    .error_get_inode_block:
1157
    .error_get_block:
3500 Serge 1158
        pop     ecx
2987 Serge 1159
    .error_get_inode:
1160
        pop     ebx
1161
    .error_empty_root:
1162
        mov     eax, ERROR_FS_FAIL
1163
        ret
2434 Serge 1164
 
2987 Serge 1165
;----------------------------------------------------------------
1166
;ext2_HdGetFileInfo - read file info from block device
1167
;
1168
;in: esi  points to filename
1169
;    edx  mem location to return data
1170
;--------------------------------------------------------------
2434 Serge 1171
ext2_HdGetFileInfo:
2987 Serge 1172
        xchg    bx, bx
2434 Serge 1173
        cmp     byte [esi], 0
2987 Serge 1174
        jz      .is_root
2434 Serge 1175
 
2987 Serge 1176
        push    edx
2434 Serge 1177
        call    ext2_find_lfn
2987 Serge 1178
        mov     ebx, edx
1179
        pop     edx
1180
        test    eax, eax
1181
        jz      @F
2434 Serge 1182
        ret
1183
 
2987 Serge 1184
    .is_root:
1185
        xor     ebx, ebx                        ;root не может быть скрытым
2434 Serge 1186
        mov     ebp, [ext2_data.root_inode]
1187
    @@:
1188
        xor     eax, eax
1189
        mov     edi, edx
1190
        mov     ecx, 40/4
1191
        rep stosd                   ; fill zero
1192
 
2987 Serge 1193
        cmp     bl, '.'
1194
        jne     @F
2434 Serge 1195
        or      dword [edx], FS_FT_HIDDEN
1196
    @@:
1197
 
1198
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
1199
        jnz     @F
1200
        mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
1201
        mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
1202
        mov     dword [edx+32], eax
1203
        mov     dword [edx+36], ebx
1204
        xor     dword [edx], FS_FT_DIR
1205
    @@:
1206
        xor     dword [edx], FS_FT_DIR
1207
 
1208
        lea     edi, [edx + 8]
2987 Serge 1209
        mov     eax, [ebp + EXT2_INODE_STRUC.i_ctime]
2434 Serge 1210
        xor     edx, edx
1211
        add     eax, 3054539008
1212
        adc     edx, 2
1213
        call    ntfs_datetime_to_bdfe.sec
1214
 
2987 Serge 1215
        mov     eax, [ebp + EXT2_INODE_STRUC.i_atime]
2434 Serge 1216
        xor     edx, edx
1217
        add     eax, 3054539008
1218
        adc     edx, 2
1219
        call    ntfs_datetime_to_bdfe.sec
1220
 
2987 Serge 1221
        mov     eax, [ebp + EXT2_INODE_STRUC.i_mtime]
2434 Serge 1222
        xor     edx, edx
1223
        add     eax, 3054539008
1224
        adc     edx, 2
1225
        call    ntfs_datetime_to_bdfe.sec
1226
 
1227
        xor     eax, eax
1228
        ret
1229
 
1230
ext2_HdRewrite:
1231
ext2_HdWrite:
1232
ext2_HdSetFileEnd:
1233
ext2_HdSetFileInfo:
1234
ext2_HdDelete:
1235
ext2_HdCreateFolder:
1236
        xor     ebx, ebx
1237
        mov     eax, ERROR_UNSUPPORTED_FS
1238
        ret