Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1378 turbanoff 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
1384 turbanoff 5
;;   02.02.2010  turbanoff  - support 70.5                      ;;
6
;;   23.01.2010  turbanoff  - support 70.0 70.1                 ;;
1378 turbanoff 7
;;                                                              ;;
8
;;                                                              ;;
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
 
11
$Revision: 1410 $
12
 
13
EXT2_BAD_INO        = 1
14
EXT2_ROOT_INO        = 2
15
EXT2_ACL_IDX_INO    = 3
16
EXT2_ACL_DATA_INO    = 4
17
EXT2_BOOT_LOADER_INO= 5
18
EXT2_UNDEL_DIR_INO    = 6
19
 
20
;type inode
1384 turbanoff 21
EXT2_S_IFREG        = 0x8000
22
EXT2_S_IFDIR        = 0x4000
1378 turbanoff 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_IROTH        = 0x0002
34
EXT2_S_IROTH        = 0x0001
35
 
36
EXT2_FT_REG_FILE        = 1     ;это файл, запись в родительском каталоге
37
EXT2_FT_DIR             = 2     ;это папка
38
 
1400 turbanoff 39
FS_FT_HIDDEN            = 2
1378 turbanoff 40
FS_FT_DIR               = 0x10  ;это папка
41
FS_FT_ASCII             = 0     ;имя в ascii
42
FS_FT_UNICODE           = 1     ;имя в unicode
43
 
1410 turbanoff 44
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002
45
 
1397 turbanoff 46
uglobal
47
    EXT2_files_in_folder    dd ?   ;всего файлов в папке
48
    EXT2_read_in_folder     dd ?   ;сколько файлов "считали"
49
    EXT2_end_block          dd ?   ;конец очередного блока папки
50
    EXT2_counter_blocks     dd ?
51
    EXT2_filename           db 256 dup ?
52
endg
53
 
1378 turbanoff 54
struct EXT2_INODE_STRUC
55
    .i_mode         dw ?
56
    .i_uid          dw ?
57
    .i_size         dd ?
58
    .i_atime        dd ?
59
    .i_ctime        dd ?
60
    .i_mtime        dd ?
61
    .i_dtime        dd ?
62
    .i_gid          dw ?
63
    .i_links_count  dw ?
64
    .i_blocks       dd ?
65
    .i_flags        dd ?
66
    .i_osd1         dd ?
67
    .i_block        dd 15 dup ?
68
    .i_generation   dd ?
69
    .i_file_acl     dd ?
70
    .i_dir_acl      dd ?
71
    .i_faddr        dd ?
72
    .i_osd2         dd ? ; 1..12
73
ends
74
 
75
struct EXT2_DIR_STRUC
76
    .inode          dd ?
77
    .rec_len        dw ?
78
    .name_len       db ?
79
    .file_type      db ?
80
    .name           db ? ; 0..255
81
ends
82
 
83
 
84
ext2_test_superblock:
1410 turbanoff 85
        cmp     [fs_type], 0x83
86
        jne     .no
87
 
1378 turbanoff 88
        mov     eax, [PARTITION_START]
89
        add     eax, 2                  ;superblock start at 1024b
90
        call    hd_read
91
 
92
        cmp     dword [ebx+24], 3       ;s_block_size 0,1,2,3
93
        ja      .no
94
        cmp     word [ebx+56], 0xEF53   ;s_magic
95
        jne     .no
96
        cmp     word [ebx+58], 1        ;s_state (EXT_VALID_FS=1)
97
        jne     .no
1410 turbanoff 98
        mov     eax, [ebx+96]
99
        test    eax, EXT2_FEATURE_INCOMPAT_FILETYPE
100
        jz      .no
101
        test    eax, not EXT2_FEATURE_INCOMPAT_FILETYPE
102
        jnz     .no
1378 turbanoff 103
 
104
    ; OK, this is correct EXT2 superblock
105
        clc
106
        ret
107
   .no:
108
    ; No, this superblock isn't EXT2
109
        stc
110
        ret
111
 
112
ext2_setup:
113
        mov     [fs_type], 2
114
        mov     ecx, [ebx+24]
115
        inc     ecx
116
        mov     [ext2_data.log_block_size], ecx    ; 1, 2, 3, 4   equ 1kb, 2kb, 4kb, 8kb
117
 
118
        mov     eax, 1
119
        shl     eax, cl
120
        mov     [ext2_data.count_block_in_block], eax
121
 
122
        shl     eax, 7
123
        mov     [ext2_data.count_pointer_in_block], eax
