Subversion Repositories Kolibri OS

Rev

Rev 6333 | Rev 6464 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 6338 $
  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_FAT_TABLE      = 9 ;deprecated
  20. ERROR_FS_FAIL        = 9
  21. ERROR_ACCESS_DENIED  = 10
  22. ERROR_DEVICE         = 11
  23. ERROR_OUT_OF_MEMORY  = 12
  24.  
  25. image_of_eax EQU esp+32
  26. image_of_ebx EQU esp+20
  27.  
  28. ; System function 70 - files with long names (LFN)
  29. ; diamond, 2006
  30.  
  31. iglobal
  32. ; in this table names must be in lowercase
  33. rootdirs:
  34. ;**********************************************
  35.         db      3,'cd0'
  36.         dd      fs_OnCd0
  37.         dd      fs_NextCd
  38.         db      3,'cd1'
  39.         dd      fs_OnCd1
  40.         dd      fs_NextCd
  41.         db      3,'cd2'
  42.         dd      fs_OnCd2
  43.         dd      fs_NextCd
  44.         db      3,'cd3'
  45.         dd      fs_OnCd3
  46.         dd      fs_NextCd
  47.         db      3,'cd4'
  48.         dd      fs_OnCd4
  49.         dd      fs_NextCd
  50.         db      3,'cd5'
  51.         dd      fs_OnCd5
  52.         dd      fs_NextCd
  53.         db      3,'cd6'
  54.         dd      fs_OnCd6
  55.         dd      fs_NextCd
  56.         db      3,'cd7'
  57.         dd      fs_OnCd7
  58.         dd      fs_NextCd
  59.         db      3,'cd8'
  60.         dd      fs_OnCd8
  61.         dd      fs_NextCd
  62.         db      3,'cd9'
  63.         dd      fs_OnCd9
  64.         dd      fs_NextCd
  65.         db      4,'cd10'
  66.         dd      fs_OnCd10
  67.         dd      fs_NextCd
  68.         db      4,'cd11'
  69.         dd      fs_OnCd11
  70.         dd      fs_NextCd
  71. ;***********************************************
  72.         db      0
  73.  
  74.  
  75. virtual_root_query:
  76. ;**********************************************
  77.         dd      fs_HasCd0
  78.         db      'cd0',0
  79.         dd      fs_HasCd1
  80.         db      'cd1',0
  81.         dd      fs_HasCd2
  82.         db      'cd2',0
  83.         dd      fs_HasCd3
  84.         db      'cd3',0
  85.         dd      fs_HasCd4
  86.         db      'cd4',0
  87.         dd      fs_HasCd5
  88.         db      'cd5',0
  89.         dd      fs_HasCd6
  90.         db      'cd6',0
  91.         dd      fs_HasCd7
  92.         db      'cd7',0
  93.         dd      fs_HasCd8
  94.         db      'cd8',0
  95.         dd      fs_HasCd9
  96.         db      'cd9',0
  97.         dd      fs_HasCd10
  98.         db      'cd10',0
  99.         dd      fs_HasCd11
  100.         db      'cd11',0
  101. ;**********************************************
  102.         dd      0
  103. endg
  104.  
  105. file_system_lfn_protected:
  106.         pushad
  107.         call    protect_from_terminate
  108.         call    file_system_lfn
  109.         call    unprotect_from_terminate
  110.         popad
  111.         mov     [image_of_eax], eax
  112.         mov     [image_of_ebx], ebx
  113.         ret
  114.  
  115. file_system_lfn:
  116. ; in: ebx->fileinfo block
  117. ; operation codes:
  118. ; 0 : read file
  119. ; 1 : read folder
  120. ; 2 : create/rewrite file
  121. ; 3 : write/append to file
  122. ; 4 : set end of file
  123. ; 5 : get file/directory attributes structure
  124. ; 6 : set file/directory attributes structure
  125. ; 7 : start application
  126. ; 8 : delete file
  127. ; 9 : create directory
  128.  
  129. ; parse file name
  130.         lea     esi, [ebx+20]
  131.         lodsb
  132.         test    al, al
  133.         jnz     @f
  134.         mov     esi, [esi]
  135.         lodsb
  136. @@:
  137.         lea     ebp, [esi-1]
  138. if 0
  139.         cmp     [ebx], dword 0
  140.         jne     @F
  141.         DEBUGF 1,'read file %s\n',ebp
  142.         jmp     .1
  143. @@:
  144.         cmp     [ebx], dword 5
  145.         jne     @F
  146.         DEBUGF 1,'get file attributes %s\n',ebp
  147. @@:
  148. .1:
  149. end if
  150.  
  151.         cmp     dword [ebx], 7
  152.         jne     @F
  153.         mov     edx, [ebx+4]
  154.         mov     ebx, [ebx+8]
  155.         call    fs_execute; ebp, ebx, edx
  156.         mov     [image_of_eax], eax
  157.         ret
  158. @@:
  159.         cmp     al, '/'
  160.         jz      .notcurdir
  161.         dec     esi
  162.         mov     ebp, esi
  163.         test    al, al
  164.         jnz     @f
  165.         xor     ebp, ebp
  166. @@:
  167.         mov     esi, [current_slot]
  168.         mov     esi, [esi+APPDATA.cur_dir]
  169.         jmp     .parse_normal
  170. .notcurdir:
  171.         cmp     byte [esi], 0
  172.         jz      .rootdir
  173.         call    process_replace_file_name
  174. .parse_normal:
  175.         mov     edi, rootdirs-8
  176.         xor     ecx, ecx
  177.         push    esi
  178. .scan1:
  179.         pop     esi
  180.         add     edi, ecx
  181.         scasd
  182.         scasd
  183.         mov     cl, byte [edi]
  184.         test    cl, cl
  185.         jz      .notfound_try
  186.         inc     edi
  187.         push    esi
  188. @@:
  189.         lodsb
  190.         or      al, 20h
  191.         scasb
  192.         loopz   @b
  193.         jnz     .scan1
  194.         lodsb
  195.         cmp     al, '/'
  196.         jz      .found1
  197.         test    al, al
  198.         jnz     .scan1
  199.         pop     eax
  200. ; directory /xxx
  201. .maindir:
  202.         mov     esi, [edi+4]
  203. .maindir_noesi:
  204.         cmp     dword [ebx], 1
  205.         jnz     .access_denied
  206.         xor     eax, eax
  207.         mov     ebp, [ebx+12] ;the number of blocks to read
  208.         mov     edx, [ebx+16] ;where to write the result
  209.     ;    add     edx, std_application_base_address
  210.         push    dword [ebx+4]   ; first block
  211.         mov     ebx, [ebx+8]    ; flags
  212. ; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
  213.         mov     edi, edx
  214.         push    ecx
  215.         mov     ecx, 32/4
  216.         rep stosd
  217.         pop     ecx
  218.         mov     byte [edx], 1   ; version
  219. .maindir_loop:
  220.         call    esi
  221.         jc      .maindir_done
  222.         inc     dword [edx+8]
  223.         dec     dword [esp]
  224.         jns     .maindir_loop
  225.         dec     ebp
  226.         js      .maindir_loop
  227.         inc     dword [edx+4]
  228.         mov     dword [edi], 0x10       ; attributes: folder
  229.         mov     dword [edi+4], 1        ; name type: UNICODE
  230.         push    eax
  231.         xor     eax, eax
  232.         add     edi, 8
  233.         push    ecx
  234.         mov     ecx, 40/4-2
  235.         rep stosd
  236.         pop     ecx
  237.         pop     eax
  238.         push    eax edx
  239. ; convert number in eax to decimal UNICODE string
  240.         push    edi
  241.         push    ecx
  242.         push    -'0'
  243.         mov     ecx, 10
  244. @@:
  245.         xor     edx, edx
  246.         div     ecx
  247.         push    edx
  248.         test    eax, eax
  249.         jnz     @b
  250. @@:
  251.         pop     eax
  252.         add     al, '0'
  253.         stosb
  254.         test    bl, 1           ; UNICODE name?
  255.         jz      .ansi2
  256.         mov     byte [edi], 0
  257.         inc     edi
  258. .ansi2:
  259.         test    al, al
  260.         jnz     @b
  261.         mov     byte [edi-1], 0
  262.         pop     ecx
  263.         pop     edi
  264. ; UNICODE name length is 520 bytes, ANSI - 264
  265.         add     edi, 520
  266.         test    bl, 1
  267.         jnz     @f
  268.         sub     edi, 520-264
  269. @@:
  270.         pop     edx eax
  271.         jmp     .maindir_loop
  272. .maindir_done:
  273.         pop     eax
  274.         mov     ebx, [edx+4]
  275.         xor     eax, eax
  276.         dec     ebp
  277.         js      @f
  278.         mov     al, ERROR_END_OF_FILE
  279. @@:
  280.         mov     [image_of_eax], eax
  281.         mov     [image_of_ebx], ebx
  282.         ret
  283. ; directory /
  284. .rootdir:
  285.         cmp     dword [ebx], 1  ; read folder?
  286.         jz      .readroot
  287. .access_denied:
  288.         mov     dword [image_of_eax], 10      ; access denied
  289.         ret
  290.  
  291. .readroot:
  292. ; virtual root folder - special handler
  293.         mov     ebp, [ebx+12]
  294.         mov     edx, [ebx+16]
  295.     ;    add     edx, std_application_base_address
  296.         push    dword [ebx+4]   ; first block
  297.         mov     ebx, [ebx+8]    ; flags
  298.         xor     eax, eax
  299. ; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
  300.         mov     edi, edx
  301.         mov     ecx, 32/4
  302.         rep stosd
  303.         mov     byte [edx], 1   ; version
  304.         sub     esp, 16
  305. .readroot_ah_loop2:
  306.         push    edi
  307.         lea     edi, [esp+4]
  308.         call    dyndisk_enum_root
  309.         pop     edi
  310.         test    eax, eax
  311.         jz      .readroot_done_dynamic
  312.         inc     dword [edx+8]
  313.         dec     dword [esp+16]
  314.         jns     .readroot_ah_loop2
  315.         dec     ebp
  316.         js      .readroot_ah_loop2
  317.         push    eax
  318.         xor     eax, eax
  319.         inc     dword [edx+4]
  320.         mov     dword [edi], 0x10       ; attributes: folder
  321.         mov     dword [edi+4], ebx
  322.         add     edi, 8
  323.         mov     ecx, 40/4-2
  324.         rep stosd
  325.         push    esi edi
  326.         lea     esi, [esp+12]
  327. @@:
  328.         lodsb
  329.         stosb
  330.         test    bl, 1
  331.         jz      .ansi3
  332.         mov     byte [edi], 0
  333.         inc     edi
  334. .ansi3:
  335.         test    al, al
  336.         jnz     @b
  337.         pop     edi esi eax
  338.         add     edi, 520
  339.         test    bl, 1
  340.         jnz     .readroot_ah_loop2
  341.         sub     edi, 520-264
  342.         jmp     .readroot_ah_loop2
  343. .readroot_done_dynamic:
  344.         add     esp, 16
  345.         mov     esi, virtual_root_query
  346. .readroot_loop:
  347.         cmp     dword [esi], eax
  348.         jz      .readroot_done
  349.         call    dword [esi]
  350.         add     esi, 4
  351.         test    eax, eax
  352.         jnz     @f
  353. .readroot_next:
  354.         or      ecx, -1
  355.         xchg    esi, edi
  356.         repnz scasb
  357.         xchg    esi, edi
  358.         jmp     .readroot_loop
  359. @@:
  360.         xor     eax, eax
  361.         inc     dword [edx+8]
  362.         dec     dword [esp]
  363.         jns     .readroot_next
  364.         dec     ebp
  365.         js      .readroot_next
  366.         inc     dword [edx+4]
  367.         mov     dword [edi], 0x10       ; attributes: folder
  368.         mov     dword [edi+4], ebx      ; name type: UNICODE
  369.         add     edi, 8
  370.         mov     ecx, 40/4-2
  371.         rep stosd
  372.         push    edi
  373. @@:
  374.         lodsb
  375.         stosb
  376.         test    bl, 1
  377.         jz      .ansi
  378.         mov     byte [edi], 0
  379.         inc     edi
  380. .ansi:
  381.         test    eax, eax
  382.         jnz     @b
  383.         pop     edi
  384.         add     edi, 520
  385.         test    bl, 1
  386.         jnz     .readroot_loop
  387.         sub     edi, 520-264
  388.         jmp     .readroot_loop
  389. .readroot_done:
  390.         pop     eax
  391.         mov     ebx, [edx+4]
  392.         xor     eax, eax
  393.         dec     ebp
  394.         js      @f
  395.         mov     al, ERROR_END_OF_FILE
  396. @@:
  397.         mov     [image_of_eax], eax
  398.         mov     [image_of_ebx], ebx
  399.         ret
  400. .notfound_try:
  401.         call    dyndisk_handler
  402. .notfound:
  403.         mov     dword [image_of_eax], ERROR_FILE_NOT_FOUND
  404.         and     dword [image_of_ebx], 0
  405.         ret
  406.  
  407. .notfounda:
  408.         cmp     edi, esp
  409.         jnz     .notfound
  410.         call    dword [edi+4]
  411.         add     esp, 16
  412.         jmp     .notfound
  413.  
  414. .found1:
  415.         pop     eax
  416.         cmp     byte [esi], 0
  417.         jz      .maindir
  418. .found2:
  419. ; read partition number
  420.         xor     ecx, ecx
  421.         xor     eax, eax
  422. @@:
  423.         lodsb
  424.         cmp     al, '/'
  425.         jz      .done1
  426.         test    al, al
  427.         jz      .done1
  428.         sub     al, '0'
  429.         cmp     al, 9
  430.         ja      .notfounda
  431.         lea     ecx, [ecx*5]
  432.         lea     ecx, [ecx*2+eax]
  433.         jmp     @b
  434. .done1:
  435.         jecxz   .notfounda
  436.         test    al, al
  437.         jnz     @f
  438.         dec     esi
  439. @@:
  440.         cmp     byte [esi], 0
  441.         jnz     @f
  442.         test    ebp, ebp
  443.         jz      @f
  444.         mov     esi, ebp
  445.         xor     ebp, ebp
  446. @@:
  447. ; now [edi] contains handler address, ecx - partition number,
  448. ; esi points to ASCIIZ string - rest of name
  449.         jmp     dword [edi]
  450.  
  451. ; handlers for devices
  452. ; in: ecx = 0 => query virtual directory /xxx
  453. ; in: ecx = partition number
  454. ;     esi -> relative (for device) name
  455. ;     ebx -> fileinfo
  456. ;     ebp = 0 or pointer to rest of name from folder addressed by esi
  457. ; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
  458.  
  459. fs_NotImplemented:
  460.         mov     eax, 2
  461.         ret
  462. ;-----------------------------------------------------------------------------
  463. fs_OnCd0:
  464.         call    reserve_cd
  465.         mov     [ChannelNumber], 1
  466.         mov     [DiskNumber], 0
  467.         push    6
  468.         push    1
  469.         jmp     fs_OnCd
  470. ;-----------------------------------------------------------------------------
  471. fs_OnCd1:
  472.         call    reserve_cd
  473.         mov     [ChannelNumber], 1
  474.         mov     [DiskNumber], 1
  475.         push    4
  476.         push    2
  477.         jmp     fs_OnCd
  478. ;-----------------------------------------------------------------------------
  479. fs_OnCd2:
  480.         call    reserve_cd
  481.         mov     [ChannelNumber], 2
  482.         mov     [DiskNumber], 0
  483.         push    2
  484.         push    3
  485.         jmp     fs_OnCd
  486. ;-----------------------------------------------------------------------------
  487. fs_OnCd3:
  488.         call    reserve_cd
  489.         mov     [ChannelNumber], 2
  490.         mov     [DiskNumber], 1
  491.         push    0
  492.         push    4
  493.         jmp     fs_OnCd
  494. ;-----------------------------------------------------------------------------
  495. fs_OnCd4:
  496.         call    reserve_cd
  497.         mov     [ChannelNumber], 1
  498.         mov     [DiskNumber], 0
  499.         push    6
  500.         push    5
  501.         jmp     fs_OnCd
  502. ;-----------------------------------------------------------------------------
  503. fs_OnCd5:
  504.         call    reserve_cd
  505.         mov     [ChannelNumber], 1
  506.         mov     [DiskNumber], 1
  507.         push    4
  508.         push    6
  509.         jmp     fs_OnCd
  510. ;-----------------------------------------------------------------------------
  511. fs_OnCd6:
  512.         call    reserve_cd
  513.         mov     [ChannelNumber], 2
  514.         mov     [DiskNumber], 0
  515.         push    2
  516.         push    7
  517.         jmp     fs_OnCd
  518. ;-----------------------------------------------------------------------------
  519. fs_OnCd7:
  520.         call    reserve_cd
  521.         mov     [ChannelNumber], 2
  522.         mov     [DiskNumber], 1
  523.         push    0
  524.         push    8
  525.         jmp     fs_OnCd
  526. ;-----------------------------------------------------------------------------
  527. fs_OnCd8:
  528.         call    reserve_cd
  529.         mov     [ChannelNumber], 1
  530.         mov     [DiskNumber], 0
  531.         push    6
  532.         push    9
  533.         jmp     fs_OnCd
  534. ;-----------------------------------------------------------------------------
  535. fs_OnCd9:
  536.         call    reserve_cd
  537.         mov     [ChannelNumber], 1
  538.         mov     [DiskNumber], 1
  539.         push    4
  540.         push    10
  541.         jmp     fs_OnCd
  542. ;-----------------------------------------------------------------------------
  543. fs_OnCd10:
  544.         call    reserve_cd
  545.         mov     [ChannelNumber], 2
  546.         mov     [DiskNumber], 0
  547.         push    2
  548.         push    11
  549.         jmp     fs_OnCd
  550. ;-----------------------------------------------------------------------------
  551. fs_OnCd11:
  552.         call    reserve_cd
  553.         mov     [ChannelNumber], 2
  554.         mov     [DiskNumber], 1
  555.         push    0
  556.         push    12
  557. ;-----------------------------------------------------------------------------
  558. fs_OnCd:
  559.         pop     eax
  560.         mov     [cdpos], eax
  561.         call    reserve_cd_channel
  562.         pop     eax
  563.         cmp     ecx, 0x100
  564.         jae     .nf
  565.         push    ecx ebx
  566.         mov     cl, al
  567.  
  568.         push    eax
  569.         mov     eax, [cdpos]
  570.         dec     eax
  571.         shr     eax, 2
  572.         lea     eax, [eax*5]
  573.         mov     bl, [eax+DRIVE_DATA+1]
  574.         pop     eax
  575.  
  576.         shr     bl, cl
  577.         test    bl, 2
  578.         pop     ebx ecx
  579.  
  580.         jnz     @f
  581. .nf:
  582.         call    free_cd_channel
  583.         and     [cd_status], 0
  584.         mov     dword [image_of_eax], 5       ; not found
  585.         ret
  586. @@:
  587.         mov     ecx, [ebx+12]
  588.         mov     edx, [ebx+16]
  589.     ;    add     edx, std_application_base_address
  590.         mov     eax, [ebx]
  591.         cmp     eax, fs_NumCdServices
  592.         jae     .not_impl
  593.         add     ebx, 4
  594.         call    dword [fs_CdServices + eax*4]
  595.         call    free_cd_channel
  596.         and     [cd_status], 0
  597.         mov     [image_of_eax], eax
  598.         mov     [image_of_ebx], ebx
  599.         ret
  600. .not_impl:
  601.         call    free_cd_channel
  602.         and     [cd_status], 0
  603.         mov     dword [image_of_eax], 2       ; not implemented
  604.         ret
  605. ;-----------------------------------------------------------------------------
  606. fs_CdServices:
  607.         dd      fs_CdRead
  608.         dd      fs_CdReadFolder
  609.         dd      fs_NotImplemented
  610.         dd      fs_NotImplemented
  611.         dd      fs_NotImplemented
  612.         dd      fs_CdGetFileInfo
  613.         dd      fs_NotImplemented
  614.         dd      0
  615.         dd      fs_NotImplemented
  616.         dd      fs_NotImplemented
  617. fs_NumCdServices = ($ - fs_CdServices)/4
  618. ;-----------------------------------------------------------------------------
  619. fs_HasCd0:
  620.         test    byte [DRIVE_DATA+1], 10000000b
  621.         setnz   al
  622.         ret
  623. ;--------------------------------------
  624. fs_HasCd1:
  625.         test    byte [DRIVE_DATA+1], 00100000b
  626.         setnz   al
  627.         ret
  628. ;--------------------------------------
  629. fs_HasCd2:
  630.         test    byte [DRIVE_DATA+1], 00001000b
  631.         setnz   al
  632.         ret
  633. ;--------------------------------------
  634. fs_HasCd3:
  635.         test    byte [DRIVE_DATA+1], 00000010b
  636.         setnz   al
  637.         ret
  638. ;--------------------------------------
  639. fs_HasCd4:
  640.         test    byte [DRIVE_DATA+6], 10000000b
  641.         setnz   al
  642.         ret
  643. ;--------------------------------------
  644. fs_HasCd5:
  645.         test    byte [DRIVE_DATA+6], 00100000b
  646.         setnz   al
  647.         ret
  648. ;--------------------------------------
  649. fs_HasCd6:
  650.         test    byte [DRIVE_DATA+6], 00001000b
  651.         setnz   al
  652.         ret
  653. ;--------------------------------------
  654. fs_HasCd7:
  655.         test    byte [DRIVE_DATA+6], 00000010b
  656.         setnz   al
  657.         ret
  658. ;--------------------------------------
  659. fs_HasCd8:
  660.         test    byte [DRIVE_DATA+11], 10000000b
  661.         setnz   al
  662.         ret
  663. ;--------------------------------------
  664. fs_HasCd9:
  665.         test    byte [DRIVE_DATA+11], 00100000b
  666.         setnz   al
  667.         ret
  668. ;--------------------------------------
  669. fs_HasCd10:
  670.         test    byte [DRIVE_DATA+11], 00001000b
  671.         setnz   al
  672.         ret
  673. ;--------------------------------------
  674. fs_HasCd11:
  675.         test    byte [DRIVE_DATA+11], 00000010b
  676.         setnz   al
  677.         ret
  678. ;-----------------------------------------------------------------------------
  679. ;
  680. ; fs_NextXXX functions:
  681. ; in: eax = partition number, from which start to scan
  682. ; out: CF=1 => no more partitions
  683. ;      CF=0 => eax=next partition number
  684. ;
  685. ;-----------------------------------------------------------------------------
  686. fs_NextCd:
  687. ; we always have /cdX/1
  688.         test    eax, eax
  689.         stc
  690.         jnz     @f
  691.         mov     al, 1
  692.         clc
  693. @@:
  694.         ret
  695. ;-----------------------------------------------------------------------------
  696. process_replace_file_name:
  697. ; in
  698. ; esi - path with filename(f.70)
  699. ;
  700. ; out
  701. ; ebp - full filename
  702.         pushfd
  703.         cli
  704.         mov     ebp, [full_file_name_table]
  705.         xor     edi, edi
  706. .loop:
  707.         cmp     edi, [full_file_name_table.size]
  708.         jae     .notfound
  709.         push    esi edi
  710.         shl     edi, 7 ; edi*128
  711.         add     edi, ebp
  712. @@:
  713.         cmp     byte [edi], 0 ; end of dir_name
  714.         jz      .dest_done
  715.         lodsb
  716.         test    al, al
  717.         jz      .cont
  718.         or      al, 20h ; 32 - space char
  719.         scasb
  720.         jz      @b
  721.         jmp     .cont
  722. .dest_done:
  723.         cmp     byte [esi], 0
  724.         jz      .found
  725.         cmp     byte [esi], '/'
  726.         jnz     .cont
  727.         inc     esi
  728.         jmp     .found
  729. .cont:
  730.         pop     edi esi
  731.         inc     edi
  732.         jmp     .loop
  733. .found:
  734.         pop     edi eax
  735.         shl     edi, 7 ; edi*128
  736.         add     edi, ebp
  737.         mov     ebp, esi
  738.         cmp     byte [esi], 0
  739.         lea     esi, [edi+64]
  740.         jnz     .ret
  741. .notfound:
  742.         xor     ebp, ebp
  743. .ret:
  744.         popfd
  745.         ret
  746. ;-----------------------------------------------------------------------------
  747. uglobal
  748. lock_flag_for_f30_3 rb 1
  749. endg
  750.  
  751. sys_current_directory:
  752. ;       mov     esi, [current_slot]
  753. ;       mov     esi, [esi+APPDATA.cur_dir]
  754. ;       mov     edx, esi
  755.  
  756. ;get length string of appdata.cur_dir
  757.         mov     eax, [current_slot]
  758.         mov     edi, [eax+APPDATA.cur_dir]
  759.  
  760.         dec     ebx
  761.         jz      .set
  762.         dec     ebx
  763.         jz      .get
  764.         dec     ebx
  765.         jz      .mount_additional_directory
  766.         ret
  767.  
  768. .mount_additional_directory:
  769. ; sysfunction 30.2: [for app] eax=30,ebx=3,ecx->dir name+dir path (128)
  770. ; for our code: nothing
  771.  
  772. ; check lock of the function
  773.         cmp     [lock_flag_for_f30_3], 1
  774.         je      @f
  775.  
  776.         mov     esi, ecx
  777.         mov     edi, sysdir_name1
  778. ; copying fake directory name
  779.         mov     ecx, 63
  780.         pushfd
  781.         cli
  782.         cld
  783.         rep movsb
  784. ; terminator of name, in case if we get the inlet trash
  785.         inc     esi
  786.         xor     eax, eax
  787.         stosb
  788. ; copying real directory path for mounting
  789.         mov     ecx, 63
  790.         rep movsb
  791. ; terminator of name, in case if we get the inlet trash
  792.         xor     eax, eax
  793.         stosb
  794. ; increase the pointer of inputs for procedure "process_replace_file_name"
  795.         mov     [full_file_name_table.size], 2
  796. ; block the ability to call f.30.3 because for one session is necessary
  797. ; for us only once
  798.         mov     [lock_flag_for_f30_3], 1
  799.         popfd
  800. @@:
  801.         ret
  802.  
  803. .get:
  804. ; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
  805. ; for our code: ebx->buffer,ecx=len
  806. max_cur_dir     equ     0x1000
  807.  
  808.         mov     ebx, edi
  809.  
  810.         push    ecx
  811.         push    edi
  812.  
  813.         xor     eax, eax
  814.         mov     ecx, max_cur_dir
  815.  
  816.         repne scasb             ;find zerro at and string
  817.         jnz     .error          ; no zero in cur_dir: internal error, should not happen
  818.  
  819.         sub     edi, ebx        ;lenght for copy
  820.         inc     edi
  821.         mov     [esp+32+8], edi ;return in eax
  822.  
  823.         cmp     edx, edi
  824.         jbe     @f
  825.         mov     edx, edi
  826. @@:
  827. ;source string
  828.         pop     esi
  829. ;destination string
  830.         pop     edi
  831.         cmp     edx, 1
  832.         jbe     .ret
  833.  
  834.         mov     al, '/'         ;start string with '/'
  835.         stosb
  836.         mov     ecx, edx
  837.         rep movsb               ;copy string
  838. .ret:
  839.         ret
  840.  
  841. .error:
  842.         add     esp, 8
  843.         or      dword [esp+32], -1      ;error not found zerro at string ->[eax+APPDATA.cur_dir]
  844.         ret
  845. .set:
  846. ; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
  847. ; for our code: ebx->string to set
  848. ; use generic resolver with APPDATA.cur_dir as destination
  849.         push    max_cur_dir     ;0x1000
  850.         push    edi     ;destination
  851.         mov     ebx, ecx
  852.         call    get_full_file_name
  853.         ret
  854.  
  855. ; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
  856. ; destroys all registers except ebp,esp
  857. get_full_file_name:
  858.         push    ebp
  859.         mov     esi, [current_slot]
  860.         mov     esi, [esi+APPDATA.cur_dir]
  861.         mov     edx, esi
  862. @@:
  863.         inc     esi
  864.         cmp     byte [esi-1], 0
  865.         jnz     @b
  866.         dec     esi
  867.         cmp     byte [ebx], '/'
  868.         jz      .set_absolute
  869. ; string gives relative path
  870.         mov     edi, [esp+8]    ; destination
  871. .relative:
  872.         cmp     byte [ebx], 0
  873.         jz      .set_ok
  874.         cmp     word [ebx], '.'
  875.         jz      .set_ok
  876.         cmp     word [ebx], './'
  877.         jnz     @f
  878.         add     ebx, 2
  879.         jmp     .relative
  880. @@:
  881.         cmp     word [ebx], '..'
  882.         jnz     .doset_relative
  883.         cmp     byte [ebx+2], 0
  884.         jz      @f
  885.         cmp     byte [ebx+2], '/'
  886.         jnz     .doset_relative
  887. @@:
  888.         dec     esi
  889.         cmp     byte [esi], '/'
  890.         jnz     @b
  891.         add     ebx, 3
  892.         jmp     .relative
  893. .set_ok:
  894.         cmp     edx, edi        ; is destination equal to APPDATA.cur_dir?
  895.         jz      .set_ok.cur_dir
  896.         sub     esi, edx
  897.         cmp     esi, [esp+12]
  898.         jb      .set_ok.copy
  899. .fail:
  900.         mov     byte [edi], 0
  901.         xor     eax, eax        ; fail
  902.         pop     ebp
  903.         ret     8
  904. .set_ok.copy:
  905.         mov     ecx, esi
  906.         mov     esi, edx
  907.         rep movsb
  908.         mov     byte [edi], 0
  909. .ret.ok:
  910.         mov     al, 1   ; ok
  911.         pop     ebp
  912.         ret     8
  913. .set_ok.cur_dir:
  914.         mov     byte [esi], 0
  915.         jmp     .ret.ok
  916. .doset_relative:
  917.         cmp     edx, edi
  918.         jz      .doset_relative.cur_dir
  919.         sub     esi, edx
  920.         cmp     esi, [esp+12]
  921.         jae     .fail
  922.         mov     ecx, esi
  923.         mov     esi, edx
  924.         mov     edx, edi
  925.         rep movsb
  926.         jmp     .doset_relative.copy
  927. .doset_relative.cur_dir:
  928.         mov     edi, esi
  929. .doset_relative.copy:
  930.         add     edx, [esp+12]
  931.         mov     byte [edi], '/'
  932.         inc     edi
  933.         cmp     edi, edx
  934.         jae     .overflow
  935. @@:
  936.         mov     al, [ebx]
  937.         inc     ebx
  938.         stosb
  939.         test    al, al
  940.         jz      .ret.ok
  941.         cmp     edi, edx
  942.         jb      @b
  943. .overflow:
  944.         dec     edi
  945.         jmp     .fail
  946. .set_absolute:
  947.         lea     esi, [ebx+1]
  948.         call    process_replace_file_name
  949.         mov     edi, [esp+8]
  950.         mov     edx, [esp+12]
  951.         add     edx, edi
  952. .set_copy:
  953.         lodsb
  954.         stosb
  955.         test    al, al
  956.         jz      .set_part2
  957. .set_copy_cont:
  958.         cmp     edi, edx
  959.         jb      .set_copy
  960.         jmp     .overflow
  961. .set_part2:
  962.         mov     esi, ebp
  963.         xor     ebp, ebp
  964.         test    esi, esi
  965.         jz      .ret.ok
  966.         mov     byte [edi-1], '/'
  967.         jmp     .set_copy_cont
  968.