Subversion Repositories Kolibri OS

Rev

Rev 9894 | 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: 10016 $
  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.         mov     ecx, [ebp + DISK.MediaInfo.SectorSize]
  452.         bsf     ecx, ecx
  453.         shld    edx, eax, cl
  454.         shl     eax, cl
  455.         mov     [edi+36], edx
  456.         mov     [edi+32], eax
  457. @@:
  458.         and     dword[image_of_eax], 0
  459.         ret
  460.  
  461. .rootdir:   ; / - virtual root folder
  462.         cmp     byte [ebx], 5
  463.         jz      @b
  464.         cmp     byte [ebx], 1   ; read folder?
  465.         jnz     .access_denied
  466.         mov     ebp, [ebx+12]   ; number of blocks
  467.         mov     edx, [ebx+16]   ; return area
  468.         push    dword[ebx+4]    ; first block
  469.         mov     ebx, [ebx+8]    ; flags
  470.         mov     ecx, 32/4
  471.         mov     edi, edx
  472.         xor     eax, eax
  473.         rep stosd
  474.         mov     byte [edx], 1   ; version
  475.         sub     esp, 16
  476. .rootdir_loop:
  477.         push    edi
  478.         lea     edi, [esp+4]
  479.         call    dyndisk_enum_root
  480.         pop     edi
  481.         test    eax, eax
  482.         jz      .rootdirCD
  483.         inc     dword[edx+8]
  484.         dec     dword[esp+16]
  485.         jns     .rootdir_loop
  486.         dec     ebp
  487.         js      .rootdir_loop
  488.         inc     dword[edx+4]
  489.         mov     dword[edi], 16      ; attributes: folder
  490.         mov     dword[edi+4], ebx   ; name encoding
  491.         push    eax
  492.         mov     ecx, 32/4
  493.         add     edi, 8
  494.         xor     eax, eax
  495.         rep stosd
  496.         push    edi
  497.         lea     esi, [esp+8]
  498.         cmp     ebx, 2
  499.         jz      .uni2
  500. @@:
  501.         lodsb
  502.         stosb
  503.         test    eax, eax
  504.         jnz     @b
  505.         pop     edi eax
  506.         cmp     ebx, 3
  507.         jz      @f
  508.         add     edi, 264
  509.         jmp     .rootdir_loop
  510.  
  511. .uni2:
  512.         lodsb
  513.         stosw
  514.         test    eax, eax
  515.         jnz     .uni2
  516.         pop     edi eax
  517. @@:
  518.         add     edi, 520
  519.         jmp     .rootdir_loop
  520.  
  521. .rootdirCD:
  522.         add     esp, 16
  523.         or      esi, -1
  524. .rootdirCD_loop:
  525.         inc     esi
  526.         cmp     esi, 10
  527.         jnc     .rootdir_done
  528.         mov     eax, esi
  529.         not     eax
  530.         and     eax, 3
  531.         shl     eax, 1
  532.         inc     eax
  533.         mov     ecx, esi
  534.         shr     ecx, 2
  535.         bt      [ecx*5+DRIVE_DATA+1], ax
  536.         jnc     .rootdirCD_loop
  537.         inc     dword[edx+8]
  538.         dec     dword[esp]
  539.         jns     .rootdirCD_loop
  540.         dec     ebp
  541.         js      .rootdirCD_loop
  542.         inc     dword[edx+4]
  543.         mov     dword[edi], 16      ; attributes: folder
  544.         mov     dword[edi+4], ebx   ; name encoding
  545.         mov     ecx, 32/4
  546.         add     edi, 8
  547.         xor     eax, eax
  548.         rep stosd
  549.         mov     eax, esi
  550.         add     eax, '0'
  551.         cmp     ebx, 1
  552.         jz      @f
  553.         mov     word [edi], 'cd'
  554.         mov     [edi+2], ax
  555.         add     edi, 264
  556.         jmp     .rootdirCD_loop
  557.  
  558. @@:
  559.         mov     dword[edi], 640063h
  560.         mov     [edi+4], eax
  561.         add     edi, 520
  562.         jmp     .rootdirCD_loop
  563.  
  564. .rootdir_done:
  565.         pop     eax
  566.         mov     ebx, [edx+4]
  567.         xor     eax, eax
  568.         dec     ebp
  569.         js      @f
  570.         mov     al, ERROR_END_OF_FILE
  571. @@:
  572.         mov     [image_of_eax], eax
  573.         mov     [image_of_ebx], ebx
  574.         ret
  575.  
  576. ;-----------------------------------------------------------------------------
  577. process_replace_file_name:
  578. ; in: [esi] = virtual path
  579. ; out: [esi]+[ebp] = physical path
  580.         xor     edi, edi
  581.         xor     ebp, ebp
  582. .loop:
  583.         cmp     edi, [full_file_name_table.size]
  584.         jae     .notfound
  585.         push    esi edi
  586.         shl     edi, 7
  587.         add     edi, [full_file_name_table]
  588. @@:
  589.         cmp     byte [edi], 0
  590.         jz      .dest_done
  591.         lodsb
  592.         test    al, al
  593.         jz      .cont
  594.         scasb
  595.         jz      @b
  596.         or      al, 20h
  597.         cmp     [edi-1], al
  598.         jz      @b
  599. .cont:
  600.         pop     edi esi
  601.         inc     edi
  602.         jmp     .loop
  603.  
  604. .dest_done:
  605.         cmp     byte [esi], 0
  606.         jz      .found
  607.         cmp     byte [esi], '/'
  608.         jnz     .cont
  609. .found:
  610.         pop     edi eax
  611.         shl     edi, 7
  612.         add     edi, [full_file_name_table]
  613.         mov     ebp, esi
  614.         lea     esi, [edi+64]
  615. .notfound:
  616.         ret
  617.  
  618. ;-----------------------------------------------------------------------------
  619. uglobal
  620. addDirSeal db  ?
  621. endg
  622.  
  623. sys_current_directory:  ; sysfunction 30
  624.         mov     eax, [current_slot]
  625.         mov     edi, [eax+APPDATA.cur_dir]
  626.         xor     eax, eax
  627.         dec     ebx
  628.         jz      .set
  629.         dec     ebx
  630.         jz      .get
  631.         dec     ebx
  632.         jz      .mount_additional_directory
  633.         mov     eax, edx
  634.         dec     ebx
  635.         jz      .set
  636.         mov     eax, esi
  637.         dec     ebx
  638.         jz      .get
  639. @@:
  640.         ret
  641.  
  642. .mount_additional_directory:
  643. ; in: ecx -> dir name+dir path (128)
  644.         mov     al, 1
  645.         xchg    [addDirSeal], al
  646.         test    al, al
  647.         jnz     @b
  648.         mov     esi, ecx
  649.         mov     edi, sysdir_name1
  650.         mov     ecx, 64
  651.         rep movsb   ; copying fake directory name
  652.         mov     byte [edi-1], 0
  653.         mov     cl, 63
  654.         call    cp866toUTF8_string
  655.         mov     byte [edi], 0
  656.         mov     [full_file_name_table.size], 2
  657.         ret
  658.  
  659. .get:
  660. ; in: ecx -> buffer, edx = length, eax = encoding
  661.         stdcall is_region_userspace, ecx, edx
  662.         jz      @f
  663.  
  664.         ; if illegal buffer given
  665.         xor     edx, edx
  666.         jmp     .ret
  667. @@:
  668.  
  669.         mov     esi, edi
  670.         inc     esi
  671.         mov     edi, ecx
  672.         cmp     edx, maxPathLength
  673.         jc      @f
  674.         mov     edx, maxPathLength
  675. @@:
  676.         mov     ecx, edx
  677.         jecxz   .ret
  678.         cmp     eax, 2
  679.         jz      .get16
  680.         cmp     eax, 3
  681.         jz      .get8
  682. @@:
  683.         dec     ecx
  684.         js      @f
  685.         call    utf8to16
  686.         call    uni2ansi_char
  687.         stosb
  688.         test    al, al
  689.         jnz     @b
  690.         sub     edx, ecx
  691. @@:
  692.         mov     byte [edi-1], 0
  693. .ret:
  694.         mov     [esp+32], edx
  695.         ret
  696.  
  697. .get8:
  698.         push    edi
  699.         mov     edi, esi
  700.         xor     eax, eax
  701.         repnz scasb
  702.         sub     edx, ecx
  703.         mov     ecx, edx
  704.         pop     edi
  705.         rep movsb
  706.         jmp     @b
  707.  
  708. .get16:
  709.         shr     ecx, 1
  710.         shr     edx, 1
  711. @@:
  712.         dec     ecx
  713.         js      @f
  714.         call    utf8to16
  715.         stosw
  716.         test    ax, ax
  717.         jnz     @b
  718.         sub     edx, ecx
  719. @@:
  720.         shl     edx, 1
  721.         mov     word [edi-2], 0
  722.         jmp     .ret
  723.  
  724. .set:
  725.         mov     esi, ecx
  726. getFullPath:
  727. ; in: esi -> file path, eax = string encoding, edi -> destination
  728. ; out: UTF-8 string (with marker), eax = length, 0 -> error
  729.         test    eax, eax
  730.         jnz     @f
  731.         cmp     byte [esi], 4
  732.         jnc     @f
  733.         cmp     byte [esi], 0
  734.         jz      @f
  735.         lodsb
  736. @@:
  737.         cmp     byte [esi], '/'
  738.         jnz     .relative
  739.         cmp     eax, 2
  740.         jnz     @f
  741.         cmp     word [esi], '/'
  742.         jnz     .relative
  743.         inc     esi
  744.         inc     esi
  745.         jmp     .start
  746.  
  747. @@:
  748.         inc     esi
  749.         cmp     byte [esi], 4
  750.         jnc     .start
  751.         lodsb
  752.         cmp     byte [esi], '/'
  753.         jnz     .start
  754.         inc     esi
  755. .start:
  756.         push    eax edi
  757.         call    process_replace_file_name
  758.         mov     edi, [esp]
  759.         mov     ecx, maxPathLength
  760.         mov     al, 3
  761.         mov     ah, '/'
  762.         stosw
  763.         sub     ecx, 2
  764.         test    ebp, ebp
  765.         jz      .absolute
  766. @@:
  767.         lodsb
  768.         stosb
  769.         dec     ecx
  770.         test    al, al
  771.         jnz     @b
  772.         mov     esi, ebp
  773.         dec     edi
  774. .absolute:
  775.         cmp     byte [esp+4], 2
  776.         jz      .utf16
  777.         cmp     byte [esp+4], 3
  778.         jz      .utf8
  779.         call    cp866toUTF8_string
  780.         jns     .end
  781.         jmp     .fail
  782.  
  783. .utf8:
  784.         dec     ecx
  785.         js      .fail
  786.         lodsb
  787.         stosb
  788.         test    al, al
  789.         jz      .end
  790.         jmp     .utf8
  791.  
  792. .utf16:
  793.         call    UTF16to8_string
  794.         jns     .end
  795. .fail:
  796.         mov     byte [edi], 0
  797.         pop     eax eax
  798.         xor     eax, eax
  799.         ret
  800.  
  801. .relative:
  802.         push    eax edi
  803.         mov     ebx, esi
  804.         mov     edi, [current_slot]
  805.         mov     edi, [edi+APPDATA.cur_dir]
  806.         mov     edx, edi
  807.         mov     ecx, maxPathLength
  808.         xor     eax, eax
  809.         repnz scasb
  810.         mov     esi, edi
  811.         mov     edi, [esp]
  812.         jecxz   .fail
  813.         cmp     byte [ebx], 0
  814.         jz      .set_ok
  815.         dec     esi
  816.         cmp     edx, edi    ; is destination equal to cur_dir?
  817.         mov     edi, esi
  818.         jz      @f
  819.         mov     edi, [esp]
  820.         mov     ecx, esi
  821.         sub     ecx, edx
  822.         mov     esi, edx
  823.         mov     edx, edi
  824.         rep movsb
  825. @@:
  826.         mov     byte [edi], '/'
  827.         inc     edi
  828.         mov     esi, ebx
  829.         mov     ecx, edx
  830.         add     ecx, maxPathLength
  831.         sub     ecx, edi
  832.         jmp     .absolute
  833.  
  834. .set_ok:
  835.         cmp     edx, edi    ; is destination equal to cur_dir?
  836.         jz      @f
  837.         mov     ecx, esi
  838.         sub     ecx, edx
  839.         mov     esi, edx
  840.         rep movsb
  841. @@:
  842.         pop     eax
  843.         sub     edi, eax
  844.         pop     eax
  845.         mov     eax, edi
  846.         ret
  847.  
  848. .end:
  849.         or      ecx, -1
  850.         mov     edi, [esp]
  851.         xor     eax, eax
  852.         push    edi
  853.         repnz scasb
  854.         not     ecx
  855.         pop     edi
  856. .parse:
  857.         mov     al, '/'
  858.         repnz scasb
  859.         jecxz   @b
  860.         cmp     byte [edi], '.'
  861.         jnz     .parse
  862.         mov     esi, edi
  863. @@:
  864.         lodsw
  865.         sub     ecx, 2
  866.         cmp     ax, './'
  867.         jz      @b
  868.         cmp     ax, '..'
  869.         jnz     @f
  870.         cmp     byte [esi], '/'
  871.         jnz     @f
  872.         mov     edx, ecx
  873.         mov     ecx, edi
  874.         sub     ecx, [esp]
  875.         sub     ecx, 2
  876.         jc      .fail
  877.         sub     edi, 2
  878.         lodsb
  879.         dec     edx
  880.         std
  881.         repnz scasb
  882.         cld
  883.         add     edi, 2
  884.         mov     ecx, edx
  885.         jmp     @b
  886.  
  887. @@:
  888.         sub     esi, 2
  889.         add     ecx, 2
  890.         cmp     esi, edi
  891.         jz      .parse
  892.         push    edi ecx
  893.         rep movsb
  894.         pop     ecx edi
  895.         jmp     .parse
  896.  
  897. include "parse_fn.inc"
  898. include "fs_common.inc"
  899. include "iso9660.inc"   ; read for CD filesystem
  900. include "fat.inc"
  901. include "exfat.inc"
  902. include "ntfs.inc"
  903. include "ext.inc"
  904. include "xfs.asm"
  905.