Subversion Repositories Kolibri OS

Rev

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