Subversion Repositories Kolibri OS

Rev

Rev 1505 | Blame | Compare with Previous | 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: 3487 $
  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.     cmp   ecx,0x80
  369.     jb    search_partition_array
  370.     mov   ecx,4
  371.  search_partition_array:
  372.     mov   bl,[edx]
  373.     movzx ebx,bl
  374.     add   eax,ebx
  375.     inc   edx
  376.     loop  search_partition_array
  377.     mov   ecx,[hdpos]
  378.     mov   edx,BiosDiskPartitions
  379.     sub   ecx,0x80
  380.     jb    .s
  381.     je    .f
  382.  @@:
  383.     mov   ebx,[edx]
  384.     add   edx,4
  385.     add   eax,ebx
  386.     loop  @b
  387.     jmp   .f
  388.  .s:
  389.     sub   eax,ebx
  390.  .f:
  391.     add   eax, [known_part] ;   add   eax,[fat32part]
  392.     dec   eax
  393.     xor   edx,edx
  394.     imul  eax,100
  395.     add   eax,DRIVE_DATA+0xa
  396.     mov   [transfer_adress],eax
  397.     call  partition_data_transfer_1
  398.     ret
  399.  
  400.  old_path_harddisk:
  401.     mov   eax,[edi+1]
  402.     cmp   eax,'HD  '
  403.     je    fs_yesharddisk
  404.     cmp   eax,'HARD'
  405.     jne   fs_noharddisk
  406.  
  407.   fs_yesharddisk:
  408.     cmp   dword [esp+20],8      ; LBA read
  409.     jne   fs_no_LBA_read
  410.     mov   eax,[esp+16]          ; LBA block to read
  411.     lea   ebx,[edi+1+12]        ; pointer to FIRST/SECOND/THIRD/FOURTH
  412.     mov   ecx,[esp+8]           ; abs pointer to return area
  413.     call  LBA_read
  414.     jmp   file_system_return
  415.  
  416.   fs_no_LBA_read:
  417.  
  418.     cmp   byte [edi+1+11],0     ; directory read
  419.     je    fs_give_dir1
  420.     call  reserve_hd1
  421.  fs_for_new_semantic:
  422.     call  choice_necessity_partition
  423.  
  424.   fs_yesharddisk_all:
  425.     mov   eax,1
  426.     mov    ebx, [esp+24+24]
  427.     cmp   [hdpos],0             ; is hd base set?
  428.     jz    hd_err_return
  429.     cmp   [fat32part],0         ; is partition set?
  430.     jnz   @f
  431. hd_err_return:
  432.     call  free_hd_channel
  433.     and   [hd1_status], 0
  434.     jmp   file_system_return
  435. @@:
  436.  
  437.     cmp   dword [esp+20],0      ; READ
  438.     jne   fs_noharddisk_read
  439.  
  440.     mov   eax,[esp+0]           ; /fname
  441.     lea   edi,[eax+12]
  442.     mov   byte [eax],0          ; path to asciiz
  443.     inc   eax                   ; filename start
  444.  
  445.     mov   ebx,[esp+12]          ; count to read
  446.     mov   ecx,[esp+8]           ; buffer
  447.     mov   edx,[esp+4]
  448.     add   edx,12*2              ; dir start
  449.     sub   edi,edx               ; path length
  450.     mov   esi,[esp+16]          ; blocks to read
  451.  
  452.     call  file_read
  453.  
  454.     mov   edi,[esp+0]
  455.     mov   byte [edi],'/'
  456.  
  457.     call  free_hd_channel
  458.     and   [hd1_status], 0
  459.     jmp   file_system_return
  460.  
  461.   fs_noharddisk_read:
  462.  
  463.     call  free_hd_channel
  464.     and   [hd1_status], 0
  465.  
  466.   fs_noharddisk:
  467. ; \begin{diamond}[18.03.2006]
  468.     mov    eax, 5        ; file not found
  469. ; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
  470.     mov    ebx, [esp+24+24]    ; do not change ebx in application
  471. ; \end{diamond}[18.03.2006]
  472.  
  473.   file_system_return:
  474.  
  475.     add   esp,24
  476.  
  477.     mov   [esp+36],eax
  478.     mov   [esp+24],ebx
  479.     ret
  480.  
  481.  
  482.   fs_give_dir1:
  483.  
  484. ; \begin{diamond}[18.03.2006]
  485. ; /RD,/FD,/HD - only read is allowed
  486. ; other operations return "access denied", eax=10
  487. ; (execute operation returns eax=-10)
  488.     cmp    dword [esp+20], 0
  489.     jz    .read
  490.     add    esp, 20
  491.     pop    ecx
  492.     mov    dword [esp+36], 10
  493.     ret
  494. .read:
  495. ; \end{diamond}[18.03.2006]
  496.     mov   al,0x10
  497.     mov   ebx,1
  498.     mov   edi,[esp+8]
  499.     mov   esi,dir1
  500.   fs_d1_new:
  501.     mov   ecx,11
  502. ;    cld
  503.     rep   movsb
  504.     stosb
  505.     add   edi,32-11-1
  506.     dec   ebx
  507.     jne   fs_d1_new
  508.  
  509.     add   esp,24
  510.  
  511.     and   dword [esp+36],0      ; ok read
  512.     mov   dword [esp+24],32*1   ; dir/data size
  513.     ret
  514.  
  515.  
  516.  
  517. LBA_read_ramdisk:
  518.  
  519.     cmp   [lba_read_enabled],1
  520.     je    lbarrl1
  521.  
  522.     xor   ebx,ebx
  523.     mov   eax,2
  524.     ret
  525.  
  526.   lbarrl1:
  527.  
  528.     cmp   eax,18*2*80
  529.     jb    lbarrl2
  530.     xor   ebx,ebx
  531.     mov   eax,3
  532.     ret
  533.  
  534.   lbarrl2:
  535.  
  536.     pushad
  537.  
  538.     call  restorefatchain
  539.  
  540.     mov   edi,ecx
  541.     mov   esi,eax
  542.  
  543.     shl   esi,9
  544.     add   esi,RAMDISK
  545.     mov   ecx,512/4
  546. ;    cld
  547.     rep   movsd
  548.  
  549.     popad
  550.  
  551.     xor   ebx,ebx
  552.     xor   eax,eax
  553.     ret
  554.  
  555. LBA_read:
  556.  
  557. ; IN:
  558. ;
  559. ; eax = LBA block to read
  560. ; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
  561. ; ecx = abs pointer to return area
  562.  
  563.     cmp   [lba_read_enabled],1
  564.     je    lbarl1
  565.     mov   eax,2
  566.     ret
  567.  
  568.   lbarl1:
  569.  
  570.     call  reserve_hd1
  571.  
  572.     push  eax
  573.     push  ecx
  574.  
  575.     mov   edi,hd_address_table
  576.     mov   esi,dir1
  577.     mov   eax,[ebx]
  578.     mov   edx,'1   '
  579.     mov   ecx,4
  580.   blar0:
  581.     cmp   eax,[esi]
  582.     je    blar2
  583.     cmp   eax,edx
  584.     je    blar2
  585.     inc   edx
  586.     add   edi,8
  587.     add   esi,11
  588.     dec   ecx
  589.     jnz   blar0
  590.  
  591.     mov   eax,1
  592.     mov   ebx,1
  593.     jmp   LBA_read_ret
  594.  
  595.   blar2:
  596.     mov   eax,[edi+0]
  597.     mov   ebx,[edi+4]
  598.  
  599.     mov  [hdbase],eax
  600.     mov  [hdid],ebx
  601.  
  602.     call  wait_for_hd_idle
  603.     cmp   [hd_error],0
  604.     jne   hd_lba_error
  605.  
  606.     ; eax = hd port
  607.     ; ebx = set for primary (0x00) or slave (0x10)
  608.  
  609.     cli
  610.  
  611.     mov   edx,eax
  612.     inc   edx
  613.     xor   eax,eax
  614.     out   dx,al
  615.     inc   edx
  616.     inc   eax
  617.     out   dx,al
  618.     inc   edx
  619.     mov   eax,[esp+4]
  620.     out   dx,al
  621.     shr   eax,8
  622.     inc   edx
  623.     out   dx,al
  624.     shr   eax,8
  625.     inc   edx
  626.     out   dx,al
  627.     shr   eax,8
  628.     inc   edx
  629.     and   al,1+2+4+8
  630.     add   al,bl
  631.     add   al,128+64+32
  632.     out   dx,al
  633.  
  634.     inc   edx
  635.     mov   al,20h
  636.     out   dx,al
  637.  
  638.     sti
  639.  
  640.     call  wait_for_sector_buffer
  641.     cmp   [hd_error],0
  642.     jne   hd_lba_error
  643.  
  644.     cli
  645.  
  646.     mov   edi,[esp+0]
  647.     mov   ecx,256
  648.     sub   edx,7
  649.     cld
  650.     rep   insw
  651.  
  652.     sti
  653.  
  654.     xor   eax,eax
  655.     xor   ebx,ebx
  656.  
  657.   LBA_read_ret:
  658.     mov [hd_error],0
  659.     mov   [hd1_status],0
  660.     add   esp,2*4
  661.  
  662.     ret
  663.  
  664.  
  665. expand_pathz:
  666. ; IN:
  667. ;   esi = asciiz path & file
  668. ;   edi = buffer for path & file name
  669. ; OUT:
  670. ;   edi = directory & file : / 11 + / 11 + / 11 - zero terminated
  671. ;   ebx = /file name - zero terminated
  672. ;   esi = pointer after source
  673.  
  674.     push  eax
  675.     push  ecx
  676.     push  edi ;[esp+0]
  677.  
  678.   pathz_start:
  679.     mov   byte [edi],'/'
  680.     inc   edi
  681.     mov   al,32
  682.     mov   ecx,11
  683.     cld
  684.     rep   stosb                 ; clear filename area
  685.     sub   edi,11
  686.     mov   ebx,edi               ; start of dir/file name
  687.  
  688.   pathz_new_char:
  689.     mov   al,[esi]
  690.     inc   esi
  691.     cmp   al,0
  692.     je    pathz_end
  693.  
  694.     cmp   al,'/'
  695.     jne   pathz_not_path
  696.     cmp   edi,ebx               ; skip first '/'
  697.     jz    pathz_new_char
  698.     lea   edi,[ebx+11]          ; start of next directory
  699.     jmp   pathz_start
  700.  
  701.   pathz_not_path:
  702.     cmp   al,'.'
  703.     jne   pathz_not_ext
  704.     lea   edi,[ebx+8]           ; start of extension
  705.     jmp   pathz_new_char
  706.  
  707.   pathz_not_ext:
  708.     cmp   al,'a'
  709.     jb    pathz_not_low
  710.     cmp   al,'z'
  711.     ja    pathz_not_low
  712.     sub   al,0x20               ; char to uppercase
  713.  
  714.   pathz_not_low:
  715.     mov   [edi],al
  716.     inc   edi
  717.     mov   eax,[esp+0]           ; start_of_dest_path
  718.     add   eax,512               ; keep maximum path under 512 bytes
  719.     cmp   edi,eax
  720.     jb    pathz_new_char
  721.  
  722.   pathz_end:
  723.     cmp   ebx,edi               ; if path end with '/'
  724.     jnz   pathz_put_zero        ; go back 1 level
  725.     sub   ebx,12
  726.  
  727.   pathz_put_zero:
  728.     mov   byte [ebx+11],0
  729.     dec   ebx                   ; include '/' char into file name
  730.     pop   edi
  731.     pop   ecx
  732.     pop   eax
  733.     ret
  734.  
  735. ;*******************************************
  736. ;* string to number
  737. ;* input eax - 4 byte string
  738. ;* output eax - number
  739. ;*******************************************
  740. StringToNumber:
  741. ;    ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ
  742. ;    Âõîä:
  743. ;        EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh
  744. ;    Âûõîä:
  745. ;        CF - èíäèêàòîð îøèáîê:
  746. ;            0 - îøèáîê íåò;
  747. ;            1 - îøèáêà
  748. ;        Åñëè CF=0, òî AX - ÷èñëî.
  749.  
  750.     push    bx
  751.     push    cx
  752.     push    dx
  753.     push    edi
  754.     mov   [partition_string],eax
  755.     mov    edi,partition_string
  756.     xor    cx,cx
  757. i1:
  758.     mov    al,[edi]
  759.     cmp    al,32  ;13
  760.     je    i_exit
  761. ;    cmp    al,'0'
  762. ;    jb    err
  763. ;    cmp    al,'9'
  764. ;    ja    err
  765.     sub    al,48
  766.     shl    cx,1
  767.     jc    error
  768.     mov    bx,cx
  769.     shl    cx,1
  770.     jc    error
  771.     shl    cx,1
  772.     jc    error
  773.     add    cx,bx
  774.     jc    error
  775.     cbw
  776.     add    cx,ax
  777.     jc    error
  778. i3:
  779.     inc    edi
  780.     jmp    i1
  781. i_exit:
  782.     mov    ax,cx
  783.     clc
  784. i4:
  785.     movzx  eax,ax
  786.     pop    edi
  787.     pop    dx
  788.     pop    cx
  789.     pop    bx
  790.     ret
  791.  
  792. error:
  793.     stc
  794.     jmp    i4
  795.  
  796. partition_string: dd 0
  797.                   db 32
  798.