Subversion Repositories Kolibri OS

Rev

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

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