Subversion Repositories Kolibri OS

Rev

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

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