Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1378 turbanoff 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3742 clevermous 3
;; Copyright (C) KolibriOS team 2004-2013. 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: 3742 $
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
 
3742 clevermous 180
struct EXTFS PARTITION
181
    Lock                           MUTEX
182
    log_block_size                 dd ?
183
    block_size                     dd ?
184
    count_block_in_block           dd ?
185
    blocks_per_group               dd ?
186
    global_desc_table              dd ?
187
    root_inode                     dd ?   ; pointer to root inode in memory
188
    inode_size                     dd ?
189
    count_pointer_in_block         dd ?   ;  block_size / 4
190
    count_pointer_in_block_square  dd ?   ; (block_size / 4)**2
191
    ext2_save_block                dd ?   ;RUS: блок на глобальную 1 процедуру   ;ENG: block for 1 global procedure
192
    ext2_temp_block                dd ?   ;RUS: блок для мелких процедур         ;ENG: block for small procedures
193
    ext2_save_inode                dd ?   ;RUS: inode на глобальную процедуру    ;ENG: inode for global procedure
194
    ext2_temp_inode                dd ?   ;RUS: inode для мелких процедур        ;ENG: inode for small procedures
195
    groups_count                   dd ?
196
    superblock                     rd 512/4
197
ends
1410 turbanoff 198
 
3742 clevermous 199
iglobal
200
align 4
201
ext2_user_functions:
202
        dd      ext2_free
203
        dd      (ext2_user_functions_end - ext2_user_functions - 4) / 4
204
        dd      ext2_Read
205
        dd      ext2_ReadFolder
206
        dd      ext2_Rewrite
207
        dd      ext2_Write
208
        dd      ext2_SetFileEnd
209
        dd      ext2_GetFileInfo
210
        dd      ext2_SetFileInfo
211
        dd      0
212
        dd      ext2_Delete
213
        dd      ext2_CreateFolder
214
ext2_user_functions_end:
215
endg
1378 turbanoff 216
 
3742 clevermous 217
proc ext2_create_partition
218
        push    ebx
219
 
220
        mov     eax, 2                  ;superblock start at 1024b
221
        add     ebx, 512        ; get pointer to fs-specific buffer
222
        call    fs_read32_sys
223
 
2889 turbanoff 224
        cmp     [ebx + EXT2_SB_STRUC.log_block_size], 3  ;0,1,2,3
1378 turbanoff 225
        ja      .no
2889 turbanoff 226
        cmp     [ebx + EXT2_SB_STRUC.magic], 0xEF53
1378 turbanoff 227
        jne     .no
2889 turbanoff 228
        cmp     [ebx + EXT2_SB_STRUC.state], 1        ;EXT_VALID_FS=1
1378 turbanoff 229
        jne     .no
2889 turbanoff 230
        cmp     [ebx + EXT2_SB_STRUC.inodes_per_group], 0
231
        je      .no
232
 
233
        mov     eax, [ebx + EXT2_SB_STRUC.feature_incompat]
1410 turbanoff 234
        test    eax, EXT2_FEATURE_INCOMPAT_FILETYPE
235
        jz      .no
2889 turbanoff 236
        test    eax, not EXT4_FEATURE_INCOMPAT_SUPP
3742 clevermous 237
        jz      ext2_setup
1378 turbanoff 238
 
239
   .no:
240
    ; No, this superblock isn't EXT2
3742 clevermous 241
        pop     ebx
242
        xor     eax, eax
1378 turbanoff 243
        ret
244
 
3742 clevermous 245
    ; OK, this is correct EXT2 superblock
1378 turbanoff 246
ext2_setup:
3742 clevermous 247
        movi    eax, sizeof.EXTFS
248
        call    malloc
249
        test    eax, eax
250
        jz      ext2_create_partition.no
1419 turbanoff 251
 
3742 clevermous 252
        mov     ecx, dword [ebp+PARTITION.FirstSector]
253
        mov     dword [eax+EXTFS.FirstSector], ecx
254
        mov     ecx, dword [ebp+PARTITION.FirstSector+4]
255
        mov     dword [eax+EXTFS.FirstSector+4], ecx
256
        mov     ecx, dword [ebp+PARTITION.Length]
257
        mov     dword [eax+EXTFS.Length], ecx
258
        mov     ecx, dword [ebp+PARTITION.Length+4]
259
        mov     dword [eax+EXTFS.Length+4], ecx
260
        mov     ecx, [ebp+PARTITION.Disk]
261
        mov     [eax+EXTFS.Disk], ecx
262
        mov     [eax+EXTFS.FSUserFunctions], ext2_user_functions
263
        push    ebp esi
264
        mov     ebp, eax
265
        lea     ecx, [eax+EXTFS.Lock]
266
        call    mutex_init
267
 
1419 turbanoff 268
        mov     esi, ebx
3742 clevermous 269
        lea     edi, [ebp+EXTFS.superblock]
1419 turbanoff 270
        mov     ecx, 512/4
2288 clevermous 271
        rep movsd                                       ; copy sb to reserved mem
1419 turbanoff 272
 
273
        mov     eax, [ebx + EXT2_SB_STRUC.blocks_count]
274
        sub     eax, [ebx + EXT2_SB_STRUC.first_data_block]
275
        dec     eax
276
        xor     edx, edx
277
        div     [ebx + EXT2_SB_STRUC.blocks_per_group]
278
        inc     eax
3742 clevermous 279
        mov     [ebp+EXTFS.groups_count], eax
1419 turbanoff 280
 
2889 turbanoff 281
        mov     ecx, [ebx + EXT2_SB_STRUC.log_block_size]
1378 turbanoff 282
        inc     ecx
3742 clevermous 283
        mov     [ebp+EXTFS.log_block_size], ecx    ; 1, 2, 3, 4   equ 1kb, 2kb, 4kb, 8kb
1378 turbanoff 284
 
285
        mov     eax, 1
286
        shl     eax, cl
3742 clevermous 287
        mov     [ebp+EXTFS.count_block_in_block], eax
1378 turbanoff 288
 
289
        shl     eax, 7
3742 clevermous 290
        mov     [ebp+EXTFS.count_pointer_in_block], eax
3691 yogev_ezra 291
        mov     edx, eax   ;RUS: потом еще квадрат найдем   ;ENG: we'll find a square later
1378 turbanoff 292
 
293
        shl     eax, 2
3742 clevermous 294
        mov     [ebp+EXTFS.block_size], eax
1378 turbanoff 295
 
1419 turbanoff 296
        push    eax eax                                 ; 2 kernel_alloc
1378 turbanoff 297
 
298
        mov     eax, edx
299
        mul     edx
3742 clevermous 300
        mov     [ebp+EXTFS.count_pointer_in_block_square], eax
1378 turbanoff 301
 
302
        call    kernel_alloc
3742 clevermous 303
        mov     [ebp+EXTFS.ext2_save_block], eax        ; and for temp block
1378 turbanoff 304
        call    kernel_alloc
3742 clevermous 305
        mov     [ebp+EXTFS.ext2_temp_block], eax        ; and for get_inode proc
1378 turbanoff 306
 
3742 clevermous 307
        movzx   eax, word [ebx + EXT2_SB_STRUC.inode_size]
2889 turbanoff 308
        mov     ecx, [ebx + EXT2_SB_STRUC.blocks_per_group]
1378 turbanoff 309
 
3742 clevermous 310
        mov     [ebp+EXTFS.inode_size], eax
311
        mov     [ebp+EXTFS.blocks_per_group], ecx
1378 turbanoff 312
 
3742 clevermous 313
        push    eax eax eax                             ;3 kernel_alloc
1378 turbanoff 314
        call    kernel_alloc
