Subversion Repositories Kolibri OS

Rev

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