Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;                                                              ;;
  7. ;; System service for filesystem call                           ;;
  8. ;; (C) 2004 Ville Turjanmaa, License: GPL                       ;;
  9. ;; 29.04.2006 Elimination of hangup after the                   ;;
  10. ;;            expiration hd_wait_timeout (for LBA) -  Mario79   ;;
  11. ;; 15.01.2005 get file size/attr/date,                          ;;
  12. ;;            file_append (only for hd) - ATV                   ;;
  13. ;; 23.11.2004 test if hd/partition is set - ATV                 ;;
  14. ;; 18.11.2004 get_disk_info and more error codes - ATV          ;;
  15. ;; 08.11.2004 expand_pathz and rename (only for hd) - ATV       ;;
  16. ;; 20.10.2004 Makedir/Removedir (only for hd) - ATV             ;;
  17. ;;                                                              ;;
  18. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  19.  
  20. $Revision: 3908 $
  21.  
  22.  
  23. iglobal
  24.  
  25. if lang eq sp
  26. include 'fs/fs-sp.inc'
  27. else
  28. dir0:
  29.              db  'HARDDISK   '
  30.              db  'RAMDISK    '
  31.              db  'FLOPPYDISK '
  32.              db  0
  33.  
  34. dir1:
  35.              db  'FIRST      '
  36.              db  'SECOND     '
  37.              db  'THIRD      '
  38.              db  'FOURTH     '
  39.              db  0
  40. end if
  41.  
  42. not_select_IDE db 0
  43.  
  44. hd_address_table:
  45.                    dd  0x1f0,0x00,0x1f0,0x10
  46.                    dd  0x170,0x00,0x170,0x10
  47. endg
  48.  
  49. file_system:
  50.  
  51. ; IN:
  52. ;
  53. ; eax = 0  ; read file          /RamDisk/First  6
  54. ; eax = 8  ; lba read
  55. ; eax = 15 ; get_disk_info
  56. ;
  57. ; OUT:
  58. ;
  59. ; eax = 0  : read ok
  60. ; eax = 1  : no hd base and/or partition defined
  61. ; eax = 2  : function is unsupported for this FS
  62. ; eax = 3  : unknown FS
  63. ; eax = 4  : partition not defined at hd
  64. ; eax = 5  : file not found
  65. ; eax = 6  : end of file
  66. ; eax = 7  : memory pointer not in application area
  67. ; eax = 8  : disk full
  68. ; eax = 9  : fat table corrupted
  69. ; eax = 10 : access denied
  70. ; eax = 11 : disk error
  71. ;
  72. ; ebx = size
  73.  
  74. ; \begin{diamond}[18.03.2006]
  75. ; for subfunction 16 (start application) error codes must be negative
  76. ;    because positive values are valid PIDs
  77. ; so possible return values are:
  78. ; eax > 0 : process created, eax=PID
  79.  
  80. ; -0x10 <= eax < 0 : -eax is filesystem error code:
  81. ; eax = -1  = 0xFFFFFFFF : no hd base and/or partition defined
  82. ; eax = -3  = 0xFFFFFFFD : unknown FS
  83. ; eax = -5  = 0xFFFFFFFB : file not found
  84. ; eax = -6  = 0xFFFFFFFA : unexpected end of file (probably not executable file)
  85. ; eax = -9  = 0xFFFFFFF7 : fat table corrupted
  86. ; eax = -10 = 0xFFFFFFF6 : access denied
  87.  
  88. ; -0x20 <= eax < -0x10: eax is process creation error code:
  89. ; eax = -0x20 = 0xFFFFFFE0 : too many processes
  90. ; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
  91. ; eax = -0x1E = 0xFFFFFFE2 : no memory
  92.  
  93. ; ebx is not changed
  94.  
  95. ; \end{diamond}[18.03.2006]
  96.  
  97.     ; Extract parameters
  98.  ;   add    eax, std_application_base_address    ; abs start of info block
  99.  
  100.         cmp     dword [eax+0], 15; GET_DISK_INFO
  101.         je      fs_info
  102.  
  103.         cmp     dword [CURRENT_TASK], 1; no memory checks for kernel requests
  104.         jz      no_checks_for_kernel
  105.         mov     edx, eax
  106.         cmp     dword [eax+0], 1
  107.         jnz     .usual_check
  108.         mov     ebx, [eax+12]
  109.  ;   add   ebx,std_application_base_address
  110.         mov     ecx, [eax+8]
  111.         call    check_region
  112.         test    eax, eax
  113.         jnz     area_in_app_mem
  114.  
  115. .error_output:
  116.         mov     esi, buffer_failed
  117.         call    sys_msg_board_str
  118. ;    mov   eax,7
  119.         mov     dword [esp+36], 7
  120.         ret
  121. iglobal
  122.   buffer_failed db 'K : Buffer check failed',13,10,0
  123. endg
  124. .usual_check:
  125.         cmp     dword [eax+0], 0
  126.         mov     ecx, 512
  127.         jnz     .small_size
  128.         mov     ecx, [eax+8]
  129.         shl     ecx, 9
  130. .small_size:
  131.         mov     ebx, [eax+12]
  132.  ;   add   ebx,std_application_base_address
  133.         call    check_region
  134.         test    eax, eax
  135.         jz      .error_output
  136.   area_in_app_mem:
  137.         mov     eax, edx
  138.   no_checks_for_kernel:
  139.  
  140.   fs_read:
  141.  
  142.         mov     ebx, [eax+20]   ; program wants root directory ?
  143.         test    bl, bl
  144.         je      fs_getroot
  145.         test    bh, bh
  146.         jne     fs_noroot
  147.   fs_getroot:
  148. ; \begin{diamond}[18.03.2006]
  149. ; root - only read is allowed
  150. ; other operations return "access denied", eax=10
  151. ; (execute operation returns eax=-10)
  152.         cmp     dword [eax], 0
  153.         jz      .read_root
  154.         mov     dword [esp+36], 10
  155.         ret
  156. .read_root:
  157. ; \end{diamond}[18.03.2006]
  158.         mov     esi, dir0
  159.         mov     edi, [eax+12]
  160.  ;   add   edi,std_application_base_address
  161.         mov     ecx, 11
  162.         push    ecx
  163. ;    cld    ; already is
  164.         rep movsb
  165.         mov     al, 0x10
  166.         stosb
  167.         add     edi, 32-11-1
  168.         pop     ecx
  169.         rep movsb
  170.         stosb
  171.         and     dword [esp+36], 0; ok read
  172.         mov     dword [esp+24], 32*2; size of root
  173.         ret
  174.  
  175.   fs_info:                      ;start of code - Mihasik
  176.         push    eax
  177.         cmp     [eax+21], byte 'r'
  178.         je      fs_info_r
  179.         cmp     [eax+21], byte 'R'
  180.         je      fs_info_r
  181.         mov     eax, 3          ;if unknown disk
  182.         xor     ebx, ebx
  183.         xor     ecx, ecx
  184.         xor     edx, edx
  185.         jmp     fs_info1
  186.   fs_info_r:
  187.         call    ramdisk_free_space;if ramdisk
  188.         mov     ecx, edi        ;free space in ecx
  189.         shr     ecx, 9          ;free clusters
  190.         mov     ebx, 2847       ;total clusters
  191.         mov     edx, 512        ;cluster size
  192.         xor     eax, eax        ;always 0
  193.   fs_info1:
  194.         pop     edi
  195.         mov     [esp+36], eax
  196.         mov     [esp+24], ebx    ; total clusters on disk
  197.         mov     [esp+32], ecx    ; free clusters on disk
  198.         mov     [edi], edx       ; cluster size in bytes
  199.         ret                      ;end of code - Mihasik
  200.  
  201.   fs_noroot:
  202.  
  203.         push    dword [eax+0]   ; read/write/delete/.../makedir/rename/lba/run
  204.         push    dword [eax+4]   ; 512 block number to read
  205.         push    dword [eax+8]   ; bytes to write/append or 512 blocks to read
  206.         mov     ebx, [eax+12]
  207.  ;   add   ebx,std_application_base_address
  208.         push    ebx             ; abs start of return/save area
  209.  
  210.         lea     esi, [eax+20]   ; abs start of dir + filename
  211.         mov     edi, [eax+16]
  212.  ;   add   edi,std_application_base_address    ; abs start of work area
  213.  
  214.         call    expand_pathz
  215.  
  216.         push    edi             ; dir start
  217.         push    ebx             ; name of file start
  218.  
  219.         mov     eax, [edi+1]
  220.         cmp     eax, 'RD  '
  221.         je      fs_yesramdisk
  222.         cmp     eax, 'RAMD'
  223.         jne     fs_noramdisk
  224.  
  225.   fs_yesramdisk:
  226.  
  227.         cmp     byte [edi+1+11], 0
  228.         je      fs_give_dir1
  229.  
  230.         mov     eax, [edi+1+12]
  231.         cmp     eax, '1   '
  232.         je      fs_yesramdisk_first
  233.         cmp     eax, 'FIRS'
  234.         jne     fs_noramdisk
  235.  
  236.   fs_yesramdisk_first:
  237.  
  238.         cmp     dword [esp+20], 8; LBA read ramdisk
  239.         jne     fs_no_LBA_read_ramdisk
  240.  
  241.         mov     eax, [esp+16]   ; LBA block to read
  242.         mov     ecx, [esp+8]    ; abs pointer to return area
  243.  
  244.         call    LBA_read_ramdisk
  245.         jmp     file_system_return
  246.  
  247.  
  248.   fs_no_LBA_read_ramdisk:
  249.  
  250.         cmp     dword [esp+20], 0; READ
  251.         jne     fs_noramdisk_read
  252.  
  253.         mov     eax, [esp+4]    ; fname
  254.         add     eax, 2*12+1
  255.         mov     ebx, [esp+16]   ; block start
  256.         inc     ebx
  257.         mov     ecx, [esp+12]   ; block count
  258.         mov     edx, [esp+8]    ; return
  259.         mov     esi, [esp+0]
  260.         sub     esi, eax
  261.         add     esi, 12+1       ; file name length
  262.         call    fileread
  263.  
  264.         jmp     file_system_return
  265.  
  266.  
  267.   fs_noramdisk_read:
  268.   fs_noramdisk:
  269.  
  270.   ;********************************************************************
  271.         mov     eax, [edi+1]
  272.         cmp     eax, 'FD  '
  273.         je      fs_yesflpdisk
  274.         cmp     eax, 'FLOP'
  275.         jne     fs_noflpdisk
  276.  
  277.   fs_yesflpdisk:
  278.         call    reserve_flp
  279.  
  280.         cmp     byte [edi+1+11], 0
  281.         je      fs_give_dir1
  282.  
  283.         mov     eax, [edi+1+12]
  284.         cmp     eax, '1   '
  285.         je      fs_yesflpdisk_first
  286.         cmp     eax, 'FIRS'
  287.         je      fs_yesflpdisk_first
  288.         cmp     eax, '2   '
  289.         je      fs_yesflpdisk_second
  290.         cmp     eax, 'SECO'
  291.         jne     fs_noflpdisk
  292.         jmp     fs_yesflpdisk_second
  293.  
  294.   fs_yesflpdisk_first:
  295.         mov     [flp_number], 1
  296.         jmp     fs_yesflpdisk_start
  297.   fs_yesflpdisk_second:
  298.         mov     [flp_number], 2
  299.   fs_yesflpdisk_start:
  300.         cmp     dword [esp+20], 0; READ
  301.         jne     fs_noflpdisk_read
  302.  
  303.         mov     eax, [esp+4]    ; fname
  304.         add     eax, 2*12+1
  305.         mov     ebx, [esp+16]   ; block start
  306.         inc     ebx
  307.         mov     ecx, [esp+12]   ; block count
  308.         mov     edx, [esp+8]    ; return
  309.         mov     esi, [esp+0]
  310.         sub     esi, eax
  311.         add     esi, 12+1       ; file name length
  312.         call    floppy_fileread
  313.  
  314.         jmp     file_system_return
  315.  
  316.  
  317.   fs_noflpdisk_read:
  318.   fs_noflpdisk:
  319.   ;*****************************************************************
  320.  
  321.  old_path_harddisk:
  322.         mov     eax, [edi+1]
  323.         cmp     eax, 'HD  '
  324.         je      fs_yesharddisk
  325.         cmp     eax, 'HARD'
  326.         jne     fs_noharddisk
  327.  
  328.   fs_yesharddisk:
  329.         cmp     dword [esp+20], 8; LBA read
  330.         jne     fs_no_LBA_read
  331.         mov     eax, [esp+16]   ; LBA block to read
  332.         lea     ebx, [edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
  333.         mov     ecx, [esp+8]    ; abs pointer to return area
  334.         call    LBA_read
  335.         jmp     file_system_return
  336.  
  337.   fs_no_LBA_read:
  338.  
  339. hd_err_return:
  340.  
  341.   fs_noharddisk:
  342. ; \begin{diamond}[18.03.2006]
  343.         mov     eax, 5   ; file not found
  344. ; а может быть, возвращать другой код ошибки?
  345.         mov     ebx, [esp+24+24]; do not change ebx in application
  346. ; \end{diamond}[18.03.2006]
  347.  
  348.   file_system_return:
  349.  
  350.         add     esp, 24
  351.  
  352.         mov     [esp+36], eax
  353.         mov     [esp+24], ebx
  354.         ret
  355.  
  356.  
  357.   fs_give_dir1:
  358.  
  359. ; \begin{diamond}[18.03.2006]
  360. ; /RD,/FD,/HD - only read is allowed
  361. ; other operations return "access denied", eax=10
  362. ; (execute operation returns eax=-10)
  363.         cmp     dword [esp+20], 0
  364.         jz      .read
  365.         add     esp, 20
  366.         pop     ecx
  367.         mov     dword [esp+36], 10
  368.         ret
  369. .read:
  370. ; \end{diamond}[18.03.2006]
  371.         mov     al, 0x10
  372.         mov     ebx, 1
  373.         mov     edi, [esp+8]
  374.         mov     esi, dir1
  375.   fs_d1_new:
  376.         mov     ecx, 11
  377. ;    cld
  378.         rep movsb
  379.         stosb
  380.         add     edi, 32-11-1
  381.         dec     ebx
  382.         jne     fs_d1_new
  383.  
  384.         add     esp, 24
  385.  
  386.         and     dword [esp+36], 0; ok read
  387.         mov     dword [esp+24], 32*1; dir/data size
  388.         ret
  389.  
  390.  
  391.  
  392. LBA_read_ramdisk:
  393.  
  394.         cmp     [lba_read_enabled], 1
  395.         je      lbarrl1
  396.  
  397.         xor     ebx, ebx
  398.         mov     eax, 2
  399.         ret
  400.  
  401.   lbarrl1:
  402.  
  403.         cmp     eax, 18*2*80
  404.         jb      lbarrl2
  405.         xor     ebx, ebx
  406.         mov     eax, 3
  407.         ret
  408.  
  409.   lbarrl2:
  410.  
  411.         pushad
  412.  
  413.         call    restorefatchain
  414.  
  415.         mov     edi, ecx
  416.         mov     esi, eax
  417.  
  418.         shl     esi, 9
  419.         add     esi, RAMDISK
  420.         mov     ecx, 512/4
  421. ;    cld
  422.         rep movsd
  423.  
  424.         popad
  425.  
  426.         xor     ebx, ebx
  427.         xor     eax, eax
  428.         ret
  429.  
  430. LBA_read:
  431.  
  432. ; IN:
  433. ;
  434. ; eax = LBA block to read
  435. ; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
  436. ; ecx = abs pointer to return area
  437.  
  438.         cmp     [lba_read_enabled], 1
  439.         je      lbarl1
  440.         mov     eax, 2
  441.         ret
  442.  
  443.   lbarl1:
  444.  
  445.         pushad
  446.         mov     ecx, ide_mutex
  447.         call    mutex_lock
  448.         popad
  449.  
  450.         push    eax
  451.         push    ecx
  452.  
  453.         mov     edi, hd_address_table
  454.         mov     esi, dir1
  455.         mov     eax, [ebx]
  456.         mov     edx, '1   '
  457.         mov     ecx, 4
  458.   blar0:
  459.         cmp     eax, [esi]
  460.         je      blar2
  461.         cmp     eax, edx
  462.         je      blar2
  463.         inc     edx
  464.         add     edi, 8
  465.         add     esi, 11
  466.         dec     ecx
  467.         jnz     blar0
  468.  
  469.         mov     eax, 1
  470.         mov     ebx, 1
  471.         jmp     LBA_read_ret
  472.  
  473.   blar2:
  474.         mov     eax, [edi+0]
  475.         mov     ebx, [edi+4]
  476.  
  477.         mov     [hdbase], eax
  478.         mov     [hdid], ebx
  479.  
  480.         call    wait_for_hd_idle
  481.         cmp     [hd_error], 0
  482.         jne     hd_lba_error
  483.  
  484.     ; eax = hd port
  485.     ; ebx = set for primary (0x00) or slave (0x10)
  486.  
  487.         cli
  488.  
  489.         mov     edx, eax
  490.         inc     edx
  491.         xor     eax, eax
  492.         out     dx, al
  493.         inc     edx
  494.         inc     eax
  495.         out     dx, al
  496.         inc     edx
  497.         mov     eax, [esp+4]
  498.         out     dx, al
  499.         shr     eax, 8
  500.         inc     edx
  501.         out     dx, al
  502.         shr     eax, 8
  503.         inc     edx
  504.         out     dx, al
  505.         shr     eax, 8
  506.         inc     edx
  507.         and     al, 1+2+4+8
  508.         add     al, bl
  509.         add     al, 128+64+32
  510.         out     dx, al
  511.  
  512.         inc     edx
  513.         mov     al, 20h
  514.         out     dx, al
  515.  
  516.         sti
  517.  
  518.         call    wait_for_sector_buffer
  519.         cmp     [hd_error], 0
  520.         jne     hd_lba_error
  521.  
  522.         cli
  523.  
  524.         mov     edi, [esp+0]
  525.         mov     ecx, 256
  526.         sub     edx, 7
  527.         cld
  528.         rep insw
  529.  
  530.         sti
  531.  
  532.         xor     eax, eax
  533.         xor     ebx, ebx
  534.  
  535.   LBA_read_ret:
  536.         mov     [hd_error], 0
  537.         mov     [hd1_status], 0
  538.         add     esp, 2*4
  539.         pushad
  540.         mov     ecx, ide_mutex
  541.         call    mutex_unlock
  542.         popad
  543.  
  544.         ret
  545.  
  546.  
  547. expand_pathz:
  548. ; IN:
  549. ;   esi = asciiz path & file
  550. ;   edi = buffer for path & file name
  551. ; OUT:
  552. ;   edi = directory & file : / 11 + / 11 + / 11 - zero terminated
  553. ;   ebx = /file name - zero terminated
  554. ;   esi = pointer after source
  555.  
  556.         push    eax
  557.         push    ecx
  558.         push    edi;[esp+0]
  559.  
  560.   pathz_start:
  561.         mov     byte [edi], '/'
  562.         inc     edi
  563.         mov     al, 32
  564.         mov     ecx, 11
  565.         cld
  566.         rep stosb               ; clear filename area
  567.         sub     edi, 11
  568.         mov     ebx, edi        ; start of dir/file name
  569.  
  570.   pathz_new_char:
  571.         mov     al, [esi]
  572.         inc     esi
  573.         cmp     al, 0
  574.         je      pathz_end
  575.  
  576.         cmp     al, '/'
  577.         jne     pathz_not_path
  578.         cmp     edi, ebx        ; skip first '/'
  579.         jz      pathz_new_char
  580.         lea     edi, [ebx+11]   ; start of next directory
  581.         jmp     pathz_start
  582.  
  583.   pathz_not_path:
  584.         cmp     al, '.'
  585.         jne     pathz_not_ext
  586.         lea     edi, [ebx+8]    ; start of extension
  587.         jmp     pathz_new_char
  588.  
  589.   pathz_not_ext:
  590.         cmp     al, 'a'
  591.         jb      pathz_not_low
  592.         cmp     al, 'z'
  593.         ja      pathz_not_low
  594.         sub     al, 0x20        ; char to uppercase
  595.  
  596.   pathz_not_low:
  597.         mov     [edi], al
  598.         inc     edi
  599.         mov     eax, [esp+0]    ; start_of_dest_path
  600.         add     eax, 512        ; keep maximum path under 512 bytes
  601.         cmp     edi, eax
  602.         jb      pathz_new_char
  603.  
  604.   pathz_end:
  605.         cmp     ebx, edi        ; if path end with '/'
  606.         jnz     pathz_put_zero  ; go back 1 level
  607.         sub     ebx, 12
  608.  
  609.   pathz_put_zero:
  610.         mov     byte [ebx+11], 0
  611.         dec     ebx             ; include '/' char into file name
  612.         pop     edi
  613.         pop     ecx
  614.         pop     eax
  615.         ret
  616.  
  617. ;*******************************************
  618. ;* string to number
  619. ;* input eax - 4 byte string
  620. ;* output eax - number
  621. ;*******************************************
  622. StringToNumber:
  623. ;    ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД
  624. ;    Вход:
  625. ;        EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh
  626. ;    Выход:
  627. ;        CF - индикатор ошибок:
  628. ;            0 - ошибок нет;
  629. ;            1 - ошибка
  630. ;        Если CF=0, то AX - число.
  631.  
  632.         push    bx
  633.         push    cx
  634.         push    dx
  635.         push    edi
  636.         mov     [partition_string], eax
  637.         mov     edi, partition_string
  638.         xor     cx, cx
  639. i1:
  640.         mov     al, [edi]
  641.         cmp     al, 32;13
  642.         je      i_exit
  643. ;    cmp    al,'0'
  644. ;    jb    err
  645. ;    cmp    al,'9'
  646. ;    ja    err
  647.         sub     al, 48
  648.         shl     cx, 1
  649.         jc      error
  650.         mov     bx, cx
  651.         shl     cx, 1
  652.         jc      error
  653.         shl     cx, 1
  654.         jc      error
  655.         add     cx, bx
  656.         jc      error
  657.         cbw
  658.         add     cx, ax
  659.         jc      error
  660. i3:
  661.         inc     edi
  662.         jmp     i1
  663. i_exit:
  664.         mov     ax, cx
  665.         clc
  666. i4:
  667.         movzx   eax, ax
  668.         pop     edi
  669.         pop     dx
  670.         pop     cx
  671.         pop     bx
  672.         ret
  673.  
  674. error:
  675.         stc
  676.         jmp     i4
  677.  
  678. partition_string:
  679.                   dd 0
  680.                   db 32
  681.