Subversion Repositories Kolibri OS

Rev

Rev 2465 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2465 Rev 2987
Line 6... Line 6...
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 10... Line 10...
10
 
10
 
Line 11... Line 11...
11
$Revision: 2465 $
11
$Revision: 2987 $
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
Line 17... Line 17...
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
;type inode
-
 
21
EXT2_S_IFREG        = 0x8000
-
 
22
EXT2_S_IFDIR        = 0x4000
-
 
23
;user inode right's
-
 
24
EXT2_S_IRUSR        = 0x0100
-
 
25
EXT2_S_IWUSR        = 0x0080
-
 
26
EXT2_S_IXUSR        = 0x0040
-
 
27
;group inode right's
-
 
28
EXT2_S_IRGRP        = 0x0020
-
 
29
EXT2_S_IWGRP        = 0x0010
-
 
30
EXT2_S_IXGRP        = 0x0008
-
 
31
;other inode right's
-
 
32
EXT2_S_IROTH        = 0x0004
20
;флаги, указываемый в inode файла
33
EXT2_S_IWOTH        = 0x0002
-
 
34
EXT2_S_IXOTH        = 0x0001
-
 
Line -... Line 21...
-
 
21
EXT2_S_IFREG        = 0x8000
35
EXT2_777_MODE       = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \
22
EXT2_S_IFDIR        = 0x4000
36
                      EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \
23
EXT2_S_IFMT          = 0xF000 ;маска для типа файла
Line -... Line 24...
-
 
24
 
37
                      EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR
25
;флаги, указываемые в linked list родительской папки
38
 
26
EXT2_FT_REG_FILE        = 1     ;это файл, запись в родительском каталоге
39
EXT2_FT_REG_FILE        = 1     ;это файл, запись в родительском каталоге
27
EXT2_FT_DIR             = 2     ;это папка
40
EXT2_FT_DIR             = 2     ;это папка
28
 
Line -... Line 29...
-
 
29
;флаги используемые KolibriOS
41
 
30
FS_FT_HIDDEN            = 2
-
 
31
FS_FT_DIR               = 0x10  ;это папка
-
 
32
FS_FT_ASCII             = 0     ;имя в ascii
-
 
33
FS_FT_UNICODE           = 1     ;имя в unicode
-
 
34
 
-
 
35
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;тип файла должен указываться в директории
Line 42... Line 36...
42
FS_FT_HIDDEN            = 2
36
EXT4_FEATURE_INCOMPAT_EXTENTS  = 0x0040 ;экстенты
43
FS_FT_DIR               = 0x10  ;это папка
37
EXT4_FEATURE_INCOMPAT_FLEX_BG  = 0x0200 ;гибкие группы блоков
44
FS_FT_ASCII             = 0     ;имя в ascii
-
 
45
FS_FT_UNICODE           = 1     ;имя в unicode
-
 
46
 
-
 
47
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002
38
;реализованные ext[234] features
48
 
-
 
49
uglobal
-
 
50
    EXT2_files_in_folder    dd ?   ;всего файлов в папке
-
 
Line 51... Line 39...
51
    EXT2_read_in_folder     dd ?   ;сколько файлов "считали"
39
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
52
    EXT2_end_block          dd ?   ;конец очередного блока папки
40
                          or EXT4_FEATURE_INCOMPAT_EXTENTS \
53
    EXT2_counter_blocks     dd ?
41
                          or EXT4_FEATURE_INCOMPAT_FLEX_BG
54
    EXT2_filename           rb 256
42
 
Line 84... Line 72...
84
        file_type       db ?
72
        file_type       db ?
85
        name            db ? ; 0..255
73
        name            db ? ; 0..255
86
ends
74
ends
Line 87... Line 75...
87
 
75
 
88
struct  EXT2_BLOCK_GROUP_DESC
76
struct  EXT2_BLOCK_GROUP_DESC
89
        block_bitmap            dd ?
77
        block_bitmap            dd ? ;+0
90
        inode_bitmap            dd ?
78
        inode_bitmap            dd ? ;+4
91
        inode_table             dd ?
79
        inode_table             dd ? ;+8
92
        free_blocks_count       dw ?
80
        free_blocks_count       dw ? ;+12
93
        free_inodes_count       dw ?
81
        free_inodes_count       dw ? ;+14
-
 
82
        used_dirs_count         dw ? ;+16
-
 
83
        pad                     dw ? ;+18
94
        used_dirs_count         dw ?
84
        reserved                rb 12;+20
Line 95... Line 85...
95
ends
85
ends
96
 
86
 
97
struct  EXT2_SB_STRUC
87
struct  EXT2_SB_STRUC
Line 130... Line 120...
130
        volume_name             rb 16 ;+120
120
        volume_name             rb 16 ;+120
131
        last_mounted            rb 64 ;+136
121
        last_mounted            rb 64 ;+136
132
        algo_bitmap             dd ? ;+200
122
        algo_bitmap             dd ? ;+200
133
        prealloc_blocks         db ? ;+204
123
        prealloc_blocks         db ? ;+204
134
        preallock_dir_blocks    db ? ;+205
124
        preallock_dir_blocks    db ? ;+205
135
                                dw ? ;+206 alignment
125
        reserved_gdt_blocks     dw ? ;+206
136
        journal_uuid            rb 16 ;+208
126
        journal_uuid            rb 16 ;+208
137
        journal_inum            dd ? ;+224
127
        journal_inum            dd ? ;+224
138
        journal_dev             dd ? ;+228
128
        journal_dev             dd ? ;+228
139
        last_orphan             dd ? ;+232
129
        last_orphan             dd ? ;+232
140
        hash_seed               rd 4 ;+236
130
        hash_seed               rd 4 ;+236
141
        def_hash_version        db ? ;+252
131
        def_hash_version        db ? ;+252
142
                                rb 3 ;+253 reserved
132
                                rb 3 ;+253 reserved
143
        default_mount_options   dd ? ;+256
133
        default_mount_options   dd ? ;+256
144
        first_meta_bg           dd ? ;+260
134
        first_meta_bg           dd ? ;+260
-
 
135
        mkfs_time               dd ? ;+264
-
 
136
        jnl_blocks              rd 17 ;+268
-
 
137
        blocks_count_hi         dd ? ;+336
-
 
138
        r_blocks_count_hi       dd ? ;+340
-
 
139
        free_blocks_count_hi    dd ? ;+344
-
 
140
        min_extra_isize         dw ? ;+348
-
 
141
        want_extra_isize        dw ? ;+350
-
 
142
        flags                   dd ? ;+352
-
 
143
        raid_stride             dw ? ;+356
-
 
144
        mmp_interval            dw ? ;+358
-
 
145
        mmp_block               dq ? ;+360
-
 
146
        raid_stripe_width       dd ? ;+368
-
 
147
        log_groups_per_flex     db ? ;+372
-
 
148
ends
-
 
149
 
-
 
150
struct EXT4_EXTENT_HEADER       ;заголовок блока экстентов/индексов
-
 
151
        eh_magic        dw ?    ;в текущей реализации ext4 должно быть 0xF30A
-
 
152
        eh_entries      dw ?    ;количество экстентов/индексов в блоке
-
 
153
        eh_max          dw ?    ;max количество (используется при записи)
-
 
154
        eh_depth        dw ?    ;глубина дерева (0, если это блок экстентов)
-
 
155
        eh_generation   dd ?    ;???
-
 
156
ends
-
 
157
 
-
 
158
struct EXT4_EXTENT              ;экстент
-
 
159
        ee_block        dd ?    ;номер ext4 блока
-
 
160
        ee_len          dw ?    ;длина экстента
-
 
161
        ee_start_hi     dw ?    ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
-
 
162
        ee_start_lo     dd ?    ;младшие 32 бита 48-битного адреса
-
 
163
ends
-
 
164
 
-
 
165
struct EXT4_EXTENT_IDX          ;индес - указатель на блок с экстентами/индексами
-
 
166
        ei_block        dd ?    ;номер ext4 блока
-
 
167
        ei_leaf_lo      dd ?    ;младшие 32 бит 48-битного адреса
-
 
168
        ei_leaf_hi      dw ?    ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
-
 
169
        ei_unused       dw ?    ;зарезервировано
145
ends
170
ends
Line 146... Line 171...
146
 
171
 
147
ext2_test_superblock:
172
ext2_test_superblock:
148
        cmp     [fs_type], 0x83
173
        cmp     [fs_type], 0x83
Line 149... Line 174...
149
        jne     .no
174
        jne     .no
150
 
175
 
151
        mov     eax, [PARTITION_START]
176
        mov     eax, [PARTITION_START]
Line 152... Line 177...
152
        add     eax, 2                  ;superblock start at 1024b
177
        add     eax, 2                  ;superblock start at 1024b
153
        call    hd_read
178
        call    hd_read
154
 
179
 
155
        cmp     dword [ebx+24], 3       ;s_block_size 0,1,2,3
180
        cmp     [ebx + EXT2_SB_STRUC.log_block_size], 3  ;0,1,2,3
156
        ja      .no
181
        ja      .no
157
        cmp     word [ebx+56], 0xEF53   ;s_magic
182
        cmp     [ebx + EXT2_SB_STRUC.magic], 0xEF53
-
 
183
        jne     .no
158
        jne     .no
184
        cmp     [ebx + EXT2_SB_STRUC.state], 1        ;EXT_VALID_FS=1
-
 
185
        jne     .no
-
 
186
        cmp     [ebx + EXT2_SB_STRUC.inodes_per_group], 0
159
        cmp     word [ebx+58], 1        ;s_state (EXT_VALID_FS=1)
187
        je      .no
160
        jne     .no
188
        
161
        mov     eax, [ebx+96]
189
        mov     eax, [ebx + EXT2_SB_STRUC.feature_incompat]
162
        test    eax, EXT2_FEATURE_INCOMPAT_FILETYPE
190
        test    eax, EXT2_FEATURE_INCOMPAT_FILETYPE
Line 163... Line 191...
163
        jz      .no
191
        jz      .no
164
        test    eax, not EXT2_FEATURE_INCOMPAT_FILETYPE
192
        test    eax, not EXT4_FEATURE_INCOMPAT_SUPP
165
        jnz     .no
193
        jnz     .no
Line 190... Line 218...
190
        xor     edx, edx
