Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1378 turbanoff 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
1378 turbanoff 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: 2973 $
12
 
2889 turbanoff 13
EXT2_BAD_INO         = 1
1378 turbanoff 14
EXT2_ROOT_INO        = 2
2889 turbanoff 15
EXT2_ACL_IDX_INO     = 3
1378 turbanoff 16
EXT2_ACL_DATA_INO    = 4
2889 turbanoff 17
EXT2_BOOT_LOADER_INO = 5
18
EXT2_UNDEL_DIR_INO   = 6
1378 turbanoff 19
 
2889 turbanoff 20
;флаги, указываемый в inode файла
21
EXT2_S_IFREG         = 0x8000
22
EXT2_S_IFDIR         = 0x4000
2973 turbanoff 23
EXT2_S_IFMT          = 0xF000 ;маска для типа файла
1378 turbanoff 24
 
2889 turbanoff 25
;флаги, указываемые в linked list родительской папки
26
EXT2_FT_REG_FILE     = 1     ;это файл, запись в родительском каталоге
27
EXT2_FT_DIR          = 2     ;это папка
1378 turbanoff 28
 
2889 turbanoff 29
;флаги используемые KolibriOS
30
FS_FT_HIDDEN         = 2
31
FS_FT_DIR            = 0x10  ;это папка
32
FS_FT_ASCII          = 0     ;имя в ascii
33
FS_FT_UNICODE        = 1     ;имя в unicode
1378 turbanoff 34
 
2889 turbanoff 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
1410 turbanoff 42
 
1397 turbanoff 43
 
2889 turbanoff 44
;флаги, указываемые для inode в i_flags
45
EXT2_EXTENTS_FL      = 0x00080000
46
 
2381 hidnplayr 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
1378 turbanoff 66
ends
67
 
2381 hidnplayr 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
1378 turbanoff 74
ends
75
 
2381 hidnplayr 76
struct  EXT2_BLOCK_GROUP_DESC
2889 turbanoff 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
1419 turbanoff 85
ends
1378 turbanoff 86
 
2381 hidnplayr 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
2889 turbanoff 125
        reserved_gdt_blocks     dw ? ;+206
2381 hidnplayr 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
2889 turbanoff 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
1419 turbanoff 148
ends
149
 
2889 turbanoff 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
 
1378 turbanoff 172
ext2_test_superblock:
1410 turbanoff 173
        cmp     [fs_type], 0x83
174
        jne     .no
175
 
1378 turbanoff 176
        mov     eax, [PARTITION_START]
177
        add     eax, 2                  ;superblock start at 1024b
178
        call    hd_read
179
 
2889 turbanoff 180
        cmp     [ebx + EXT2_SB_STRUC.log_block_size], 3  ;0,1,2,3
1378 turbanoff 181
        ja      .no
2889 turbanoff 182
        cmp     [ebx + EXT2_SB_STRUC.magic], 0xEF53
1378 turbanoff 183
        jne     .no
2889 turbanoff 184
        cmp     [ebx + EXT2_SB_STRUC.state], 1        ;EXT_VALID_FS=1
1378 turbanoff 185
        jne     .no
2889 turbanoff 186
        cmp     [ebx + EXT2_SB_STRUC.inodes_per_group], 0
187
        je      .no
188
 
189
        mov     eax, [ebx + EXT2_SB_STRUC.feature_incompat]
1410 turbanoff 190
        test    eax, EXT2_FEATURE_INCOMPAT_FILETYPE
191
        jz      .no
2889 turbanoff 192
        test    eax, not EXT4_FEATURE_INCOMPAT_SUPP
1410 turbanoff 193
        jnz     .no
1378 turbanoff 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
1419 turbanoff 205
 
206
        push    512
207
        call    kernel_alloc                            ; mem for superblock
208
        mov     esi, ebx
209
        mov     edi, eax
210
        mov     ecx, 512/4
2288 clevermous 211
        rep movsd                                       ; copy sb to reserved mem
1419 turbanoff 212
        mov     ebx, eax
2288 clevermous 213
        mov     [ext2_data.sb], eax
1419 turbanoff 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
 
2889 turbanoff 223
        mov     ecx, [ebx + EXT2_SB_STRUC.log_block_size]
1378 turbanoff 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
 
1419 turbanoff 238
        push    eax eax                                 ; 2 kernel_alloc
1378 turbanoff 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
 
2889 turbanoff 249
        movzx   ebp, word [ebx + EXT2_SB_STRUC.inode_size]
250
        mov     ecx, [ebx + EXT2_SB_STRUC.blocks_per_group]
1378 turbanoff 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
1419 turbanoff 266
 
2288 clevermous 267
        jmp     return_from_part_set
1378 turbanoff 268
 
269
;==================================================================
2889 turbanoff 270
;read ext2 block form FS to memory
271
;in:  eax = i_block (address of block in ext2 terms)
272
;     ebx = pointer to return memory
273
;out: eax - error code (0 = no_error)
1378 turbanoff 274
ext2_get_block:
2889 turbanoff 275
        push    ebx ecx
1378 turbanoff 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
2889 turbanoff 282
        cmp     [hd_error], 0
283
        jnz     .fail
1378 turbanoff 284
        inc     eax
