Subversion Repositories Kolibri OS

Rev

Rev 1378 | 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: 1384 $
  12.  
  13. EXT2_BAD_INO        = 1
  14. EXT2_ROOT_INO        = 2
  15. EXT2_ACL_IDX_INO    = 3
  16. EXT2_ACL_DATA_INO    = 4
  17. EXT2_BOOT_LOADER_INO= 5
  18. EXT2_UNDEL_DIR_INO    = 6
  19.  
  20. ;type inode
  21. EXT2_S_IFREG        = 0x8000
  22. EXT2_S_IFDIR        = 0x4000
  23. ;user inode right's
  24. EXT2_S_IRUSR        = 0x0100
  25. EXT2_S_IWUSR        = 0x0080
  26. EXT2_S_IXUSR        = 0x0040
  27. ;group inode right's
  28. EXT2_S_IRGRP        = 0x0020
  29. EXT2_S_IWGRP        = 0x0010
  30. EXT2_S_IXGRP        = 0x0008
  31. ;other inode right's
  32. EXT2_S_IROTH        = 0x0004
  33. EXT2_S_IROTH        = 0x0002
  34. EXT2_S_IROTH        = 0x0001
  35.  
  36. EXT2_FT_REG_FILE        = 1     ;это файл, запись в родительском каталоге
  37. EXT2_FT_DIR             = 2     ;это папка
  38.  
  39. FS_FT_DIR               = 0x10  ;это папка
  40. FS_FT_ASCII             = 0     ;имя в ascii
  41. FS_FT_UNICODE           = 1     ;имя в unicode
  42.  
  43. struct EXT2_INODE_STRUC
  44.     .i_mode         dw ?
  45.     .i_uid          dw ?
  46.     .i_size         dd ?
  47.     .i_atime        dd ?
  48.     .i_ctime        dd ?
  49.     .i_mtime        dd ?
  50.     .i_dtime        dd ?
  51.     .i_gid          dw ?
  52.     .i_links_count  dw ?
  53.     .i_blocks       dd ?
  54.     .i_flags        dd ?
  55.     .i_osd1         dd ?
  56.     .i_block        dd 15 dup ?
  57.     .i_generation   dd ?
  58.     .i_file_acl     dd ?
  59.     .i_dir_acl      dd ?
  60.     .i_faddr        dd ?
  61.     .i_osd2         dd ? ; 1..12
  62. ends
  63.  
  64. struct EXT2_DIR_STRUC
  65.     .inode          dd ?
  66.     .rec_len        dw ?
  67.     .name_len       db ?
  68.     .file_type      db ?
  69.     .name           db ? ; 0..255
  70. ends
  71.  
  72.  
  73. ext2_test_superblock:
  74.         mov     eax, [PARTITION_START]
  75.         add     eax, 2                  ;superblock start at 1024b
  76.         call    hd_read
  77.  
  78.         cmp     [fs_type], 0x83
  79.         jne     .no
  80.         cmp     dword [ebx+24], 3       ;s_block_size 0,1,2,3
  81.         ja      .no
  82.         cmp     word [ebx+56], 0xEF53   ;s_magic
  83.         jne     .no
  84.         cmp     word [ebx+58], 1        ;s_state (EXT_VALID_FS=1)
  85.         jne     .no
  86.  
  87.     ; OK, this is correct EXT2 superblock
  88.         clc
  89.         ret
  90.    .no:
  91.     ; No, this superblock isn't EXT2
  92.         stc
  93.         ret
  94.  
  95. ext2_setup:
  96.         mov     [fs_type], 2
  97.         mov     ecx, [ebx+24]
  98.         inc     ecx
  99.         mov     [ext2_data.log_block_size], ecx    ; 1, 2, 3, 4   equ 1kb, 2kb, 4kb, 8kb
  100.  
  101.         mov     eax, 1
  102.         shl     eax, cl
  103.         mov     [ext2_data.count_block_in_block], eax
  104.  
  105.         shl     eax, 7
  106.         mov     [ext2_data.count_pointer_in_block], eax
  107.         mov     edx, eax                                ; потом еще квадрат найдем
  108.  
  109.         shl     eax, 2
  110.         mov     [ext2_data.block_size], eax
  111.  
  112.         push    eax eax eax                             ;3 kernel_alloc
  113.  
  114.         mov     eax, edx
  115.         mul     edx
  116.         mov     [ext2_data.count_pointer_in_block_square], eax
  117.  
  118.         call    kernel_alloc
  119.         mov     [ext2_data.global_desc_table],eax       ;reserve mem for gdt
  120.         call    kernel_alloc
  121.         mov     [ext2_data.ext2_save_block], eax        ; and for temp block
  122.         call    kernel_alloc
  123.         mov     [ext2_data.ext2_temp_block], eax        ; and for get_inode proc
  124.  
  125.         movzx   ebp, word [ebx+88]
  126.         mov     ecx, [ebx+32]
  127.         mov     edx, [ebx+40]
  128.         mov     eax, [ebx+20]                           ; first_data_block
  129.  
  130.         mov     [ext2_data.inode_size], ebp
  131.         mov     [ext2_data.blocks_per_group], ecx
  132.         mov     [ext2_data.inodes_per_group], edx
  133.  
  134.         mov     ebx, [ext2_data.global_desc_table]
  135.         inc     eax                                     ; first_data_block + 1 = gdt
  136.         call    ext2_get_block                          ; read gtd
  137.  
  138.         push    ebp ebp ebp                             ;3 kernel_alloc
  139.         call    kernel_alloc
  140.         mov     [ext2_data.ext2_save_inode], eax
  141.         call    kernel_alloc
  142.         mov     [ext2_data.ext2_temp_inode], eax
  143.         call    kernel_alloc
  144.         mov     [ext2_data.root_inode], eax
  145.  
  146.         mov     ebx, eax
  147.         mov     eax, EXT2_ROOT_INO
  148.         call    ext2_get_inode                          ; read root inode
  149.  
  150.         popad
  151.         call    free_hd_channel
  152.         and     [hd1_status], 0
  153.         ret
  154. ;==================================================================
  155. ;in: eax = i_block
  156. ;    ebx = pointer to return memory
  157. ext2_get_block:
  158.         push    eax ebx ecx
  159.         mov     ecx, [ext2_data.log_block_size]
  160.         shl     eax, cl
  161.         add     eax, [PARTITION_START]
  162.         mov     ecx, [ext2_data.count_block_in_block]
  163.     @@:
  164.         call    hd_read
  165.         inc     eax
  166.         add     ebx, 512
  167.         loop    @B
  168.         pop     ecx ebx eax
  169.         ret
  170. ;===================================================================
  171. ; in:  ecx = номер блока
  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.             jb      .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     eax, [ebp + EXT2_INODE_STRUC.i_blocks]
  422.         mov     [EXT2_counter_blocks], eax
  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.             jae      .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.             mov     edi, edx
  466.             push    eax ecx
  467.             xor     eax, eax
  468.             mov     ecx, 40 / 4
  469.             rep     stosd
  470.             pop     ecx eax
  471.  
  472.             cmp     [eax + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR   ;папка или нет
  473.             jz      @F
  474.  
  475.             push    eax                                             ;получим размер, если это файл
  476.             mov     eax, [eax + EXT2_DIR_STRUC.inode]
  477.             mov     ebx, [ext2_data.ext2_temp_inode]
  478.             call    ext2_get_inode
  479.             mov     eax, [ebx + EXT2_INODE_STRUC.i_size]            ;low size
  480.             mov     ebx, [ebx + EXT2_INODE_STRUC.i_dir_acl]         ;high size
  481.             mov     dword [edx+32], eax
  482.             mov     dword [edx+36], ebx
  483.             xor     dword [edx], FS_FT_DIR          ; для файлов xor - 2 раза
  484.             pop     eax
  485.           @@:
  486.             xor     dword [edx], FS_FT_DIR
  487.             or      dword [edx+4], FS_FT_ASCII      ; symbol type in name
  488.  
  489.             push    ecx esi                         ;copy name
  490.             movzx   ecx, [eax + EXT2_DIR_STRUC.name_len]
  491.             mov     edi, edx
  492.             add     edi, 40
  493.             lea     esi, [eax + EXT2_DIR_STRUC.name]
  494.             rep     movsb
  495.             pop     esi ecx
  496.             and     byte [edi], 0
  497.  
  498.             add     edx, 40 + 264                       ; go to next record
  499.         .empty_rec:
  500.             movzx   ebx, [eax + EXT2_DIR_STRUC.rec_len]
  501.             add     eax, ebx
  502.             cmp     eax, [EXT2_end_block]
  503.             jae     .end_block_wanted                   ;по хорошему должно быть =, но ччнш
  504.             loop    .wanted_cycle
  505.  
  506.     .wanted_end:                        ;теперь дойдем до конца чтобы узнать сколько файлов в папке
  507.         or      ecx, -1                 ;цикл уже есть, просто поставим ему огромный счетчик
  508.         jmp     .find_wanted_cycle
  509.  
  510.     .end_block_find_wanted:                                   ;вылетили из цикла find_wanted
  511.         mov     ebx, [ext2_data.count_block_in_block]
  512.         sub     [EXT2_counter_blocks], ebx
  513.         jz      .end_dir
  514.  
  515.         ;получаем новый блок
  516.         inc     esi
  517.         push    ecx
  518.         mov     ecx, esi
  519.         call    ext2_get_inode_block
  520.         mov     eax, ecx
  521.         mov     ebx, [ext2_data.ext2_save_block]
  522.         call    ext2_get_block
  523.         pop     ecx
  524.         dec     ecx
  525.         mov     eax, ebx
  526.         add     ebx, [ext2_data.block_size]
  527.         mov     [EXT2_end_block], ebx
  528.         jmp     .find_wanted_start
  529.  
  530.     .end_block_wanted:                                      ;вылетели из цикла wanted
  531.         mov     ebx, [ext2_data.count_block_in_block]
  532.         sub     [EXT2_counter_blocks], ebx
  533.         jz      .end_dir
  534.  
  535.         inc     esi
  536.         push    ecx
  537.         mov     ecx, esi
  538.         call    ext2_get_inode_block
  539.         mov     eax, ecx
  540.         mov     ebx, [ext2_data.ext2_save_block]
  541.         call    ext2_get_block
  542.         pop     ecx
  543.         dec     ecx
  544.         mov     eax, ebx
  545.         add     ebx, [ext2_data.block_size]
  546.         mov     [EXT2_end_block], ebx
  547.         jmp     .wanted_start
  548.  
  549.     .end_dir:
  550.         pop     edx
  551.         mov     ebx, [EXT2_read_in_folder]
  552.         mov     ecx, [EXT2_files_in_folder]
  553.         mov     dword [edx], 1    ;version
  554.         xor     eax, eax
  555.         mov     [edx+4], ebx
  556.         mov     [edx+8], ecx
  557.         lea     edi, [edx + 12]
  558.         mov     ecx, 20 / 4
  559.         rep     stosd
  560.         ret
  561. ;====================== end ext2_HdReadFolder
  562.  
  563. ;----------------------------------------------------------------
  564. ;
  565. ;  ext2_HdRead - read hard disk
  566. ;
  567. ;  esi  points to filename
  568. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  569. ;       may be ebx=0 - start from first byte
  570. ;  ecx  number of bytes to read, 0+
  571. ;  edx  mem location to return data
  572. ;
  573. ;  ret ebx = bytes read or 0xffffffff file not found
  574. ;      eax = 0 ok read or other = errormsg
  575. ;
  576. ;--------------------------------------------------------------
  577. ext2_HdRead:
  578.         mov     ebp, [ext2_data.root_inode]
  579.  
  580.         push    ecx edx ebx
  581.     .next_folder:
  582.         push    esi
  583.     @@:
  584.             lodsb
  585.             test    al, al
  586.             jz      .find_end
  587.             cmp     al, '/'
  588.             jz      .find_folder
  589.             jmp     @B
  590.  
  591.     .find_end:
  592.         ;установим флаг что ищем файл или очередную папку
  593.         mov     edi, 1
  594.         jmp     .find_any
  595.     .find_folder:
  596.         xor     edi, edi
  597.     .find_any:
  598.         pop     esi
  599.  
  600.         cmp     byte [esi], 0
  601.         jz      .not_found
  602.  
  603.         or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
  604.         mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
  605.         add     eax, [ext2_data.count_block_in_block]
  606.         mov     [EXT2_end_block], eax
  607.     .next_block_folder:
  608.         mov     eax, [ext2_data.count_block_in_block]
  609.         sub     [EXT2_end_block], eax
  610.         jz      .not_found
  611.         inc     [EXT2_counter_blocks]
  612.         mov     ecx, [EXT2_counter_blocks]
  613.         call    ext2_get_inode_block
  614.  
  615.         mov     eax, ecx
  616.         mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
  617.         call    ext2_get_block
  618.  
  619.         mov     eax, esi
  620.         call    ext2_test_block_by_name
  621.         cmp     eax, esi                                ;нашли имя?
  622.         je      .next_block_folder
  623.  
  624.         cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_REG_FILE
  625.         je      .test_file
  626.         cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
  627.         jne     .this_is_nofile
  628.  
  629.     ;.test_dir:
  630.         cmp     edi, 0
  631.         jne     .this_is_nofile
  632.  
  633.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  634.         mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
  635.         call    ext2_get_inode
  636.         mov     ebp, ebx
  637.         jmp     .next_folder
  638.  
  639.     .test_file:
  640.         cmp     edi, 0
  641.         je      .not_found
  642.  
  643.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  644.         mov     ebx, [ext2_data.ext2_save_inode]
  645.         call    ext2_get_inode
  646.         jmp     .get_file
  647.  
  648.     .not_found:
  649.         pop     edx ecx ebx
  650.         or      ebx, -1
  651.         mov     eax, ERROR_FILE_NOT_FOUND
  652.         ret
  653.     .this_is_nofile:
  654.         pop     edx ecx ebx
  655.         or      ebx, -1
  656.         mov     eax, ERROR_ACCESS_DENIED
  657.     .end_read:
  658.         ret
  659.  
  660.     ;-----------------------------------------------------------------------------final step
  661.     .get_file:
  662.         mov     ebp ,ebx
  663.  
  664.         ;pop     eax edi ecx         ; первый_блок память кол-во_байт
  665.         mov     esi, [esp]
  666.         mov     edi, [esp + 8]      ;edi = нужно считать байт
  667.  
  668.         ;///// сравним хватит ли нам файла или нет
  669.         mov     ebx, [esi+4]
  670.         mov     eax, [esi]          ; ebx : eax - стартовый номер байта
  671.  
  672.         mov     edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
  673.         mov     ecx, [ebp + EXT2_INODE_STRUC.i_size]        ;edx : ecx - размер файла
  674.  
  675.         cmp     edx, ebx
  676.         ja      .size_great
  677.         jb      .size_less
  678.  
  679.         cmp     ecx, eax
  680.         ja      .size_great
  681.  
  682.     .size_less:
  683.         add     esp, 12
  684.         mov     ebx, 0
  685.         mov     eax, 6      ;EOF
  686.         ret
  687.     .size_great:
  688.         ;прибавим к старту кол-во байт для чтения
  689.         add     eax, edi
  690.         jnc     @F
  691.         inc     ebx
  692.     @@:
  693.         cmp     edx, ebx
  694.         ja      .size_great_great
  695.         jb      .size_great_less
  696.         cmp     ecx, eax
  697.         jae     .size_great_great
  698.         ;jmp      .size_great_less
  699.                                                 ; а если равно, то не важно куда
  700.     .size_great_less:
  701.         or      [EXT2_files_in_folder], 1       ;читаем по границе размера
  702.         sub     ecx, [esi]
  703.         pop     eax edi edx                     ;ecx - не меняем
  704.         jmp     @F
  705.  
  706.     .size_great_great:
  707.         and     [EXT2_files_in_folder], 0       ;читаем нормально
  708.         pop     eax edi ecx
  709.  
  710.     @@:
  711.         push    ecx                             ;сохраним размер считанных байт в стеке
  712.         test    eax, eax
  713.         je      .zero_start
  714.  
  715.         ;пока делаем п..ц криво =)
  716.         mov     edx, [eax+4]
  717.         mov     eax, [eax]
  718.         div     [ext2_data.block_size]
  719.  
  720.         mov     [EXT2_counter_blocks], eax       ;номер блока запоминаем
  721.  
  722.         push    ecx
  723.         mov     ecx, eax
  724.         call    ext2_get_inode_block
  725.         mov     ebx , [ext2_data.ext2_save_block]
  726.         mov     eax, ecx
  727.         call    ext2_get_block
  728.         pop     ecx
  729.         add     ebx, edx
  730.  
  731.         neg     edx
  732.         add     edx,[ext2_data.block_size]      ;block_size - стартоый блок = сколько байт 1-го блока
  733.         cmp     ecx, edx
  734.         jbe     .only_one_block
  735.  
  736.         mov     eax, ecx
  737.         sub     eax, edx
  738.         mov     ecx, edx
  739.  
  740.         mov     esi, ebx
  741.         rep     movsb                           ;кусок 1-го блока
  742.  
  743.     .zero_start:
  744.         mov     ebx, edi                        ;чтение блока прям в ebx
  745.         ;теперь в eax кол-во оставшихся байт для чтения
  746.         xor     edx, edx
  747.         div     [ext2_data.block_size]
  748.         mov     [EXT2_end_block], eax          ;кол-во целых блоков
  749.     @@:
  750.         cmp     [EXT2_end_block], 0
  751.         jz      .finish_block
  752.         inc     [EXT2_counter_blocks]
  753.         mov     ecx, [EXT2_counter_blocks]
  754.         call    ext2_get_inode_block
  755.  
  756.         mov     eax, ecx            ;а ebx уже забит нужным значением
  757.         call    ext2_get_block
  758.         add     ebx, [ext2_data.block_size]
  759.  
  760.         dec     [EXT2_end_block]
  761.         jmp     @B
  762.  
  763.     .finish_block:          ;в edx - кол-во байт в последнем блоке
  764.         cmp     edx, 0
  765.         je      .end_read
  766.  
  767.         mov     ecx, [EXT2_counter_blocks]
  768.         inc     ecx
  769.         call    ext2_get_inode_block
  770.  
  771.         mov     edi, ebx
  772.         mov     eax, ecx
  773.         mov     ebx, [ext2_data.ext2_save_block]
  774.         call    ext2_get_block
  775.  
  776.         mov     ecx, edx
  777.  
  778.     .only_one_block:
  779.         mov     esi, ebx
  780.         rep     movsb                           ;кусок 1-го блока (последнего)
  781.         pop     ebx
  782.         cmp     [EXT2_files_in_folder], 0
  783.         jz      @F
  784.  
  785.         mov     eax, 6      ;EOF
  786.         ret
  787.     @@:
  788.         xor     eax, eax
  789.         ret
  790. ;========================
  791. ;in : esi -> name           not save register
  792. ;out: ebp -> inode cf=0
  793. ;     ebp -> trash cf=1
  794. ext2_find_lfn:
  795.         mov     ebp, [ext2_data.root_inode]
  796.     .next_folder:
  797.         or      [EXT2_counter_blocks], -1               ;счетчик блоков папки    cur block of inode
  798.         mov     eax, [ebp + EXT2_INODE_STRUC.i_blocks]  ;убывающий счетчик блоков
  799.         add     eax, [ext2_data.count_block_in_block]
  800.         mov     [EXT2_end_block], eax
  801.     .next_block_folder:
  802.         mov     eax, [ext2_data.count_block_in_block]
  803.         sub     [EXT2_end_block], eax
  804.         jz      .not_found
  805.         inc     [EXT2_counter_blocks]
  806.         mov     ecx, [EXT2_counter_blocks]
  807.         call    ext2_get_inode_block
  808.  
  809.         mov     eax, ecx
  810.         mov     ebx, [ext2_data.ext2_save_block]        ;ebx = cur dir record
  811.         call    ext2_get_block
  812.  
  813.         mov     eax, esi
  814.         call    ext2_test_block_by_name
  815.         cmp     eax, esi                                ;нашли имя?
  816.         jz      .next_block_folder
  817.  
  818.         cmp     byte [esi],0
  819.         jz      .get_inode_ret
  820.  
  821.         cmp     [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
  822.         jne     .not_found                                      ;нашли, но это не папка
  823.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  824.         mov     ebx, [ext2_data.ext2_save_inode]                ;все же папка.
  825.         call    ext2_get_inode
  826.         mov     ebp, ebx
  827.         jmp     .next_folder
  828.  
  829.     .not_found:
  830.         stc
  831.         ret
  832.     .get_inode_ret:
  833.         mov     eax, [ebx + EXT2_DIR_STRUC.inode]
  834.         mov     ebx, [ext2_data.ext2_save_inode]
  835.         call    ext2_get_inode
  836.         mov     ebp, ebx
  837.     .ret:
  838.         clc
  839.         ret
  840.  
  841.  
  842. ;========================
  843. ext2_HdRewrite:
  844. ;    xchg    bx, bx
  845.         xor     ebx, ebx
  846.         mov     eax, ERROR_UNSUPPORTED_FS
  847.         ret
  848.  
  849. ext2_HdWrite:
  850. ;    xchg    bx, bx
  851.         xor     ebx, ebx
  852.         mov     eax, ERROR_UNSUPPORTED_FS
  853.         ret
  854. ext2_HdSetFileEnd:
  855. ;    xchg    bx, bx
  856.         xor     ebx, ebx
  857.         mov     eax, ERROR_UNSUPPORTED_FS
  858.         ret
  859.  
  860. ext2_HdGetFileInfo:
  861.         cmp     byte [esi], 0
  862.         jz      .doit
  863.  
  864.         call    ext2_find_lfn
  865.         jnc     .doit2
  866.     ;.not_found:
  867.         mov     eax, ERROR_FILE_NOT_FOUND
  868.         ret
  869.  
  870.     .doit:
  871.         mov     ebp, [ext2_data.root_inode]
  872.     .doit2:
  873.         xor     eax, eax
  874.         mov     edi, edx
  875.         mov     ecx, 40/4
  876.         rep stosd               ; fill zero
  877.  
  878.         test    [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
  879.         jz      @F
  880.         or      dword [edx], FS_FT_DIR
  881.     @@:
  882.         mov     byte [edx+1], FS_FT_ASCII
  883.         mov     eax, [ebp + EXT2_INODE_STRUC.i_size]            ;low size
  884.         mov     ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl]         ;high size
  885.         mov     dword [edx+32], eax
  886.         mov     dword [edx+36], ebx
  887.  
  888.         xor     eax, eax
  889.         ret
  890.  
  891. ext2_HdSetFileInfo:
  892. ;    xchg    bx, bx
  893.         xor     ebx, ebx
  894.         mov     eax, ERROR_UNSUPPORTED_FS
  895.         ret
  896. ext2_HdDelete:
  897. ;    xchg    bx, bx
  898.         xor     ebx, ebx
  899.         mov     eax, ERROR_UNSUPPORTED_FS
  900.         ret
  901.  
  902.