Subversion Repositories Kolibri OS

Rev

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

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