Subversion Repositories Kolibri OS

Rev

Rev 495 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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