Subversion Repositories Kolibri OS

Rev

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

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