Subversion Repositories Kolibri OS

Rev

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