Subversion Repositories Kolibri OS

Rev

Rev 1397 | 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: 1398 $
  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.             dec     ecx
  428.           @@:
  429.             movzx   ebx, [eax+EXT2_DIR_STRUC.rec_len]
  430.             add     eax, ebx                            ; к следующей записи
  431.             cmp     eax, [EXT2_end_block]              ; проверяем "конец"
  432.             jb      .find_wanted_start
  433.  
  434.    .end_block_find_wanted:                                   ;вылетили из цикла find_wanted
  435.         mov     ebx, [ext2_data.count_block_in_block]
  436.         sub     [EXT2_counter_blocks], ebx
  437.         jz      .end_dir
  438.  
  439.         ;получаем новый блок
  440.         inc     esi
  441.         push    ecx
  442.         mov     ecx, esi
  443.         call    ext2_get_inode_block
  444.         mov     eax, ecx
  445.         mov     ebx, [ext2_data.ext2_save_block]
  446.         call    ext2_get_block
  447.         pop     ecx
  448.         dec     ecx
  449.         mov     eax, ebx
  450.         add     ebx, [ext2_data.block_size]
  451.         mov     [EXT2_end_block], ebx
  452.         jmp     .find_wanted_start
  453.  
  454.     .find_wanted_end:
  455.         mov     ecx, edi
  456.  
  457.     .wanted_start:                                      ; ищем first_wanted+count
  458.             jecxz   .find_wanted_cycle                  ; ecx=0 => огромный цикл до конца папки
  459.             cmp     [eax + EXT2_DIR_STRUC.inode], 0     ; if (inode = 0) => not used
  460.             jz      .empty_rec
  461.             inc     [EXT2_files_in_folder]
  462.             inc     [EXT2_read_in_folder]
  463.  
  464.             mov     edi, edx
  465.             push    eax ecx
  466.             xor     eax, eax
  467.             mov     ecx, 40 / 4
  468.             rep     stosd
  469.             pop     ecx eax
  470.  
  471.             cmp     [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;папка или нет
  472.             jz      @F
  473.  
  474.             push    eax                                             ;получим размер, если это файл
  475.             mov     eax, [eax + EXT2_DIR_STRUC.inode]
  476.             mov     ebx, [ext2_data.ext2_temp_inode]
  477.             call    ext2_get_inode
  478.             mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
  479.             mov     ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
  480.             mov     dword [edx+32], eax
  481.             mov     dword [edx+36], ebx
  482.             xor     dword [edx], FS_FT_DIR          ; для файлов xor - 2 раза
  483.             pop     eax
  484.           @@:
  485.             xor     dword [edx], FS_FT_DIR
  486.             or      dword [edx+4], FS_FT_ASCII      ; symbol type in name
  487.  
  488.             ;теперь скопируем название, сконвертировав из UTF-8 в CP866
  489.             push    eax ecx esi
  490.             movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
  491.             lea     edi, [edx + 40]
  492.             lea     esi, [eax + EXT2_DIR_STRUC.name]
  493.             call    utf8toansi_str
  494.             pop     esi ecx eax
  495.             and     byte [edi], 0
  496.  
  497.             add     edx, 40 + 264                       ; go to next record
  498.  
  499.             dec     ecx                                 ; если запись пустая ecx не надо уменьшать
  500.         .empty_rec:
  501.             movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
  502.             add     eax, ebx
  503.             cmp     eax, [EXT2_end_block]
  504.             jb      .wanted_start
  505.  
  506.     .end_block_wanted:                                      ;вылетели из цикла wanted
  507.         mov     ebx, [ext2_data.count_block_in_block]
  508.         sub     [EXT2_counter_blocks], ebx
  509.         jz      .end_dir
  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     .wanted_start
  524.  
  525.     .wanted_end:
  526.         dec     ecx
  527.         jmp     .find_wanted_cycle
  528.  
  529.     .end_dir:
  530.         pop     edx
  531.         mov     ebx, [EXT2_read_in_folder]
  532.         mov     ecx, [EXT2_files_in_folder]
  533.         mov     dword [edx], 1    ;version
  534.         xor     eax, eax
  535.         mov     [edx+4], ebx
  536.         mov     [edx+8], ecx
  537.         lea     edi, [edx + 12]
  538.         mov     ecx, 20 / 4
  539.         rep     stosd
  540.         ret
  541. ;====================== end ext2_HdReadFolder
  542. utf8toansi_str:
  543. ; convert UTF-8 string to ASCII-string (codepage 866)
  544. ; in: ecx=length source, esi->source, edi->buffer
  545. ; destroys: eax,esi,edi
  546.         jecxz   .ret
  547.     .start:
  548.         lodsw
  549.         cmp     al, 0x80
  550.         jb      .ascii
  551.  
  552.         xchg    al, ah
  553.         cmp     ax, 0xd080
  554.         jz      .yo1
  555.         cmp     ax, 0xd191
  556.         jz      .yo2
  557.         cmp     ax, 0xd090
  558.         jb      .unk
  559.         cmp     ax, 0xd180
  560.         jb      .rus1
  561.         cmp     ax, 0xd190
  562.         jb      .rus2
  563.     .unk:
  564.         mov     al, '_'
  565.         jmp     .doit
  566.     .yo1:
  567.         mov     al, 0xf0    ; Ё capital
  568.         jmp     .doit
  569.     .yo2:
  570.         mov     al, 0xf1    ; ё small
  571.         jmp     .doit
  572.     .rus1:
  573.         sub     ax, 0xd090 - 0x80
  574.         jmp     .doit
  575.     .rus2:
  576.         sub     ax, 0xd18f - 0xEF
  577.     .doit:
  578.         stosb
  579.         sub     ecx, 2
  580.         ja      .start
  581.         ret
  582.  
  583.     .ascii:
  584.         stosb
  585.         dec     esi
  586.         dec     ecx
  587.         jnz     .start
  588.     .ret:
  589.         ret
  590.  
  591. ;----------------------------------------------------------------
  592. ;
  593. ;  ext2_HdRead - read hard disk
  594. ;
  595. ;  esi  points to filename
  596. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  597. ;       may be ebx=0 - start from first byte
  598. ;  ecx  number of bytes to read, 0+
  599. ;  edx  mem location to return data
  600. ;
  601. ;  ret ebx = bytes read or 0xffffffff file not found
  602. ;      eax = 0 ok read or other = errormsg
  603. ;
  604. ;--------------------------------------------------------------
  605. ext2_HdRead:
  606.         cmp     byte [esi], 0
  607.         jnz     @F
  608.  
  609.     .this_is_nofile:
  610.         or      ebx, -1
  611.         mov     eax, ERROR_ACCESS_DENIED
  612.         ret
  613.  
  614.     @@:
  615.         push    ecx ebx
  616.         call    ext2_find_lfn
  617.         pop     ebx ecx
  618.         jnc     .doit
  619.     ;.not_found:
  620.         or      ebx, -1
  621.         mov     eax, ERROR_FILE_NOT_FOUND
  622.         ret
  623.  
  624.     .doit:
  625.         test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
  626.         jz      .this_is_nofile
  627.  
  628.     ;-----------------------------------------------------------------------------final step
  629.  
  630.         mov     edi, edx            ; edi = pointer to return mem
  631.         mov     esi, ebx            ; esi = pointer to first_wanted
  632.  
  633.         ;///// сравним хватит ли нам файла или нет
  634.         mov     ebx, [esi+4]
  635.         mov     eax, [esi]          ; ebx : eax - стартовый номер байта
  636.  
  637.    ;    mov     edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
  638.    ;    mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]        ;edx : ecx - размер файла
  639.  
  640.         cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
  641.         ja      .size_great
  642.         jb      .size_less
  643.  
  644.         cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
  645.         ja      .size_great
  646.  
  647.     .size_less:
  648.         pop     ecx
  649.         xor     ebx, ebx
  650.         mov     eax, 6      ;EOF
  651.         ret
  652.     .size_great:
  653.         add     eax, ecx                  ;add to first_wanted кол-во байт для чтения
  654.         adc     ebx, 0
  655.  
  656.         cmp     [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
  657.         ja      .size_great_great
  658.         jb      .size_great_less
  659.         cmp     [ebp + EXT2_INODE_STRUC.i_size], eax
  660.         jae     .size_great_great               ; а если равно, то не важно куда
  661.  
  662.     .size_great_less:
  663.         or      [EXT2_files_in_folder], 1       ;читаем по границе размера
  664.         mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]
  665.         sub     ecx, [esi]                      ;(размер - старт)
  666.         jmp     @F
  667.  
  668.     .size_great_great:
  669.         and     [EXT2_files_in_folder], 0       ;читаем столько сколько запросили
  670.  
  671.     @@:
  672.         push    ecx                             ;save for return
  673.         test    esi, esi
  674.         jz      .zero_start
  675.  
  676.         ;пока делаем п..ц криво =)
  677.         mov     edx, [esi+4]
  678.         mov     eax, [esi]
  679.         div     [ext2_data.block_size]
  680.  
  681.         mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
  682.  
  683.         push    ecx
  684.         mov     ecx, eax
  685.         call    ext2_get_inode_block
  686.         mov     ebx, [ext2_data.ext2_save_block]
  687.         mov     eax, ecx
  688.         call    ext2_get_block
  689.         pop     ecx
  690.         add     ebx, edx
  691.  
  692.         neg     edx
  693.         add     edx,[ext2_data.block_size]      ;block_size - стартовый байт = сколько байт 1-го блока
  694.         cmp     ecx, edx
  695.         jbe     .only_one_block
  696.  
  697.         mov     eax, ecx
  698.         sub     eax, edx
  699.         mov     ecx, edx
  700.  
  701.         mov     esi, ebx
  702.         rep     movsb                           ;кусок 1-го блока
  703.         jmp     @F
  704.  
  705.     .zero_start:
  706.         mov     eax, ecx
  707.         ;теперь в eax кол-во оставшихся байт для чтения
  708.     @@:
  709.         mov     ebx, edi                        ;чтение блока прям в ->ebx
  710.         xor     edx, edx
  711.         div     [ext2_data.block_size]          ;кол-во байт в последнем блоке (остаток) в edx
  712.         mov     edi, eax                        ;кол-во целых блоков в edi
  713.     @@:
  714.         test     edi, edi
  715.         jz      .finish_block
  716.         inc     [EXT2_counter_blocks]
  717.         mov     ecx, [EXT2_counter_blocks]
  718.         call    ext2_get_inode_block
  719.  
  720.         mov     eax, ecx                        ;а ebx уже забит нужным значением
  721.         call    ext2_get_block
  722.         add     ebx, [ext2_data.block_size]
  723.  
  724.         dec     edi
  725.         jmp     @B
  726.  
  727.     .finish_block:          ;в edx - кол-во байт в последнем блоке
  728.         test    edx, edx
  729.         jz      .end_read
  730.  
  731.         mov     ecx, [EXT2_counter_blocks]
  732.         inc     ecx
  733.         call    ext2_get_inode_block
  734.  
  735.         mov     edi, ebx
  736.         mov     eax, ecx
  737.         mov     ebx, [ext2_data.ext2_save_block]
  738.         call    ext2_get_block
  739.  
  740.         mov     ecx, edx
  741.  
  742.     .only_one_block:
  743.         mov     esi, ebx
  744.         rep     movsb                           ;кусок last блока
  745.     .end_read:
  746.         pop     ebx
  747.         cmp     [EXT2_files_in_folder], 0
  748.         jz      @F
  749.  
  750.         mov     eax, 6      ;EOF
  751.         ret
  752.     @@:
  753.         xor     eax, eax
  754.         ret
  755. ;========================
  756. ;in : esi -> name           not save register
  757. ;out: ebp -> inode cf=0
  758. ;     ebp -> trash cf=1
  759. ext2_find_lfn:
  760.         mov     ebp, [ext2_data.root_inode]
  761.     .next_folder:
  762.         or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
  763.         mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
  764.         add     eax, [ext2_data.count_block_in_block]
  765.         mov     [EXT2_end_block], eax
  766.     .next_block_folder:
  767.         mov     eax, [ext2_data.count_block_in_block]
  768.         sub     [EXT2_end_block], eax
  769.         jz      .not_found
  770.         inc     [EXT2_counter_blocks]
  771.         mov     ecx, [EXT2_counter_blocks]
  772.         call    ext2_get_inode_block
  773.  
  774.         mov     eax, ecx
  775.         mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
  776.         call    ext2_get_block
  777.  
  778.         mov     eax, esi
  779.         call    ext2_test_block_by_name
  780.         cmp     eax, esi                                ;нашли имя?
  781.         jz      .next_block_folder
  782.  
  783.         cmp     byte [esi],0
  784.         jz      .get_inode_ret
  785.  
  786.         cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
  787.         jne     .not_found                                      ;нашли, но это не папка
  788.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  789.         mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
  790.         call    ext2_get_inode
  791.         mov     ebp, ebx
  792.         jmp     .next_folder
  793.  
  794.     .not_found:
  795.         stc
  796.         ret
  797.     .get_inode_ret:
  798.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  799.         mov     ebx, [ext2_data.ext2_save_inode]
  800.         call    ext2_get_inode
  801.         mov     ebp, ebx
  802.         clc
  803.         ret
  804.  
  805.  
  806. ;========================
  807. ext2_HdRewrite:
  808. ;    xchg    bx, bx
  809.         xor     ebx, ebx
  810.         mov     eax, ERROR_UNSUPPORTED_FS
  811.         ret
  812.  
  813. ext2_HdWrite:
  814. ;    xchg    bx, bx
  815.         xor     ebx, ebx
  816.         mov     eax, ERROR_UNSUPPORTED_FS
  817.         ret
  818. ext2_HdSetFileEnd:
  819. ;    xchg    bx, bx
  820.         xor     ebx, ebx
  821.         mov     eax, ERROR_UNSUPPORTED_FS
  822.         ret
  823.  
  824. ext2_HdGetFileInfo:
  825.         cmp     byte [esi], 0
  826.         jz      .doit
  827.  
  828.         call    ext2_find_lfn
  829.         jnc     .doit2
  830.     ;.not_found:
  831.         mov     eax, ERROR_FILE_NOT_FOUND
  832.         ret
  833.  
  834.     .doit:
  835.         mov     ebp, [ext2_data.root_inode]
  836.     .doit2:
  837.         xor     eax, eax
  838.         mov     edi, edx
  839.         mov     ecx, 40/4
  840.         rep stosd               ; fill zero
  841.  
  842.         test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
  843.         jz      @F
  844.         or      dword [edx], FS_FT_DIR
  845.     @@:
  846.         mov     byte [edx+1], FS_FT_ASCII
  847.         mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
  848.         mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
  849.         mov     dword [edx+32], eax
  850.         mov     dword [edx+36], ebx
  851.  
  852.         xor     eax, eax
  853.         ret
  854.  
  855. ext2_HdSetFileInfo:
  856. ;    xchg    bx, bx
  857.         xor     ebx, ebx
  858.         mov     eax, ERROR_UNSUPPORTED_FS
  859.         ret
  860. ext2_HdDelete:
  861. ;    xchg    bx, bx
  862.         xor     ebx, ebx
  863.         mov     eax, ERROR_UNSUPPORTED_FS
  864.         ret
  865.  
  866.