Subversion Repositories Kolibri OS

Rev

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