Subversion Repositories Kolibri OS

Rev

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

  1. delete_file_worker:
  2. ; in: ecx=flags: 1=deleting directory
  3. ; out: eax=0 - OK, eax=1 - retry, eax=2 - skip, eax=-1 - cancel,
  4. ;      PF, ZF, CF and SF set accordingly to 'cmp eax,2' (or 'cmp al,2')
  5.         push    ebx
  6.         push    70
  7.         pop     eax
  8.         mov     ebx, delinfo
  9.         int     0x40
  10.         pop     ebx
  11.         test    eax, eax
  12.         jz      .ret
  13.         cmp     [del_bSkipAll], 0
  14.         jz      @f
  15.         push    2
  16.         pop     eax
  17.         jmp     .ret
  18. @@:
  19.         push    execdata
  20.         push    aCannotDeleteFolder
  21.         test    cl, 1
  22.         jnz     @f
  23.         mov     dword [esp], aCannotDeleteFile
  24. @@:
  25.         call    get_error_msg
  26.         push    eax
  27.         mov     eax, esp
  28.         push    DeleteErrorBtn
  29.         push    4
  30.         push    eax
  31.         push    3
  32.         call    SayErr
  33.         add     esp, 3*4
  34.         cmp     al, -1
  35.         jz      @f
  36.         inc     eax
  37.         cmp     al, 4   ; "cancel" button
  38.         jnz     @f
  39.         or      eax, -1
  40. @@:
  41.         cmp     al, 3   ; "skip all" button
  42.         jnz     .ret
  43.         mov     [del_bSkipAll], 1
  44.         dec     eax
  45. .ret:
  46.         cmp     al, 2
  47.         ret
  48.  
  49. delete_file:
  50. ; in: eax->BDFE block
  51. ; out: CF and ZF not set <=> cancel job ("ja cancel_label")
  52.         pushad
  53.         mov     [del_dir_stack_ptr], del_dir_stack
  54.         lea     esi, [ebp + panel1_dir - panel1_data]
  55.         mov     edi, execdata
  56. @@:
  57.         lodsb
  58.         test    al, al
  59.         jz      @f
  60.         stosb
  61.         jmp     @b
  62. @@:
  63.         mov     esi, [esp+28]
  64.         mov     ecx, esi
  65.         add     esi, 40
  66.         cmp     byte [edi-1], '/'
  67.         jz      .l1
  68.         mov     al, '/'
  69.         stosb
  70. .l1:
  71.         lodsb
  72.         cmp     edi, execdataend
  73.         jb      @f
  74.         call    panels_OnKey.bigfilename
  75.         popad
  76.         ret
  77. @@:
  78.         stosb
  79.         test    al, al
  80.         jnz     .l1
  81.         mov     ecx, [esp+28]
  82.         test    byte [ecx], 10h
  83.         jnz     .delete_dir
  84. .retrydel:
  85.         xor     ecx, ecx
  86.         call    delete_file_worker
  87.         jae     @f
  88.         jp      .retrydel
  89. @@:
  90.         popad
  91.         ret
  92.  
  93. .delete_dir:
  94. ; recursive delete of directory
  95.         xor     ebp, ebp        ; ebp will contain number of undeletable items
  96. .return_from_recursion:
  97.         mov     ebx, dirinfo
  98.         mov     [ebx+dirinfo.first-dirinfo], ebp
  99.         mov     [ebx+dirinfo.size-dirinfo], del_dir_query_size
  100.         mov     [ebx+dirinfo.dirdata-dirinfo], del_dir_query_area
  101.         mov     [ebx+dirinfo.name-dirinfo], execdata
  102.         push    70
  103.         pop     eax
  104.         int     0x40
  105. ; if we get read error, the best available action is try to delete directory itself
  106.         test    eax, eax
  107.         jz      @f
  108.         cmp     eax, 6
  109.         jnz     .do_delete_dir
  110. @@:
  111. ; loop through a directory and delete items
  112.         mov     edx, del_dir_query_area+32
  113.         imul    ebx, 304
  114.         add     ebx, edx
  115. .delete_dir_entry_loop:
  116.         cmp     edx, ebx
  117.         jb      .do_delete_dir_entry
  118.         cmp     ebx, del_dir_query_area+32+304*del_dir_query_size
  119.         jnz     .delete_dir_entry_done
  120.         jmp     .return_from_recursion
  121. .do_delete_dir_entry:
  122. ; ignore special entries "." and ".."
  123.         inc     ebp
  124.         cmp     word [edx+40], '.'
  125.         jz      .delete_dir_entry_continue
  126.         cmp     word [edx+40], '..'
  127.         jnz     @f
  128.         cmp     byte [edx+42], 0
  129.         jz      .delete_dir_entry_continue
  130. @@:
  131.         dec     ebp
  132.         mov     esi, execdata
  133. @@:
  134.         lodsb
  135.         test    al, al
  136.         jnz     @b
  137.         mov     byte [esi-1], '/'
  138.         mov     edi, esi
  139.         lea     esi, [edx+40]
  140. @@:
  141.         cmp     edi, execdataend
  142.         jae     .fullname_big
  143.         lodsb
  144.         stosb
  145.         test    al, al
  146.         jnz     @b
  147.         test    byte [edx], 10h
  148.         jnz     .entry_is_folder
  149. .retry2:
  150.         xor     ecx, ecx
  151.         call    delete_file_worker
  152.         ja      .cancel
  153.         jz      .skip
  154.         jp      .retry2
  155.         jmp     .restore_name
  156. .entry_is_folder:
  157. ; allocate new item in directory stack
  158.         mov     eax, [del_dir_stack_ptr]
  159.         mov     [eax], ebp
  160.         add     eax, 4
  161.         mov     [del_dir_stack_ptr], eax
  162. ; do recursive deleting
  163.         jmp     .delete_dir
  164. .fullname_big:
  165. ; we will just ignore such files and continue - in real life this situation can not happen
  166.         inc     ebp
  167.         mov     esi, execdataend-1
  168.         jmp     .do_restore_name
  169. .skip:
  170.         inc     ebp
  171. .restore_name:
  172.         mov     esi, execdata
  173. @@:
  174.         lodsb
  175.         test    al, al
  176.         jnz     @b
  177.         dec     esi
  178.         dec     esi
  179. .do_restore_name:
  180.         call    delete_last_name
  181. .delete_dir_entry_continue:
  182.         add     edx, 304
  183.         jmp     .delete_dir_entry_loop
  184. .delete_dir_entry_done:
  185. .do_delete_dir:
  186.         mov     cl, 1
  187.         call    delete_file_worker
  188.         ja      .cancel
  189.         jz      @f
  190.         jp      .delete_dir
  191. @@:
  192. ; al=0 - OK, al=2 - skip this directory
  193. ; return to previous directory
  194. ; pop item from directory stack
  195.         mov     ecx, [del_dir_stack_ptr]
  196.         cmp     ecx, del_dir_stack
  197.         jbe     .done
  198.         sub     ecx, 4
  199.         mov     [del_dir_stack_ptr], ecx
  200.         mov     ebp, [ecx]
  201.         cmp     al, 2
  202.         sbb     ebp, -1
  203. ; restore prev directory name
  204.         mov     esi, execdata
  205.         call    delete_last_name_from_end
  206.         jmp     .return_from_recursion
  207. .done:
  208. .cancel:
  209.         mov     [dirinfo.first], 0      ; do not destroys flags
  210.         popad
  211.         ret
  212.  
  213. makedir:
  214. ; create directory with name from CopyDestEditBuf+12
  215. ; destroys eax
  216.         push    ebx
  217.         push    70
  218.         pop     eax
  219.         mov     ebx, mkdirinfo
  220.         int     0x40
  221.         pop     ebx
  222.         test    eax, eax
  223.         jz      .ret
  224.         cmp     dword [esp+8], DeleteErrorBtn
  225.         jnz     @f
  226.         cmp     [copy_bSkipAll], 0
  227.         jz      @f
  228.         push    1
  229.         pop     eax
  230.         jmp     .ret
  231. @@:
  232.         push    dword CopyDestEditBuf+12
  233.         push    dword aCannotMakeFolder
  234.         call    get_error_msg
  235.         push    eax
  236.         mov     eax, esp
  237.         push    dword [eax+20]
  238.         push    dword [eax+16]
  239.         push    eax
  240.         push    3
  241.         call    SayErr
  242.         add     esp, 3*4
  243.         test    eax, eax
  244.         jz      makedir
  245. .ret:
  246.         ret     8
  247.  
  248. copy_file_worker:
  249. ; in: execdata = source name, CopyDestEditBuf+12 = destination name, edx = BDFE block for source
  250. ; out: CF and ZF not set <=> cancel job ("ja cancel_label")
  251. ; destroys eax,esi,edi
  252.         lea     edi, [edx+40]
  253.         and     [source_hFile], 0
  254. copy_file_worker2:
  255.         push    CopyDestEditBuf+12+513
  256.         cmp     [bDestIsFolder], 0
  257.         jz      .noaddtoname
  258.         mov     esi, CopyDestEditBuf+12
  259. @@:
  260.         lodsb
  261.         test    al, al
  262.         jnz     @b
  263.         pop     eax
  264.         dec     esi
  265.         push    esi
  266.         cmp     byte [esi-1], '/'
  267.         jz      @f
  268.         mov     byte [esi], '/'
  269.         inc     esi
  270. @@:
  271.         xchg    esi, edi
  272. @@:
  273.         cmp     edi, CopyDestEditBuf+12+513
  274.         jae     .overflow
  275.         lodsb
  276.         stosb
  277.         test    al, al
  278.         jnz     @b
  279.         jmp     .noaddtoname
  280. .overflow:
  281. .ret_zf:
  282.         pop     esi
  283.         and     byte [esi], 0           ; ZF=1
  284.         ret
  285. .noaddtoname:
  286. ; ¥«ì§ï ᪮¯¨à®¢ âì ä ©« ¯®¢¥àå á ¬®£® ᥡï!
  287.         mov     esi, execdata
  288.         mov     edi, CopyDestEditBuf+12
  289.         cmp     [source_hModule], 0
  290.         jnz     @f
  291.         push    esi edi
  292.         call    strcmpi
  293.         pop     edi esi
  294.         jnz     @f
  295.         push    esi
  296.         push    aCannotCopyToSelf
  297.         mov     eax, esp
  298.         push    ContinueBtn
  299.         push    1
  300.         push    eax
  301.         push    2
  302.         call    SayErr
  303.         pop     eax
  304.         pop     eax
  305.         jmp     .ret_zf
  306. @@:
  307. ; ‘®¡á⢥­­®, ª®¯¨à㥬
  308. ; esi->source name, edi->destination name
  309.         push    ebx
  310.         mov     [writeinfo.code], 2
  311.         mov     [writeinfo.name], edi
  312.         and     dword [writeinfo.first], 0
  313.         and     dword [writeinfo.first+4], 0
  314.         mov     [writeinfo.data], copy_buffer
  315.         mov     ebx, readinfo
  316.         and     dword [ebx+readinfo.first-readinfo], 0
  317.         and     dword [ebx+readinfo.first+4-readinfo], 0
  318.         mov     [ebx+readinfo.size-readinfo], copy_buffer_size
  319.         mov     [ebx+readinfo.data-readinfo], copy_buffer
  320.         mov     [ebx+readinfo.name-readinfo], esi
  321.         mov     eax, [source_hFile]
  322.         push    eax
  323.         test    eax, eax
  324.         jnz     .copyloop
  325. .source_reopen:
  326.         mov     eax, [source_hModule]
  327.         test    eax, eax
  328.         jz      .copyloop
  329.         pushad
  330.         push    O_READ+O_SEQUENTIAL_ONLY
  331.         push    esi
  332.         push    [source_hPlugin]
  333.         call    [eax+PluginInfo.open]
  334.         mov     [source_hFile], eax
  335.         popad
  336. .copyloop:
  337.         mov     ebx, readinfo
  338.         mov     eax, [source_hModule]
  339.         test    eax, eax
  340.         jz      .native
  341.         mov     ecx, [source_hFile]
  342.         jecxz   .readerr
  343.         pushad
  344.         push    [ebx+readinfo.size-readinfo]
  345.         push    [ebx+readinfo.data-readinfo]
  346.         push    ecx
  347.         call    [eax+PluginInfo.read]
  348.         mov     [esp+28], eax
  349.         popad
  350.         cmp     eax, -1
  351.         jz      .readerr
  352.         mov     ebx, eax
  353.         jmp     .copyreadok
  354. .native:
  355.         push    70
  356.         pop     eax
  357.         int     0x40
  358.         test    eax, eax
  359.         jz      .copyreadok
  360.         cmp     eax, 6
  361.         jz      .copyreadok
  362. .readerr:
  363.         cmp     [copy_bSkipAll2], 0
  364.         jnz     .copyfailed_del2
  365.         push    esi
  366.         push    dword aCannotReadFile
  367.         call    get_error_msg
  368.         push    eax
  369.         mov     eax, esp
  370.         push    dword DeleteErrorBtn
  371.         push    4
  372.         push    eax
  373.         push    3
  374.         call    SayErr
  375.         add     esp, 3*4
  376.         test    eax, eax
  377.         jnz     .copyfailed_parseuser
  378.         cmp     [source_hModule], 0
  379.         jz      .copyloop
  380.         cmp     [source_hFile], 0
  381.         jz      .source_reopen
  382.         jmp     .copyloop
  383. .copyreadok:
  384.         add     dword [readinfo.first], ebx
  385.         adc     dword [readinfo.first+4], 0
  386.         mov     [writeinfo.size], ebx
  387.         test    ebx, ebx
  388.         jnz     .copywrite
  389.         cmp     byte [writeinfo.code], 2
  390.         jnz     .copydone
  391. .copywrite:
  392.         mov     ebx, writeinfo
  393.         push    70
  394.         pop     eax
  395.         int     0x40
  396.         test    eax, eax
  397.         jz      .copywriteok
  398.         cmp     [copy_bSkipAll2], 0
  399.         jnz     .copyfailed_del2
  400.         push    edi
  401.         push    dword aCannotWriteFile
  402.         call    get_error_msg
  403.         push    eax
  404.         mov     eax, esp
  405.         push    dword DeleteErrorBtn
  406.         push    4
  407.         push    eax
  408.         push    3
  409.         call    SayErr
  410.         add     esp, 3*4
  411.         test    eax, eax
  412.         jz      .copywrite
  413. .copyfailed_parseuser:
  414.         cmp     al, 2
  415.         jnz     @f
  416.         mov     [copy_bSkipAll2], 1
  417.         dec     eax
  418. @@:
  419.         cmp     al, 1
  420.         pushf
  421.         jmp     .copyfailed
  422. .copywriteok:
  423.         mov     ecx, [writeinfo.size]
  424.         add     dword [writeinfo.first], ecx
  425.         adc     dword [writeinfo.first+4], 0
  426.         mov     [writeinfo.code], 3
  427.         cmp     ecx, copy_buffer_size
  428.         jz      .copyloop
  429. .copydone:
  430.         pop     ecx
  431.         test    ecx, ecx
  432.         jnz     @f
  433.         mov     eax, [source_hModule]
  434.         test    eax, eax
  435.         jz      @f
  436.         mov     ecx, [source_hFile]
  437.         jecxz   @f
  438.         push    edx
  439.         push    ecx
  440.         call    [eax+PluginInfo.close]
  441.         pop     edx
  442. @@:
  443. ; now try to set attributes from source, ignore errors
  444.         mov     edi, attrinfo.attr
  445.         mov     esi, edx
  446.         push    8
  447.         pop     ecx
  448.         rep     movsd
  449. ; replace zero dates with default values
  450.         mov     eax, [default_attr]
  451.         cmp     dword [edi-32+8], 0
  452.         jnz     @f
  453.         mov     ecx, [eax+8]
  454.         mov     [edi-32+8], ecx
  455.         mov     ecx, [eax+12]
  456.         mov     [edi-32+12], ecx
  457. @@:
  458.         cmp     dword [edi-32+16], 0
  459.         jnz     @f
  460.         mov     ecx, [eax+16]
  461.         mov     [edi-32+16], ecx
  462.         mov     ecx, [eax+20]
  463.         mov     [edi-32+20], ecx
  464. @@:
  465.         cmp     dword [edi-32+24], 0
  466.         jnz     @f
  467.         mov     ecx, [eax+24]
  468.         mov     [edi-32+24], ecx
  469.         mov     ecx, [eax+28]
  470.         mov     [edi-32+28], ecx
  471. @@:
  472.         mov     ebx, attrinfo
  473.         mov     [ebx+attrinfo.name-attrinfo], CopyDestEditBuf+12
  474.         inc     dword [ebx]
  475.         push    70
  476.         pop     eax
  477.         push    ebx
  478.         int     0x40
  479.         pop     ebx
  480.         dec     dword [ebx]
  481.         xor     eax, eax        ; ZF=1
  482. .ret:
  483.         pop     ebx
  484.         pop     esi
  485.         mov     byte [esi], 0
  486.         ret
  487. .copydone2:
  488.         popf
  489.         jmp     .ret
  490. .copyfailed:
  491.         pop     ecx
  492.         test    ecx, ecx
  493.         jnz     @f
  494.         mov     eax, [source_hModule]
  495.         test    eax, eax
  496.         jz      @f
  497.         mov     ecx, [source_hFile]
  498.         jecxz   @f
  499.         push    ecx
  500.         call    [eax+PluginInfo.close]
  501. @@:
  502.         cmp     [bConfirmDeleteIncomplete], 0
  503.         jz      .copyfailed_del
  504.         cmp     [writeinfo.code], 2
  505.         jz      .copydone2
  506.         push    dword aIncompleteFile
  507.         mov     eax, esp
  508.         push    dword DeleteOrKeepBtn
  509.         push    2
  510.         push    eax
  511.         push    1
  512.         push    dword aCopyCaption
  513.         call    Message
  514.         add     esp, 4
  515.         test    eax, eax
  516.         jnz     .copydone2
  517. .copyfailed_del:
  518.         mov     ebx, delinfo
  519.         push    dword [ebx+21]
  520.         mov     dword [ebx+21], edi
  521.         push    70
  522.         pop     eax
  523.         int     0x40
  524. ; ignore errors
  525.         pop     dword [delinfo+21]
  526.         jmp     .copydone2
  527. .copyfailed_del2:
  528.         xor     eax, eax
  529.         pushf
  530.         jmp     .copyfailed_del
  531.  
  532. copy_file:
  533. ; in: eax->BDFE block for source, CopyDestEditBuf+12 contains ASCIIZ full name for destination
  534. ; out: CF and ZF not set <=> cancel job ("ja cancel_label")
  535.         pushad
  536.         mov     [copy_dir_stack_ptr], copy_dir_stack
  537.         mov     [bNeedRestoreName], 0
  538.         lea     esi, [ebp + panel1_dir - panel1_data]
  539.         mov     edi, execdata
  540. @@:
  541.         lodsb
  542.         test    al, al
  543.         jz      @f
  544.         stosb
  545.         jmp     @b
  546. @@:
  547.         mov     esi, [esp+28]
  548.         add     esi, 40
  549.         cmp     byte [edi-1], '/'
  550.         jz      .l1
  551.         mov     al, '/'
  552.         stosb
  553. .l1:
  554.         lodsb
  555.         cmp     edi, execdataend
  556.         jb      @f
  557.         call    panels_OnKey.bigfilename
  558.         stc
  559.         popad
  560.         ret
  561. @@:
  562.         stosb
  563.         test    al, al
  564.         jnz     .l1
  565.         mov     edx, [esp+28]
  566.         test    byte [edx], 10h
  567.         jnz     .copy_dir
  568.         call    copy_file_worker
  569. .popad_ret:
  570.         popad
  571.         ret
  572.  
  573. .biiig:
  574.         mov     byte [edi-1], 0
  575.         jmp     .popad_ret
  576.  
  577. .copy_dir:
  578. ; recursive copy of directory
  579.         cmp     [bDestIsFolder], 0
  580.         mov     [bDestIsFolder], 0
  581.         jz      .target_created
  582.         mov     [bNeedRestoreName], 1
  583.         mov     esi, CopyDestEditBuf+12
  584. @@:
  585.         lodsb
  586.         test    al, al
  587.         jnz     @b
  588.         dec     esi
  589.         cmp     byte [esi-1], '/'
  590.         jz      @f
  591.         mov     byte [esi], '/'
  592.         inc     esi
  593. @@:
  594.         mov     edi, esi
  595.         lea     esi, [edx+40]
  596. @@:
  597.         cmp     edi, CopyDestEditBuf+12+513
  598.         jae     .biiig
  599.         lodsb
  600.         stosb
  601.         test    al, al
  602.         jnz     @b
  603. .create_target:
  604. .enter_recursion:
  605.         push    DeleteErrorBtn
  606.         push    4
  607.         call    makedir
  608.         jz      .target_created
  609.         cmp     al, 2
  610.         jnz     @f
  611.         dec     eax
  612.         mov     [copy_bSkipAll], 1
  613. @@:
  614.         cmp     al, 1
  615.         jz      .copy_dir_entry_done
  616.         jmp     .cancel2
  617. .target_created:
  618.         mov     edx, [source_hModule]
  619.         test    edx, edx
  620.         jz      .nosetdir
  621.         mov     esi, execdata
  622.         push    esi     ; absolute_path
  623. @@:
  624.         lodsb
  625.         test    al, al
  626.         jnz     @b
  627. @@:
  628.         dec     esi
  629.         cmp     byte [esi-1], '/'
  630.         jnz     @b
  631.         push    esi     ; relative_path
  632.         push    [source_hPlugin]        ; hPlugin
  633.         call    [edx+PluginInfo.SetFolder]
  634.         test    al, al
  635.         jnz     .nosetdir
  636.         cmp     [copy_bSkipAll3], 0
  637.         jz      .skip2
  638.         push    execdata
  639.         push    aCannotSetFolder
  640.         mov     eax, esp
  641.         push    DeleteErrorBtn
  642.         push    4
  643.         push    eax
  644.         push    2
  645.         call    SayErr
  646.         pop     ecx ecx
  647.         test    al, al
  648.         jz      .target_created
  649.         cmp     al, 2
  650.         setz    [copy_bSkipAll3]
  651.         ja      .cancel2
  652.         jmp     .skip2
  653. .nosetdir:
  654.         xor     ebp, ebp        ; ebp will contain number of copied items
  655. .return_from_recursion:
  656. .read_retry:
  657.         mov     ebx, dirinfo
  658.         mov     [ebx+dirinfo.first-dirinfo], ebp
  659.         mov     [ebx+dirinfo.size-dirinfo], copy_dir_query_size
  660.         mov     [ebx+dirinfo.dirdata-dirinfo], copy_dir_query_area
  661.         mov     [ebx+dirinfo.name-dirinfo], execdata
  662.         mov     eax, [source_hModule]
  663.         test    eax, eax
  664.         jz      .readfolder_native
  665.         push    ebp
  666.         push    [ebx+dirinfo.dirdata-dirinfo]
  667.         push    [ebx+dirinfo.size-dirinfo]
  668.         push    [ebx+dirinfo.first-dirinfo]
  669.         push    [source_hPlugin]
  670.         call    [eax+PluginInfo.ReadFolder]
  671.         pop     ebp
  672.         mov     ebx, dword [copy_dir_query_area+4]
  673.         jmp     @f
  674. .readfolder_native:
  675.         push    70
  676.         pop     eax
  677.         int     0x40
  678. @@:
  679.         test    eax, eax
  680.         jz      .readok
  681.         cmp     eax, 6
  682.         jz      .readok
  683. ; read error
  684.         cmp     [copy_bSkipAll], 0
  685.         jnz     .skip1
  686.         push    execdata
  687.         push    aCannotReadFolder
  688.         call    get_error_msg
  689.         push    eax
  690.         mov     eax, esp
  691.         push    DeleteErrorBtn
  692.         push    4
  693.         push    eax
  694.         push    3
  695.         call    SayErr
  696.         add     esp, 3*4
  697.         test    al, al
  698.         jz      .read_retry
  699.         cmp     al, 2
  700.         jnz     @f
  701.         dec     eax
  702.         mov     [copy_bSkipAll], 1
  703. @@:
  704.         cmp     al, 1
  705.         jz      .skip1
  706.         jmp     .cancel
  707. .readok:
  708. ; loop through a directory and copy items
  709.         mov     edx, copy_dir_query_area+32
  710.         imul    ebx, 304
  711.         add     ebx, edx
  712. .copy_dir_entry_loop:
  713.         cmp     edx, ebx
  714.         jb      .do_copy_dir_entry
  715.         cmp     ebx, copy_dir_query_area+32+copy_dir_query_size*304
  716.         jz      .return_from_recursion
  717.         jmp     .copy_dir_entry_done
  718. .do_copy_dir_entry:
  719.         inc     ebp
  720. ; ignore special entries "." and ".."
  721.         cmp     word [edx+40], '.'
  722.         jz      .copy_dir_entry_continue
  723.         cmp     word [edx+40], '..'
  724.         jnz     @f
  725.         cmp     byte [edx+42], 0
  726.         jz      .copy_dir_entry_continue
  727. @@:
  728.         mov     esi, execdata
  729. @@:
  730.         lodsb
  731.         test    al, al
  732.         jnz     @b
  733.         dec     esi
  734.         cmp     byte [esi-1], '/'
  735.         jz      @f
  736.         mov     byte [esi], '/'
  737.         inc     esi
  738. @@:
  739.         mov     edi, esi
  740.         lea     esi, [edx+40]
  741. @@:
  742.         cmp     edi, execdataend
  743.         jae     .fullname_big
  744.         lodsb
  745.         stosb
  746.         test    al, al
  747.         jnz     @b
  748.         mov     esi, CopyDestEditBuf+12
  749. @@:
  750.         lodsb
  751.         test    al, al
  752.         jnz     @b
  753.         dec     esi
  754.         cmp     byte [esi-1], '/'
  755.         jz      @f
  756.         mov     byte [esi], '/'
  757.         inc     esi
  758. @@:
  759.         mov     edi, esi
  760.         lea     esi, [edx+40]
  761. @@:
  762.         cmp     edi, CopyDestEditBuf+513
  763.         jae     .fullname2_big
  764.         lodsb
  765.         stosb
  766.         test    al, al
  767.         jnz     @b
  768.         test    byte [edx], 10h
  769.         jnz     .entry_is_folder
  770.         call    copy_file_worker
  771.         ja      .cancel3
  772.         jmp     .restore_name
  773. .entry_is_folder:
  774. ; allocate new item in directory stack
  775.         mov     eax, [copy_dir_stack_ptr]
  776.         mov     [eax], ebp
  777.         add     eax, 4
  778.         mov     [copy_dir_stack_ptr], eax
  779. ; do recursive copying
  780.         jmp     .enter_recursion
  781. .fullname_big:
  782. ; we will just ignore such files and continue - in real life this situation can not happen
  783.         mov     esi, execdataend-1
  784.         jmp     .do_restore_name2
  785. .fullname2_big:
  786.         mov     esi, CopyDestEditBuf+12+512
  787.         jmp     .restore_name2
  788. .restore_name:
  789.         mov     esi, CopyDestEditBuf+12
  790. @@:
  791.         lodsb
  792.         test    al, al
  793.         jnz     @b
  794.         dec     esi
  795.         dec     esi
  796. .restore_name2:
  797.         call    delete_last_name
  798.         mov     esi, execdata
  799. @@:
  800.         lodsb
  801.         test    al, al
  802.         jnz     @b
  803.         dec     esi
  804.         dec     esi
  805. .do_restore_name2:
  806.         call    delete_last_name
  807. .copy_dir_entry_continue:
  808.         add     edx, 304
  809.         jmp     .copy_dir_entry_loop
  810. .skip1:
  811. .copy_dir_entry_done:
  812. ; return to previous directory
  813.         mov     esi, execdata
  814.         call    delete_last_name_from_end
  815.         mov     eax, [source_hModule]
  816.         test    eax, eax
  817.         jz      @f
  818.         push    execdata
  819.         push    aDotDot
  820.         push    [source_hPlugin]
  821.         call    [eax+PluginInfo.SetFolder]
  822.         jmp     @f
  823. .skip2:
  824.         mov     esi, execdata
  825.         call    delete_last_name_from_end
  826. @@:
  827. ; pop item from directory stack
  828.         mov     ecx, [copy_dir_stack_ptr]
  829.         cmp     ecx, copy_dir_stack
  830.         jbe     .done
  831.         sub     ecx, 4
  832.         mov     [copy_dir_stack_ptr], ecx
  833.         mov     ebp, [ecx]
  834. ; restore prev directory name
  835.         mov     esi, CopyDestEditBuf+12
  836.         call    delete_last_name_from_end
  837.         jmp     .return_from_recursion
  838. .done:
  839.         mov     [dirinfo.first], 0      ; do not destroys flags
  840.         popad
  841.         ret
  842. .cancel2:
  843.         sub     [copy_dir_stack_ptr], 4
  844. .cancel3:
  845.         mov     esi, execdata
  846.         call    delete_last_name_from_end
  847. .cancel:
  848.         mov     eax, [source_hModule]
  849.         test    eax, eax
  850.         jz      .cancel.ret
  851.         cmp     [copy_dir_stack_ptr], copy_dir_stack
  852.         jb      .cancel.ret
  853.         push    execdata
  854.         push    aDotDot
  855.         push    [source_hPlugin]
  856.         call    [eax+PluginInfo.SetFolder]
  857.         jmp     .cancel2
  858. .cancel.ret:
  859.         xor     eax, eax
  860.         inc     eax
  861.         popad
  862.         ret
  863.  
  864. delete_last_name_from_end:
  865.         lodsb
  866.         test    al, al
  867.         jnz     delete_last_name_from_end
  868.         dec     esi
  869.         dec     esi
  870. delete_last_name:
  871.         std
  872. @@:
  873.         lodsb
  874.         cmp     al, '/'
  875.         jnz     @b
  876.         cld
  877.         inc     esi
  878.         cmp     esi, execdata
  879.         jz      @f
  880.         cmp     esi, CopyDestEditBuf+12
  881.         jz      @f
  882.         dec     esi
  883. @@:
  884.         mov     byte [esi+1], 0
  885.         ret
  886.  
  887. copy_AddDir:
  888.         push    1
  889.         pop     eax                     ; for "return true"
  890.         pushad
  891.         mov     esi, CopyDestEditBuf+12
  892. @@:
  893.         lodsb
  894.         test    al, al
  895.         jnz     @b
  896.         cmp     byte [esi-2], '/'
  897.         jnz     @f
  898.         dec     esi
  899. @@:
  900.         push    dword [esi-1]
  901.         push    esi
  902.         mov     byte [esi-1], '/'
  903.         mov     edi, esi
  904.         mov     esi, [esp+28h+4]
  905. .0:
  906.         lodsb
  907.         stosb
  908.         cmp     edi, CopyDestEditBuf+12+512
  909.         jae     .done
  910.         test    al, al
  911.         jnz     .0
  912.         push    RetryOrCancelBtn
  913.         push    2
  914.         call    makedir
  915.         jz      .done
  916.         and     dword [esp+8+1Ch], 0
  917. .done:
  918.         pop     esi
  919.         pop     dword [esi-1]
  920.         popad
  921.         ret     8
  922.  
  923. copy_AddFile:
  924.         pushad
  925.         mov     eax, [esp+20h+12]
  926.         mov     [source_hFile], eax
  927.         mov     edx, [esp+20h+8]
  928.         mov     edi, [esp+20h+4]
  929.         call    copy_file_worker2
  930.         popad
  931.         setna   al
  932.         ret     12
  933.  
  934. virtual at 0
  935. _FILE:
  936. .pos            dq      ?
  937. .bufpos         dq      ?
  938. .bufsize        dd      ?
  939. .mode           dd      ?
  940. .hPlugin        dd      ?
  941. .hFile          dd      ?
  942. .fileinfo:
  943. .fimode         dd      ?
  944. .fioffset       dq      ?
  945. .fisize         dd      ?
  946. .fibuf          dd      ?
  947. .finame         rb      1024
  948. .attr           rb      40
  949. align 512
  950. .buf            rb      2048
  951. .size = $
  952. end virtual
  953.  
  954. O_READ = 1      ; allows read from file
  955. O_WRITE = 2     ; allows write to file
  956. O_CREATE = 4    ; if file does not exist and this flag is set, create file;
  957.                 ; if file does not exist and this flag is not set, fail
  958. O_TRUNCATE = 8  ; truncate file if it exists
  959. O_SEQUENTIAL_ONLY = 10h ; there will be no 'seek'/'setpos' calls
  960.  
  961. ; HANDLE __stdcall open(const char* name, int mode);
  962. ; Opens physical file
  963. open:
  964.         pushad
  965.         mov     ecx, _FILE.size
  966.         call    xpgalloc
  967.         test    eax, eax
  968.         jz      .ret0z
  969.         mov     [esp+28], eax
  970.         mov     ecx, eax
  971.         mov     esi, [esp+36]
  972.         lea     edi, [eax+_FILE.finame]
  973.         lea     edx, [eax+_FILE.finame+1024]
  974. @@:
  975.         lodsb
  976.         stosb
  977.         test    al, al
  978.         jz      @f
  979.         cmp     edi, edx
  980.         jb      @b
  981. .ret0:
  982.         call    pgfree
  983. .ret0z:
  984.         popad
  985.         xor     eax, eax
  986.         ret     8
  987. @@:
  988.         mov     eax, [esp+40]
  989.         mov     [ecx+_FILE.mode], eax
  990. .getattr:
  991.         lea     edi, [ecx+_FILE.fileinfo]
  992.         mov     ebx, edi
  993.         push    5
  994.         pop     eax
  995.         stosd
  996.         xor     eax, eax
  997.         stosd
  998.         stosd
  999.         stosd
  1000.         lea     eax, [ecx+_FILE.attr]
  1001.         stosd
  1002.         push    70
  1003.         pop     eax
  1004.         int     0x40
  1005.         test    eax, eax
  1006.         jz      .found
  1007.         cmp     eax, 5
  1008.         jnz     .ret0
  1009. ; file does not exist
  1010.         test    [ecx+_FILE.mode], O_CREATE
  1011.         jz      .ret0z
  1012. .truncate:
  1013.         lea     ebx, [ecx+_FILE.fileinfo]
  1014.         mov     byte [ebx], 2
  1015.         push    70
  1016.         pop     eax
  1017.         int     0x40
  1018.         test    eax, eax
  1019.         jz      .getattr
  1020.         jmp     .ret0
  1021. .found:
  1022.         test    [ecx+_FILE.mode], O_TRUNCATE
  1023.         jz      @f
  1024.         cmp     dword [ecx+_FILE.attr+36], eax
  1025.         jnz     .truncate
  1026.         cmp     dword [ecx+_FILE.attr+32], eax
  1027.         jnz     .truncate
  1028. @@:
  1029.         mov     dword [ecx+_FILE.pos], eax
  1030.         mov     dword [ecx+_FILE.pos+4], eax
  1031.         mov     dword [ecx+_FILE.bufpos], eax
  1032.         mov     dword [ecx+_FILE.bufpos+4], eax
  1033.         mov     [ecx+_FILE.bufsize], eax
  1034.         mov     [ecx+_FILE.hPlugin], eax
  1035.         mov     [ecx+_FILE.hFile], eax
  1036.         mov     dword [ecx+_FILE.fioffset], eax
  1037.         mov     dword [ecx+_FILE.fioffset+4], eax
  1038.         mov     [esp+28], ecx
  1039.         popad
  1040.         ret     8
  1041.  
  1042. ; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
  1043. read:
  1044.         xor     eax, eax
  1045.         pushad
  1046.         mov     ecx, [esp+36]
  1047.         test    [ecx+_FILE.mode], O_READ
  1048.         jnz     @f
  1049. .ret:
  1050.         popad
  1051.         ret     12
  1052. @@:
  1053.         cmp     dword [esp+44], eax
  1054.         jz      .ret
  1055.         mov     [ecx+_FILE.fimode], eax
  1056.         mov     ebx, [ecx+_FILE.bufsize]
  1057.         mov     eax, dword [ecx+_FILE.pos]
  1058.         and     eax, 2047
  1059.         sub     ebx, eax
  1060.         jbe     .nobuf0
  1061.         cmp     ebx, [esp+44]
  1062.         jbe     @f
  1063.         mov     ebx, [esp+44]
  1064. @@:
  1065.         push    ecx
  1066.         lea     esi, [ecx+eax+_FILE.buf]
  1067.         mov     ecx, ebx
  1068.         mov     edi, [esp+44]
  1069.         rep     movsb
  1070.         pop     ecx
  1071.         mov     [esp+40], edi
  1072.         add     [esp+28], ebx
  1073.         add     dword [ecx+_FILE.pos], ebx
  1074.         adc     dword [ecx+_FILE.pos+4], 0
  1075.         sub     [esp+44], ebx
  1076.         jz      .ret
  1077. .nobuf0:
  1078.         test    dword [ecx+_FILE.pos], 2047
  1079.         jz      .aligned
  1080.         cmp     dword [ecx+_FILE.bufsize], 0
  1081.         jnz     .ret
  1082.         lea     ebx, [ecx+_FILE.fileinfo]
  1083.         mov     dword [ebx+12], 2048
  1084.         lea     eax, [ecx+_FILE.buf]
  1085.         mov     dword [ebx+16], eax
  1086.         mov     eax, dword [ecx+_FILE.fioffset]
  1087.         mov     dword [ecx+_FILE.bufpos], eax
  1088.         mov     eax, dword [ecx+_FILE.fioffset+4]
  1089.         mov     dword [ecx+_FILE.bufpos+4], eax
  1090.         call    .doread
  1091.         test    eax, eax
  1092.         jnz     .ret
  1093.         mov     [ecx+_FILE.bufsize], ebx
  1094.         mov     eax, dword [ecx+_FILE.pos]
  1095.         and     eax, 2047
  1096.         sub     ebx, eax
  1097.         jbe     .ret
  1098.         cmp     ebx, [esp+44]
  1099.         jbe     @f
  1100.         mov     ebx, [esp+44]
  1101. @@:
  1102.         push    ecx
  1103.         lea     esi, [ecx+eax+_FILE.buf]
  1104.         mov     ecx, ebx
  1105.         mov     edi, [esp+44]
  1106.         rep     movsb
  1107.         pop     ecx
  1108.         add     dword [ecx+_FILE.pos], ebx
  1109.         adc     dword [ecx+_FILE.pos+4], 0
  1110.         mov     [esp+40], edi
  1111.         add     [esp+28], ebx
  1112.         sub     [esp+44], ebx
  1113.         jz      .ret
  1114.         test    dword [ecx+_FILE.pos], 2047
  1115.         jnz     .ret
  1116. .aligned:
  1117.         lea     ebx, [ecx+_FILE.fileinfo]
  1118.         mov     eax, [esp+44]
  1119.         and     eax, not 2047
  1120.         jz      .finish
  1121.         and     [ecx+_FILE.bufsize], 0
  1122.         mov     [ebx+12], eax
  1123.         mov     eax, [esp+40]
  1124.         mov     [ebx+16], eax
  1125.         call    .doread
  1126.         test    eax, eax
  1127.         jnz     .ret
  1128.         add     dword [ecx+_FILE.pos], ebx
  1129.         adc     dword [ecx+_FILE.pos+4], 0
  1130.         add     [esp+28], ebx
  1131.         add     [esp+40], ebx
  1132.         sub     [esp+44], ebx
  1133.         jz      .ret
  1134.         cmp     ebx, [ecx+_FILE.fisize]
  1135.         jb      .ret
  1136. .finish:
  1137.         lea     ebx, [ecx+_FILE.fileinfo]
  1138.         mov     dword [ebx+12], 2048
  1139.         lea     eax, [ecx+_FILE.buf]
  1140.         mov     [ebx+16], eax
  1141.         and     [ecx+_FILE.bufsize], 0
  1142.         mov     eax, dword [ecx+_FILE.fioffset]
  1143.         mov     dword [ecx+_FILE.bufpos], eax
  1144.         mov     eax, dword [ecx+_FILE.fioffset+4]
  1145.         mov     dword [ecx+_FILE.bufpos+4], eax
  1146.         call    .doread
  1147.         test    eax, eax
  1148.         jnz     .ret
  1149.         mov     [ecx+_FILE.bufsize], ebx
  1150.         cmp     ebx, [esp+44]
  1151.         jb      @f
  1152.         mov     ebx, [esp+44]
  1153. @@:
  1154.         add     [esp+28], ebx
  1155.         add     dword [ecx+_FILE.pos], ebx
  1156.         adc     dword [ecx+_FILE.pos+4], 0
  1157.         lea     esi, [ecx+_FILE.buf]
  1158.         mov     edi, [esp+40]
  1159.         mov     ecx, ebx
  1160.         rep     movsb
  1161.         popad
  1162.         ret     12
  1163. .doread:
  1164.         mov     eax, [ecx+_FILE.hPlugin]
  1165.         test    eax, eax
  1166.         jz      .native
  1167.         push    ecx
  1168.         push    [ecx+_FILE.fisize]
  1169.         push    [ecx+_FILE.fibuf]
  1170.         push    [ecx+_FILE.hFile]
  1171.         call    [eax+PluginInfo.read]
  1172.         pop     ecx
  1173.         cmp     eax, -1
  1174.         jz      @f
  1175.         mov     ebx, eax
  1176.         xor     eax, eax
  1177.         jmp     .addpos
  1178. @@:
  1179.         ret
  1180. .native:
  1181.         push    70
  1182.         pop     eax
  1183.         int     0x40
  1184.         test    eax, eax
  1185.         jz      .addpos
  1186.         cmp     eax, 6
  1187.         jnz     @b
  1188.         xor     eax, eax
  1189. .addpos:
  1190.         add     dword [ecx+_FILE.fioffset], ebx
  1191.         adc     dword [ecx+_FILE.fioffset+4], 0
  1192.         ret
  1193.  
  1194. ; void __stdcall seek(HANDLE hFile, int method, __int64 newpos);
  1195. seek:
  1196.         pushad
  1197.         mov     ecx, [esp+36]
  1198.         mov     eax, [esp+44]
  1199.         mov     edx, [esp+48]
  1200.         cmp     dword [esp+40], 1
  1201.         jb      .set
  1202.         ja      .end
  1203.         add     eax, dword [ecx+_FILE.pos]
  1204.         adc     edx, dword [ecx+_FILE.pos+4]
  1205.         jmp     .set
  1206. .end:
  1207.         add     eax, dword [ecx+_FILE.attr+32]
  1208.         adc     edx, dword [ecx+_FILE.attr+36]
  1209. .set:
  1210.         mov     dword [ecx+_FILE.pos], eax
  1211.         mov     dword [ecx+_FILE.pos+4], edx
  1212.         and     eax, not 2047
  1213.         cmp     eax, dword [ecx+_FILE.bufpos]
  1214.         jnz     @f
  1215.         cmp     edx, dword [ecx+_FILE.bufpos+4]
  1216.         jz      .bufposok
  1217. @@:
  1218.         and     [ecx+_FILE.bufsize], 0
  1219.         mov     dword [ecx+_FILE.bufpos], eax
  1220.         mov     dword [ecx+_FILE.bufpos+4], edx
  1221. .bufposok:
  1222.         cmp     [ecx+_FILE.bufsize], 0
  1223.         jnz     .ret
  1224.         cmp     eax, dword [ecx+_FILE.fioffset]
  1225.         jnz     @f
  1226.         cmp     edx, dword [ecx+_FILE.fioffset+4]
  1227.         jz      .ret
  1228. @@:
  1229.         mov     dword [ecx+_FILE.fioffset], eax
  1230.         mov     dword [ecx+_FILE.fioffset+4], edx
  1231.         mov     eax, [ecx+_FILE.hPlugin]
  1232.         test    eax, eax
  1233.         jz      @f
  1234.         push    dword [ecx+_FILE.fioffset+4]
  1235.         push    dword [ecx+_FILE.fioffset]
  1236.         push    [ecx+_FILE.hFile]
  1237.         call    [eax+PluginInfo.setpos]
  1238. @@:
  1239. .ret:
  1240.         popad
  1241.         ret     16
  1242.  
  1243. setpos_default:
  1244.         push    dword [esp+12]
  1245.         push    dword [esp+12]
  1246.         push    0
  1247.         push    dword [esp+16]
  1248.         call    seek
  1249.         ret     12
  1250.  
  1251. ; __int64 __stdcall filesize(HANDLE hFile);
  1252. filesize:
  1253.         mov     eax, [esp+4]
  1254.         mov     edx, dword [eax+_FILE.attr+36]
  1255.         mov     eax, dword [eax+_FILE.attr+32]
  1256.         ret     4
  1257.  
  1258. ; void __stdcall close(HANDLE hFile);
  1259. close:
  1260.         pushad
  1261.         mov     ecx, [esp+24h]
  1262.         mov     eax, [ecx+_FILE.hPlugin]
  1263.         test    eax, eax
  1264.         jz      @f
  1265.         push    ecx
  1266.         push    [ecx+_FILE.hFile]
  1267.         call    [eax+PluginInfo.close]
  1268.         pop     ecx
  1269. @@:
  1270.         call    pgfree
  1271.         popad
  1272.         ret     4
  1273.  
  1274. getattr_default:
  1275.         mov     eax, 2
  1276.         ret     12
  1277.