124
        mov     edx, eax                                ; потом еще квадрат найдем
125
 
126
        shl     eax, 2
127
        mov     [ext2_data.block_size], eax
128
 
1387 turbanoff 129
        push    eax eax eax                             ; 3 kernel_alloc
1378 turbanoff 130
 
131
        mov     eax, edx
132
        mul     edx
133
        mov     [ext2_data.count_pointer_in_block_square], eax
134
 
135
        call    kernel_alloc
1387 turbanoff 136
        mov     [ext2_data.global_desc_table],eax       ; reserve mem for gdt
1378 turbanoff 137
        call    kernel_alloc
138
        mov     [ext2_data.ext2_save_block], eax        ; and for temp block
139
        call    kernel_alloc
140
        mov     [ext2_data.ext2_temp_block], eax        ; and for get_inode proc
141
 
1384 turbanoff 142
        movzx   ebp, word [ebx+88]
1378 turbanoff 143
        mov     ecx, [ebx+32]
144
        mov     edx, [ebx+40]
145
        mov     eax, [ebx+20]                           ; first_data_block
146
 
147
        mov     [ext2_data.inode_size], ebp
148
        mov     [ext2_data.blocks_per_group], ecx
149
        mov     [ext2_data.inodes_per_group], edx
150
 
151
        mov     ebx, [ext2_data.global_desc_table]
152
        inc     eax                                     ; first_data_block + 1 = gdt
153
        call    ext2_get_block                          ; read gtd
154
 
155
        push    ebp ebp ebp                             ;3 kernel_alloc
156
        call    kernel_alloc
157
        mov     [ext2_data.ext2_save_inode], eax
158
        call    kernel_alloc
159
        mov     [ext2_data.ext2_temp_inode], eax
160
        call    kernel_alloc
161
        mov     [ext2_data.root_inode], eax
162
 
163
        mov     ebx, eax
164
        mov     eax, EXT2_ROOT_INO
165
        call    ext2_get_inode                          ; read root inode
1410 turbanoff 166
	jmp	return_from_part_set
1378 turbanoff 167
 
168
;==================================================================
169
;in: eax = i_block
170
;    ebx = pointer to return memory
171
ext2_get_block:
172
        push    eax ebx ecx
173
        mov     ecx, [ext2_data.log_block_size]
174
        shl     eax, cl
175
        add     eax, [PARTITION_START]
176
        mov     ecx, [ext2_data.count_block_in_block]
177
    @@:
178
        call    hd_read
179
        inc     eax
180
        add     ebx, 512
181
        loop    @B
182
        pop     ecx ebx eax
183
        ret
184
;===================================================================
1387 turbanoff 185
; in:  ecx = номер блока в inode (0..)
1378 turbanoff 186
;      ebp = адрес inode
187
; out: ecx = адрес очередного блока
188
ext2_get_inode_block:
1387 turbanoff 189
        cmp     ecx, 12                                         ; 0..11 - direct block address
190
        jb      .get_direct_block
1378 turbanoff 191
 
192
        sub     ecx, 12
1387 turbanoff 193
        cmp     ecx, [ext2_data.count_pointer_in_block]         ; 12.. - indirect block
194
        jb      .get_indirect_block
1378 turbanoff 195
 
196
        sub     ecx, [ext2_data.count_pointer_in_block]
197
        cmp     ecx, [ext2_data.count_pointer_in_block_square]
1387 turbanoff 198
        jb      .get_double_indirect_block
1378 turbanoff 199
 
1387 turbanoff 200
        sub     ecx, [ext2_data.count_pointer_in_block_square]
1378 turbanoff 201
    ;.get_triple_indirect_block:
202
        push    eax edx ebx
203
 
204
        mov    eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
205
        mov    ebx, [ext2_data.ext2_temp_block]
206
        call    ext2_get_block
207
 
208
        xor     edx, edx
209
        mov     eax, ecx
210
        div     [ext2_data.count_pointer_in_block_square]
211
 
212
    ;eax - номер в полученном блоке   edx - номер дальше
213
        mov    eax, [ebx + eax*4]
1387 turbanoff 214
        call   ext2_get_block
1378 turbanoff 215
 
216
        mov    eax, edx
217
        jmp    @F
218
 
219
    .get_double_indirect_block:
220
        push    eax edx ebx
221
 
222
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
223
        mov     ebx, [ext2_data.ext2_temp_block]
224
        call    ext2_get_block
225
 
226
        mov     eax, ecx
227
      @@:
228
        xor     edx, edx
