Subversion Repositories Kolibri OS

Rev

Rev 10016 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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