Subversion Repositories Kolibri OS

Rev

Rev 84 | Rev 87 | 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.         db      0
  32.  
  33. virtual_root_query:
  34.         dd      fs_HasRamdisk
  35.         db      'rd',0
  36.         dd      fs_HasFloppy
  37.         db      'fd',0
  38.         dd      fs_HasHd0
  39.         db      'hd0',0
  40.         dd      fs_HasHd1
  41.         db      'hd1',0
  42.         dd      fs_HasHd2
  43.         db      'hd2',0
  44.         dd      fs_HasHd3
  45.         db      'hd3',0
  46.         dd      0
  47. endg
  48.  
  49. file_system_lfn:
  50. ; in: eax->fileinfo block
  51. ; operation codes:
  52. ; 0 : read file
  53. ; 1 : read folder
  54. ; 2 : create/rewrite file
  55. ; 3 : write/append to file - not implemented yet
  56. ; 4 : set end of file - not implemented yet
  57. ; 5 : get file/directory attributes structure
  58. ; 6 : set file/directory attributes structure
  59. ; 7 : start application - not implemented yet
  60. ; 8 : delete file - not implemented yet
  61. ; 9 : create directory - not implemented yet
  62. ; 10: rename file/directory - not implemented yet
  63.  
  64.         add     eax, std_application_base_address
  65. ; parse file name
  66.         xchg    ebx, eax
  67.         lea     esi, [ebx+20]
  68.         lodsb
  69.         test    al, al
  70.         jnz     @f
  71.         mov     esi, [esi]
  72.         add     esi, std_application_base_address
  73.         lodsb
  74. @@:
  75.         cmp     al, '/'
  76.         jz      @f
  77. .notfound:
  78.         mov     dword [esp+36], 5       ; file not found
  79.         ret
  80. @@:
  81.         cmp     byte [esi], 0
  82.         jz      .rootdir
  83.         mov     edi, rootdirs-8
  84.         xor     ecx, ecx
  85.         push    esi
  86. .scan1:
  87.         pop     esi
  88.         add     edi, ecx
  89.         scasd
  90.         scasd
  91.         mov     cl, byte [edi]
  92.         jecxz   .notfound
  93.         inc     edi
  94.         push    esi
  95. @@:
  96.         lodsb
  97.         or      al, 20h
  98.         scasb
  99.         loopz   @b
  100.         jnz     .scan1
  101.         lodsb
  102.         cmp     al, '/'
  103.         jz      .found1
  104.         test    al, al
  105.         jnz     .scan1
  106.         pop     eax
  107. ; directory /xxx
  108. .maindir:
  109.         cmp     dword [ebx], 1
  110.         jnz     .access_denied
  111.         xor     eax, eax
  112.         mov     ebp, [ebx+12]
  113.         mov     edx, [ebx+16]
  114.         add     edx, std_application_base_address
  115.         push    dword [ebx+4]   ; first block
  116.         mov     ebx, [ebx+8]    ; flags
  117.         mov     esi, [edi+4]
  118. ; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
  119.         mov     edi, edx
  120.         mov     ecx, 32/4
  121.         rep     stosd
  122.         mov     byte [edx], 1   ; version
  123. .maindir_loop:
  124.         call    esi
  125.         jc      .maindir_done
  126.         inc     dword [edx+8]
  127.         dec     dword [esp]
  128.         jns     .maindir_loop
  129.         dec     ebp
  130.         js      .maindir_loop
  131.         inc     dword [edx+4]
  132.         mov     dword [edi], 0x10       ; attributes: folder
  133.         mov     dword [edi+4], 1        ; name type: UNICODE
  134.         push    eax
  135.         xor     eax, eax
  136.         add     edi, 8
  137.         mov     ecx, 40/4-2
  138.         rep     stosd
  139.         pop     eax
  140.         push    eax edx
  141. ; convert number in eax to decimal UNICODE string
  142.         push    edi
  143.         push    -'0'
  144.         mov     cl, 10
  145. @@:
  146.         xor     edx, edx
  147.         div     ecx
  148.         push    edx
  149.         test    eax, eax
  150.         jnz     @b
  151. @@:
  152.         pop     eax
  153.         add     al, '0'
  154.         stosb
  155.         test    bl, 1           ; UNICODE name?
  156.         jz      .ansi2
  157.         mov     byte [edi], 0
  158.         inc     edi
  159. .ansi2:
  160.         test    al, al
  161.         jnz     @b
  162.         mov     byte [edi-1], 0
  163.         pop     edi
  164. ; UNICODE name length is 520 bytes, ANSI - 264
  165.         add     edi, 520
  166.         test    bl, 1
  167.         jnz     @f
  168.         sub     edi, 520-264
  169. @@:
  170.         pop     edx eax
  171.         jmp     .maindir_loop
  172. .maindir_done:
  173.         pop     eax
  174.         mov     ebx, [edx+4]
  175.         xor     eax, eax
  176.         dec     ebp
  177.         js      @f
  178.         mov     al, ERROR_END_OF_FILE
  179. @@:
  180.         mov     [esp+36], eax
  181.         mov     [esp+24], ebx
  182.         ret
  183. ; directory /
  184. .rootdir:
  185.         cmp     dword [ebx], 1  ; read folder?
  186.         jz      .readroot
  187. .access_denied:
  188.         mov     dword [esp+36], 10      ; access denied
  189.         ret
  190.  
  191. .readroot:
  192. ; virtual root folder - special handler
  193.         mov     esi, virtual_root_query
  194.         mov     ebp, [ebx+12]
  195.         mov     edx, [ebx+16]
  196.         add     edx, std_application_base_address
  197.         push    dword [ebx+4]   ; first block
  198.         mov     ebx, [ebx+8]    ; flags
  199.         xor     eax, eax
  200. ; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
  201.         mov     edi, edx
  202.         mov     ecx, 32/4
  203.         rep     stosd
  204.         mov     byte [edx], 1   ; version
  205. .readroot_loop:
  206.         cmp     dword [esi], eax
  207.         jz      .readroot_done
  208.         call    dword [esi]
  209.         add     esi, 4
  210.         test    eax, eax
  211.         jnz     @f
  212. .readroot_next:
  213.         or      ecx, -1
  214.         xchg    esi, edi
  215.         repnz   scasb
  216.         xchg    esi, edi
  217.         jmp     .readroot_loop
  218. @@:
  219.         xor     eax, eax
  220.         inc     dword [edx+8]
  221.         dec     dword [esp]
  222.         jns     .readroot_next
  223.         dec     ebp
  224.         js      .readroot_next
  225.         inc     dword [edx+4]
  226.         mov     dword [edi], 0x10       ; attributes: folder
  227.         mov     dword [edi+4], 1        ; name type: UNICODE
  228.         add     edi, 8
  229.         mov     ecx, 40/4-2
  230.         rep     stosd
  231.         push    edi
  232. @@:
  233.         lodsb
  234.         stosb
  235.         test    bl, 1
  236.         jz      .ansi
  237.         mov     byte [edi], 0
  238.         inc     edi
  239. .ansi:
  240.         test    eax, eax
  241.         jnz     @b
  242.         pop     edi
  243.         add     edi, 520
  244.         test    bl, 1
  245.         jnz     .readroot_loop
  246.         sub     edi, 520-264
  247.         jmp     .readroot_loop
  248. .readroot_done:
  249.         pop     eax
  250.         mov     ebx, [edx+4]
  251.         xor     eax, eax
  252.         dec     ebp
  253.         js      @f
  254.         mov     al, ERROR_END_OF_FILE
  255. @@:
  256.         mov     [esp+36], eax
  257.         mov     [esp+24], ebx
  258.         ret
  259.  
  260. .found1:
  261.         pop     eax
  262.         cmp     byte [esi], 0
  263.         jz      .maindir
  264. ; read partition number
  265.         xor     ecx, ecx
  266.         xor     eax, eax
  267. @@:
  268.         lodsb
  269.         cmp     al, '/'
  270.         jz      .done1
  271.         test    al, al
  272.         jz      .done1
  273.         sub     al, '0'
  274.         cmp     al, 9
  275.         ja      .notfound
  276.         imul    ecx, 10
  277.         add     ecx, eax
  278.         jmp     @b
  279. .done1:
  280.         test    ecx, ecx
  281.         jz      .notfound
  282.         test    al, al
  283.         jnz     @f
  284.         dec     esi
  285. @@:
  286. ; now [edi] contains handler address, ecx - partition number,
  287. ; esi points to ASCIIZ string - rest of name
  288.         jmp     dword [edi]
  289.  
  290. ; handlers for devices
  291. ; in: ecx = 0 => query virtual directory /xxx
  292. ; in: ecx = partition number
  293. ;     esi -> relative (for device) name
  294. ;     ebx -> fileinfo
  295. ; out: [esp+36]=image of eax, [esp+24]=image of ebx
  296.  
  297. fs_OnRamdisk:
  298.         cmp     ecx, 1
  299.         jnz     file_system_lfn.notfound
  300.         mov     eax, [ebx]
  301.         cmp     eax, fs_NumRamdiskServices
  302.         jae     .not_impl
  303.         mov     ecx, [ebx+12]
  304.         mov     edx, [ebx+16]
  305.         add     edx, std_application_base_address
  306.         add     ebx, 4
  307.         call    dword [fs_RamdiskServices + eax*4]
  308.         mov     [esp+36], eax
  309.         mov     [esp+24], ebx
  310.         ret
  311. .not_impl:
  312.         mov     dword [esp+36], 2       ; not implemented
  313.         ret
  314.  
  315. fs_NotImplemented:
  316.         mov     eax, 2
  317.         ret
  318.  
  319. fs_RamdiskServices:
  320.         dd      fs_RamdiskRead
  321.         dd      fs_RamdiskReadFolder
  322.         dd      fs_RamdiskRewrite
  323.         dd      fs_NotImplemented
  324.         dd      fs_NotImplemented
  325.         dd      fs_RamdiskGetFileInfo
  326.         dd      fs_RamdiskSetFileInfo
  327. fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
  328.  
  329. fs_OnFloppy:
  330.         cmp     ecx, 2
  331.         ja      file_system_lfn.notfound
  332.         mov     eax, [ebx]
  333.         cmp     eax, fs_NumFloppyServices
  334.         jae     fs_OnRamdisk.not_impl
  335.         call    reserve_flp
  336.         mov     [flp_number], cl
  337.         mov     ecx, [ebx+12]
  338.         mov     edx, [ebx+16]
  339.         add     edx, std_application_base_address
  340.         add     ebx, 4
  341.         call    dword [fs_FloppyServices + eax*4]
  342.         and     [flp_status], 0
  343.         mov     [esp+36], eax
  344.         mov     [esp+24], ebx
  345.         ret
  346.  
  347. fs_FloppyServices:
  348.         dd      fs_FloppyRead
  349.         dd      fs_FloppyReadFolder
  350.         dd      fs_FloppyRewrite
  351.         dd      fs_NotImplemented
  352.         dd      fs_NotImplemented
  353.         dd      fs_FloppyGetFileInfo
  354.         dd      fs_FloppySetFileInfo
  355. fs_NumFloppyServices = ($ - fs_FloppyServices)/4
  356.  
  357. fs_OnHd0:
  358.         call    reserve_hd1
  359.         mov     [hdbase], 0x1F0
  360.         mov     [hdid], 0
  361.         push    1
  362.         jmp     fs_OnHd
  363. fs_OnHd1:
  364.         call    reserve_hd1
  365.         mov     [hdbase], 0x1F0
  366.         mov     [hdid], 0x10
  367.         push    2
  368.         jmp     fs_OnHd
  369. fs_OnHd2:
  370.         call    reserve_hd1
  371.         mov     [hdbase], 0x170
  372.         mov     [hdid], 0
  373.         push    3
  374.         jmp     fs_OnHd
  375. fs_OnHd3:
  376.         call    reserve_hd1
  377.         mov     [hdbase], 0x170
  378.         mov     [hdid], 0x10
  379.         push    4
  380. fs_OnHd:
  381.         pop     eax
  382.         mov     [hdpos], eax
  383.         cmp     ecx, 0x100
  384.         jae     .nf
  385.         cmp     cl, [0x40001+eax]
  386.         jbe     @f
  387. .nf:
  388.         and     [hd1_status], 0
  389.         mov     dword [esp+36], 5       ; not found
  390.         ret
  391. @@:
  392.         mov     [fat32part], ecx
  393.         push    ebx esi
  394.         call    choice_necessity_partition_1
  395.         pop     esi ebx
  396.         mov     ecx, [ebx+12]
  397.         mov     edx, [ebx+16]
  398.         add     edx, std_application_base_address
  399.         mov     eax, [ebx]
  400.         cmp     eax, fs_NumHdServices
  401.         jae     .not_impl
  402.         add     ebx, 4
  403.         call    dword [fs_HdServices + eax*4]
  404.         and     [hd1_status], 0
  405.         mov     [esp+36], eax
  406.         mov     [esp+24], ebx
  407.         ret
  408. .not_impl:
  409.         and     [hd1_status], 0
  410.         mov     dword [esp+36], 2       ; not implemented
  411.         ret
  412.  
  413. fs_HdServices:
  414.         dd      fs_HdRead
  415.         dd      fs_HdReadFolder
  416.         dd      fs_HdRewrite
  417.         dd      fs_NotImplemented
  418.         dd      fs_NotImplemented
  419.         dd      fs_HdGetFileInfo
  420.         dd      fs_HdSetFileInfo
  421. fs_NumHdServices = ($ - fs_HdServices)/4
  422.  
  423. fs_HasRamdisk:
  424.         mov     al, 1   ; we always have ramdisk
  425.         ret
  426.  
  427. fs_HasFloppy:
  428.         cmp     byte [0x40000], 0
  429.         setnz   al
  430.         ret
  431.  
  432. fs_HasHd0:
  433.         mov     al, [0x40001]
  434.         and     al, 11000000b
  435.         cmp     al, 01000000b
  436.         setz    al
  437.         ret
  438. fs_HasHd1:
  439.         mov     al, [0x40001]
  440.         and     al, 00110000b
  441.         cmp     al, 00010000b
  442.         setz    al
  443.         ret
  444. fs_HasHd2:
  445.         mov     al, [0x40001]
  446.         and     al, 00001100b
  447.         cmp     al, 00000100b
  448.         setz    al
  449.         ret
  450. fs_HasHd3:
  451.         mov     al, [0x40001]
  452.         and     al, 00000011b
  453.         cmp     al, 00000001b
  454.         setz    al
  455.         ret
  456.  
  457. ; fs_NextXXX functions:
  458. ; in: eax = partition number, from which start to scan
  459. ; out: CF=1 => no more partitions
  460. ;      CF=0 => eax=next partition number
  461.  
  462. fs_NextRamdisk:
  463. ; we always have /rd/1
  464.         test    eax, eax
  465.         stc
  466.         jnz     @f
  467.         mov     al, 1
  468.         clc
  469. @@:
  470.         ret
  471.  
  472. fs_NextFloppy:
  473. ; we have /fd/1 iff (([0x40000] and 0xF0) != 0) and /fd/2 iff (([0x40000] and 0x0F) != 0)
  474.         test    byte [0x40000], 0xF0
  475.         jz      .no1
  476.         test    eax, eax
  477.         jnz     .no1
  478.         inc     eax
  479.         ret     ; CF cleared
  480. .no1:
  481.         test    byte [0x40000], 0x0F
  482.         jz      .no2
  483.         cmp     al, 2
  484.         jae     .no2
  485.         mov     al, 2
  486.         clc
  487.         ret
  488. .no2:
  489.         stc
  490.         ret
  491.  
  492. ; on hdx, we have partitions from 1 to [0x40002+x]
  493. fs_NextHd0:
  494.         push    0
  495.         jmp     fs_NextHd
  496. fs_NextHd1:
  497.         push    1
  498.         jmp     fs_NextHd
  499. fs_NextHd2:
  500.         push    2
  501.         jmp     fs_NextHd
  502. fs_NextHd3:
  503.         push    3
  504. fs_NextHd:
  505.         pop     ecx
  506.         movzx   ecx, byte [0x40002+ecx]
  507.         cmp     eax, ecx
  508.         jae     fs_NextFloppy.no2
  509.         inc     eax
  510.         clc
  511.         ret
  512.