229
        div     [ext2_data.count_pointer_in_block]
230
 
231
        mov    eax, [ebx + eax*4]
232
        call    ext2_get_block
233
        mov    ecx, [ebx + edx*4]
234
 
235
        pop     ebx edx eax
236
        ret
237
 
238
    .get_indirect_block:
239
        push    eax ebx
240
        mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
1387 turbanoff 241
        mov     ebx, [ext2_data.ext2_temp_block]
1378 turbanoff 242
        call    ext2_get_block
243
 
244
        mov     ecx, [ebx + ecx*4]
245
        pop     ebx eax
246
        ret
247
 
248
    .get_direct_block:
249
        mov     ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
250
        ret
251
 
252
 
253
;===================================================================
254
;get content inode by num
255
;in:   eax = inode_num
256
;      ebx = address of inode content
257
ext2_get_inode:
258
 
259
    pushad
260
    mov     edi, ebx        ;сохраним адрес inode
261
    dec    eax
262
    xor    edx, edx
263
    div    [ext2_data.inodes_per_group]
264
 
265
        push    edx                             ;locale num
266
 
267
        mov     edx, 32
268
        mul     edx                             ; address block_group in global_desc_table
269
 
270
        add     eax, [ext2_data.global_desc_table]
271
        mov     eax, [eax+8]                    ; номер блока - в терминах ext2
272
 
273
        mov     ecx, [ext2_data.log_block_size]
274
        shl     eax, cl
275
        add     eax, [PARTITION_START]          ; а старт раздела - в терминах hdd (512)
276
 
277
        ;eax - указывает на таблицу inode-ов на hdd
1410 turbanoff 278
        mov     esi, eax                        ;сохраним его пока в esi
1378 turbanoff 279
 
280
        ; прибавим локальный адрес inode-а
281
        pop     eax                             ; index
1410 turbanoff 282
        mov     ecx, [ext2_data.inode_size]
283
        mul     ecx                             ; (index * inode_size)
1378 turbanoff 284
        mov     ebp, 512
285
        div     ebp                             ;поделим на размер блока
286
 
1410 turbanoff 287
        add     eax, esi                        ;нашли адрес блока для чтения
1378 turbanoff 288
        mov     ebx, [ext2_data.ext2_temp_block]
289
        call    hd_read
290
 
291
        mov     esi, edx                        ;добавим "остаток"
292
        add     esi, ebx                        ;к адресу
1410 turbanoff 293
       ; mov     ecx, [ext2_data.inode_size]
1378 turbanoff 294
        rep     movsb                           ;копируем inode
295
        popad
296
        ret
297
 
298
;----------------------------------------------------------------
299
; in:  esi -> children
300
;      ebx -> pointer to dir block
301
; out: esi -> name without parent or not_changed
302
;      ebx -> dir_rec of inode children      or trash
303
ext2_test_block_by_name:
304
        push    eax ecx edx edi
305
 
306
        mov        edx, ebx
307
        add        edx, [ext2_data.block_size]    ;запомним конец блока
308
 
309
        .start_rec:
310
            cmp     [ebx + EXT2_DIR_STRUC.inode], 0
311
            jz      .next_rec
312
 
313
            push    esi
314
            movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
1397 turbanoff 315
            mov     edi, EXT2_filename
316
            lea     esi, [ebx + EXT2_DIR_STRUC.name]
1378 turbanoff 317
 
1397 turbanoff 318
            call    utf8toansi_str
319
            mov     ecx, edi
320
            sub     ecx, EXT2_filename      ;кол-во байт в получившейся строке
321
 
322
            mov     edi, EXT2_filename
323
            mov     esi, [esp]
1378 turbanoff 324
          @@:
1397 turbanoff 325
                jecxz   .test_find
1378 turbanoff 326
                dec     ecx
1397 turbanoff 327
 
1378 turbanoff 328
                lodsb
1397 turbanoff 329
                call    char_toupper
330
 
1378 turbanoff 331
                mov     ah, [edi]
332
                inc     edi
333
                xchg    al, ah
1397 turbanoff 334
                call    char_toupper
1378 turbanoff 335
                cmp     al, ah
336
                je      @B
337
          @@:                           ;не подошло
338
            pop     esi
339
        .next_rec:
340
            movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
341
            add     ebx, eax                                ;к след. записи
342
            cmp     ebx, edx                                ;проверим конец ли
1384 turbanoff 343
            jb      .start_rec
1378 turbanoff 344
            jmp     .ret
345
 
346
    .test_find:
347
        cmp     byte [esi], 0
