Subversion Repositories Kolibri OS

Rev

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