Subversion Repositories Kolibri OS

Rev

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

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