Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
  4. ;;  Distributed under terms of the GNU General Public License.  ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 6471 $
  9.  
  10. ERROR_SUCCESS        = 0
  11. ERROR_DISK_BASE      = 1
  12. ERROR_UNSUPPORTED_FS = 2
  13. ERROR_UNKNOWN_FS     = 3
  14. ERROR_PARTITION      = 4
  15. ERROR_FILE_NOT_FOUND = 5
  16. ERROR_END_OF_FILE    = 6
  17. ERROR_MEMORY_POINTER = 7
  18. ERROR_DISK_FULL      = 8
  19. ERROR_FS_FAIL        = 9
  20. ERROR_ACCESS_DENIED  = 10
  21. ERROR_DEVICE         = 11
  22. ERROR_OUT_OF_MEMORY  = 12
  23.  
  24. maxPathLength = 1000h
  25.  
  26. image_of_eax EQU esp+32
  27. image_of_ebx EQU esp+20
  28.  
  29. ; System function 70
  30.  
  31. file_system_lfn_protected:
  32.         pushad
  33.         call    protect_from_terminate
  34.         call    file_system_lfn
  35.         call    unprotect_from_terminate
  36.         popad
  37.         mov     [image_of_eax], eax
  38.         mov     [image_of_ebx], ebx
  39.         ret
  40.  
  41. file_system_lfn:
  42. ; in: ebx -> parameter structure
  43. ;   operation codes:
  44. ; 0 = read file
  45. ; 1 = read folder
  46. ; 2 = create/rewrite file
  47. ; 3 = write/append to file
  48. ; 4 = set file end
  49. ; 5 = get file info
  50. ; 6 = set file info
  51. ; start application
  52. ; 8 = delete file/folder
  53. ; 9 = create folder
  54.         lea     ebp, [ebx+20]
  55.         cmp     byte [ebp], 0
  56.         jnz     @f
  57.         mov     ebp, [ebx+21]
  58. @@:
  59.         cmp     dword[ebx], 7   ; start application
  60.         jne     @f
  61.         mov     edx, [ebx+4]
  62.         mov     ebx, [ebx+8]
  63.         call    fs_execute      ; ebp, ebx, edx
  64.         mov     [image_of_eax], eax
  65.         ret
  66.  
  67. @@:
  68.         cmp     word [ebp], '/'
  69.         jz      .rootdir
  70.         cmp     byte [ebp], 2
  71.         jnz     @f
  72.         cmp     dword[ebp+1], '/'
  73.         jz      .rootdir
  74. @@:
  75.         stdcall kernel_alloc, maxPathLength
  76.         push    ebx
  77.         mov     ebx, ebp
  78.         mov     ebp, eax
  79.         push    maxPathLength
  80.         push    eax
  81.         call    get_full_file_name
  82.         pop     ebx
  83.         test    eax, eax
  84.         jz      .notfound
  85.         mov     esi, ebp
  86.         mov     ax, [ebp]
  87.         or      ax, 2020h
  88.         cmp     ax, 'cd'
  89.         jz      .CD
  90.         call    dyndisk_handler ; not returns if success
  91. .notfound:
  92.         stdcall kernel_free, ebp
  93.         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
  94.         ret
  95.  
  96. .CD:
  97.         add     esi, 2
  98.         xor     eax, eax
  99.         lodsb       ; disk number
  100.         sub     eax, '0'
  101.         cmp     eax, 10
  102.         jnc     .notfound
  103.         mov     edi, eax
  104.         lodsb
  105.         test    eax, eax
  106.         jz      .maindir
  107.         cmp     al, '/'
  108.         jnz     .notfound
  109.         lodsb       ; partition number
  110.         test    eax, eax
  111.         jz      .maindir
  112.         cmp     al, '1'
  113.         jnz     .notfound
  114.         cmp     byte [esi], '/'
  115.         jnz     @f
  116.         inc     esi
  117. @@:
  118.         call    reserve_cd
  119.         mov     eax, edi
  120.         bt      eax, 0
  121.         setc    [DiskNumber]
  122.         bt      eax, 1
  123.         setc    [ChannelNumber]
  124.         inc     [ChannelNumber]
  125.         inc     eax
  126.         mov     [cdpos], eax
  127.         call    reserve_cd_channel
  128.         mov     eax, edi
  129.         not     eax
  130.         and     eax, 3
  131.         shl     eax, 1
  132.         inc     eax
  133.         shr     edi, 2
  134.         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
  135.         bt      [edi*5+DRIVE_DATA+1], ax
  136.         jnc     @f
  137.         mov     ecx, [ebx+12]
  138.         mov     edx, [ebx+16]
  139.         mov     eax, [ebx]
  140.         mov     dword[image_of_eax], ERROR_UNSUPPORTED_FS
  141.         cmp     eax, fs_NumCdServices
  142.         jae     @f
  143.         add     ebx, 4
  144.         call    dword[fs_CdServices + eax*4]
  145.         mov     [image_of_eax], eax
  146.         mov     [image_of_ebx], ebx
  147. @@:
  148.         call    free_cd_channel
  149.         and     [cd_status], 0
  150.         stdcall kernel_free, ebp
  151.         ret
  152.  
  153. .nextCD:
  154.         test    eax, eax    ; partition number
  155.         stc
  156.         jnz     @f      ; no more partitions
  157.         mov     al, 1   ; /cdX/1
  158.         clc
  159. @@:
  160.         ret
  161.  
  162. .maindir:   ; list partitions
  163.         mov     esi, .nextCD
  164. .maindir_noesi:     ; backjump from dyndisk_handler
  165.         push    ebp
  166.         mov     ebp, ecx
  167.         call    kernel_free
  168.         cmp     dword[ebx], 1
  169.         jnz     .access_denied  ; read folder?
  170.         push    ebp
  171.         pushd   [ebx+4]         ; first block
  172.         mov     ebp, [ebx+12]   ; the number of blocks to read
  173.         mov     edx, [ebx+16]   ; buffer
  174.         mov     ebx, [ebx+8]    ; flags
  175.         mov     ecx, 32/4
  176.         mov     edi, edx
  177.         xor     eax, eax
  178.         rep stosd
  179.         mov     byte [edx], 1   ; version
  180. .maindir_loop:
  181.         call    esi
  182.         jc      .maindir_done
  183.         inc     dword[edx+8]
  184.         dec     dword[esp]
  185.         jns     .maindir_loop
  186.         dec     ebp
  187.         js      .maindir_loop
  188.         inc     dword[edx+4]
  189.         mov     dword[edi], 16      ; attributes: folder
  190.         mov     dword[edi+4], ebx   ; name encoding
  191.         push    eax
  192.         mov     ecx, 32/4
  193.         add     edi, 8
  194.         xor     eax, eax
  195.         rep stosd
  196.         pop     eax
  197.         push    eax edx edi
  198. ; convert number in eax to decimal string
  199.         push    -'0'
  200.         mov     ecx, 10
  201. @@:
  202.         xor     edx, edx
  203.         div     ecx
  204.         push    edx
  205.         test    eax, eax
  206.         jnz     @b
  207.         cmp     ebx, 1
  208.         jz      .uni
  209. @@:
  210.         pop     eax
  211.         add     eax, '0'
  212.         stosb
  213.         test    eax, eax
  214.         jnz     @b
  215.         pop     edi edx eax
  216.         add     edi, 264
  217.         jmp     .maindir_loop
  218.  
  219. .uni:
  220.         pop     eax
  221.         add     eax, '0'
  222.         stosw
  223.         test    eax, eax
  224.         jnz     .uni
  225.         pop     edi edx eax
  226.         add     edi, 520
  227.         jmp     .maindir_loop
  228.  
  229. .maindir_done:
  230.         pop     eax eax
  231.         mov     ebx, [edx+4]
  232.         xor     eax, eax
  233.         dec     ebp
  234.         js      @f
  235.         mov     al, ERROR_END_OF_FILE
  236. @@:
  237.         mov     [image_of_eax], eax
  238.         mov     [image_of_ebx], ebx
  239.         ret
  240.  
  241. .access_denied:
  242.         mov     dword[image_of_eax], ERROR_ACCESS_DENIED
  243.         ret
  244.  
  245. .rootdir:   ; / - virtual root folder
  246.         cmp     dword[ebx], 1   ; read folder?
  247.         jnz     .access_denied
  248.         mov     ebp, [ebx+12]   ; number of blocks
  249.         mov     edx, [ebx+16]   ; return area
  250.         push    dword[ebx+4]    ; first block
  251.         mov     ebx, [ebx+8]    ; flags
  252.         mov     ecx, 32/4
  253.         mov     edi, edx
  254.         xor     eax, eax
  255.         rep stosd
  256.         mov     byte [edx], 1   ; version
  257.         sub     esp, 16
  258. .rootdir_loop:
  259.         push    edi
  260.         lea     edi, [esp+4]
  261.         call    dyndisk_enum_root
  262.         pop     edi
  263.         test    eax, eax
  264.         jz      .rootdirCD
  265.         inc     dword[edx+8]
  266.         dec     dword[esp+16]
  267.         jns     .rootdir_loop
  268.         dec     ebp
  269.         js      .rootdir_loop
  270.         inc     dword[edx+4]
  271.         mov     dword[edi], 16      ; attributes: folder
  272.         mov     dword[edi+4], ebx   ; name encoding
  273.         push    eax
  274.         mov     ecx, 32/4
  275.         add     edi, 8
  276.         xor     eax, eax
  277.         rep stosd
  278.         push    edi
  279.         lea     esi, [esp+8]
  280.         cmp     ebx, 1
  281.         jz      .uni2
  282. @@:
  283.         lodsb
  284.         stosb
  285.         test    eax, eax
  286.         jnz     @b
  287.         pop     edi eax
  288.         add     edi, 264
  289.         jmp     .rootdir_loop
  290.  
  291. .uni2:
  292.         lodsb
  293.         stosw
  294.         test    eax, eax
  295.         jnz     .uni2
  296.         pop     edi eax
  297.         add     edi, 520
  298.         jmp     .rootdir_loop
  299.  
  300. .rootdirCD:
  301.         add     esp, 16
  302.         or      esi, -1
  303. .rootdirCD_loop:
  304.         inc     esi
  305.         cmp     esi, 10
  306.         jnc     .rootdir_done
  307.         mov     eax, esi
  308.         not     eax
  309.         and     eax, 3
  310.         shl     eax, 1
  311.         inc     eax
  312.         mov     ecx, esi
  313.         shr     ecx, 2
  314.         bt      [ecx*5+DRIVE_DATA+1], ax
  315.         jnc     .rootdirCD_loop
  316.         inc     dword[edx+8]
  317.         dec     dword[esp]
  318.         jns     .rootdirCD_loop
  319.         dec     ebp
  320.         js      .rootdirCD_loop
  321.         inc     dword[edx+4]
  322.         mov     dword[edi], 16      ; attributes: folder
  323.         mov     dword[edi+4], ebx   ; name encoding
  324.         mov     ecx, 32/4
  325.         add     edi, 8
  326.         xor     eax, eax
  327.         rep stosd
  328.         mov     eax, esi
  329.         add     eax, '0'
  330.         cmp     ebx, 1
  331.         jz      @f
  332.         mov     word [edi], 'cd'
  333.         mov     [edi+2], ax
  334.         add     edi, 264
  335.         jmp     .rootdirCD_loop
  336.  
  337. @@:
  338.         mov     dword[edi], 640063h
  339.         mov     [edi+4], eax
  340.         add     edi, 520
  341.         jmp     .rootdirCD_loop
  342.  
  343. .rootdir_done:
  344.         pop     eax
  345.         mov     ebx, [edx+4]
  346.         xor     eax, eax
  347.         dec     ebp
  348.         js      @f
  349.         mov     al, ERROR_END_OF_FILE
  350. @@:
  351.         mov     [image_of_eax], eax
  352.         mov     [image_of_ebx], ebx
  353.         ret
  354.  
  355. ;-----------------------------------------------------------------------------
  356. process_replace_file_name:
  357. ; in: [esi] = virtual path
  358. ; out: [esi]+[ebp] = physical path
  359.         xor     edi, edi
  360.         xor     ebp, ebp
  361. .loop:
  362.         cmp     edi, [full_file_name_table.size]
  363.         jae     .notfound
  364.         push    esi edi
  365.         shl     edi, 7
  366.         add     edi, [full_file_name_table]
  367. @@:
  368.         cmp     byte [edi], 0
  369.         jz      .dest_done
  370.         lodsb
  371.         test    al, al
  372.         jz      .cont
  373.         or      al, 20h
  374.         scasb
  375.         jz      @b
  376. .cont:
  377.         pop     edi esi
  378.         inc     edi
  379.         jmp     .loop
  380.  
  381. .dest_done:
  382.         cmp     byte [esi], 0
  383.         jz      .found
  384.         cmp     byte [esi], '/'
  385.         jnz     .cont
  386. .found:
  387.         pop     edi eax
  388.         shl     edi, 7
  389.         add     edi, [full_file_name_table]
  390.         mov     ebp, esi
  391.         lea     esi, [edi+64]
  392. .notfound:
  393.         ret
  394.  
  395. ;-----------------------------------------------------------------------------
  396. uglobal
  397. addDirSeal db  ?
  398. endg
  399.  
  400. sys_current_directory:  ; sysfunction 30
  401.         mov     eax, [current_slot]
  402.         mov     edi, [eax+APPDATA.cur_dir]
  403.         dec     ebx
  404.         jz      .set
  405.         dec     ebx
  406.         jz      .get
  407.         dec     ebx
  408.         jz      .mount_additional_directory
  409.         dec     ebx
  410.         jz      .get16
  411. @@:
  412.         ret
  413.  
  414. .mount_additional_directory:
  415. ; in: ecx -> dir name+dir path (128)
  416.         mov     al, 1
  417.         xchg    [addDirSeal], al
  418.         test    al, al
  419.         jnz     @b
  420.         mov     esi, ecx
  421.         mov     edi, sysdir_name1
  422.         mov     ecx, 63
  423.         rep movsb   ; copying fake directory name
  424.         inc     esi
  425.         xor     eax, eax
  426.         stosb       ; terminator of name, in case if we get the inlet trash
  427.         mov     cl, 63
  428.         cmp     word [esi], 2
  429.         jz      .utf16
  430.         call    cp866toUTF8_string
  431. @@:
  432.         mov     byte [edi], 0
  433.         mov     [full_file_name_table.size], 2
  434.         ret
  435.  
  436. .utf16:
  437.         add     esi, 2
  438.         call    UTF16to8_string
  439.         jmp     @b
  440.  
  441. .get:       ; in: ecx -> buffer, edx = length
  442.         mov     esi, edi
  443.         mov     edi, ecx
  444.         cmp     edx, maxPathLength
  445.         jc      @f
  446.         mov     edx, maxPathLength
  447. @@:
  448.         mov     al, '/'
  449.         stosb
  450.         mov     ecx, edx
  451.         dec     ecx
  452. @@:
  453.         dec     ecx
  454.         js      @f
  455.         call    utf8to16
  456.         call    uni2ansi_char
  457.         stosb
  458.         test    al, al
  459.         jnz     @b
  460.         sub     edx, ecx
  461.         mov     ecx, edx
  462. @@:
  463.         mov     [esp+32], ecx
  464.         ret
  465.  
  466. .get16:
  467.         mov     esi, edi
  468.         mov     edi, ecx
  469.         cmp     edx, maxPathLength
  470.         jc      @f
  471.         mov     edx, maxPathLength
  472. @@:
  473.         shr     edx, 1
  474.         mov     ax, '/'
  475.         stosw
  476.         mov     ecx, edx
  477.         dec     ecx
  478. @@:
  479.         dec     ecx
  480.         js      @f
  481.         call    utf8to16
  482.         stosw
  483.         test    ax, ax
  484.         jnz     @b
  485.         sub     edx, ecx
  486.         mov     ecx, edx
  487. @@:
  488.         mov     [esp+32], ecx
  489.         ret
  490.  
  491. .set:
  492.         pop     eax
  493.         push    maxPathLength
  494.         push    edi
  495.         push    eax
  496.         mov     ebx, ecx
  497. get_full_file_name:
  498. ; in: ebx -> file name, [esp+4] -> destination, [esp+8] = max length
  499. ; out: eax=0 -> out of length
  500.         push    ebp ebx
  501.         mov     esi, ebx
  502.         cmp     byte [ebx], 2
  503.         jnz     @f
  504.         inc     esi
  505. @@:
  506.         cmp     byte [esi], '/'
  507.         jnz     .set_relative
  508.         inc     esi
  509.         cmp     byte [ebx], 2
  510.         jnz     @f
  511.         inc     esi
  512. @@:
  513.         call    process_replace_file_name
  514.         mov     edi, [esp+12]
  515.         mov     ecx, [esp+16]
  516.         test    ebp, ebp
  517.         jz      .absolute
  518. @@:
  519.         lodsb
  520.         stosb
  521.         dec     ecx
  522.         test    al, al
  523.         jnz     @b
  524.         mov     esi, ebp
  525.         dec     edi
  526. .absolute:
  527.         cmp     byte [ebx], 2
  528.         jz      @f
  529.         call    cp866toUTF8_string
  530.         jns     .ret
  531.         jmp     .fail
  532.  
  533. @@:
  534.         call    UTF16to8_string
  535.         jns     .ret
  536. .fail:
  537.         mov     byte [edi], 0
  538.         xor     eax, eax
  539.         pop     ebx ebp
  540.         ret     8
  541.  
  542. .set_relative:
  543.         mov     edi, [current_slot]
  544.         mov     edi, [edi+APPDATA.cur_dir]
  545.         mov     edx, edi
  546.         mov     ecx, [esp+16]
  547.         xor     eax, eax
  548.         repnz scasb
  549.         mov     esi, edi
  550.         dec     esi
  551.         mov     edi, [esp+12]
  552.         jecxz   .fail
  553.         cmp     byte [ebx], 2
  554.         jz      .relative16
  555. .relative:
  556.         cmp     byte [ebx], 0
  557.         jz      .set_ok
  558.         cmp     word [ebx], '.'
  559.         jz      .set_ok
  560.         cmp     word [ebx], './'
  561.         jz      .next
  562.         cmp     word [ebx], '..'
  563.         jnz     .doset_relative
  564.         cmp     byte [ebx+2], 0
  565.         jz      @f
  566.         cmp     byte [ebx+2], '/'
  567.         jnz     .doset_relative
  568.         inc     ebx
  569. @@:
  570.         dec     esi
  571.         cmp     byte [esi], '/'
  572.         jnz     @b
  573. .next:
  574.         add     ebx, 2
  575.         jmp     .relative
  576.  
  577. .set_ok:
  578.         cmp     edx, edi    ; is destination equal to cur_dir?
  579.         jz      @f
  580.         mov     ecx, esi
  581.         sub     ecx, edx
  582.         mov     esi, edx
  583.         rep movsb
  584.         mov     byte [edi], 0
  585. .ret:
  586.         mov     al, 1
  587.         pop     ebx ebp
  588.         ret     8
  589.  
  590. @@:
  591.         mov     byte [esi], 0
  592.         jmp     .ret
  593.  
  594. .doset_relative:
  595.         cmp     edx, edi    ; is destination equal to cur_dir?
  596.         mov     edi, esi
  597.         jz      @f
  598.         mov     edi, [esp+12]
  599.         mov     ecx, esi
  600.         sub     ecx, edx
  601.         mov     esi, edx
  602.         mov     edx, edi
  603.         rep movsb
  604. @@:
  605.         mov     byte [edi], '/'
  606.         inc     edi
  607.         mov     esi, ebx
  608.         mov     ecx, edx
  609.         add     ecx, [esp+16]
  610.         sub     ecx, edi
  611.         mov     ebx, [esp]
  612.         jmp     .absolute
  613.  
  614. .relative16:
  615.         cmp     word [ebx], 0
  616.         jz      .set_ok
  617.         cmp     word [ebx], '.'
  618.         jnz     .doset_relative
  619.         cmp     word [ebx+2], 0
  620.         jz      .set_ok
  621.         cmp     word [ebx+2], '/'
  622.         jz      .next16
  623.         cmp     word [ebx+2], '.'
  624.         jnz     .doset_relative
  625.         cmp     word [ebx+4], 0
  626.         jz      @f
  627.         cmp     word [ebx+4], '/'
  628.         jnz     .doset_relative
  629.         add     ebx, 2
  630. @@:
  631.         dec     esi
  632.         cmp     byte [esi], '/'
  633.         jnz     @b
  634. .next16:
  635.         add     ebx, 4
  636.         jmp     .relative16
  637.  
  638. include "parse_fn.inc"
  639. include "fs_common.inc"
  640. include "iso9660.inc"   ; read for CD filesystem
  641. include "fat.inc"
  642. include "ntfs.inc"
  643. include "ext.inc"
  644. include "xfs.asm"
  645.