Subversion Repositories Kolibri OS

Rev

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