Subversion Repositories Kolibri OS

Rev

Rev 3316 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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