Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 585 $
  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.         dd      fs_NotImplemented
  392.         dd      fs_NotImplemented
  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.         dd      fs_NotImplemented
  425.         dd      fs_NotImplemented
  426. fs_NumFloppyServices = ($ - fs_FloppyServices)/4
  427.  
  428. fs_OnHd0:
  429.         call    reserve_hd1
  430.         mov     [hdbase], 0x1F0
  431.         mov     [hdid], 0
  432.         push    1
  433.         jmp     fs_OnHd
  434. fs_OnHd1:
  435.         call    reserve_hd1
  436.         mov     [hdbase], 0x1F0
  437.         mov     [hdid], 0x10
  438.         push    2
  439.         jmp     fs_OnHd
  440. fs_OnHd2:
  441.         call    reserve_hd1
  442.         mov     [hdbase], 0x170
  443.         mov     [hdid], 0
  444.         push    3
  445.         jmp     fs_OnHd
  446. fs_OnHd3:
  447.         call    reserve_hd1
  448.         mov     [hdbase], 0x170
  449.         mov     [hdid], 0x10
  450.         push    4
  451. fs_OnHd:
  452.         call    reserve_hd_channel
  453.         pop     eax
  454.         mov     [hdpos], eax
  455.         cmp     ecx, 0x100
  456.         jae     .nf
  457.         cmp     cl, [DRIVE_DATA+1+eax]
  458.         jbe     @f
  459. .nf:
  460.         call    free_hd_channel
  461.         and     [hd1_status], 0
  462.         mov     dword [image_of_eax], 5       ; not found
  463.         ret
  464. @@:
  465.         mov     [fat32part], ecx
  466.         push    ebx esi
  467.         call    choice_necessity_partition_1
  468.         pop     esi ebx
  469.         mov     ecx, [ebx+12]
  470.         mov     edx, [ebx+16]
  471.     ;    add     edx, std_application_base_address
  472.         mov     eax, [ebx]
  473.         cmp     eax, fs_NumHdServices
  474.         jae     .not_impl
  475.         add     ebx, 4
  476.         call    dword [fs_HdServices + eax*4]
  477.         call    free_hd_channel
  478.         and     [hd1_status], 0
  479.         mov     [image_of_eax], eax
  480.         mov     [image_of_ebx], ebx
  481.         ret
  482. .not_impl:
  483.         call    free_hd_channel
  484.         and     [hd1_status], 0
  485.         mov     dword [image_of_eax], 2       ; not implemented
  486.         ret
  487.  
  488. fs_HdServices:
  489.         dd      fs_HdRead
  490.         dd      fs_HdReadFolder
  491.         dd      fs_HdRewrite
  492.         dd      fs_HdWrite
  493.         dd      fs_HdSetFileEnd
  494.         dd      fs_HdGetFileInfo
  495.         dd      fs_HdSetFileInfo
  496.         dd      0
  497.         dd      fs_HdDelete
  498.         dd      fs_HdCreateFolder
  499.         dd      fs_NotImplemented
  500.         dd      fs_NotImplemented
  501. fs_NumHdServices = ($ - fs_HdServices)/4
  502.  
  503. ;*******************************************************
  504. fs_OnCd0:
  505.         call    reserve_cd
  506.         mov  [ChannelNumber],1
  507.         mov  [DiskNumber],0
  508.         push    6
  509.         push    1
  510.         jmp     fs_OnCd
  511. fs_OnCd1:
  512.         call    reserve_cd
  513.         mov  [ChannelNumber],1
  514.         mov  [DiskNumber],1
  515.         push    4
  516.         push    2
  517.         jmp     fs_OnCd
  518. fs_OnCd2:
  519.         call    reserve_cd
  520.         mov  [ChannelNumber],2
  521.         mov  [DiskNumber],0
  522.         push    2
  523.         push    3
  524.         jmp     fs_OnCd
  525. fs_OnCd3:
  526.         call    reserve_cd
  527.         mov  [ChannelNumber],2
  528.         mov  [DiskNumber],1
  529.         push    0
  530.         push    4
  531. fs_OnCd:
  532.         call    reserve_cd_channel
  533.         pop     eax
  534.         mov     [cdpos], eax
  535.         pop     eax
  536.         cmp     ecx, 0x100
  537.         jae     .nf
  538.         push    ecx ebx
  539.         mov     cl,al
  540.         mov     bl,[DRIVE_DATA+1]
  541.         shr     bl,cl
  542.         test    bl,2
  543.         pop     ebx ecx
  544.  
  545.         jnz     @f
  546. .nf:
  547.         call    free_cd_channel
  548.         and    [cd_status], 0
  549.         mov     dword [image_of_eax], 5       ; not found
  550.         ret
  551. @@:
  552.         mov     ecx, [ebx+12]
  553.         mov     edx, [ebx+16]
  554.     ;    add     edx, std_application_base_address
  555.         mov     eax, [ebx]
  556.         cmp     eax,fs_NumCdServices
  557.         jae      .not_impl
  558.         add     ebx, 4
  559.         call    dword [fs_CdServices + eax*4]
  560.         call    free_cd_channel
  561.         and     [cd_status], 0
  562.         mov     [image_of_eax], eax
  563.         mov     [image_of_ebx], ebx
  564.         ret
  565. .not_impl:
  566.         call    free_cd_channel
  567.         and     [cd_status], 0
  568.         mov     dword [image_of_eax], 2       ; not implemented
  569.         ret
  570.  
  571. fs_CdServices:
  572.         dd      fs_CdRead
  573.         dd      fs_CdReadFolder
  574.         dd      fs_NotImplemented
  575.         dd      fs_NotImplemented
  576.         dd      fs_NotImplemented
  577.         dd      fs_CdGetFileInfo
  578.         dd      fs_NotImplemented
  579.         dd      0
  580.         dd      fs_NotImplemented
  581.         dd      fs_NotImplemented
  582.         dd  fs_EjectDeviceTray
  583.         dd  fs_LoadDeviceTray
  584. fs_NumCdServices = ($ - fs_CdServices)/4
  585.  
  586. ;*******************************************************
  587.  
  588. fs_HasRamdisk:
  589.         mov     al, 1   ; we always have ramdisk
  590.         ret
  591.  
  592. fs_HasFloppy:
  593.         cmp     byte [DRIVE_DATA], 0
  594.         setnz   al
  595.         ret
  596.  
  597. fs_HasHd0:
  598.         mov     al, [DRIVE_DATA+1]
  599.         and     al, 11000000b
  600.         cmp     al, 01000000b
  601.         setz    al
  602.         ret
  603. fs_HasHd1:
  604.         mov     al, [DRIVE_DATA+1]
  605.         and     al, 00110000b
  606.         cmp     al, 00010000b
  607.         setz    al
  608.         ret
  609. fs_HasHd2:
  610.         mov     al, [DRIVE_DATA+1]
  611.         and     al, 00001100b
  612.         cmp     al, 00000100b
  613.         setz    al
  614.         ret
  615. fs_HasHd3:
  616.         mov     al, [DRIVE_DATA+1]
  617.         and     al, 00000011b
  618.         cmp     al, 00000001b
  619.         setz    al
  620.         ret
  621.  
  622. ;*******************************************************
  623. fs_HasCd0:
  624.         mov     al, [DRIVE_DATA+1]
  625.         and     al, 11000000b
  626.         cmp     al, 10000000b
  627.         setz    al
  628.         ret
  629. fs_HasCd1:
  630.         mov     al, [DRIVE_DATA+1]
  631.         and     al, 00110000b
  632.         cmp     al, 00100000b
  633.         setz    al
  634.         ret
  635. fs_HasCd2:
  636.         mov     al, [DRIVE_DATA+1]
  637.         and     al, 00001100b
  638.         cmp     al, 00001000b
  639.         setz    al
  640.         ret
  641. fs_HasCd3:
  642.         mov     al, [DRIVE_DATA+1]
  643.         and     al, 00000011b
  644.         cmp     al, 00000010b
  645.         setz    al
  646.         ret
  647. ;*******************************************************
  648.  
  649. ; fs_NextXXX functions:
  650. ; in: eax = partition number, from which start to scan
  651. ; out: CF=1 => no more partitions
  652. ;      CF=0 => eax=next partition number
  653.  
  654. fs_NextRamdisk:
  655. ; we always have /rd/1
  656.         test    eax, eax
  657.         stc
  658.         jnz     @f
  659.         mov     al, 1
  660.         clc
  661. @@:
  662.         ret
  663.  
  664. fs_NextFloppy:
  665. ; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
  666.         test    byte [DRIVE_DATA], 0xF0
  667.         jz      .no1
  668.         test    eax, eax
  669.         jnz     .no1
  670.         inc     eax
  671.         ret     ; CF cleared
  672. .no1:
  673.         test    byte [DRIVE_DATA], 0x0F
  674.         jz      .no2
  675.         cmp     al, 2
  676.         jae     .no2
  677.         mov     al, 2
  678.         clc
  679.         ret
  680. .no2:
  681.         stc
  682.         ret
  683.  
  684. ; on hdx, we have partitions from 1 to [0x40002+x]
  685. fs_NextHd0:
  686.         push    0
  687.         jmp     fs_NextHd
  688. fs_NextHd1:
  689.         push    1
  690.         jmp     fs_NextHd
  691. fs_NextHd2:
  692.         push    2
  693.         jmp     fs_NextHd
  694. fs_NextHd3:
  695.         push    3
  696. fs_NextHd:
  697.         pop     ecx
  698.         movzx   ecx, byte [DRIVE_DATA+2+ecx]
  699.         cmp     eax, ecx
  700.         jae     fs_NextFloppy.no2
  701.         inc     eax
  702.         clc
  703.         ret
  704.  
  705. ;*******************************************************
  706. fs_NextCd:
  707. ; we always have /cdX/1
  708.         test    eax, eax
  709.         stc
  710.         jnz     @f
  711.         mov     al, 1
  712.         clc
  713. @@:
  714.         ret
  715. ;*******************************************************
  716.  
  717. process_replace_file_name:
  718.         mov     ebp, [full_file_name_table]
  719.         mov     edi, [full_file_name_table.size]
  720.         dec     edi
  721.         shl     edi, 7
  722.         add     edi, ebp
  723. .loop:
  724.         cmp     edi, ebp
  725.         jb      .notfound
  726.         push    esi edi
  727. @@:
  728.         cmp     byte [edi], 0
  729.         jz      .dest_done
  730.         lodsb
  731.         test    al, al
  732.         jz      .cont
  733.         or      al, 20h
  734.         scasb
  735.         jz      @b
  736.         jmp     .cont
  737. .dest_done:
  738.         cmp     byte [esi], 0
  739.         jz      .found
  740.         cmp     byte [esi], '/'
  741.         jnz     .cont
  742.         inc     esi
  743.         jmp     .found
  744. .cont:
  745.         pop     edi esi
  746.         sub     edi, 128
  747.         jmp     .loop
  748. .found:
  749.         pop     edi eax
  750.         mov     ebp, esi
  751.         cmp     byte [esi], 0
  752.         lea     esi, [edi+64]
  753.         jnz     .ret
  754. .notfound:
  755.         xor     ebp, ebp
  756. .ret:
  757.         ret
  758.  
  759. sys_current_directory:
  760.         mov     esi, [current_slot]
  761.         mov     esi, [esi+APPDATA.cur_dir]
  762.         mov     edx, esi
  763.         dec     eax
  764.         jz      .set
  765.         dec     eax
  766.         jz      .get
  767.         ret
  768. .get:
  769. ; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
  770. ; for our code: ebx->buffer,ecx=len
  771. @@:
  772.         lodsb
  773.         test    al, al
  774.         jnz     @b
  775.         sub     esi, edx
  776.         inc     esi
  777.         mov     [esp+36], esi
  778.         cmp     ecx, esi
  779.         jbe     @f
  780.         mov     ecx, esi
  781. @@:
  782.         cmp     ecx, 1
  783.         jbe     .ret
  784.         mov     esi, edx
  785.         mov     edi, ebx
  786.         mov     al, '/'
  787.         stosb
  788.         dec     ecx
  789.         dec     ecx
  790.         rep     movsb
  791.         mov     byte [edi], 0
  792. .ret:
  793.         ret
  794. .set:
  795. ; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
  796. ; for our code: ebx->string to set
  797. @@:
  798.         inc     esi
  799.         cmp     byte [esi-1], 0
  800.         jnz     @b
  801.         dec     esi
  802.         cmp     byte [ebx], '/'
  803.         jz      .set_absolute
  804. ; string gives relative path
  805. .relative:
  806.         cmp     byte [ebx], 0
  807.         jz      .set_ok
  808.         cmp     word [ebx], '.'
  809.         jz      .set_ok
  810.         cmp     word [ebx], './'
  811.         jnz     @f
  812.         add     ebx, 2
  813.         jmp     .relative
  814. @@:
  815.         cmp     word [ebx], '..'
  816.         jnz     .doset_relative
  817.         cmp     byte [ebx+2], 0
  818.         jz      @f
  819.         cmp     byte [ebx+2], '/'
  820.         jnz     .doset_relative
  821. @@:
  822.         dec     esi
  823.         cmp     byte [esi], '/'
  824.         jnz     @b
  825.         mov     byte [esi], 0
  826.         add     ebx, 3
  827.         jmp     .relative
  828. .doset_relative:
  829.         add     edx, 0x1000
  830.         mov     byte [esi], '/'
  831.         inc     esi
  832.         cmp     esi, edx
  833.         jae     .overflow_esi
  834. @@:
  835.         mov     al, [ebx]
  836.         inc     ebx
  837.         mov     [esi], al
  838.         inc     esi
  839.         test    al, al
  840.         jz      .set_ok
  841.         cmp     esi, edx
  842.         jb      @b
  843. .overflow_esi:
  844.         mov     byte [esi-1], 0         ; force null-terminated string
  845. .set_ok:
  846.         ret
  847. .set_absolute:
  848.         lea     esi, [ebx+1]
  849.         call    process_replace_file_name
  850.         mov     edi, edx
  851.         add     edx, 0x1000
  852. .set_copy:
  853.         lodsb
  854.         stosb
  855.         test    al, al
  856.         jz      .set_part2
  857. .set_copy_cont:
  858.         cmp     edi, edx
  859.         jb      .set_copy
  860. .overflow_edi:
  861.         mov     byte [edi-1], 0
  862.         ret
  863. .set_part2:
  864.         mov     esi, ebp
  865.         xor     ebp, ebp
  866.         test    esi, esi
  867.         jz      .set_ok
  868.         mov     byte [edi-1], '/'
  869.         jmp     .set_copy_cont
  870.