Subversion Repositories Kolibri OS

Rev

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

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