348
        je      .find               ;нашли конец
349
        cmp     byte [esi], '/'
350
        jne      @B
351
        inc     esi
352
    .find:
353
        pop eax         ;удаляем из стека сохраненое значение
354
    .ret:
355
        pop edi edx ecx eax
356
        ret
357
 
358
;----------------------------------------------------------------
359
;
360
;  ext2_HdReadFolder - read disk folder
361
;
362
;  esi  points to filename
363
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
364
;                          & flags (bitfields)
365
; flags: bit 0: 0=ANSI names, 1=UNICODE names
366
;  ecx  number of blocks to read, 0+
367
;  edx  mem location to return data
368
;
369
;  ret ebx = blocks read or 0xffffffff folder not found
370
;      eax = 0 ok read or other = errormsg
371
;
372
;--------------------------------------------------------------
373
ext2_HdReadFolder:
374
        cmp     byte [esi], 0
1387 turbanoff 375
        jz      .doit
1378 turbanoff 376
 
1387 turbanoff 377
        push    ecx ebx
378
        call    ext2_find_lfn
379
        jnc     .doit2
380
        pop     ebx
1378 turbanoff 381
    .not_found:
1387 turbanoff 382
        pop     ecx
1378 turbanoff 383
        or      ebx, -1
384
        mov     eax, ERROR_FILE_NOT_FOUND
385
        ret
1387 turbanoff 386
 
387
    .doit:
388
        mov     ebp, [ext2_data.root_inode]
389
        push    ecx
390
        jmp     @F
391
    .doit2:
392
        pop     ebx
393
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
394
        jz      .not_found
395
    @@:
396
        xor     eax, eax
397
        mov     edi, edx
398
        mov     ecx, 32/4
399
        rep     stosd                           ; fill header zero
400
        pop     edi                             ; edi = число блоков для чтения
401
        push    edx ebx
402
 
1378 turbanoff 403
     ;--------------------------------------------- final step
404
        and     [EXT2_read_in_folder], 0
405
        and     [EXT2_files_in_folder], 0
406
 
1384 turbanoff 407
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]
408
        mov     [EXT2_counter_blocks], eax
1378 turbanoff 409
 
1397 turbanoff 410
        add     edx, 32                         ; (header pointer in stack) edx = current mem for return
1387 turbanoff 411
        xor     esi, esi                        ; esi = номер блока по порядку
1378 turbanoff 412
 
413
    .new_block_folder:              ;reserved label
414
        mov     ecx, esi                        ; получим номер блока
415
        call    ext2_get_inode_block
416
 
417
        mov     eax, ecx
418
        mov     ebx, [ext2_data.ext2_save_block]
419
        call    ext2_get_block                  ; и считываем блок с hdd
420
 
421
        mov     eax, ebx                        ; eax = current dir record
422
        add     ebx, [ext2_data.block_size]
423
        mov     [EXT2_end_block], ebx           ; запомним конец очередного блока
424
 
425
        pop     ecx
426
        mov     ecx, [ecx]                      ; ecx = first wanted (flags ommited)
427
 
428
    .find_wanted_start:
1398 turbanoff 429
            jecxz   .find_wanted_end
1378 turbanoff 430
    .find_wanted_cycle:
431
            cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
1397 turbanoff 432
            jz      @F
1378 turbanoff 433
            inc     [EXT2_files_in_folder]
1398 turbanoff 434
            dec     ecx
1378 turbanoff 435
          @@:
436
            movzx   ebx, [eax+EXT2_DIR_STRUC.rec_len]
437
            add     eax, ebx                            ; к следующей записи
438
            cmp     eax, [EXT2_end_block]              ; проверяем "конец"
1398 turbanoff 439
            jb      .find_wanted_start
440
 
1400 turbanoff 441
		push	.find_wanted_start
442
   .end_block:                                   		;вылетили из цикла
1398 turbanoff 443
        mov     ebx, [ext2_data.count_block_in_block]
444
        sub     [EXT2_counter_blocks], ebx
1400 turbanoff 445
        jbe      .end_dir
1398 turbanoff 446
 
1400 turbanoff 447
        inc     esi										;получаем новый блок
1398 turbanoff 448
        push    ecx
449
        mov     ecx, esi
450
        call    ext2_get_inode_block
451
        mov     eax, ecx
452
        mov     ebx, [ext2_data.ext2_save_block]
453
        call    ext2_get_block
454
        pop     ecx
455
        mov     eax, ebx
456
        add     ebx, [ext2_data.block_size]
457
        mov     [EXT2_end_block], ebx
