Subversion Repositories Kolibri OS

Rev

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