Subversion Repositories Kolibri OS

Rev

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

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