Subversion Repositories Kolibri OS

Rev

Rev 1387 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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