Subversion Repositories Kolibri OS

Rev

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