Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 593 $
  9.  
  10.  
  11. image_of_eax EQU esp+36
  12. image_of_ebx EQU esp+24
  13.  
  14. ; System function 70 - files with long names (LFN)
  15. ; diamond, 2006
  16.  
  17. iglobal
  18. ; in this table names must be in lowercase
  19. rootdirs:
  20.         db      2,'rd'
  21.         dd      fs_OnRamdisk
  22.         dd      fs_NextRamdisk
  23.         db      7,'ramdisk'
  24.         dd      fs_OnRamdisk
  25.         dd      fs_NextRamdisk
  26.         db      2,'fd'
  27.         dd      fs_OnFloppy
  28.         dd      fs_NextFloppy
  29.         db      10,'floppydisk'
  30.         dd      fs_OnFloppy
  31.         dd      fs_NextFloppy
  32.         db      3,'hd0'
  33.         dd      fs_OnHd0
  34.         dd      fs_NextHd0
  35.         db      3,'hd1'
  36.         dd      fs_OnHd1
  37.         dd      fs_NextHd1
  38.         db      3,'hd2'
  39.         dd      fs_OnHd2
  40.         dd      fs_NextHd2
  41.         db      3,'hd3'
  42.         dd      fs_OnHd3
  43.         dd      fs_NextHd3
  44. ;**********************************************
  45.         db      3,'cd0'
  46.         dd      fs_OnCd0
  47.         dd      fs_NextCd
  48.         db      3,'cd1'
  49.         dd      fs_OnCd1
  50.         dd      fs_NextCd
  51.         db      3,'cd2'
  52.         dd      fs_OnCd2
  53.         dd      fs_NextCd
  54.         db      3,'cd3'
  55.         dd      fs_OnCd3
  56.         dd      fs_NextCd
  57. ;***********************************************
  58.         db      0
  59.  
  60.  
  61. virtual_root_query:
  62.         dd      fs_HasRamdisk
  63.         db      'rd',0
  64.         dd      fs_HasFloppy
  65.         db      'fd',0
  66.         dd      fs_HasHd0
  67.         db      'hd0',0
  68.         dd      fs_HasHd1
  69.         db      'hd1',0
  70.         dd      fs_HasHd2
  71.         db      'hd2',0
  72.         dd      fs_HasHd3
  73.         db      'hd3',0
  74. ;**********************************************
  75.         dd      fs_HasCd0
  76.         db      'cd0',0
  77.         dd      fs_HasCd1
  78.         db      'cd1',0
  79.         dd      fs_HasCd2
  80.         db      'cd2',0
  81.         dd      fs_HasCd3
  82.         db      'cd3',0
  83. ;**********************************************
  84.         dd      0
  85. endg
  86.  
  87. file_system_lfn:
  88. ; in: eax->fileinfo block
  89. ; operation codes:
  90. ; 0 : read file
  91. ; 1 : read folder
  92. ; 2 : create/rewrite file
  93. ; 3 : write/append to file
  94. ; 4 : set end of file
  95. ; 5 : get file/directory attributes structure
  96. ; 6 : set file/directory attributes structure
  97. ; 7 : start application
  98. ; 8 : delete file
  99. ; 9 : create directory
  100.  
  101. ; parse file name
  102.         xchg    ebx, eax
  103.         lea     esi, [ebx+20]
  104.         lodsb
  105.         test    al, al
  106.         jnz     @f
  107.         mov     esi, [esi]
  108.         lodsb
  109. @@:
  110.         cmp     al, '/'
  111.         jz      .notcurdir
  112.         dec     esi
  113.         mov     ebp, esi
  114.         test    al, al
  115.         jnz     @f
  116.         xor     ebp, ebp
  117. @@:
  118.         mov     esi, [current_slot]
  119.         mov     esi, [esi+APPDATA.cur_dir]
  120.         jmp     .parse_normal
  121. .notcurdir:
  122.         cmp     byte [esi], 0
  123.         jz      .rootdir
  124.         call    process_replace_file_name
  125. .parse_normal:
  126.         cmp dword [ebx], 7
  127.         jne @F
  128.         mov edx, [ebx+4]
  129.         mov ebx, [ebx+8]
  130.         call fs_execute  ; esi+ebp, ebx, edx
  131.         mov [image_of_eax], eax
  132.         ret
  133. @@:
  134.         mov     edi, rootdirs-8
  135.         xor     ecx, ecx
  136.         push    esi
  137. .scan1:
  138.         pop     esi
  139.         add     edi, ecx
  140.         scasd
  141.         scasd
  142.         mov     cl, byte [edi]
  143.         test    cl, cl
  144.         jz      .notfound
  145.         inc     edi
  146.         push    esi
  147. @@:
  148.         lodsb
  149.         or      al, 20h
  150.         scasb
  151.         loopz   @b
  152.         jnz     .scan1
  153.         lodsb
  154.         cmp     al, '/'
  155.         jz      .found1
  156.         test    al, al
  157.         jnz     .scan1
  158.         pop     eax
  159. ; directory /xxx
  160. .maindir:
  161.         cmp     dword [ebx], 1
  162.         jnz     .access_denied
  163.         xor     eax, eax
  164.         mov     ebp, [ebx+12]
  165.         mov     edx, [ebx+16]
  166.     ;    add     edx, std_application_base_address
  167.         push    dword [ebx+4]   ; first block
  168.         mov     ebx, [ebx+8]    ; flags
  169.         mov     esi, [edi+4]
  170. ; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
  171.         mov     edi, edx
  172.         mov     ecx, 32/4
  173.         rep     stosd
  174.         mov     byte [edx], 1   ; version
  175. .maindir_loop:
  176.         call    esi
  177.         jc      .maindir_done
  178.         inc     dword [edx+8]
  179.         dec     dword [esp]
  180.         jns     .maindir_loop
  181.         dec     ebp
  182.         js      .maindir_loop
  183.         inc     dword [edx+4]
  184.         mov     dword [edi], 0x10       ; attributes: folder
  185.         mov     dword [edi+4], 1        ; name type: UNICODE
  186.         push    eax
  187.         xor     eax, eax
  188.         add     edi, 8
  189.         mov     ecx, 40/4-2
  190.         rep     stosd
  191.         pop     eax
  192.         push    eax edx
  193. ; convert number in eax to decimal UNICODE string
  194.         push    edi
  195.         push    -'0'
  196.         mov     cl, 10
  197. @@:
  198.         xor     edx, edx
  199.         div     ecx
  200.         push    edx
  201.         test    eax, eax
  202.         jnz     @b
  203. @@:
  204.         pop     eax
  205.         add     al, '0'
  206.         stosb
  207.         test    bl, 1           ; UNICODE name?
  208.         jz      .ansi2
  209.         mov     byte [edi], 0
  210.         inc     edi
  211. .ansi2:
  212.         test    al, al
  213.         jnz     @b
  214.         mov     byte [edi-1], 0
  215.         pop     edi
  216. ; UNICODE name length is 520 bytes, ANSI - 264
  217.         add     edi, 520
  218.         test    bl, 1
  219.         jnz     @f
  220.         sub     edi, 520-264
  221. @@:
  222.         pop     edx eax
  223.         jmp     .maindir_loop
  224. .maindir_done:
  225.         pop     eax
  226.         mov     ebx, [edx+4]
  227.         xor     eax, eax
  228.         dec     ebp
  229.         js      @f
  230.         mov     al, ERROR_END_OF_FILE
  231. @@:
  232.         mov     [image_of_eax], eax
  233.         mov     [image_of_ebx], ebx
  234.         ret
  235. ; directory /
  236. .rootdir:
  237.         cmp     dword [ebx], 1  ; read folder?
  238.         jz      .readroot
  239. .access_denied:
  240.         mov     dword [image_of_eax], 10      ; access denied
  241.         ret
  242.  
  243. .readroot:
  244. ; virtual root folder - special handler
  245.         mov     esi, virtual_root_query
  246.         mov     ebp, [ebx+12]
  247.         mov     edx, [ebx+16]
  248.     ;    add     edx, std_application_base_address
  249.         push    dword [ebx+4]   ; first block
  250.         mov     ebx, [ebx+8]    ; flags
  251.         xor     eax, eax
  252. ; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
  253.         mov     edi, edx
  254.         mov     ecx, 32/4
  255.         rep     stosd
  256.         mov     byte [edx], 1   ; version
  257. .readroot_loop:
  258.         cmp     dword [esi], eax
  259.         jz      .readroot_done
  260.         call    dword [esi]
  261.         add     esi, 4
  262.         test    eax, eax
  263.         jnz     @f
  264. .readroot_next:
  265.         or      ecx, -1
  266.         xchg    esi, edi
  267.         repnz   scasb
  268.         xchg    esi, edi
  269.         jmp     .readroot_loop
  270. @@:
  271.         xor     eax, eax
  272.         inc     dword [edx+8]
  273.         dec     dword [esp]
  274.         jns     .readroot_next
  275.         dec     ebp
  276.         js      .readroot_next
  277.         inc     dword [edx+4]
  278.         mov     dword [edi], 0x10       ; attributes: folder
  279.         mov     dword [edi+4], 1        ; name type: UNICODE
  280.         add     edi, 8
  281.         mov     ecx, 40/4-2
  282.         rep     stosd
  283.         push    edi
  284. @@:
  285.         lodsb
  286.         stosb
  287.         test    bl, 1
  288.         jz      .ansi
  289.         mov     byte [edi], 0
  290.         inc     edi
  291. .ansi:
  292.         test    eax, eax
  293.         jnz     @b
  294.         pop     edi
  295.         add     edi, 520
  296.         test    bl, 1
  297.         jnz     .readroot_loop
  298.         sub     edi, 520-264
  299.         jmp     .readroot_loop
  300. .readroot_done:
  301.         pop     eax
  302.         mov     ebx, [edx+4]
  303.         xor     eax, eax
  304.         dec     ebp
  305.         js      @f
  306.         mov     al, ERROR_END_OF_FILE
  307. @@:
  308.         mov     [image_of_eax], eax
  309.         mov     [image_of_ebx], ebx
  310.         ret
  311. .notfound:
  312.         mov     dword [image_of_eax], ERROR_FILE_NOT_FOUND
  313.         and     dword [image_of_ebx], 0
  314.         ret
  315.  
  316. .found1:
  317.         pop     eax
  318.         cmp     byte [esi], 0
  319.         jz      .maindir
  320. ; read partition number
  321.         xor     ecx, ecx
  322.         xor     eax, eax
  323. @@:
  324.         lodsb
  325.         cmp     al, '/'
  326.         jz      .done1
  327.         test    al, al
  328.         jz      .done1
  329.         sub     al, '0'
  330.         cmp     al, 9
  331.         ja      .notfound
  332.         lea     ecx, [ecx*5]
  333.         lea     ecx, [ecx*2+eax]
  334.         jmp     @b
  335. .done1:
  336.         jecxz   .notfound
  337.         test    al, al
  338.         jnz     @f
  339.         dec     esi
  340. @@:
  341.         cmp     byte [esi], 0
  342.         jnz     @f
  343.         test    ebp, ebp
  344.         jz      @f
  345.         mov     esi, ebp
  346.         xor     ebp, ebp
  347. @@:
  348. ; now [edi] contains handler address, ecx - partition number,
  349. ; esi points to ASCIIZ string - rest of name
  350.         jmp     dword [edi]
  351.  
  352. ; handlers for devices
  353. ; in: ecx = 0 => query virtual directory /xxx
  354. ; in: ecx = partition number
  355. ;     esi -> relative (for device) name
  356. ;     ebx -> fileinfo
  357. ;     ebp = 0 or pointer to rest of name from folder addressed by esi
  358. ; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
  359.  
  360. fs_OnRamdisk:
  361.         cmp     ecx, 1
  362.         jnz     file_system_lfn.notfound
  363.         mov     eax, [ebx]
  364.         cmp     eax, fs_NumRamdiskServices
  365.         jae     .not_impl
  366.         mov     ecx, [ebx+12]
  367.         mov     edx, [ebx+16]
  368.    ;     add     edx, std_application_base_address
  369.         add     ebx, 4
  370.         call    dword [fs_RamdiskServices + eax*4]
  371.         mov     [image_of_eax], eax
  372.         mov     [image_of_ebx], ebx
  373.         ret
  374. .not_impl:
  375.         mov     dword [image_of_eax], 2       ; not implemented
  376.         ret
  377.  
  378. fs_NotImplemented:
  379.         mov     eax, 2
  380.         ret
  381.  
  382. fs_RamdiskServices:
  383.         dd      fs_RamdiskRead
  384.         dd      fs_RamdiskReadFolder
  385.         dd      fs_RamdiskRewrite
  386.         dd      fs_RamdiskWrite
  387.         dd      fs_RamdiskSetFileEnd
  388.         dd      fs_RamdiskGetFileInfo
  389.         dd      fs_RamdiskSetFileInfo
  390.         dd      0
  391.         dd      fs_RamdiskDelete
  392.         dd      fs_RamdiskCreateFolder
  393. fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
  394.  
  395. fs_OnFloppy:
  396.         cmp     ecx, 2
  397.         ja      file_system_lfn.notfound
  398.         mov     eax, [ebx]
  399.         cmp     eax, fs_NumFloppyServices
  400.         jae     fs_OnRamdisk.not_impl
  401.         call    reserve_flp
  402.         mov     [flp_number], cl
  403.         mov     ecx, [ebx+12]
  404.         mov     edx, [ebx+16]
  405.    ;     add     edx, std_application_base_address
  406.         add     ebx, 4
  407.         call    dword [fs_FloppyServices + eax*4]
  408.         and     [flp_status], 0
  409.         mov     [image_of_eax], eax
  410.         mov     [image_of_ebx], ebx
  411.         ret
  412.  
  413. fs_FloppyServices:
  414.         dd      fs_FloppyRead
  415.         dd      fs_FloppyReadFolder
  416.         dd      fs_FloppyRewrite
  417.         dd      fs_FloppyWrite
  418.         dd      fs_FloppySetFileEnd
  419.         dd      fs_FloppyGetFileInfo
  420.         dd      fs_FloppySetFileInfo
  421.         dd      0
  422.         dd      fs_FloppyDelete
  423.         dd      fs_FloppyCreateFolder
  424. fs_NumFloppyServices = ($ - fs_FloppyServices)/4
  425.  
  426. fs_OnHd0:
  427.         call    reserve_hd1
  428.         mov     [hdbase], 0x1F0
  429.         mov     [hdid], 0
  430.         push    1
  431.         jmp     fs_OnHd
  432. fs_OnHd1:
  433.         call    reserve_hd1
  434.         mov     [hdbase], 0x1F0
  435.         mov     [hdid], 0x10
  436.         push    2
  437.         jmp     fs_OnHd
  438. fs_OnHd2:
  439.         call    reserve_hd1
  440.         mov     [hdbase], 0x170
  441.         mov     [hdid], 0
  442.         push    3
  443.         jmp     fs_OnHd
  444. fs_OnHd3:
  445.         call    reserve_hd1
  446.         mov     [hdbase], 0x170
  447.         mov     [hdid], 0x10
  448.         push    4
  449. fs_OnHd:
  450.         call    reserve_hd_channel
  451.         pop     eax
  452.         mov     [hdpos], eax
  453.         cmp     ecx, 0x100
  454.         jae     .nf
  455.         cmp     cl, [DRIVE_DATA+1+eax]
  456.         jbe     @f
  457. .nf:
  458.         call    free_hd_channel
  459.         and     [hd1_status], 0
  460.         mov     dword [image_of_eax], 5       ; not found
  461.         ret
  462. @@:
  463.         mov     [fat32part], ecx
  464.         push    ebx esi
  465.         call    choice_necessity_partition_1
  466.         pop     esi ebx
  467.         mov     ecx, [ebx+12]
  468.         mov     edx, [ebx+16]
  469.     ;    add     edx, std_application_base_address
  470.         mov     eax, [ebx]
  471.         cmp     eax, fs_NumHdServices
  472.         jae     .not_impl
  473.         add     ebx, 4
  474.         call    dword [fs_HdServices + eax*4]
  475.         call    free_hd_channel
  476.         and     [hd1_status], 0
  477.         mov     [image_of_eax], eax
  478.         mov     [image_of_ebx], ebx
  479.         ret
  480. .not_impl:
  481.         call    free_hd_channel
  482.         and     [hd1_status], 0
  483.         mov     dword [image_of_eax], 2       ; not implemented
  484.         ret
  485.  
  486. fs_HdServices:
  487.         dd      fs_HdRead
  488.         dd      fs_HdReadFolder
  489.         dd      fs_HdRewrite
  490.         dd      fs_HdWrite
  491.         dd      fs_HdSetFileEnd
  492.         dd      fs_HdGetFileInfo
  493.         dd      fs_HdSetFileInfo
  494.         dd      0
  495.         dd      fs_HdDelete
  496.         dd      fs_HdCreateFolder
  497. fs_NumHdServices = ($ - fs_HdServices)/4
  498.  
  499. ;*******************************************************
  500. fs_OnCd0:
  501.         call    reserve_cd
  502.         mov  [ChannelNumber],1
  503.         mov  [DiskNumber],0
  504.         push    6
  505.         push    1
  506.         jmp     fs_OnCd
  507. fs_OnCd1:
  508.         call    reserve_cd
  509.         mov  [ChannelNumber],1
  510.         mov  [DiskNumber],1
  511.         push    4
  512.         push    2
  513.         jmp     fs_OnCd
  514. fs_OnCd2:
  515.         call    reserve_cd
  516.         mov  [ChannelNumber],2
  517.         mov  [DiskNumber],0
  518.         push    2
  519.         push    3
  520.         jmp     fs_OnCd
  521. fs_OnCd3:
  522.         call    reserve_cd
  523.         mov  [ChannelNumber],2
  524.         mov  [DiskNumber],1
  525.         push    0
  526.         push    4
  527. fs_OnCd:
  528.         call    reserve_cd_channel
  529.         pop     eax
  530.         mov     [cdpos], eax
  531.         pop     eax
  532.         cmp     ecx, 0x100
  533.         jae     .nf
  534.         push    ecx ebx
  535.         mov     cl,al
  536.         mov     bl,[DRIVE_DATA+1]
  537.         shr     bl,cl
  538.         test    bl,2
  539.         pop     ebx ecx
  540.  
  541.         jnz     @f
  542. .nf:
  543.         call    free_cd_channel
  544.         and    [cd_status], 0
  545.         mov     dword [image_of_eax], 5       ; not found
  546.         ret
  547. @@:
  548.         mov     ecx, [ebx+12]
  549.         mov     edx, [ebx+16]
  550.     ;    add     edx, std_application_base_address
  551.         mov     eax, [ebx]
  552.         cmp     eax,fs_NumCdServices
  553.         jae      .not_impl
  554.         add     ebx, 4
  555.         call    dword [fs_CdServices + eax*4]
  556.         call    free_cd_channel
  557.         and     [cd_status], 0
  558.         mov     [image_of_eax], eax
  559.         mov     [image_of_ebx], ebx
  560.         ret
  561. .not_impl:
  562.         call    free_cd_channel
  563.         and     [cd_status], 0
  564.         mov     dword [image_of_eax], 2       ; not implemented
  565.         ret
  566.  
  567. fs_CdServices:
  568.         dd      fs_CdRead
  569.         dd      fs_CdReadFolder
  570.         dd      fs_NotImplemented
  571.         dd      fs_NotImplemented
  572.         dd      fs_NotImplemented
  573.         dd      fs_CdGetFileInfo
  574.         dd      fs_NotImplemented
  575.         dd      0
  576.         dd      fs_NotImplemented
  577.         dd      fs_NotImplemented
  578. fs_NumCdServices = ($ - fs_CdServices)/4
  579.  
  580. ;*******************************************************
  581.  
  582. fs_HasRamdisk:
  583.         mov     al, 1   ; we always have ramdisk
  584.         ret
  585.  
  586. fs_HasFloppy:
  587.         cmp     byte [DRIVE_DATA], 0
  588.         setnz   al
  589.         ret
  590.  
  591. fs_HasHd0:
  592.         mov     al, [DRIVE_DATA+1]
  593.         and     al, 11000000b
  594.         cmp     al, 01000000b
  595.         setz    al
  596.         ret
  597. fs_HasHd1:
  598.         mov     al, [DRIVE_DATA+1]
  599.         and     al, 00110000b
  600.         cmp     al, 00010000b
  601.         setz    al
  602.         ret
  603. fs_HasHd2:
  604.         mov     al, [DRIVE_DATA+1]
  605.         and     al, 00001100b
  606.         cmp     al, 00000100b
  607.         setz    al
  608.         ret
  609. fs_HasHd3:
  610.         mov     al, [DRIVE_DATA+1]
  611.         and     al, 00000011b
  612.         cmp     al, 00000001b
  613.         setz    al
  614.         ret
  615.  
  616. ;*******************************************************
  617. fs_HasCd0:
  618.         mov     al, [DRIVE_DATA+1]
  619.         and     al, 11000000b
  620.         cmp     al, 10000000b
  621.         setz    al
  622.         ret
  623. fs_HasCd1:
  624.         mov     al, [DRIVE_DATA+1]
  625.         and     al, 00110000b
  626.         cmp     al, 00100000b
  627.         setz    al
  628.         ret
  629. fs_HasCd2:
  630.         mov     al, [DRIVE_DATA+1]
  631.         and     al, 00001100b
  632.         cmp     al, 00001000b
  633.         setz    al
  634.         ret
  635. fs_HasCd3:
  636.         mov     al, [DRIVE_DATA+1]
  637.         and     al, 00000011b
  638.         cmp     al, 00000010b
  639.         setz    al
  640.         ret
  641. ;*******************************************************
  642.  
  643. ; fs_NextXXX functions:
  644. ; in: eax = partition number, from which start to scan
  645. ; out: CF=1 => no more partitions
  646. ;      CF=0 => eax=next partition number
  647.  
  648. fs_NextRamdisk:
  649. ; we always have /rd/1
  650.         test    eax, eax
  651.         stc
  652.         jnz     @f
  653.         mov     al, 1
  654.         clc
  655. @@:
  656.         ret
  657.  
  658. fs_NextFloppy:
  659. ; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
  660.         test    byte [DRIVE_DATA], 0xF0
  661.         jz      .no1
  662.         test    eax, eax
  663.         jnz     .no1
  664.         inc     eax
  665.         ret     ; CF cleared
  666. .no1:
  667.         test    byte [DRIVE_DATA], 0x0F
  668.         jz      .no2
  669.         cmp     al, 2
  670.         jae     .no2
  671.         mov     al, 2
  672.         clc
  673.         ret
  674. .no2:
  675.         stc
  676.         ret
  677.  
  678. ; on hdx, we have partitions from 1 to [0x40002+x]
  679. fs_NextHd0:
  680.         push    0
  681.         jmp     fs_NextHd
  682. fs_NextHd1:
  683.         push    1
  684.         jmp     fs_NextHd
  685. fs_NextHd2:
  686.         push    2
  687.         jmp     fs_NextHd
  688. fs_NextHd3:
  689.         push    3
  690. fs_NextHd:
  691.         pop     ecx
  692.         movzx   ecx, byte [DRIVE_DATA+2+ecx]
  693.         cmp     eax, ecx
  694.         jae     fs_NextFloppy.no2
  695.         inc     eax
  696.         clc
  697.         ret
  698.  
  699. ;*******************************************************
  700. fs_NextCd:
  701. ; we always have /cdX/1
  702.         test    eax, eax
  703.         stc
  704.         jnz     @f
  705.         mov     al, 1
  706.         clc
  707. @@:
  708.         ret
  709. ;*******************************************************
  710.  
  711. process_replace_file_name:
  712.         mov     ebp, [full_file_name_table]
  713.         mov     edi, [full_file_name_table.size]
  714.         dec     edi
  715.         shl     edi, 7
  716.         add     edi, ebp
  717. .loop:
  718.         cmp     edi, ebp
  719.         jb      .notfound
  720.         push    esi edi
  721. @@:
  722.         cmp     byte [edi], 0
  723.         jz      .dest_done
  724.         lodsb
  725.         test    al, al
  726.         jz      .cont
  727.         or      al, 20h
  728.         scasb
  729.         jz      @b
  730.         jmp     .cont
  731. .dest_done:
  732.         cmp     byte [esi], 0
  733.         jz      .found
  734.         cmp     byte [esi], '/'
  735.         jnz     .cont
  736.         inc     esi
  737.         jmp     .found
  738. .cont:
  739.         pop     edi esi
  740.         sub     edi, 128
  741.         jmp     .loop
  742. .found:
  743.         pop     edi eax
  744.         mov     ebp, esi
  745.         cmp     byte [esi], 0
  746.         lea     esi, [edi+64]
  747.         jnz     .ret
  748. .notfound:
  749.         xor     ebp, ebp
  750. .ret:
  751.         ret
  752.  
  753. sys_current_directory:
  754.         mov     esi, [current_slot]
  755.         mov     esi, [esi+APPDATA.cur_dir]
  756.         mov     edx, esi
  757.         dec     eax
  758.         jz      .set
  759.         dec     eax
  760.         jz      .get
  761.         ret
  762. .get:
  763. ; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
  764. ; for our code: ebx->buffer,ecx=len
  765. @@:
  766.         lodsb
  767.         test    al, al
  768.         jnz     @b
  769.         sub     esi, edx
  770.         inc     esi
  771.         mov     [esp+36], esi
  772.         cmp     ecx, esi
  773.         jbe     @f
  774.         mov     ecx, esi
  775. @@:
  776.         cmp     ecx, 1
  777.         jbe     .ret
  778.         mov     esi, edx
  779.         mov     edi, ebx
  780.         mov     al, '/'
  781.         stosb
  782.         dec     ecx
  783.         dec     ecx
  784.         rep     movsb
  785.         mov     byte [edi], 0
  786. .ret:
  787.         ret
  788. .set:
  789. ; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
  790. ; for our code: ebx->string to set
  791. @@:
  792.         inc     esi
  793.         cmp     byte [esi-1], 0
  794.         jnz     @b
  795.         dec     esi
  796.         cmp     byte [ebx], '/'
  797.         jz      .set_absolute
  798. ; string gives relative path
  799. .relative:
  800.         cmp     byte [ebx], 0
  801.         jz      .set_ok
  802.         cmp     word [ebx], '.'
  803.         jz      .set_ok
  804.         cmp     word [ebx], './'
  805.         jnz     @f
  806.         add     ebx, 2
  807.         jmp     .relative
  808. @@:
  809.         cmp     word [ebx], '..'
  810.         jnz     .doset_relative
  811.         cmp     byte [ebx+2], 0
  812.         jz      @f
  813.         cmp     byte [ebx+2], '/'
  814.         jnz     .doset_relative
  815. @@:
  816.         dec     esi
  817.         cmp     byte [esi], '/'
  818.         jnz     @b
  819.         mov     byte [esi], 0
  820.         add     ebx, 3
  821.         jmp     .relative
  822. .doset_relative:
  823.         add     edx, 0x1000
  824.         mov     byte [esi], '/'
  825.         inc     esi
  826.         cmp     esi, edx
  827.         jae     .overflow_esi
  828. @@:
  829.         mov     al, [ebx]
  830.         inc     ebx
  831.         mov     [esi], al
  832.         inc     esi
  833.         test    al, al
  834.         jz      .set_ok
  835.         cmp     esi, edx
  836.         jb      @b
  837. .overflow_esi:
  838.         mov     byte [esi-1], 0         ; force null-terminated string
  839. .set_ok:
  840.         ret
  841. .set_absolute:
  842.         lea     esi, [ebx+1]
  843.         call    process_replace_file_name
  844.         mov     edi, edx
  845.         add     edx, 0x1000
  846. .set_copy:
  847.         lodsb
  848.         stosb
  849.         test    al, al
  850.         jz      .set_part2
  851. .set_copy_cont:
  852.         cmp     edi, edx
  853.         jb      .set_copy
  854. .overflow_edi:
  855.         mov     byte [edi-1], 0
  856.         ret
  857. .set_part2:
  858.         mov     esi, ebp
  859.         xor     ebp, ebp
  860.         test    esi, esi
  861.         jz      .set_ok
  862.         mov     byte [edi-1], '/'
  863.         jmp     .set_copy_cont
  864.