Subversion Repositories Kolibri OS

Rev

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. ;;                                                              ;;
  6. ;;   23.01.2010  turbanoff  - read from ext2fs                  ;;
  7. ;;                                                              ;;
  8. ;;                                                              ;;
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10.  
  11. $Revision: 1378 $
  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.         mov     ebp, [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 = номер блока
  172. ;      ebp = адрес inode
  173. ; out: ecx = адрес очередного блока
  174. ext2_get_inode_block:
  175.         cmp     ecx, 12
  176.         jbe     .get_direct_block
  177.  
  178.         sub     ecx, 12
  179.         cmp     ecx, [ext2_data.count_pointer_in_block]
  180.         jbe     .get_indirect_block
  181.  
  182.         sub     ecx, [ext2_data.count_pointer_in_block]
  183.         cmp     ecx, [ext2_data.count_pointer_in_block_square]
  184.         jbe     .get_double_indirect_block
  185.  
  186.     ;.get_triple_indirect_block:
  187.         push    eax edx ebx
  188.  
  189.         mov    eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
  190.         mov    ebx, [ext2_data.ext2_temp_block]
  191.         call    ext2_get_block
  192.  
  193.         xor     edx, edx
  194.         mov     eax, ecx
  195.         div     [ext2_data.count_pointer_in_block_square]
  196.  
  197.     ;eax - номер в полученном блоке   edx - номер дальше
  198.         mov    eax, [ebx + eax*4]
  199.         call    ext2_get_block
  200.  
  201.         mov    eax, edx
  202.         jmp    @F
  203.  
  204.     .get_double_indirect_block:
  205.         push    eax edx ebx
  206.  
  207.         mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
  208.         mov     ebx, [ext2_data.ext2_temp_block]
  209.         call    ext2_get_block
  210.  
  211.         mov     eax, ecx
  212.       @@:
  213.         xor     edx, edx
  214.         div     [ext2_data.count_pointer_in_block]
  215.  
  216.         mov    eax, [ebx + eax*4]
  217.         call    ext2_get_block
  218.         mov    ecx, [ebx + edx*4]
  219.  
  220.         pop     ebx edx eax
  221.         ret
  222.  
  223.     .get_indirect_block:
  224.         push    eax ebx
  225.         mov     eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
  226.         mov    ebx, [ext2_data.ext2_temp_block]
  227.         call    ext2_get_block
  228.  
  229.         mov     ecx, [ebx + ecx*4]
  230.         pop     ebx eax
  231.         ret
  232.  
  233.     .get_direct_block:
  234.         mov     ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
  235.         ret
  236.  
  237.  
  238. ;===================================================================
  239. ;get content inode by num
  240. ;in:   eax = inode_num
  241. ;      ebx = address of inode content
  242. ext2_get_inode:
  243.  
  244.     pushad
  245.     mov     edi, ebx        ;сохраним адрес inode
  246.     dec    eax
  247.     xor    edx, edx
  248.     div    [ext2_data.inodes_per_group]
  249.  
  250.         push    edx                             ;locale num
  251.  
  252.         mov     edx, 32
  253.         mul     edx                             ; address block_group in global_desc_table
  254.  
  255.         add     eax, [ext2_data.global_desc_table]
  256.         mov     eax, [eax+8]                    ; номер блока - в терминах ext2
  257.  
  258.         mov     ecx, [ext2_data.log_block_size]
  259.         shl     eax, cl
  260.         add     eax, [PARTITION_START]          ; а старт раздела - в терминах hdd (512)
  261.  
  262.         ;eax - указывает на таблицу inode-ов на hdd
  263.         mov     ecx, eax                        ;сохраним его пока в ecx
  264.  
  265.         ; прибавим локальный адрес inode-а
  266.         pop     eax                             ; index
  267.         mul     [ext2_data.inode_size]        ; (index * inode_size)
  268.         mov     ebp, 512
  269.         div     ebp                             ;поделим на размер блока
  270.  
  271.         add     eax, ecx                        ;нашли адрес блока для чтения
  272.         mov     ebx, [ext2_data.ext2_temp_block]
  273.         call    hd_read
  274.  
  275.         mov     esi, edx                        ;добавим "остаток"
  276.         add     esi, ebx                        ;к адресу
  277.         mov     ecx, [ext2_data.inode_size]
  278.         rep     movsb                           ;копируем inode
  279.         popad
  280.         ret
  281.  
  282. ;----------------------------------------------------------------
  283. ext2_upcase:
  284.         cmp     al, 'a'
  285.         jb      .ret
  286.         cmp     al, 'z'
  287.         ja      .ret
  288.         and     al, 0xDF        ; upcase = clear 0010 0000
  289.     .ret:
  290.         ret
  291. ;----------------------------------------------------------------
  292. ; in:  esi -> children
  293. ;      ebx -> pointer to dir block
  294. ; out: esi -> name without parent or not_changed
  295. ;      ebx -> dir_rec of inode children      or trash
  296. ext2_test_block_by_name:
  297.         push    eax ecx edx edi
  298.  
  299.         mov        edx, ebx
  300.         add        edx, [ext2_data.block_size]    ;запомним конец блока
  301.  
  302.         .start_rec:
  303.             cmp     [ebx + EXT2_DIR_STRUC.inode], 0
  304.             jz      .next_rec
  305. ;            test    [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
  306. ;            jz      .next_rec
  307.  
  308.             push    esi
  309.             movzx   ecx, [ebx + EXT2_DIR_STRUC.name_len]
  310.             lea     edi, [ebx + EXT2_DIR_STRUC.name]
  311.             inc     ecx
  312.  
  313.           @@:
  314.                 dec     ecx
  315.                 jecxz   .test_find
  316.                 lodsb
  317.                 mov     ah, [edi]
  318.                 inc     edi
  319.  
  320.                 call    ext2_upcase
  321.                 xchg    al, ah
  322.                 call    ext2_upcase
  323.                 cmp     al, ah
  324.                 je      @B
  325.           @@:                           ;не подошло
  326.             pop     esi
  327.         .next_rec:
  328.             movzx   eax, [ebx + EXT2_DIR_STRUC.rec_len]
  329.             add     ebx, eax                                ;к след. записи
  330.             cmp     ebx, edx                                ;проверим конец ли
  331.             jne     .start_rec
  332.             jmp     .ret
  333.  
  334.     .test_find:
  335.         cmp     byte [esi], 0
  336.         je      .find               ;нашли конец
  337.         cmp     byte [esi], '/'
  338.         jne      @B
  339.         inc     esi
  340.     .find:
  341.         pop eax         ;удаляем из стека сохраненое значение
  342.        ; mov ebx, [ebx + EXT2_DIR_STRUC.inode]
  343.     .ret:
  344.         pop edi edx ecx eax
  345.         ret
  346.  
  347. ;----------------------------------------------------------------
  348. ;
  349. ;  ext2_HdReadFolder - read disk folder
  350. ;
  351. ;  esi  points to filename
  352. ;  ebx  pointer to structure 32-bit number = first wanted block, 0+
  353. ;                          & flags (bitfields)
  354. ; flags: bit 0: 0=ANSI names, 1=UNICODE names
  355. ;  ecx  number of blocks to read, 0+
  356. ;  edx  mem location to return data
  357. ;
  358. ;  ret ebx = blocks read or 0xffffffff folder not found
  359. ;      eax = 0 ok read or other = errormsg
  360. ;
  361. ;--------------------------------------------------------------
  362. uglobal
  363.     EXT2_files_in_folder    dd ?   ;всего файлов в папке
  364.     EXT2_read_in_folder     dd ?   ;сколько файлов "считали"
  365.     EXT2_end_block          dd ?   ;конец очередного блока папки
  366.     EXT2_counter_blocks     dd ?
  367. endg
  368.  
  369. ext2_HdReadFolder:
  370.         mov     ebp, [ext2_data.root_inode]
  371.         mov     [EXT2_read_in_folder], ebx
  372.         mov     [EXT2_files_in_folder], ecx     ;сохраним регистры
  373.  
  374.     .next_folder:
  375.         cmp     byte [esi], 0
  376.         jz      .get_folder
  377.  
  378.         or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
  379.         mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
  380.         add     eax, [ext2_data.count_block_in_block]
  381.         mov     [EXT2_end_block], eax
  382.     .next_block_folder:
  383.         mov     eax, [ext2_data.count_block_in_block]
  384.         sub     [EXT2_end_block], eax
  385.         jz      .not_found
  386.         inc     [EXT2_counter_blocks]
  387.         mov     ecx, [EXT2_counter_blocks]
  388.         call    ext2_get_inode_block
  389.  
  390.         mov     eax, ecx
  391.         mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
  392.         call    ext2_get_block
  393.  
  394.         mov     eax, esi
  395.         call    ext2_test_block_by_name
  396.         cmp     eax, esi                                ;нашли имя?
  397.         je      .next_block_folder
  398.  
  399.         cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
  400.         jne     .not_found                                      ;нашли, но это не папка
  401.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  402.         mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
  403.         call    ext2_get_inode
  404.         mov     ebp, ebx
  405.         jmp     .next_folder
  406.  
  407.     .not_found:
  408.         or      ebx, -1
  409.         mov     eax, ERROR_FILE_NOT_FOUND
  410.         ret
  411.      ;--------------------------------------------- final step
  412.         ; in ebp - pointer to final inode (folder).
  413.     .get_folder:
  414.         push    edx                             ;заголовок будем заполнять в конце (адрес - в стеке) edx
  415.         push    [EXT2_read_in_folder]           ;сохраненный регистр тоже в стек
  416.  
  417.         mov     edi, [EXT2_files_in_folder]     ;edi = число блоков для чтения
  418.         and     [EXT2_read_in_folder], 0
  419.         and     [EXT2_files_in_folder], 0
  420.  
  421.         mov     esi, [ebp + EXT2_INODE_STRUC.i_blocks]
  422.         mov     [EXT2_counter_blocks], esi
  423.  
  424.         add     edx, 32                         ;заголовок будем заполнять в конце (адрес - в стеке) edx = current mem for return
  425.         xor     esi, esi                        ;esi = номер блока по порядку
  426.  
  427.     .new_block_folder:              ;reserved label
  428.         mov     ecx, esi                        ; получим номер блока
  429.         call    ext2_get_inode_block
  430.  
  431.         mov     eax, ecx
  432.         mov     ebx, [ext2_data.ext2_save_block]
  433.         call    ext2_get_block                  ; и считываем блок с hdd
  434.  
  435.         mov     eax, ebx                        ; eax = current dir record
  436.         add     ebx, [ext2_data.block_size]
  437.         mov     [EXT2_end_block], ebx           ; запомним конец очередного блока
  438.  
  439.         pop     ecx
  440.         mov     ecx, [ecx]                      ; ecx = first wanted (flags ommited)
  441.  
  442.     .find_wanted_start:
  443.         jecxz   .find_wanted_end
  444.     .find_wanted_cycle:
  445.             cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
  446.             je      @F
  447.             inc     [EXT2_files_in_folder]
  448.           @@:
  449.             movzx   ebx, [eax+EXT2_DIR_STRUC.rec_len]
  450.             add     eax, ebx                            ; к следующей записи
  451.             cmp     eax, [EXT2_end_block]              ; проверяем "конец"
  452.             je      .end_block_find_wanted
  453.             loop    .find_wanted_cycle
  454.     .find_wanted_end:
  455.  
  456.         mov     ecx, edi
  457.     .wanted_start:                                      ; ищем first_wanted+count
  458.         jecxz   .wanted_end
  459.     .wanted_cycle:
  460.             cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
  461.             jz      .empty_rec
  462.             inc     [EXT2_files_in_folder]
  463.             inc     [EXT2_read_in_folder]
  464.  
  465.             test    [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;папка или нет
  466.             jnz      @F
  467.  
  468.             push    eax                                             ;получим размер, если это файл
  469.             mov     eax, [eax + EXT2_DIR_STRUC.inode]
  470.             mov     ebx, [ext2_data.ext2_temp_inode]
  471.             call    ext2_get_inode
  472.             mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
  473.             mov     ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
  474.             mov     dword [edx+32], eax
  475.             mov     dword [edx+36], ebx
  476.             xor     dword [edx], FS_FT_DIR          ; для файлов xor - 2 раза
  477.             pop     eax
  478.           @@:
  479.             xor     dword [edx], FS_FT_DIR
  480.             mov     dword [edx+4], FS_FT_ASCII      ; symbol type in name
  481.  
  482.             push    ecx esi                         ;copy name
  483.             movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
  484.             mov     edi, edx
  485.             add     edi, 40
  486.             lea     esi, [eax + EXT2_DIR_STRUC.name]
  487.             rep     movsb
  488.             pop     esi ecx
  489.             and     byte [edi], 0
  490.  
  491.             add     edx, 40 + 264                       ; go to next record
  492.         .empty_rec:
  493.             movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
  494.             add     eax, ebx
  495.             cmp     eax, [EXT2_end_block]
  496.             je      .end_block_wanted
  497.             loop    .wanted_cycle
  498.  
  499.     .wanted_end:                        ;теперь дойдем до конца чтобы узнать сколько файлов в папке
  500.         or      ecx, -1                 ;цикл уже есть, просто поставим ему огромный счетчик
  501.         jmp     .find_wanted_cycle
  502.  
  503.     .end_block_find_wanted:                                   ;вылетили из цикла find_wanted
  504.         mov     ebx, [ext2_data.count_block_in_block]
  505.         sub     [EXT2_counter_blocks], ebx
  506.         jz      .end_dir
  507.  
  508.         ;получаем новый блок
  509.         inc     esi
  510.         push    ecx
  511.         mov     ecx, esi
  512.         call    ext2_get_inode_block
  513.         mov     eax, ecx
  514.         mov     ebx, [ext2_data.ext2_save_block]
  515.         call    ext2_get_block
  516.         pop     ecx
  517.         dec     ecx
  518.         mov     eax, ebx
  519.         add     ebx, [ext2_data.block_size]
  520.         mov     [EXT2_end_block], ebx
  521.         jmp     .find_wanted_start
  522.  
  523.     .end_block_wanted:                                      ;вылетели из цикла wanted
  524.         mov     ebx, [ext2_data.count_block_in_block]
  525.         sub     [EXT2_counter_blocks], ebx
  526.         jz      .end_dir
  527.  
  528.         inc     esi
  529.         push    ecx
  530.         mov     ecx, esi
  531.         call    ext2_get_inode_block
  532.         mov     eax, ecx
  533.         mov     ebx, [ext2_data.ext2_save_block]
  534.         call    ext2_get_block
  535.         pop     ecx
  536.         dec     ecx
  537.         mov     eax, ebx
  538.         add     ebx, [ext2_data.block_size]
  539.         mov     [EXT2_end_block], ebx
  540.         jmp     .wanted_start
  541.  
  542.     .end_dir:
  543.         pop     edx
  544.         mov     ebx, [EXT2_read_in_folder]
  545.         mov     ecx, [EXT2_files_in_folder]
  546.         mov     dword [edx], 1    ;version
  547.         xor     eax, eax
  548.         mov     [edx+4], ebx
  549.         mov     [edx+8], ecx
  550.         lea     edi, [edx + 12]
  551.         mov     ecx, 20 / 4
  552.         rep     stosd
  553.         ret
  554. ;====================== end ext2_HdReadFolder
  555.  
  556. ;----------------------------------------------------------------
  557. ;
  558. ;  ext2_HdRead - read hard disk
  559. ;
  560. ;  esi  points to filename
  561. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  562. ;       may be ebx=0 - start from first byte
  563. ;  ecx  number of bytes to read, 0+
  564. ;  edx  mem location to return data
  565. ;
  566. ;  ret ebx = bytes read or 0xffffffff file not found
  567. ;      eax = 0 ok read or other = errormsg
  568. ;
  569. ;--------------------------------------------------------------
  570. ext2_HdRead:
  571.         mov     ebp, [ext2_data.root_inode]
  572.  
  573.         push    ecx edx ebx
  574.     .next_folder:
  575.         push    esi
  576.     @@:
  577.             lodsb
  578.             test    al, al
  579.             jz      .find_end
  580.             cmp     al, '/'
  581.             jz      .find_folder
  582.             jmp     @B
  583.  
  584.     .find_end:
  585.         ;установим флаг что ищем файл или очередную папку
  586.         mov     edi, 1
  587.         jmp     .find_any
  588.     .find_folder:
  589.         xor     edi, edi
  590.     .find_any:
  591.         pop     esi
  592.  
  593.         cmp     byte [esi], 0
  594.         jz      .not_found
  595.  
  596.         or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
  597.         mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
  598.         add     eax, [ext2_data.count_block_in_block]
  599.         mov     [EXT2_end_block], eax
  600.     .next_block_folder:
  601.         mov     eax, [ext2_data.count_block_in_block]
  602.         sub     [EXT2_end_block], eax
  603.         jz      .not_found
  604.         inc     [EXT2_counter_blocks]
  605.         mov     ecx, [EXT2_counter_blocks]
  606.         call    ext2_get_inode_block
  607.  
  608.         mov     eax, ecx
  609.         mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
  610.         call    ext2_get_block
  611.  
  612.         mov     eax, esi
  613.         call    ext2_test_block_by_name
  614.         cmp     eax, esi                                ;нашли имя?
  615.         je      .next_block_folder
  616.  
  617.         cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_REG_FILE
  618.         je      .test_file
  619.         cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
  620.         jne     .not_found
  621.     .test_dir:
  622.         cmp     edi, 0
  623.         jne     .this_is_folder
  624.  
  625.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  626.         mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
  627.         call    ext2_get_inode
  628.         mov     ebp, ebx
  629.         jmp     .next_folder
  630.  
  631.     .test_file:
  632.         cmp     edi, 0
  633.         je      .not_found
  634.  
  635.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  636.         mov     ebx, [ext2_data.ext2_save_inode]
  637.         call    ext2_get_inode
  638.         jmp     .get_file
  639.  
  640.     .not_found:
  641.         pop     edx ecx ebx
  642.         or      ebx, -1
  643.         mov     eax, ERROR_FILE_NOT_FOUND
  644.         ret
  645.     .this_is_folder:
  646.         pop     edx ecx ebx
  647.         or      ebx, -1
  648.         mov     eax, ERROR_ACCESS_DENIED
  649.     .end_read:
  650.         ret
  651.  
  652.     ;-----------------------------------------------------------------------------final step
  653.     .get_file:
  654.         xchg    bx, bx
  655.         mov     ebp ,ebx
  656.  
  657.         ;pop     eax edi ecx         ; первый_блок память кол-во_байт
  658.         mov     esi, [esp]
  659.         mov     edi, [esp + 8]      ;edi = нужно считать байт
  660.  
  661.         ;///// сравним хватит ли нам файла или нет
  662.         mov     ebx, [esi+4]
  663.         mov     eax, [esi]          ; ebx : eax - стартовый номер байта
  664.  
  665.         mov     edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
  666.         mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]        ;edx : ecx - размер файла
  667.  
  668.         cmp     edx, ebx
  669.         ja      .size_great
  670.         jb      .size_less
  671.  
  672.         cmp     ecx, eax
  673.         ja      .size_great
  674.  
  675.     .size_less:
  676.         add     esp, 12
  677.         mov     ebx, 0
  678.         mov     eax, 6      ;EOF
  679.         ret
  680.     .size_great:
  681.         ;прибавим к старту кол-во байт для чтения
  682.         add     eax, edi
  683.         jnc     @F
  684.         inc     ebx
  685.     @@:
  686.         cmp     edx, ebx
  687.         ja      .size_great_great
  688.         jb      .size_great_less
  689.         cmp     ecx, eax
  690.         jae     .size_great_great
  691.         ;jmp      .size_great_less
  692.                                                 ; а если равно, то не важно куда
  693.     .size_great_less:
  694.         or      [EXT2_files_in_folder], 1       ;читаем по границе размера
  695.         sub     ecx, [esi]
  696.         pop     eax edi edx                     ;ecx - не меняем
  697.         jmp     @F
  698.  
  699.     .size_great_great:
  700.         and     [EXT2_files_in_folder], 0       ;читаем нормально
  701.         pop     eax edi ecx
  702.  
  703.     @@:
  704.         push    ecx                             ;сохраним размер считанных байт в стеке
  705.         test    eax, eax
  706.         je      .zero_start
  707.  
  708.         ;пока делаем п..ц криво =)
  709.         mov     edx, [eax+4]
  710.         mov     eax, [eax]
  711.         div     [ext2_data.block_size]
  712.  
  713.         mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
  714.  
  715.         push    ecx
  716.         mov     ecx, eax
  717.         call    ext2_get_inode_block
  718.         mov     ebx , [ext2_data.ext2_save_block]
  719.         mov     eax, ecx
  720.         call    ext2_get_block
  721.         pop     ecx
  722.         add     ebx, edx
  723.  
  724.         neg     edx
  725.         add     edx,[ext2_data.block_size]      ;block_size - стартоый блок = сколько байт 1-го блока
  726.         cmp     ecx, edx
  727.         jbe     .only_one_block
  728.  
  729.         mov     eax, ecx
  730.         sub     eax, edx
  731.         mov     ecx, edx
  732.  
  733.         mov     esi, ebx
  734.         rep     movsb                           ;кусок 1-го блока
  735.  
  736.     .zero_start:
  737.         mov     ebx, edi                        ;чтение блока прям в ebx
  738.         ;теперь в eax кол-во оставшихся байт для чтения
  739.         xor     edx, edx
  740.         div     [ext2_data.block_size]
  741.         mov     [EXT2_end_block], eax          ;кол-во целых блоков
  742.     @@:
  743.         cmp     [EXT2_end_block], 0
  744.         jz      .finish_block
  745.         inc     [EXT2_counter_blocks]
  746.         mov     ecx, [EXT2_counter_blocks]
  747.         call    ext2_get_inode_block
  748.  
  749.         mov     eax, ecx            ;а ebx уже забит нужным значением
  750.         call    ext2_get_block
  751.         add     ebx, [ext2_data.block_size]
  752.  
  753.         dec     [EXT2_end_block]
  754.         jmp     @B
  755.  
  756.     .finish_block:          ;в edx - кол-во байт в последнем блоке
  757.         cmp     edx, 0
  758.         je      .end_read
  759.  
  760.         mov     ecx, [EXT2_counter_blocks]
  761.         inc     ecx
  762.         call    ext2_get_inode_block
  763.  
  764.         mov     edi, ebx
  765.         mov     eax, ecx
  766.         mov     ebx, [ext2_data.ext2_save_block]
  767.         call    ext2_get_block
  768.  
  769.         mov     ecx, edx
  770.  
  771.     .only_one_block:
  772.         mov     esi, ebx
  773.         rep     movsb                           ;кусок 1-го блока (последнего)
  774.         pop     ebx
  775.         cmp     [EXT2_files_in_folder], 0
  776.         jz      @F
  777.  
  778.         mov     eax, 6      ;EOF
  779.         ret
  780.     @@:
  781.         xor     eax, eax
  782.         ret
  783. ;========================
  784.  
  785. ext2_HdRewrite:
  786. ;    xchg    bx, bx
  787.         xor     ebx, ebx
  788.         mov     eax, ERROR_UNSUPPORTED_FS
  789.         ret
  790.  
  791. ext2_HdWrite:
  792. ;    xchg    bx, bx
  793.         xor     ebx, ebx
  794.         mov     eax, ERROR_UNSUPPORTED_FS
  795.         ret
  796. ext2_HdSetFileEnd:
  797. ;    xchg    bx, bx
  798.         xor     ebx, ebx
  799.         mov     eax, ERROR_UNSUPPORTED_FS
  800.         ret
  801. ext2_HdGetFileInfo:
  802. ;    xchg    bx, bx
  803.         xor     ebx, ebx
  804.         mov     eax, ERROR_UNSUPPORTED_FS
  805.         ret
  806. ext2_HdSetFileInfo:
  807. ;    xchg    bx, bx
  808.         xor     ebx, ebx
  809.         mov     eax, ERROR_UNSUPPORTED_FS
  810.         ret
  811. ext2_HdDelete:
  812. ;    xchg    bx, bx
  813.         xor     ebx, ebx
  814.         mov     eax, ERROR_UNSUPPORTED_FS
  815.         ret
  816.  
  817.