3742 clevermous 315
        mov     [ebp+EXTFS.ext2_save_inode], eax
1378 turbanoff 316
        call    kernel_alloc
3742 clevermous 317
        mov     [ebp+EXTFS.ext2_temp_inode], eax
1378 turbanoff 318
        call    kernel_alloc
3742 clevermous 319
        mov     [ebp+EXTFS.root_inode], eax
1378 turbanoff 320
 
321
        mov     ebx, eax
322
        mov     eax, EXT2_ROOT_INO
323
        call    ext2_get_inode                          ; read root inode
1419 turbanoff 324
 
3742 clevermous 325
        mov     eax, ebp        ; return pointer to EXTFS
326
        pop     esi ebp ebx
327
        ret
328
endp
1378 turbanoff 329
 
3742 clevermous 330
proc ext2_free
331
        push    ebp
332
        xchg    ebp, eax
333
        stdcall kernel_free, [ebp+EXTFS.ext2_save_block]
334
        stdcall kernel_free, [ebp+EXTFS.ext2_temp_block]
335
        stdcall kernel_free, [ebp+EXTFS.ext2_save_inode]
336
        stdcall kernel_free, [ebp+EXTFS.ext2_temp_inode]
337
        stdcall kernel_free, [ebp+EXTFS.root_inode]
338
        xchg    ebp, eax
339
        call    free
340
        pop     ebp
341
        ret
342
endp
343
 
344
proc ext2_lock
345
        lea     ecx, [ebp+EXTFS.Lock]
346
        jmp     mutex_lock
347
endp
348
 
349
proc ext2_unlock
350
        lea     ecx, [ebp+EXTFS.Lock]
351
        jmp     mutex_unlock
352
endp
353
 
1378 turbanoff 354
;==================================================================
2889 turbanoff 355
;read ext2 block form FS to memory
356
;in:  eax = i_block (address of block in ext2 terms)
357
;     ebx = pointer to return memory
3742 clevermous 358
;     ebp = pointer to EXTFS
2889 turbanoff 359
;out: eax - error code (0 = no_error)
1378 turbanoff 360
ext2_get_block:
2889 turbanoff 361
        push    ebx ecx
3742 clevermous 362
        mov     ecx, [ebp+EXTFS.log_block_size]
1378 turbanoff 363
        shl     eax, cl
3742 clevermous 364
        mov     ecx, eax
365
        push    [ebp+EXTFS.count_block_in_block]
1378 turbanoff 366
    @@:
3742 clevermous 367
        mov     eax, ecx
368
        call    fs_read32_sys
369
        test    eax, eax
2889 turbanoff 370
        jnz     .fail
3742 clevermous 371
        inc     ecx
1378 turbanoff 372
        add     ebx, 512
3742 clevermous 373
        dec     dword [esp]
374
        jnz     @B
375
        pop     ecx
2889 turbanoff 376
        xor     eax, eax
377
    @@:
378
        pop     ecx ebx
1378 turbanoff 379
        ret
2889 turbanoff 380
    .fail:
381
        mov     eax, ERROR_DEVICE
382
        jmp     @B
383
 
384
 
