Subversion Repositories Kolibri OS

Rev

Rev 9734 | 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: 9894 $
  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.  
  23. maxPathLength = 1000h
  24.  
  25. image_of_eax EQU esp+32
  26. image_of_ebx EQU esp+20
  27.  
  28. ; fs api for drivers
  29. struct  FileSystem
  30.         Next            dd ?
  31.         Prev            dd ?
  32.         Creat_part      dd ?  ; %FSNAME%_create_partition
  33.         UserFuncs       dd ? ; for fs_del
  34.         Name            rd 16 ;ascii string + \n
  35. ends
  36.  
  37.  
  38. fs_list:
  39.         dd      fs_list
  40.         dd      fs_list
  41. ;.look:  dd      0
  42.  
  43. ; IN: ecx = %FSNAME%_create_partition
  44. ;     edx = ptr to UserFuncs
  45. ;     [esp] = fs name
  46. ;OUT: eax = list item
  47. fs_add:
  48.         push    ecx edx
  49.         ; add in fs_list
  50.         mov     eax, sizeof.FileSystem
  51.         call    malloc
  52.         pop     edx ecx
  53.         test    eax, eax
  54.         jz      .err
  55.  
  56.         mov     [eax + FileSystem.Creat_part], ecx
  57.         mov     [eax + FileSystem.UserFuncs], edx
  58.         mov     edx, [esp + 4]
  59.         mov     [eax + FileSystem.Name], edx
  60.         mov     edx, eax
  61.  
  62.         cli          ; DELETE
  63.         list_add_tail edx, fs_list
  64.         sti          ; DELETE
  65.         mov     edx, ecx ; save function
  66.  
  67.         ;DEBUGF  1, 'K : FS: find partition\n'
  68.         ; check all disks
  69.         mov     esi, [disk_list]
  70. .new_disk:
  71.         cmp     dword[esi], disk_list
  72.         jz      .end
  73.  
  74.         push    edx
  75.         mov     eax, [esi + DISK.MediaInfo.SectorSize]
  76.         shl     eax, 2
  77.         stdcall kernel_alloc, eax   ;get buffer
  78.         test    eax, eax
  79.         pop     edx
  80.         jz      .end ; no memory
  81.         mov     ebx, eax
  82.  
  83.         mov     ecx, [esi + DISK.NumPartitions]
  84.         dec     ecx
  85.         shl     ecx, 2 ; to dword
  86.         add     ecx, [esi + DISK.Partitions]
  87. @@:
  88.         mov     ebp, [ecx]
  89.         cmp     [ebp + PARTITION.FSUserFunctions], default_fs_functions
  90.         jnz     .no_fs
  91.  
  92.         ;DEBUGF  1, 'K : FS: found partition\n'
  93.         push    ecx edx
  94.  
  95.         xor     eax, eax     ; first sector of the partition
  96.         call    fs_read32_sys
  97.         push    eax
  98.         ;DEBUGF  1, 'K : FS: call driver func = %x\n', edx
  99.  
  100.         call    edx ; creat_partition
  101.         add     esp, 4
  102.         ;DEBUGF  1, 'K : FS: end call\n'
  103.         pop     edx ecx
  104.  
  105.         test    eax, eax
  106.         jz      .no_fs
  107.         ; save and delete old struct
  108.         xchg    [ecx], eax
  109.         push    ecx edx
  110.         call    free
  111.         pop     edx ecx
  112.         ;DEBUGF  1, 'K : FS: set fs for partition\n'
  113. .no_fs:
  114.         ;sub     ecx, 4
  115.         cmp     ecx, [esi + DISK.Partitions]
  116.         lea     ecx, [ecx - 4]
  117.         jnz     @b
  118.  
  119.         push    edx
  120.         stdcall kernel_free, ebx
  121.         pop     edx
  122.  
  123.         mov     esi, [esi]
  124.         jmp     .new_disk
  125. .end:
  126. .err:
  127.         ret
  128. ; IN: ecx = list item
  129. ;OUT: -
  130. ;fs_del:
  131. ;
  132. ;        ret
  133.  
  134.  
  135.  
  136. ; System function 70 security check
  137. align 4
  138. proc file_system_is_operation_safe stdcall, inf_struct_ptr: dword
  139. ; in:
  140. ;      inf_struct_ptr = pointer to information structure was given to sysfn70
  141. ; out: ZF = 1 if operation is safe
  142. ;      ZF = 0 if operation can cause kernel crash
  143.         push    ebx ecx edx
  144.         xor     ecx, ecx ; ecx - length of target buffer
  145.  
  146.         mov     ebx, [inf_struct_ptr]
  147.         mov     edx, [ebx + 16] ; base of target buffer
  148.  
  149.         cmp     dword [ebx], 0 ; if 70.0
  150.         jnz     .case1
  151.         mov     ecx, dword [ebx + 12]
  152.         jmp     .end_switch
  153.  
  154. .case1:
  155.         cmp     dword [ebx], 1 ; if 70.1
  156.         jnz     .case2_3
  157.         ;mov     ecx, 32
  158.         cmp     dword [ebx + 8], 1 ; check encoding
  159.         jbe     .case1_304 ; if encdoing <= 1 i.e cpp866
  160.         mov     ecx, 560 ; if unicode then bdvk block len is 560 bytes
  161.         jmp     .case1_end
  162. .case1_304:
  163.         mov     ecx, 304 ; if cp866 then bdvk block len is 304 bytes
  164. .case1_end:
  165.         imul    ecx, dword [ebx + 12] ; multiply bdvk length by their count
  166.         add     ecx, 32 ; add result header len
  167.         jmp     .end_switch
  168.  
  169. .case2_3:
  170.         cmp     dword [ebx], 3
  171.         ja      .case5 ; if subfn > 3
  172.         mov     ecx, dword [ebx + 12]
  173.         jmp     .end_switch
  174.  
  175. .case5:
  176.         cmp     dword [ebx], 5
  177.         jnz     .case6
  178.         mov     ecx, 40
  179.         jmp     .end_switch
  180.  
  181. .case6:
  182.         cmp     dword [ebx], 6
  183.         jnz     .switch_none
  184.         mov     ecx, 32
  185.         jmp     .end_switch
  186.  
  187. .switch_none:
  188.         cmp     ecx, ecx
  189.         jmp     .ret
  190.      
  191. .end_switch:
  192.         stdcall is_region_userspace, edx, ecx
  193. .ret:
  194.         pop     edx ecx ebx
  195.         ret
  196. endp
  197.  
  198. sys_fileSystemUnicode: ; with user pointer correctness checking
  199. ; in: ebx -> f.80 parameter structure
  200.         stdcall file_system_is_operation_safe, ebx
  201.         jz      @f
  202.  
  203.         DEBUGF  1, "sysfn80 addr error\n"
  204.         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
  205.         ret
  206. @@:
  207.         jmp     fileSystemUnicode
  208.  
  209. ;System function 70
  210. sys_file_system_lfn: ; with user pointer correctness checking
  211. ; in: ebx -> f.70 parameter structure
  212.         stdcall file_system_is_operation_safe, ebx
  213.         jz      @f
  214.  
  215.         DEBUGF  1, "sysfn70 addr error\n"
  216.         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
  217.         ret
  218. @@:
  219.         jmp     file_system_lfn
  220.  
  221. ;file_system_lfn_protected returns values not in registers, but in their images
  222. ;on stack. Make a short wrapper to actually return values in registers.
  223. file_system_lfn_protected_registers:
  224.         pushad
  225.         call    file_system_lfn_protected
  226.         popad
  227.         ret
  228.  
  229. file_system_lfn_protected:
  230.         pushad
  231.         call    protect_from_terminate
  232.         call    file_system_lfn
  233.         call    unprotect_from_terminate
  234.         popad
  235.         mov     [image_of_eax], eax
  236.         mov     [image_of_ebx], ebx
  237.         ret
  238.  
  239. fileSystemUnicode:
  240. ; in: ebx -> f.80 parameter structure
  241.         mov     edi, [ebx+20]
  242.         mov     esi, [ebx+24]
  243.         jmp     @f
  244.  
  245. file_system_lfn:
  246. ; in: ebx -> f.70 parameter structure
  247.         xor     edi, edi
  248.         lea     esi, [ebx+20]
  249.         cmp     byte [esi], 0
  250.         jnz     @f
  251.         mov     esi, [ebx+21]
  252. @@:
  253.         cmp     word [esi], '/'
  254.         jnz     @f
  255.         cmp     edi, 2
  256.         jnz     .rootdir
  257.         cmp     dword[esi], '/'
  258.         jz      .rootdir
  259. @@:
  260.         stdcall kernel_alloc, maxPathLength
  261.         push    eax ebx
  262.         xchg    eax, edi
  263.         call    getFullPath
  264.         pop     ebx ebp
  265.         test    eax, eax
  266.         jz      .notfound
  267.         cmp     dword[ebx], 7   ; start application
  268.         jnz     @f
  269.         mov     edx, [ebx+4]
  270.         mov     ecx, [ebx+8]
  271.         mov     ebx, ebp
  272.         call    fs_execute
  273.         mov     [image_of_eax], eax
  274.         ret
  275.  
  276. @@:
  277.         lea     esi, [ebp+2]
  278.         mov     ax, [esi]
  279.         or      ax, 2020h
  280.         cmp     ax, 'cd'
  281.         jz      .CD
  282.         call    dyndisk_handler ; not returns if success
  283. .notfound:
  284.         stdcall kernel_free, ebp
  285.         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
  286.         ret
  287.  
  288. .CD:
  289.         add     esi, 2
  290.         xor     eax, eax
  291.         lodsb       ; disk number
  292.         sub     eax, '0'
  293.         cmp     eax, 10
  294.         jnc     .notfound
  295.         mov     edi, eax
  296.         lodsb
  297.         test    eax, eax
  298.         jz      .maindir
  299.         cmp     al, '/'
  300.         jnz     .notfound
  301.         lodsb       ; partition number
  302.         test    eax, eax
  303.         jz      .maindir
  304.         cmp     al, '1'
  305.         jnz     .notfound
  306.         cmp     byte [esi], '/'
  307.         jnz     @f
  308.         inc     esi
  309. @@:
  310.         call    reserve_cd
  311.         mov     eax, edi
  312.         bt      eax, 0
  313.         setc    [DiskNumber]
  314.         bt      eax, 1
  315.         setc    [ChannelNumber]
  316.         inc     [ChannelNumber]
  317.         inc     eax
  318.         mov     [cdpos], eax
  319.         call    reserve_cd_channel
  320.         mov     eax, edi
  321.         not     eax
  322.         and     eax, 3
  323.         shl     eax, 1
  324.         inc     eax
  325.         shr     edi, 2
  326.         mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
  327.         bt      [edi*5+DRIVE_DATA+1], ax
  328.         jnc     @f
  329.         mov     ecx, [ebx+12]
  330.         mov     edx, [ebx+16]
  331.         mov     eax, [ebx]
  332.         mov     dword[image_of_eax], ERROR_UNSUPPORTED_FS
  333.         cmp     eax, fs_NumCdServices
  334.         jae     @f
  335.         add     ebx, 4
  336.         push    ebp
  337.         call    dword[fs_CdServices + eax*4]
  338.         pop     ebp
  339.         mov     [image_of_eax], eax
  340.         mov     [image_of_ebx], ebx
  341. @@:
  342.         call    free_cd_channel
  343.         and     [cd_status], 0
  344.         stdcall kernel_free, ebp
  345.         ret
  346.  
  347. .nextCD:
  348.         test    eax, eax    ; partition number
  349.         jnz     @f
  350.         inc     eax     ; /cdX/1
  351.         ret
  352.  
  353. @@:
  354.         stc
  355.         ret
  356.  
  357. .maindir:   ; list partitions
  358.         mov     esi, .nextCD
  359.         xor     ecx, ecx
  360. .maindir_noesi:     ; backjump from dyndisk_handler
  361.         push    ebp
  362.         mov     ebp, ecx
  363.         call    kernel_free
  364.         mov     edi, [ebx+16]   ; buffer
  365.         cmp     byte [ebx], 5
  366.         jz      .deviceInfo
  367.         cmp     byte [ebx], 1   ; read folder?
  368.         jnz     .access_denied
  369.         push    ebp
  370.         pushd   [ebx+4]         ; first block
  371.         mov     ebp, [ebx+12]   ; the number of blocks to read
  372.         mov     ebx, [ebx+8]    ; flags
  373.         mov     ecx, 32/4
  374.         mov     edx, edi
  375.         xor     eax, eax
  376.         rep stosd
  377.         mov     byte [edx], 1   ; version
  378. .maindir_loop:
  379.         call    esi
  380.         jc      .maindir_done
  381.         inc     dword[edx+8]
  382.         dec     dword[esp]
  383.         jns     .maindir_loop
  384.         dec     ebp
  385.         js      .maindir_loop
  386.         inc     dword[edx+4]
  387.         mov     dword[edi], 16      ; attributes: folder
  388.         mov     dword[edi+4], ebx   ; name encoding
  389.         push    eax
  390.         mov     ecx, 32/4
  391.         add     edi, 8
  392.         xor     eax, eax
  393.         rep stosd
  394.         pop     eax
  395.         push    eax edx edi
  396. ; convert number in eax to decimal string
  397.         push    -'0'
  398.         mov     ecx, 10
  399. @@:
  400.         xor     edx, edx
  401.         div     ecx
  402.         push    edx
  403.         test    eax, eax
  404.         jnz     @b
  405.         cmp     ebx, 2
  406.         jz      .uni
  407. @@:
  408.         pop     eax
  409.         add     eax, '0'
  410.         stosb
  411.         test    eax, eax
  412.         jnz     @b
  413.         pop     edi edx eax
  414.         cmp     ebx, 3
  415.         jz      @f
  416.         add     edi, 264
  417.         jmp     .maindir_loop
  418.  
  419. .uni:
  420.         pop     eax
  421.         add     eax, '0'
  422.         stosw
  423.         test    eax, eax
  424.         jnz     .uni
  425.         pop     edi edx eax
  426. @@:
  427.         add     edi, 520
  428.         jmp     .maindir_loop
  429.  
  430. .maindir_done:
  431.         pop     eax eax
  432.         mov     ebx, [edx+4]
  433.         xor     eax, eax
  434.         dec     ebp
  435.         js      @f
  436.         mov     al, ERROR_END_OF_FILE
  437. @@:
  438.         mov     [image_of_eax], eax
  439.         mov     [image_of_ebx], ebx
  440.         ret
  441.  
  442. .access_denied:
  443.         mov     dword[image_of_eax], ERROR_ACCESS_DENIED
  444.         ret
  445.  
  446. .deviceInfo:
  447.         test    ebp, ebp
  448.         jz      @f
  449.         mov     eax, dword[ebp+DISK.MediaInfo.Capacity]
  450.         mov     edx, dword[ebp+DISK.MediaInfo.Capacity+4]
  451.         shld    edx, eax, 9
  452.         shl     eax, 9
  453.         mov     [edi+36], edx
  454.         mov     [edi+32], eax
  455. @@:
  456.         and     dword[image_of_eax], 0
  457.         ret
  458.  
  459. .rootdir:   ; / - virtual root folder
  460.         cmp     byte [ebx], 5
  461.         jz      @b
  462.         cmp     byte [ebx], 1   ; read folder?
  463.         jnz     .access_denied
  464.         mov     ebp, [ebx+12]   ; number of blocks
  465.         mov     edx, [ebx+16]   ; return area
  466.         push    dword[ebx+4]    ; first block
  467.         mov     ebx, [ebx+8]    ; flags
  468.         mov     ecx, 32/4
  469.         mov     edi, edx
  470.         xor     eax, eax
  471.         rep stosd
  472.         mov     byte [edx], 1   ; version
  473.         sub     esp, 16
  474. .rootdir_loop:
  475.         push    edi
  476.         lea     edi, [esp+4]
  477.         call    dyndisk_enum_root
  478.         pop     edi
  479.         test    eax, eax
  480.         jz      .rootdirCD
  481.         inc     dword[edx+8]
  482.         dec     dword[esp+16]
  483.         jns     .rootdir_loop
  484.         dec     ebp
  485.         js      .rootdir_loop
  486.         inc     dword[edx+4]
  487.         mov     dword[edi], 16      ; attributes: folder
  488.         mov     dword[edi+4], ebx   ; name encoding
  489.         push    eax
  490.         mov     ecx, 32/4
  491.         add     edi, 8
  492.         xor     eax, eax
  493.         rep stosd
  494.         push    edi
  495.         lea     esi, [esp+8]
  496.         cmp     ebx, 2
  497.         jz      .uni2
  498. @@:
  499.         lodsb
  500.         stosb
  501.         test    eax, eax
  502.         jnz     @b
  503.         pop     edi eax
  504.         cmp     ebx, 3
  505.         jz      @f
  506.         add     edi, 264
  507.         jmp     .rootdir_loop
  508.  
  509. .uni2:
  510.         lodsb
  511.         stosw
  512.         test    eax, eax
  513.         jnz     .uni2
  514.         pop     edi eax
  515. @@:
  516.         add     edi, 520
  517.         jmp     .rootdir_loop
  518.  
  519. .rootdirCD:
  520.         add     esp, 16
  521.         or      esi, -1
  522. .rootdirCD_loop:
  523.         inc     esi
  524.         cmp     esi, 10
  525.         jnc     .rootdir_done
  526.         mov     eax, esi
  527.         not     eax
  528.         and     eax, 3
  529.         shl     eax, 1
  530.         inc     eax
  531.         mov     ecx, esi
  532.         shr     ecx, 2
  533.         bt      [ecx*5+DRIVE_DATA+1], ax
  534.         jnc     .rootdirCD_loop
  535.         inc     dword[edx+8]
  536.         dec     dword[esp]
  537.         jns     .rootdirCD_loop
  538.         dec     ebp
  539.         js      .rootdirCD_loop
  540.         inc     dword[edx+4]
  541.         mov     dword[edi], 16      ; attributes: folder
  542.         mov     dword[edi+4], ebx   ; name encoding
  543.         mov     ecx, 32/4
  544.         add     edi, 8
  545.         xor     eax, eax
  546.         rep stosd
  547.         mov     eax, esi
  548.         add     eax, '0'
  549.         cmp     ebx, 1
  550.         jz      @f
  551.         mov     word [edi], 'cd'
  552.         mov     [edi+2], ax
  553.         add     edi, 264
  554.         jmp     .rootdirCD_loop
  555.  
  556. @@:
  557.         mov     dword[edi], 640063h
  558.         mov     [edi+4], eax
  559.         add     edi, 520
  560.         jmp     .rootdirCD_loop
  561.  
  562. .rootdir_done:
  563.         pop     eax
  564.         mov     ebx, [edx+4]
  565.         xor     eax, eax
  566.         dec     ebp
  567.         js      @f
  568.         mov     al, ERROR_END_OF_FILE
  569. @@:
  570.         mov     [image_of_eax], eax
  571.         mov     [image_of_ebx], ebx
  572.         ret
  573.  
  574. ;-----------------------------------------------------------------------------
  575. process_replace_file_name:
  576. ; in: [esi] = virtual path
  577. ; out: [esi]+[ebp] = physical path
  578.         xor     edi, edi
  579.         xor     ebp, ebp
  580. .loop:
  581.         cmp     edi, [full_file_name_table.size]
  582.         jae     .notfound
  583.         push    esi edi
  584.         shl     edi, 7
  585.         add     edi, [full_file_name_table]
  586. @@:
  587.         cmp     byte [edi], 0
  588.         jz      .dest_done
  589.         lodsb
  590.         test    al, al
  591.         jz      .cont
  592.         scasb
  593.         jz      @b
  594.         or      al, 20h
  595.         cmp     [edi-1], al
  596.         jz      @b
  597. .cont:
  598.         pop     edi esi
  599.         inc     edi
  600.         jmp     .loop
  601.  
  602. .dest_done:
  603.         cmp     byte [esi], 0
  604.         jz      .found
  605.         cmp     byte [esi], '/'
  606.         jnz     .cont
  607. .found:
  608.         pop     edi eax
  609.         shl     edi, 7
  610.         add     edi, [full_file_name_table]
  611.         mov     ebp, esi
  612.         lea     esi, [edi+64]
  613. .notfound:
  614.         ret
  615.  
  616. ;-----------------------------------------------------------------------------
  617. uglobal
  618. addDirSeal db  ?
  619. endg
  620.  
  621. sys_current_directory:  ; sysfunction 30
  622.         mov     eax, [current_slot]
  623.         mov     edi, [eax+APPDATA.cur_dir]
  624.         xor     eax, eax
  625.         dec     ebx
  626.         jz      .set
  627.         dec     ebx
  628.         jz      .get
  629.         dec     ebx
  630.         jz      .mount_additional_directory
  631.         mov     eax, edx
  632.         dec     ebx
  633.         jz      .set
  634.         mov     eax, esi
  635.         dec     ebx
  636.         jz      .get
  637. @@:
  638.         ret
  639.  
  640. .mount_additional_directory:
  641. ; in: ecx -> dir name+dir path (128)
  642.         mov     al, 1
  643.         xchg    [addDirSeal], al
  644.         test    al, al
  645.         jnz     @b
  646.         mov     esi, ecx
  647.         mov     edi, sysdir_name1
  648.         mov     ecx, 64
  649.         rep movsb   ; copying fake directory name
  650.         mov     byte [edi-1], 0
  651.         mov     cl, 63
  652.         call    cp866toUTF8_string
  653.         mov     byte [edi], 0
  654.         mov     [full_file_name_table.size], 2
  655.         ret
  656.  
  657. .get:
  658. ; in: ecx -> buffer, edx = length, eax = encoding
  659.         stdcall is_region_userspace, ecx, edx
  660.         jz      @f
  661.  
  662.         ; if illegal buffer given
  663.         xor     edx, edx
  664.         jmp     .ret
  665. @@:
  666.  
  667.         mov     esi, edi
  668.         inc     esi
  669.         mov     edi, ecx
  670.         cmp     edx, maxPathLength
  671.         jc      @f
  672.         mov     edx, maxPathLength
  673. @@:
  674.         mov     ecx, edx
  675.         jecxz   .ret
  676.         cmp     eax, 2
  677.         jz      .get16
  678.         cmp     eax, 3
  679.         jz      .get8
  680. @@:
  681.         dec     ecx
  682.         js      @f
  683.         call    utf8to16
  684.         call    uni2ansi_char
  685.         stosb
  686.         test    al, al
  687.         jnz     @b
  688.         sub     edx, ecx
  689. @@:
  690.         mov     byte [edi-1], 0
  691. .ret:
  692.         mov     [esp+32], edx
  693.         ret
  694.  
  695. .get8:
  696.         push    edi
  697.         mov     edi, esi
  698.         xor     eax, eax
  699.         repnz scasb
  700.         sub     edx, ecx
  701.         mov     ecx, edx
  702.         pop     edi
  703.         rep movsb
  704.         jmp     @b
  705.  
  706. .get16:
  707.         shr     ecx, 1
  708.         shr     edx, 1
  709. @@:
  710.         dec     ecx
  711.         js      @f
  712.         call    utf8to16
  713.         stosw
  714.         test    ax, ax
  715.         jnz     @b
  716.         sub     edx, ecx
  717. @@:
  718.         shl     edx, 1
  719.         mov     word [edi-2], 0
  720.         jmp     .ret
  721.  
  722. .set:
  723.         mov     esi, ecx
  724. getFullPath:
  725. ; in: esi -> file path, eax = string encoding, edi -> destination
  726. ; out: UTF-8 string (with marker), eax = length, 0 -> error
  727.         test    eax, eax
  728.         jnz     @f
  729.         cmp     byte [esi], 4
  730.         jnc     @f
  731.         cmp     byte [esi], 0
  732.         jz      @f
  733.         lodsb
  734. @@:
  735.         cmp     byte [esi], '/'
  736.         jnz     .relative
  737.         cmp     eax, 2
  738.         jnz     @f
  739.         cmp     word [esi], '/'
  740.         jnz     .relative
  741.         inc     esi
  742.         inc     esi
  743.         jmp     .start
  744.  
  745. @@:
  746.         inc     esi
  747.         cmp     byte [esi], 4
  748.         jnc     .start
  749.         lodsb
  750.         cmp     byte [esi], '/'
  751.         jnz     .start
  752.         inc     esi
  753. .start:
  754.         push    eax edi
  755.         call    process_replace_file_name
  756.         mov     edi, [esp]
  757.         mov     ecx, maxPathLength
  758.         mov     al, 3
  759.         mov     ah, '/'
  760.         stosw
  761.         sub     ecx, 2
  762.         test    ebp, ebp
  763.         jz      .absolute
  764. @@:
  765.         lodsb
  766.         stosb
  767.         dec     ecx
  768.         test    al, al
  769.         jnz     @b
  770.         mov     esi, ebp
  771.         dec     edi
  772. .absolute:
  773.         cmp     byte [esp+4], 2
  774.         jz      .utf16
  775.         cmp     byte [esp+4], 3
  776.         jz      .utf8
  777.         call    cp866toUTF8_string
  778.         jns     .end
  779.         jmp     .fail
  780.  
  781. .utf8:
  782.         dec     ecx
  783.         js      .fail
  784.         lodsb
  785.         stosb
  786.         test    al, al
  787.         jz      .end
  788.         jmp     .utf8
  789.  
  790. .utf16:
  791.         call    UTF16to8_string
  792.         jns     .end
  793. .fail:
  794.         mov     byte [edi], 0
  795.         pop     eax eax
  796.         xor     eax, eax
  797.         ret
  798.  
  799. .relative:
  800.         push    eax edi
  801.         mov     ebx, esi
  802.         mov     edi, [current_slot]
  803.         mov     edi, [edi+APPDATA.cur_dir]
  804.         mov     edx, edi
  805.         mov     ecx, maxPathLength
  806.         xor     eax, eax
  807.         repnz scasb
  808.         mov     esi, edi
  809.         mov     edi, [esp]
  810.         jecxz   .fail
  811.         cmp     byte [ebx], 0
  812.         jz      .set_ok
  813.         dec     esi
  814.         cmp     edx, edi    ; is destination equal to cur_dir?
  815.         mov     edi, esi
  816.         jz      @f
  817.         mov     edi, [esp]
  818.         mov     ecx, esi
  819.         sub     ecx, edx
  820.         mov     esi, edx
  821.         mov     edx, edi
  822.         rep movsb
  823. @@:
  824.         mov     byte [edi], '/'
  825.         inc     edi
  826.         mov     esi, ebx
  827.         mov     ecx, edx
  828.         add     ecx, maxPathLength
  829.         sub     ecx, edi
  830.         jmp     .absolute
  831.  
  832. .set_ok:
  833.         cmp     edx, edi    ; is destination equal to cur_dir?
  834.         jz      @f
  835.         mov     ecx, esi
  836.         sub     ecx, edx
  837.         mov     esi, edx
  838.         rep movsb
  839. @@:
  840.         pop     eax
  841.         sub     edi, eax
  842.         pop     eax
  843.         mov     eax, edi
  844.         ret
  845.  
  846. .end:
  847.         or      ecx, -1
  848.         mov     edi, [esp]
  849.         xor     eax, eax
  850.         push    edi
  851.         repnz scasb
  852.         not     ecx
  853.         pop     edi
  854. .parse:
  855.         mov     al, '/'
  856.         repnz scasb
  857.         jecxz   @b
  858.         cmp     byte [edi], '.'
  859.         jnz     .parse
  860.         mov     esi, edi
  861. @@:
  862.         lodsw
  863.         sub     ecx, 2
  864.         cmp     ax, './'
  865.         jz      @b
  866.         cmp     ax, '..'
  867.         jnz     @f
  868.         cmp     byte [esi], '/'
  869.         jnz     @f
  870.         mov     edx, ecx
  871.         mov     ecx, edi
  872.         sub     ecx, [esp]
  873.         sub     ecx, 2
  874.         jc      .fail
  875.         sub     edi, 2
  876.         lodsb
  877.         dec     edx
  878.         std
  879.         repnz scasb
  880.         cld
  881.         add     edi, 2
  882.         mov     ecx, edx
  883.         jmp     @b
  884.  
  885. @@:
  886.         sub     esi, 2
  887.         add     ecx, 2
  888.         cmp     esi, edi
  889.         jz      .parse
  890.         push    edi ecx
  891.         rep movsb
  892.         pop     ecx edi
  893.         jmp     .parse
  894.  
  895. include "parse_fn.inc"
  896. include "fs_common.inc"
  897. include "iso9660.inc"   ; read for CD filesystem
  898. include "fat.inc"
  899. include "exfat.inc"
  900. include "ntfs.inc"
  901. include "ext.inc"
  902. include "xfs.asm"
  903.