1400 turbanoff 458
        ret												; опять в цикл
1398 turbanoff 459
 
1400 turbanoff 460
    .wanted_end:
461
    	loop	.find_wanted_cycle                      ; ecx = -1
462
 
1378 turbanoff 463
    .find_wanted_end:
1398 turbanoff 464
        mov     ecx, edi
1378 turbanoff 465
    .wanted_start:                                      ; ищем first_wanted+count
1400 turbanoff 466
            jecxz   .wanted_end
1378 turbanoff 467
            cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
468
            jz      .empty_rec
469
            inc     [EXT2_files_in_folder]
470
            inc     [EXT2_read_in_folder]
471
 
1384 turbanoff 472
            mov     edi, edx
473
            push    eax ecx
474
            xor     eax, eax
475
            mov     ecx, 40 / 4
476
            rep     stosd
477
            pop     ecx eax
1378 turbanoff 478
 
1400 turbanoff 479
            push    eax esi edx                                        ;получим inode
1378 turbanoff 480
            mov     eax, [eax + EXT2_DIR_STRUC.inode]
481
            mov     ebx, [ext2_data.ext2_temp_inode]
482
            call    ext2_get_inode
1400 turbanoff 483
 
484
            lea     edi, [edx + 8]
485
 
486
            mov     eax, [ebx + EXT2_INODE_STRUC.i_ctime]           ; переведем время в ntfs формат
487
            xor     edx, edx
488
            add     eax, 3054539008                                 ;(369 * 365 + 89) * 24 * 3600
489
            adc     edx, 2
490
            call    ntfs_datetime_to_bdfe.sec
491
 
492
            mov     eax, [ebx + EXT2_INODE_STRUC.i_atime]
493
            xor     edx, edx
494
            add     eax, 3054539008
495
            adc     edx, 2
496
            call    ntfs_datetime_to_bdfe.sec
497
 
498
            mov     eax, [ebx + EXT2_INODE_STRUC.i_mtime]
499
            xor     edx, edx
500
            add     eax, 3054539008
501
            adc     edx, 2
502
            call    ntfs_datetime_to_bdfe.sec
503
 
504
            pop     edx                                             ; пока достаем только буфер
