Subversion Repositories Kolibri OS

Rev

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