Subversion Repositories Kolibri OS

Rev

Rev 589 | Rev 997 | 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      .ret0
  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. ; HANDLE __stdcall open2(int plugin_id, HANDLE plugin_instance, const char* name, int mode);
  1043. ; Opens file on plugin panel
  1044. open2:
  1045.         cmp     dword [esp+4], 0
  1046.         jnz     .plugin
  1047.         pop     eax
  1048.         add     esp, 8
  1049.         push    eax
  1050.         jmp     open
  1051. .plugin:
  1052.         pushad
  1053.         mov     ecx, _FILE.size
  1054.         call    xpgalloc
  1055.         test    eax, eax
  1056.         jz      .ret0z
  1057.         mov     [esp+28], eax
  1058.         mov     ecx, eax
  1059.         mov     esi, [esp+44]
  1060.         lea     edi, [eax+_FILE.finame]
  1061.         lea     edx, [eax+_FILE.finame+1024]
  1062. @@:
  1063.         lodsb
  1064.         stosb
  1065.         test    al, al
  1066.         jz      @f
  1067.         cmp     edi, edx
  1068.         jb      @b
  1069. .ret0:
  1070.         call    pgfree
  1071. .ret0z:
  1072.         popad
  1073.         xor     eax, eax
  1074.         ret     8
  1075. @@:
  1076.         mov     edx, [esp+36]
  1077.         mov     [ecx+_FILE.hPlugin], edx
  1078.         mov     ebx, [esp+40]
  1079.         mov     eax, [esp+48]
  1080.         mov     [ecx+_FILE.mode], eax
  1081.         push    ebx ecx
  1082.         push    eax
  1083.         lea     eax, [ecx+_FILE.finame]
  1084.         push    eax
  1085.         push    ebx
  1086.         call    [edx+PluginInfo.open]
  1087.         pop     ecx ebx
  1088.         test    eax, eax
  1089.         jz      .ret0
  1090.         mov     [ecx+_FILE.hFile], eax
  1091.         mov     edx, [esp+36]
  1092.         push    ecx
  1093.         lea     edi, [ecx+_FILE.fileinfo]
  1094.         push    edi
  1095.         xor     eax, eax
  1096.         push    ecx
  1097.         push    10
  1098.         pop     ecx
  1099.         rep     stosd
  1100.         pop     ecx
  1101.         lea     eax, [ecx+_FILE.finame]
  1102.         push    eax
  1103.         push    ebx
  1104.         call    [edx+PluginInfo.getattr]
  1105.         pop     ecx
  1106.         xor     eax, eax
  1107.         mov     dword [ecx+_FILE.pos], eax
  1108.         mov     dword [ecx+_FILE.pos+4], eax
  1109.         mov     dword [ecx+_FILE.bufpos], eax
  1110.         mov     dword [ecx+_FILE.bufpos+4], eax
  1111.         mov     [ecx+_FILE.bufsize], eax
  1112.         mov     dword [ecx+_FILE.fioffset], eax
  1113.         mov     dword [ecx+_FILE.fioffset+4], eax
  1114.         mov     [esp+28], ecx
  1115.         popad
  1116.         ret     16
  1117.  
  1118. ; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
  1119. read:
  1120.         xor     eax, eax
  1121.         pushad
  1122.         mov     ecx, [esp+36]
  1123.         test    [ecx+_FILE.mode], O_READ
  1124.         jnz     @f
  1125. .ret:
  1126.         popad
  1127.         ret     12
  1128. @@:
  1129.         cmp     dword [esp+44], eax
  1130.         jz      .ret
  1131.         mov     [ecx+_FILE.fimode], eax
  1132.         mov     ebx, [ecx+_FILE.bufsize]
  1133.         mov     eax, dword [ecx+_FILE.pos]
  1134.         and     eax, 2047
  1135.         sub     ebx, eax
  1136.         jbe     .nobuf0
  1137.         cmp     ebx, [esp+44]
  1138.         jbe     @f
  1139.         mov     ebx, [esp+44]
  1140. @@:
  1141.         push    ecx
  1142.         lea     esi, [ecx+eax+_FILE.buf]
  1143.         mov     ecx, ebx
  1144.         mov     edi, [esp+44]
  1145.         rep     movsb
  1146.         pop     ecx
  1147.         mov     [esp+40], edi
  1148.         add     [esp+28], ebx
  1149.         add     dword [ecx+_FILE.pos], ebx
  1150.         adc     dword [ecx+_FILE.pos+4], 0
  1151.         test    dword [ecx+_FILE.pos], 2047
  1152.         jnz     @f
  1153.         and     [ecx+_FILE.bufsize], 0
  1154. @@:
  1155.         sub     [esp+44], ebx
  1156.         jz      .ret
  1157. .nobuf0:
  1158.         test    dword [ecx+_FILE.pos], 2047
  1159.         jz      .aligned
  1160.         cmp     dword [ecx+_FILE.bufsize], 0
  1161.         jnz     .ret
  1162.         lea     ebx, [ecx+_FILE.fileinfo]
  1163.         mov     dword [ebx+12], 2048
  1164.         lea     eax, [ecx+_FILE.buf]
  1165.         mov     dword [ebx+16], eax
  1166.         mov     eax, dword [ecx+_FILE.fioffset]
  1167.         mov     dword [ecx+_FILE.bufpos], eax
  1168.         mov     eax, dword [ecx+_FILE.fioffset+4]
  1169.         mov     dword [ecx+_FILE.bufpos+4], eax
  1170.         call    .doread
  1171.         test    eax, eax
  1172.         jnz     .ret
  1173.         mov     [ecx+_FILE.bufsize], ebx
  1174.         mov     eax, dword [ecx+_FILE.pos]
  1175.         and     eax, 2047
  1176.         sub     ebx, eax
  1177.         jbe     .ret
  1178.         cmp     ebx, [esp+44]
  1179.         jbe     @f
  1180.         mov     ebx, [esp+44]
  1181. @@:
  1182.         push    ecx
  1183.         lea     esi, [ecx+eax+_FILE.buf]
  1184.         mov     ecx, ebx
  1185.         mov     edi, [esp+44]
  1186.         rep     movsb
  1187.         pop     ecx
  1188.         add     dword [ecx+_FILE.pos], ebx
  1189.         adc     dword [ecx+_FILE.pos+4], 0
  1190.         mov     [esp+40], edi
  1191.         add     [esp+28], ebx
  1192.         sub     [esp+44], ebx
  1193.         jz      .ret
  1194.         test    dword [ecx+_FILE.pos], 2047
  1195.         jnz     .ret
  1196. .aligned:
  1197.         lea     ebx, [ecx+_FILE.fileinfo]
  1198.         mov     eax, [esp+44]
  1199.         and     eax, not 2047
  1200.         jz      .finish
  1201.         and     [ecx+_FILE.bufsize], 0
  1202.         mov     [ebx+12], eax
  1203.         mov     eax, [esp+40]
  1204.         mov     [ebx+16], eax
  1205.         call    .doread
  1206.         test    eax, eax
  1207.         jnz     .ret
  1208.         add     dword [ecx+_FILE.pos], ebx
  1209.         adc     dword [ecx+_FILE.pos+4], 0
  1210.         add     [esp+28], ebx
  1211.         add     [esp+40], ebx
  1212.         sub     [esp+44], ebx
  1213.         jz      .ret
  1214.         cmp     ebx, [ecx+_FILE.fisize]
  1215.         jb      .ret
  1216. .finish:
  1217.         lea     ebx, [ecx+_FILE.fileinfo]
  1218.         mov     dword [ebx+12], 2048
  1219.         lea     eax, [ecx+_FILE.buf]
  1220.         mov     [ebx+16], eax
  1221.         and     [ecx+_FILE.bufsize], 0
  1222.         mov     eax, dword [ecx+_FILE.fioffset]
  1223.         mov     dword [ecx+_FILE.bufpos], eax
  1224.         mov     eax, dword [ecx+_FILE.fioffset+4]
  1225.         mov     dword [ecx+_FILE.bufpos+4], eax
  1226.         call    .doread
  1227.         test    eax, eax
  1228.         jnz     .ret
  1229.         mov     [ecx+_FILE.bufsize], ebx
  1230.         cmp     ebx, [esp+44]
  1231.         jb      @f
  1232.         mov     ebx, [esp+44]
  1233. @@:
  1234.         add     [esp+28], ebx
  1235.         add     dword [ecx+_FILE.pos], ebx
  1236.         adc     dword [ecx+_FILE.pos+4], 0
  1237.         lea     esi, [ecx+_FILE.buf]
  1238.         mov     edi, [esp+40]
  1239.         mov     ecx, ebx
  1240.         rep     movsb
  1241.         popad
  1242.         ret     12
  1243. .doread:
  1244.         mov     eax, [ecx+_FILE.hPlugin]
  1245.         test    eax, eax
  1246.         jz      .native
  1247.         push    ecx
  1248.         push    [ecx+_FILE.fisize]
  1249.         push    [ecx+_FILE.fibuf]
  1250.         push    [ecx+_FILE.hFile]
  1251.         call    [eax+PluginInfo.read]
  1252.         pop     ecx
  1253.         cmp     eax, -1
  1254.         jz      @f
  1255.         mov     ebx, eax
  1256.         xor     eax, eax
  1257.         jmp     .addpos
  1258. @@:
  1259.         ret
  1260. .native:
  1261.         push    70
  1262.         pop     eax
  1263.         int     0x40
  1264.         test    eax, eax
  1265.         jz      .addpos
  1266.         cmp     eax, 6
  1267.         jnz     @b
  1268.         xor     eax, eax
  1269. .addpos:
  1270.         add     dword [ecx+_FILE.fioffset], ebx
  1271.         adc     dword [ecx+_FILE.fioffset+4], 0
  1272.         ret
  1273.  
  1274. ; void __stdcall seek(HANDLE hFile, int method, __int64 newpos);
  1275. seek:
  1276.         pushad
  1277.         mov     ecx, [esp+36]
  1278.         mov     eax, [esp+44]
  1279.         mov     edx, [esp+48]
  1280.         cmp     dword [esp+40], 1
  1281.         jb      .set
  1282.         ja      .end
  1283.         add     eax, dword [ecx+_FILE.pos]
  1284.         adc     edx, dword [ecx+_FILE.pos+4]
  1285.         jmp     .set
  1286. .end:
  1287.         add     eax, dword [ecx+_FILE.attr+32]
  1288.         adc     edx, dword [ecx+_FILE.attr+36]
  1289. .set:
  1290.         mov     dword [ecx+_FILE.pos], eax
  1291.         mov     dword [ecx+_FILE.pos+4], edx
  1292.         and     eax, not 2047
  1293.         cmp     eax, dword [ecx+_FILE.bufpos]
  1294.         jnz     @f
  1295.         cmp     edx, dword [ecx+_FILE.bufpos+4]
  1296.         jz      .bufposok
  1297. @@:
  1298.         and     [ecx+_FILE.bufsize], 0
  1299.         mov     dword [ecx+_FILE.bufpos], eax
  1300.         mov     dword [ecx+_FILE.bufpos+4], edx
  1301. .bufposok:
  1302.         cmp     [ecx+_FILE.bufsize], 0
  1303.         jnz     .ret
  1304.         cmp     eax, dword [ecx+_FILE.fioffset]
  1305.         jnz     @f
  1306.         cmp     edx, dword [ecx+_FILE.fioffset+4]
  1307.         jz      .ret
  1308. @@:
  1309.         mov     dword [ecx+_FILE.fioffset], eax
  1310.         mov     dword [ecx+_FILE.fioffset+4], edx
  1311.         mov     eax, [ecx+_FILE.hPlugin]
  1312.         test    eax, eax
  1313.         jz      @f
  1314.         push    dword [ecx+_FILE.fioffset+4]
  1315.         push    dword [ecx+_FILE.fioffset]
  1316.         push    [ecx+_FILE.hFile]
  1317.         call    [eax+PluginInfo.setpos]
  1318. @@:
  1319. .ret:
  1320.         popad
  1321.         ret     16
  1322.  
  1323. setpos_default:
  1324.         push    dword [esp+12]
  1325.         push    dword [esp+12]
  1326.         push    0
  1327.         push    dword [esp+16]
  1328.         call    seek
  1329.         ret     12
  1330.  
  1331. ; __int64 __stdcall tell(HANDLE hFile);
  1332. tell:
  1333.         mov     eax, [esp+4]
  1334.         mov     edx, dword [eax+_FILE.pos+4]
  1335.         mov     eax, dword [eax+_FILE.pos]
  1336.         ret     4
  1337.  
  1338. ; __int64 __stdcall filesize(HANDLE hFile);
  1339. filesize:
  1340.         mov     eax, [esp+4]
  1341.         mov     edx, dword [eax+_FILE.attr+36]
  1342.         mov     eax, dword [eax+_FILE.attr+32]
  1343.         ret     4
  1344.  
  1345. ; void __stdcall close(HANDLE hFile);
  1346. close:
  1347.         pushad
  1348.         mov     ecx, [esp+24h]
  1349.         mov     eax, [ecx+_FILE.hPlugin]
  1350.         test    eax, eax
  1351.         jz      @f
  1352.         push    ecx
  1353.         push    [ecx+_FILE.hFile]
  1354.         call    [eax+PluginInfo.close]
  1355.         pop     ecx
  1356. @@:
  1357.         call    pgfree
  1358.         popad
  1359.         ret     4
  1360.  
  1361. getattr_default:
  1362.         mov     eax, 2
  1363.         ret     12
  1364.