Subversion Repositories Kolibri OS

Rev

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