505
            test    [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR   ; для папки размер
506
            jnz     @F                                              ; не возвращаем
507
 
1378 turbanoff 508
            mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
1400 turbanoff 509
            stosd
510
            mov     eax, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
511
            stosd
1378 turbanoff 512
            xor     dword [edx], FS_FT_DIR
1400 turbanoff 513
        @@:
514
            xor     dword [edx], FS_FT_DIR
515
            pop     esi eax
516
 
1384 turbanoff 517
            or      dword [edx+4], FS_FT_ASCII      ; symbol type in name
1378 turbanoff 518
 
1400 turbanoff 519
            ;теперь скопируем имя, сконвертировав из UTF-8 в CP866
1397 turbanoff 520
            push    eax ecx esi
1378 turbanoff 521
            movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
1397 turbanoff 522
            lea     edi, [edx + 40]
1378 turbanoff 523
            lea     esi, [eax + EXT2_DIR_STRUC.name]
1397 turbanoff 524
            call    utf8toansi_str
525
            pop     esi ecx eax
1378 turbanoff 526
            and     byte [edi], 0
527
 
1400 turbanoff 528
            cmp     byte [edx + 40], '.'
529
            jne     @F
530
            or      dword [edx], FS_FT_HIDDEN
531
        @@:
532
 
1378 turbanoff 533
            add     edx, 40 + 264                       ; go to next record
1397 turbanoff 534
            dec     ecx                                 ; если запись пустая ecx не надо уменьшать
1378 turbanoff 535
        .empty_rec:
536
            movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
537
            add     eax, ebx
538
            cmp     eax, [EXT2_end_block]
1397 turbanoff 539
            jb      .wanted_start
1378 turbanoff 540
 
1400 turbanoff 541
        push    .wanted_start                           ; дошли до конца очередного блока
542
        jmp     .end_block
1378 turbanoff 543
 
544
    .end_dir:
1400 turbanoff 545
    	pop     eax		; мусор (адрес возврата в цикл)
1378 turbanoff 546
        pop     edx
547
        mov     ebx, [EXT2_read_in_folder]
548
        mov     ecx, [EXT2_files_in_folder]
549
        mov     dword [edx], 1    ;version
550
        xor     eax, eax
551
        mov     [edx+4], ebx
552
        mov     [edx+8], ecx
553
        lea     edi, [edx + 12]
554
        mov     ecx, 20 / 4
555
        rep     stosd
556
        ret
557
;====================== end ext2_HdReadFolder
1397 turbanoff 558
utf8toansi_str:
559
; convert UTF-8 string to ASCII-string (codepage 866)
560
; in: ecx=length source, esi->source, edi->buffer
561
; destroys: eax,esi,edi
562
        jecxz   .ret
563
    .start:
564
        lodsw
565
        cmp     al, 0x80
566
        jb      .ascii
1378 turbanoff 567
 
1400 turbanoff 568
        xchg    al, ah              ; big-endian
1397 turbanoff 569
        cmp     ax, 0xd080
570
        jz      .yo1
571
        cmp     ax, 0xd191
572
        jz      .yo2
573
        cmp     ax, 0xd090
574
        jb      .unk
575
        cmp     ax, 0xd180
576
        jb      .rus1
577
        cmp     ax, 0xd190
578
        jb      .rus2
579
    .unk:
580
        mov     al, '_'
581
        jmp     .doit
582
    .yo1:
583
        mov     al, 0xf0    ; Ё capital
584
        jmp     .doit
585
    .yo2:
586
        mov     al, 0xf1    ; ё small
587
        jmp     .doit
588
    .rus1:
589
        sub     ax, 0xd090 - 0x80
590
        jmp     .doit
591
    .rus2:
592
        sub     ax, 0xd18f - 0xEF
593
    .doit:
594
        stosb
595
        sub     ecx, 2
596
        ja      .start
597
        ret
598
 
599
    .ascii:
600
        stosb
601
        dec     esi
602
        dec     ecx
603
        jnz     .start
604
    .ret:
605
        ret
606
 
1378 turbanoff 607
;----------------------------------------------------------------
608
;
609
;  ext2_HdRead - read hard disk
610
;
611
;  esi  points to filename
612
;  ebx  pointer to 64-bit number = first wanted byte, 0+
613
;       may be ebx=0 - start from first byte
614
;  ecx  number of bytes to read, 0+
615
;  edx  mem location to return data
616
;
617
;  ret ebx = bytes read or 0xffffffff file not found
618
;      eax = 0 ok read or other = errormsg
619
;
620
;--------------------------------------------------------------
621
ext2_HdRead:
622
        cmp     byte [esi], 0
1397 turbanoff 623
        jnz     @F
1378 turbanoff 624
 
1384 turbanoff 625
    .this_is_nofile:
1378 turbanoff 626
        or      ebx, -1
627
        mov     eax, ERROR_ACCESS_DENIED
628
        ret
629
 
1397 turbanoff 630
    @@:
631
        push    ecx ebx
632
        call    ext2_find_lfn
633
        pop     ebx ecx
634
        jnc     .doit
635
    ;.not_found:
636
        or      ebx, -1
637
        mov     eax, ERROR_FILE_NOT_FOUND
638
        ret
639
 
640
    .doit:
641
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
642
        jz      .this_is_nofile
643
 
1378 turbanoff 644
    ;-----------------------------------------------------------------------------final step
1397 turbanoff 645
        mov     edi, edx            ; edi = pointer to return mem
646
        mov     esi, ebx            ; esi = pointer to first_wanted
1378 turbanoff 647
 
648
        ;///// сравним хватит ли нам файла или нет
649
        mov     ebx, [esi+4]
650
        mov     eax, [esi]          ; ebx : eax - стартовый номер байта
651
 
1397 turbanoff 652
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
1378 turbanoff 653
        ja      .size_great
654
        jb      .size_less
655
 
1397 turbanoff 656
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
1378 turbanoff 657
        ja      .size_great
658
 
659
    .size_less:
1397 turbanoff 660
        xor     ebx, ebx
1378 turbanoff 661
        mov     eax, 6      ;EOF
662
        ret
663
    .size_great:
1397 turbanoff 664
        add     eax, ecx                  ;add to first_wanted кол-во байт для чтения
665
        adc     ebx, 0
666
 
667
        cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
1378 turbanoff 668
        ja      .size_great_great
669
        jb      .size_great_less
1397 turbanoff 670
        cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
671
        jae     .size_great_great               ; а если равно, то не важно куда
672
 
1378 turbanoff 673
    .size_great_less:
674
        or      [EXT2_files_in_folder], 1       ;читаем по границе размера
1397 turbanoff 675
        mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]
676
        sub     ecx, [esi]                      ;(размер - старт)
1378 turbanoff 677
        jmp     @F
678
 
679
    .size_great_great:
