Subversion Repositories Kolibri OS

Rev

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