Subversion Repositories Kolibri OS

Rev

Rev 129 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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