1397 turbanoff 680
        and     [EXT2_files_in_folder], 0       ;читаем столько сколько запросили
1378 turbanoff 681
 
682
    @@:
1397 turbanoff 683
        push    ecx                             ;save for return
684
        test    esi, esi
685
        jz      .zero_start
1378 turbanoff 686
 
687
        ;пока делаем п..ц криво =)
1397 turbanoff 688
        mov     edx, [esi+4]
689
        mov     eax, [esi]
1378 turbanoff 690
        div     [ext2_data.block_size]
691
 
692
        mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
693
 
694
        push    ecx
695
        mov     ecx, eax
696
        call    ext2_get_inode_block
1397 turbanoff 697
        mov     ebx, [ext2_data.ext2_save_block]
1378 turbanoff 698
        mov     eax, ecx
699
        call    ext2_get_block
700
        pop     ecx
701
        add     ebx, edx
702
 
703
        neg     edx
1397 turbanoff 704
        add     edx,[ext2_data.block_size]      ;block_size - стартовый байт = сколько байт 1-го блока
1378 turbanoff 705
        cmp     ecx, edx
706
        jbe     .only_one_block
707
 
708
        mov     eax, ecx
709
        sub     eax, edx
710
        mov     ecx, edx
711
 
712
        mov     esi, ebx
713
        rep     movsb                           ;кусок 1-го блока
1389 turbanoff 714
        jmp     @F
1378 turbanoff 715
 
716
    .zero_start:
1389 turbanoff 717
        mov     eax, ecx
1378 turbanoff 718
        ;теперь в eax кол-во оставшихся байт для чтения
1389 turbanoff 719
    @@:
1397 turbanoff 720
        mov     ebx, edi                        ;чтение блока прям в ->ebx
1378 turbanoff 721
        xor     edx, edx
1389 turbanoff 722
        div     [ext2_data.block_size]          ;кол-во байт в последнем блоке (остаток) в edx
1397 turbanoff 723
        mov     edi, eax                        ;кол-во целых блоков в edi
1378 turbanoff 724
    @@:
1397 turbanoff 725
        test     edi, edi
1378 turbanoff 726
        jz      .finish_block
727
        inc     [EXT2_counter_blocks]
728
        mov     ecx, [EXT2_counter_blocks]
729
        call    ext2_get_inode_block
730
 
1397 turbanoff 731
        mov     eax, ecx                        ;а ebx уже забит нужным значением
1378 turbanoff 732
        call    ext2_get_block
733
        add     ebx, [ext2_data.block_size]
734
 
1397 turbanoff 735
        dec     edi
1378 turbanoff 736
        jmp     @B
737
 
738
    .finish_block:          ;в edx - кол-во байт в последнем блоке
1397 turbanoff 739
        test    edx, edx
740
        jz      .end_read
1378 turbanoff 741
 
742
        mov     ecx, [EXT2_counter_blocks]
743
        inc     ecx
744
        call    ext2_get_inode_block
745
 
746
        mov     edi, ebx
747
        mov     eax, ecx
748
        mov     ebx, [ext2_data.ext2_save_block]
749
        call    ext2_get_block
750
 
751
        mov     ecx, edx
752
 
753
    .only_one_block:
754
        mov     esi, ebx
1389 turbanoff 755
        rep     movsb                           ;кусок last блока
756
    .end_read:
1378 turbanoff 757
        pop     ebx
758
        cmp     [EXT2_files_in_folder], 0
759
        jz      @F
760
 
761
        mov     eax, 6      ;EOF
762
        ret
763
    @@:
764
        xor     eax, eax
765
        ret
766
;========================
1400 turbanoff 767
;in : esi -> name           not save: eax ebx ecx
1384 turbanoff 768
;out: ebp -> inode cf=0
769
;     ebp -> trash cf=1
770
ext2_find_lfn:
771
        mov     ebp, [ext2_data.root_inode]
772
    .next_folder:
773
        or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
774
        mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
775
        add     eax, [ext2_data.count_block_in_block]
776
        mov     [EXT2_end_block], eax
777
    .next_block_folder:
778
        mov     eax, [ext2_data.count_block_in_block]
779
        sub     [EXT2_end_block], eax
780
        jz      .not_found
781
        inc     [EXT2_counter_blocks]
782
        mov     ecx, [EXT2_counter_blocks]
783
        call    ext2_get_inode_block
1378 turbanoff 784
 
1384 turbanoff 785
        mov     eax, ecx
786
        mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
787
        call    ext2_get_block
788
 
789
        mov     eax, esi
