Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
  4. ;;  Distributed under terms of the GNU General Public License.  ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 8986 $
  9.  
  10. ERROR_SUCCESS        = 0
  11. ERROR_DISK_BASE      = 1
  12. ERROR_UNSUPPORTED_FS = 2
  13. ERROR_UNKNOWN_FS     = 3
  14. ERROR_PARTITION      = 4
  15. ERROR_FILE_NOT_FOUND = 5
  16. ERROR_END_OF_FILE    = 6
  17. ERROR_MEMORY_POINTER = 7
  18. ERROR_DISK_FULL      = 8
  19. ERROR_FS_FAIL        = 9
  20. ERROR_ACCESS_DENIED  = 10
  21. ERROR_DEVICE         = 11
  22. ERROR_OUT_OF_MEMORY  = 12
  23.  
  24. maxPathLength = 1000h
  25.  
  26. image_of_eax EQU esp+32
  27. image_of_ebx EQU esp+20
  28.  
  29. ; ; System function 70 security check
  30. ; align 4
  31. ; proc file_system_is_operation_safe stdcall, inf_struct_ptr: dword
  32. ; ; in:
  33. ; ;      inf_struct_ptr = pointer to information structure was given to sysfn70
  34. ; ; out: ZF = 1 if operation is safe
  35. ; ;      ZF = 0 if operation can cause kernel crash
  36. ;         push    ebx ecx edx
  37. ;         xor     ecx, ecx ; ecx - length of target buffer
  38.  
  39. ;         mov     ebx, [inf_struct_ptr]
  40. ;         mov     edx, [ebx + 16] ; base of target buffer
  41.  
  42. ;         cmp     dword [ebx], 0 ; if 70.0
  43. ;         jnz     .case1
  44. ;         mov     ecx, dword [ebx + 12]
  45. ;         jmp     .end_switch
  46.  
  47. ; .case1:
  48. ;         cmp     dword [ebx], 1 ; if 70.1
  49. ;         jnz     .case2_3
  50. ;         ;mov     ecx, 32
  51. ;         cmp     dword [ebx + 8], 1 ; check encoding
  52. ;         jbe     .case1_304 ; if encdoing <= 1 i.e cpp866
  53. ;         mov     ecx, 560 ; if unicode then bdvk block len is 560 bytes
  54. ;         jmp     .case1_end
  55. ; .case1_304:
  56. ;         mov     ecx, 304 ; if cp866 then bdvk block len is 304 bytes
  57. ; .case1_end:
  58. ;         imul    ecx, dword [ebx + 12] ; multiply bdvk length by their count
  59. ;         add     ecx, 32 ; add result header len
  60. ;         jmp     .end_switch
  61.  
  62. ; .case2_3:
  63. ;         cmp     dword [ebx], 3
  64. ;         ja      .case5 ; if subfn > 3
  65. ;         mov     ecx, dword [ebx + 12]
  66. ;         jmp     .end_switch
  67.  
  68. ; .case5:
  69. ;         cmp     dword [ebx], 5
  70. ;         jnz     .case6
  71. ;         mov     ecx, 40
  72. ;         jmp     .end_switch
  73.  
  74. ; .case6:
  75. ;         cmp     dword [ebx], 6
  76. ;         jnz     .switch_none
  77. ;         mov     ecx, 32
  78. ;         jmp     .end_switch
  79.  
  80. ; .switch_none:
  81. ;         mov     ecx, 1
  82. ;         test    ecx, ecx
  83. ;         jmp     .ret
  84.        
  85. ; .end_switch:
  86. ;         ;;
  87. ;         stdcall is_region_userspace, edx, ecx
  88. ; .ret:
  89. ;         pop     edx ecx ebx
  90. ;         ret
  91. ; endp
  92.  
  93. ; syscall_syscall_fs_diff_encodings: ; with user pointer correctness checking
  94. ; ; in: ebx -> f.80 parameter structure
  95. ;         stdcall file_system_is_operation_safe, ebx
  96. ;         jnz     @f
  97.  
  98. ;         DEBUGF  1, "sysfn80 addr error\n"
  99. ;         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
  100. ;         ret
  101. ; @@:
  102. ;         jmp     syscall_fs_diff_encodings
  103.  
  104. ; temporarily commented out cause acpi driver (drivers/devman) uses sysfn70 via 0x40
  105. ; so because drivers it kernel space, pointer checking fails
  106. ; TODO solution: add filesystem functions without pointer checking to kernel exports
  107. ; and make the driver use them, not int 0x40
  108. ; syscall_syscall_fs_diff_encodings commented out for the same reason
  109. ; syscall_file_system_lfn: ; with user pointer correctness checking
  110. ; ; in: ebx -> f.70 parameter structure
  111. ;         stdcall file_system_is_operation_safe, ebx
  112. ;         jnz     @f
  113.  
  114. ;         DEBUGF  1, "sysfn70 addr error\n"
  115. ;         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
  116. ;         ret
  117. ; @@:
  118. ;         jmp     syscall_file_system_lfn
  119.  
  120.  
  121. ; System function 70
  122.  
  123. syscall_file_system_lfn_protected:
  124.         pushad
  125.         call    protect_from_terminate
  126.         call    syscall_file_system_lfn
  127.         call    unprotect_from_terminate
  128.         popad
  129.         mov     [image_of_eax], eax
  130.         mov     [image_of_ebx], ebx
  131.         ret
  132.  
  133. syscall_fs_diff_encodings:
  134. ; in: ebx -> f.80 parameter structure
  135.         mov     edi, [ebx+20]
  136.         mov     esi, [ebx+24]
  137.         jmp     @f
  138.  
  139. syscall_file_system_lfn:
  140. ; in: ebx -> f.70 parameter structure
  141.         xor     edi, edi
  142.         lea     esi, [ebx+20]
  143.         cmp     byte [esi], 0
  144.         jnz     @f
  145.         mov     esi, [ebx+21]
  146. @@:
  147.         cmp     word [esi], '/'
  148.         jnz     @f
  149.         cmp     edi, 2
  150.         jnz     .rootdir
  151.         cmp     dword[esi], '/'
  152.         jz      .rootdir
  153. @@:
  154.         stdcall kernel_alloc, maxPathLength
  155.         push    eax ebx
  156.         xchg    eax, edi
  157.         call    getFullPath
  158.         pop     ebx ebp
  159.         test    eax, eax
  160.         jz      .notfound
  161.         cmp     dword[ebx], 7   ; start application
  162.         jnz     @f
  163.         mov     edx, [ebx+4]
  164.         mov     ecx, [ebx+8]
  165.         mov     ebx, ebp
  166.         call    fs_execute
  167.         mov     [image_of_eax], eax
  168.         ret
  169.  
  170. @@:
  171.         lea     esi, [ebp+2]
  172.         mov     ax, [esi]
  173.         or      ax, 2020h
  174.         cmp     ax, 'cd'
  175.         jz      .CD
  176.         call    dyndisk_handler ; not returns if success
  177. .notfound:
  178.         stdcall kernel_free, ebp
  179.         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
  180.         ret
  181.  
  182. .CD:
  183.         add     esi, 2
  184.         xor     eax, eax
  185.         lodsb       ; disk number
  186.         sub     eax, '0'
  187.         cmp     eax, 10
  188.         jnc     .notfound
  189.         mov     edi, eax
  190.         lodsb
  191.         test    eax, eax
  192.         jz      .maindir
  193.         cmp     al, '/'
  194.         jnz     .notfound
  195.         lodsb       ; partition number
  196.         test    eax, eax
  197.         jz      .maindir
  198.         cmp     al, '1'
  199.         jnz     .notfound
  200.         cmp     byte [esi], '/'
  201.         jnz     @f
  202.         inc     esi
  203. @@:
  204.         call    reserve_cd
  205.         mov     eax, edi
  206.         bt      eax, 0
  207.         setc    [DiskNumber]
  208.         bt      eax, 1
  209.         setc    [ChannelNumber]
  210.         inc     [ChannelNumber]
  211.         inc     eax
  212.         mov     [cdpos], eax
  213.         call    reserve_cd_channel
  214.         mov     eax, edi
  215.         not     eax
  216.         and     eax, 3
  217.         shl     eax, 1
  218.         inc     eax
  219.         shr     edi, 2
  220.         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
  221.         bt      [edi*5+DRIVE_DATA+1], ax
  222.         jnc     @f
  223.         mov     ecx, [ebx+12]
  224.         mov     edx, [ebx+16]
  225.         mov     eax, [ebx]
  226.         mov     dword[image_of_eax], ERROR_UNSUPPORTED_FS
  227.         cmp     eax, fs_NumCdServices
  228.         jae     @f
  229.         add     ebx, 4
  230.         push    ebp
  231.         call    dword[fs_CdServices + eax*4]
  232.         pop     ebp
  233.         mov     [image_of_eax], eax
  234.         mov     [image_of_ebx], ebx
  235. @@:
  236.         call    free_cd_channel
  237.         and     [cd_status], 0
  238.         stdcall kernel_free, ebp
  239.         ret
  240.  
  241. .nextCD:
  242.         test    eax, eax    ; partition number
  243.         jnz     @f
  244.         inc     eax     ; /cdX/1
  245.         ret
  246.  
  247. @@:
  248.         stc
  249.         ret
  250.  
  251. .maindir:   ; list partitions
  252.         mov     esi, .nextCD
  253.         xor     ecx, ecx
  254. .maindir_noesi:     ; backjump from dyndisk_handler
  255.         push    ebp
  256.         mov     ebp, ecx
  257.         call    kernel_free
  258.         mov     edi, [ebx+16]   ; buffer
  259.         cmp     byte [ebx], 5
  260.         jz      .deviceInfo
  261.         cmp     byte [ebx], 1   ; read folder?
  262.         jnz     .access_denied
  263.         push    ebp
  264.         pushd   [ebx+4]         ; first block
  265.         mov     ebp, [ebx+12]   ; the number of blocks to read
  266.         mov     ebx, [ebx+8]    ; flags
  267.         mov     ecx, 32/4
  268.         mov     edx, edi
  269.         xor     eax, eax
  270.         rep stosd
  271.         mov     byte [edx], 1   ; version
  272. .maindir_loop:
  273.         call    esi
  274.         jc      .maindir_done
  275.         inc     dword[edx+8]
  276.         dec     dword[esp]
  277.         jns     .maindir_loop
  278.         dec     ebp
  279.         js      .maindir_loop
  280.         inc     dword[edx+4]
  281.         mov     dword[edi], 16      ; attributes: folder
  282.         mov     dword[edi+4], ebx   ; name encoding
  283.         push    eax
  284.         mov     ecx, 32/4
  285.         add     edi, 8
  286.         xor     eax, eax
  287.         rep stosd
  288.         pop     eax
  289.         push    eax edx edi
  290. ; convert number in eax to decimal string
  291.         push    -'0'
  292.         mov     ecx, 10
  293. @@:
  294.         xor     edx, edx
  295.         div     ecx
  296.         push    edx
  297.         test    eax, eax
  298.         jnz     @b
  299.         cmp     ebx, 2
  300.         jz      .uni
  301. @@:
  302.         pop     eax
  303.         add     eax, '0'
  304.         stosb
  305.         test    eax, eax
  306.         jnz     @b
  307.         pop     edi edx eax
  308.         cmp     ebx, 3
  309.         jz      @f
  310.         add     edi, 264
  311.         jmp     .maindir_loop
  312.  
  313. .uni:
  314.         pop     eax
  315.         add     eax, '0'
  316.         stosw
  317.         test    eax, eax
  318.         jnz     .uni
  319.         pop     edi edx eax
  320. @@:
  321.         add     edi, 520
  322.         jmp     .maindir_loop
  323.  
  324. .maindir_done:
  325.         pop     eax eax
  326.         mov     ebx, [edx+4]
  327.         xor     eax, eax
  328.         dec     ebp
  329.         js      @f
  330.         mov     al, ERROR_END_OF_FILE
  331. @@:
  332.         mov     [image_of_eax], eax
  333.         mov     [image_of_ebx], ebx
  334.         ret
  335.  
  336. .access_denied:
  337.         mov     dword[image_of_eax], ERROR_ACCESS_DENIED
  338.         ret
  339.  
  340. .deviceInfo:
  341.         test    ebp, ebp
  342.         jz      @f
  343.         mov     eax, dword[ebp+DISK.MediaInfo.Capacity]
  344.         mov     edx, dword[ebp+DISK.MediaInfo.Capacity+4]
  345.         shld    edx, eax, 9
  346.         shl     eax, 9
  347.         mov     [edi+36], edx
  348.         mov     [edi+32], eax
  349. @@:
  350.         and     dword[image_of_eax], 0
  351.         ret
  352.  
  353. .rootdir:   ; / - virtual root folder
  354.         cmp     byte [ebx], 5
  355.         jz      @b
  356.         cmp     byte [ebx], 1   ; read folder?
  357.         jnz     .access_denied
  358.         mov     ebp, [ebx+12]   ; number of blocks
  359.         mov     edx, [ebx+16]   ; return area
  360.         push    dword[ebx+4]    ; first block
  361.         mov     ebx, [ebx+8]    ; flags
  362.         mov     ecx, 32/4
  363.         mov     edi, edx
  364.         xor     eax, eax
  365.         rep stosd
  366.         mov     byte [edx], 1   ; version
  367.         sub     esp, 16
  368. .rootdir_loop:
  369.         push    edi
  370.         lea     edi, [esp+4]
  371.         call    dyndisk_enum_root
  372.         pop     edi
  373.         test    eax, eax
  374.         jz      .rootdirCD
  375.         inc     dword[edx+8]
  376.         dec     dword[esp+16]
  377.         jns     .rootdir_loop
  378.         dec     ebp
  379.         js      .rootdir_loop
  380.         inc     dword[edx+4]
  381.         mov     dword[edi], 16      ; attributes: folder
  382.         mov     dword[edi+4], ebx   ; name encoding
  383.         push    eax
  384.         mov     ecx, 32/4
  385.         add     edi, 8
  386.         xor     eax, eax
  387.         rep stosd
  388.         push    edi
  389.         lea     esi, [esp+8]
  390.         cmp     ebx, 2
  391.         jz      .uni2
  392. @@:
  393.         lodsb
  394.         stosb
  395.         test    eax, eax
  396.         jnz     @b
  397.         pop     edi eax
  398.         cmp     ebx, 3
  399.         jz      @f
  400.         add     edi, 264
  401.         jmp     .rootdir_loop
  402.  
  403. .uni2:
  404.         lodsb
  405.         stosw
  406.         test    eax, eax
  407.         jnz     .uni2
  408.         pop     edi eax
  409. @@:
  410.         add     edi, 520
  411.         jmp     .rootdir_loop
  412.  
  413. .rootdirCD:
  414.         add     esp, 16
  415.         or      esi, -1
  416. .rootdirCD_loop:
  417.         inc     esi
  418.         cmp     esi, 10
  419.         jnc     .rootdir_done
  420.         mov     eax, esi
  421.         not     eax
  422.         and     eax, 3
  423.         shl     eax, 1
  424.         inc     eax
  425.         mov     ecx, esi
  426.         shr     ecx, 2
  427.         bt      [ecx*5+DRIVE_DATA+1], ax
  428.         jnc     .rootdirCD_loop
  429.         inc     dword[edx+8]
  430.         dec     dword[esp]
  431.         jns     .rootdirCD_loop
  432.         dec     ebp
  433.         js      .rootdirCD_loop
  434.         inc     dword[edx+4]
  435.         mov     dword[edi], 16      ; attributes: folder
  436.         mov     dword[edi+4], ebx   ; name encoding
  437.         mov     ecx, 32/4
  438.         add     edi, 8
  439.         xor     eax, eax
  440.         rep stosd
  441.         mov     eax, esi
  442.         add     eax, '0'
  443.         cmp     ebx, 1
  444.         jz      @f
  445.         mov     word [edi], 'cd'
  446.         mov     [edi+2], ax
  447.         add     edi, 264
  448.         jmp     .rootdirCD_loop
  449.  
  450. @@:
  451.         mov     dword[edi], 640063h
  452.         mov     [edi+4], eax
  453.         add     edi, 520
  454.         jmp     .rootdirCD_loop
  455.  
  456. .rootdir_done:
  457.         pop     eax
  458.         mov     ebx, [edx+4]
  459.         xor     eax, eax
  460.         dec     ebp
  461.         js      @f
  462.         mov     al, ERROR_END_OF_FILE
  463. @@:
  464.         mov     [image_of_eax], eax
  465.         mov     [image_of_ebx], ebx
  466.         ret
  467.  
  468. ;-----------------------------------------------------------------------------
  469. process_replace_file_name:
  470. ; in: [esi] = virtual path
  471. ; out: [esi]+[ebp] = physical path
  472.         xor     edi, edi
  473.         xor     ebp, ebp
  474. .loop:
  475.         cmp     edi, [full_file_name_table.size]
  476.         jae     .notfound
  477.         push    esi edi
  478.         shl     edi, 7
  479.         add     edi, [full_file_name_table]
  480. @@:
  481.         cmp     byte [edi], 0
  482.         jz      .dest_done
  483.         lodsb
  484.         test    al, al
  485.         jz      .cont
  486.         scasb
  487.         jz      @b
  488.         or      al, 20h
  489.         cmp     [edi-1], al
  490.         jz      @b
  491. .cont:
  492.         pop     edi esi
  493.         inc     edi
  494.         jmp     .loop
  495.  
  496. .dest_done:
  497.         cmp     byte [esi], 0
  498.         jz      .found
  499.         cmp     byte [esi], '/'
  500.         jnz     .cont
  501. .found:
  502.         pop     edi eax
  503.         shl     edi, 7
  504.         add     edi, [full_file_name_table]
  505.         mov     ebp, esi
  506.         lea     esi, [edi+64]
  507. .notfound:
  508.         ret
  509.  
  510. ;-----------------------------------------------------------------------------
  511. uglobal
  512. addDirSeal db  ?
  513. endg
  514.  
  515. syscall_current_directory:  ; sysfunction 30
  516.         mov     eax, [current_slot]
  517.         mov     edi, [eax+APPDATA.cur_dir]
  518.         xor     eax, eax
  519.         dec     ebx
  520.         jz      .set
  521.         dec     ebx
  522.         jz      .get
  523.         dec     ebx
  524.         jz      .mount_additional_directory
  525.         mov     eax, edx
  526.         dec     ebx
  527.         jz      .set
  528.         mov     eax, esi
  529.         dec     ebx
  530.         jz      .get
  531. @@:
  532.         ret
  533.  
  534. .mount_additional_directory:
  535. ; in: ecx -> dir name+dir path (128)
  536.         mov     al, 1
  537.         xchg    [addDirSeal], al
  538.         test    al, al
  539.         jnz     @b
  540.         mov     esi, ecx
  541.         mov     edi, sysdir_name1
  542.         mov     ecx, 64
  543.         rep movsb   ; copying fake directory name
  544.         mov     byte [edi-1], 0
  545.         mov     cl, 63
  546.         call    cp866toUTF8_string
  547.         mov     byte [edi], 0
  548.         mov     [full_file_name_table.size], 2
  549.         ret
  550.  
  551. .get:
  552. ; in: ecx -> buffer, edx = length, eax = encoding
  553.         stdcall is_region_userspace, ecx, edx
  554.         jnz     @f
  555.  
  556.         ; if illegal buffer given
  557.         xor     edx, edx
  558.         jmp     .ret
  559. @@:
  560.  
  561.         mov     esi, edi
  562.         inc     esi
  563.         mov     edi, ecx
  564.         cmp     edx, maxPathLength
  565.         jc      @f
  566.         mov     edx, maxPathLength
  567. @@:
  568.         mov     ecx, edx
  569.         jecxz   .ret
  570.         cmp     eax, 2
  571.         jz      .get16
  572.         cmp     eax, 3
  573.         jz      .get8
  574. @@:
  575.         dec     ecx
  576.         js      @f
  577.         call    utf8to16
  578.         call    uni2ansi_char
  579.         stosb
  580.         test    al, al
  581.         jnz     @b
  582.         sub     edx, ecx
  583. @@:
  584.         mov     byte [edi-1], 0
  585. .ret:
  586.         mov     [esp+32], edx
  587.         ret
  588.  
  589. .get8:
  590.         push    edi
  591.         mov     edi, esi
  592.         xor     eax, eax
  593.         repnz scasb
  594.         sub     edx, ecx
  595.         mov     ecx, edx
  596.         pop     edi
  597.         rep movsb
  598.         jmp     @b
  599.  
  600. .get16:
  601.         shr     ecx, 1
  602.         shr     edx, 1
  603. @@:
  604.         dec     ecx
  605.         js      @f
  606.         call    utf8to16
  607.         stosw
  608.         test    ax, ax
  609.         jnz     @b
  610.         sub     edx, ecx
  611. @@:
  612.         shl     edx, 1
  613.         mov     word [edi-2], 0
  614.         jmp     .ret
  615.  
  616. .set:
  617.         mov     esi, ecx
  618. getFullPath:
  619. ; in: esi -> file path, eax = string encoding, edi -> destination
  620. ; out: UTF-8 string (with marker), eax = length, 0 -> error
  621.         test    eax, eax
  622.         jnz     @f
  623.         cmp     byte [esi], 4
  624.         jnc     @f
  625.         cmp     byte [esi], 0
  626.         jz      @f
  627.         lodsb
  628. @@:
  629.         cmp     byte [esi], '/'
  630.         jnz     .relative
  631.         cmp     eax, 2
  632.         jnz     @f
  633.         cmp     word [esi], '/'
  634.         jnz     .relative
  635.         inc     esi
  636.         inc     esi
  637.         jmp     .start
  638.  
  639. @@:
  640.         inc     esi
  641.         cmp     byte [esi], 4
  642.         jnc     .start
  643.         lodsb
  644.         cmp     byte [esi], '/'
  645.         jnz     .start
  646.         inc     esi
  647. .start:
  648.         push    eax edi
  649.         call    process_replace_file_name
  650.         mov     edi, [esp]
  651.         mov     ecx, maxPathLength
  652.         mov     al, 3
  653.         mov     ah, '/'
  654.         stosw
  655.         sub     ecx, 2
  656.         test    ebp, ebp
  657.         jz      .absolute
  658. @@:
  659.         lodsb
  660.         stosb
  661.         dec     ecx
  662.         test    al, al
  663.         jnz     @b
  664.         mov     esi, ebp
  665.         dec     edi
  666. .absolute:
  667.         cmp     byte [esp+4], 2
  668.         jz      .utf16
  669.         cmp     byte [esp+4], 3
  670.         jz      .utf8
  671.         call    cp866toUTF8_string
  672.         jns     .end
  673.         jmp     .fail
  674.  
  675. .utf8:
  676.         dec     ecx
  677.         js      .fail
  678.         lodsb
  679.         stosb
  680.         test    al, al
  681.         jz      .end
  682.         jmp     .utf8
  683.  
  684. .utf16:
  685.         call    UTF16to8_string
  686.         jns     .end
  687. .fail:
  688.         mov     byte [edi], 0
  689.         pop     eax eax
  690.         xor     eax, eax
  691.         ret
  692.  
  693. .relative:
  694.         push    eax edi
  695.         mov     ebx, esi
  696.         mov     edi, [current_slot]
  697.         mov     edi, [edi+APPDATA.cur_dir]
  698.         mov     edx, edi
  699.         mov     ecx, maxPathLength
  700.         xor     eax, eax
  701.         repnz scasb
  702.         mov     esi, edi
  703.         mov     edi, [esp]
  704.         jecxz   .fail
  705.         cmp     byte [ebx], 0
  706.         jz      .set_ok
  707.         dec     esi
  708.         cmp     edx, edi    ; is destination equal to cur_dir?
  709.         mov     edi, esi
  710.         jz      @f
  711.         mov     edi, [esp]
  712.         mov     ecx, esi
  713.         sub     ecx, edx
  714.         mov     esi, edx
  715.         mov     edx, edi
  716.         rep movsb
  717. @@:
  718.         mov     byte [edi], '/'
  719.         inc     edi
  720.         mov     esi, ebx
  721.         mov     ecx, edx
  722.         add     ecx, maxPathLength
  723.         sub     ecx, edi
  724.         jmp     .absolute
  725.  
  726. .set_ok:
  727.         cmp     edx, edi    ; is destination equal to cur_dir?
  728.         jz      @f
  729.         mov     ecx, esi
  730.         sub     ecx, edx
  731.         mov     esi, edx
  732.         rep movsb
  733. @@:
  734.         pop     eax
  735.         sub     edi, eax
  736.         pop     eax
  737.         mov     eax, edi
  738.         ret
  739.  
  740. .end:
  741.         or      ecx, -1
  742.         mov     edi, [esp]
  743.         xor     eax, eax
  744.         push    edi
  745.         repnz scasb
  746.         not     ecx
  747.         pop     edi
  748. .parse:
  749.         mov     al, '/'
  750.         repnz scasb
  751.         jecxz   @b
  752.         cmp     byte [edi], '.'
  753.         jnz     .parse
  754.         mov     esi, edi
  755. @@:
  756.         lodsw
  757.         sub     ecx, 2
  758.         cmp     ax, './'
  759.         jz      @b
  760.         cmp     ax, '..'
  761.         jnz     @f
  762.         cmp     byte [esi], '/'
  763.         jnz     @f
  764.         mov     edx, ecx
  765.         mov     ecx, edi
  766.         sub     ecx, [esp]
  767.         sub     ecx, 2
  768.         jc      .fail
  769.         sub     edi, 2
  770.         lodsb
  771.         dec     edx
  772.         std
  773.         repnz scasb
  774.         cld
  775.         add     edi, 2
  776.         mov     ecx, edx
  777.         jmp     @b
  778.  
  779. @@:
  780.         sub     esi, 2
  781.         add     ecx, 2
  782.         cmp     esi, edi
  783.         jz      .parse
  784.         push    edi ecx
  785.         rep movsb
  786.         pop     ecx edi
  787.         jmp     .parse
  788.  
  789. include "parse_fn.inc"
  790. include "fs_common.inc"
  791. include "iso9660.inc"   ; read for CD filesystem
  792. include "fat.inc"
  793. include "ntfs.inc"
  794. include "ext.inc"
  795. include "xfs.asm"
  796.