Subversion Repositories Kolibri OS

Rev

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

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