218
        xor     edx, edx
191
        div     [ebx + EXT2_SB_STRUC.blocks_per_group]
219
        div     [ebx + EXT2_SB_STRUC.blocks_per_group]
192
        inc     eax
220
        inc     eax
193
        mov     [ext2_data.groups_count], eax
221
        mov     [ext2_data.groups_count], eax
Line 194... Line 222...
194
 
222
 
195
        mov     ecx, [ebx+24]
223
        mov     ecx, [ebx + EXT2_SB_STRUC.log_block_size]
196
        inc     ecx
224
        inc     ecx
Line 197... Line 225...
197
        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
198
 
226
 
Line 216... Line 244...
216
        call    kernel_alloc
244
        call    kernel_alloc
217
        mov     [ext2_data.ext2_save_block], eax        ; and for temp block
245
        mov     [ext2_data.ext2_save_block], eax        ; and for temp block
218
        call    kernel_alloc
246
        call    kernel_alloc
219
        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
Line 220... Line 248...
220
 
248
 
221
        movzx   ebp, word [ebx+88]
249
        movzx   ebp, word [ebx + EXT2_SB_STRUC.inode_size]
222
        mov     ecx, [ebx+32]
-
 
Line 223... Line 250...
223
        mov     edx, [ebx+40]
250
        mov     ecx, [ebx + EXT2_SB_STRUC.blocks_per_group]
224
 
251
 
225
        mov     [ext2_data.inode_size], ebp
-
 
Line 226... Line 252...
226
        mov     [ext2_data.blocks_per_group], ecx
252
        mov     [ext2_data.inode_size], ebp
227
        mov     [ext2_data.inodes_per_group], edx
253
        mov     [ext2_data.blocks_per_group], ecx
228
 
254
 
229
        push    ebp ebp ebp                             ;3 kernel_alloc
255
        push    ebp ebp ebp                             ;3 kernel_alloc
Line 239... Line 265...
239
        call    ext2_get_inode                          ; read root inode
265
        call    ext2_get_inode                          ; read root inode
Line 240... Line 266...
240
 
266
 
Line 241... Line 267...
241
        jmp     return_from_part_set
267
        jmp     return_from_part_set
-
 
268
 
242
 
269
;==================================================================
243
;==================================================================
270
;read ext2 block form FS to memory
-
 
271
;in:  eax = i_block (address of block in ext2 terms)
244
;in: eax = i_block
272
;    ebx = pointer to return memory
245
;    ebx = pointer to return memory
273
;out: eax - error code (0 = no_error)
246
ext2_get_block:
274
ext2_get_block:
247
        push    eax ebx ecx
275
        push    ebx ecx
248
        mov     ecx, [ext2_data.log_block_size]
276
        mov     ecx, [ext2_data.log_block_size]
249
        shl     eax, cl
277
        shl     eax, cl
250
        add     eax, [PARTITION_START]
278
        add     eax, [PARTITION_START]
251
        mov     ecx, [ext2_data.count_block_in_block]
279
        mov     ecx, [ext2_data.count_block_in_block]
-
 
280
    @@:
-
 
281
        call    hd_read
252
    @@:
282
        cmp     [hd_error], 0
253
        call    hd_read
283
        jnz     .fail
254
        inc     eax
284
        inc     eax
-
 
285
        add     ebx, 512
-
 
286
        loop    @B
255
        add     ebx, 512
287
        xor     eax, eax
-
 
288
    @@:
-
 
289
        pop     ecx ebx
-
 
290
        ret
-
 
291
    .fail:
-
 
292
        mov     eax, ERROR_DEVICE
-
 
293
        jmp     @B
-
 
294
        
-
 
295
 
-
 
296
;===================================================================
-
 
297
;получает номер блока из extent inode
-
 
298
;in:  ecx = номер блока по порядку
-
 