790
        call    ext2_test_block_by_name
791
        cmp     eax, esi                                ;нашли имя?
792
        jz      .next_block_folder
793
 
794
        cmp     byte [esi],0
795
        jz      .get_inode_ret
796
 
797
        cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
798
        jne     .not_found                                      ;нашли, но это не папка
799
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
800
        mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
801
        call    ext2_get_inode
802
        mov     ebp, ebx
803
        jmp     .next_folder
804
 
805
    .not_found:
806
        stc
807
        ret
808
    .get_inode_ret:
1400 turbanoff 809
        mov     [EXT2_end_block], ebx                           ; сохраняем указатеть на dir_rec
1384 turbanoff 810
        mov     eax, [ebx + EXT2_DIR_STRUC.inode]
811
        mov     ebx, [ext2_data.ext2_save_inode]
812
        call    ext2_get_inode
813
        mov     ebp, ebx
814
        clc
815
        ret
816
 
817
 
818
;========================
1378 turbanoff 819
ext2_HdRewrite:
820
;    xchg    bx, bx
821
        xor     ebx, ebx
822
        mov     eax, ERROR_UNSUPPORTED_FS
823
        ret
824
 
825
ext2_HdWrite:
826
;    xchg    bx, bx
827
        xor     ebx, ebx
828
        mov     eax, ERROR_UNSUPPORTED_FS
829
        ret
830
ext2_HdSetFileEnd:
831
;    xchg    bx, bx
832
        xor     ebx, ebx
833
        mov     eax, ERROR_UNSUPPORTED_FS
834
        ret
1384 turbanoff 835
 
1378 turbanoff 836
ext2_HdGetFileInfo:
1384 turbanoff 837
        cmp     byte [esi], 0
838
        jz      .doit
839
 
840
        call    ext2_find_lfn
841
        jnc     .doit2
842
    ;.not_found:
843
        mov     eax, ERROR_FILE_NOT_FOUND
1378 turbanoff 844
        ret
1384 turbanoff 845
 
846
    .doit:
847
        mov     ebp, [ext2_data.root_inode]
1400 turbanoff 848
        mov     ebx, .doit                        ;неважно что лишь бы этому адресу не '.'
849
        jmp     @F
1384 turbanoff 850
    .doit2:
1400 turbanoff 851
        mov     ebx, [EXT2_end_block]
852
        add     ebx, EXT2_DIR_STRUC.name
853
    @@:
1384 turbanoff 854
        xor     eax, eax
855
        mov     edi, edx
856
        mov     ecx, 40/4
1400 turbanoff 857
        rep     stosd               ; fill zero
1384 turbanoff 858
 
1400 turbanoff 859
        cmp     byte [ebx], '.'
860
        jnz     @F
861
        or      dword [edx], FS_FT_HIDDEN
862
    @@:
863
 
1384 turbanoff 864
        test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
1400 turbanoff 865
        jnz      @F
1384 turbanoff 866
        mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
867
        mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
868
        mov     dword [edx+32], eax
869
        mov     dword [edx+36], ebx
1400 turbanoff 870
        xor     dword [edx], FS_FT_DIR
871
    @@:
872
        xor     dword [edx], FS_FT_DIR
1384 turbanoff 873
 
1400 turbanoff 874
        lea     edi, [edx + 8]
875
        mov     eax, [ebx + EXT2_INODE_STRUC.i_ctime]
876
        xor     edx, edx
877
        add     eax, 3054539008
878
        adc     edx, 2
879
        call    ntfs_datetime_to_bdfe.sec
880
 
881
        mov     eax, [ebx + EXT2_INODE_STRUC.i_atime]
882
        xor     edx, edx
883
        add     eax, 3054539008
884
        adc     edx, 2
885
        call    ntfs_datetime_to_bdfe.sec
886
 
887
        mov     eax, [ebx + EXT2_INODE_STRUC.i_mtime]
888
        xor     edx, edx
889
        add     eax, 3054539008
890
        adc     edx, 2
891
        call    ntfs_datetime_to_bdfe.sec
892
 
1384 turbanoff 893
        xor     eax, eax
894
        ret
895
 
1378 turbanoff 896
ext2_HdSetFileInfo:
897
;    xchg    bx, bx
898
        xor     ebx, ebx
899
        mov     eax, ERROR_UNSUPPORTED_FS
900
        ret
901
ext2_HdDelete:
902
;    xchg    bx, bx
903
        xor     ebx, ebx
904
        mov     eax, ERROR_UNSUPPORTED_FS
905
        ret
906