285
        add     ebx, 512
286
        loop    @B
2889 turbanoff 287
        xor     eax, eax
288
    @@:
289
        pop     ecx ebx
1378 turbanoff 290
        ret
2889 turbanoff 291
    .fail:
292
        mov     eax, ERROR_DEVICE
293
        jmp     @B
294
 
295
 
1378 turbanoff 296
;===================================================================
2889 turbanoff 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..)
373
;     ebp = адрес inode
374
;out: ecx = адрес очередного блока
375
;     eax - error code
1378 turbanoff 376
ext2_get_inode_block:
2889 turbanoff 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
    @@:
1387 turbanoff 389
        cmp     ecx, 12                                         ; 0..11 - direct block address
390
        jb      .get_direct_block
1378 turbanoff 391
 
392
        sub     ecx, 12
2889 turbanoff 393
        cmp     ecx, [ext2_data.count_pointer_in_block]         ; 12.. - indirect blocks
1387 turbanoff 394
        jb      .get_indirect_block
1378 turbanoff 395
 
396
        sub     ecx, [ext2_data.count_pointer_in_block]
397
        cmp     ecx, [ext2_data.count_pointer_in_block_square]
1387 turbanoff 398
        jb      .get_double_indirect_block
1378 turbanoff 399
 
1387 turbanoff 400
        sub     ecx, [ext2_data.count_pointer_in_block_square]
2889 turbanoff 401
    ;triple indirect block
402
        push    edx ebx
1378 turbanoff 403
 
2288 clevermous 404
        mov     eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
405
        mov     ebx, [ext2_data.ext2_temp_block]
1378 turbanoff 406
        call    ext2_get_block
2889 turbanoff 407
        test    eax, eax
408
        jnz     .fail
1378 turbanoff 409
 
410
        xor     edx, edx
411
        mov     eax, ecx
412
        div     [ext2_data.count_pointer_in_block_square]
413
 
414
    ;eax - номер в полученном блоке   edx - номер дальше
2288 clevermous 415
        mov     eax, [ebx + eax*4]
416
        call    ext2_get_block
2889 turbanoff 417
        test    eax, eax
418
        jnz     .fail
1378 turbanoff 419
 
2288 clevermous 420
        mov     eax, edx
421
        jmp     @F
1378 turbanoff 422
 
423
    .get_double_indirect_block:
2889 turbanoff 424
        push    edx ebx
1378 turbanoff 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
2889 turbanoff 429
        test    eax, eax
430
        jnz     .fail
1378 turbanoff 431
 
432
        mov     eax, ecx
2889 turbanoff 433
    @@:
1378 turbanoff 434
        xor     edx, edx
435
        div     [ext2_data.count_pointer_in_block]
436
 
2288 clevermous 437
        mov     eax, [ebx + eax*4]
1378 turbanoff 438
        call    ext2_get_block
2889 turbanoff 439
        test    eax, eax
440
        jnz     .fail
441
 
2288 clevermous 442
        mov     ecx, [ebx + edx*4]
2889 turbanoff 443
    .fail:
444
        pop     ebx edx
1378 turbanoff 445
        ret
446
 
447
    .get_indirect_block:
2889 turbanoff 448
        push    ebx
1378 turbanoff 449
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
1387 turbanoff 450
        mov     ebx, [ext2_data.ext2_temp_block]
1378 turbanoff 451
        call    ext2_get_block
2889 turbanoff 452
        test    eax, eax
453
        jz      @F                      ;если не было ошибки
1378 turbanoff 454
 
2889 turbanoff 455
        mov     ecx, [ebx + ecx*4]    ;заносим результат
456
    @@:
457
        pop     ebx
1378 turbanoff 458
        ret
459
 
460
    .get_direct_block:
2889 turbanoff 461
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
462
        xor     eax, eax
1378 turbanoff 463
        ret
464
 
465
;===================================================================
466
;get content inode by num
2889 turbanoff 467
;in:  eax = inode_num
468
;     ebx = address of inode content
469
;out: eax - error code
1378 turbanoff 470
ext2_get_inode:
2288 clevermous 471
        pushad
472
        mov     edi, ebx   ;сохраним адрес inode
473
        dec     eax
474
        xor     edx, edx
2889 turbanoff 475
 
476
        mov     ecx, [ext2_data.sb]
477
        div     [ecx + EXT2_SB_STRUC.inodes_per_group]
1378 turbanoff 478
 
1419 turbanoff 479
        push    edx                             ;locale num in group
1378 turbanoff 480
 
481
        mov     edx, 32
482
        mul     edx                             ; address block_group in global_desc_table
483
 
1419 turbanoff 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
2889 turbanoff 491
        test    eax, eax
492
        jnz     .fail
1419 turbanoff 493
 
494
        add     ebx, edx                        ; локальный номер в блоке
2889 turbanoff 495
        mov     eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]; номер блока - в терминах ext2
1419 turbanoff 496
 
1378 turbanoff 497
        mov     ecx, [ext2_data.log_block_size]
498
        shl     eax, cl
2889 turbanoff 499
        add     eax, [PARTITION_START]        ; а старт раздела - в терминах hdd (512)
1378 turbanoff 500
 
501
        ;eax - указывает на таблицу inode-ов на hdd
