Subversion Repositories Kolibri OS

Rev

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