Subversion Repositories Kolibri OS

Rev

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