299
;     ebp = адрес extent header`а
-
 
300
;out: ecx - адрес очередного блока в случае успеха
-
 
301
;     eax - номер ошибки (если равно 0, то ошибки нет)
-
 
302
ext4_block_recursive_search:
-
 
303
        cmp     word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
-
 
304
        jne     .fail
-
 
305
        
-
 
306
        movzx   ebx, [ebp + EXT4_EXTENT_HEADER.eh_entries]
-
 
307
        add     ebp, sizeof.EXT4_EXTENT_HEADER
-
 
308
        cmp     word [ebp - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0
-
 
309
        je      .leaf_block     ;листовой ли это блок?
-
 
310
        
-
 
311
        ;не листовой блок, а индексный ; eax - ext4_extent_idx
-
 
312
        test    ebx, ebx
-
 
313
        jz      .fail               ;пустой индексный блок -> ошибка
-
 
314
 
-
 
315
        ;цикл по индексам экстентов
-
 
316
    @@:
-
 
317
        cmp     ebx, 1              ;у индексов не хранится длина, 
-
 
318
        je      .end_search_index   ;поэтому, если остался последний - то это нужный
-
 
319
        
-
 
320
        cmp     ecx, [ebp + EXT4_EXTENT_IDX.ei_block]
-
 
321
        jb      .fail
-
 
322
        
-
 
323
        cmp     ecx, [ebp + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса
-
 
324
        jb      .end_search_index ;следующий дальше - значит текущий, то что нам нужен
-
 
325
        
-
 
326
        add     ebp, sizeof.EXT4_EXTENT_IDX
-
 
327
        dec     ebx
-
 
328
        jmp     @B
-
 
329
        
-
 
330
    .end_search_index:
-
 
331
        ;ebp указывает на нужный extent_idx, считываем следующий блок
-
 
332
        mov     ebx, [ext2_data.ext2_temp_block]
-
 
333
        mov     eax, [ebp + EXT4_EXTENT_IDX.ei_leaf_lo]
-
 
334
        call    ext2_get_block
-
 
335
        test    eax, eax
-
 
336
        jnz     .fail
-
 
337
        mov     ebp, ebx
-
 
338
        jmp     ext4_block_recursive_search ;рекурсивно прыгаем в начало
-
 
339
        
-
 
340
    .leaf_block:    ;листовой блок ebp - ext4_extent
-
 
341
        ;цикл по экстентам
-
 
342
    @@: 
-
 
343
        test    ebx, ebx
-
 
344
        jz      .fail       ;ни один узел не подошел - ошибка
-
 
345
 
-
 
346
        mov     edx, [ebp + EXT4_EXTENT.ee_block]
-
 
347
        cmp     ecx, edx
-
 
348
        jb      .fail       ;если меньше, значит он был в предыдущих блоках -> ошибка
-
 
349
 
-
 
350
        movzx   edi, [ebp + EXT4_EXTENT.ee_len]
-
 
351
        add     edx, edi
-
 
352
        cmp     ecx, edx
-
 
353
        jb      .end_search_extent     ;нашли нужный блок
-
 
354
        
-
 
355
        add     ebp, sizeof.EXT4_EXTENT
-
 
356
        dec     ebx
-
 
357
        jmp     @B
-
 
358
        
-
 
359
    .end_search_extent:
-
 
360
        mov     edx, [ebp + EXT4_EXTENT.ee_start_lo]
-
 
361
        sub     ecx, [ebp + EXT4_EXTENT.ee_block] ;разница в ext4 блоках
256
        loop    @B
362
        add     ecx, edx
-
 
363
        xor     eax, eax
-
 
364
        ret
-
 
365
 
-
 
366
    .fail:
-
 
367
        mov     eax, ERROR_FS_FAIL
257
        pop     ecx ebx eax
368
        ret
-
 
369
 
258
        ret
370
;===================================================================
259
;===================================================================
371
;получает адрес ext2 блока из inode с определнным номером
260
; in:  ecx = номер блока в inode (0..)
372
;in:  ecx = номер блока в inode (0..)
-
 
373
;      ebp = адрес inode
261
;      ebp = адрес inode
374
;out: ecx = адрес очередного блока
-
 
375
;     eax - error code
-
 
376
ext2_get_inode_block:
-
 
377
        test    [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
-
 
378
        jz      @F
-
 
379
 
-
 
380
        pushad
-
 
381
        add     ebp, EXT2_INODE_STRUC.i_block             ;ebp - extent_header
-
 
382
        call    ext4_block_recursive_search
-
 
383
        mov     PUSHAD_ECX, ecx
-
 
384
        mov     PUSHAD_EAX, eax
-
 
385
        popad
-
 
386
        ret
262
; out: ecx = адрес очередного блока
387
 
263
ext2_get_inode_block:
388
    @@:
Line 264... Line 389...
264
        cmp     ecx, 12                                         ; 0..11 - direct block address
389
        cmp     ecx, 12                                         ; 0..11 - direct block address
265
        jb      .get_direct_block
390
        jb      .get_direct_block
266
 
391
 
Line 267... Line 392...
267
        sub     ecx, 12
392
        sub     ecx, 12
268
        cmp     ecx, [ext2_data.count_pointer_in_block]         ; 12.. - indirect block
393
        cmp     ecx, [ext2_data.count_pointer_in_block]         ; 12.. - indirect blocks
269
        jb      .get_indirect_block
394
        jb      .get_indirect_block
Line 270... Line 395...
270
 
395
 
271
        sub     ecx, [ext2_data.count_pointer_in_block]
396
        sub     ecx, [ext2_data.count_pointer_in_block]
272
        cmp     ecx, [ext2_data.count_pointer_in_block_square]
397
        cmp     ecx, [ext2_data.count_pointer_in_block_square]
Line 273... Line 398...
273
        jb      .get_double_indirect_block
398
        jb      .get_double_indirect_block
274
 
399
 
275
        sub     ecx, [ext2_data.count_pointer_in_block_square]
400
        sub     ecx, [ext2_data.count_pointer_in_block_square]
-
 
401
    ;triple indirect block
-
 
402
        push    edx ebx
Line 276... Line 403...
276
    ;.get_triple_indirect_block:
403
 
277
        push    eax edx ebx
404
        mov     eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
278
 
405
        mov     ebx, [ext2_data.ext2_temp_block]
Line 279... Line 406...
279
        mov     eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
406
        call    ext2_get_block
280
        mov     ebx, [ext2_data.ext2_temp_block]
407
        test    eax, eax
281
        call    ext2_get_block
408
        jnz     .fail
-
 
409
 
-
 
410
        xor     edx, edx
Line 282... Line 411...
282
 
411
        mov     eax, ecx
283
        xor     edx, edx
412
        div     [ext2_data.count_pointer_in_block_square]
Line 284... Line 413...
284
        mov     eax, ecx
413
 
285
        div     [ext2_data.count_pointer_in_block_square]
414
    ;eax - номер в полученном блоке   edx - номер дальше
Line 286... Line 415...
286
 
415
        mov     eax, [ebx + eax*4]
287
    ;eax - номер в полученном блоке   edx - номер дальше
416
        call    ext2_get_block
288
        mov     eax, [ebx + eax*4]
417
        test    eax, eax
-
 
418
        jnz     .fail
-
 
419
 
Line 289... Line 420...
289
        call    ext2_get_block
420
        mov     eax, edx
290
 
421
        jmp     @F
291
        mov     eax, edx
422
 
292
        jmp     @F
423
    .get_double_indirect_block:
Line 293... Line 424...
293
 
424
        push    edx ebx
294
    .get_double_indirect_block:
425
 
295
        push    eax edx ebx
426
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
-
 
427
        mov     ebx, [ext2_data.ext2_temp_block]
Line -... Line 428...
-
 
428
        call    ext2_get_block
-
 
429
        test    eax, eax
296
 
430
        jnz     .fail
297
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
431
 
Line 298... Line 432...
298
        mov     ebx, [ext2_data.ext2_temp_block]
432
        mov     eax, ecx
299
        call    ext2_get_block
433
      @@:
300
 
434
        xor     edx, edx
301
        mov     eax, ecx
435
        div     [ext2_data.count_pointer_in_block]
302
      @@:
436
 
-
 
437
        mov     eax, [ebx + eax*4]
-
 
438
        call    ext2_get_block
Line 303... Line 439...
303
        xor     edx, edx
439
        test    eax, eax
-
 
440
        jnz     .fail
304
        div     [ext2_data.count_pointer_in_block]
441
 
305
 
442
        mov     ecx, [ebx + edx*4]
Line 306... Line 443...
306
        mov     eax, [ebx + eax*4]
443
    .fail:
307
        call    ext2_get_block
444
        pop     ebx edx
-
 
445
        ret
308
        mov     ecx, [ebx + edx*4]
446
 
Line 309... Line 447...
309
 
447
    .get_indirect_block:
310
        pop     ebx edx eax
448
        push    ebx
311
        ret
449
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
312
 
450
        mov     ebx, [ext2_data.ext2_temp_block]
-
 
451
        call    ext2_get_block
313
    .get_indirect_block:
452
        test    eax, eax
314
        push    eax ebx
-
 
315
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
453
        jz      @F                      ;если не было ошибки
316
        mov     ebx, [ext2_data.ext2_temp_block]
454
 
317
        call    ext2_get_block
455
        mov     ecx, [ebx + ecx*4]    ;заносим результат
318
 
456
    @@:
-
 
457
        pop     ebx
-
 
458
        ret
319
        mov     ecx, [ebx + ecx*4]
459
 
Line 320... Line 460...
320
        pop     ebx eax
460
    .get_direct_block:
Line 321... Line 461...
321
        ret
461
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
322
 
462
        xor     eax, eax
Line 323... Line 463...
323
    .get_direct_block:
463
        ret
324
        mov     ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
464
 
325
        ret
-
 
326
 
465
;===================================================================
327
;===================================================================
-
 
328
;get content inode by num
466
;get content inode by num
329
;in:   eax = inode_num
467
;in:   eax = inode_num
330
;      ebx = address of inode content
468
;      ebx = address of inode content
331
ext2_get_inode:
469
;out: eax - error code
-
 
470
ext2_get_inode:
-
 
471
        pushad
Line 332... Line 472...
332
 
472
        mov     edi, ebx   ;сохраним адрес inode
333
        pushad
473
        dec     eax
Line 334... Line 474...
334
        mov     edi, ebx   ;сохраним адрес inode
474
        xor     edx, edx
335
        dec     eax
475
        
336
        xor     edx, edx
476
        mov     ecx, [ext2_data.sb]
Line 369... Line 509...
369
        div     ebp                             ;поделим на размер блока
509
        div     ebp                             ;поделим на размер блока
Line 370... Line 510...
370
 
510
 
371
        add     eax, esi                        ;нашли адрес блока для чтения
511
        add     eax, esi                        ;нашли адрес блока для чтения
372
        mov     ebx, [ext2_data.ext2_temp_block]
512
        mov     ebx, [ext2_data.ext2_temp_block]
-
 
513
        call    hd_read
-
 
514
        cmp     [hd_error], 0
Line 373... Line 515...
373
        call    hd_read
515
        jnz     .fail
374
 
516
 
375
        mov     esi, edx                        ;добавим "остаток"
-
 
376
        add     esi, ebx                        ;к адресу
517
        mov     esi, edx                        ;добавим "остаток"
-
 
518
        add     esi, ebx                        ;к адресу
-
 
519
        rep movsb                               ;копируем inode
-
 
520
        xor     eax, eax
377
       ; mov     ecx, [ext2_data.inode_size]
521
    .fail:
378
        rep movsb                               ;копируем inode
522
        mov     PUSHAD_EAX, eax
Line 379... Line 523...
379
        popad
523
        popad
380
        ret
-
 
381
 
-
 
382
;----------------------------------------------------------------
-
 
383
; in:  esi -> children
-
 
384
;      ebx -> pointer to dir block
-
 
385
; out: esi -> name without parent or not_changed
-
 
386
;      ebx -> dir_rec of inode children      or trash
-
 
387
ext2_test_block_by_name:
-
 
388
        push    eax ecx edx edi
-
 
389
 
-
 
390
        mov     edx, ebx
-
 
391
        add     edx, [ext2_data.block_size]       ;запомним конец блока
-
 
392
 
-
 
393
        .start_rec:
-
 
394
        cmp     [ebx + EXT2_DIR_STRUC.inode], 0
-
 
395
        jz      .next_rec
-
 
396
 
-
 
397
        push    esi
-
 
398
        movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
-
 
399
        mov     edi, EXT2_filename
-
 
400
        lea     esi, [ebx + EXT2_DIR_STRUC.name]
-
 
401
 
-
 
402
        call    utf8toansi_str
-
 
403
        mov     ecx, edi
-
 
404
        sub     ecx, EXT2_filename          ;кол-во байт в получившейся строке
-
 
405
 
-
 
406
        mov     edi, EXT2_filename
-
 
407
        mov     esi, [esp]
-
 
408
          @@:
-
 
409
        jecxz   .test_find
-
 
410
        dec     ecx
-
 
411
 
-
 
412
        lodsb
-
 
413
        call    char_toupper
-
 
414
 
-
 
415
        mov     ah, [edi]
-
 
416
        inc     edi
-
 
417
        xchg    al, ah
-
 
418
        call    char_toupper
-
 
419
        cmp     al, ah
-
 
420
        je      @B
-
 
421
          @@:                           ;не подошло
-
 
422
        pop     esi
-
 
423
        .next_rec:
-
 
424
        movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
-
 
425
        add     ebx, eax                                    ;к след. записи
-
 
426
        cmp     ebx, edx                                    ;проверим конец ли
-
 
427
        jb      .start_rec
-
 
428
        jmp     .ret
-
 
429
 
-
 
430
    .test_find:
-
 
431
        cmp     byte [esi], 0
-
 
432
        je      .find               ;нашли конец
-
 
433
        cmp     byte [esi], '/'
-
 
434
        jne     @B
-
 
435
        inc     esi
-
 
436
    .find:
-
 
437
        pop     eax     ;удаляем из стека сохраненое значение
-
 
438
    .ret:
-
 
439
        pop     edi edx ecx eax
-
 
440
        ret
524
        ret
441
 
525
 
442
;----------------------------------------------------------------
526
;----------------------------------------------------------------
443
;
527
;
444
;  ext2_HdReadFolder - read disk folder
528
;  ext2_HdReadFolder - read disk folder
Line 454... Line 538...
454
;      eax = 0 ok read or other = errormsg
538
;      eax = 0 ok read or other = errormsg
455
;
539
;
456
;--------------------------------------------------------------
540
;--------------------------------------------------------------
457
ext2_HdReadFolder:
541
ext2_HdReadFolder:
458
        cmp     byte [esi], 0
542
        cmp     byte [esi], 0
459
        jz      .doit
543
        jz      .root_folder
Line 460... Line 544...
460
 
544
 
461
        push    ecx ebx
545
        push    ebx ecx edx
462
        call    ext2_find_lfn
546
        call    ext2_find_lfn               ;вернет в ebp адрес inode
463
        jnc     .doit2
547
        pop     edx ecx ebx
464
        pop     ebx
-
 
465
    .not_found:
548
        test    eax, eax
466
        pop     ecx
549
        jnz     .error_ret
467
        or      ebx, -1
550
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
468
        mov     eax, ERROR_FILE_NOT_FOUND
551
        jz      .error_not_found
Line 469... Line 552...
469
        ret
552
        jmp     @F
470
 
553
 
471
    .doit:
-
 
472
        mov     ebp, [ext2_data.root_inode]
-
 
473
        push    ecx
-
 
474
        jmp     @F
-
 
475
    .doit2:
554
    .root_folder:
476
        pop     ebx
555
        mov     ebp, [ext2_data.root_inode]
-
 
556
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
-
 
557
        jz      .error_root
-
 
558
        ;придется копировать inode
-
 
559
        push    ecx
-
 
560
        mov     esi, ebp
-
 
561
        mov     edi, [ext2_data.ext2_save_inode]
-
 
562
        mov     ecx, [ext2_data.inode_size]
-
 
563
        shr     ecx, 2
-
 
564
        mov     ebp, edi
477
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
565
        rep movsd
-
 
566
        pop     ecx
478
        jz      .not_found
567
    @@:
-
 
568
        cmp     [ebp + EXT2_INODE_STRUC.i_blocks], 0 ;папка пуста
-
 
569
        je      .error_empty_dir
-
 
570
        
-
 
571
        push    edx      ;адрес результата              [edi + 28]
-
 
572
        push    0        ;конец очередного блока папки   [edi + 24]
-
 
573
        push    ecx      ;сколько файлов нужно прочитать [edi + 20]
-
 
574
        push    dword [ebx]   ;первый "нужный" файл           [edi + 16]
-
 
575
        push    dword [ebx + 4];флаги                        [edi + 12]
-
 
576
        push    0       ;[EXT2_read_in_folder]     [edi + 8]
-
 
577
        push    0       ;[EXT2_files_in_folder]    [edi + 4]
479
    @@:
578
        push    0       ;номер блока по порядку    [edi]
480
        xor     eax, eax
579
 
481
        mov     edi, edx
580
        mov     edi, edx
482
        mov     ecx, 32/4
-
 
483
        rep stosd                               ; fill header zero
-
 
484
        pop     edi                             ; edi = число блоков для чтения
-
 
485
        push    edx ebx
-
 
486
 
-
 
487
     ;--------------------------------------------- final step
-
 
488
        and     [EXT2_read_in_folder], 0
-
 
489
        and     [EXT2_files_in_folder], 0
-
 
490
 
-
 
Line 491... Line 581...
491
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]
581
        mov     ecx, 32/4
492
        mov     [EXT2_counter_blocks], eax
582
        rep stosd                               ; fill header zero
Line 493... Line -...
493
 
-
 
494
        add     edx, 32                         ; (header pointer in stack) edx = current mem for return
583
 
495
        xor     esi, esi                        ; esi = номер блока по порядку
584
        mov     edi, esp                        ; edi - указатель на локальные переменные
-
 
585
        add     edx, 32                         ; edx = current mem for return
-
 
586
 
Line 496... Line 587...
496
 
587
        xor     ecx, ecx                        ; получим номер первого блока
497
    .new_block_folder:              ;reserved label
588
        call    ext2_get_inode_block
498
        mov     ecx, esi                        ; получим номер блока
589
        test    eax, eax
-
 
590
        jnz     .error_get_block
-
 
591
 
Line 499... Line 592...
499
        call    ext2_get_inode_block
592
        mov     eax, ecx
500
 
593
        mov     ebx, [ext2_data.ext2_save_block]
501
        mov     eax, ecx
594
        call    ext2_get_block                  ; и считываем блок с hdd
Line 502... Line -...
502
        mov     ebx, [ext2_data.ext2_save_block]
-
 
503
        call    ext2_get_block                  ; и считываем блок с hdd
595
        test    eax, eax
Line 504... Line 596...
504
 
596
        jnz     .error_get_block
505
        mov     eax, ebx                        ; eax = current dir record
597
 
506
        add     ebx, [ext2_data.block_size]
598
        mov     esi, ebx                         ; esi = current dir record
507
        mov     [EXT2_end_block], ebx           ; запомним конец очередного блока
599
        add     ebx, [ext2_data.block_size]
508
 
600
        mov     [edi + 24], ebx               ; запомним конец очередного блока
509
        pop     ecx
601
 
510
        mov     ecx, [ecx]                      ; ecx = first wanted (flags ommited)
602
        mov     ecx, [edi + 16]                        ; ecx = first wanted (flags ommited)
511
 
603
 
512
    .find_wanted_start:
604
    .find_wanted_start:
Line 513... Line 605...
513
        jecxz   .find_wanted_end
605
        jecxz   .find_wanted_end
514
    .find_wanted_cycle:
606
    .find_wanted_cycle:
515
        cmp     [eax + EXT2_DIR_STRUC.inode], 0         ; if (inode = 0) => not used
607
        cmp     [esi + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
516
        jz      @F
608
        jz      @F
Line 517... Line 609...
517
        inc     [EXT2_files_in_folder]
609
        inc     dword [edi + 4]                        ; EXT2_files_in_folder
518
        dec     ecx
610
        dec     ecx
519
          @@:
611
          @@:
Line 520... Line 612...
520
        movzx   ebx, [eax+EXT2_DIR_STRUC.rec_len]
612
        movzx   ebx, [esi + EXT2_DIR_STRUC.rec_len]
521
 
613
 
522
        cmp     ebx, 12                                 ; минимальная длина записи
614
        cmp     ebx, 12                                 ; минимальная длина записи
523
        jb      .end_error
615
        jb      .error_bad_len
524
        test    ebx, 0x3                                ; длина записи должна делиться на 4
616
        test    ebx, 0x3                                ; длина записи должна делиться на 4
Line 525... Line 617...
525
        jnz     .end_error
617
        jnz     .error_bad_len
526
 
618
 
527
        add     eax, ebx                                ; к следующей записи
619
        add     esi, ebx                                ; к следующей записи
528
        cmp     eax, [EXT2_end_block]                  ; проверяем "конец"
620
        cmp     esi, [edi + 24]                        ; сравниваем с концом блока
-
 
621
        jb      .find_wanted_start
-
 
622
 
-
 
623
        push    .find_wanted_start
529
        jb      .find_wanted_start
624
   .end_block:                                              ;вылетели из цикла
530
 
625
        mov     ebx, [ext2_data.count_block_in_block]
531
        push    .find_wanted_start
626
        sub     [ebp + EXT2_INODE_STRUC.i_blocks], ebx  ;вычитаем напрямую из структуры inode
-
 
627
        jle     .end_dir
-
 
628
 
-
 
629
        inc     dword [edi]                                 ;получаем новый блок
532
   .end_block:                                                  ;вылетили из цикла
630
        push    ecx
533
        mov     ebx, [ext2_data.count_block_in_block]
631
        mov     ecx, [edi]
534
        sub     [EXT2_counter_blocks], ebx
632
        call    ext2_get_inode_block
535
        jbe     .end_dir
633
        test    eax, eax
536
 
634
        jnz     .error_get_block
Line 537... Line 635...
537
        inc     esi                                                                             ;получаем новый блок
635
 
538
        push    ecx
636
        mov     eax, ecx
Line -... Line 637...
-
 
637
        mov     ebx, [ext2_data.ext2_save_block]
539
        mov     ecx, esi
638
        call    ext2_get_block
540
        call    ext2_get_inode_block
639
        test    eax, eax
541
        mov     eax, ecx
640
        jnz     .error_get_block
542
        mov     ebx, [ext2_data.ext2_save_block]
641
 
543
        call    ext2_get_block
642
        pop     ecx
544
        pop     ecx
643
        mov     esi, ebx
545
        mov     eax, ebx
644
        add     ebx, [ext2_data.block_size]
546
        add     ebx, [ext2_data.block_size]
645
        mov     [edi + 24], ebx                            ;запомним конец блока
Line 547... Line -...
547
        mov     [EXT2_end_block], ebx
-
 
548
        ret                                                                                             ; опять в цикл
646
        ret                                                                                             ; опять в цикл
-
 
647
 
549
 
648
    .wanted_end:
550
    .wanted_end:
649
        loop    .find_wanted_cycle                          ; ecx 0 => -1 нужно посчитать сколько файлов
551
        loop    .find_wanted_cycle                      ; ecx = -1
650
 
552
 
651
    ;дошли до первого "нужного" файла
Line 553... Line 652...
553
    .find_wanted_end:
652
    .find_wanted_end:
554
        mov     ecx, edi
653
        mov     ecx, [edi + 20]
555
    .wanted_start:                                      ; ищем first_wanted+count
654
    .wanted_start:                                      ; ищем first_wanted+count
556
        jecxz   .wanted_end
655
        jecxz   .wanted_end
-
 
656
        cmp     [esi + EXT2_DIR_STRUC.inode], 0         ; if (inode = 0) => not used
-
 
657
        jz      .empty_rec
Line 557... Line 658...
557
        cmp     [eax + EXT2_DIR_STRUC.inode], 0         ; if (inode = 0) => not used
658
        inc     dword [edi + 8]
Line 558... Line 659...
558
        jz      .empty_rec
659
        inc     dword [edi + 4]
559
        inc     [EXT2_files_in_folder]
660
 
Line 597... Line 698...
597
 
698
 
598
        mov     eax, [ebx + EXT2_INODE_STRUC.i_size]                ;low size
699
        mov     eax, [ebx + EXT2_INODE_STRUC.i_size]                ;low size
599
        stosd
700
        stosd
600
        mov     eax, [ebx + EXT2_INODE_STRUC.i_dir_acl]             ;high size
701
        mov     eax, [ebx + EXT2_INODE_STRUC.i_dir_acl]             ;high size
601
        stosd
702
        stosd
602
        xor     dword [edx], FS_FT_DIR
703
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл(2 раза xor)
603
        @@:
-
 
604
        xor     dword [edx], FS_FT_DIR
-
 
605
        pop     esi eax
-
 
606
 
704
        @@:
Line 607... Line 705...
607
        or      dword [edx+4], FS_FT_ASCII          ; symbol type in name
705
        xor     dword [edx], FS_FT_DIR                              ;помечаем, что это файл
608
 
706
 
609
            ;теперь скопируем имя, сконвертировав из UTF-8 в CP866
707
            ;теперь скопируем имя, сконвертировав из UTF-8 в CP866
610
        push    eax ecx esi
708
        push    ecx  ;edi и esi уже сохранены в стеке
611
        movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
709
        movzx   ecx, [esi + EXT2_DIR_STRUC.name_len]
612
        lea     edi, [edx + 40]
710
        lea     edi, [edx + 40]
613
        lea     esi, [eax + EXT2_DIR_STRUC.name]
-
 
614
        call    utf8toansi_str
711
        lea     esi, [esi + EXT2_DIR_STRUC.name]
-
 
712
        call    utf8_to_cp866
Line 615... Line 713...
615
        pop     esi ecx eax
713
        and     byte [edi], 0
616
        and     byte [edi], 0
714
        pop     ecx edi esi
617
 
715
 
618
        cmp     byte [edx + 40], '.'
716
        cmp     byte [edx + 40], '.'                    ; в linux файл, начинающийся с точки - скрытый
Line 619... Line 717...
619
        jne     @F
717
        jne     @F
620
        or      dword [edx], FS_FT_HIDDEN
718
        or      dword [edx], FS_FT_HIDDEN
621
        @@:
719
        @@:
622
 
720
 
623
        add     edx, 40 + 264                           ; go to next record
721
        add     edx, 40 + 264                           ; go to next record
624
        dec     ecx                                     ; если запись пустая ecx не надо уменьшать
722
        dec     ecx                                     ; если запись пустая ecx не надо уменьшать
625
        .empty_rec:
723
        .empty_rec:
626
        movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
724
        movzx   ebx, [esi + EXT2_DIR_STRUC.rec_len]
Line 627... Line 725...
627
        cmp     ebx, 12                                 ; минимальная длина записи
725
        cmp     ebx, 12                                 ; минимальная длина записи
628
        jb      .end_error
726
        jb      .error_bad_len
629
        test    ebx, 0x3                                ; длина записи должна делиться на 4
727
        test    ebx, 0x3                                ; длина записи должна делиться на 4
Line 630... Line 728...
630
        jnz     .end_error
728
        jnz     .error_bad_len
631
 
729
 
Line 632... Line -...
632
        add     eax, ebx
-
 
633
        cmp     eax, [EXT2_end_block]
730
        add     esi, ebx
634
        jb      .wanted_start
-
 
635
 
731
        cmp     esi, [edi + 24]                         ;дошли ли до конца блока?
636
        push    .wanted_start                           ; дошли до конца очередного блока
732
        jb      .wanted_start
637
        jmp     .end_block
733
 
638
 
734
        push    .wanted_start                           ; дошли 
639
    .end_dir:
-
 
640
        pop     eax             ; мусор (адрес возврата в цикл)
735
        jmp     .end_block
641
    .end_error:
736
 
-
 
737
    .end_dir:   ;конец папки, когда еще не дошли до нужного файла
-
 
738
        mov     edx, [edi + 28] ;адрес структуры результата
-
 
739
        mov     ebx, [edi + 8] ;EXT2_read_in_folder
-
 
740
        mov     ecx, [edi + 4] ;EXT2_files_in_folder
642
        pop     edx
741
        mov     dword [edx], 1    ;version
643
        mov     ebx, [EXT2_read_in_folder]
742
        mov     [edx + 4], ebx
644
        mov     ecx, [EXT2_files_in_folder]
743
        mov     [edx + 8], ecx
645
        mov     dword [edx], 1    ;version
744
        
-
 
745
        lea     esp, [edi + 32]
-
 
746
        
646
        xor     eax, eax
747
        xor     eax, eax            ;зарезервировано: нули в текущей реализации
-
 
748
        lea     edi, [edx + 12]
-
 
749
        mov     ecx, 20 / 4
-
 
750
        rep stosd
647
        mov     [edx+4], ebx
751
        ret
-
 
752
 
-
 
753
    .error_bad_len:
-
 
754
        mov     eax, ERROR_FS_FAIL
-
 
755
    .error_read_subinode:
-
 
756
    .error_get_block:
-
 
757
        lea     esp, [edi + 32]
-
 
758
    .error_ret:
-
 
759
        or      ebx, -1
-
 
760
        ret
-
 
761
        
-
 
762
    .error_empty_dir:               ;inode папки без блоков
-
 
763
    .error_root:                    ;root - не папка
-
 
764
        mov     eax, ERROR_FS_FAIL
648
        mov     [edx+8], ecx
765
        jmp     .error_ret
649
        lea     edi, [edx + 12]
766
 
-
 
767
    .error_not_found:               ;файл не найден
-
 
768
        mov     eax, ERROR_FILE_NOT_FOUND
650
        mov     ecx, 20 / 4
769
        jmp     .error_ret
-
 
770
            
651
        rep stosd
771
;============================================
652
        ret
772
;convert UTF-8 string to ASCII-string (codepage 866)
653
;====================== end ext2_HdReadFolder
773
;in:  ecx = length source
654
utf8toansi_str:
774
;     esi = source
655
; convert UTF-8 string to ASCII-string (codepage 866)
775
;     edi = buffer
Line 710... Line 830...
710
;  ecx  number of bytes to read, 0+
830
;  ecx  number of bytes to read, 0+
711
;  edx  mem location to return data
831
;  edx  mem location to return data
712
;
832
;
713
;  ret ebx = bytes read or 0xffffffff file not found
833
;  ret ebx = bytes read or 0xffffffff file not found
714
;      eax = 0 ok read or other = errormsg
834
;      eax = 0 ok read or other = errormsg
715
;
835
 
716
;--------------------------------------------------------------
836
;--------------------------------------------------------------
717
ext2_HdRead:
837
ext2_HdRead:
718
        cmp     byte [esi], 0
838
        cmp     byte [esi], 0
719
        jnz     @F
839
        jnz     @F
Line 722... Line 842...
722
        or      ebx, -1
842
        or      ebx, -1
723
        mov     eax, ERROR_ACCESS_DENIED
843
        mov     eax, ERROR_ACCESS_DENIED
724
        ret
844
        ret
Line 725... Line 845...
725
 
845
 
726
    @@:
846
    @@:
727
        push    ecx ebx
847
        push    ecx ebx edx
728
        call    ext2_find_lfn
848
        call    ext2_find_lfn
729
        pop     ebx ecx
849
        pop     edx ebx ecx
730
        jnc     .doit
850
        test    eax, eax
-
 
851
        jz      @F
731
    ;.not_found:
852
 
732
        or      ebx, -1
853
        or      ebx, -1
733
        mov     eax, ERROR_FILE_NOT_FOUND
854
        mov     eax, ERROR_FILE_NOT_FOUND
Line 734... Line 855...
734
        ret
855
        ret
735
 
856
 
-
 
857
    @@:
-
 
858
        mov     ax, [ebp + EXT2_INODE_STRUC.i_mode]
736
    .doit:
859
        and     ax, EXT2_S_IFMT     ;оставляем только тип inode в ax
Line 737... Line -...
737
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
-
 
738
        jz      .this_is_nofile
860
        cmp     ax, EXT2_S_IFREG
739
 
-
 
Line -... Line 861...
-
 
861
        jne     .this_is_nofile
-
 
862
 
740
    ;-----------------------------------------------------------------------------final step
863
        mov     edi, edx            ; edi = pointer to return mem
741
        mov     edi, edx            ; edi = pointer to return mem
864
 
742
        mov     esi, ebx            ; esi = pointer to first_wanted
865
        test    ebx, ebx
Line -... Line 866...
-
 
866
        jz      @F
743
 
867
        mov     esi, ebx            ; esi = pointer to first_wanted
744
        ;///// сравним хватит ли нам файла или нет
868
        mov     ebx, [esi+4]
745
        mov     ebx, [esi+4]
869
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
Line 746... Line 870...
746
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
870
 
Line 754... Line 878...
754
 
878
 
755
    .size_less:
879
    .size_less:
756
        xor     ebx, ebx
880
        xor     ebx, ebx
757
        mov     eax, ERROR_END_OF_FILE
881
        mov     eax, ERROR_END_OF_FILE
-
 
882
        ret
-
 
883
        
-
 
884
    @@:
-
 
885
        xor     ebx, ebx
758
        ret
886
        xor     eax, eax
759
    .size_great:
887
    .size_great:
760
        add     eax, ecx                  ;add to first_wanted кол-во байт для чтения
888
        add     eax, ecx                  ;add to first_wanted кол-во байт для чтения
Line 761... Line 889...
761
        adc     ebx, 0
889
        adc     ebx, 0
762
 
890
 
763
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
891
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
764
        ja      .size_great_great
892
        ja      .size_great_great
765
        jb      .size_great_less
893
        jb      .size_great_less
Line 766... Line 894...
766
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
894
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
-
 
895
        jae     .size_great_great
767
        jae     .size_great_great               ; а если равно, то не важно куда
896
 
768
 
897
    .size_great_less:
769
    .size_great_less:
898
        push    1
770
        or      [EXT2_files_in_folder], 1       ;читаем по границе размера
899
;        or      [EXT2_files_in_folder], 1       ;читаем по границе размера
Line 771... Line 900...
771
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]
900
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]
-
 
901
        sub     ecx, [esi]                      ;(размер - старт) = сколько читать
772
        sub     ecx, [esi]                      ;(размер - старт)
902
        jmp     @F
Line 773... Line 903...
773
        jmp     @F
903
 
-
 
904
    .size_great_great:
-
 
905
        push    0
-
 
906
;        and     [EXT2_files_in_folder], 0       ;читаем столько сколько запросили
-
 
907
 
774
 
908
    @@:
775
    .size_great_great:
909
        ;здесь мы точно знаем сколько байт читать - ecx
776
        and     [EXT2_files_in_folder], 0       ;читаем столько сколько запросили
910
        ;edi - return memory
Line 777... Line 911...
777
 
911
        ;esi -> first wanted
778
    @@:
912
 
779
        push    ecx                             ;save for return
913
        push    ecx                             ;количество считанных байт
780
        test    esi, esi
914
        test    esi, esi
Line 781... Line 915...
781
        jz      .zero_start
915
        jz      .zero_start
Line 782... Line 916...
782
 
916
 
783
        ;пока делаем п..ц криво =)
917
        ;получим кусок из первого блока
784
        mov     edx, [esi+4]
918
        mov     edx, [esi+4]
-
 
919
        mov     eax, [esi]
-
 
920
        div     [ext2_data.block_size]
785
        mov     eax, [esi]
921
 
786
        div     [ext2_data.block_size]
922
        push    eax       ;номер блока запоминаем
787
 
923
 
-
 
924
        push    ecx
-
 
925
        mov     ecx, eax
788
        mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
926
        call    ext2_get_inode_block
789
 
927
        test    eax, eax
Line 790... Line 928...
790
        push    ecx
928
        jnz     .error_at_first_block
791
        mov     ecx, eax
929
        mov     ebx, [ext2_data.ext2_save_block]
Line 805... Line 943...
805
        sub     eax, edx
943
        sub     eax, edx
806
        mov     ecx, edx
944
        mov     ecx, edx
Line 807... Line 945...
807
 
945
 
808
        mov     esi, ebx
946
        mov     esi, ebx
809
        rep movsb                               ;кусок 1-го блока
947
        rep movsb                               ;кусок 1-го блока
Line 810... Line 948...
810
        jmp     @F
948
        jmp     .calc_blocks_count
811
 
949
 
-
 
950
    .zero_start:
812
    .zero_start:
951
        mov     eax, ecx
813
        mov     eax, ecx
952
        push    0                               ;счетчик блоков
814
        ;теперь в eax кол-во оставшихся байт для чтения
953
        ;теперь в eax кол-во оставшихся байт для чтения
815
    @@:
954
    .calc_blocks_count:
816
        mov     ebx, edi                        ;чтение блока прям в ->ebx
955
        mov     ebx, edi                        ;чтение блока прям в ->ebx
817
        xor     edx, edx
956
        xor     edx, edx
818
        div     [ext2_data.block_size]          ;кол-во байт в последнем блоке (остаток) в edx
957
        div     [ext2_data.block_size]          ;кол-во байт в последнем блоке (остаток) в edx
819
        mov     edi, eax                        ;кол-во целых блоков в edi
958
        mov     edi, eax                        ;кол-во целых блоков в edi
820
    @@:
959
    @@:
821
        test    edi, edi
960
        test    edi, edi
822
        jz      .finish_block
961
        jz      .finish_block
823
        inc     [EXT2_counter_blocks]
962
        inc     dword [esp]
-
 
963
        mov     ecx, [esp]
-
 
964
        call    ext2_get_inode_block
Line 824... Line 965...
824
        mov     ecx, [EXT2_counter_blocks]
965
        test    eax, eax
825
        call    ext2_get_inode_block
966
        jnz     .error_at_read_cycle
-
 
967
 
-
 
968
        mov     eax, ecx                        ;а ebx уже забит нужным значением
826
 
969
        call    ext2_get_block
Line 827... Line 970...
827
        mov     eax, ecx                        ;а ebx уже забит нужным значением
970
        test    eax, eax
828
        call    ext2_get_block
971
        jnz     .error_at_read_cycle
Line 829... Line 972...
829
        add     ebx, [ext2_data.block_size]
972
        add     ebx, [ext2_data.block_size]
830
 
973
 
831
        dec     edi
974
        dec     edi
Line 832... Line 975...
832
        jmp     @B
975
        jmp     @B
833
 
976
 
834
    .finish_block:          ;в edx - кол-во байт в последнем блоке
977
    .finish_block:          ;в edx - кол-во байт в последнем блоке
-
 
978
        test    edx, edx
-
 
979
        jz      .end_read
Line 835... Line 980...
835
        test    edx, edx
980
 
836
        jz      .end_read
981
        pop     ecx         ;счетчик блоков -> ecx
837
 
982
        inc     ecx
838
        mov     ecx, [EXT2_counter_blocks]
983
        call    ext2_get_inode_block
-
 
984
        test    eax, eax
-
 
985
        jz      .error_at_finish_block
Line 839... Line 986...
839
        inc     ecx
986
 
840
        call    ext2_get_inode_block
-
 
841
 
-
 
842
        mov     edi, ebx
987
        mov     edi, ebx
843
        mov     eax, ecx
988
        mov     eax, ecx
844
        mov     ebx, [ext2_data.ext2_save_block]
989
        mov     ebx, [ext2_data.ext2_save_block]
845
        call    ext2_get_block
990
        call    ext2_get_block
-
 
991
        test    eax, eax
846
 
992
        jnz     .error_at_finish_block
847
        mov     ecx, edx
993
 
Line 848... Line 994...
848
 
994
        mov     ecx, edx
849
    .only_one_block:
995
        mov     esi, ebx
850
        mov     esi, ebx
996
        rep movsb                               ;кусок last блока
851
        rep movsb                               ;кусок last блока
997
    .end_read:
852
    .end_read:
998
        pop     ebx
-
 
999
        pop     eax
-
 
1000
        test    eax, eax
-
 
1001
        jz      @F
-
 
1002
 
-
 
1003
        mov     eax, ERROR_END_OF_FILE
-
 
1004
        ret
-
 
1005
    @@:
-
 
1006
        xor     eax, eax
-
 
1007
        ret
-
 
1008
        
-
 
1009
    .only_one_block:
-
 
1010
        mov     esi, ebx
-
 
1011
        rep movsb                               ;кусок last блока
-
 
1012
        pop     eax
-
 
1013
        jmp     .end_read
-
 
1014
        
-
 
1015
   .error_at_first_block:
-
 
1016
        pop     edx
-
 
1017
   .error_at_read_cycle:
-
 
1018
        pop     ebx 
-
 
1019
   .error_at_finish_block:
-
 
1020
        pop     ecx edx
-
 
1021
        or      ebx, -1
-
 
1022
        ret
-
 
1023
 
-
 
1024
;----------------------------------------------------------------
-
 
1025
; in:  esi = file path
-
 
1026
;      ebx = pointer to dir block
-
 
1027
; out: esi - name without parent or not_changed
-
 
1028
;      ebx - dir_rec of inode children
-
 
1029
ext2_test_block_by_name:
-
 
1030
        sub     esp, 256        ;EXT2_filename
-
 
1031
        mov     edx, ebx
-
 
1032
        add     edx, [ext2_data.block_size]       ;запомним конец блока
-
 
1033
 
-
 
1034
    .start_rec:
-
 
1035
        cmp     [ebx + EXT2_DIR_STRUC.inode], 0
-
 
1036
        jz      .next_rec
-
 
1037
 
-
 
1038
        mov     edi, esp
-
 
1039
        push    esi
-
 
1040
        movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
-
 
1041
        lea     esi, [ebx + EXT2_DIR_STRUC.name]
-
 
1042
        call    utf8_to_cp866
-
 
1043
 
-
 
1044
        mov     ecx, edi
-
 
1045
        lea     edi, [esp + 4]
-
 
1046
        sub     ecx, edi          ;кол-во байт в получившейся строке
-
 
1047
 
-
 
1048
        mov     esi, [esp]
-
 
1049
    @@:
-
 
1050
        jecxz   .test_find
-
 
1051
        dec     ecx
-
 
1052
 
-
 
1053
        lodsb
-
 
1054
        call    char_toupper
-
 
1055
 
-
 
1056
        mov     ah, [edi]
-
 
1057
        inc     edi
-
 
1058
        xchg    al, ah
-
 
1059
        call    char_toupper
-
 
1060
        cmp     al, ah
-
 
1061
        je      @B
-
 
1062
    @@:                           ;не подошло
-
 
1063
        pop     esi
-
 
1064
    .next_rec:
-
 
1065
        movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
-
 
1066
        add     ebx, eax                                    ;к след. записи
-
 
1067
        cmp     ebx, edx                                    ;проверим конец ли
-
 
1068
        jb      .start_rec
-
 
1069
        add     esp, 256
-
 
1070
        ret
-
 
1071
 
-
 
1072
    .test_find:
853
        pop     ebx
1073
        cmp     byte [esi], 0
854
        cmp     [EXT2_files_in_folder], 0
1074
        je      .ret                ;нашли конец
-
 
1075
        cmp     byte [esi], '/'
855
        jz      @F
1076
        jne     @B
856
 
1077
        inc     esi
-
 
1078
    .ret:
857
        mov     eax, ERROR_END_OF_FILE
1079
        add     esp, 256 + 4
858
        ret
1080
        ret
859
    @@:
-
 
860
        xor     eax, eax
-
 
861
        ret
-
 
862
;========================
1081
 
863
;in : esi -> name           not save: eax ebx ecx
1082
;========================
-
 
1083
;Ищет inode по строке пути
864
;out: ebp -> inode cf=0
1084
;in:  esi = name
865
;     ebp -> trash cf=1
1085
;out: eax - error code
866
ext2_find_lfn:
1086
;     ebp = inode
867
        mov     ebp, [ext2_data.root_inode]
1087
;      dl - первый байт из имени файла/папки
868
    .next_folder:
-
 
869
        or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
-
 
870
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
1088
ext2_find_lfn:
-
 
1089
        mov     ebp, [ext2_data.root_inode]
-
 
1090
        cmp     [ebp + EXT2_INODE_STRUC.i_blocks], 0
Line 871... Line 1091...
871
        add     eax, [ext2_data.count_block_in_block]
1091
        je      .error_empty_root
872
        mov     [EXT2_end_block], eax
1092
        
873
    .next_block_folder:
1093
    .next_path_part:
-
 
1094
        push    [ebp + EXT2_INODE_STRUC.i_blocks]
-
 
1095
        xor     ecx, ecx
Line 874... Line 1096...
874
        mov     eax, [ext2_data.count_block_in_block]
1096
    .folder_block_cycle:
875
        sub     [EXT2_end_block], eax
1097
        call    ext2_get_inode_block
876
        jz      .not_found
-
 
877
        inc     [EXT2_counter_blocks]
1098
        test    eax, eax
Line 878... Line 1099...
878
        mov     ecx, [EXT2_counter_blocks]
1099
        jnz     .error_get_inode_block
-
 
1100
 
-
 
1101
        mov     eax, ecx
-
 
1102
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
879
        call    ext2_get_inode_block
1103
        call    ext2_get_block
Line 880... Line 1104...
880
 
1104
        test    eax, eax
881
        mov     eax, ecx
1105
        jnz     .error_get_block
-
 
1106
 
882
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
1107
        push    esi
883
        call    ext2_get_block
1108
        call    ext2_test_block_by_name
884
 
1109
        pop     edi
-
 
1110
 
-
 
1111
        cmp     edi, esi                                ;нашли имя?
-
 
1112
        je      .next_folder_block                      ;не нашли -> к след. блоку
885
        mov     eax, esi
1113
 
886
        call    ext2_test_block_by_name
1114
        cmp     byte [esi], 0                           ;дошли до "конца" пути -> возваращаемся
-
 
1115
        jz      .get_inode_ret
-
 
1116
 
-
 
1117
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;нашли, но это не папка
-
 
1118
        jne     .not_found
-
 
1119
 
-
 
1120
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
-
 
1121
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
-
 
1122
        call    ext2_get_inode
-
 
1123
        test    eax, eax
Line 887... Line 1124...
887
        cmp     eax, esi                                ;нашли имя?
1124
        jnz     .error_get_inode
888
        jz      .next_block_folder
1125
        pop     ecx                                     ;в стеке лежит кол-во блоков
-
 
1126
        mov     ebp, ebx
889
 
1127
        jmp     .next_path_part
-
 
1128
        
890
        cmp     byte [esi], 0
1129
    .next_folder_block:
891
        jz      .get_inode_ret
1130
        ;к следующему блоку в текущей папке
-
 
1131
        pop     eax                                     ;счетчик блоков
892
 
1132
        sub     eax, [ext2_data.count_block_in_block]
893
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
1133
        jle     .not_found
894
        jne     .not_found                                      ;нашли, но это не папка
1134
        
895
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
1135
        inc     ecx
896
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
1136
        jmp     .folder_block_cycle
897
        call    ext2_get_inode
1137
 
Line -... Line 1138...
-
 
1138
    .not_found:
-
 
1139
        pop     ebx
-
 
1140
        mov     eax, ERROR_FILE_NOT_FOUND
-
 
1141
        ret
-
 
1142
 
-
 
1143
    .get_inode_ret:
-
 
1144
        pop     ecx                                     ;в стеке лежит кол-во блоков
Line -... Line 1145...
-
 
1145
        mov     dl, [ebx + EXT2_DIR_STRUC.name]     ;в dl - первый символ ()
898
        mov     ebp, ebx
1146
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
899
        jmp     .next_folder
1147
        mov     ebx, [ext2_data.ext2_save_inode]
-
 
1148
        call    ext2_get_inode
-
 
1149
        mov     ebp, ebx
-
 
1150
        xor     eax, eax
900
 
1151
        ret
-
 
1152
 
901
    .not_found:
1153
    .error_get_inode_block:
902
        stc
1154
    .error_get_block:
Line -... Line 1155...
-
 
1155
    .error_get_inode:
903
        ret
1156
        pop     ebx
904
    .get_inode_ret:
1157
    .error_empty_root:
905
        mov     [EXT2_end_block], ebx                           ; сохраняем указатеть на dir_rec
1158
        mov     eax, ERROR_FS_FAIL
906
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
1159
        ret
-
 
1160
 
907
        mov     ebx, [ext2_data.ext2_save_inode]
1161
;----------------------------------------------------------------
Line 908... Line 1162...
908
        call    ext2_get_inode
1162
;ext2_HdGetFileInfo - read file info from block device
-
 
1163
;
909
        mov     ebp, ebx
1164
;in: esi  points to filename
910
        clc
-
 
911
        ret
-
 
912
 
-
 
913
 
-
 
914
;========================
-
 
915
 
1165
;    edx  mem location to return data
916
ext2_HdGetFileInfo:
1166
;--------------------------------------------------------------
917
        cmp     byte [esi], 0
1167
ext2_HdGetFileInfo:
918
        jz      .doit
1168
        xchg    bx, bx
919
 
1169
        cmp     byte [esi], 0
Line 920... Line 1170...
920
        call    ext2_find_lfn
1170
        jz      .is_root
921
        jnc     .doit2
1171
 
922
    ;.not_found:
1172
        push    edx
923
        mov     eax, ERROR_FILE_NOT_FOUND
1173
        call    ext2_find_lfn
Line 924... Line 1174...
924
        ret
1174
        mov     ebx, edx
925
 
1175
        pop     edx
Line 950... Line 1200...
950
        xor     dword [edx], FS_FT_DIR
1200
        xor     dword [edx], FS_FT_DIR
951
    @@:
1201
    @@:
952
        xor     dword [edx], FS_FT_DIR
1202
        xor     dword [edx], FS_FT_DIR
Line 953... Line 1203...
953
 
1203
 
954
        lea     edi, [edx + 8]
1204
        lea     edi, [edx + 8]
955
        mov     eax, [ebx + EXT2_INODE_STRUC.i_ctime]
1205
        mov     eax, [ebp + EXT2_INODE_STRUC.i_ctime]
956
        xor     edx, edx
1206
        xor     edx, edx
957
        add     eax, 3054539008
1207
        add     eax, 3054539008
958
        adc     edx, 2
1208
        adc     edx, 2
Line 959... Line 1209...
959
        call    ntfs_datetime_to_bdfe.sec
1209
        call    ntfs_datetime_to_bdfe.sec
960
 
1210
 
961
        mov     eax, [ebx + EXT2_INODE_STRUC.i_atime]
1211
        mov     eax, [ebp + EXT2_INODE_STRUC.i_atime]
962
        xor     edx, edx
1212
        xor     edx, edx
963
        add     eax, 3054539008
1213
        add     eax, 3054539008
Line 964... Line 1214...
964
        adc     edx, 2
1214
        adc     edx, 2
965
        call    ntfs_datetime_to_bdfe.sec
1215
        call    ntfs_datetime_to_bdfe.sec
966
 
1216
 
967
        mov     eax, [ebx + EXT2_INODE_STRUC.i_mtime]
1217
        mov     eax, [ebp + EXT2_INODE_STRUC.i_mtime]
968
        xor     edx, edx
1218
        xor     edx, edx
Line 980... Line 1230...
980
ext2_HdDelete:
1230
ext2_HdDelete:
981
ext2_HdCreateFolder:
1231
ext2_HdCreateFolder:
982
        xor     ebx, ebx
1232
        xor     ebx, ebx
983
        mov     eax, ERROR_UNSUPPORTED_FS
1233
        mov     eax, ERROR_UNSUPPORTED_FS
984
        ret
1234
        ret
985
;----------------------------------------------------------------
-
 
986
;
-
 
987
;  ext2_HdCreateFolder - create new folder
-
 
988
;
-
 
989
;  esi  points to filename
-
 
990
;
-
 
991
;  ret  eax = 0 ok read or other = errormsg
-
 
992
;
-
 
993
;--------------------------------------------------------------
-
 
994
        cmp     byte [esi], 0
-
 
995
        jz      .not_found
-
 
996
        cmp     byte [esi], '/'
-
 
997
        jz      .not_found
-
 
998
 
-
 
999
        mov     ebx, esi            ; save source pointer
-
 
1000
        xor     edi, edi            ; slah pointer
-
 
1001
    @@:
-
 
1002
        lodsb
-
 
1003
        cmp     al, 0
-
 
1004
        jz      .zero
-
 
1005
        cmp     al, '/'
-
 
1006
        jz      .slash
-
 
1007
        jmp     @B
-
 
1008
 
-
 
1009
    .slash:
-
 
1010
        lodsb
-
 
1011
        cmp     al, 0
-
 
1012
        jz      .zero               ; уберем слеш из имени
-
 
1013
        cmp     al, '/'
-
 
1014
        jz      .not_found
-
 
1015
        mov     edi, esi            ; edi -> next symbol after '/'
-
 
1016
        dec     edi
-
 
1017
        jmp     @B
-
 
1018
 
-
 
1019
    .zero:
-
 
1020
        dec     esi
-
 
1021
        test    edi, edi
-
 
1022
        jz      .doit
-
 
1023
 
-
 
1024
        ;слеш был
-
 
1025
        mov     eax, esi
-
 
1026
        sub     eax, edi
-
 
1027
        mov     [EXT2_name_len], eax
-
 
1028
 
-
 
1029
        mov     ecx, edi
-
 
1030
        sub     ecx, ebx
-
 
1031
        dec     ecx                     ;выкинули '/' из имени ролителя
-
 
1032
        mov     esi, ebx
-
 
1033
        mov     edi, EXT2_parent_name
-
 
1034
        rep movsb
-
 
1035
        ; esi - pointer to last slash
-
 
1036
 
-
 
1037
        mov     edx, esi
-
 
1038
        mov     esi, EXT2_parent_name
-
 
1039
        call    ext2_find_lfn
-
 
1040
        jnc     .doit2
-
 
1041
    .not_found:
-
 
1042
        or      ebx, -1
-
 
1043
        mov     eax, ERROR_FILE_NOT_FOUND
-
 
1044
        ret
-
 
1045
 
-
 
1046
    .doit:
-
 
1047
        mov     ebp, [ext2_data.root_inode]
-
 
1048
        mov     edx, ebx                        ; имя создаваемой папки
-
 
1049
        sub     esi, ebx
-
 
1050
        mov     [EXT2_name_len], esi
-
 
1051
    .doit2:
-
 
1052
        ;ebp -> parent_inode    ebx->name_new_folder   [EXT2_name_len]=length of name
-
 
1053
; стратегия выбора группы для нового inode: (так делает линукс)
-
 
1054
; 1) Ищем группу в которой меньше всего папок и в есть свободное место
-
 
1055
; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места
-
 
1056
 
-
 
1057
 
-
 
1058
 
-
 
1059
 
-
 
1060
        call    ext2_balloc
-
 
1061
        jmp     ext2_HdDelete
-
 
1062
 
-
 
1063
        push    ebx
-
 
1064
        push    ebp
-
 
1065
 
-
 
1066
        mov     ecx, [ext2_data.sb]
-
 
1067
        cmp     [ecx + EXT2_SB_STRUC.free_inodes_count], 0      ; есть ли место для inode
-
 
1068
        jz      .no_space
-
 
1069
        mov     eax, [ecx + EXT2_SB_STRUC.free_block_count]
-
 
1070
        sub     eax, [ecx + EXT2_SB_STRUC.r_block_count]
-
 
1071
        cmp     eax, 2                                          ; и как минимум на 2 блока
-
 
1072
        jb      .no_space
-
 
1073
 
-
 
1074
        mov     ecx, [ext2_data.groups_count]
-
 
1075
        mov     esi, [ext2_data.global_desc_table]
-
 
1076
        mov     edi, -1                         ;указатель на лучшую группу
-
 
1077
        mov     edx, 0
-
 
1078
    .find_group_dir:
-
 
1079
        jecxz   .end_find_group_dir
-
 
1080
        movzx   eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
-
 
1081
        cmp     eax, edx
-
 
1082
        jbe     @F
-
 
1083
        cmp     [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0
-
 
1084
        jz      @F
-
 
1085
        mov     edi, esi
-
 
1086
        movzx   edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
-
 
1087
    @@:
-
 
1088
        dec     ecx
-
 
1089
        add     esi, 32                         ;размер структуры
-
 
1090
        jmp     .find_group_dir
-
 
1091
    .end_find_group_dir:
-
 
1092
        cmp     edx, 0
-
 
1093
        jz      .no_space
-
 
1094
 
-
 
1095
        ;нашли группу, получим битовую карту inode-ов (найдем locale number)
-
 
1096
        mov     eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
-
 
1097
        mov     ebx, [ext2_data.ext2_save_block]
-
 
1098
        call    ext2_get_block
-
 
1099
 
-
 
1100
        ;теперь цикл по всем битам
-
 
1101
        mov     esi, ebx
-
 
1102
        mov     ecx, [ext2_data.inodes_per_group]
-
 
1103
        shr     ecx, 5                              ;делим на 32
-
 
1104
        mov     ebp, ecx                            ; всего сохраним в ebp
-
 
1105
        or      eax, -1                             ; ищем первый свободный inode (!= -1)
-
 
1106
        repne scasd
-
 
1107
        jnz     .test_last_dword                    ;нашли или нет
-
 
1108
        mov     eax, [esi-4]
-
 
1109
 
-
 
1110
        sub     ebp, ecx
-
 
1111
        dec     ebp
-
 
1112
        shl     ebp, 5                              ; глобальный номер локального номера
-
 
1113
 
-
 
1114
        mov     ecx, 32
-
 
1115
    @@:
-
 
1116
        test    eax, 1
-
 
1117
        jz      @F
-
 
1118
        shr     eax, 1
-
 
1119
        loop    @B
-
 
1120
    @@:
-
 
1121
        mov     eax, 32
-
 
1122
        sub     eax, ecx
-
 
1123
 
-
 
1124
        add     ebp, eax                            ; locale num of inode
-
 
1125
 
-
 
1126
        mov     eax, [esi-4]
-
 
1127
    ;устанавливаем в eax крайний справа нулевой бит в 1
-
 
1128
        mov     ecx, eax
-
 
1129
        inc     ecx
-
 
1130
        or      eax, ecx        ; x | (x+1)
-
 
1131
        mov     [esi-4], eax
-
 
1132
        mov     ebx, [ext2_data.ext2_save_block]
-
 
1133
        mov     eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
-
 
1134
        call    ext2_set_block
-
 
1135
    ;считаем таблицу inode
-
 
1136
        sub     edi, [ext2_data.global_desc_table]
-
 
1137
        shr     edi, 5
-
 
1138
 
-
 
1139
        mov     eax, edi
-
 
1140
        mul     [ext2_data.inodes_per_group]
-
 
1141
        add     eax, ebp
-
 
1142
        inc     eax                                     ; теперь в eax (ebp) номер inode-а
-
 
1143
        mov     ebp, eax
-
 
1144
        ;call    ext2_get_inode_address
-
 
1145
 
-
 
1146
        mov     ebx, [ext2_data.ext2_save_block]
-
 
1147
        call    hd_read
-
 
1148
        add     edx, ebx                                ; в edx адрес нужного inode
-
 
1149
 
-
 
1150
        ;забьем 0 для начала
-
 
1151
        mov     edi, edx
-
 
1152
        mov     ecx, [ext2_data.inode_size]
-
 
1153
        shr     ecx, 2
-
 
1154
        xor     eax, eax
-
 
1155
        rep stosd
-
 
1156
 
-
 
1157
        mov     edi, edx
-
 
1158
        mov     eax, EXT2_S_IFDIR or EXT2_777_MODE
-
 
1159
        stosd                                           ; i_mode
-
 
1160
        xor     eax, eax
-
 
1161
        stosd                                           ; i_uid
-
 
1162
        mov     eax, [ext2_data.block_size]
-
 
1163
        stosd                                           ; i_size
-
 
1164
        xor     eax, eax
-
 
1165
        stosd                                           ; i_atime
-
 
1166
        stosd                                           ; i_ctime
-
 
1167
        stosd                                           ; i_mtime
-
 
1168
        stosd                                           ; i_dtime
-
 
1169
        stosd                                           ; i_gid
-
 
1170
        inc     eax
-
 
1171
        stosd                                           ; i_links_count
-
 
1172
        mov     eax, [ext2_data.count_block_in_block]
-
 
1173
        stosd                                           ; i_blocks
-
 
1174
 
-
 
1175
 
-
 
1176
 
-
 
1177
 
-
 
1178
.test_last_dword:
-
 
1179
 
-
 
1180
        xor     ebx, ebx
-
 
1181
        mov     eax, ERROR_UNSUPPORTED_FS
-
 
1182
        ret
-
 
1183
 
-
 
1184
 
-
 
1185
 
-
 
1186
    .no_space:
-
 
1187
        or      ebx, -1
-
 
1188
        mov     eax, ERROR_DISK_FULL
-
 
1189
        ret
-
 
1190
 
-
 
1191
;выделяет новый блок, если это можно
-
 
1192
;иначе возвращает eax=0
-
 
1193
ext2_balloc:
-
 
1194
        mov     ecx, [ext2_data.sb]
-
 
1195
        mov     eax, [ecx + EXT2_SB_STRUC.free_block_count]
-
 
1196
        sub     eax, [ecx + EXT2_SB_STRUC.r_block_count]
-
 
1197
        jbe     .no_space
-
 
1198
 
-
 
1199
        mov     ecx, [ext2_data.groups_count]
-
 
1200
        mov     edi, [ext2_data.global_desc_table]
-
 
1201
        ;mov     esi, -1                         ;указатель на лучшую группу
-
 
1202
        mov     edx, 0
-
 
1203
    .find_group:
-
 
1204
        jecxz   .end_find_group
-
 
1205
        movzx   eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
-
 
1206
        cmp     eax, edx
-
 
1207
        jbe     @F
-
 
1208
        mov     esi, edi
-
 
1209
        mov     edx, eax
-
 
1210
    @@:
-
 
1211
        dec     ecx
-
 
1212
        add     edi, 32                         ;размер структуры
-
 
1213
        jmp     .find_group
-
 
1214
    .end_find_group:
-
 
1215
        cmp     edx, 0
-
 
1216
        jz      .no_space
-
 
1217
 
-
 
1218
        ;нашли группу, получим битовую карту block-ов
-
 
1219
        mov     eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap]
-
 
1220
        mov     ebx, [ext2_data.ext2_save_block]
-
 
1221
        call    ext2_get_block
-
 
1222
 
-
 
1223
        ;теперь цикл по всем битам
-
 
1224
        mov     edi, ebx
-
 
1225
        mov     ecx, [ext2_data.blocks_per_group]
-
 
1226
        shr     ecx, 5                              ;делим на 32
-
 
1227
        mov     ebp, ecx                            ;всего сохраним в ebp
-
 
1228
        or      eax, -1                             ;ищем первый свободный inode (!= -1)
-
 
1229
        repe scasd
-
 
1230
        jz      .test_last_dword                    ;нашли или нет
-
 
1231
 
-
 
1232
        mov     eax, [edi-4]
-
 
1233
        sub     ebp, ecx
-
 
1234
        dec     ebp
-
 
1235
        shl     ebp, 5                              ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32)
-
 
1236
 
-
 
1237
        mov     ecx, 32
-
 
1238
    @@:
-
 
1239
        test    eax, 1
-
 
1240
        jz      @F
-
 
1241
        shr     eax, 1
-
 
1242
        loop    @B
-
 
1243
    @@:
-
 
1244
        mov     eax, 32
-
 
1245
        sub     eax, ecx
-
 
1246
 
-
 
1247
        add     ebp, eax                            ; ebp = номер блока в группе
-
 
1248
 
-
 
1249
        mov     eax, [edi-4]
-
 
1250
        mov     ecx, eax
-
 
1251
        inc     ecx
-
 
1252
        or      eax, ecx        ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used)
-
 
1253
        mov     [edi-4], eax
-
 
1254
 
-
 
1255
        mov     ebx, [ext2_data.ext2_save_block]
-
 
1256
        mov     eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
-
 
1257
       ; call    ext2_set_block                      ; и пишем на hdd новую битовую маску
-
 
1258
 
-
 
1259
        ;============== тут получаем номер блока
-
 
1260
        mov     eax, [ext2_data.blocks_per_group]
-
 
1261
        sub     esi, [ext2_data.global_desc_table]
-
 
1262
        shr     esi, 5                                  ;esi - номер группы
-
 
1263
        mul     esi
-
 
1264
        add     ebp, eax                                ;(номер_группы) * (blocks_per_group) + локальный номер в группе
-
 
1265
        mov     eax, [ext2_data.sb]
-
 
1266
        add     ebp, [eax + EXT2_SB_STRUC.first_data_block]
-
 
1267
 
-
 
1268
        ;теперь поправим глобальную дескрипторную таблицу и суперблок
-
 
1269
        mov     ebx, [ext2_data.sb]
-
 
1270
        dec     [ebx + EXT2_SB_STRUC.free_block_count]
-
 
1271
        mov     eax, 2
-
 
1272
        add     eax, [PARTITION_START]
-
 
1273
        call    hd_write
-
 
1274
        mov     eax, [ebx + EXT2_SB_STRUC.first_data_block]
-
 
1275
        inc     eax
-
 
1276
        dec     [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок
-
 
1277
        call    ext2_set_block
-
 
1278
 
-
 
1279
        mov     eax, ebx
-
 
1280
        ret
-
 
1281
 
-
 
1282
    .test_last_dword:
-
 
1283
        lodsd
-
 
1284
        mov     ecx, [ext2_data.blocks_per_group]
-
 
1285
        and     ecx, not (32-1)                     ;обнуляем все кроме последних 5 бит
-
 
1286
        mov     edx, ecx
-
 
1287
        mov     ebx, 1
-
 
1288
    @@:
-
 
1289
        jecxz   .no_space
-
 
1290
        mov     edx, ebx
-
 
1291
        or      edx, eax                            ; тестируем очередной бит
-
 
1292
        shl     ebx, 1
-
 
1293
        jmp     @B
-
 
1294
    @@:
-
 
1295
        sub     edx, ecx
-
 
1296
        dec     edx                                 ;номер в последнем блоке
-
 
1297
 
-
 
1298
 
-
 
1299
    .no_space:
-
 
1300
        xor     eax, eax
-
 
1301
        ret
-
 
1302
 
-
 
1303
;in: eax = i_block
-
 
1304
;    ebx = pointer to memory
-
 
1305
ext2_set_block:
-
 
1306
        push    eax ebx ecx
-
 
1307
        mov     ecx, [ext2_data.log_block_size]
-
 
1308
        shl     eax, cl
-
 
1309
        add     eax, [PARTITION_START]
-
 
1310
        mov     ecx, [ext2_data.count_block_in_block]
-
 
1311
    @@:
-
 
1312
        call    hd_write
-
 
1313
        inc     eax
-
 
1314
        add     ebx, 512
-
 
1315
        loop    @B
-
 
1316
        pop     ecx ebx eax
-
 
1317
        ret
-
 
1318
-