Subversion Repositories Kolibri OS

Rev

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