Subversion Repositories Kolibri OS

Rev

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