Subversion Repositories Kolibri OS

Rev

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

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