1410 turbanoff 502
        mov     esi, eax                        ;сохраним его пока в esi
1378 turbanoff 503
 
504
        ; прибавим локальный адрес inode-а
505
        pop     eax                             ; index
1410 turbanoff 506
        mov     ecx, [ext2_data.inode_size]
507
        mul     ecx                             ; (index * inode_size)
1378 turbanoff 508
        mov     ebp, 512
509
        div     ebp                             ;поделим на размер блока
510
 
1410 turbanoff 511
        add     eax, esi                        ;нашли адрес блока для чтения
1378 turbanoff 512
        mov     ebx, [ext2_data.ext2_temp_block]
513
        call    hd_read
2889 turbanoff 514
        cmp     [hd_error], 0
515
        jnz     .fail
1378 turbanoff 516
 
517
        mov     esi, edx                        ;добавим "остаток"
518
        add     esi, ebx                        ;к адресу
2288 clevermous 519
        rep movsb                               ;копируем inode
2889 turbanoff 520
        xor     eax, eax
521
    .fail:
522
        mov     PUSHAD_EAX, eax
1378 turbanoff 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
2889 turbanoff 543
        jz      .root_folder
1378 turbanoff 544
 
2889 turbanoff 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
1387 turbanoff 553
 
2889 turbanoff 554
    .root_folder:
1387 turbanoff 555
        mov     ebp, [ext2_data.root_inode]
2889 turbanoff 556
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
557
        jz      .error_root
558
        ;придется копировать inode
1387 turbanoff 559
        push    ecx
2889 turbanoff 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
1387 turbanoff 567
    @@:
2889 turbanoff 568
        cmp     [ebp + EXT2_INODE_STRUC.i_blocks], 0 ;папка пуста
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
 
1387 turbanoff 580
        mov     edi, edx
581
        mov     ecx, 32/4
2288 clevermous 582
        rep stosd                               ; fill header zero
2889 turbanoff 583
 
584
        mov     edi, esp                        ; edi - указатель на локальные переменные
585
        add     edx, 32                         ; edx = current mem for return
1387 turbanoff 586
 
2889 turbanoff 587
        xor     ecx, ecx                        ; получим номер первого блока
1378 turbanoff 588
        call    ext2_get_inode_block
2889 turbanoff 589
        test    eax, eax
590
        jnz     .error_get_block
1378 turbanoff 591
 
592
        mov     eax, ecx
593
        mov     ebx, [ext2_data.ext2_save_block]
594
        call    ext2_get_block                  ; и считываем блок с hdd
2889 turbanoff 595
        test    eax, eax
596
        jnz     .error_get_block
1378 turbanoff 597
 
2889 turbanoff 598
        mov     esi, ebx                         ; esi = current dir record
1378 turbanoff 599
        add     ebx, [ext2_data.block_size]
2889 turbanoff 600
        mov     [edi + 24], ebx               ; запомним конец очередного блока
1378 turbanoff 601
 
2889 turbanoff 602
        mov     ecx, [edi + 16]                        ; ecx = first wanted (flags ommited)
1378 turbanoff 603
 
604
    .find_wanted_start:
2288 clevermous 605
        jecxz   .find_wanted_end
1378 turbanoff 606
    .find_wanted_cycle:
