Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 465 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. ; System function 70 - files with long names (LFN)
  10. ; diamond, 2006
  11.  
  12. iglobal
  13. ; in this table names must be in lowercase
  14. rootdirs:
  15.         db      2,'rd'
  16.         dd      fs_OnRamdisk
  17.         dd      fs_NextRamdisk
  18.         db      7,'ramdisk'
  19.         dd      fs_OnRamdisk
  20.         dd      fs_NextRamdisk
  21.         db      2,'fd'
  22.         dd      fs_OnFloppy
  23.         dd      fs_NextFloppy
  24.         db      10,'floppydisk'
  25.         dd      fs_OnFloppy
  26.         dd      fs_NextFloppy
  27.         db      3,'hd0'
  28.         dd      fs_OnHd0
  29.         dd      fs_NextHd0
  30.         db      3,'hd1'
  31.         dd      fs_OnHd1
  32.         dd      fs_NextHd1
  33.         db      3,'hd2'
  34.         dd      fs_OnHd2
  35.         dd      fs_NextHd2
  36.         db      3,'hd3'
  37.         dd      fs_OnHd3
  38.         dd      fs_NextHd3
  39. ;**********************************************
  40.         db      3,'cd0'
  41.         dd      fs_OnCd0
  42.         dd      fs_NextCd
  43.         db      3,'cd1'
  44.         dd      fs_OnCd1
  45.         dd      fs_NextCd
  46.         db      3,'cd2'
  47.         dd      fs_OnCd2
  48.         dd      fs_NextCd
  49.         db      3,'cd3'
  50.         dd      fs_OnCd3
  51.         dd      fs_NextCd
  52. ;***********************************************
  53.         db      0
  54.  
  55.  
  56. virtual_root_query:
  57.         dd      fs_HasRamdisk
  58.         db      'rd',0
  59.         dd      fs_HasFloppy
  60.         db      'fd',0
  61.         dd      fs_HasHd0
  62.         db      'hd0',0
  63.         dd      fs_HasHd1
  64.         db      'hd1',0
  65.         dd      fs_HasHd2
  66.         db      'hd2',0
  67.         dd      fs_HasHd3
  68.         db      'hd3',0
  69. ;**********************************************
  70.         dd      fs_HasCd0
  71.         db      'cd0',0
  72.         dd      fs_HasCd1
  73.         db      'cd1',0
  74.         dd      fs_HasCd2
  75.         db      'cd2',0
  76.         dd      fs_HasCd3
  77.         db      'cd3',0
  78. ;**********************************************
  79.         dd      0
  80. endg
  81.  
  82. file_system_lfn:
  83. ; in: eax->fileinfo block
  84. ; operation codes:
  85. ; 0 : read file
  86. ; 1 : read folder
  87. ; 2 : create/rewrite file
  88. ; 3 : write/append to file
  89. ; 4 : set end of file
  90. ; 5 : get file/directory attributes structure
  91. ; 6 : set file/directory attributes structure
  92. ; 7 : start application
  93. ; 8 : delete file
  94. ; 9 : create directory
  95.  
  96.    ;     add     eax, std_application_base_address
  97. ; parse file name
  98.         xchg    ebx, eax
  99.         lea     esi, [ebx+20]
  100.         mov     ebp, esi        ; for 'start app' function full path must be known
  101.         lodsb
  102.         test    al, al
  103.         jnz     @f
  104.         mov     esi, [esi]
  105.   ;      add     esi, std_application_base_address
  106.         mov     ebp, esi
  107.         lodsb
  108. @@:
  109.         cmp dword [ebx], 7
  110.         jne @F
  111.         mov edx, [ebx+4]
  112.         mov ebx, [ebx+8]
  113.         test ebx, ebx
  114.         jz .l1
  115.     ;    add ebx, new_app_base
  116. .l1:
  117.         call fs_execute  ; ebp, ebx, edx
  118.         mov [esp+36], eax
  119.         ret
  120. @@:
  121.         cmp     al, '/'
  122.         jz      @f
  123. .notfound:
  124.         mov     dword [esp+36], 5       ; file not found
  125.         ret
  126. @@:
  127.         cmp     byte [esi], 0
  128.         jz      .rootdir
  129.         mov     edi, rootdirs-8
  130.         xor     ecx, ecx
  131.         push    esi
  132. .scan1:
  133.         pop     esi
  134.         add     edi, ecx
  135.         scasd
  136.         scasd
  137.         mov     cl, byte [edi]
  138.         jecxz   .notfound
  139.         inc     edi
  140.         push    esi
  141. @@:
  142.         lodsb
  143.         or      al, 20h
  144.         scasb
  145.         loopz   @b
  146.         jnz     .scan1
  147.         lodsb
  148.         cmp     al, '/'
  149.         jz      .found1
  150.         test    al, al
  151.         jnz     .scan1
  152.         pop     eax
  153. ; directory /xxx
  154. .maindir:
  155.         cmp     dword [ebx], 1
  156.         jnz     .access_denied
  157.         xor     eax, eax
  158.         mov     ebp, [ebx+12]
  159.         mov     edx, [ebx+16]
  160.     ;    add     edx, std_application_base_address
  161.         push    dword [ebx+4]   ; first block
  162.         mov     ebx, [ebx+8]    ; flags
  163.         mov     esi, [edi+4]
  164. ; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
  165.         mov     edi, edx
  166.         mov     ecx, 32/4
  167.         rep     stosd
  168.         mov     byte [edx], 1   ; version
  169. .maindir_loop:
  170.         call    esi
  171.         jc      .maindir_done
  172.         inc     dword [edx+8]
  173.         dec     dword [esp]
  174.         jns     .maindir_loop
  175.         dec     ebp
  176.         js      .maindir_loop
  177.         inc     dword [edx+4]
  178.         mov     dword [edi], 0x10       ; attributes: folder
  179.         mov     dword [edi+4], 1        ; name type: UNICODE
  180.         push    eax
  181.         xor     eax, eax
  182.         add     edi, 8
  183.         mov     ecx, 40/4-2
  184.         rep     stosd
  185.         pop     eax
  186.         push    eax edx
  187. ; convert number in eax to decimal UNICODE string
  188.         push    edi
  189.         push    -'0'
  190.         mov     cl, 10
  191. @@:
  192.         xor     edx, edx
  193.         div     ecx
  194.         push    edx
  195.         test    eax, eax
  196.         jnz     @b
  197. @@:
  198.         pop     eax
  199.         add     al, '0'
  200.         stosb
  201.         test    bl, 1           ; UNICODE name?
  202.         jz      .ansi2
  203.         mov     byte [edi], 0
  204.         inc     edi
  205. .ansi2:
  206.         test    al, al
  207.         jnz     @b
  208.         mov     byte [edi-1], 0
  209.         pop     edi
  210. ; UNICODE name length is 520 bytes, ANSI - 264
  211.         add     edi, 520
  212.         test    bl, 1
  213.         jnz     @f
  214.         sub     edi, 520-264
  215. @@:
  216.         pop     edx eax
  217.         jmp     .maindir_loop
  218. .maindir_done:
  219.         pop     eax
  220.         mov     ebx, [edx+4]
  221.         xor     eax, eax
  222.         dec     ebp
  223.         js      @f
  224.         mov     al, ERROR_END_OF_FILE
  225. @@:
  226.         mov     [esp+36], eax
  227.         mov     [esp+24], ebx
  228.         ret
  229. ; directory /
  230. .rootdir:
  231.         cmp     dword [ebx], 1  ; read folder?
  232.         jz      .readroot
  233. .access_denied:
  234.         mov     dword [esp+36], 10      ; access denied
  235.         ret
  236.  
  237. .readroot:
  238. ; virtual root folder - special handler
  239.         mov     esi, virtual_root_query
  240.         mov     ebp, [ebx+12]
  241.         mov     edx, [ebx+16]
  242.     ;    add     edx, std_application_base_address
  243.         push    dword [ebx+4]   ; first block
  244.         mov     ebx, [ebx+8]    ; flags
  245.         xor     eax, eax
  246. ; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
  247.         mov     edi, edx
  248.         mov     ecx, 32/4
  249.         rep     stosd
  250.         mov     byte [edx], 1   ; version
  251. .readroot_loop:
  252.         cmp     dword [esi], eax
  253.         jz      .readroot_done
  254.         call    dword [esi]
  255.         add     esi, 4
  256.         test    eax, eax
  257.         jnz     @f
  258. .readroot_next:
  259.         or      ecx, -1
  260.         xchg    esi, edi
  261.         repnz   scasb
  262.         xchg    esi, edi
  263.         jmp     .readroot_loop
  264. @@:
  265.         xor     eax, eax
  266.         inc     dword [edx+8]
  267.         dec     dword [esp]
  268.         jns     .readroot_next
  269.         dec     ebp
  270.         js      .readroot_next
  271.         inc     dword [edx+4]
  272.         mov     dword [edi], 0x10       ; attributes: folder
  273.         mov     dword [edi+4], 1        ; name type: UNICODE
  274.         add     edi, 8
  275.         mov     ecx, 40/4-2
  276.         rep     stosd
  277.         push    edi
  278. @@:
  279.         lodsb
  280.         stosb
  281.         test    bl, 1
  282.         jz      .ansi
  283.         mov     byte [edi], 0
  284.         inc     edi
  285. .ansi:
  286.         test    eax, eax
  287.         jnz     @b
  288.         pop     edi
  289.         add     edi, 520
  290.         test    bl, 1
  291.         jnz     .readroot_loop
  292.         sub     edi, 520-264
  293.         jmp     .readroot_loop
  294. .readroot_done:
  295.         pop     eax
  296.         mov     ebx, [edx+4]
  297.         xor     eax, eax
  298.         dec     ebp
  299.         js      @f
  300.         mov     al, ERROR_END_OF_FILE
  301. @@:
  302.         mov     [esp+36], eax
  303.         mov     [esp+24], ebx
  304.         ret
  305.  
  306. .found1:
  307.         pop     eax
  308.         cmp     byte [esi], 0
  309.         jz      .maindir
  310. ; read partition number
  311.         xor     ecx, ecx
  312.         xor     eax, eax
  313. @@:
  314.         lodsb
  315.         cmp     al, '/'
  316.         jz      .done1
  317.         test    al, al
  318.         jz      .done1
  319.         sub     al, '0'
  320.         cmp     al, 9
  321.         ja      .notfound
  322.         imul    ecx, 10
  323.         add     ecx, eax
  324.         jmp     @b
  325. .done1:
  326.         test    ecx, ecx
  327.         jz      .notfound
  328.         test    al, al
  329.         jnz     @f
  330.         dec     esi
  331. @@:
  332. ; now [edi] contains handler address, ecx - partition number,
  333. ; esi points to ASCIIZ string - rest of name
  334.         jmp     dword [edi]
  335.  
  336. ; handlers for devices
  337. ; in: ecx = 0 => query virtual directory /xxx
  338. ; in: ecx = partition number
  339. ;     esi -> relative (for device) name
  340. ;     ebx -> fileinfo
  341. ; out: [esp+36]=image of eax, [esp+24]=image of ebx
  342.  
  343. fs_OnRamdisk:
  344.         cmp     ecx, 1
  345.         jnz     file_system_lfn.notfound
  346.         mov     eax, [ebx]
  347.         cmp     eax, fs_NumRamdiskServices
  348.         jae     .not_impl
  349.         mov     ecx, [ebx+12]
  350.         mov     edx, [ebx+16]
  351.    ;     add     edx, std_application_base_address
  352.         add     ebx, 4
  353.         call    dword [fs_RamdiskServices + eax*4]
  354.         mov     [esp+36], eax
  355.         mov     [esp+24], ebx
  356.         ret
  357. .not_impl:
  358.         mov     dword [esp+36], 2       ; not implemented
  359.         ret
  360.  
  361. fs_NotImplemented:
  362.         mov     eax, 2
  363.         ret
  364.  
  365. fs_RamdiskServices:
  366.         dd      fs_RamdiskRead
  367.         dd      fs_RamdiskReadFolder
  368.         dd      fs_RamdiskRewrite
  369.         dd      fs_RamdiskWrite
  370.         dd      fs_RamdiskSetFileEnd
  371.         dd      fs_RamdiskGetFileInfo
  372.         dd      fs_RamdiskSetFileInfo
  373.         dd      0 ;fs_RamdiskExecute
  374.         dd      fs_RamdiskDelete
  375.         dd      fs_RamdiskCreateFolder
  376. fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
  377.  
  378. fs_OnFloppy:
  379.         cmp     ecx, 2
  380.         ja      file_system_lfn.notfound
  381.         mov     eax, [ebx]
  382.         cmp     eax, fs_NumFloppyServices
  383.         jae     fs_OnRamdisk.not_impl
  384.         call    reserve_flp
  385.         mov     [flp_number], cl
  386.         mov     ecx, [ebx+12]
  387.         mov     edx, [ebx+16]
  388.    ;     add     edx, std_application_base_address
  389.         add     ebx, 4
  390.         call    dword [fs_FloppyServices + eax*4]
  391.         and     [flp_status], 0
  392.         mov     [esp+36], eax
  393.         mov     [esp+24], ebx
  394.         ret
  395.  
  396. fs_FloppyServices:
  397.         dd      fs_FloppyRead
  398.         dd      fs_FloppyReadFolder
  399.         dd      fs_FloppyRewrite
  400.         dd      fs_FloppyWrite
  401.         dd      fs_FloppySetFileEnd
  402.         dd      fs_FloppyGetFileInfo
  403.         dd      fs_FloppySetFileInfo
  404.         dd      0 ;fs_FloppyExecute
  405.         dd      fs_FloppyDelete
  406.         dd      fs_FloppyCreateFolder
  407. fs_NumFloppyServices = ($ - fs_FloppyServices)/4
  408.  
  409. fs_OnHd0:
  410.         call    reserve_hd1
  411.         mov     [hdbase], 0x1F0
  412.         mov     [hdid], 0
  413.         push    1
  414.         jmp     fs_OnHd
  415. fs_OnHd1:
  416.         call    reserve_hd1
  417.         mov     [hdbase], 0x1F0
  418.         mov     [hdid], 0x10
  419.         push    2
  420.         jmp     fs_OnHd
  421. fs_OnHd2:
  422.         call    reserve_hd1
  423.         mov     [hdbase], 0x170
  424.         mov     [hdid], 0
  425.         push    3
  426.         jmp     fs_OnHd
  427. fs_OnHd3:
  428.         call    reserve_hd1
  429.         mov     [hdbase], 0x170
  430.         mov     [hdid], 0x10
  431.         push    4
  432. fs_OnHd:
  433.         call    reserve_hd_channel
  434.         pop     eax
  435.         mov     [hdpos], eax
  436.         cmp     ecx, 0x100
  437.         jae     .nf
  438.         cmp     cl, [DRIVE_DATA+1+eax]
  439.         jbe     @f
  440. .nf:
  441.         call    free_hd_channel
  442.         and     [hd1_status], 0
  443.         mov     dword [esp+36], 5       ; not found
  444.         ret
  445. @@:
  446.         mov     [fat32part], ecx
  447.         push    ebx esi
  448.         call    choice_necessity_partition_1
  449.         pop     esi ebx
  450.         mov     ecx, [ebx+12]
  451.         mov     edx, [ebx+16]
  452.     ;    add     edx, std_application_base_address
  453.         mov     eax, [ebx]
  454.         cmp     eax, fs_NumHdServices
  455.         jae     .not_impl
  456.         add     ebx, 4
  457.         call    dword [fs_HdServices + eax*4]
  458.         call    free_hd_channel
  459.         and     [hd1_status], 0
  460.         mov     [esp+36], eax
  461.         mov     [esp+24], ebx
  462.         ret
  463. .not_impl:
  464.         call    free_hd_channel
  465.         and     [hd1_status], 0
  466.         mov     dword [esp+36], 2       ; not implemented
  467.         ret
  468.  
  469. fs_HdServices:
  470.         dd      fs_HdRead
  471.         dd      fs_HdReadFolder
  472.         dd      fs_HdRewrite
  473.         dd      fs_HdWrite
  474.         dd      fs_HdSetFileEnd
  475.         dd      fs_HdGetFileInfo
  476.         dd      fs_HdSetFileInfo
  477.         dd      0 ;fs_HdExecute
  478.         dd      fs_HdDelete
  479.         dd      fs_HdCreateFolder
  480. fs_NumHdServices = ($ - fs_HdServices)/4
  481.  
  482. ;*******************************************************
  483. fs_OnCd0:
  484.         call    reserve_cd
  485.         mov  [ChannelNumber],1
  486.         mov  [DiskNumber],0
  487.         push    6
  488.         jmp     fs_OnCd
  489. fs_OnCd1:
  490.         call    reserve_cd
  491.         mov  [ChannelNumber],1
  492.         mov  [DiskNumber],1
  493.         push    4
  494.         jmp     fs_OnCd
  495. fs_OnCd2:
  496.         call    reserve_cd
  497.         mov  [ChannelNumber],2
  498.         mov  [DiskNumber],0
  499.         push    2
  500.         jmp     fs_OnCd
  501. fs_OnCd3:
  502.         call    reserve_cd
  503.         mov  [ChannelNumber],2
  504.         mov  [DiskNumber],1
  505.         push    0
  506. fs_OnCd:
  507.         call    reserve_cd_channel
  508.         pop     eax
  509.         mov     [hdpos], eax
  510.         cmp     ecx, 0x100
  511.         jae     .nf
  512.         push    ecx ebx
  513.         mov     cl,al
  514.         mov     bl,[DRIVE_DATA+1]
  515.         shr     bl,cl
  516.         test    bl,2
  517.         pop     ebx ecx
  518.  
  519.         jnz     @f
  520. .nf:
  521.         call    free_cd_channel
  522.         and    [cd_status], 0
  523.         mov     dword [esp+36], 5       ; not found
  524.         ret
  525. @@:
  526.         mov     ecx, [ebx+12]
  527.         mov     edx, [ebx+16]
  528.     ;    add     edx, std_application_base_address
  529.         mov     eax, [ebx]
  530.         cmp     eax,fs_NumCdServices
  531.         jae      .not_impl
  532.         add     ebx, 4
  533.         call    dword [fs_CdServices + eax*4]
  534.         call    free_cd_channel
  535.         and     [cd_status], 0
  536.         mov     [esp+36], eax
  537.         mov     [esp+24], ebx
  538.         ret
  539. .not_impl:
  540.         call    free_cd_channel
  541.         and     [cd_status], 0
  542.         mov     dword [esp+36], 2       ; not implemented
  543.         ret
  544.  
  545. fs_CdServices:
  546.         dd      fs_CdRead
  547.         dd      fs_CdReadFolder
  548.         dd      fs_NotImplemented
  549.         dd      fs_NotImplemented
  550.         dd      fs_NotImplemented
  551.         dd      fs_CdGetFileInfo
  552.         dd      fs_NotImplemented
  553.         dd      fs_CdExecute
  554. fs_NumCdServices = ($ - fs_CdServices)/4
  555.  
  556. ;*******************************************************
  557.  
  558. fs_HasRamdisk:
  559.         mov     al, 1   ; we always have ramdisk
  560.         ret
  561.  
  562. fs_HasFloppy:
  563.         cmp     byte [DRIVE_DATA], 0
  564.         setnz   al
  565.         ret
  566.  
  567. fs_HasHd0:
  568.         mov     al, [DRIVE_DATA+1]
  569.         and     al, 11000000b
  570.         cmp     al, 01000000b
  571.         setz    al
  572.         ret
  573. fs_HasHd1:
  574.         mov     al, [DRIVE_DATA+1]
  575.         and     al, 00110000b
  576.         cmp     al, 00010000b
  577.         setz    al
  578.         ret
  579. fs_HasHd2:
  580.         mov     al, [DRIVE_DATA+1]
  581.         and     al, 00001100b
  582.         cmp     al, 00000100b
  583.         setz    al
  584.         ret
  585. fs_HasHd3:
  586.         mov     al, [DRIVE_DATA+1]
  587.         and     al, 00000011b
  588.         cmp     al, 00000001b
  589.         setz    al
  590.         ret
  591.  
  592. ;*******************************************************
  593. fs_HasCd0:
  594.         mov     al, [DRIVE_DATA+1]
  595.         and     al, 11000000b
  596.         cmp     al, 10000000b
  597.         setz    al
  598.         ret
  599. fs_HasCd1:
  600.         mov     al, [DRIVE_DATA+1]
  601.         and     al, 00110000b
  602.         cmp     al, 00100000b
  603.         setz    al
  604.         ret
  605. fs_HasCd2:
  606.         mov     al, [DRIVE_DATA+1]
  607.         and     al, 00001100b
  608.         cmp     al, 00001000b
  609.         setz    al
  610.         ret
  611. fs_HasCd3:
  612.         mov     al, [DRIVE_DATA+1]
  613.         and     al, 00000011b
  614.         cmp     al, 00000010b
  615.         setz    al
  616.         ret
  617. ;*******************************************************
  618.  
  619. ; fs_NextXXX functions:
  620. ; in: eax = partition number, from which start to scan
  621. ; out: CF=1 => no more partitions
  622. ;      CF=0 => eax=next partition number
  623.  
  624. fs_NextRamdisk:
  625. ; we always have /rd/1
  626.         test    eax, eax
  627.         stc
  628.         jnz     @f
  629.         mov     al, 1
  630.         clc
  631. @@:
  632.         ret
  633.  
  634. fs_NextFloppy:
  635. ; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
  636.         test    byte [DRIVE_DATA], 0xF0
  637.         jz      .no1
  638.         test    eax, eax
  639.         jnz     .no1
  640.         inc     eax
  641.         ret     ; CF cleared
  642. .no1:
  643.         test    byte [DRIVE_DATA], 0x0F
  644.         jz      .no2
  645.         cmp     al, 2
  646.         jae     .no2
  647.         mov     al, 2
  648.         clc
  649.         ret
  650. .no2:
  651.         stc
  652.         ret
  653.  
  654. ; on hdx, we have partitions from 1 to [0x40002+x]
  655. fs_NextHd0:
  656.         push    0
  657.         jmp     fs_NextHd
  658. fs_NextHd1:
  659.         push    1
  660.         jmp     fs_NextHd
  661. fs_NextHd2:
  662.         push    2
  663.         jmp     fs_NextHd
  664. fs_NextHd3:
  665.         push    3
  666. fs_NextHd:
  667.         pop     ecx
  668.         movzx   ecx, byte [DRIVE_DATA+2+ecx]
  669.         cmp     eax, ecx
  670.         jae     fs_NextFloppy.no2
  671.         inc     eax
  672.         clc
  673.         ret
  674.  
  675. ;*******************************************************
  676. fs_NextCd:
  677. ; we always have /cdX/1
  678.         test    eax, eax
  679.         stc
  680.         jnz     @f
  681.         mov     al, 1
  682.         clc
  683. @@:
  684.         ret
  685. ;*******************************************************
  686.  
  687.