Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                      ;;
  3. ;; System service for filesystem call                                   ;;
  4. ;; (C) 2004 Ville Turjanmaa, License: GPL                               ;;
  5. ;;                                                                      ;;
  6. ;; xx.04.2006 LFN support - diamond                                     ;;
  7. ;; 15.01.2005 get file size/attr/date, file_append (only for hd) - ATV  ;;
  8. ;; 23.11.2004 test if hd/partition is set - ATV                         ;;
  9. ;; 18.11.2004 get_disk_info and more error codes - ATV                  ;;
  10. ;; 08.11.2004 expand_pathz and rename (only for hd) - ATV               ;;
  11. ;; 20.10.2004 Makedir/Removedir (only for hd) - ATV                     ;;
  12. ;;                                                                      ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. iglobal
  16. dir0:        db  'HARDDISK   '
  17.              db  'RAMDISK    '
  18.              db  'FLOPPYDISK '
  19.              db  0
  20.  
  21. dir1:        db  'FIRST      '
  22.              db  'SECOND     '
  23.              db  'THIRD      '
  24.              db  'FOURTH     '
  25.              db  0
  26.  
  27. not_select_IDE db 0
  28.  
  29. hd_address_table:  dd  0x1f0,0x00,0x1f0,0x10
  30.                    dd  0x170,0x00,0x170,0x10
  31. endg
  32.  
  33. file_system:
  34. ; IN:
  35. ;
  36. ; eax = 0  ; read file          /RamDisk/First  6   /HardDisk/First 30
  37. ; eax = 1  ; write file         /RamDisk/First 33   /HardDisk/First 56
  38. ; eax = 2  ; delete file        /RamDisk/First 32   /HardDisk/First 57
  39. ; eax = 3  ; append to a file   /RamDisk/First ??   /HardDisk/First ??
  40. ; eax = 4  ; makedir
  41. ; eax = 5  ; rename file/directory
  42. ; eax = 8  ; lba read
  43. ; eax = 12 ; get_filesize
  44. ; eax = 13 ; get_fileattr
  45. ; eax = 14 ; get_filedate
  46. ; eax = 15 ; get_disk_info
  47. ; eax = 16 ; start application
  48. ;
  49. ; OUT:
  50. ;
  51. ; eax = 0  : read ok
  52. ; eax = 1  : no hd base and/or partition defined
  53. ; eax = 2  : function is unsupported for this FS
  54. ; eax = 3  : unknown FS
  55. ; eax = 4  : partition not defined at hd
  56. ; eax = 5  : file not found
  57. ; eax = 6  : end of file
  58. ; eax = 7  : memory pointer not in application area
  59. ; eax = 8  : disk full
  60. ; eax = 9  : fat table corrupted
  61. ; eax = 10 : access denied
  62. ;
  63. ; ebx = size
  64.  
  65. ; \begin{diamond}[18.03.2006]
  66. ; for subfunction 16 (start application) error codes must be negative
  67. ;    because positive values are valid PIDs
  68. ; so possible return values are:
  69. ; eax > 0 : process created, eax=PID
  70.  
  71. ; -0x10 <= eax < 0 : -eax is filesystem error code:
  72. ; eax = -1  = 0xFFFFFFFF : no hd base and/or partition defined
  73. ; eax = -3  = 0xFFFFFFFD : unknown FS
  74. ; eax = -5  = 0xFFFFFFFB : file not found
  75. ; eax = -6  = 0xFFFFFFFA : unexpected end of file (probably not executable file)
  76. ; eax = -9  = 0xFFFFFFF7 : fat table corrupted
  77. ; eax = -10 = 0xFFFFFFF6 : access denied
  78.  
  79. ; -0x20 <= eax < -0x10: eax is process creation error code:
  80. ; eax = -0x20 = 0xFFFFFFE0 : too many processes
  81. ; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
  82. ; eax = -0x1E = 0xFFFFFFE2 : no memory
  83.  
  84. ; ebx is not changed
  85.  
  86. ; \end{diamond}[18.03.2006]
  87.  
  88.     ; Extract parameters
  89.     add    eax, std_application_base_address    ; abs start of info block
  90. ; \begin{diamond}
  91.         cmp     byte [eax+1], 1
  92.         jz      file_system_lfn
  93. ; \end{diamond}
  94.  
  95.     cmp   dword [eax+0],12      ; Get file size
  96.     je    fs_read
  97.     cmp   dword [eax+0],13      ; Get file attribute
  98.     je    fs_read
  99.     cmp   dword [eax+0],14      ; Get file date/time
  100.     je    fs_read
  101.     cmp   dword [eax+0],15      ; GET_DISK_INFO
  102.     je    fs_info
  103.     cmp   dword [eax+0],16      ; RUN - dont care about read&write blocks
  104.     je    fs_read
  105.     cmp   dword [eax+0],5       ; RENAME - dont care about read&write blocks
  106.     je    fs_read
  107.     cmp   dword [eax+0],4       ; MAKEDIR - dont care about read&write blocks
  108.     je    fs_read
  109.     cmp   dword [eax+0],2       ; DELETE - dont care about read&write blocks
  110.     je    fs_read
  111.  
  112.     cmp   dword [0x3000],1      ; no memory checks for kernel requests
  113.     jz    no_checks_for_kernel
  114.     mov   edx,eax
  115.     cmp   dword [eax+0],1
  116.     jz    .check_for_write_op
  117.     cmp   dword [eax+0],3
  118.     jnz   .usual_check
  119. .check_for_write_op:    
  120.     mov   ebx,[eax+12]
  121.     add   ebx,std_application_base_address
  122.     mov   ecx,[eax+8]
  123.     call  check_region
  124.     test  eax,eax
  125.     jnz   area_in_app_mem
  126.    
  127. .error_output:
  128.     mov   esi,buffer_failed
  129.     call  sys_msg_board_str
  130. ;    mov   eax,7
  131.     mov   dword [esp+36],7
  132.     ret
  133. iglobal
  134.   buffer_failed db 'K : Buffer check failed',13,10,0
  135. endg
  136. .usual_check:
  137.     cmp   dword [eax+0],0
  138.     mov   ecx,512
  139.     jnz   .small_size
  140.     mov   ecx,[eax+8]
  141.     shl   ecx,9
  142. .small_size:
  143.     mov   ebx,[eax+12]
  144.     add   ebx,std_application_base_address
  145.     call  check_region
  146.     test  eax,eax
  147.     jz    .error_output
  148.   area_in_app_mem:
  149.     mov   eax,edx
  150.   no_checks_for_kernel:
  151.  
  152.  
  153.     cmp   dword [eax+0],3       ; APPEND - allow write 0 bytes (truncate)
  154.     je    fs_read
  155.     cmp   dword [eax+8],0       ; read or write 0 blocks/bytes ?
  156.     jne   fs_read
  157.     and   dword [esp+36],0
  158.     ret
  159.   fs_read:
  160.  
  161.     mov   ebx,[eax+20]          ; program wants root directory ?
  162.     test  bl,bl
  163.     je    fs_getroot
  164.     test  bh,bh
  165.     jne   fs_noroot
  166.   fs_getroot:
  167. ; \begin{diamond}[18.03.2006]
  168. ; root - only read is allowed
  169. ; other operations return "access denied", eax=10
  170. ; (execute operation returns eax=-10)
  171.     cmp    dword [eax], 0
  172.     jz    .read_root
  173.     mov    ecx, 10
  174.     cmp    dword [eax], 16
  175.     jnz    @f
  176.     neg    ecx
  177. @@:    mov    [esp+36], ecx
  178.     ret
  179. .read_root:
  180. ; \end{diamond}[18.03.2006]
  181.     mov   esi,dir0
  182.     mov   edi,[eax+12]
  183.     add   edi,std_application_base_address
  184.     mov   ecx,11
  185.     push  ecx
  186. ;    cld    ; already is
  187.     rep   movsb
  188.     mov   al,0x10
  189.     stosb
  190.     add   edi,32-11-1
  191.     pop   ecx
  192.     rep   movsb
  193.     stosb
  194.     and   dword [esp+36],0      ; ok read
  195.     mov   dword [esp+24],32*2   ; size of root
  196.     ret
  197.  
  198.   fs_info:                      ;start of code - Mihasik
  199.     push  eax
  200.     cmp   [eax+21],byte 'h'
  201.     je    fs_info_h
  202.     cmp   [eax+21],byte 'H'
  203.     je    fs_info_h
  204.     cmp   [eax+21],byte 'r'
  205.     je    fs_info_r
  206.     cmp   [eax+21],byte 'R'
  207.     je    fs_info_r
  208.     mov   eax,3                 ;if unknown disk
  209.     xor   ebx,ebx
  210.     xor   ecx,ecx
  211.     xor   edx,edx
  212.     jmp   fs_info1
  213.   fs_info_r:
  214.     call  ramdisk_free_space    ;if ramdisk
  215.     mov   ecx,edi               ;free space in ecx
  216.     shr   ecx,9                 ;free clusters
  217.     mov   ebx,2847              ;total clusters
  218.     mov   edx,512               ;cluster size
  219.     xor   eax,eax               ;always 0
  220.     jmp   fs_info1
  221.   fs_info_h:                    ;if harddisk
  222.     call  get_hd_info
  223.   fs_info1:
  224.     pop   edi
  225.     mov   [esp+36],eax
  226.     mov   [esp+24],ebx           ; total clusters on disk
  227.     mov   [esp+32],ecx           ; free clusters on disk
  228.     mov   [edi],edx              ; cluster size in bytes
  229.     ret                          ;end of code - Mihasik
  230.  
  231.   fs_noroot:
  232.  
  233.     push  dword [eax+0]         ; read/write/delete/.../makedir/rename/lba/run
  234.     push  dword [eax+4]         ; 512 block number to read
  235.     push  dword [eax+8]         ; bytes to write/append or 512 blocks to read
  236.     mov   ebx,[eax+12]
  237.     add   ebx,std_application_base_address
  238.     push  ebx                   ; abs start of return/save area
  239.  
  240.     lea   esi,[eax+20]          ; abs start of dir + filename
  241.     mov   edi,[eax+16]
  242.     add   edi,std_application_base_address    ; abs start of work area
  243.  
  244.     call  expand_pathz
  245.  
  246.     push  edi                   ; dir start
  247.     push  ebx                   ; name of file start
  248.  
  249.     mov   eax,[edi+1]
  250.     cmp   eax,'RD  '
  251.     je    fs_yesramdisk
  252.     cmp   eax,'RAMD'
  253.     jne   fs_noramdisk
  254.  
  255.   fs_yesramdisk:
  256.  
  257.     cmp   byte [edi+1+11],0
  258.     je    fs_give_dir1
  259.  
  260.     mov   eax,[edi+1+12]
  261.     cmp   eax,'1   '
  262.     je    fs_yesramdisk_first
  263.     cmp   eax,'FIRS'
  264.     jne   fs_noramdisk
  265.  
  266.   fs_yesramdisk_first:
  267.  
  268.     cmp   dword [esp+20],8      ; LBA read ramdisk
  269.     jne   fs_no_LBA_read_ramdisk
  270.  
  271.     mov   eax,[esp+16]          ; LBA block to read
  272.     mov   ecx,[esp+8]           ; abs pointer to return area
  273.  
  274.     call  LBA_read_ramdisk
  275.     jmp   file_system_return
  276.  
  277.  
  278.   fs_no_LBA_read_ramdisk:
  279.  
  280.     cmp   dword [esp+20],0      ; READ
  281.     jne   fs_noramdisk_read
  282.  
  283.     mov   eax,[esp+4]           ; fname
  284.     add   eax,2*12+1
  285.     mov   ebx,[esp+16]          ; block start
  286.     inc   ebx
  287.     mov   ecx,[esp+12]          ; block count
  288.     mov   edx,[esp+8]           ; return
  289.     mov   esi,[esp+0]
  290.     sub   esi,eax
  291.     add   esi,12+1              ; file name length
  292.     call  fileread
  293.  
  294.     jmp   file_system_return
  295.  
  296.  
  297.   fs_noramdisk_read:
  298.  
  299.     cmp   dword [esp+20],1      ; WRITE
  300.     jne   fs_noramdisk_write
  301.  
  302.     mov   eax,[esp+4]           ; fname
  303.     add   eax,2*12+1
  304.     mov   ebx,[esp+8]           ; buffer
  305.     mov   ecx,[esp+12]          ; count to write
  306.     mov   edx,0                 ; create new
  307.     call  filesave
  308.  
  309.     ; eax=0 ok - eax=1 not enough free space
  310.  
  311.     jmp   file_system_return
  312.  
  313.   fs_noramdisk_write:
  314.  
  315.     cmp   dword [esp+20],16     ; START APPLICATION
  316.     jne   fs_noramdisk_start_application
  317.  
  318.     mov   eax,[esp+4]           ; fname
  319.     add   eax,2*12+1
  320.  
  321.     xor   ebx,ebx               ; parameters to pass
  322.     cmp   dword [esp+12],ebx;0
  323.     je    no_fl_start_param
  324.     mov   ebx, [esp+12]
  325.     add   ebx, std_application_base_address
  326.   no_fl_start_param:
  327.     mov   edx,[esp+16]        ; flags
  328.  
  329.     call  start_application_fl
  330.  
  331.     jmp   file_system_startapp_return
  332.  
  333.   fs_noramdisk_start_application:     ;there's new code - Mihasik
  334.     cmp   dword [esp+20],2      ;DELETE
  335.     jne   fs_noramdisk_delete
  336.     mov   eax,[esp+4]           ; fname
  337.     add   eax,2*12+1
  338.     call  filedelete
  339.     jmp   file_system_return
  340.  
  341.   fs_noramdisk_delete:
  342.     cmp   dword [esp+20],12     ;GET TIME,DATE,SIZE AND ATTRS
  343.     jb    fs_noramdisk_getinfo
  344.     cmp   dword [esp+20],14
  345.     ja    fs_noramdisk_getinfo
  346.     mov   eax,[esp+4]           ; fname
  347.     add   eax,2*12+1
  348.     mov   ebx,[esp+20]
  349.     mov   ecx,[esp+0]
  350.     sub   ecx,eax
  351.     add   ecx,12+1              ; file name length
  352.     call  rd_getfileinfo
  353.     jmp   file_system_return
  354.   fs_noramdisk_getinfo:             ;End of code - Mihasik
  355.  
  356.   fs_noramdisk:
  357.  
  358.   ;********************************************************************
  359.     mov   eax,[edi+1]
  360.     cmp   eax,'FD  '
  361.     je    fs_yesflpdisk
  362.     cmp   eax,'FLOP'
  363.     jne   fs_noflpdisk
  364.  
  365.   fs_yesflpdisk:
  366.     call   reserve_flp
  367.  
  368.     cmp   byte [edi+1+11],0
  369.     je    fs_give_dir1
  370.  
  371.     mov   eax,[edi+1+12]
  372.     cmp   eax,'1   '            
  373.     je    fs_yesflpdisk_first
  374.     cmp   eax,'FIRS'
  375.     je    fs_yesflpdisk_first
  376.     cmp   eax,'2   '
  377.     je    fs_yesflpdisk_second
  378.     cmp   eax,'SECO'
  379.     jne   fs_noflpdisk
  380.     jmp   fs_yesflpdisk_second
  381.  
  382.   fs_yesflpdisk_first:
  383.     mov   [flp_number],1
  384.     jmp   fs_yesflpdisk_start
  385.   fs_yesflpdisk_second:
  386.     mov   [flp_number],2
  387.   fs_yesflpdisk_start:
  388.     cmp   dword [esp+20],0      ; READ
  389.     jne   fs_noflpdisk_read
  390.  
  391.     mov   eax,[esp+4]           ; fname
  392.     add   eax,2*12+1
  393.     mov   ebx,[esp+16]          ; block start
  394.     inc   ebx
  395.     mov   ecx,[esp+12]          ; block count
  396.     mov   edx,[esp+8]           ; return
  397.     mov   esi,[esp+0]
  398.     sub   esi,eax
  399.     add   esi,12+1              ; file name length
  400.     call  floppy_fileread
  401.  
  402.     jmp   file_system_return
  403.  
  404.  
  405.   fs_noflpdisk_read:
  406.  
  407.     cmp   dword [esp+20],1      ; WRITE
  408.     jne   fs_noflpdisk_write
  409.  
  410.     mov   eax,[esp+4]           ; fname
  411.     add   eax,2*12+1
  412.     mov   ebx,[esp+8]           ; buffer
  413.     mov   ecx,[esp+12]          ; count to write
  414.     mov   edx,0                 ; create new
  415.     call  floppy_filesave
  416.  
  417.     ; eax=0 ok - eax=1 not enough free space
  418.  
  419.     jmp   file_system_return
  420.  
  421.   fs_noflpdisk_write:
  422.  
  423.     cmp   dword [esp+20],2      ; DELETE
  424.     jne   fs_noflpdisk_delete
  425.  
  426.     mov   eax,[esp+4]           ; fname
  427.     add   eax,2*12+1
  428.     call  floppy_filedelete
  429.     mov   [flp_status],0
  430.     jmp   file_system_return
  431.  
  432.   fs_noflpdisk_delete:
  433.     cmp   dword [esp+20],16     ; START APPLICATION
  434.     jne   fs_noflpdisk_start_application
  435.  
  436.     mov   eax,[esp+4]           ; fname
  437.     add   eax,2*12+1
  438.  
  439.     xor   ebx,ebx               ; parameters to pass
  440.     cmp   dword [esp+12],ebx;0
  441.     je    no_flp_start_param
  442.     mov   ebx,[0x3010]
  443.     mov   ebx,[ebx+0x10]
  444.     add   ebx,[esp+12]
  445.  
  446.   no_flp_start_param:
  447.     mov   edx,[esp+16]        ; flags
  448.  
  449.     call  start_application_floppy
  450.  
  451. file_system_startapp_return:
  452.     mov    ebx, [esp+24+24]    ; do not modify ebx in application
  453.     jmp   file_system_return
  454.  
  455.   fs_noflpdisk_start_application:
  456.  
  457.   fs_noflpdisk:
  458.   ;*****************************************************************
  459.  
  460.     mov   eax,[edi+1]
  461.     cmp   eax,'HD0 '
  462.     je    fs_yesharddisk_IDE0
  463.     cmp   eax,'HD1 '
  464.     je    fs_yesharddisk_IDE1
  465.     cmp   eax,'HD2 '
  466.     je    fs_yesharddisk_IDE2
  467.     cmp   eax,'HD3 '
  468.     je    fs_yesharddisk_IDE3
  469.     jmp   old_path_harddisk
  470. fs_yesharddisk_IDE0:
  471.      call  reserve_hd1
  472.      mov  [hdbase],0x1f0
  473.      mov  [hdid],0x0
  474.      mov  [hdpos],1
  475.      jmp  fs_yesharddisk_partition
  476. fs_yesharddisk_IDE1:
  477.      call  reserve_hd1
  478.      mov  [hdbase],0x1f0
  479.      mov  [hdid],0x10
  480.      mov  [hdpos],2
  481.      jmp  fs_yesharddisk_partition
  482. fs_yesharddisk_IDE2:
  483.      call  reserve_hd1
  484.      mov  [hdbase],0x170
  485.      mov  [hdid],0x0
  486.      mov  [hdpos],3
  487.      jmp  fs_yesharddisk_partition
  488. fs_yesharddisk_IDE3:
  489.      call  reserve_hd1
  490.      mov  [hdbase],0x170
  491.      mov  [hdid],0x10
  492.      mov  [hdpos],4
  493. fs_yesharddisk_partition:
  494. ;    call  choice_necessity_partition
  495. ;    jmp   fs_yesharddisk_all    
  496.     jmp   fs_for_new_semantic
  497.  
  498. choice_necessity_partition:
  499.     mov   eax,[edi+1+12]
  500.     call  StringToNumber
  501.         mov   [fat32part],eax
  502. choice_necessity_partition_1:
  503.     mov   ecx,[hdpos]
  504.     xor   eax,eax
  505.     mov   [0xfe10], eax    ; entries in hd cache
  506.     mov   edx,0x40002
  507.  search_partition_array:
  508.     mov   bl,[edx]
  509.     movzx ebx,bl
  510.     add   eax,ebx
  511.     inc   edx
  512.     loop  search_partition_array
  513.     sub   eax,ebx
  514.     add   eax,[fat32part]
  515.     dec   eax
  516.     xor   edx,edx
  517.     imul  eax,100
  518.     add   eax,0x4000a
  519.     mov   [transfer_adress],eax
  520.     call  partition_data_transfer_1
  521.     ret
  522.  
  523.  old_path_harddisk:
  524.     mov   eax,[edi+1]
  525.     cmp   eax,'HD  '
  526.     je    fs_yesharddisk
  527.     cmp   eax,'HARD'
  528.     jne   fs_noharddisk
  529.  
  530.   fs_yesharddisk:
  531.     cmp   dword [esp+20],8      ; LBA read
  532.     jne   fs_no_LBA_read
  533.     mov   eax,[esp+16]          ; LBA block to read
  534.     lea   ebx,[edi+1+12]        ; pointer to FIRST/SECOND/THIRD/FOURTH
  535.     mov   ecx,[esp+8]           ; abs pointer to return area
  536.     call  LBA_read
  537.     jmp   file_system_return
  538.  
  539.   fs_no_LBA_read:
  540.  
  541.     cmp   byte [edi+1+11],0     ; directory read
  542.     je    fs_give_dir1
  543.     call  reserve_hd1
  544.  fs_for_new_semantic:
  545.     call  choice_necessity_partition
  546.  
  547.   fs_yesharddisk_all:
  548.     mov   eax,1
  549.     cmp    dword [esp+20], 16
  550.     jnz    @f
  551.     neg    eax
  552. @@:    mov    ebx, [esp+24+24]
  553.     cmp   [hdpos],0             ; is hd base set?
  554.     jz    hd_err_return
  555.     cmp   [fat32part],0         ; is partition set?
  556.     jnz   @f
  557. hd_err_return:
  558.     and   [hd1_status], 0
  559.     jmp   file_system_return
  560. @@:
  561.  
  562.     cmp   dword [esp+20],0      ; READ
  563.     jne   fs_noharddisk_read
  564.  
  565.     mov   eax,[esp+0]           ; /fname
  566.     lea   edi,[eax+12]
  567.     mov   byte [eax],0          ; path to asciiz
  568.     inc   eax                   ; filename start
  569.  
  570.     mov   ebx,[esp+12]          ; count to read
  571.     mov   ecx,[esp+8]           ; buffer
  572.     mov   edx,[esp+4]
  573.     add   edx,12*2              ; dir start
  574.     sub   edi,edx               ; path length
  575.     mov   esi,[esp+16]          ; blocks to read
  576.  
  577.     call  file_read
  578.  
  579.     mov   edi,[esp+0]
  580.     mov   byte [edi],'/'
  581.  
  582.     jmp   file_system_return
  583.  
  584.   fs_noharddisk_read:
  585.  
  586.  
  587.     cmp   dword [esp+20],1      ; WRITE
  588.     jne   fs_noharddisk_write
  589.  
  590.     mov   eax,[esp+0]           ; /fname
  591.     mov   byte [eax],0          ; path to asciiz
  592.     inc   eax                   ; filename start
  593.  
  594.     mov   ebx,[esp+12]          ; count to write
  595.     mov   ecx,[esp+8]           ; buffer
  596.     mov   edx,[esp+4]
  597.     add   edx,12*2              ; path start
  598.  
  599.     call  file_write
  600.  
  601.     mov   edi,[esp+0]
  602.     mov   byte [edi],'/'
  603.  
  604.     ; eax=0 ok - eax=1 not enough free space
  605.  
  606.     jmp   file_system_return
  607.  
  608.  
  609.   fs_noharddisk_write:
  610.  
  611.     cmp   dword [esp+20],2      ; DELETE
  612.     jne   fs_noharddisk_delete
  613.  
  614.     mov   eax,[esp+0]           ; /dirname or /filename
  615.     mov   byte [eax],0          ; path to asciiz
  616.     inc   eax                   ; filename start
  617.     mov   edx,[esp+4]
  618.     add   edx,12*2              ; path start
  619.  
  620.     call  removedir
  621.  
  622.     mov   edi,[esp+0]
  623.     mov   byte [edi],'/'
  624.  
  625.     jmp   file_system_return
  626.  
  627.   fs_noharddisk_delete:
  628.  
  629.     cmp   dword [esp+20],3      ; APPEND
  630.     jne   fs_noharddisk_append
  631.  
  632.     mov   eax,[esp+0]           ; /dirname or /filename
  633.     mov   byte [eax],0          ; path to asciiz
  634.     inc   eax                   ; filename start
  635.     mov   edx,[esp+4]
  636.     add   edx,12*2              ; path start
  637.     mov   ecx,[esp+8]           ; buffer
  638.     mov   ebx,[esp+12]          ; count to write
  639.     mov   esi,[esp+16]          ; bytes to skip over
  640.  
  641.     call  file_append
  642.  
  643.     mov   edi,[esp+0]
  644.     mov   byte [edi],'/'
  645.  
  646.     jmp   file_system_return
  647.  
  648.   fs_noharddisk_append:
  649.  
  650.     cmp   dword [esp+20],4      ; MAKEDIR
  651.     jne   fs_noharddisk_makedir
  652.  
  653.     mov   eax,[esp+0]           ; /dirname
  654.     mov   byte [eax],0          ; path to asciiz
  655.     inc   eax                   ; filename start
  656.     mov   edx,[esp+4]
  657.     add   edx,12*2              ; path start
  658.  
  659.     call  makedir
  660.  
  661.     mov   edi,[esp+0]
  662.     mov   byte [edi],'/'
  663.  
  664.     jmp   file_system_return
  665.  
  666.   fs_noharddisk_makedir:
  667.  
  668.     cmp   dword [esp+20],5      ; RENAME
  669.     jne   fs_noharddisk_rename
  670.  
  671.     mov   edi,[esp+0]           ; start of source file name
  672.     add   edi,12+1              ; continue after name
  673.     call  expand_pathz          ; convert destination name
  674.  
  675.     mov   eax,[edi+1]
  676.     cmp   eax,'HD  '
  677.     je    fs_rename_test1
  678.     cmp   eax,'HARD'
  679.     jne   fs_rename_error
  680.  
  681.   fs_rename_test1:
  682.     mov   eax,[edi+1+12]
  683.     cmp   eax,'1   '
  684.     je    fs_rename_start
  685.     cmp   eax,'FIRS'
  686.     jne   fs_rename_error
  687.  
  688.   fs_rename_start:
  689.     mov   byte [ebx],0          ; path to asciiz
  690.     inc   ebx                   ; filename start
  691.     add   edi,12*2              ; path start
  692.     cmp   byte [ebx],0
  693.     je    fs_rename_error
  694.     cmp   byte [ebx],32
  695.     je    fs_rename_error
  696.  
  697.     mov   eax,[esp+0]           ; /filename
  698.     mov   byte [eax],0          ; path to asciiz
  699.     inc   eax                   ; filename start
  700.     mov   edx,[esp+4]
  701.     add   edx,12*2              ; path start
  702.  
  703.     call  rename
  704.  
  705.     mov   edi,[esp+0]
  706.     mov   byte [edi],'/'
  707.  
  708.     jmp   file_system_return
  709.  
  710.   fs_rename_error:
  711.     mov   eax,4                 ; partition not defined at hd
  712.     jmp   file_system_return
  713.  
  714.   fs_noharddisk_rename:
  715.  
  716.     cmp   dword [esp+20],12     ; get FILESIZE
  717.     jne   fs_noharddisk_get_filesize
  718.  
  719.     mov   eax,[esp+0]           ; /fname
  720.     lea   edi,[eax+12]
  721.     mov   byte [eax],0          ; path to asciiz
  722.     inc   eax                   ; filename start
  723.     mov   edx,[esp+4]
  724.     add   edx,12*2              ; path start
  725.     sub   edi,edx               ; path length
  726.  
  727.     call  get_filesize
  728.  
  729.     mov   edi,[esp+0]
  730.     mov   byte [edi],'/'
  731.  
  732.     jmp   file_system_return
  733.  
  734.   fs_noharddisk_get_filesize:
  735.  
  736.     cmp   dword [esp+20],13     ; get FILEATTR
  737.     jne   fs_noharddisk_get_fileattr
  738.  
  739.     mov   eax,[esp+0]           ; /dirname
  740.     mov   byte [eax],0          ; path to asciiz
  741.     inc   eax                   ; filename start
  742.     mov   edx,[esp+4]
  743.     add   edx,12*2              ; path start
  744.  
  745.     call  get_fileattr
  746.  
  747.     mov   edi,[esp+0]
  748.     mov   byte [edi],'/'
  749.  
  750.     jmp   file_system_return
  751.  
  752.   fs_noharddisk_get_fileattr:
  753.  
  754.     cmp   dword [esp+20],14     ; get FILEDATE
  755.     jne   fs_noharddisk_get_filedate
  756.  
  757.     mov   eax,[esp+0]           ; /dirname
  758.     mov   byte [eax],0          ; path to asciiz
  759.     inc   eax                   ; filename start
  760.     mov   edx,[esp+4]
  761.     add   edx,12*2              ; path start
  762.  
  763.     call  get_filedate
  764.  
  765.     mov   edi,[esp+0]
  766.     mov   byte [edi],'/'
  767.  
  768.     jmp   file_system_return
  769.  
  770.   fs_noharddisk_get_filedate:
  771.  
  772.     cmp   dword [esp+20],16     ; START APPLICATION
  773.     jne   fs_noharddisk_start_application
  774.  
  775.     mov   eax,[esp+4]           ; fname
  776.     add   eax,12*2
  777.  
  778.     mov   ebx,[esp+0]           ; length
  779.     sub   ebx,eax
  780.     add   ebx,12
  781.  
  782.     mov   ecx,[esp+4]           ; work area
  783.     add   ecx,512
  784.  
  785.     xor   ebp,ebp               ; parameters to pass
  786.     cmp   dword [esp+12],ebp;0
  787.     je    no_hd_start_param
  788.     mov   ebp, [esp+12]
  789.     add   ebp, std_application_base_address
  790.   no_hd_start_param:
  791.     mov   edx,[esp+16]        ; flags
  792.  
  793.     call  start_application_hd
  794.  
  795.     jmp   file_system_startapp_return
  796.  
  797.   fs_noharddisk_start_application:
  798.  
  799.   fs_noharddisk:
  800. ; \begin{diamond}[18.03.2006]
  801.     mov    eax, 5        ; file not found
  802. ; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
  803.     cmp    dword [esp+20], 16
  804.     jnz    @f
  805.     neg    eax
  806. @@:    mov    ebx, [esp+24+24]    ; do not change ebx in application
  807. ; \end{diamond}[18.03.2006]
  808.  
  809.   file_system_return:
  810.  
  811.     add   esp,24
  812.  
  813.     mov   [esp+36],eax
  814.     mov   [esp+24],ebx
  815.     ret
  816.  
  817.  
  818.   fs_give_dir1:
  819.  
  820. ; \begin{diamond}[18.03.2006]
  821. ; /RD,/FD,/HD - only read is allowed
  822. ; other operations return "access denied", eax=10
  823. ; (execute operation returns eax=-10)
  824.     cmp    dword [esp+20], 0
  825.     jz    .read
  826.     add    esp, 20
  827.     pop    ecx
  828.     mov    eax, 10
  829.     cmp    ecx, 16
  830.     jnz    @f
  831.     neg    eax
  832. @@:    mov    [esp+36], eax
  833.     ret
  834. .read:
  835. ; \end{diamond}[18.03.2006]
  836.     mov   al,0x10
  837.     mov   ebx,1
  838.     mov   edi,[esp+8]
  839.     mov   esi,dir1
  840.   fs_d1_new:
  841.     mov   ecx,11
  842. ;    cld
  843.     rep   movsb
  844.     stosb
  845.     add   edi,32-11-1
  846.     dec   ebx
  847.     jne   fs_d1_new
  848.  
  849.     add   esp,24
  850.  
  851.     and   dword [esp+36],0      ; ok read
  852.     mov   dword [esp+24],32*1   ; dir/data size
  853.     ret
  854.  
  855.  
  856.  
  857. LBA_read_ramdisk:
  858.  
  859.     cmp   [lba_read_enabled],1
  860.     je    lbarrl1
  861.  
  862.     xor   ebx,ebx
  863.     mov   eax,2
  864.     ret
  865.  
  866.   lbarrl1:
  867.  
  868.     cmp   eax,18*2*80
  869.     jb    lbarrl2
  870.     xor   ebx,ebx
  871.     mov   eax,3
  872.     ret
  873.  
  874.   lbarrl2:
  875.  
  876.     pushad
  877.  
  878.     call  restorefatchain
  879.  
  880.     mov   edi,ecx
  881.     mov   esi,eax
  882.  
  883.     shl   esi,9
  884.     add   esi,0x100000
  885.     mov   ecx,512/4
  886. ;    cld
  887.     rep   movsd
  888.  
  889.     popad
  890.  
  891.     xor   ebx,ebx
  892.     xor   eax,eax
  893.     ret
  894.  
  895. LBA_read:
  896.  
  897. ; IN:
  898. ;
  899. ; eax = LBA block to read
  900. ; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
  901. ; ecx = abs pointer to return area
  902.  
  903.     cmp   [lba_read_enabled],1
  904.     je    lbarl1
  905.     mov   eax,2
  906.     ret
  907.  
  908.   lbarl1:
  909.  
  910.     call  reserve_hd1
  911.  
  912.     push  eax
  913.     push  ecx
  914.  
  915.     mov   edi,hd_address_table
  916.     mov   esi,dir1
  917.     mov   eax,[ebx]
  918.     mov   edx,'1   '
  919.     mov   ecx,4
  920.   blar0:
  921.     cmp   eax,[esi]
  922.     je    blar2
  923.     cmp   eax,edx
  924.     je    blar2
  925.     inc   edx
  926.     add   edi,8
  927.     add   esi,11
  928.     dec   ecx
  929.     jnz   blar0
  930.  
  931.     mov   eax,1
  932.     mov   ebx,1
  933.     jmp   LBA_read_ret
  934.  
  935.   blar2:
  936.     mov   eax,[edi+0]
  937.     mov   ebx,[edi+4]
  938.  
  939.     mov  [hdbase],eax
  940.     mov  [hdid],ebx
  941.  
  942.     call  wait_for_hd_idle
  943.  
  944.     ; eax = hd port
  945.     ; ebx = set for primary (0x00) or slave (0x10)
  946.  
  947.     cli
  948.  
  949.     mov   edx,eax
  950.     inc   edx
  951.     xor   eax,eax
  952.     out   dx,al
  953.     inc   edx
  954.     inc   eax
  955.     out   dx,al
  956.     inc   edx
  957.     mov   eax,[esp+4]
  958.     out   dx,al
  959.     shr   eax,8
  960.     inc   edx
  961.     out   dx,al
  962.     shr   eax,8
  963.     inc   edx
  964.     out   dx,al
  965.     shr   eax,8
  966.     inc   edx
  967.     and   al,1+2+4+8
  968.     add   al,bl
  969.     add   al,128+64+32
  970.     out   dx,al
  971.  
  972.     inc   edx
  973.     mov   al,20h
  974.     out   dx,al
  975.  
  976.     sti
  977.  
  978.     call  wait_for_sector_buffer
  979.  
  980.     cli
  981.  
  982.     mov   edi,[esp+0]
  983.     mov   ecx,256
  984.     sub   edx,7
  985.     cld
  986.     rep   insw
  987.  
  988.     sti
  989.  
  990.     xor   eax,eax
  991.     xor   ebx,ebx
  992.  
  993.   LBA_read_ret:
  994.  
  995.     mov   [hd1_status],0
  996.     add   esp,2*4
  997.  
  998.     ret
  999.  
  1000.  
  1001. expand_pathz:
  1002. ; IN:
  1003. ;   esi = asciiz path & file
  1004. ;   edi = buffer for path & file name
  1005. ; OUT:
  1006. ;   edi = directory & file : / 11 + / 11 + / 11 - zero terminated
  1007. ;   ebx = /file name - zero terminated
  1008. ;   esi = pointer after source
  1009.  
  1010.     push  eax
  1011.     push  ecx
  1012.     push  edi ;[esp+0]
  1013.  
  1014.   pathz_start:
  1015.     mov   byte [edi],'/'
  1016.     inc   edi
  1017.     mov   al,32
  1018.     mov   ecx,11
  1019.     cld
  1020.     rep   stosb                 ; clear filename area
  1021.     sub   edi,11
  1022.     mov   ebx,edi               ; start of dir/file name
  1023.  
  1024.   pathz_new_char:
  1025.     mov   al,[esi]
  1026.     inc   esi
  1027.     cmp   al,0
  1028.     je    pathz_end
  1029.  
  1030.     cmp   al,'/'
  1031.     jne   pathz_not_path
  1032.     cmp   edi,ebx               ; skip first '/'
  1033.     jz    pathz_new_char
  1034.     lea   edi,[ebx+11]          ; start of next directory
  1035.     jmp   pathz_start
  1036.  
  1037.   pathz_not_path:
  1038.     cmp   al,'.'
  1039.     jne   pathz_not_ext
  1040.     lea   edi,[ebx+8]           ; start of extension
  1041.     jmp   pathz_new_char
  1042.  
  1043.   pathz_not_ext:
  1044.     cmp   al,'a'
  1045.     jb    pathz_not_low
  1046.     cmp   al,'z'
  1047.     ja    pathz_not_low
  1048.     sub   al,0x20               ; char to uppercase
  1049.  
  1050.   pathz_not_low:
  1051.     mov   [edi],al
  1052.     inc   edi
  1053.     mov   eax,[esp+0]           ; start_of_dest_path
  1054.     add   eax,512               ; keep maximum path under 512 bytes
  1055.     cmp   edi,eax
  1056.     jb    pathz_new_char
  1057.  
  1058.   pathz_end:
  1059.     cmp   ebx,edi               ; if path end with '/'
  1060.     jnz   pathz_put_zero        ; go back 1 level
  1061.     sub   ebx,12
  1062.  
  1063.   pathz_put_zero:
  1064.     mov   byte [ebx+11],0
  1065.     dec   ebx                   ; include '/' char into file name
  1066.     pop   edi
  1067.     pop   ecx
  1068.     pop   eax
  1069.     ret
  1070.  
  1071. ;*******************************************
  1072. ;* string to number
  1073. ;* input eax - 4 byte string
  1074. ;* output eax - number
  1075. ;*******************************************
  1076. StringToNumber:
  1077. ;    ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ
  1078. ;    Âõîä:
  1079. ;        EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh
  1080. ;    Âûõîä:
  1081. ;        CF - èíäèêàòîð îøèáîê:
  1082. ;            0 - îøèáîê íåò;
  1083. ;            1 - îøèáêà
  1084. ;        Åñëè CF=0, òî AX - ÷èñëî.
  1085.  
  1086.     push    bx
  1087.     push    cx
  1088.     push    dx
  1089.     push    edi
  1090.     mov   [partition_string],eax
  1091.     mov    edi,partition_string
  1092.     xor    cx,cx
  1093. i1:
  1094.     mov    al,[edi]
  1095.     cmp    al,32  ;13
  1096.     je    i_exit
  1097. ;    cmp    al,'0'
  1098. ;    jb    err
  1099. ;    cmp    al,'9'
  1100. ;    ja    err
  1101.     sub    al,48
  1102.     shl    cx,1
  1103.     jc    err
  1104.     mov    bx,cx
  1105.     shl    cx,1
  1106.     jc    err
  1107.     shl    cx,1
  1108.     jc    err
  1109.     add    cx,bx
  1110.     jc    err
  1111.     cbw
  1112.     add    cx,ax
  1113.     jc    err
  1114. i3:
  1115.     inc    edi
  1116.     jmp    i1
  1117. i_exit:
  1118.     mov    ax,cx
  1119.     clc
  1120. i4:
  1121.     movzx  eax,ax
  1122.     pop    edi
  1123.     pop    dx
  1124.     pop    cx
  1125.     pop    bx
  1126.     ret
  1127.  
  1128. err:
  1129.     stc
  1130.     jmp    i4
  1131.  
  1132. partition_string: dd 0
  1133.                   db 32
  1134.  
  1135.         include 'fs_lfn.inc'
  1136.