Subversion Repositories Kolibri OS

Rev

Rev 1689 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;                                                              ;;
  2. ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
  3. ;; Distributed under terms of the GNU General Public License    ;;
  4. ;;                                                              ;;
  5. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  6.  
  7. $Revision: 3487 $
  8.  
  9.  
  10. image_of_eax EQU esp+32
  11. image_of_ebx EQU esp+20
  12.  
  13. ; System function 70 - files with long names (LFN)
  14. ; diamond, 2006
  15.  
  16. iglobal
  17. ; in this table names must be in lowercase
  18. rootdirs:
  19.         db      2,'rd'
  20.         dd      fs_OnRamdisk
  21.         dd      fs_NextRamdisk
  22.         db      7,'ramdisk'
  23.         dd      fs_OnRamdisk
  24.         dd      fs_NextRamdisk
  25.         db      3,'hd0'
  26.         dd      fs_OnHd0
  27.         dd      fs_NextHd0
  28.         db      3,'hd1'
  29.         dd      fs_OnHd1
  30.         dd      fs_NextHd1
  31.         db      3,'hd2'
  32.         dd      fs_OnHd2
  33.         dd      fs_NextHd2
  34.         db      3,'hd3'
  35.         dd      fs_OnHd3
  36.         dd      fs_NextHd3
  37.         db      0
  38.  
  39.  
  40. virtual_root_query:
  41.         dd      fs_HasRamdisk
  42.         db      'rd',0
  43.         dd      fs_HasFloppy
  44.         db      'fd',0
  45.         dd      fs_HasHd0
  46.         db      'hd0',0
  47.         dd      fs_HasHd1
  48.         db      'hd1',0
  49.         dd      fs_HasHd2
  50.         db      'hd2',0
  51.         dd      fs_HasHd3
  52.         db      'hd3',0
  53.         dd      0
  54.  
  55. fs_additional_handlers:
  56.         dd      biosdisk_handler, biosdisk_enum_root
  57. ; add new handlers here
  58.         dd      0
  59.  
  60. endg
  61. file_system_lfn:
  62. ; in: ebx->fileinfo block
  63. ; operation codes:
  64. ; 0 : read file
  65. ; 1 : read folder
  66. ; 2 : create/rewrite file
  67. ; 3 : write/append to file
  68. ; 4 : set end of file
  69. ; 5 : get file/directory attributes structure
  70. ; 6 : set file/directory attributes structure
  71. ; 7 : start application
  72. ; 8 : delete file
  73. ; 9 : create directory
  74.  
  75. ; parse file name
  76.         lea     esi, [ebx+20]
  77.         lodsb
  78.         test    al, al
  79.         jnz     @f
  80.         mov     esi, [esi]
  81.         lodsb
  82. @@:
  83.         cmp     al, '/'
  84.         jz      .notcurdir
  85.         dec     esi
  86.         mov     ebp, esi
  87.         test    al, al
  88.         jnz     @f
  89.         xor     ebp, ebp
  90. @@:
  91.         mov     esi, [current_slot]
  92.         mov     esi, [esi+APPDATA.cur_dir]
  93.         jmp     .parse_normal
  94. .notcurdir:
  95.         cmp     byte [esi], 0
  96.         jz      .rootdir
  97.         call    process_replace_file_name
  98. .parse_normal:
  99.         cmp dword [ebx], 7
  100.         jne @F
  101.         mov edx, [ebx+4]
  102.         mov ebx, [ebx+8]
  103.         call fs_execute  ; esi+ebp, ebx, edx
  104.         mov [image_of_eax], eax
  105.         ret
  106. @@:
  107.         mov     edi, rootdirs-8
  108.         xor     ecx, ecx
  109.         push    esi
  110. .scan1:
  111.         pop     esi
  112.         add     edi, ecx
  113.         scasd
  114.         scasd
  115.         mov     cl, byte [edi]
  116.         test    cl, cl
  117.         jz      .notfound_try
  118.         inc     edi
  119.         push    esi
  120. @@:
  121.         lodsb
  122.         or      al, 20h
  123.         scasb
  124.         loopz   @b
  125.         jnz     .scan1
  126.         lodsb
  127.         cmp     al, '/'
  128.         jz      .found1
  129.         test    al, al
  130.         jnz     .scan1
  131.         pop     eax
  132. ; directory /xxx
  133. .maindir:
  134.         mov     esi, [edi+4]
  135. .maindir_noesi:
  136.         cmp     dword [ebx], 1
  137.         jnz     .access_denied
  138.         xor     eax, eax
  139.         mov     ebp, [ebx+12]                   ;ъюышўхёЄтю сыюъют фы  ёўшЄ√трэш 
  140.         mov     edx, [ebx+16]                   ;ъєфр чряшё√трЄ№ Ёєчхы№ЄрЄ
  141.     ;    add     edx, std_application_base_address
  142.         push    dword [ebx+4]   ; first block
  143.         mov     ebx, [ebx+8]    ; flags
  144. ; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
  145.         mov     edi, edx
  146.         push    ecx
  147.         mov     ecx, 32/4
  148.         rep     stosd
  149.         pop     ecx
  150.         mov     byte [edx], 1   ; version
  151. .maindir_loop:
  152.         call    esi
  153.         jc      .maindir_done
  154.         inc     dword [edx+8]
  155.         dec     dword [esp]
  156.         jns     .maindir_loop
  157.         dec     ebp
  158.         js      .maindir_loop
  159.         inc     dword [edx+4]
  160.         mov     dword [edi], 0x10       ; attributes: folder
  161.         mov     dword [edi+4], 1        ; name type: UNICODE
  162.         push    eax
  163.         xor     eax, eax
  164.         add     edi, 8
  165.         push    ecx
  166.         mov     ecx, 40/4-2
  167.         rep     stosd
  168.         pop     ecx
  169.         pop     eax
  170.         push    eax edx
  171. ; convert number in eax to decimal UNICODE string
  172.         push    edi
  173.         push    ecx
  174.         push    -'0'
  175.         mov     ecx, 10
  176. @@:
  177.         xor     edx, edx
  178.         div     ecx
  179.         push    edx
  180.         test    eax, eax
  181.         jnz     @b
  182. @@:
  183.         pop     eax
  184.         add     al, '0'
  185.         stosb
  186.         test    bl, 1           ; UNICODE name?
  187.         jz      .ansi2
  188.         mov     byte [edi], 0
  189.         inc     edi
  190. .ansi2:
  191.         test    al, al
  192.         jnz     @b
  193.         mov     byte [edi-1], 0
  194.         pop     ecx
  195.         pop     edi
  196. ; UNICODE name length is 520 bytes, ANSI - 264
  197.         add     edi, 520
  198.         test    bl, 1
  199.         jnz     @f
  200.         sub     edi, 520-264
  201. @@:
  202.         pop     edx eax
  203.         jmp     .maindir_loop
  204. .maindir_done:
  205.         pop     eax
  206.         mov     ebx, [edx+4]
  207.         xor     eax, eax
  208.         dec     ebp
  209.         js      @f
  210.         mov     al, ERROR_END_OF_FILE
  211. @@:
  212.         mov     [image_of_eax], eax
  213.         mov     [image_of_ebx], ebx
  214.         ret
  215. ; directory /
  216. .rootdir:
  217.         cmp     dword [ebx], 1  ; read folder?
  218.         jz      .readroot
  219. .access_denied:
  220.         mov     dword [image_of_eax], 10      ; access denied
  221.         ret
  222.  
  223. .readroot:
  224. ; virtual root folder - special handler
  225.         mov     esi, virtual_root_query
  226.         mov     ebp, [ebx+12]
  227.         mov     edx, [ebx+16]
  228.     ;    add     edx, std_application_base_address
  229.         push    dword [ebx+4]   ; first block
  230.         mov     ebx, [ebx+8]    ; flags
  231.         xor     eax, eax
  232. ; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
  233.         mov     edi, edx
  234.         mov     ecx, 32/4
  235.         rep     stosd
  236.         mov     byte [edx], 1   ; version
  237. .readroot_loop:
  238.         cmp     dword [esi], eax
  239.         jz      .readroot_done_static
  240.         call    dword [esi]
  241.         add     esi, 4
  242.         test    eax, eax
  243.         jnz     @f
  244. .readroot_next:
  245.         or      ecx, -1
  246.         xchg    esi, edi
  247.         repnz   scasb
  248.         xchg    esi, edi
  249.         jmp     .readroot_loop
  250. @@:
  251.         xor     eax, eax
  252.         inc     dword [edx+8]
  253.         dec     dword [esp]
  254.         jns     .readroot_next
  255.         dec     ebp
  256.         js      .readroot_next
  257.         inc     dword [edx+4]
  258.         mov     dword [edi], 0x10       ; attributes: folder
  259.         mov     dword [edi+4], ebx      ; name type: UNICODE
  260.         add     edi, 8
  261.         mov     ecx, 40/4-2
  262.         rep     stosd
  263.         push    edi
  264. @@:
  265.         lodsb
  266.         stosb
  267.         test    bl, 1
  268.         jz      .ansi
  269.         mov     byte [edi], 0
  270.         inc     edi
  271. .ansi:
  272.         test    eax, eax
  273.         jnz     @b
  274.         pop     edi
  275.         add     edi, 520
  276.         test    bl, 1
  277.         jnz     .readroot_loop
  278.         sub     edi, 520-264
  279.         jmp     .readroot_loop
  280. .readroot_done_static:
  281.         mov     esi, fs_additional_handlers-8
  282.         sub     esp, 16
  283. .readroot_ah_loop:
  284.         add     esi, 8
  285.         cmp     dword [esi], 0
  286.         jz      .readroot_done
  287.         xor     eax, eax
  288. .readroot_ah_loop2:
  289.         push    edi
  290.         lea     edi, [esp+4]
  291.         call    dword [esi+4]
  292.         pop     edi
  293.         test    eax, eax
  294.         jz      .readroot_ah_loop
  295.         inc     dword [edx+8]
  296.         dec     dword [esp+16]
  297.         jns     .readroot_ah_loop2
  298.         dec     ebp
  299.         js      .readroot_ah_loop2
  300.         push    eax
  301.         xor     eax, eax
  302.         inc     dword [edx+4]
  303.         mov     dword [edi], 0x10       ; attributes: folder
  304.         mov     dword [edi+4], ebx
  305.         add     edi, 8
  306.         mov     ecx, 40/4-2
  307.         rep     stosd
  308.         push    esi edi
  309.         lea     esi, [esp+12]
  310. @@:
  311.         lodsb
  312.         stosb
  313.         test    bl, 1
  314.         jz      .ansi3
  315.         mov     byte [edi], 0
  316.         inc     edi
  317. .ansi3:
  318.         test    al, al
  319.         jnz     @b
  320.         pop     edi esi eax
  321.         add     edi, 520
  322.         test    bl, 1
  323.         jnz     .readroot_ah_loop2
  324.         sub     edi, 520-264
  325.         jmp     .readroot_ah_loop2
  326. .readroot_done:
  327.         add     esp, 16
  328.         pop     eax
  329.         mov     ebx, [edx+4]
  330.         xor     eax, eax
  331.         dec     ebp
  332.         js      @f
  333.         mov     al, ERROR_END_OF_FILE
  334. @@:
  335.         mov     [image_of_eax], eax
  336.         mov     [image_of_ebx], ebx
  337.         ret
  338. .notfound_try:
  339.         mov     edi, fs_additional_handlers
  340. @@:
  341.         cmp     dword [edi], 0
  342.         jz      .notfound
  343.         call    dword [edi]
  344.         scasd
  345.         scasd
  346.         jmp     @b
  347. .notfound:
  348.         mov     dword [image_of_eax], ERROR_FILE_NOT_FOUND
  349.         and     dword [image_of_ebx], 0
  350.         ret
  351.  
  352. .notfounda:
  353.         cmp     edi, esp
  354.         jnz     .notfound
  355.         add     esp, 8
  356.         jmp     .notfound
  357.  
  358. .found1:
  359.         pop     eax
  360.         cmp     byte [esi], 0
  361.         jz      .maindir
  362. .found2:
  363. ; read partition number
  364.         xor     ecx, ecx
  365.         xor     eax, eax
  366. @@:
  367.         lodsb
  368.         cmp     al, '/'
  369.         jz      .done1
  370.         test    al, al
  371.         jz      .done1
  372.         sub     al, '0'
  373.         cmp     al, 9
  374.         ja      .notfounda
  375.         lea     ecx, [ecx*5]
  376.         lea     ecx, [ecx*2+eax]
  377.         jmp     @b
  378. .done1:
  379.         jecxz   .notfounda
  380.         test    al, al
  381.         jnz     @f
  382.         dec     esi
  383. @@:
  384.         cmp     byte [esi], 0
  385.         jnz     @f
  386.         test    ebp, ebp
  387.         jz      @f
  388.         mov     esi, ebp
  389.         xor     ebp, ebp
  390. @@:
  391. ; now [edi] contains handler address, ecx - partition number,
  392. ; esi points to ASCIIZ string - rest of name
  393.         jmp     dword [edi]
  394.  
  395. ; handlers for devices
  396. ; in: ecx = 0 => query virtual directory /xxx
  397. ; in: ecx = partition number
  398. ;     esi -> relative (for device) name
  399. ;     ebx -> fileinfo
  400. ;     ebp = 0 or pointer to rest of name from folder addressed by esi
  401. ; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
  402.  
  403. fs_OnRamdisk:
  404.         cmp     ecx, 1
  405.         jnz     file_system_lfn.notfound
  406.         mov     eax, [ebx]
  407.         cmp     eax, fs_NumRamdiskServices
  408.         jae     .not_impl
  409.         mov     ecx, [ebx+12]
  410.         mov     edx, [ebx+16]
  411.    ;     add     edx, std_application_base_address
  412.         add     ebx, 4
  413.         call    dword [fs_RamdiskServices + eax*4]
  414.         mov     [image_of_eax], eax
  415.         mov     [image_of_ebx], ebx
  416.         ret
  417. .not_impl:
  418.         mov     dword [image_of_eax], 2       ; not implemented
  419.         ret
  420.  
  421. fs_NotImplemented:
  422.         mov     eax, 2
  423.         ret
  424.  
  425. fs_RamdiskServices:
  426.         dd      fs_RamdiskRead
  427.         dd      fs_RamdiskReadFolder
  428.         dd      fs_RamdiskRewrite
  429.         dd      fs_RamdiskWrite
  430.         dd      fs_RamdiskSetFileEnd
  431.         dd      fs_RamdiskGetFileInfo
  432.         dd      fs_RamdiskSetFileInfo
  433.         dd      0
  434.         dd      fs_RamdiskDelete
  435.         dd      fs_RamdiskCreateFolder
  436. fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
  437.  
  438. fs_OnHd0:
  439.         call    reserve_hd1
  440.         mov     [hdbase], 0x1F0
  441.         mov     [hdid], 0
  442.         push    1
  443.         jmp     fs_OnHd
  444. fs_OnHd1:
  445.         call    reserve_hd1
  446.         mov     [hdbase], 0x1F0
  447.         mov     [hdid], 0x10
  448.         push    2
  449.         jmp     fs_OnHd
  450. fs_OnHd2:
  451.         call    reserve_hd1
  452.         mov     [hdbase], 0x170
  453.         mov     [hdid], 0
  454.         push    3
  455.         jmp     fs_OnHd
  456. fs_OnHd3:
  457.         call    reserve_hd1
  458.         mov     [hdbase], 0x170
  459.         mov     [hdid], 0x10
  460.         push    4
  461. fs_OnHd:
  462.         call    reserve_hd_channel
  463.         pop     eax
  464.         mov     [hdpos], eax
  465.         cmp     ecx, 0x100
  466.         jae     fs_OnHdAndBd.nf
  467.         cmp     cl, [DRIVE_DATA+1+eax]
  468. fs_OnHdAndBd:
  469.         jbe     @f
  470. .nf:
  471.         call    free_hd_channel
  472.         and     [hd1_status], 0
  473.         mov     dword [image_of_eax], 5       ; not found
  474.         ret
  475. @@:
  476.         mov     [known_part], ecx ;     mov     [fat32part], ecx
  477.         push    ebx esi
  478.         call    choice_necessity_partition_1
  479.         pop     esi ebx
  480.         mov     ecx, [ebx+12]
  481.         mov     edx, [ebx+16]
  482.     ;    add     edx, std_application_base_address
  483.         mov     eax, [ebx]
  484.         cmp     eax, fs_NumHdServices
  485.         jae     .not_impl
  486.         add     ebx, 4
  487.         call    dword [fs_HdServices + eax*4]
  488.         call    free_hd_channel
  489.         and     [hd1_status], 0
  490.         mov     [image_of_eax], eax
  491.         mov     [image_of_ebx], ebx
  492.         ret
  493. .not_impl:
  494.         call    free_hd_channel
  495.         and     [hd1_status], 0
  496.         mov     dword [image_of_eax], 2       ; not implemented
  497.         ret
  498.  
  499. fs_HdServices:
  500.         dd      fs_HdRead
  501.         dd      fs_HdReadFolder
  502.         dd      fs_HdRewrite
  503.         dd      fs_HdWrite
  504.         dd      fs_HdSetFileEnd
  505.         dd      fs_HdGetFileInfo
  506.         dd      fs_HdSetFileInfo
  507.         dd      0
  508.         dd      fs_HdDelete
  509.         dd      fs_HdCreateFolder
  510. fs_NumHdServices = ($ - fs_HdServices)/4
  511.  
  512.  
  513. fs_HasRamdisk:
  514.         mov     al, 1   ; we always have ramdisk
  515.         ret
  516.  
  517. fs_HasFloppy:
  518.         cmp     byte [DRIVE_DATA], 0
  519.         setnz   al
  520.         ret
  521.  
  522. fs_HasHd0:
  523.         mov     al, [DRIVE_DATA+1]
  524.         and     al, 11000000b
  525.         cmp     al, 01000000b
  526.         setz    al
  527.         ret
  528. fs_HasHd1:
  529.         mov     al, [DRIVE_DATA+1]
  530.         and     al, 00110000b
  531.         cmp     al, 00010000b
  532.         setz    al
  533.         ret
  534. fs_HasHd2:
  535.         mov     al, [DRIVE_DATA+1]
  536.         and     al, 00001100b
  537.         cmp     al, 00000100b
  538.         setz    al
  539.         ret
  540. fs_HasHd3:
  541.         mov     al, [DRIVE_DATA+1]
  542.         and     al, 00000011b
  543.         cmp     al, 00000001b
  544.         setz    al
  545.         ret
  546.  
  547. ;*******************************************************
  548. fs_HasCd0:
  549.         mov     al, [DRIVE_DATA+1]
  550.         and     al, 11000000b
  551.         cmp     al, 10000000b
  552.         setz    al
  553.         ret
  554. fs_HasCd1:
  555.         mov     al, [DRIVE_DATA+1]
  556.         and     al, 00110000b
  557.         cmp     al, 00100000b
  558.         setz    al
  559.         ret
  560. fs_HasCd2:
  561.         mov     al, [DRIVE_DATA+1]
  562.         and     al, 00001100b
  563.         cmp     al, 00001000b
  564.         setz    al
  565.         ret
  566. fs_HasCd3:
  567.         mov     al, [DRIVE_DATA+1]
  568.         and     al, 00000011b
  569.         cmp     al, 00000010b
  570.         setz    al
  571.         ret
  572. ;*******************************************************
  573.  
  574. ; fs_NextXXX functions:
  575. ; in: eax = partition number, from which start to scan
  576. ; out: CF=1 => no more partitions
  577. ;      CF=0 => eax=next partition number
  578.  
  579. fs_NextRamdisk:
  580. ; we always have /rd/1
  581.         test    eax, eax
  582.         stc
  583.         jnz     @f
  584.         mov     al, 1
  585.         clc
  586. @@:
  587.         ret
  588.  
  589. fs_NextFloppy:
  590. ; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
  591.         test    byte [DRIVE_DATA], 0xF0
  592.         jz      .no1
  593.         test    eax, eax
  594.         jnz     .no1
  595.         inc     eax
  596.         ret     ; CF cleared
  597. .no1:
  598.         test    byte [DRIVE_DATA], 0x0F
  599.         jz      .no2
  600.         cmp     al, 2
  601.         jae     .no2
  602.         mov     al, 2
  603.         clc
  604.         ret
  605. .no2:
  606.         stc
  607.         ret
  608.  
  609. ; on hdx, we have partitions from 1 to [0x40002+x]
  610. fs_NextHd0:
  611.         push    0
  612.         jmp     fs_NextHd
  613. fs_NextHd1:
  614.         push    1
  615.         jmp     fs_NextHd
  616. fs_NextHd2:
  617.         push    2
  618.         jmp     fs_NextHd
  619. fs_NextHd3:
  620.         push    3
  621. fs_NextHd:
  622.         pop     ecx
  623.         movzx   ecx, byte [DRIVE_DATA+2+ecx]
  624.         cmp     eax, ecx
  625.         jae     fs_NextFloppy.no2
  626.         inc     eax
  627.         clc
  628.         ret
  629.  
  630. ;*******************************************************
  631. fs_NextCd:
  632. ; we always have /cdX/1
  633.         test    eax, eax
  634.         stc
  635.         jnz     @f
  636.         mov     al, 1
  637.         clc
  638. @@:
  639.         ret
  640. ;*******************************************************
  641.  
  642. ; Additional FS handlers.
  643. ; This handler gets the control each time when fn 70 is called
  644. ; with unknown item of root subdirectory.
  645. ; in: esi -> name
  646. ;     ebp = 0 or rest of name relative to esi
  647. ; out: if the handler processes path, he must not return in file_system_lfn,
  648. ;      but instead pop return address and return directly to the caller
  649. ;      otherwise simply return
  650.  
  651. ; here we test for /bd<N>/... - BIOS disks
  652. biosdisk_handler:
  653.         cmp     [NumBiosDisks], 0
  654.         jz      .ret
  655.         mov     al, [esi]
  656.         or      al, 20h
  657.         cmp     al, 'b'
  658.         jnz     .ret
  659.         mov     al, [esi+1]
  660.         or      al, 20h
  661.         cmp     al, 'd'
  662.         jnz     .ret
  663.         push    esi
  664.         inc     esi
  665.         inc     esi
  666.         cmp     byte [esi], '0'
  667.         jb      .ret2
  668.         cmp     byte [esi], '9'
  669.         ja      .ret2
  670.         xor     edx, edx
  671. @@:
  672.         lodsb
  673.         test    al, al
  674.         jz      .ok
  675.         cmp     al, '/'
  676.         jz      .ok
  677.         sub     al, '0'
  678.         cmp     al, 9
  679.         ja      .ret2
  680.         lea     edx, [edx*5]
  681.         lea     edx, [edx*2+eax]
  682.         jmp     @b
  683. .ret2:
  684.         pop     esi
  685. .ret:
  686.         ret
  687. .ok:
  688.         cmp     al, '/'
  689.         jz      @f
  690.         dec     esi
  691. @@:
  692.         add     dl, 80h
  693.         xor     ecx, ecx
  694. @@:
  695.         cmp     dl, [BiosDisksData+ecx*4]
  696.         jz      .ok2
  697.         inc     ecx
  698.         cmp     ecx, [NumBiosDisks]
  699.         jb      @b
  700.         jmp     .ret2
  701. .ok2:
  702.         add     esp, 8
  703.         test    al, al
  704.         jnz     @f
  705.         mov     esi, fs_BdNext
  706.         jmp     file_system_lfn.maindir_noesi
  707. @@:
  708.         push    ecx
  709.         push    fs_OnBd
  710.         mov     edi, esp
  711.         jmp     file_system_lfn.found2
  712.  
  713. fs_BdNext:
  714.         cmp     eax, [BiosDiskPartitions+ecx*4]
  715.         inc     eax
  716.         cmc
  717.         ret
  718.  
  719. fs_OnBd:
  720.         pop     edx edx
  721. ; edx = disk number, ecx = partition number
  722. ; esi+ebp = name
  723.         call    reserve_hd1
  724.         add     edx, 0x80
  725.         mov     [hdpos], edx
  726.         cmp     ecx, [BiosDiskPartitions+(edx-0x80)*4]
  727.         jmp     fs_OnHdAndBd
  728.  
  729. ; This handler is called when virtual root is enumerated
  730. ; and must return all items which can be handled by this.
  731. ; It is called several times, first time with eax=0
  732. ; in: eax = 0 for first call, previously returned value for subsequent calls
  733. ; out: eax = 0 => no more items
  734. ;      eax != 0 => buffer pointed to by edi contains name of item
  735.  
  736. ; here we enumerate existing BIOS disks /bd<N>
  737. biosdisk_enum_root:
  738.         cmp     eax, [NumBiosDisks]
  739.         jae     .end
  740.         push    eax
  741.         movzx   eax, byte [BiosDisksData+eax*4]
  742.         sub     al, 80h
  743.         push    eax
  744.         mov     al, 'b'
  745.         stosb
  746.         mov     al, 'd'
  747.         stosb
  748.         pop     eax
  749.         cmp     al, 10
  750.         jae     .big
  751.         add     al, '0'
  752.         stosb
  753.         mov     byte [edi], 0
  754.         pop     eax
  755.         inc     eax
  756.         ret
  757. .end:
  758.         xor     eax, eax
  759.         ret
  760. .big:
  761.         push    ecx edx
  762.         push    -'0'
  763.         mov     ecx, 10
  764. @@:
  765.         xor     edx, edx
  766.         div     ecx
  767.         push    edx
  768.         test    eax, eax
  769.         jnz     @b
  770.         xchg    eax, edx
  771. @@:
  772.         pop     eax
  773.         add     al, '0'
  774.         stosb
  775.         jnz     @b
  776.         pop     edx ecx
  777.         pop     eax
  778.         inc     eax
  779.         ret
  780.  
  781. process_replace_file_name:
  782.         mov     ebp, [full_file_name_table]
  783.         mov     edi, [full_file_name_table.size]
  784.         dec     edi
  785.         shl     edi, 7
  786.         add     edi, ebp
  787. .loop:
  788.         cmp     edi, ebp
  789.         jb      .notfound
  790.         push    esi edi
  791. @@:
  792.         cmp     byte [edi], 0
  793.         jz      .dest_done
  794.         lodsb
  795.         test    al, al
  796.         jz      .cont
  797.         or      al, 20h
  798.         scasb
  799.         jz      @b
  800.         jmp     .cont
  801. .dest_done:
  802.         cmp     byte [esi], 0
  803.         jz      .found
  804.         cmp     byte [esi], '/'
  805.         jnz     .cont
  806.         inc     esi
  807.         jmp     .found
  808. .cont:
  809.         pop     edi esi
  810.         sub     edi, 128
  811.         jmp     .loop
  812. .found:
  813.         pop     edi eax
  814.         mov     ebp, esi
  815.         cmp     byte [esi], 0
  816.         lea     esi, [edi+64]
  817.         jnz     .ret
  818. .notfound:
  819.         xor     ebp, ebp
  820. .ret:
  821.         ret
  822.  
  823. sys_current_directory:
  824. ;       mov     esi, [current_slot]
  825. ;       mov     esi, [esi+APPDATA.cur_dir]
  826. ;       mov     edx, esi
  827.  
  828. ;get length string of appdata.cur_dir
  829.         mov     eax, [current_slot]
  830.         mov     edi, [eax+APPDATA.cur_dir]
  831.  
  832.         dec     ebx
  833.         jz      .set
  834.         dec     ebx
  835.         jz      .get
  836.         ret
  837. .get:
  838. ; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
  839. ; for our code: ebx->buffer,ecx=len
  840. max_cur_dir     equ     0x1000
  841.  
  842.         mov     ebx,edi
  843.  
  844.         push    ecx
  845.         push    edi
  846.  
  847.         xor     eax,eax
  848.         mov     ecx,max_cur_dir
  849.  
  850.         repne   scasb           ;find zerro at and string
  851.         jnz     .error          ; no zero in cur_dir: internal error, should not happen
  852.  
  853.         sub     edi,ebx         ;lenght for copy
  854.         inc     edi
  855.         mov     [esp+32+8],edi  ;return in eax
  856.  
  857.         cmp     edx, edi
  858.         jbe     @f
  859.         mov     edx, edi
  860. @@:
  861. ;source string
  862.         pop     esi
  863. ;destination string
  864.         pop     edi
  865.         cmp     edx, 1
  866.         jbe     .ret
  867.  
  868.         mov     al,'/'          ;start string with '/'
  869.         stosb
  870.         mov     ecx,edx
  871.         rep     movsb           ;copy string
  872. .ret:   ret
  873.  
  874. .error: add     esp,8
  875.         or      dword [esp+32],-1       ;error not found zerro at string ->[eax+APPDATA.cur_dir]
  876.         ret
  877. .set:
  878. ; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
  879. ; for our code: ebx->string to set
  880. ; use generic resolver with APPDATA.cur_dir as destination
  881.         push    max_cur_dir     ;0x1000
  882.         push    edi     ;destination
  883.         mov     ebx,ecx
  884.         call    get_full_file_name
  885.         ret
  886.  
  887. ; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
  888. ; destroys all registers except ebp,esp
  889. get_full_file_name:
  890.         push    ebp
  891.         mov     esi, [current_slot]
  892.         mov     esi, [esi+APPDATA.cur_dir]
  893.         mov     edx, esi
  894. @@:
  895.         inc     esi
  896.         cmp     byte [esi-1], 0
  897.         jnz     @b
  898.         dec     esi
  899.         cmp     byte [ebx], '/'
  900.         jz      .set_absolute
  901. ; string gives relative path
  902.         mov     edi, [esp+8]    ; destination
  903. .relative:
  904.         cmp     byte [ebx], 0
  905.         jz      .set_ok
  906.         cmp     word [ebx], '.'
  907.         jz      .set_ok
  908.         cmp     word [ebx], './'
  909.         jnz     @f
  910.         add     ebx, 2
  911.         jmp     .relative
  912. @@:
  913.         cmp     word [ebx], '..'
  914.         jnz     .doset_relative
  915.         cmp     byte [ebx+2], 0
  916.         jz      @f
  917.         cmp     byte [ebx+2], '/'
  918.         jnz     .doset_relative
  919. @@:
  920.         dec     esi
  921.         cmp     byte [esi], '/'
  922.         jnz     @b
  923.         add     ebx, 3
  924.         jmp     .relative
  925. .set_ok:
  926.         cmp     edx, edi        ; is destination equal to APPDATA.cur_dir?
  927.         jz      .set_ok.cur_dir
  928.         sub     esi, edx
  929.         cmp     esi, [esp+12]
  930.         jb      .set_ok.copy
  931. .fail:
  932.         mov     byte [edi], 0
  933.         xor     eax, eax        ; fail
  934.         pop     ebp
  935.         ret     8
  936. .set_ok.copy:
  937.         mov     ecx, esi
  938.         mov     esi, edx
  939.         rep     movsb
  940.         mov     byte [edi], 0
  941. .ret.ok:
  942.         mov     al, 1   ; ok
  943.         pop     ebp
  944.         ret     8
  945. .set_ok.cur_dir:
  946.         mov     byte [esi], 0
  947.         jmp     .ret.ok
  948. .doset_relative:
  949.         cmp     edx, edi
  950.         jz      .doset_relative.cur_dir
  951.         sub     esi, edx
  952.         cmp     esi, [esp+12]
  953.         jae     .fail
  954.         mov     ecx, esi
  955.         mov     esi, edx
  956.         mov     edx, edi
  957.         rep     movsb
  958.         jmp     .doset_relative.copy
  959. .doset_relative.cur_dir:
  960.         mov     edi, esi
  961. .doset_relative.copy:
  962.         add     edx, [esp+12]
  963.         mov     byte [edi], '/'
  964.         inc     edi
  965.         cmp     edi, edx
  966.         jae     .overflow
  967. @@:
  968.         mov     al, [ebx]
  969.         inc     ebx
  970.         stosb
  971.         test    al, al
  972.         jz      .ret.ok
  973.         cmp     edi, edx
  974.         jb      @b
  975. .overflow:
  976.         dec     edi
  977.         jmp     .fail
  978. .set_absolute:
  979.         lea     esi, [ebx+1]
  980.         call    process_replace_file_name
  981.         mov     edi, [esp+8]
  982.         mov     edx, [esp+12]
  983.         add     edx, edi
  984. .set_copy:
  985.         lodsb
  986.         stosb
  987.         test    al, al
  988.         jz      .set_part2
  989. .set_copy_cont:
  990.         cmp     edi, edx
  991.         jb      .set_copy
  992.         jmp     .overflow
  993. .set_part2:
  994.         mov     esi, ebp
  995.         xor     ebp, ebp
  996.         test    esi, esi
  997.         jz      .ret.ok
  998.         mov     byte [edi-1], '/'
  999.         jmp     .set_copy_cont
  1000.  
  1001. ; ===============  moved from fs/iso9660.inc
  1002.  
  1003. char_todown:
  1004. ; convert character to uppercase, using cp866 encoding
  1005. ; in: al=symbol
  1006. ; out: al=converted symbol
  1007.         cmp     al, 'A'
  1008.         jb      .ret
  1009.         cmp     al, 'Z'
  1010.         jbe     .az
  1011.         cmp     al, 'А'
  1012.         jb      .ret
  1013.         cmp     al, 'Р'
  1014.         jb      .rus1
  1015.         cmp     al, 'Я'
  1016.         ja      .ret
  1017. ; 0x90-0x9F -> 0xE0-0xEF
  1018.         add     al, 'р'-'Р'
  1019. .ret:
  1020.         ret
  1021. .rus1:
  1022. ; 0x80-0x8F -> 0xA0-0xAF
  1023. .az:
  1024.         add     al, 0x20
  1025.         ret
  1026.  
  1027. uni2ansi_char:
  1028. ; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
  1029. ; in: ax=UNICODE character
  1030. ; out: al=converted ANSI character
  1031.         cmp     ax, 0x80
  1032.         jb      .ascii
  1033.         cmp     ax, 0x401
  1034.         jz      .yo1
  1035.         cmp     ax, 0x451
  1036.         jz      .yo2
  1037.         cmp     ax, 0x410
  1038.         jb      .unk
  1039.         cmp     ax, 0x440
  1040.         jb      .rus1
  1041.         cmp     ax, 0x450
  1042.         jb      .rus2
  1043. .unk:
  1044.         mov     al, '_'
  1045.         jmp     .doit
  1046. .yo1:
  1047.         mov     al, 'Ё'
  1048.         jmp     .doit
  1049. .yo2:
  1050.         mov     al, 'ё'
  1051.         jmp     .doit
  1052. .rus1:
  1053. ; 0x410-0x43F -> 0x80-0xAF
  1054.         add     al, 0x70
  1055.         jmp     .doit
  1056. .rus2:
  1057. ; 0x440-0x44F -> 0xE0-0xEF
  1058.         add     al, 0xA0
  1059. .ascii:
  1060. .doit:
  1061.         ret
  1062.