Subversion Repositories Kolibri OS

Rev

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