1378 turbanoff 385
;===================================================================
3691 yogev_ezra 386
;RUS: получает номер блока из extent inode                    ;ENG: receives block number from extent inode
387
;RUS: in:  ecx = номер блока по порядку                       ;ENG: in:  ecx = consecutive block number
3742 clevermous 388
;RUS:      esi = адрес extent header`а                        ;ENG:      esi = address of extent header
389
;RUS:      ebp = указатель на структуру EXTFS                 ;ENG:      ebp = pointer to EXTFS
3691 yogev_ezra 390
;RUS: out: ecx - адрес очередного блока в случае успеха       ;ENG: out: ecx - address of next block, if successful
391
;RUS:      eax - номер ошибки (если равно 0, то ошибки нет)   ;ENG:      eax - error number (0 - no error)
2889 turbanoff 392
ext4_block_recursive_search:
3742 clevermous 393
        cmp     word [esi + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
2889 turbanoff 394
        jne     .fail
395
 
3742 clevermous 396
        movzx   ebx, [esi + EXT4_EXTENT_HEADER.eh_entries]
397
        add     esi, sizeof.EXT4_EXTENT_HEADER
398
        cmp     word [esi - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0
2889 turbanoff 399
        je      .leaf_block     ;листовой ли это блок?
400
 
401
        ;не листовой блок, а индексный ; eax - ext4_extent_idx
402
        test    ebx, ebx
403
        jz      .fail               ;пустой индексный блок -> ошибка
404
 
405
        ;цикл по индексам экстентов
406
    @@:
407
        cmp     ebx, 1              ;у индексов не хранится длина,
408
        je      .end_search_index   ;поэтому, если остался последний - то это нужный
409
 
3742 clevermous 410
        cmp     ecx, [esi + EXT4_EXTENT_IDX.ei_block]
2889 turbanoff 411
        jb      .fail
412
 
3742 clevermous 413
        cmp     ecx, [esi + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса
2889 turbanoff 414
        jb      .end_search_index ;следующий дальше - значит текущий, то что нам нужен
415
 
3742 clevermous 416
        add     esi, sizeof.EXT4_EXTENT_IDX
2889 turbanoff 417
        dec     ebx
418
        jmp     @B
419
 
420
    .end_search_index:
421
        ;ebp указывает на нужный extent_idx, считываем следующий блок
3742 clevermous 422
        mov     ebx, [ebp+EXTFS.ext2_temp_block]
423
        mov     eax, [esi + EXT4_EXTENT_IDX.ei_leaf_lo]
2889 turbanoff 424
        call    ext2_get_block
425
        test    eax, eax
426
        jnz     .fail
3742 clevermous 427
        mov     esi, ebx
2889 turbanoff 428
        jmp     ext4_block_recursive_search ;рекурсивно прыгаем в начало
429
 
3742 clevermous 430
    .leaf_block:    ;листовой блок esi - ext4_extent
2889 turbanoff 431
        ;цикл по экстентам
432
    @@:
433
        test    ebx, ebx
434
        jz      .fail       ;ни один узел не подошел - ошибка
435
 
3742 clevermous 436
        mov     edx, [esi + EXT4_EXTENT.ee_block]
2889 turbanoff 437
        cmp     ecx, edx
438
        jb      .fail       ;если меньше, значит он был в предыдущих блоках -> ошибка
439
 
3742 clevermous 440
        movzx   edi, [esi + EXT4_EXTENT.ee_len]
2889 turbanoff 441
        add     edx, edi
442
        cmp     ecx, edx
443
        jb      .end_search_extent     ;нашли нужный блок
444
 
3742 clevermous 445
        add     esi, sizeof.EXT4_EXTENT
2889 turbanoff 446
        dec     ebx
447
        jmp     @B
448
 
449
    .end_search_extent:
3742 clevermous 450
        mov     edx, [esi + EXT4_EXTENT.ee_start_lo]
451
        sub     ecx, [esi + EXT4_EXTENT.ee_block] ;разница в ext4 блоках
2889 turbanoff 452
        add     ecx, edx
453
        xor     eax, eax
454
        ret
455
 
456
    .fail:
457
        mov     eax, ERROR_FS_FAIL
458
        ret
459
 
460
;===================================================================
461
;получает адрес ext2 блока из inode с определнным номером
3691 yogev_ezra 462
;RUS: in:  ecx = номер блока в inode (0..)   ;ENG: in:  ecx = number of block in inode (0..)
3742 clevermous 463
;RUS:      esi = адрес inode                 ;ENG:      esi = inode address
464
;RUS:      ebp = указатель на структуру EXTFS;ENG:      ebp = pointer to EXTFS
3691 yogev_ezra 465
;RUS: out: ecx = адрес очередного блока      ;ENG: out: ecx = next block address
466
;RUS:      eax - error code                  ;ENG:      eax - error code
1378 turbanoff 467
ext2_get_inode_block:
3742 clevermous 468
        test    [esi + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
2889 turbanoff 469
        jz      @F
470
 
471
        pushad
3742 clevermous 472
        add     esi, EXT2_INODE_STRUC.i_block             ;esi - extent_header
2889 turbanoff 473
        call    ext4_block_recursive_search
474
        mov     PUSHAD_ECX, ecx
475
        mov     PUSHAD_EAX, eax
476
        popad
477
        ret
478
 
479
    @@:
1387 turbanoff 480
        cmp     ecx, 12                                         ; 0..11 - direct block address
481
        jb      .get_direct_block
1378 turbanoff 482
 
483
        sub     ecx, 12
3742 clevermous 484
        cmp     ecx, [ebp+EXTFS.count_pointer_in_block]         ; 12.. - indirect blocks
1387 turbanoff 485
        jb      .get_indirect_block
1378 turbanoff 486
 
3742 clevermous 487
        sub     ecx, [ebp+EXTFS.count_pointer_in_block]
488
        cmp     ecx, [ebp+EXTFS.count_pointer_in_block_square]
1387 turbanoff 489
        jb      .get_double_indirect_block
1378 turbanoff 490
 
3742 clevermous 491
        sub     ecx, [ebp+EXTFS.count_pointer_in_block_square]
2889 turbanoff 492
    ;triple indirect block
493
        push    edx ebx
1378 turbanoff 494
 
3742 clevermous 495
        mov     eax, [esi + EXT2_INODE_STRUC.i_block + 14*4]
496
        mov     ebx, [ebp+EXTFS.ext2_temp_block]
1378 turbanoff 497
        call    ext2_get_block
2889 turbanoff 498
        test    eax, eax
499
        jnz     .fail
1378 turbanoff 500
 
501
        xor     edx, edx
502
        mov     eax, ecx
3742 clevermous 503
        div     [ebp+EXTFS.count_pointer_in_block_square]
1378 turbanoff 504
 
3691 yogev_ezra 505
    ;RUS: eax - номер в полученном блоке   edx - номер дальше
506
    ;ENG: eax - current block number, edx - next block number
2288 clevermous 507
        mov     eax, [ebx + eax*4]
508
        call    ext2_get_block
2889 turbanoff 509
        test    eax, eax
510
        jnz     .fail
1378 turbanoff 511
 
2288 clevermous 512
        mov     eax, edx
513
        jmp     @F
1378 turbanoff 514
 
515
    .get_double_indirect_block:
2889 turbanoff 516
        push    edx ebx
1378 turbanoff 517
 
3742 clevermous 518
        mov     eax, [esi + EXT2_INODE_STRUC.i_block + 13*4]
519
        mov     ebx, [ebp+EXTFS.ext2_temp_block]
1378 turbanoff 520
        call    ext2_get_block
2889 turbanoff 521
        test    eax, eax
522
        jnz     .fail
1378 turbanoff 523
 
524
        mov     eax, ecx
2889 turbanoff 525
    @@:
1378 turbanoff 526
        xor     edx, edx
3742 clevermous 527
        div     [ebp+EXTFS.count_pointer_in_block]
1378 turbanoff 528
 
2288 clevermous 529
        mov     eax, [ebx + eax*4]
1378 turbanoff 530
        call    ext2_get_block
2889 turbanoff 531
        test    eax, eax
532
        jnz     .fail
533
 
2288 clevermous 534
        mov     ecx, [ebx + edx*4]
2889 turbanoff 535
    .fail:
536
        pop     ebx edx
1378 turbanoff 537
        ret
538
 
539
    .get_indirect_block:
2889 turbanoff 540
        push    ebx
3742 clevermous 541
        mov     eax, [esi + EXT2_INODE_STRUC.i_block + 12*4]
542
        mov     ebx, [ebp+EXTFS.ext2_temp_block]
1378 turbanoff 543
        call    ext2_get_block
2889 turbanoff 544
        test    eax, eax
3691 yogev_ezra 545
        jnz     @F          ;RUS: если не было ошибки   ;ENG: if there was no error
1378 turbanoff 546
 
3691 yogev_ezra 547
        mov     ecx, [ebx + ecx*4]   ;RUS: заносим результат   ;ENG: ???
2889 turbanoff 548
    @@:
549
        pop     ebx
1378 turbanoff 550
        ret
551
 
552
    .get_direct_block:
3742 clevermous 553
        mov     ecx, [esi + EXT2_INODE_STRUC.i_block + ecx*4]
2889 turbanoff 554
        xor     eax, eax
1378 turbanoff 555
        ret
556
 
557
;===================================================================
558
;get content inode by num
2889 turbanoff 559
;in:  eax = inode_num
560
;     ebx = address of inode content
3742 clevermous 561
;     ebp = pointer to EXTFS
2889 turbanoff 562
;out: eax - error code
1378 turbanoff 563
ext2_get_inode:
2288 clevermous 564
        pushad
565
        mov     edi, ebx   ;сохраним адрес inode
566
        dec     eax
567
        xor     edx, edx
2889 turbanoff 568
 
3742 clevermous 569
        div     [ebp + EXT2_SB_STRUC.inodes_per_group + EXTFS.superblock]
1378 turbanoff 570
 
1419 turbanoff 571
        push    edx                             ;locale num in group
1378 turbanoff 572
 
573
        mov     edx, 32
574
        mul     edx                             ; address block_group in global_desc_table
575
 
3691 yogev_ezra 576
        ;RUS: в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
577
        ;RUS: найдем блок в котором он находится
578
        ;ENG: in eax - inode group offset relative to global descriptor table start
579
        ;ENG: let's find the block this inode is in
3742 clevermous 580
        div     [ebp+EXTFS.block_size]
581
        add     eax, [ebp + EXT2_SB_STRUC.first_data_block + EXTFS.superblock]
1419 turbanoff 582
        inc     eax
3742 clevermous 583
        mov     ebx, [ebp+EXTFS.ext2_temp_block]
1419 turbanoff 584
        call    ext2_get_block
2889 turbanoff 585
        test    eax, eax
3711 clevermous 586
        jnz     .fail
1419 turbanoff 587
 
3691 yogev_ezra 588
        add     ebx, edx   ;RUS: локальный номер в блоке   ;ENG: local number inside block
589
        mov     eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]   ;RUS: номер блока - в терминах ext2
590
                                                                 ;ENG: block number - in ext2 terms
3742 clevermous 591
        mov     ecx, [ebp+EXTFS.log_block_size]
1378 turbanoff 592
        shl     eax, cl
3691 yogev_ezra 593
        ;RUS: eax - указывает на таблицу inode-ов на hdd   ;ENG: eax - points to inode table on HDD
594
        mov     esi, eax   ;RUS: сохраним его пока в esi   ;ENG: let's save it in esi for now
1378 turbanoff 595
 
3691 yogev_ezra 596
        ;RUS: прибавим локальный адрес inode-а   ;ENG: add local address of inode
1378 turbanoff 597
        pop     eax                             ; index
3742 clevermous 598
        mov     ecx, [ebp+EXTFS.inode_size]
1410 turbanoff 599
        mul     ecx                             ; (index * inode_size)
3742 clevermous 600
                ;RUS: поделим на размер блока        ;ENG: divide by block size
601
        mov     ecx, eax
602
        and     ecx, 512 - 1
603
        shrd    eax, edx, 9
1378 turbanoff 604
 
3691 yogev_ezra 605
        add     eax, esi   ;RUS: нашли адрес блока для чтения   ;ENG: found block address to read
3742 clevermous 606
        mov     ebx, [ebp+EXTFS.ext2_temp_block]
607
        call    fs_read32_sys
608
        test    eax, eax
2889 turbanoff 609
        jnz     .fail
1378 turbanoff 610
 
3742 clevermous 611
        mov     esi, ecx         ;RUS: добавим "остаток"   ;ENG: add the "remainder"
612
        mov     ecx, [ebp+EXTFS.inode_size]
3691 yogev_ezra 613
        add     esi, ebx         ;RUS: к адресу            ;ENG: to the address
614
        rep movsb                ;RUS: копируем inode      ;ENG: copy inode
2889 turbanoff 615
        xor     eax, eax
616
    .fail:
617
        mov     PUSHAD_EAX, eax
1378 turbanoff 618
        popad
619
        ret
620
 
621
;----------------------------------------------------------------
3742 clevermous 622
; ext2_ReadFolder - EXT2FS implementation of reading a folder
623
; in:  ebp = pointer to EXTFS structure
624
; in:  esi+[esp+4] = name
625
; in:  ebx = pointer to parameters from sysfunc 70
626
; out: eax, ebx = return values for sysfunc 70
627
;----------------------------------------------------------------
628
ext2_ReadFolder:
629
        call    ext2_lock
1378 turbanoff 630
        cmp     byte [esi], 0
2889 turbanoff 631
        jz      .root_folder
1378 turbanoff 632
 
3742 clevermous 633
        push    ebx
634
        stdcall ext2_find_lfn, [esp+4+4]    ;вернет в esi адрес inode
635
        pop     ebx
2889 turbanoff 636
        test    eax, eax
637
        jnz     .error_ret
3742 clevermous 638
        test    [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
2889 turbanoff 639
        jz      .error_not_found
640
        jmp     @F
1387 turbanoff 641
 
2889 turbanoff 642
    .root_folder:
3742 clevermous 643
        mov     esi, [ebp+EXTFS.root_inode]
644
        test    [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
2889 turbanoff 645
        jz      .error_root
646
        ;придется копировать inode
3742 clevermous 647
        mov     edi, [ebp+EXTFS.ext2_save_inode]
648
        mov     ecx, [ebp+EXTFS.inode_size]
2889 turbanoff 649
        shr     ecx, 2
3742 clevermous 650
        push    edi
2889 turbanoff 651
        rep movsd
3742 clevermous 652
        pop     esi
1387 turbanoff 653
    @@:
3742 clevermous 654
        cmp     [esi + EXT2_INODE_STRUC.i_size], 0 ;папка пуста
2889 turbanoff 655
        je      .error_empty_dir
656
 
3742 clevermous 657
        mov     edx, [ebx + 16]
2889 turbanoff 658
        push    edx      ;адрес результата              [edi + 28]
659
        push    0        ;конец очередного блока папки   [edi + 24]
3742 clevermous 660
        push    dword [ebx +12];сколько файлов нужно прочитать [edi + 20]
661
        push    dword [ebx + 4];первый "нужный" файл           [edi + 16]
662
        push    dword [ebx + 8];флаги                        [edi + 12]
2889 turbanoff 663
        push    0       ;[EXT2_read_in_folder]     [edi + 8]
664
        push    0       ;[EXT2_files_in_folder]    [edi + 4]
665
        push    0       ;номер блока по порядку    [edi]
666
 
1387 turbanoff 667
        mov     edi, edx
668
        mov     ecx, 32/4
2288 clevermous 669
        rep stosd                               ; fill header zero
2889 turbanoff 670
 
671
        mov     edi, esp                        ; edi - указатель на локальные переменные
672
        add     edx, 32                         ; edx = current mem for return
1387 turbanoff 673
 
2889 turbanoff 674
        xor     ecx, ecx                        ; получим номер первого блока
1378 turbanoff 675
        call    ext2_get_inode_block
2889 turbanoff 676
        test    eax, eax
677
        jnz     .error_get_block
1378 turbanoff 678
 
679
        mov     eax, ecx
3742 clevermous 680
        mov     ebx, [ebp+EXTFS.ext2_save_block]
1378 turbanoff 681
        call    ext2_get_block                  ; и считываем блок с hdd
2889 turbanoff 682
        test    eax, eax
683
        jnz     .error_get_block
1378 turbanoff 684
 
3742 clevermous 685
        mov     eax, ebx                         ; ebx = current dir record
686
        add     eax, [ebp+EXTFS.block_size]
687
        mov     [edi + 24], eax               ; запомним конец очередного блока
1378 turbanoff 688
 
2889 turbanoff 689
        mov     ecx, [edi + 16]                        ; ecx = first wanted (flags ommited)
1378 turbanoff 690
 
691
    .find_wanted_start:
2288 clevermous 692
        jecxz   .find_wanted_end
1378 turbanoff 693
    .find_wanted_cycle:
3742 clevermous 694
        cmp     [ebx + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
2288 clevermous 695
        jz      @F
2889 turbanoff 696
        inc     dword [edi + 4]                        ; EXT2_files_in_folder
2288 clevermous 697
        dec     ecx
2889 turbanoff 698
    @@:
3742 clevermous 699
        movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
1419 turbanoff 700
 
3742 clevermous 701
        cmp     eax, 12                                 ; минимальная длина записи
2889 turbanoff 702
        jb      .error_bad_len
3742 clevermous 703
        test    eax, 0x3                                ; длина записи должна делиться на 4
2889 turbanoff 704
        jnz     .error_bad_len
1419 turbanoff 705
 
3742 clevermous 706
        sub     [esi + EXT2_INODE_STRUC.i_size], eax    ;вычитаем напрямую из структуры inode
707
        add     ebx, eax                                ; к следующей записи
708
        cmp     ebx, [edi + 24]                        ; сравниваем с концом блока
2288 clevermous 709
        jb      .find_wanted_start
1398 turbanoff 710
 
1419 turbanoff 711
        push    .find_wanted_start
2889 turbanoff 712
   .end_block:                                              ;вылетели из цикла
3742 clevermous 713
        cmp     [esi + EXT2_INODE_STRUC.i_size], 0
2889 turbanoff 714
        jle     .end_dir
1398 turbanoff 715
 
2889 turbanoff 716
        inc     dword [edi]                                 ;получаем новый блок
1398 turbanoff 717
        push    ecx
2889 turbanoff 718
        mov     ecx, [edi]
1398 turbanoff 719
        call    ext2_get_inode_block
2889 turbanoff 720
        test    eax, eax
721
        jnz     .error_get_block
722
 
1398 turbanoff 723
        mov     eax, ecx
3742 clevermous 724
        mov     ebx, [ebp+EXTFS.ext2_save_block]
1398 turbanoff 725
        call    ext2_get_block
2889 turbanoff 726
        test    eax, eax
727
        jnz     .error_get_block
728
 
1398 turbanoff 729
        pop     ecx
3742 clevermous 730
        mov     eax, ebx
731
        add     eax, [ebp+EXTFS.block_size]
732
        mov     [edi + 24], eax                            ;запомним конец блока
2889 turbanoff 733
        ret                                                 ; опять в цикл
1398 turbanoff 734
 
1400 turbanoff 735
    .wanted_end:
2889 turbanoff 736
        loop    .find_wanted_cycle                          ; ecx 0 => -1 нужно посчитать сколько файлов
1400 turbanoff 737
 
2889 turbanoff 738
    ;дошли до первого "нужного" файла
1378 turbanoff 739
    .find_wanted_end:
2889 turbanoff 740
        mov     ecx, [edi + 20]
741
    .wanted_start:                                          ; ищем first_wanted+count
2288 clevermous 742
        jecxz   .wanted_end
3742 clevermous 743
        cmp     [ebx + EXT2_DIR_STRUC.inode], 0         ; if (inode = 0) => not used
2288 clevermous 744
        jz      .empty_rec
2889 turbanoff 745
        inc     dword [edi + 8]
746
        inc     dword [edi + 4]
1378 turbanoff 747
 
2889 turbanoff 748
        push    edi ecx
749
        mov     edi, edx                            ;обнуляем место под очереное имя файла/папки
2288 clevermous 750
        xor     eax, eax
751
        mov     ecx, 40 / 4
752
        rep stosd
2889 turbanoff 753
        pop     ecx edi
1378 turbanoff 754
 
3742 clevermous 755
        push    ebx edi edx
756
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]             ;получим дочерний inode
757
        mov     ebx, [ebp+EXTFS.ext2_temp_inode]
2288 clevermous 758
        call    ext2_get_inode
2889 turbanoff 759
        test    eax, eax
760
        jnz     .error_read_subinode
1400 turbanoff 761
 
2288 clevermous 762
        lea     edi, [edx + 8]
1400 turbanoff 763
 
2889 turbanoff 764
        mov     eax, [ebx + EXT2_INODE_STRUC.i_ctime]           ; переведем время в ntfs формат
2288 clevermous 765
        xor     edx, edx
766
        add     eax, 3054539008                                     ;(369 * 365 + 89) * 24 * 3600
767
        adc     edx, 2
768
        call    ntfs_datetime_to_bdfe.sec
1400 turbanoff 769
 
2288 clevermous 770
        mov     eax, [ebx + EXT2_INODE_STRUC.i_atime]
771
        xor     edx, edx
772
        add     eax, 3054539008
773
        adc     edx, 2
774
        call    ntfs_datetime_to_bdfe.sec
1400 turbanoff 775
 
2288 clevermous 776
        mov     eax, [ebx + EXT2_INODE_STRUC.i_mtime]
777
        xor     edx, edx
778
        add     eax, 3054539008
779
        adc     edx, 2
780
        call    ntfs_datetime_to_bdfe.sec
1400 turbanoff 781
 
2288 clevermous 782
        pop     edx                                                 ; пока достаем только буфер
2889 turbanoff 783
        test    [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR   ; для папки размер
2288 clevermous 784
        jnz     @F                                                  ; не возвращаем
1400 turbanoff 785
 
2889 turbanoff 786
        mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
2288 clevermous 787
        stosd
2889 turbanoff 788
        mov     eax, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
2288 clevermous 789
        stosd
2889 turbanoff 790
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл(2 раза xor)
791
    @@:
792
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл
1400 turbanoff 793
 
2889 turbanoff 794
        ;теперь скопируем имя, сконвертировав из UTF-8 в CP866
3742 clevermous 795
        push    ecx esi ;edi уже сохранен в стеке
796
        mov     esi, [esp+12]
2889 turbanoff 797
        movzx   ecx, [esi + EXT2_DIR_STRUC.name_len]
2288 clevermous 798
        lea     edi, [edx + 40]
2889 turbanoff 799
        lea     esi, [esi + EXT2_DIR_STRUC.name]
800
        call    utf8_to_cp866
2288 clevermous 801
        and     byte [edi], 0
3742 clevermous 802
        pop     esi ecx edi ebx
1378 turbanoff 803
 
2889 turbanoff 804
        cmp     byte [edx + 40], '.'                    ; в linux файл, начинающийся с точки - скрытый
2288 clevermous 805
        jne     @F
806
        or      dword [edx], FS_FT_HIDDEN
2889 turbanoff 807
    @@:
1400 turbanoff 808
 
2288 clevermous 809
        add     edx, 40 + 264                           ; go to next record
810
        dec     ecx                                     ; если запись пустая ecx не надо уменьшать
2889 turbanoff 811
    .empty_rec:
3742 clevermous 812
        movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
813
        cmp     eax, 12                                 ; минимальная длина записи
2889 turbanoff 814
        jb      .error_bad_len
3742 clevermous 815
        test    eax, 0x3                                ; длина записи должна делиться на 4
2889 turbanoff 816
        jnz     .error_bad_len
1419 turbanoff 817
 
3742 clevermous 818
        sub     [esi + EXT2_INODE_STRUC.i_size], eax    ;вычитаем напрямую из структуры inode
819
        add     ebx, eax
820
        cmp     ebx, [edi + 24]                         ;дошли ли до конца блока?
2288 clevermous 821
        jb      .wanted_start
1378 turbanoff 822
 
2889 turbanoff 823
        push    .wanted_start                           ; дошли
1400 turbanoff 824
        jmp     .end_block
1378 turbanoff 825
 
2889 turbanoff 826
    .end_dir:   ;конец папки, когда еще не дошли до нужного файла
3742 clevermous 827
        call    ext2_unlock
2889 turbanoff 828
        mov     edx, [edi + 28] ;адрес структуры результата
829
        mov     ebx, [edi + 8] ;EXT2_read_in_folder
830
        mov     ecx, [edi + 4] ;EXT2_files_in_folder
1378 turbanoff 831
        mov     dword [edx], 1    ;version
2889 turbanoff 832
        mov     [edx + 4], ebx
833
        mov     [edx + 8], ecx
834
 
835
        lea     esp, [edi + 32]
836
 
3691 yogev_ezra 837
        xor     eax, eax        ;RUS: зарезервировано: нули в текущей реализации
838
                                ;ENG: reserved: zeros in current implementation
1378 turbanoff 839
        lea     edi, [edx + 12]
840
        mov     ecx, 20 / 4
2288 clevermous 841
        rep stosd
1378 turbanoff 842
        ret
2889 turbanoff 843
 
844
    .error_bad_len:
845
        mov     eax, ERROR_FS_FAIL
846
    .error_read_subinode:
847
    .error_get_block:
848
        lea     esp, [edi + 32]
849
    .error_ret:
850
        or      ebx, -1
3742 clevermous 851
        push    eax
852
        call    ext2_unlock
853
        pop     eax
2889 turbanoff 854
        ret
855
 
3691 yogev_ezra 856
    .error_empty_dir:   ;RUS: inode папки без блоков   ;ENG: inode of folder without blocks
857
    .error_root:        ;RUS: root - не папка          ;ENG: root is not a folder
2889 turbanoff 858
        mov     eax, ERROR_FS_FAIL
859
        jmp     .error_ret
860
 
3691 yogev_ezra 861
    .error_not_found:   ;RUS: файл не найден           ;ENG: file not found
2889 turbanoff 862
        mov     eax, ERROR_FILE_NOT_FOUND
863
        jmp     .error_ret
864
 
865
;============================================
866
;convert UTF-8 string to ASCII-string (codepage 866)
867
;in:  ecx = length source
868
;     esi = source
869
;     edi = buffer
1397 turbanoff 870
; destroys: eax,esi,edi
2889 turbanoff 871
utf8_to_cp866:
1397 turbanoff 872
        jecxz   .ret
873
    .start:
874
        lodsw
2288 clevermous 875
        cmp     al, 0x80
1397 turbanoff 876
        jb      .ascii
1378 turbanoff 877
 
1400 turbanoff 878
        xchg    al, ah              ; big-endian
1397 turbanoff 879
        cmp     ax, 0xd080
880
        jz      .yo1
881
        cmp     ax, 0xd191
882
        jz      .yo2
883
        cmp     ax, 0xd090
2288 clevermous 884
        jb      .unk
885
        cmp     ax, 0xd180
886
        jb      .rus1
887
        cmp     ax, 0xd190
1397 turbanoff 888
        jb      .rus2
889
    .unk:
890
        mov     al, '_'
891
        jmp     .doit
892
    .yo1:
893
        mov     al, 0xf0    ; Ё capital
894
        jmp     .doit
895
    .yo2:
896
        mov     al, 0xf1    ; ё small
897
        jmp     .doit
898
    .rus1:
899
        sub     ax, 0xd090 - 0x80
900
        jmp     .doit
901
    .rus2:
902
        sub     ax, 0xd18f - 0xEF
903
    .doit:
904
        stosb
905
        sub     ecx, 2
906
        ja      .start
907
        ret
908
 
909
    .ascii:
910
        stosb
911
        dec     esi
912
        dec     ecx
913
        jnz     .start
914
    .ret:
915
        ret
916
 
2288 clevermous 917
;----------------------------------------------------------------
3742 clevermous 918
; ext2_Read - EXT2FS implementation of reading a file
919
; in:  ebp = pointer to FAT structure
920
; in:  esi+[esp+4] = name
921
; in:  ebx = pointer to parameters from sysfunc 70
922
; out: eax, ebx = return values for sysfunc 70
923
;----------------------------------------------------------------
924
ext2_Read:
925
        call    ext2_lock
1378 turbanoff 926
        cmp     byte [esi], 0
1397 turbanoff 927
        jnz     @F
1378 turbanoff 928
 
1384 turbanoff 929
    .this_is_nofile:
3742 clevermous 930
        call    ext2_unlock
1378 turbanoff 931
        or      ebx, -1
932
        mov     eax, ERROR_ACCESS_DENIED
933
        ret
934
 
1397 turbanoff 935
    @@:
3742 clevermous 936
        push    ebx
937
        stdcall ext2_find_lfn, [esp+4+4]
938
        pop     ebx
2889 turbanoff 939
        test    eax, eax
940
        jz      @F
941
 
3742 clevermous 942
        call    ext2_unlock
1397 turbanoff 943
        or      ebx, -1
944
        mov     eax, ERROR_FILE_NOT_FOUND
945
        ret
946
 
2889 turbanoff 947
    @@:
3742 clevermous 948
        mov     ax, [esi + EXT2_INODE_STRUC.i_mode]
2973 turbanoff 949
        and     ax, EXT2_S_IFMT     ;оставляем только тип inode в ax
950
        cmp     ax, EXT2_S_IFREG
951
        jne     .this_is_nofile
1397 turbanoff 952
 
3742 clevermous 953
        mov     edi, [ebx+16]       ; edi = pointer to return mem
954
        mov     ecx, [ebx+12]
2889 turbanoff 955
 
3742 clevermous 956
        mov     eax, [ebx+4]
957
        mov     edx, [ebx+8] ;RUS: edx : eax - стартовый номер байта   ;ENG: edx : eax - start byte number
1378 turbanoff 958
 
3691 yogev_ezra 959
        ;RUS: ///// сравним хватит ли нам файла или нет    ;ENG: ///// check if file is big enough for us
3742 clevermous 960
        cmp     [esi + EXT2_INODE_STRUC.i_dir_acl], edx
1378 turbanoff 961
        ja      .size_great
962
        jb      .size_less
963
 
3742 clevermous 964
        cmp     [esi + EXT2_INODE_STRUC.i_size], eax
1378 turbanoff 965
        ja      .size_great
966
 
967
    .size_less:
3742 clevermous 968
        call    ext2_unlock
1397 turbanoff 969
        xor     ebx, ebx
1419 turbanoff 970
        mov     eax, ERROR_END_OF_FILE
1378 turbanoff 971
        ret
2889 turbanoff 972
 
1378 turbanoff 973
    .size_great:
3691 yogev_ezra 974
        add     eax, ecx    ;RUS: add to first_wanted кол-во байт для чтения
975
                            ;ENG: add to first_wanted number of bytes to read
3742 clevermous 976
        adc     edx, 0
1397 turbanoff 977
 
3742 clevermous 978
        cmp     [esi + EXT2_INODE_STRUC.i_dir_acl], edx
1378 turbanoff 979
        ja      .size_great_great
980
        jb      .size_great_less
3742 clevermous 981
        cmp     [esi + EXT2_INODE_STRUC.i_size], eax
3691 yogev_ezra 982
        jae     .size_great_great   ; and if it's equal, no matter where we jump
1397 turbanoff 983
 
1378 turbanoff 984
    .size_great_less:
3691 yogev_ezra 985
        push    1            ;RUS: читаем по границе размера   ;ENG: reading till the end of file
3742 clevermous 986
        mov     ecx, [esi + EXT2_INODE_STRUC.i_size]
987
        sub     ecx, [ebx+4] ;RUS: (размер - старт) = сколько читать   ;ENG: to read = (size - start)
1378 turbanoff 988
        jmp     @F
989
 
990
    .size_great_great:
3691 yogev_ezra 991
        push    0            ;RUS: читаем столько, сколько запросили   ;ENG: reading as much as requested
1378 turbanoff 992
 
993
    @@:
2889 turbanoff 994
        ;здесь мы точно знаем сколько байт читать - ecx
995
        ;edi - return memory
996
        ;esi -> first wanted
997
 
998
        push    ecx                             ;количество считанных байт
1378 turbanoff 999
 
2889 turbanoff 1000
        ;получим кусок из первого блока
3742 clevermous 1001
        mov     edx, [ebx+8]
1002
        mov     eax, [ebx+4]
1003
        div     [ebp+EXTFS.block_size]
1378 turbanoff 1004
 
3313 turbanoff 1005
        push    eax       ;счетчик блоков ложим в стек
2889 turbanoff 1006
 
1378 turbanoff 1007
        push    ecx
1008
        mov     ecx, eax
1009
        call    ext2_get_inode_block
2889 turbanoff 1010
        test    eax, eax
1011
        jnz     .error_at_first_block
3742 clevermous 1012
        mov     ebx, [ebp+EXTFS.ext2_save_block]
1378 turbanoff 1013
        mov     eax, ecx
1014
        call    ext2_get_block
2889 turbanoff 1015
        test    eax, eax
1016
        jnz     .error_at_first_block
1378 turbanoff 1017
        pop     ecx
1018
        add     ebx, edx
1019
 
1020
        neg     edx
3742 clevermous 1021
        add     edx, [ebp+EXTFS.block_size]     ;RUS: block_size - стартовый байт = сколько байт 1-го блока
3691 yogev_ezra 1022
                                                ;ENG: block_size - start byte = number of bytes in 1st block
1378 turbanoff 1023
        cmp     ecx, edx
1024
        jbe     .only_one_block
1025
 
1026
        mov     eax, ecx
1027
        sub     eax, edx
1028
        mov     ecx, edx
1029
 
3742 clevermous 1030
        push    esi
1378 turbanoff 1031
        mov     esi, ebx
3691 yogev_ezra 1032
        rep movsb                               ;RUS: кусок 1-го блока   ;ENG: part of 1st block
3742 clevermous 1033
        pop     esi
1378 turbanoff 1034
 
1035
        ;теперь в eax кол-во оставшихся байт для чтения
2889 turbanoff 1036
    .calc_blocks_count:
1397 turbanoff 1037
        mov     ebx, edi                        ;чтение блока прям в ->ebx
1378 turbanoff 1038
        xor     edx, edx
3742 clevermous 1039
        div     [ebp+EXTFS.block_size]       ;кол-во байт в последнем блоке (остаток) в edx
1397 turbanoff 1040
        mov     edi, eax                        ;кол-во целых блоков в edi
1378 turbanoff 1041
    @@:
2288 clevermous 1042
        test    edi, edi
1378 turbanoff 1043
        jz      .finish_block
2889 turbanoff 1044
        inc     dword [esp]
1045
        mov     ecx, [esp]
1378 turbanoff 1046
        call    ext2_get_inode_block
2889 turbanoff 1047
        test    eax, eax
1048
        jnz     .error_at_read_cycle
1378 turbanoff 1049
 
1397 turbanoff 1050
        mov     eax, ecx                        ;а ebx уже забит нужным значением
1378 turbanoff 1051
        call    ext2_get_block
2889 turbanoff 1052
        test    eax, eax
1053
        jnz     .error_at_read_cycle
3742 clevermous 1054
        add     ebx, [ebp+EXTFS.block_size]
1378 turbanoff 1055
 
1397 turbanoff 1056
        dec     edi
1378 turbanoff 1057
        jmp     @B
1058
 
1059
    .finish_block:          ;в edx - кол-во байт в последнем блоке
1397 turbanoff 1060
        test    edx, edx
1061
        jz      .end_read
1378 turbanoff 1062
 
2889 turbanoff 1063
        pop     ecx         ;счетчик блоков -> ecx
1378 turbanoff 1064
        inc     ecx
1065
        call    ext2_get_inode_block
2889 turbanoff 1066
        test    eax, eax
3317 turbanoff 1067
        jnz     .error_at_finish_block
1378 turbanoff 1068
 
1069
        mov     edi, ebx
1070
        mov     eax, ecx
3742 clevermous 1071
        mov     ebx, [ebp+EXTFS.ext2_save_block]
1378 turbanoff 1072
        call    ext2_get_block
2889 turbanoff 1073
        test    eax, eax
1074
        jnz     .error_at_finish_block
1378 turbanoff 1075
 
3711 clevermous 1076
        mov     ecx, edx
1378 turbanoff 1077
        mov     esi, ebx
2288 clevermous 1078
        rep movsb                               ;кусок last блока
3313 turbanoff 1079
        jmp     @F
1080
 
1389 turbanoff 1081
    .end_read:
3313 turbanoff 1082
        pop     ecx                             ;счетчик блоков, который хранился в стеке
1083
    @@:
1084
        pop     ebx                             ;количество считанных байт
3742 clevermous 1085
        call    ext2_unlock
3313 turbanoff 1086
        pop     eax                             ; 1 или 0 - достигли ли конца файла
2889 turbanoff 1087
        test    eax, eax
1378 turbanoff 1088
        jz      @F
1089
 
1419 turbanoff 1090
        mov     eax, ERROR_END_OF_FILE
1378 turbanoff 1091
        ret
1092
    @@:
1093
        xor     eax, eax
1094
        ret
2889 turbanoff 1095
 
1096
    .only_one_block:
1097
        mov     esi, ebx
1098
        rep movsb                               ;кусок last блока
1099
        jmp     .end_read
1100
 
1101
   .error_at_first_block:
1102
        pop     edx
1103
   .error_at_read_cycle:
3711 clevermous 1104
        pop     ebx
2889 turbanoff 1105
   .error_at_finish_block:
1106
        pop     ecx edx
1107
        or      ebx, -1
3742 clevermous 1108
        push    eax
1109
        call    ext2_unlock
1110
        pop     eax
2889 turbanoff 1111
        ret
1112
 
1113
;----------------------------------------------------------------
1114
; in:  esi = file path
1115
;      ebx = pointer to dir block
3742 clevermous 1116
;      ebp = pointer to EXTFS structure
2889 turbanoff 1117
; out: esi - name without parent or not_changed
1118
;      ebx - dir_rec of inode children
1119
ext2_test_block_by_name:
1120
        sub     esp, 256        ;EXT2_filename
1121
        mov     edx, ebx
3742 clevermous 1122
        add     edx, [ebp+EXTFS.block_size]   ;RUS: запомним конец блока   ;ENG: save block end
2889 turbanoff 1123
 
1124
    .start_rec:
1125
        cmp     [ebx + EXT2_DIR_STRUC.inode], 0
1126
        jz      .next_rec
1127
 
1128
        mov     edi, esp
1129
        push    esi
1130
        movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
1131
        lea     esi, [ebx + EXT2_DIR_STRUC.name]
1132
        call    utf8_to_cp866
1133
 
1134
        mov     ecx, edi
1135
        lea     edi, [esp + 4]
3691 yogev_ezra 1136
        sub     ecx, edi   ;RUS: кол-во байт в получившейся строке   ;ENG: number of bytes in resulting string
2889 turbanoff 1137
 
1138
        mov     esi, [esp]
1139
    @@:
1140
        jecxz   .test_find
1141
        dec     ecx
1142
 
1143
        lodsb
1144
        call    char_toupper
1145
 
1146
        mov     ah, [edi]
1147
        inc     edi
1148
        xchg    al, ah
1149
        call    char_toupper
1150
        cmp     al, ah
1151
        je      @B
3691 yogev_ezra 1152
    @@:                           ;RUS: не подошло   ;ENG: didn't fit
2889 turbanoff 1153
        pop     esi
1154
    .next_rec:
1155
        movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
3691 yogev_ezra 1156
        add     ebx, eax          ;RUS: к след. записи      ;ENG: go to next record
1157
        cmp     ebx, edx          ;RUS: проверим конец ли   ;ENG: check if this is the end
2889 turbanoff 1158
        jb      .start_rec
1159
        add     esp, 256
1160
        ret
1161
 
1162
    .test_find:
1163
        cmp     byte [esi], 0
3691 yogev_ezra 1164
        je      .ret              ;RUS: нашли конец         ;ENG: the end reached
2889 turbanoff 1165
        cmp     byte [esi], '/'
1166
        jne     @B
1167
        inc     esi
1168
    .ret:
1169
        add     esp, 256 + 4
1170
        ret
1171
 
1378 turbanoff 1172
;========================
2889 turbanoff 1173
;Ищет inode по строке пути
3742 clevermous 1174
;in:  esi+[esp+4] = name
1175
;     ebp = pointer to EXTFS
2889 turbanoff 1176
;out: eax - error code
3742 clevermous 1177
;     esi = inode
2889 turbanoff 1178
;      dl - первый байт из имени файла/папки
1384 turbanoff 1179
ext2_find_lfn:
3742 clevermous 1180
        mov     edx, [ebp+EXTFS.root_inode]
1181
        cmp     [edx + EXT2_INODE_STRUC.i_blocks], 0
2889 turbanoff 1182
        je      .error_empty_root
1183
 
1184
    .next_path_part:
3742 clevermous 1185
        push    [edx + EXT2_INODE_STRUC.i_blocks]
2889 turbanoff 1186
        xor     ecx, ecx
1187
    .folder_block_cycle:
3403 turbanoff 1188
        push    ecx
3742 clevermous 1189
        xchg    esi, edx
1384 turbanoff 1190
        call    ext2_get_inode_block
3742 clevermous 1191
        xchg    esi, edx
2889 turbanoff 1192
        test    eax, eax
1193
        jnz     .error_get_inode_block
1194
 
1384 turbanoff 1195
        mov     eax, ecx
3742 clevermous 1196
        mov     ebx, [ebp+EXTFS.ext2_save_block]        ;ebx = cur dir record
1384 turbanoff 1197
        call    ext2_get_block
2889 turbanoff 1198
        test    eax, eax
1199
        jnz     .error_get_block
1200
 
1201
        push    esi
3742 clevermous 1202
        push    edx
1384 turbanoff 1203
        call    ext2_test_block_by_name
3742 clevermous 1204
        pop     edx
3403 turbanoff 1205
        pop     edi ecx
1384 turbanoff 1206
 
3691 yogev_ezra 1207
        cmp     edi, esi             ;RUS: нашли имя?   ;ENG: did we find a name?
1208
        je      .next_folder_block   ;RUS: не нашли -> к след. блоку   ;ENG: we didn't -> moving to next block
2889 turbanoff 1209
 
3691 yogev_ezra 1210
        cmp     byte [esi], 0   ;RUS: дошли до "конца" пути -> возваращаемся
1211
                                ;ENG: reached the "end" of path -> returning
3742 clevermous 1212
        jnz     @f
1213
        cmp     dword [esp+8], 0
1384 turbanoff 1214
        jz      .get_inode_ret
3742 clevermous 1215
        mov     esi, [esp+8]
1216
        mov     dword [esp+8], 0
1217
    @@:
1384 turbanoff 1218
 
3691 yogev_ezra 1219
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;RUS: нашли, но это не папка
1220
        jne     .not_found                                      ;ENG: found, but it's not a folder
2889 turbanoff 1221
 
1384 turbanoff 1222
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
3742 clevermous 1223
        mov     ebx, [ebp+EXTFS.ext2_save_inode]   ;RUS: все же папка.   ;ENG: it's a folder afterall
1384 turbanoff 1224
        call    ext2_get_inode
2889 turbanoff 1225
        test    eax, eax
1226
        jnz     .error_get_inode
3691 yogev_ezra 1227
        pop     ecx   ;RUS: в стеке лежит кол-во блоков   ;ENG: stack top contains number of blocks
3742 clevermous 1228
        mov     edx, ebx
2889 turbanoff 1229
        jmp     .next_path_part
1230
 
1231
    .next_folder_block:
1232
        ;к следующему блоку в текущей папке
3691 yogev_ezra 1233
        pop     eax                ;RUS: счетчик блоков   ;ENG: blocks counter
3742 clevermous 1234
        sub     eax, [ebp+EXTFS.count_block_in_block]
2889 turbanoff 1235
        jle     .not_found
1236
 
3316 turbanoff 1237
        push    eax
2889 turbanoff 1238
        inc     ecx
1239
        jmp     .folder_block_cycle
1384 turbanoff 1240
 
1241
    .not_found:
2889 turbanoff 1242
        mov     eax, ERROR_FILE_NOT_FOUND
3742 clevermous 1243
        ret     4
2889 turbanoff 1244
 
1384 turbanoff 1245
    .get_inode_ret:
3691 yogev_ezra 1246
        pop     ecx   ;RUS: в стеке лежит кол-во блоков   ;ENG: stack top contains number of blocks
1247
        mov     dl, [ebx + EXT2_DIR_STRUC.name]   ;RUS: в dl - первый символ ()   ;ENG: ???
1384 turbanoff 1248
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
3742 clevermous 1249
        mov     ebx, [ebp+EXTFS.ext2_save_inode]
1384 turbanoff 1250
        call    ext2_get_inode
3742 clevermous 1251
        mov     esi, ebx
2889 turbanoff 1252
        xor     eax, eax
3742 clevermous 1253
        ret     4
1384 turbanoff 1254
 
2889 turbanoff 1255
    .error_get_inode_block:
1256
    .error_get_block:
3403 turbanoff 1257
        pop     ecx
2889 turbanoff 1258
    .error_get_inode:
1259
        pop     ebx
1260
    .error_empty_root:
1261
        mov     eax, ERROR_FS_FAIL
3742 clevermous 1262
        ret     4
1384 turbanoff 1263
 
2889 turbanoff 1264
;----------------------------------------------------------------
3742 clevermous 1265
; ext2_GetFileInfo - EXT2 implementation of getting file info
1266
; in:  ebp = pointer to EXTFS structure
1267
; in:  esi+[esp+4] = name
1268
; in:  ebx = pointer to parameters from sysfunc 70
1269
; out: eax, ebx = return values for sysfunc 70
1270
;----------------------------------------------------------------
1271
ext2_GetFileInfo:
1272
        call    ext2_lock
1273
        mov     edx, [ebx+16]
1384 turbanoff 1274
        cmp     byte [esi], 0
2889 turbanoff 1275
        jz      .is_root
1384 turbanoff 1276
 
2889 turbanoff 1277
        push    edx
3742 clevermous 1278
        stdcall ext2_find_lfn, [esp+4+4]
2889 turbanoff 1279
        mov     ebx, edx
1280
        pop     edx
1281
        test    eax, eax
1282
        jz      @F
3742 clevermous 1283
        push    eax
1284
        call    ext2_unlock
1285
        pop     eax
1378 turbanoff 1286
        ret
1384 turbanoff 1287
 
2889 turbanoff 1288
    .is_root:
3691 yogev_ezra 1289
        xor     ebx, ebx      ;RUS: root не может быть скрытым   ;ENG: root cannot be hidden
3742 clevermous 1290
        mov     esi, [ebp+EXTFS.root_inode]
1400 turbanoff 1291
    @@:
1384 turbanoff 1292
        xor     eax, eax
1293
        mov     edi, edx
1294
        mov     ecx, 40/4
2288 clevermous 1295
        rep stosd                   ; fill zero
1384 turbanoff 1296
 
2889 turbanoff 1297
        cmp     bl, '.'
1298
        jne     @F
1400 turbanoff 1299
        or      dword [edx], FS_FT_HIDDEN
1300
    @@:
1301
 
3742 clevermous 1302
        test    [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
2288 clevermous 1303
        jnz     @F
3742 clevermous 1304
        mov     eax, [esi + EXT2_INODE_STRUC.i_size]            ;low size
1305
        mov     ebx, [esi + EXT2_INODE_STRUC.i_dir_acl]         ;high size
1384 turbanoff 1306
        mov     dword [edx+32], eax
1307
        mov     dword [edx+36], ebx
1400 turbanoff 1308
        xor     dword [edx], FS_FT_DIR
1309
    @@:
1310
        xor     dword [edx], FS_FT_DIR
1384 turbanoff 1311
 
1400 turbanoff 1312
        lea     edi, [edx + 8]
3742 clevermous 1313
        mov     eax, [esi + EXT2_INODE_STRUC.i_ctime]
1400 turbanoff 1314
        xor     edx, edx
1315
        add     eax, 3054539008
1316
        adc     edx, 2
1317
        call    ntfs_datetime_to_bdfe.sec
1318
 
3742 clevermous 1319
        mov     eax, [esi + EXT2_INODE_STRUC.i_atime]
1400 turbanoff 1320
        xor     edx, edx
1321
        add     eax, 3054539008
1322
        adc     edx, 2
1323
        call    ntfs_datetime_to_bdfe.sec
1324
 
3742 clevermous 1325
        mov     eax, [esi + EXT2_INODE_STRUC.i_mtime]
1400 turbanoff 1326
        xor     edx, edx
1327
        add     eax, 3054539008
1328
        adc     edx, 2
1329
        call    ntfs_datetime_to_bdfe.sec
1330
 
3742 clevermous 1331
        call    ext2_unlock
1384 turbanoff 1332
        xor     eax, eax
1333
        ret
1334
 
3742 clevermous 1335
ext2_Rewrite:
1336
ext2_Write:
1337
ext2_SetFileEnd:
1338
ext2_SetFileInfo:
1339
ext2_Delete:
1340
ext2_CreateFolder:
1378 turbanoff 1341
        xor     ebx, ebx
1342
        mov     eax, ERROR_UNSUPPORTED_FS
1343
        ret