Subversion Repositories Kolibri OS

Rev

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