2889 turbanoff 607
        cmp     [esi + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
2288 clevermous 608
        jz      @F
2889 turbanoff 609
        inc     dword [edi + 4]                        ; EXT2_files_in_folder
2288 clevermous 610
        dec     ecx
2889 turbanoff 611
    @@:
612
        movzx   ebx, [esi + EXT2_DIR_STRUC.rec_len]
1419 turbanoff 613
 
2288 clevermous 614
        cmp     ebx, 12                                 ; минимальная длина записи
2889 turbanoff 615
        jb      .error_bad_len
2288 clevermous 616
        test    ebx, 0x3                                ; длина записи должна делиться на 4
2889 turbanoff 617
        jnz     .error_bad_len
1419 turbanoff 618
 
2889 turbanoff 619
        add     esi, ebx                                ; к следующей записи
620
        cmp     esi, [edi + 24]                        ; сравниваем с концом блока
2288 clevermous 621
        jb      .find_wanted_start
1398 turbanoff 622
 
1419 turbanoff 623
        push    .find_wanted_start
2889 turbanoff 624
   .end_block:                                              ;вылетели из цикла
1398 turbanoff 625
        mov     ebx, [ext2_data.count_block_in_block]
2889 turbanoff 626
        sub     [ebp + EXT2_INODE_STRUC.i_blocks], ebx  ;вычитаем напрямую из структуры inode
627
        jle     .end_dir
1398 turbanoff 628
 
2889 turbanoff 629
        inc     dword [edi]                                 ;получаем новый блок
1398 turbanoff 630
        push    ecx
2889 turbanoff 631
        mov     ecx, [edi]
1398 turbanoff 632
        call    ext2_get_inode_block
2889 turbanoff 633
        test    eax, eax
634
        jnz     .error_get_block
635
 
1398 turbanoff 636
        mov     eax, ecx
637
        mov     ebx, [ext2_data.ext2_save_block]
638
        call    ext2_get_block
2889 turbanoff 639
        test    eax, eax
640
        jnz     .error_get_block
641
 
1398 turbanoff 642
        pop     ecx
2889 turbanoff 643
        mov     esi, ebx
1398 turbanoff 644
        add     ebx, [ext2_data.block_size]
2889 turbanoff 645
        mov     [edi + 24], ebx                            ;запомним конец блока
646
        ret                                                 ; опять в цикл
1398 turbanoff 647
 
1400 turbanoff 648
    .wanted_end:
2889 turbanoff 649
        loop    .find_wanted_cycle                          ; ecx 0 => -1 нужно посчитать сколько файлов
1400 turbanoff 650
 
2889 turbanoff 651
    ;дошли до первого "нужного" файла
1378 turbanoff 652
    .find_wanted_end:
2889 turbanoff 653
        mov     ecx, [edi + 20]
654
    .wanted_start:                                          ; ищем first_wanted+count
2288 clevermous 655
        jecxz   .wanted_end
2889 turbanoff 656
        cmp     [esi + EXT2_DIR_STRUC.inode], 0         ; if (inode = 0) => not used
2288 clevermous 657
        jz      .empty_rec
2889 turbanoff 658
        inc     dword [edi + 8]
659
        inc     dword [edi + 4]
1378 turbanoff 660
 
2889 turbanoff 661
        push    edi ecx
662
        mov     edi, edx                            ;обнуляем место под очереное имя файла/папки
2288 clevermous 663
        xor     eax, eax
664
        mov     ecx, 40 / 4
665
        rep stosd
2889 turbanoff 666
        pop     ecx edi
1378 turbanoff 667
 
2889 turbanoff 668
        push    esi edi edx
669
        mov     eax, [esi + EXT2_DIR_STRUC.inode]             ;получим дочерний inode
2288 clevermous 670
        mov     ebx, [ext2_data.ext2_temp_inode]
671
        call    ext2_get_inode
2889 turbanoff 672
        test    eax, eax
673
        jnz     .error_read_subinode
1400 turbanoff 674
 
2288 clevermous 675
        lea     edi, [edx + 8]
1400 turbanoff 676
 
2889 turbanoff 677
        mov     eax, [ebx + EXT2_INODE_STRUC.i_ctime]           ; переведем время в ntfs формат
2288 clevermous 678
        xor     edx, edx
679
        add     eax, 3054539008                                     ;(369 * 365 + 89) * 24 * 3600
680
        adc     edx, 2
681
        call    ntfs_datetime_to_bdfe.sec
1400 turbanoff 682
 
2288 clevermous 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
1400 turbanoff 688
 
2288 clevermous 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
1400 turbanoff 694
 
2288 clevermous 695
        pop     edx                                                 ; пока достаем только буфер
2889 turbanoff 696
        test    [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR   ; для папки размер
2288 clevermous 697
        jnz     @F                                                  ; не возвращаем
1400 turbanoff 698
 
2889 turbanoff 699
        mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
2288 clevermous 700
        stosd
2889 turbanoff 701
        mov     eax, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
2288 clevermous 702
        stosd
2889 turbanoff 703
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл(2 раза xor)
704
    @@:
705
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл
1400 turbanoff 706
 
2889 turbanoff 707
        ;теперь скопируем имя, сконвертировав из UTF-8 в CP866
708
        push    ecx  ;edi и esi уже сохранены в стеке
709
        movzx   ecx, [esi + EXT2_DIR_STRUC.name_len]
2288 clevermous 710
        lea     edi, [edx + 40]
2889 turbanoff 711
        lea     esi, [esi + EXT2_DIR_STRUC.name]
712
        call    utf8_to_cp866
2288 clevermous 713
        and     byte [edi], 0
2889 turbanoff 714
        pop     ecx edi esi
1378 turbanoff 715
 
2889 turbanoff 716
        cmp     byte [edx + 40], '.'                    ; в linux файл, начинающийся с точки - скрытый
2288 clevermous 717
        jne     @F
718
        or      dword [edx], FS_FT_HIDDEN
2889 turbanoff 719
    @@:
1400 turbanoff 720
 
2288 clevermous 721
        add     edx, 40 + 264                           ; go to next record
722
        dec     ecx                                     ; если запись пустая ecx не надо уменьшать
2889 turbanoff 723
    .empty_rec:
724
        movzx   ebx, [esi + EXT2_DIR_STRUC.rec_len]
2288 clevermous 725
        cmp     ebx, 12                                 ; минимальная длина записи
2889 turbanoff 726
        jb      .error_bad_len
2288 clevermous 727
        test    ebx, 0x3                                ; длина записи должна делиться на 4
2889 turbanoff 728
        jnz     .error_bad_len
1419 turbanoff 729
 
2889 turbanoff 730
        add     esi, ebx
731
        cmp     esi, [edi + 24]                         ;дошли ли до конца блока?
2288 clevermous 732
        jb      .wanted_start
1378 turbanoff 733
 
2889 turbanoff 734
        push    .wanted_start                           ; дошли
1400 turbanoff 735
        jmp     .end_block
1378 turbanoff 736
 
2889 turbanoff 737
    .end_dir:   ;конец папки, когда еще не дошли до нужного файла
738
        mov     edx, [edi + 28] ;адрес структуры результата
739
        mov     ebx, [edi + 8] ;EXT2_read_in_folder
740
        mov     ecx, [edi + 4] ;EXT2_files_in_folder
1378 turbanoff 741
        mov     dword [edx], 1    ;version
2889 turbanoff 742
        mov     [edx + 4], ebx
743
        mov     [edx + 8], ecx
744
 
745
        lea     esp, [edi + 32]
746
 
747
        xor     eax, eax            ;зарезервировано: нули в текущей реализации
1378 turbanoff 748
        lea     edi, [edx + 12]
749
        mov     ecx, 20 / 4
2288 clevermous 750
        rep stosd
1378 turbanoff 751
        ret
2889 turbanoff 752
 
753
    .error_bad_len:
754
        mov     eax, ERROR_FS_FAIL
755
    .error_read_subinode:
756
    .error_get_block:
757
        lea     esp, [edi + 32]
758
    .error_ret:
759
        or      ebx, -1
760
        ret
761
 
762
    .error_empty_dir:               ;inode папки без блоков
763
    .error_root:                    ;root - не папка
764
        mov     eax, ERROR_FS_FAIL
765
        jmp     .error_ret
766
 
767
    .error_not_found:               ;файл не найден
768
        mov     eax, ERROR_FILE_NOT_FOUND
769
        jmp     .error_ret
770
 
771
;============================================
772
;convert UTF-8 string to ASCII-string (codepage 866)
773
;in:  ecx = length source
774
;     esi = source
775
;     edi = buffer
1397 turbanoff 776
; destroys: eax,esi,edi
2889 turbanoff 777
utf8_to_cp866:
1397 turbanoff 778
        jecxz   .ret
779
    .start:
780
        lodsw
2288 clevermous 781
        cmp     al, 0x80
1397 turbanoff 782
        jb      .ascii
1378 turbanoff 783
 
1400 turbanoff 784
        xchg    al, ah              ; big-endian
1397 turbanoff 785
        cmp     ax, 0xd080
786
        jz      .yo1
787
        cmp     ax, 0xd191
788
        jz      .yo2
789
        cmp     ax, 0xd090
2288 clevermous 790
        jb      .unk
791
        cmp     ax, 0xd180
792
        jb      .rus1
793
        cmp     ax, 0xd190
1397 turbanoff 794
        jb      .rus2
795
    .unk:
796
        mov     al, '_'
797
        jmp     .doit
798
    .yo1:
799
        mov     al, 0xf0    ; Ё capital
800
        jmp     .doit
801
    .yo2:
802
        mov     al, 0xf1    ; ё small
803
        jmp     .doit
804
    .rus1:
805
        sub     ax, 0xd090 - 0x80
806
        jmp     .doit
807
    .rus2:
808
        sub     ax, 0xd18f - 0xEF
809
    .doit:
810
        stosb
811
        sub     ecx, 2
812
        ja      .start
813
        ret
814
 
815
    .ascii:
816
        stosb
817
        dec     esi
818
        dec     ecx
819
        jnz     .start
820
    .ret:
821
        ret
822
 
2288 clevermous 823
;----------------------------------------------------------------
824
;
825
;  ext2_HdRead - read hard disk
826
;
827
;  esi  points to filename
828
;  ebx  pointer to 64-bit number = first wanted byte, 0+
829
;       may be ebx=0 - start from first byte
830
;  ecx  number of bytes to read, 0+
831
;  edx  mem location to return data
832
;
833
;  ret ebx = bytes read or 0xffffffff file not found
834
;      eax = 0 ok read or other = errormsg
2889 turbanoff 835
 
1378 turbanoff 836
;--------------------------------------------------------------
837
ext2_HdRead:
838
        cmp     byte [esi], 0
1397 turbanoff 839
        jnz     @F
1378 turbanoff 840
 
1384 turbanoff 841
    .this_is_nofile:
1378 turbanoff 842
        or      ebx, -1
843
        mov     eax, ERROR_ACCESS_DENIED
844
        ret
845
 
1397 turbanoff 846
    @@:
2889 turbanoff 847
        push    ecx ebx edx
1397 turbanoff 848
        call    ext2_find_lfn
2889 turbanoff 849
        pop     edx ebx ecx
850
        test    eax, eax
851
        jz      @F
852
 
1397 turbanoff 853
        or      ebx, -1
854
        mov     eax, ERROR_FILE_NOT_FOUND
855
        ret
856
 
2889 turbanoff 857
    @@:
2973 turbanoff 858
        mov     ax, [ebp + EXT2_INODE_STRUC.i_mode]
859
        and     ax, EXT2_S_IFMT     ;оставляем только тип inode в ax
860
        cmp     ax, EXT2_S_IFREG
861
        jne     .this_is_nofile
1397 turbanoff 862
 
863
        mov     edi, edx            ; edi = pointer to return mem
2889 turbanoff 864
 
865
        test    ebx, ebx
866
        jz      @F
1397 turbanoff 867
        mov     esi, ebx            ; esi = pointer to first_wanted
1378 turbanoff 868
        mov     ebx, [esi+4]
869
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
870
 
2889 turbanoff 871
        ;///// сравним хватит ли нам файла или нет
1397 turbanoff 872
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
1378 turbanoff 873
        ja      .size_great
874
        jb      .size_less
875
 
1397 turbanoff 876
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
1378 turbanoff 877
        ja      .size_great
878
 
879
    .size_less:
1397 turbanoff 880
        xor     ebx, ebx
1419 turbanoff 881
        mov     eax, ERROR_END_OF_FILE
1378 turbanoff 882
        ret
2889 turbanoff 883
 
884
    @@:
885
        xor     ebx, ebx
886
        xor     eax, eax
1378 turbanoff 887
    .size_great:
1397 turbanoff 888
        add     eax, ecx                  ;add to first_wanted кол-во байт для чтения
889
        adc     ebx, 0
890
 
891
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
1378 turbanoff 892
        ja      .size_great_great
893
        jb      .size_great_less
1397 turbanoff 894
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
2889 turbanoff 895
        jae     .size_great_great
1397 turbanoff 896
 
1378 turbanoff 897
    .size_great_less:
2889 turbanoff 898
        push    1
899
;        or      [EXT2_files_in_folder], 1       ;читаем по границе размера
1397 turbanoff 900
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]
2889 turbanoff 901
        sub     ecx, [esi]                      ;(размер - старт) = сколько читать
1378 turbanoff 902
        jmp     @F
903
 
904
    .size_great_great:
2889 turbanoff 905
        push    0
906
;        and     [EXT2_files_in_folder], 0       ;читаем столько сколько запросили
1378 turbanoff 907
 
908
    @@:
2889 turbanoff 909
        ;здесь мы точно знаем сколько байт читать - ecx
910
        ;edi - return memory
911
        ;esi -> first wanted
912
 
913
        push    ecx                             ;количество считанных байт
1397 turbanoff 914
        test    esi, esi
915
        jz      .zero_start
1378 turbanoff 916
 
2889 turbanoff 917
        ;получим кусок из первого блока
1397 turbanoff 918
        mov     edx, [esi+4]
919
        mov     eax, [esi]
1378 turbanoff 920
        div     [ext2_data.block_size]
921
 
2889 turbanoff 922
        push    eax       ;номер блока запоминаем
923
 
1378 turbanoff 924
        push    ecx
925
        mov     ecx, eax
926
        call    ext2_get_inode_block
2889 turbanoff 927
        test    eax, eax
928
        jnz     .error_at_first_block
1397 turbanoff 929
        mov     ebx, [ext2_data.ext2_save_block]
1378 turbanoff 930
        mov     eax, ecx
931
        call    ext2_get_block
2889 turbanoff 932
        test    eax, eax
933
        jnz     .error_at_first_block
1378 turbanoff 934
        pop     ecx
935
        add     ebx, edx
936
 
937
        neg     edx
2288 clevermous 938
        add     edx, [ext2_data.block_size]     ;block_size - стартовый байт = сколько байт 1-го блока
1378 turbanoff 939
        cmp     ecx, edx
940
        jbe     .only_one_block
941
 
942
        mov     eax, ecx
943
        sub     eax, edx
944
        mov     ecx, edx
945
 
946
        mov     esi, ebx
2288 clevermous 947
        rep movsb                               ;кусок 1-го блока
2889 turbanoff 948
        jmp     .calc_blocks_count
1378 turbanoff 949
 
950
    .zero_start:
1389 turbanoff 951
        mov     eax, ecx
2889 turbanoff 952
        push    0                               ;счетчик блоков
1378 turbanoff 953
        ;теперь в eax кол-во оставшихся байт для чтения
2889 turbanoff 954
    .calc_blocks_count:
1397 turbanoff 955
        mov     ebx, edi                        ;чтение блока прям в ->ebx
1378 turbanoff 956
        xor     edx, edx
2889 turbanoff 957
        div     [ext2_data.block_size]       ;кол-во байт в последнем блоке (остаток) в edx
1397 turbanoff 958
        mov     edi, eax                        ;кол-во целых блоков в edi
1378 turbanoff 959
    @@:
2288 clevermous 960
        test    edi, edi
1378 turbanoff 961
        jz      .finish_block
2889 turbanoff 962
        inc     dword [esp]
963
        mov     ecx, [esp]
1378 turbanoff 964
        call    ext2_get_inode_block
2889 turbanoff 965
        test    eax, eax
966
        jnz     .error_at_read_cycle
1378 turbanoff 967
 
1397 turbanoff 968
        mov     eax, ecx                        ;а ebx уже забит нужным значением
1378 turbanoff 969
        call    ext2_get_block
2889 turbanoff 970
        test    eax, eax
971
        jnz     .error_at_read_cycle
1378 turbanoff 972
        add     ebx, [ext2_data.block_size]
973
 
1397 turbanoff 974
        dec     edi
1378 turbanoff 975
        jmp     @B
976
 
977
    .finish_block:          ;в edx - кол-во байт в последнем блоке
1397 turbanoff 978
        test    edx, edx
979
        jz      .end_read
1378 turbanoff 980
 
2889 turbanoff 981
        pop     ecx         ;счетчик блоков -> ecx
1378 turbanoff 982
        inc     ecx
983
        call    ext2_get_inode_block
2889 turbanoff 984
        test    eax, eax
985
        jz      .error_at_finish_block
1378 turbanoff 986
 
987
        mov     edi, ebx
988
        mov     eax, ecx
989
        mov     ebx, [ext2_data.ext2_save_block]
990
        call    ext2_get_block
2889 turbanoff 991
        test    eax, eax
992
        jnz     .error_at_finish_block
1378 turbanoff 993
 
2889 turbanoff 994
        mov     ecx, edx
1378 turbanoff 995
        mov     esi, ebx
2288 clevermous 996
        rep movsb                               ;кусок last блока
1389 turbanoff 997
    .end_read:
1378 turbanoff 998
        pop     ebx
2889 turbanoff 999
        pop     eax
1000
        test    eax, eax
1378 turbanoff 1001
        jz      @F
1002
 
1419 turbanoff 1003
        mov     eax, ERROR_END_OF_FILE
1378 turbanoff 1004
        ret
1005
    @@:
1006
        xor     eax, eax
1007
        ret
2889 turbanoff 1008
 
1009
    .only_one_block:
1010
        mov     esi, ebx
1011
        rep movsb                               ;кусок last блока
1012
        pop     eax
1013
        jmp     .end_read
1014
 
1015
   .error_at_first_block:
1016
        pop     edx
1017
   .error_at_read_cycle:
1018
        pop     ebx
1019
   .error_at_finish_block:
1020
        pop     ecx edx
1021
        or      ebx, -1
1022
        ret
1023
 
1024
;----------------------------------------------------------------
1025
; in:  esi = file path
1026
;      ebx = pointer to dir block
1027
; out: esi - name without parent or not_changed
1028
;      ebx - dir_rec of inode children
1029
ext2_test_block_by_name:
1030
        sub     esp, 256        ;EXT2_filename
1031
        mov     edx, ebx
1032
        add     edx, [ext2_data.block_size]       ;запомним конец блока
1033
 
1034
    .start_rec:
1035
        cmp     [ebx + EXT2_DIR_STRUC.inode], 0
1036
        jz      .next_rec
1037
 
1038
        mov     edi, esp
1039
        push    esi
1040
        movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
1041
        lea     esi, [ebx + EXT2_DIR_STRUC.name]
1042
        call    utf8_to_cp866
1043
 
1044
        mov     ecx, edi
1045
        lea     edi, [esp + 4]
1046
        sub     ecx, edi          ;кол-во байт в получившейся строке
1047
 
1048
        mov     esi, [esp]
1049
    @@:
1050
        jecxz   .test_find
1051
        dec     ecx
1052
 
1053
        lodsb
1054
        call    char_toupper
1055
 
1056
        mov     ah, [edi]
1057
        inc     edi
1058
        xchg    al, ah
1059
        call    char_toupper
1060
        cmp     al, ah
1061
        je      @B
1062
    @@:                           ;не подошло
1063
        pop     esi
1064
    .next_rec:
1065
        movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
1066
        add     ebx, eax                                    ;к след. записи
1067
        cmp     ebx, edx                                    ;проверим конец ли
1068
        jb      .start_rec
1069
        add     esp, 256
1070
        ret
1071
 
1072
    .test_find:
1073
        cmp     byte [esi], 0
1074
        je      .ret                ;нашли конец
1075
        cmp     byte [esi], '/'
1076
        jne     @B
1077
        inc     esi
1078
    .ret:
1079
        add     esp, 256 + 4
1080
        ret
1081
 
1378 turbanoff 1082
;========================
2889 turbanoff 1083
;Ищет inode по строке пути
1084
;in:  esi = name
1085
;out: eax - error code
1086
;     ebp = inode
1087
;      dl - первый байт из имени файла/папки
1384 turbanoff 1088
ext2_find_lfn:
1089
        mov     ebp, [ext2_data.root_inode]
2889 turbanoff 1090
        cmp     [ebp + EXT2_INODE_STRUC.i_blocks], 0
1091
        je      .error_empty_root
1092
 
1093
    .next_path_part:
1094
        push    [ebp + EXT2_INODE_STRUC.i_blocks]
1095
        xor     ecx, ecx
1096
    .folder_block_cycle:
1384 turbanoff 1097
        call    ext2_get_inode_block
2889 turbanoff 1098
        test    eax, eax
1099
        jnz     .error_get_inode_block
1100
 
1384 turbanoff 1101
        mov     eax, ecx
1102
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
1103
        call    ext2_get_block
2889 turbanoff 1104
        test    eax, eax
1105
        jnz     .error_get_block
1106
 
1107
        push    esi
1384 turbanoff 1108
        call    ext2_test_block_by_name
2889 turbanoff 1109
        pop     edi
1384 turbanoff 1110
 
2889 turbanoff 1111
        cmp     edi, esi                                ;нашли имя?
1112
        je      .next_folder_block                      ;не нашли -> к след. блоку
1113
 
1114
        cmp     byte [esi], 0                           ;дошли до "конца" пути -> возваращаемся
1384 turbanoff 1115
        jz      .get_inode_ret
1116
 
2889 turbanoff 1117
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;нашли, но это не папка
1118
        jne     .not_found
1119
 
1384 turbanoff 1120
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
1121
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
1122
        call    ext2_get_inode
2889 turbanoff 1123
        test    eax, eax
1124
        jnz     .error_get_inode
1125
        pop     ecx                                     ;в стеке лежит кол-во блоков
1384 turbanoff 1126
        mov     ebp, ebx
2889 turbanoff 1127
        jmp     .next_path_part
1128
 
1129
    .next_folder_block:
1130
        ;к следующему блоку в текущей папке
1131
        pop     eax                                     ;счетчик блоков
1132
        sub     eax, [ext2_data.count_block_in_block]
1133
        jle     .not_found
1134
 
1135
        inc     ecx
1136
        jmp     .folder_block_cycle
1384 turbanoff 1137
 
1138
    .not_found:
2889 turbanoff 1139
        pop     ebx
1140
        mov     eax, ERROR_FILE_NOT_FOUND
1384 turbanoff 1141
        ret
2889 turbanoff 1142
 
1384 turbanoff 1143
    .get_inode_ret:
2889 turbanoff 1144
        pop     ecx                                     ;в стеке лежит кол-во блоков
1145
        mov     dl, [ebx + EXT2_DIR_STRUC.name]     ;в dl - первый символ ()
1384 turbanoff 1146
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
1147
        mov     ebx, [ext2_data.ext2_save_inode]
1148
        call    ext2_get_inode
1149
        mov     ebp, ebx
2889 turbanoff 1150
        xor     eax, eax
1384 turbanoff 1151
        ret
1152
 
2889 turbanoff 1153
    .error_get_inode_block:
1154
    .error_get_block:
1155
    .error_get_inode:
1156
        pop     ebx
1157
    .error_empty_root:
1158
        mov     eax, ERROR_FS_FAIL
1159
        ret
1384 turbanoff 1160
 
2889 turbanoff 1161
;----------------------------------------------------------------
1162
;ext2_HdGetFileInfo - read file info from block device
1163
;
1164
;in: esi  points to filename
1165
;    edx  mem location to return data
1166
;--------------------------------------------------------------
1378 turbanoff 1167
ext2_HdGetFileInfo:
2889 turbanoff 1168
        xchg    bx, bx
1384 turbanoff 1169
        cmp     byte [esi], 0
2889 turbanoff 1170
        jz      .is_root
1384 turbanoff 1171
 
2889 turbanoff 1172
        push    edx
1384 turbanoff 1173
        call    ext2_find_lfn
2889 turbanoff 1174
        mov     ebx, edx
1175
        pop     edx
1176
        test    eax, eax
1177
        jz      @F
1378 turbanoff 1178
        ret
1384 turbanoff 1179
 
2889 turbanoff 1180
    .is_root:
1181
        xor     ebx, ebx                        ;root не может быть скрытым
1384 turbanoff 1182
        mov     ebp, [ext2_data.root_inode]
1400 turbanoff 1183
    @@:
1384 turbanoff 1184
        xor     eax, eax
1185
        mov     edi, edx
1186
        mov     ecx, 40/4
2288 clevermous 1187
        rep stosd                   ; fill zero
1384 turbanoff 1188
 
2889 turbanoff 1189
        cmp     bl, '.'
1190
        jne     @F
1400 turbanoff 1191
        or      dword [edx], FS_FT_HIDDEN
1192
    @@:
1193
 
1384 turbanoff 1194
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
2288 clevermous 1195
        jnz     @F
1384 turbanoff 1196
        mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
1197
        mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
1198
        mov     dword [edx+32], eax
1199
        mov     dword [edx+36], ebx
1400 turbanoff 1200
        xor     dword [edx], FS_FT_DIR
1201
    @@:
1202
        xor     dword [edx], FS_FT_DIR
1384 turbanoff 1203
 
1400 turbanoff 1204
        lea     edi, [edx + 8]
2889 turbanoff 1205
        mov     eax, [ebp + EXT2_INODE_STRUC.i_ctime]
1400 turbanoff 1206
        xor     edx, edx
1207
        add     eax, 3054539008
1208
        adc     edx, 2
1209
        call    ntfs_datetime_to_bdfe.sec
1210
 
2889 turbanoff 1211
        mov     eax, [ebp + EXT2_INODE_STRUC.i_atime]
1400 turbanoff 1212
        xor     edx, edx
1213
        add     eax, 3054539008
1214
        adc     edx, 2
1215
        call    ntfs_datetime_to_bdfe.sec
1216
 
2889 turbanoff 1217
        mov     eax, [ebp + EXT2_INODE_STRUC.i_mtime]
1400 turbanoff 1218
        xor     edx, edx
1219
        add     eax, 3054539008
1220
        adc     edx, 2
1221
        call    ntfs_datetime_to_bdfe.sec
1222
 
1384 turbanoff 1223
        xor     eax, eax
1224
        ret
1225
 
1419 turbanoff 1226
ext2_HdRewrite:
1227
ext2_HdWrite:
1228
ext2_HdSetFileEnd:
1378 turbanoff 1229
ext2_HdSetFileInfo:
1419 turbanoff 1230
ext2_HdDelete:
1231
ext2_HdCreateFolder:
1378 turbanoff 1232
        xor     ebx, ebx
1233
        mov     eax, ERROR_UNSUPPORTED_FS
1234
        ret