Subversion Repositories Kolibri OS

Rev

Rev 631 | Rev 8960 | 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.         mov     edx, execdata
  687.         call    recursive_read_folder_err
  688.         jz      .read_retry
  689.         cmp     al, 2
  690.         jnz     @f
  691.         dec     eax
  692.         mov     [copy_bSkipAll], 1
  693. @@:
  694.         cmp     al, 1
  695.         jz      .skip1
  696.         jmp     .cancel
  697. .readok:
  698. ; loop through a directory and copy items
  699.         mov     edx, copy_dir_query_area+32
  700.         imul    ebx, 304
  701.         add     ebx, edx
  702. .copy_dir_entry_loop:
  703.         cmp     edx, ebx
  704.         jb      .do_copy_dir_entry
  705.         cmp     ebx, copy_dir_query_area+32+copy_dir_query_size*304
  706.         jz      .return_from_recursion
  707.         jmp     .copy_dir_entry_done
  708. .do_copy_dir_entry:
  709.         inc     ebp
  710. ; ignore special entries "." and ".."
  711.         cmp     word [edx+40], '.'
  712.         jz      .copy_dir_entry_continue
  713.         cmp     word [edx+40], '..'
  714.         jnz     @f
  715.         cmp     byte [edx+42], 0
  716.         jz      .copy_dir_entry_continue
  717. @@:
  718.         mov     esi, execdata
  719. @@:
  720.         lodsb
  721.         test    al, al
  722.         jnz     @b
  723.         dec     esi
  724.         cmp     byte [esi-1], '/'
  725.         jz      @f
  726.         mov     byte [esi], '/'
  727.         inc     esi
  728. @@:
  729.         mov     edi, esi
  730.         lea     esi, [edx+40]
  731. @@:
  732.         cmp     edi, execdataend
  733.         jae     .fullname_big
  734.         lodsb
  735.         stosb
  736.         test    al, al
  737.         jnz     @b
  738.         mov     esi, CopyDestEditBuf+12
  739. @@:
  740.         lodsb
  741.         test    al, al
  742.         jnz     @b
  743.         dec     esi
  744.         cmp     byte [esi-1], '/'
  745.         jz      @f
  746.         mov     byte [esi], '/'
  747.         inc     esi
  748. @@:
  749.         mov     edi, esi
  750.         lea     esi, [edx+40]
  751. @@:
  752.         cmp     edi, CopyDestEditBuf+513
  753.         jae     .fullname2_big
  754.         lodsb
  755.         stosb
  756.         test    al, al
  757.         jnz     @b
  758.         test    byte [edx], 10h
  759.         jnz     .entry_is_folder
  760.         call    copy_file_worker
  761.         ja      .cancel3
  762.         jmp     .restore_name
  763. .entry_is_folder:
  764. ; allocate new item in directory stack
  765.         mov     eax, [copy_dir_stack_ptr]
  766.         mov     [eax], ebp
  767.         add     eax, 4
  768.         mov     [copy_dir_stack_ptr], eax
  769. ; do recursive copying
  770.         jmp     .enter_recursion
  771. .fullname_big:
  772. ; we will just ignore such files and continue - in real life this situation can not happen
  773.         mov     esi, execdataend-1
  774.         jmp     .do_restore_name2
  775. .fullname2_big:
  776.         mov     esi, CopyDestEditBuf+12+512
  777.         jmp     .restore_name2
  778. .restore_name:
  779.         mov     esi, CopyDestEditBuf+12
  780. @@:
  781.         lodsb
  782.         test    al, al
  783.         jnz     @b
  784.         dec     esi
  785.         dec     esi
  786. .restore_name2:
  787.         call    delete_last_name
  788.         mov     esi, execdata
  789. @@:
  790.         lodsb
  791.         test    al, al
  792.         jnz     @b
  793.         dec     esi
  794.         dec     esi
  795. .do_restore_name2:
  796.         call    delete_last_name
  797. .copy_dir_entry_continue:
  798.         add     edx, 304
  799.         jmp     .copy_dir_entry_loop
  800. .skip1:
  801. .copy_dir_entry_done:
  802. ; return to previous directory
  803.         mov     esi, execdata
  804.         call    delete_last_name_from_end
  805.         mov     eax, [source_hModule]
  806.         test    eax, eax
  807.         jz      @f
  808.         push    execdata
  809.         push    aDotDot
  810.         push    [source_hPlugin]
  811.         call    [eax+PluginInfo.SetFolder]
  812.         jmp     @f
  813. .skip2:
  814.         mov     esi, execdata
  815.         call    delete_last_name_from_end
  816. @@:
  817. ; pop item from directory stack
  818.         mov     ecx, [copy_dir_stack_ptr]
  819.         cmp     ecx, copy_dir_stack
  820.         jbe     .done
  821.         sub     ecx, 4
  822.         mov     [copy_dir_stack_ptr], ecx
  823.         mov     ebp, [ecx]
  824. ; restore prev directory name
  825.         mov     esi, CopyDestEditBuf+12
  826.         call    delete_last_name_from_end
  827.         jmp     .return_from_recursion
  828. .done:
  829.         mov     [dirinfo.first], 0      ; do not destroys flags
  830.         popad
  831.         ret
  832. .cancel2:
  833.         sub     [copy_dir_stack_ptr], 4
  834. .cancel3:
  835.         mov     esi, execdata
  836.         call    delete_last_name_from_end
  837. .cancel:
  838.         mov     eax, [source_hModule]
  839.         test    eax, eax
  840.         jz      .cancel.ret
  841.         cmp     [copy_dir_stack_ptr], copy_dir_stack
  842.         jb      .cancel.ret
  843.         push    execdata
  844.         push    aDotDot
  845.         push    [source_hPlugin]
  846.         call    [eax+PluginInfo.SetFolder]
  847.         jmp     .cancel2
  848. .cancel.ret:
  849.         xor     eax, eax
  850.         inc     eax
  851.         popad
  852.         ret
  853.  
  854. delete_last_name_from_end:
  855.         lodsb
  856.         test    al, al
  857.         jnz     delete_last_name_from_end
  858.         dec     esi
  859.         dec     esi
  860. delete_last_name:
  861.         std
  862. @@:
  863.         lodsb
  864.         cmp     al, '/'
  865.         jnz     @b
  866.         cld
  867.         inc     esi
  868.         cmp     esi, execdata
  869.         jz      @f
  870.         cmp     esi, CopyDestEditBuf+12
  871.         jz      @f
  872.         dec     esi
  873. @@:
  874.         mov     byte [esi+1], 0
  875.         ret
  876.  
  877. recursive_read_folder_err:
  878.         push    edx
  879.         push    aCannotReadFolder
  880.         call    get_error_msg
  881.         push    eax
  882.         mov     eax, esp
  883.         push    DeleteErrorBtn
  884.         push    4
  885.         push    eax
  886.         push    3
  887.         call    SayErr
  888.         add     esp, 3*4
  889.         test    al, al
  890.         ret
  891.  
  892. recursive_read_file_err:
  893.         push    edx
  894.         push    aCannotReadFile
  895.         call    get_error_msg
  896.         push    eax
  897.         mov     eax, esp
  898.         push    DeleteErrorBtn
  899.         push    4
  900.         push    eax
  901.         push    3
  902.         call    SayErr
  903.         add     esp, 3*4
  904.         test    al, al
  905.         ret
  906.  
  907. copy_AddDir:
  908.         push    1
  909.         pop     eax                     ; for "return true"
  910.         pushad
  911.         mov     esi, CopyDestEditBuf+12
  912. @@:
  913.         lodsb
  914.         test    al, al
  915.         jnz     @b
  916.         cmp     byte [esi-2], '/'
  917.         jnz     @f
  918.         dec     esi
  919. @@:
  920.         push    dword [esi-1]
  921.         push    esi
  922.         mov     byte [esi-1], '/'
  923.         mov     edi, esi
  924.         mov     esi, [esp+28h+4]
  925. .0:
  926.         lodsb
  927.         stosb
  928.         cmp     edi, CopyDestEditBuf+12+512
  929.         jae     .done
  930.         test    al, al
  931.         jnz     .0
  932.         push    RetryOrCancelBtn
  933.         push    2
  934.         call    makedir
  935.         jz      .done
  936.         and     dword [esp+8+1Ch], 0
  937. .done:
  938.         pop     esi
  939.         pop     dword [esi-1]
  940.         popad
  941.         ret     8
  942.  
  943. copy_AddFile:
  944.         pushad
  945.         mov     eax, [esp+20h+12]
  946.         mov     [source_hFile], eax
  947.         mov     edx, [esp+20h+8]
  948.         mov     edi, [esp+20h+4]
  949.         call    copy_file_worker2
  950.         popad
  951.         setna   al
  952.         ret     12
  953.  
  954. search_dir_query_size = 32
  955. search_filebuf_size = 32768
  956.  
  957. virtual at 0
  958. filesearch_data:
  959. .prev_screen_vtable     dd      ?       ; previous in window stack
  960. .prev_screen_data       dd      ?
  961. .tid                    dd      ?       ; -1 for query stage, secondary thread id for search stage
  962. .slot                   dd      ?       ; 0 if secondary thread is not running, it's slot otherwise
  963. .result_blocks          dd      ?       ; head of heap blocks for resulting data
  964. .cur_result_ptr         dd      ?       ; offset of free data in the current heap block for result
  965. .stop                   db      ?       ; set to 1 when secondary thread need to be stopped
  966. .skip_errors_mask       db      ?
  967. .skip_read_folder = 1
  968. .skip_set_folder = 2
  969. .skip_open_file = 4
  970. .skip_read_file = 8
  971. .skip_bigname = 10h
  972. .updating               db      ?
  973. .datachanged            db      ?
  974. .list.curitemptr        dd      ?
  975. .list.numitems          dd      ?
  976. .list.head              dd      ?
  977. .list.curitem           dd      ?
  978. .list.end               dd      ?
  979. .query_dlgdata          rb      filesearch_query_template.size
  980. .search_dlgdata         rb      filesearch_search_template.size
  981. .mask.maxlen            dd      ?
  982. .mask.pos               dd      ?
  983. .mask.start             dd      ?
  984. .mask                   rb      512
  985. .string.maxlen          dd      ?
  986. .string.pos             dd      ?
  987. .string.start           dd      ?
  988. .string                 rb      256
  989. .caption                rb      268
  990. .statusstr              rb      80
  991. .stack                  rb      8192
  992. .stacktop = $
  993. .fs.func                dd      ?
  994. .fs.pos_low             dd      ?
  995. .fs.pos_high            dd      ?
  996. .fs.size                dd      ?
  997. .fs.ptr                 dd      ?
  998. .curfile                rb      1024
  999. .curdir                 rb      1024
  1000. .lowername              rb      264
  1001. .dir_area               rb      32 + 304*search_dir_query_size
  1002. .filebuf                rb      search_filebuf_size
  1003. .size = $
  1004. end virtual
  1005.  
  1006. panels_OnKey.alt_f7:
  1007.         mov     ecx, filesearch_data.size
  1008.         mov     edx, filesearch_vtable
  1009.         call    new_screen
  1010.         test    eax, eax
  1011.         jnz     @f
  1012.         ret
  1013. @@:
  1014.         mov     [ebp+filesearch_data.prev_screen_vtable], panels_vtable
  1015.         mov     ecx, (filesearch_query_template.size + filesearch_search_template.size) / 4
  1016.         mov     esi, filesearch_query_template
  1017.         lea     edi, [ebp+filesearch_data.query_dlgdata]
  1018.         rep     movsd
  1019.         lea     eax, [ebp+filesearch_data.string.maxlen]
  1020.         xor     ebx, ebx
  1021.         mov     dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.editptr2-filesearch_query_template], eax
  1022.         mov     dword [eax], 253
  1023.         mov     [eax+4], ebx
  1024.         mov     [eax+8], ebx
  1025.         mov     [eax+12], bl
  1026.         sub     eax, filesearch_data.string - filesearch_data.mask
  1027.         mov     dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.editptr1-filesearch_query_template], eax
  1028.         mov     dword [eax], 511
  1029.         mov     [eax+8], ebx
  1030.         inc     ebx
  1031.         mov     word [eax+12], '*'
  1032.         mov     [eax+4], ebx
  1033.         mov     eax, [find_in_file_dlgdata.flags_case]
  1034.         and     al, 10h
  1035.         or      al, 8
  1036.         mov     dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_case-filesearch_query_template], eax
  1037.         mov     eax, [find_in_file_dlgdata.flags_whole]
  1038.         and     al, 10h
  1039.         or      al, 8
  1040.         mov     dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], eax
  1041.         lea     edi, [ebp+filesearch_data.caption]
  1042.         mov     dword [ebp+dlgtemplate.title+filesearch_data.search_dlgdata], edi
  1043.         lea     eax, [ebp+filesearch_data.list.curitemptr]
  1044.         mov     dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data1-filesearch_search_template], eax
  1045. .reinit:
  1046.         xor     ebx, ebx
  1047.         or      [ebp+filesearch_data.tid], -1
  1048.         mov     [ebp+filesearch_data.slot], ebx
  1049.         mov     [ebp+filesearch_data.result_blocks], ebx
  1050.         mov     [ebp+filesearch_data.cur_result_ptr], 0x4000
  1051.         mov     [ebp+filesearch_data.list.curitemptr], ebx
  1052.         mov     [ebp+filesearch_data.list.numitems], ebx
  1053.         mov     [ebp+filesearch_data.list.head], ebx
  1054.         mov     [ebp+filesearch_data.list.curitem], ebx
  1055.         mov     [ebp+filesearch_data.list.end], ebx
  1056.         mov     [ebp+filesearch_data.stop], bl
  1057.         mov     al, [dialog_main_color]
  1058.         mov     [ebp+filesearch_data.query_dlgdata+dlgtemplate.main_color], al
  1059.         mov     [ebp+filesearch_data.search_dlgdata+dlgtemplate.main_color], al
  1060.         mov     al, [dialog_border_color]
  1061.         mov     [ebp+filesearch_data.query_dlgdata+dlgtemplate.border_color], al
  1062.         mov     [ebp+filesearch_data.search_dlgdata+dlgtemplate.border_color], al
  1063.         mov     al, [dialog_header_color]
  1064.         mov     [ebp+filesearch_data.query_dlgdata+dlgtemplate.header_color], al
  1065.         mov     [ebp+filesearch_data.search_dlgdata+dlgtemplate.header_color], al
  1066. filesearch_OnRedraw:
  1067.         push    ebp
  1068.         mov     byte [draw_image], 0xC3
  1069.         mov     eax, [ebp+filesearch_data.prev_screen_vtable]
  1070.         mov     ebp, [ebp+filesearch_data.prev_screen_data]
  1071.         call    dword [eax+screen_vtable.OnRedraw]
  1072.         mov     byte [draw_image], 0xC6
  1073.         pop     ebp
  1074.         cmp     [ebp+filesearch_data.tid], -1
  1075.         jnz     .prepare_search_dlg
  1076.         lea     ebx, [ebp+filesearch_data.query_dlgdata]
  1077.         mov     eax, [cur_width]
  1078.         mov     [ebx + dlgtemplate.x], 6
  1079.         sub     eax, 12
  1080.         mov     [ebx + dlgtemplate.width], eax
  1081.         dec     eax
  1082.         dec     eax
  1083.         mov     [ebx - filesearch_query_template + filesearch_query_template.width2], eax
  1084.         mov     [ebx - filesearch_query_template + filesearch_query_template.width3], eax
  1085.         shr     eax, 1
  1086.         dec     eax
  1087.         dec     eax
  1088.         mov     [ebx - filesearch_query_template + filesearch_query_template.search_x2], eax
  1089.         sub     eax, aSearchBLength-1
  1090.         mov     [ebx - filesearch_query_template + filesearch_query_template.search_x1], eax
  1091.         add     eax, aSearchBLength+3
  1092.         mov     [ebx - filesearch_query_template + filesearch_query_template.cnl_x1], eax
  1093.         add     eax, aCancelBLength-1
  1094.         mov     [ebx - filesearch_query_template + filesearch_query_template.cnl_x2], eax
  1095.         mov     eax, [cur_height]
  1096.         sub     eax, [ebx + dlgtemplate.height]
  1097.         shr     eax, 1
  1098.         mov     [ebx + dlgtemplate.y], eax
  1099.         jmp     .dlg_prepared
  1100. .prepare_search_dlg:
  1101.         lea     ebx, [ebp+filesearch_data.search_dlgdata]
  1102. ; width: for big screens use all screen except for one column on each side,
  1103. ;       that is, [cur_width] - 10 (standard frame width is 4);
  1104. ; if [cur_width]-10 does not contain enough place for all buttons with two spaces between them,
  1105. ;       but [cur_width]-2 does, use fixed size = place for all buttons with two spaces between them
  1106. ; for small screens use [cur_width]-2 as maximum possible
  1107. .btnsize = 2 + aNewSearchLen + 2 + aGotoLen + 2 + aViewLen + 2 + aCancelB2Length + 2
  1108.         mov     eax, [cur_width]
  1109.         mov     edx, eax
  1110.         sub     eax, 10
  1111.         cmp     eax, .btnsize
  1112.         jae     @f
  1113.         add     eax, 8
  1114.         cmp     eax, .btnsize
  1115.         jb      @f
  1116.         mov     al, .btnsize
  1117. @@:
  1118.         mov     [ebx + dlgtemplate.width], eax
  1119.         sub     edx, eax
  1120.         shr     edx, 1
  1121.         mov     [ebx + dlgtemplate.x], edx
  1122.         dec     eax
  1123.         mov     [ebx + filesearch_search_template.width1 - filesearch_search_template], eax
  1124.         mov     [ebx + filesearch_search_template.width4 - filesearch_search_template], eax
  1125.         cmp     [ebp + filesearch_data.slot], 0
  1126.         jnz     @f
  1127.         mov     [ebx + filesearch_search_template.width3 - filesearch_search_template], eax
  1128. @@:
  1129.         sub     eax, aNewSearchLen + aGotoLen + aViewLen + aCancelB2Length - 1
  1130.         cdq
  1131.         push    5
  1132.         pop     ecx
  1133.         idiv    ecx
  1134.         sar     edx, 1
  1135.         add     edx, eax
  1136.         inc     eax
  1137.         mov     [ebx + filesearch_search_template.btn1x1 - filesearch_search_template], edx
  1138.         add     edx, aNewSearchLen-1
  1139.         mov     [ebx + filesearch_search_template.btn1x2 - filesearch_search_template], edx
  1140.         add     edx, eax
  1141.         mov     [ebx + filesearch_search_template.btn2x1 - filesearch_search_template], edx
  1142.         add     edx, aGotoLen-1
  1143.         mov     [ebx + filesearch_search_template.btn2x2 - filesearch_search_template], edx
  1144.         add     edx, eax
  1145.         mov     [ebx + filesearch_search_template.btn3x1 - filesearch_search_template], edx
  1146.         add     edx, aViewLen-1
  1147.         mov     [ebx + filesearch_search_template.btn3x2 - filesearch_search_template], edx
  1148.         add     edx, eax
  1149.         mov     [ebx + filesearch_search_template.btn4x1 - filesearch_search_template], edx
  1150.         add     edx, aCancelB2Length-1
  1151.         mov     [ebx + filesearch_search_template.btn4x2 - filesearch_search_template], edx
  1152.         mov     eax, [cur_height]
  1153.         mov     edx, eax
  1154.         sub     eax, 8
  1155.         cmp     eax, 6
  1156.         jae     @f
  1157.         mov     eax, 6
  1158. @@:
  1159.         mov     [ebx + dlgtemplate.height], eax
  1160.         sub     edx, eax
  1161.         shr     edx, 1
  1162.         mov     [ebx + dlgtemplate.y], edx
  1163.         dec     eax
  1164.         mov     [ebx + filesearch_search_template.btn1y - filesearch_search_template], eax
  1165.         mov     [ebx + filesearch_search_template.btn2y - filesearch_search_template], eax
  1166.         mov     [ebx + filesearch_search_template.btn3y - filesearch_search_template], eax
  1167.         mov     [ebx + filesearch_search_template.btn4y - filesearch_search_template], eax
  1168.         dec     eax
  1169.         mov     [ebx + filesearch_search_template.y5 - filesearch_search_template], eax
  1170.         dec     eax
  1171.         mov     [ebx + filesearch_search_template.y3 - filesearch_search_template], eax
  1172.         mov     [ebx + filesearch_search_template.y4 - filesearch_search_template], eax
  1173.         dec     eax
  1174.         mov     [ebx + filesearch_search_template.y2 - filesearch_search_template], eax
  1175.         dec     eax
  1176.         mov     [ebx + filesearch_search_template.height1 - filesearch_search_template], eax
  1177. .dlg_prepared:
  1178.         call    draw_dialog_shadow
  1179.         push    ebx
  1180.         call    DrawDialogBox
  1181.         ret
  1182.  
  1183. filesearch_OnActivate:
  1184.         mov     eax, [active_screen_data]
  1185.         cmp     eax, ebp
  1186.         jz      @f
  1187.         mov     [ebp+filesearch_data.prev_screen_data], eax
  1188.         mov     eax, [active_screen_vtable]
  1189.         mov     [ebp+filesearch_data.prev_screen_vtable], eax
  1190. @@:
  1191.         mov     eax, [ebp+filesearch_data.prev_screen_data]
  1192.         mov     ecx, [num_screens]
  1193.         mov     edx, [screens]
  1194.         push    edx
  1195. @@:
  1196.         cmp     [edx+4], eax
  1197.         jz      @f
  1198.         add     edx, 8
  1199.         loop    @b
  1200. @@:
  1201.         pop     edx
  1202.         jz      @f
  1203.         mov     eax, [active_screen]
  1204.         dec     eax
  1205.         mov     ecx, [edx+eax*8+4]
  1206.         mov     [ebp+filesearch_data.prev_screen_data], ecx
  1207.         mov     ecx, [edx+eax*8]
  1208.         mov     [ebp+filesearch_data.prev_screen_vtable], ecx
  1209. @@:
  1210.         cmp     [ebp+filesearch_data.slot], 0
  1211.         jz      @f
  1212.         mov     [idle_interval], 10
  1213. @@:
  1214. ;        ret    ; continue to filesearch_OnIdle
  1215.  
  1216. filesearch_OnIdle:
  1217.         xor     eax, eax
  1218.         xchg    al, [ebp+filesearch_data.datachanged]
  1219.         cmp     al, 1
  1220.         ja      .done
  1221.         jz      .new
  1222. .ret:
  1223.         ret
  1224. .done:
  1225.         call    filesearch_wait_thread
  1226.         call    filesearch_done
  1227. .new:
  1228.         jmp     filesearch_OnRedraw
  1229.  
  1230. filesearch_OnKey:
  1231.         cmp     al, 0x58
  1232.         jz      F12
  1233.         cmp     [ebp+filesearch_data.tid], -1
  1234.         jz      .handle_generic
  1235.         cmp     al, 0x47
  1236.         jb      .notforlist
  1237.         cmp     al, 0x49
  1238.         jbe     @f
  1239.         cmp     al, 0x4F
  1240.         jb      .notforlist
  1241.         cmp     al, 0x51
  1242.         ja      .notforlist
  1243. @@:
  1244.         push    ebp
  1245.         add     ebp, filesearch_data.search_dlgdata
  1246.         lea     ebx, [ebp+dlgtemplate.size+12]
  1247.         call    listbox_key
  1248.         call    draw_listbox
  1249.         call    draw_image
  1250.         pop     ebp
  1251.         ret
  1252. .notforlist:
  1253.         cmp     al, 0x3D
  1254.         jz      .view
  1255. .handle_generic:
  1256.         push    ebp
  1257.         call    filesearch_getcurdlg
  1258.         push    0
  1259.         push    eax
  1260.         push    2
  1261.         push    ebx
  1262.         call    ManagerDlgProc
  1263.         pop     ebp
  1264.         test    eax, eax
  1265.         jz      filesearch_OnIdle.ret
  1266.         cmp     eax, -1
  1267.         jz      .esc
  1268.         sub     eax, ebp
  1269.         cmp     eax, filesearch_data.query_dlgdata+filesearch_query_template.search_btn-filesearch_query_template
  1270.         jz      .query
  1271.         cmp     eax, filesearch_data.search_dlgdata+filesearch_search_template.btn1-filesearch_search_template
  1272.         jz      .newsearch
  1273.         cmp     eax, filesearch_data.search_dlgdata+filesearch_search_template.btn2-filesearch_search_template
  1274.         jz      .goto
  1275.         cmp     eax, filesearch_data.search_dlgdata+filesearch_search_template.btn3-filesearch_search_template
  1276.         jz      .view
  1277. .esc:
  1278.         cmp     dword [ebp+filesearch_data.slot], 0
  1279.         jz      .exit
  1280.         mov     [ebp+filesearch_data.stop], 2
  1281.         call    ConfirmCancel
  1282.         setz    [ebp+filesearch_data.stop]
  1283. .ret:
  1284.         ret
  1285. .exit:
  1286.         call    filesearch_OnExit
  1287.         jmp     delete_active_screen
  1288. .view:
  1289.         mov     esi, [ebp+filesearch_data.list.curitemptr]
  1290.         test    esi, esi
  1291.         jz      .ret
  1292.         add     esi, 8
  1293.         mov     eax, esi
  1294.         jmp     view_file
  1295. .goto:
  1296.         mov     esi, [ebp+filesearch_data.list.curitemptr]
  1297.         test    esi, esi
  1298.         jz      .ret
  1299.         add     esi, 8
  1300.         cmp     byte [esi], '/'
  1301.         jnz     .ret
  1302.         cmp     byte [esi+1], 0
  1303.         jz      .ret
  1304.         push    ebp
  1305.         mov     ebp, [active_panel]
  1306.         push    esi
  1307.         call    close_plugin_panels
  1308.         pop     esi
  1309.         mov     ecx, esi
  1310. @@:
  1311.         lodsb
  1312.         test    al, al
  1313.         jnz     @b
  1314. @@:
  1315.         dec     esi
  1316.         cmp     byte [esi], '/'
  1317.         jnz     @b
  1318.         mov     byte [esi], 0
  1319.         inc     esi
  1320.         mov     edi, saved_file_name
  1321. @@:
  1322.         lodsb
  1323.         stosb
  1324.         test    al, al
  1325.         jnz     @b
  1326.         mov     esi, ecx
  1327.         lea     edi, [ebp + panel1_dir - panel1_data]
  1328.         push    esi edi
  1329.         call    strcmpi
  1330.         pop     edi esi
  1331.         jz      .goto.samedir
  1332. @@:
  1333.         lodsb
  1334.         stosb
  1335.         test    al, al
  1336.         jnz     @b
  1337.         and     [ebp + panel1_start - panel1_data], 0
  1338.         and     [ebp + panel1_index - panel1_data], 0
  1339. .goto.samedir:
  1340.         push    @f
  1341.         push    [ebp + panel1_index - panel1_data]
  1342.         jmp     panels_OnKey.ctrl_r.doread
  1343. @@:
  1344.         pop     ebp
  1345.         jmp     .exit
  1346. .newsearch:
  1347.         cmp     [ebp+filesearch_data.slot], 0
  1348.         jz      .do.newsearch
  1349.         call    filesearch_stop_thread
  1350. .do.newsearch:
  1351.         call    filesearch_free_result
  1352.         jmp     panels_OnKey.alt_f7.reinit
  1353. .query:
  1354.         mov     esi, [active_panel]
  1355.         cmp     [esi + panel1_hPlugin - panel1_data], 0
  1356.         jz      @f
  1357.         push    aCannotSearchOnPlugin
  1358.         mov     eax, esp
  1359.         push    ContinueBtn
  1360.         push    1
  1361.         push    eax
  1362.         push    1
  1363.         call    SayErr
  1364.         pop     eax
  1365.         jmp     .exit
  1366. @@:
  1367.         add     esi, panel1_dir - panel1_data
  1368.         lea     edi, [ebp+filesearch_data.curdir]
  1369. @@:
  1370.         lodsb
  1371.         stosb
  1372.         test    al, al
  1373.         jnz     @b
  1374.         push    51
  1375.         pop     eax
  1376.         push    1
  1377.         pop     ebx
  1378.         mov     ecx, filesearch_thread
  1379.         lea     edx, [ebp+filesearch_data.stacktop-4]
  1380.         mov     [edx], ebp
  1381.         int     40h
  1382.         cmp     eax, -1
  1383.         jnz     @f
  1384.         push    ContinueBtn
  1385.         push    1
  1386.         push    aCannotCreateThread_ptr
  1387.         push    1
  1388.         call    SayErr
  1389.         ret
  1390. @@:
  1391.         mov     [ebp+filesearch_data.tid], eax
  1392.         mov     [ebp+filesearch_data.updating], 0
  1393.         mov     [ebp+filesearch_data.datachanged], 0
  1394.         xchg    eax, ecx
  1395.         push    18
  1396.         pop     eax
  1397.         push    21
  1398.         pop     ebx
  1399.         int     40h
  1400.         mov     [ebp+filesearch_data.slot], eax
  1401.         mov     [idle_interval], 10
  1402.         mov     esi, aFileSearch
  1403.         mov     edi, dword [ebp+filesearch_data.search_dlgdata+dlgtemplate.title]
  1404. @@:
  1405.         lodsb
  1406.         stosb
  1407.         test    al, al
  1408.         jnz     @b
  1409.         mov     byte [edi-1], ':'
  1410.         mov     al, ' '
  1411.         stosb
  1412.         lea     esi, [ebp+filesearch_data.mask]
  1413. @@:
  1414.         lodsb
  1415.         stosb
  1416.         test    al, al
  1417.         jnz     @b
  1418.         lea     edi, [ebp+filesearch_data.statusstr]
  1419.         mov     dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data3-filesearch_search_template], edi
  1420.         mov     esi, aSearchingIn
  1421. @@:
  1422.         lodsb
  1423.         stosb
  1424.         cmp     al, '"'
  1425.         jnz     @b
  1426.         push    esi
  1427.         push    10
  1428.         pop     ecx
  1429.         lea     esi, [ebp+filesearch_data.string]
  1430. @@:
  1431.         lodsb
  1432.         test    al, al
  1433.         jz      @f
  1434.         stosb
  1435.         loop    @b
  1436. @@:
  1437.         pop     esi
  1438.         movsb
  1439.         jz      @f
  1440.         mov     byte [edi-1], '.'
  1441.         mov     byte [edi-2], '.'
  1442.         mov     byte [edi-3], '.'
  1443.         mov     byte [edi-4], '"'
  1444. @@:
  1445.         cmp     byte [edi-2], '"'
  1446.         jnz     @f
  1447.         sub     edi, 3
  1448. @@:
  1449.         lodsb
  1450.         stosb
  1451.         test    al, al
  1452.         jnz     @b
  1453.         sub     edi, dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data3-filesearch_search_template]
  1454.         mov     dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.width3-filesearch_search_template], edi
  1455.         inc     edi
  1456.         mov     dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.x4-filesearch_search_template], edi
  1457.         lea     eax, [ebp+filesearch_data.curdir]
  1458.         mov     dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data4-filesearch_search_template], eax
  1459.         call    filesearch_set_dlgflags         ; use it? I think, yes
  1460.         cmp     [ebp+filesearch_data.slot], 0
  1461.         jnz     @f
  1462.         call    filesearch_done
  1463. @@:
  1464.         jmp     filesearch_OnRedraw
  1465.  
  1466. filesearch_done:
  1467.         cmp     [active_screen_data], ebp
  1468.         jnz     @f
  1469.         or      [idle_interval], -1
  1470. @@:
  1471.         and     dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data4-filesearch_search_template], 0
  1472.         mov     edi, dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data3-filesearch_search_template]
  1473.         mov     esi, aSearchDone
  1474. @@:
  1475.         lodsb
  1476.         stosb
  1477.         cmp     al, '?'
  1478.         jnz     @b
  1479.         dec     edi
  1480.         mov     eax, [ebp+filesearch_data.list.numitems]
  1481.         push    -'0'
  1482.         push    10
  1483.         pop     ecx
  1484. @@:
  1485.         xor     edx, edx
  1486.         div     ecx
  1487.         push    edx
  1488.         test    eax, eax
  1489.         jnz     @b
  1490. @@:
  1491.         pop     eax
  1492.         add     al, '0'
  1493.         jz      @f
  1494.         stosb
  1495.         jmp     @b
  1496. @@:
  1497.         lodsb
  1498.         stosb
  1499.         test    al, al
  1500.         jnz     @b
  1501.         ret
  1502.  
  1503. filesearch_getname:
  1504. if lang eq ru
  1505.         mov     eax, '„¨ «'
  1506.         stosd
  1507.         mov     eax, '®£ ¯'
  1508.         stosd
  1509.         mov     eax, '®¨áª'
  1510.         stosd
  1511.         mov     al, ' '
  1512.         stosb
  1513. else
  1514.         mov     eax, 'Find'
  1515.         stosd
  1516.         mov     eax, ' dia'
  1517.         stosd
  1518.         mov     eax, 'log '
  1519.         stosd
  1520.         mov     al, ' '
  1521.         stosb
  1522. end if
  1523.         ret
  1524.  
  1525. filesearch_stop_thread:
  1526.         mov     [ebp+filesearch_data.stop], 1
  1527.  
  1528. filesearch_wait_thread:
  1529.         mov     ecx, [ebp+filesearch_data.slot]
  1530.         mov     edx, [ebp+filesearch_data.tid]
  1531.         jecxz   .secondary_thread_exited
  1532. @@:
  1533.         mov     ebx, procinfo
  1534.         push    9
  1535.         pop     eax
  1536.         int     40h
  1537.         cmp     word [ebx+50], 9
  1538.         jz      .secondary_thread_exited
  1539.         cmp     dword [ebx+30], edx
  1540.         jnz     .secondary_thread_exited
  1541.         push    5
  1542.         pop     eax
  1543.         push    1
  1544.         pop     ebx
  1545.         int     40h
  1546.         jmp     @b
  1547. .secondary_thread_exited:
  1548.         and     [ebp+filesearch_data.slot], 0
  1549.         ret
  1550.  
  1551. filesearch_OnExit:
  1552.         call    filesearch_stop_thread
  1553.         call    filesearch_free_result
  1554. ;       call    filesearch_set_dlgflags         ; use it? I think, no
  1555.         ret
  1556.  
  1557. filesearch_IsHandleUsed:
  1558.         test    ebp, ebp
  1559.         ret
  1560.  
  1561. filesearch_set_dlgflags:
  1562.         mov     eax, dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_case-filesearch_query_template]
  1563.         and     al, 10h
  1564.         or      al, 8
  1565.         mov     [find_in_file_dlgdata.flags_case], eax
  1566.         mov     eax, dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template]
  1567.         and     al, 10h
  1568.         or      al, 8
  1569.         mov     [find_in_file_dlgdata.flags_whole], eax
  1570.         lea     esi, [ebp+filesearch_data.string]
  1571.         mov     edi, SearchString
  1572.         and     dword [edi-4], 0
  1573.         and     dword [edi-8], 0
  1574. @@:
  1575.         lodsb
  1576.         stosb
  1577.         test    al, al
  1578.         jnz     @b
  1579.         ret
  1580.  
  1581. filesearch_getcurdlg:
  1582.         lea     ebx, [ebp+filesearch_data.query_dlgdata]
  1583.         cmp     [ebp+filesearch_data.tid], -1
  1584.         jz      @f
  1585.         add     ebx, filesearch_data.search_dlgdata - filesearch_data.query_dlgdata
  1586. @@:
  1587.         ret
  1588.  
  1589. filesearch_free_result:
  1590.         mov     ecx, [ebp+filesearch_data.result_blocks]
  1591. @@:
  1592.         jecxz   .ret
  1593.         push    dword [ecx]
  1594.         call    pgfree
  1595.         pop     ecx
  1596.         jmp     @b
  1597. .ret:
  1598.         ret
  1599.  
  1600. filesearch_thread:
  1601.         pop     ebp
  1602. ; initialize search for string
  1603.         xor     ecx, ecx
  1604.         xor     edx, edx
  1605.         mov     [ebp+filesearch_data.skip_errors_mask], cl
  1606.         lea     ebx, [ebp+filesearch_data.string]
  1607.         cmp     byte [ebx], dl
  1608.         jz      .noprepare
  1609.         mov     esi, tolower_table
  1610.         test    byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_case-filesearch_query_template], 10h
  1611.         jz      @f
  1612.         mov     esi, identical_table
  1613. @@:
  1614.         test    byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], 10h
  1615.         setnz   al
  1616.         push    eax
  1617.         push    ecx     ; force cp866
  1618.         call    search_string_pre
  1619. .noprepare:
  1620.         push    -1
  1621. .enter_recursion:
  1622.         xor     esi, esi        ; start position: zero
  1623. .read_folder_loop:
  1624.         push    esi
  1625.         lea     esi, [ebp+filesearch_data.curdir]
  1626.         lea     edi, [ebp+filesearch_data.curfile]
  1627. @@:
  1628.         lodsb
  1629.         stosb
  1630.         test    al, al
  1631.         jnz     @b
  1632.         pop     esi
  1633. .read_retry:
  1634.         lea     ebx, [ebp+filesearch_data.fs.func]
  1635.         mov     dword [ebx], 1
  1636.         mov     dword [ebx+4], esi
  1637.         and     dword [ebx+8], 0
  1638.         mov     dword [ebx+12], search_dir_query_size
  1639.         lea     eax, [ebp+filesearch_data.dir_area]
  1640.         mov     [ebx+16], eax
  1641.         push    70
  1642.         pop     eax
  1643.         int     40h
  1644.         test    eax, eax
  1645.         jz      .read_folder_ok
  1646.         cmp     eax, 6
  1647.         jz      .read_folder_ok
  1648.         xor     ebx, ebx
  1649.         xchg    ebx, dword [ebp+filesearch_data.dir_area+4]
  1650.         test    [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_folder
  1651.         jnz     .skip1
  1652.         push    edx
  1653.         lea     edx, [ebp+filesearch_data.curdir]
  1654.         call    recursive_read_folder_err
  1655.         pop     edx
  1656.         jz      .read_retry
  1657.         cmp     al, 2
  1658.         jnz     @f
  1659.         dec     eax
  1660.         or      [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_folder
  1661. @@:
  1662.         cmp     al, 1
  1663.         jnz     .cancel
  1664. .skip1:
  1665. .read_folder_ok:
  1666.         imul    ebx, 304
  1667.         lea     eax, [ebp+filesearch_data.dir_area+32]
  1668.         add     ebx, eax
  1669. .scan_folder_loop:
  1670.         cmp     eax, ebx
  1671.         jae     .scan_folder_done
  1672. ; ignore special entries "." and ".."
  1673.         cmp     word [eax+40], '.'
  1674.         jz      .scan_folder_next
  1675.         cmp     word [eax+40], '..'
  1676.         jnz     @f
  1677.         cmp     byte [eax+42], 0
  1678.         jz      .scan_folder_next
  1679. @@:
  1680.         call    .check_stop
  1681. ; construct name
  1682.         push    esi edi ebx eax
  1683.         lea     ebx, [ebp+filesearch_data.curfile+1023]
  1684.         lea     esi, [eax+40]
  1685.         mov     byte [edi-1], '/'
  1686. @@:
  1687.         cmp     edi, ebx
  1688.         jae     .namebig
  1689.         lodsb
  1690.         stosb
  1691.         test    al, al
  1692.         jnz     @b
  1693.         pop     eax
  1694.         test    byte [eax], 10h
  1695.         jz      .scan_file
  1696. ; it is nested folder, enter recursion
  1697. ; to maintain ASCIIZ string coherency, copy backward
  1698.         lea     esi, [edi+filesearch_data.curdir-filesearch_data.curfile]
  1699. @@:
  1700.         dec     edi
  1701.         dec     esi
  1702.         mov     al, [edi]
  1703.         mov     [esi], al
  1704.         cmp     al, '/'
  1705.         jnz     @b
  1706.         mov     [ebp+filesearch_data.datachanged], 1
  1707.         pop     ebx edi
  1708.         jmp     .enter_recursion
  1709. .namebig:
  1710.         pop     eax
  1711.         mov     byte [edi], 0
  1712.         test    [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_bigname
  1713.         jnz     .namebig.skip
  1714.         push    eax
  1715.         push    edi
  1716.         test    byte [eax], 10h
  1717.         mov     eax, aFileNameTooBig
  1718.         jz      @f
  1719.         add     eax, aFolderNameTooBig - aFileNameTooBig
  1720. @@:
  1721.         push    eax
  1722.         mov     eax, esp
  1723.         push    SkipOrCancelBtn
  1724.         push    3
  1725.         push    eax
  1726.         push    2
  1727.         call    SayErr
  1728.         cmp     al, 1
  1729.         jnz     @f
  1730.         dec     eax
  1731.         or      [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_bigname
  1732. @@:
  1733.         test    al, al
  1734.         pop     eax eax eax
  1735.         jnz     .cancel
  1736. .namebig.skip:
  1737.         jmp     .scan_folder_next_pop
  1738. .scan_file:
  1739. ; it is a file
  1740. ; first check: does file name match the mask?
  1741.         push    eax edx
  1742. ; ®¡àî­¥â¨âì
  1743.         lea     esi, [eax+40]
  1744.         lea     edi, [ebp+filesearch_data.lowername]
  1745.         push    edi
  1746.         xor     eax, eax
  1747. @@:
  1748.         lodsb
  1749.         mov     al, [tolower_table+eax]
  1750.         stosb
  1751.         test    al, al
  1752.         jnz     @b
  1753. ; ¯®¥å «¨
  1754.         lea     edx, [edi-1]
  1755.         pop     esi
  1756.         lea     edi, [ebp+filesearch_data.mask]
  1757.         call    match_mask_rev_lowercase
  1758.         pop     edx eax
  1759.         jc      .scan_folder_next_pop
  1760. ; ok, second check: is the string present in this file?
  1761.         jecxz   .file_found
  1762.         push    eax
  1763.         call    filesearch_test_file
  1764.         pop     eax
  1765.         jc      .scan_folder_next_pop
  1766. .file_found:
  1767.         push    eax
  1768. ; allocate memory for new result
  1769.         lea     esi, [ebp+filesearch_data.curfile]
  1770.         mov     ebx, esi
  1771. @@:
  1772.         lodsb
  1773.         test    al, al
  1774.         jnz     @b
  1775.         sub     esi, ebx
  1776.         mov     eax, [ebp+filesearch_data.cur_result_ptr]
  1777.         add     esi, 8
  1778.         push    ecx
  1779.         mov     ecx, 0x4000
  1780.         sub     ecx, eax
  1781.         cmp     ecx, esi
  1782.         jae     .nonewblock
  1783.         mov     ecx, 0x4000
  1784.         call    xpgalloc
  1785.         test    eax, eax
  1786.         jz      .cancel
  1787.         pushd   [ebp+filesearch_data.result_blocks]
  1788.         popd    [eax]
  1789.         mov     [ebp+filesearch_data.result_blocks], eax
  1790.         push    4
  1791.         pop     eax
  1792.         mov     [ebp+filesearch_data.cur_result_ptr], eax
  1793. .nonewblock:
  1794.         add     eax, [ebp+filesearch_data.result_blocks]
  1795.         add     [ebp+filesearch_data.cur_result_ptr], esi
  1796.         pop     ecx
  1797. ; eax -> allocated memory, fill it
  1798.         push    eax
  1799.         lea     edi, [eax+8]
  1800.         mov     esi, ebx
  1801. @@:
  1802.         lodsb
  1803.         stosb
  1804.         test    al, al
  1805.         jnz     @b
  1806.         pop     eax
  1807.         mov     ebx, [ebp+filesearch_data.list.end]
  1808.         mov     [eax+4], ebx
  1809.         and     dword [eax], 0
  1810.         mov     [ebp+filesearch_data.list.end], eax
  1811.         test    ebx, ebx
  1812.         jz      @f
  1813.         mov     [ebx], eax
  1814. @@:
  1815.         inc     [ebp+filesearch_data.list.numitems]
  1816.         cmp     [ebp+filesearch_data.list.curitemptr], 0
  1817.         jnz     @f
  1818.         mov     [ebp+filesearch_data.list.curitemptr], eax
  1819. @@:
  1820.         cmp     [ebp+filesearch_data.list.head], 0
  1821.         jnz     @f
  1822.         mov     [ebp+filesearch_data.list.head], eax
  1823. @@:
  1824.         mov     [ebp+filesearch_data.datachanged], 1
  1825.         pop     eax
  1826. .scan_folder_next_pop:
  1827.         pop     ebx edi esi
  1828.         mov     byte [edi-1], 0
  1829. .scan_folder_next:
  1830.         inc     esi
  1831.         add     eax, 304
  1832.         jmp     .scan_folder_loop
  1833. .scan_folder_done:
  1834.         cmp     dword [ebp+filesearch_data.dir_area+4], search_dir_query_size
  1835.         jz      .read_folder_loop
  1836.         pop     esi
  1837.         inc     esi
  1838.         jz      .done
  1839.         lea     eax, [ebp+filesearch_data.curdir]
  1840. @@:
  1841.         inc     eax
  1842.         cmp     byte [eax], 0
  1843.         jnz     @b
  1844. @@:
  1845.         dec     eax
  1846.         cmp     byte [eax], '/'
  1847.         jnz     @b
  1848.         mov     byte [eax], 0
  1849.         mov     [ebp+filesearch_data.datachanged], 1
  1850.         jmp     .read_folder_loop
  1851. .cancel:
  1852. .done:
  1853.         mov     [ebp+filesearch_data.datachanged], 2
  1854.         or      eax, -1
  1855.         int     40h
  1856.  
  1857. .check_stop:
  1858.         cmp     [ebp+filesearch_data.stop], 1
  1859.         jz      .cancel
  1860.         ja      @f
  1861.         ret
  1862. @@:
  1863.         push    eax ebx
  1864.         push    5
  1865.         pop     eax
  1866.         push    1
  1867.         pop     ebx
  1868.         int     40h
  1869.         pop     ebx eax
  1870.         jmp     .check_stop
  1871.  
  1872. filesearch_test_file:
  1873.         lea     ebx, [ebp+filesearch_data.fs.func]
  1874.         lea     eax, [ebp+filesearch_data.filebuf]
  1875.         mov     [ebx+16], eax
  1876.         xor     eax, eax
  1877.         mov     [ebx], eax
  1878.         mov     [ebx+4], eax
  1879.         mov     [ebx+8], eax
  1880.         mov     dword [ebx+12], search_filebuf_size
  1881.         mov     edi, edx
  1882.         test    byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], 10h
  1883.         jz      .loop
  1884.         add     edi, 256
  1885. .loop:
  1886. .read_retry:
  1887.         call    filesearch_thread.check_stop
  1888.         push    70
  1889.         pop     eax
  1890.         lea     ebx, [ebp+filesearch_data.fs.func]
  1891.         int     40h
  1892.         test    eax, eax
  1893.         jz      .readok
  1894.         cmp     eax, 6
  1895.         jz      .readok
  1896.         test    [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_file
  1897.         jnz     .ret_failed
  1898.         push    edx
  1899.         lea     edx, [ebp+filesearch_data.curfile]
  1900.         call    recursive_read_file_err
  1901.         pop     edx
  1902.         jz      .read_retry
  1903.         cmp     al, 2
  1904.         jnz     @f
  1905.         dec     eax
  1906.         or      [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_file
  1907. @@:
  1908.         cmp     al, 1
  1909.         jnz     filesearch_thread.cancel
  1910. .ret_failed:
  1911.         stc
  1912.         ret
  1913. .readok:
  1914.         test    ebx, ebx
  1915.         jz      .eof
  1916.         push    ebx
  1917.         lea     esi, [ebp+filesearch_data.filebuf]
  1918.         add     ebx, esi
  1919. ; edi = current state, edx -> FSM, ecx = last state,
  1920. ; esi -> current data, ebx -> end of buffer
  1921. .scanloop:       ; loop unrolled
  1922. ; get current symbol
  1923.         movzx   eax, byte [esi]
  1924. ; calculate next state
  1925.         movzx   edi, byte [edi+eax]
  1926. ; done?
  1927.         cmp     edi, ecx
  1928.         jz      .ret_ok_pop
  1929. ; no; proceed to next symbol
  1930.         shl     edi, 8
  1931.         add     edi, edx
  1932.         cmp     esi, ebx
  1933.         jae     .scandone
  1934.         movzx   eax, byte [esi+1]
  1935.         add     esi, 2
  1936.         movzx   edi, byte [edi+eax]
  1937.         cmp     edi, ecx
  1938.         jz      .ret_ok_pop
  1939.         shl     edi, 8
  1940.         add     edi, edx
  1941.         cmp     esi, ebx
  1942.         jb      .scanloop
  1943. .scandone:
  1944.         pop     ebx
  1945. .eof:
  1946.         add     [ebp+filesearch_data.fs.pos_low], ebx
  1947.         adc     [ebp+filesearch_data.fs.pos_high], 0
  1948.         cmp     ebx, search_filebuf_size
  1949.         jz      .loop
  1950. ; EOF, last chance for whole-words-only search
  1951.         test    byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], 10h
  1952.         jz      .ret_failed
  1953.         movzx   edi, byte [edi+' ']
  1954.         cmp     edi, ecx
  1955.         jnz     .ret_failed
  1956.         clc
  1957.         ret
  1958. .ret_ok_pop:
  1959.         pop     ebx
  1960.         clc
  1961.         ret
  1962.  
  1963. virtual at 0
  1964. _FILE:
  1965. .pos            dq      ?
  1966. .bufpos         dq      ?
  1967. .bufsize        dd      ?
  1968. .mode           dd      ?
  1969. .hPlugin        dd      ?
  1970. .hFile          dd      ?
  1971. .fileinfo:
  1972. .fimode         dd      ?
  1973. .fioffset       dq      ?
  1974. .fisize         dd      ?
  1975. .fibuf          dd      ?
  1976. .finame         rb      1024
  1977. .attr           rb      40
  1978. align 512
  1979. .buf            rb      2048
  1980. .size = $
  1981. end virtual
  1982.  
  1983. O_READ = 1      ; allows read from file
  1984. O_WRITE = 2     ; allows write to file
  1985. O_CREATE = 4    ; if file does not exist and this flag is set, create file;
  1986.                 ; if file does not exist and this flag is not set, fail
  1987. O_TRUNCATE = 8  ; truncate file if it exists
  1988. O_SEQUENTIAL_ONLY = 10h ; there will be no 'seek'/'setpos' calls
  1989.  
  1990. ; HANDLE __stdcall open(const char* name, int mode);
  1991. ; Opens physical file
  1992. open:
  1993.         pushad
  1994.         mov     ecx, _FILE.size
  1995.         call    xpgalloc
  1996.         test    eax, eax
  1997.         jz      .ret0z
  1998.         mov     [esp+28], eax
  1999.         mov     ecx, eax
  2000.         mov     esi, [esp+36]
  2001.         lea     edi, [eax+_FILE.finame]
  2002.         lea     edx, [eax+_FILE.finame+1024]
  2003. @@:
  2004.         lodsb
  2005.         stosb
  2006.         test    al, al
  2007.         jz      @f
  2008.         cmp     edi, edx
  2009.         jb      @b
  2010. .ret0:
  2011.         call    pgfree
  2012. .ret0z:
  2013.         popad
  2014.         xor     eax, eax
  2015.         ret     8
  2016. @@:
  2017.         mov     eax, [esp+40]
  2018.         mov     [ecx+_FILE.mode], eax
  2019. .getattr:
  2020.         lea     edi, [ecx+_FILE.fileinfo]
  2021.         mov     ebx, edi
  2022.         push    5
  2023.         pop     eax
  2024.         stosd
  2025.         xor     eax, eax
  2026.         stosd
  2027.         stosd
  2028.         stosd
  2029.         lea     eax, [ecx+_FILE.attr]
  2030.         stosd
  2031.         push    70
  2032.         pop     eax
  2033.         int     0x40
  2034.         test    eax, eax
  2035.         jz      .found
  2036.         cmp     eax, 5
  2037.         jnz     .ret0
  2038. ; file does not exist
  2039.         test    [ecx+_FILE.mode], O_CREATE
  2040.         jz      .ret0
  2041. .truncate:
  2042.         lea     ebx, [ecx+_FILE.fileinfo]
  2043.         mov     byte [ebx], 2
  2044.         push    70
  2045.         pop     eax
  2046.         int     0x40
  2047.         test    eax, eax
  2048.         jz      .getattr
  2049.         jmp     .ret0
  2050. .found:
  2051.         test    [ecx+_FILE.mode], O_TRUNCATE
  2052.         jz      @f
  2053.         cmp     dword [ecx+_FILE.attr+36], eax
  2054.         jnz     .truncate
  2055.         cmp     dword [ecx+_FILE.attr+32], eax
  2056.         jnz     .truncate
  2057. @@:
  2058.         mov     dword [ecx+_FILE.pos], eax
  2059.         mov     dword [ecx+_FILE.pos+4], eax
  2060.         mov     dword [ecx+_FILE.bufpos], eax
  2061.         mov     dword [ecx+_FILE.bufpos+4], eax
  2062.         mov     [ecx+_FILE.bufsize], eax
  2063.         mov     [ecx+_FILE.hPlugin], eax
  2064.         mov     [ecx+_FILE.hFile], eax
  2065.         mov     dword [ecx+_FILE.fioffset], eax
  2066.         mov     dword [ecx+_FILE.fioffset+4], eax
  2067.         mov     [esp+28], ecx
  2068.         popad
  2069.         ret     8
  2070.  
  2071. ; HANDLE __stdcall open2(int plugin_id, HANDLE plugin_instance, const char* name, int mode);
  2072. ; Opens file on plugin panel
  2073. open2:
  2074.         cmp     dword [esp+4], 0
  2075.         jnz     .plugin
  2076.         pop     eax
  2077.         add     esp, 8
  2078.         push    eax
  2079.         jmp     open
  2080. .plugin:
  2081.         pushad
  2082.         mov     ecx, _FILE.size
  2083.         call    xpgalloc
  2084.         test    eax, eax
  2085.         jz      .ret0z
  2086.         mov     [esp+28], eax
  2087.         mov     ecx, eax
  2088.         mov     esi, [esp+44]
  2089.         lea     edi, [eax+_FILE.finame]
  2090.         lea     edx, [eax+_FILE.finame+1024]
  2091. @@:
  2092.         lodsb
  2093.         stosb
  2094.         test    al, al
  2095.         jz      @f
  2096.         cmp     edi, edx
  2097.         jb      @b
  2098. .ret0:
  2099.         call    pgfree
  2100. .ret0z:
  2101.         popad
  2102.         xor     eax, eax
  2103.         ret     8
  2104. @@:
  2105.         mov     edx, [esp+36]
  2106.         mov     [ecx+_FILE.hPlugin], edx
  2107.         mov     ebx, [esp+40]
  2108.         mov     eax, [esp+48]
  2109.         mov     [ecx+_FILE.mode], eax
  2110.         push    ebx ecx
  2111.         push    eax
  2112.         lea     eax, [ecx+_FILE.finame]
  2113.         push    eax
  2114.         push    ebx
  2115.         call    [edx+PluginInfo.open]
  2116.         pop     ecx ebx
  2117.         test    eax, eax
  2118.         jz      .ret0
  2119.         mov     [ecx+_FILE.hFile], eax
  2120.         mov     edx, [esp+36]
  2121.         push    ecx
  2122.         lea     edi, [ecx+_FILE.fileinfo]
  2123.         push    edi
  2124.         xor     eax, eax
  2125.         push    ecx
  2126.         push    10
  2127.         pop     ecx
  2128.         rep     stosd
  2129.         pop     ecx
  2130.         lea     eax, [ecx+_FILE.finame]
  2131.         push    eax
  2132.         push    ebx
  2133.         call    [edx+PluginInfo.getattr]
  2134.         pop     ecx
  2135.         xor     eax, eax
  2136.         mov     dword [ecx+_FILE.pos], eax
  2137.         mov     dword [ecx+_FILE.pos+4], eax
  2138.         mov     dword [ecx+_FILE.bufpos], eax
  2139.         mov     dword [ecx+_FILE.bufpos+4], eax
  2140.         mov     [ecx+_FILE.bufsize], eax
  2141.         mov     dword [ecx+_FILE.fioffset], eax
  2142.         mov     dword [ecx+_FILE.fioffset+4], eax
  2143.         mov     [esp+28], ecx
  2144.         popad
  2145.         ret     16
  2146.  
  2147. ; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
  2148. read:
  2149.         xor     eax, eax
  2150.         pushad
  2151.         mov     ecx, [esp+36]
  2152.         test    [ecx+_FILE.mode], O_READ
  2153.         jnz     @f
  2154. .ret:
  2155.         popad
  2156.         ret     12
  2157. @@:
  2158.         cmp     dword [esp+44], eax
  2159.         jz      .ret
  2160.         mov     [ecx+_FILE.fimode], eax
  2161.         mov     ebx, [ecx+_FILE.bufsize]
  2162.         mov     eax, dword [ecx+_FILE.pos]
  2163.         and     eax, 2047
  2164.         sub     ebx, eax
  2165.         jbe     .nobuf0
  2166.         cmp     ebx, [esp+44]
  2167.         jbe     @f
  2168.         mov     ebx, [esp+44]
  2169. @@:
  2170.         push    ecx
  2171.         lea     esi, [ecx+eax+_FILE.buf]
  2172.         mov     ecx, ebx
  2173.         mov     edi, [esp+44]
  2174.         rep     movsb
  2175.         pop     ecx
  2176.         mov     [esp+40], edi
  2177.         add     [esp+28], ebx
  2178.         add     dword [ecx+_FILE.pos], ebx
  2179.         adc     dword [ecx+_FILE.pos+4], 0
  2180.         test    dword [ecx+_FILE.pos], 2047
  2181.         jnz     @f
  2182.         and     [ecx+_FILE.bufsize], 0
  2183. @@:
  2184.         sub     [esp+44], ebx
  2185.         jz      .ret
  2186. .nobuf0:
  2187.         test    dword [ecx+_FILE.pos], 2047
  2188.         jz      .aligned
  2189.         cmp     dword [ecx+_FILE.bufsize], 0
  2190.         jnz     .ret
  2191.         lea     ebx, [ecx+_FILE.fileinfo]
  2192.         mov     dword [ebx+12], 2048
  2193.         lea     eax, [ecx+_FILE.buf]
  2194.         mov     dword [ebx+16], eax
  2195.         mov     eax, dword [ecx+_FILE.fioffset]
  2196.         mov     dword [ecx+_FILE.bufpos], eax
  2197.         mov     eax, dword [ecx+_FILE.fioffset+4]
  2198.         mov     dword [ecx+_FILE.bufpos+4], eax
  2199.         call    .doread
  2200.         test    eax, eax
  2201.         jnz     .ret
  2202.         mov     [ecx+_FILE.bufsize], ebx
  2203.         mov     eax, dword [ecx+_FILE.pos]
  2204.         and     eax, 2047
  2205.         sub     ebx, eax
  2206.         jbe     .ret
  2207.         cmp     ebx, [esp+44]
  2208.         jbe     @f
  2209.         mov     ebx, [esp+44]
  2210. @@:
  2211.         push    ecx
  2212.         lea     esi, [ecx+eax+_FILE.buf]
  2213.         mov     ecx, ebx
  2214.         mov     edi, [esp+44]
  2215.         rep     movsb
  2216.         pop     ecx
  2217.         add     dword [ecx+_FILE.pos], ebx
  2218.         adc     dword [ecx+_FILE.pos+4], 0
  2219.         mov     [esp+40], edi
  2220.         add     [esp+28], ebx
  2221.         sub     [esp+44], ebx
  2222.         jz      .ret
  2223.         test    dword [ecx+_FILE.pos], 2047
  2224.         jnz     .ret
  2225. .aligned:
  2226.         lea     ebx, [ecx+_FILE.fileinfo]
  2227.         mov     eax, [esp+44]
  2228.         and     eax, not 2047
  2229.         jz      .finish
  2230.         and     [ecx+_FILE.bufsize], 0
  2231.         mov     [ebx+12], eax
  2232.         mov     eax, [esp+40]
  2233.         mov     [ebx+16], eax
  2234.         call    .doread
  2235.         test    eax, eax
  2236.         jnz     .ret
  2237.         add     dword [ecx+_FILE.pos], ebx
  2238.         adc     dword [ecx+_FILE.pos+4], 0
  2239.         add     [esp+28], ebx
  2240.         add     [esp+40], ebx
  2241.         sub     [esp+44], ebx
  2242.         jz      .ret
  2243.         cmp     ebx, [ecx+_FILE.fisize]
  2244.         jb      .ret
  2245. .finish:
  2246.         lea     ebx, [ecx+_FILE.fileinfo]
  2247.         mov     dword [ebx+12], 2048
  2248.         lea     eax, [ecx+_FILE.buf]
  2249.         mov     [ebx+16], eax
  2250.         and     [ecx+_FILE.bufsize], 0
  2251.         mov     eax, dword [ecx+_FILE.fioffset]
  2252.         mov     dword [ecx+_FILE.bufpos], eax
  2253.         mov     eax, dword [ecx+_FILE.fioffset+4]
  2254.         mov     dword [ecx+_FILE.bufpos+4], eax
  2255.         call    .doread
  2256.         test    eax, eax
  2257.         jnz     .ret
  2258.         mov     [ecx+_FILE.bufsize], ebx
  2259.         cmp     ebx, [esp+44]
  2260.         jb      @f
  2261.         mov     ebx, [esp+44]
  2262. @@:
  2263.         add     [esp+28], ebx
  2264.         add     dword [ecx+_FILE.pos], ebx
  2265.         adc     dword [ecx+_FILE.pos+4], 0
  2266.         lea     esi, [ecx+_FILE.buf]
  2267.         mov     edi, [esp+40]
  2268.         mov     ecx, ebx
  2269.         rep     movsb
  2270.         popad
  2271.         ret     12
  2272. .doread:
  2273.         mov     eax, [ecx+_FILE.hPlugin]
  2274.         test    eax, eax
  2275.         jz      .native
  2276.         push    ecx
  2277.         push    [ecx+_FILE.fisize]
  2278.         push    [ecx+_FILE.fibuf]
  2279.         push    [ecx+_FILE.hFile]
  2280.         call    [eax+PluginInfo.read]
  2281.         pop     ecx
  2282.         cmp     eax, -1
  2283.         jz      @f
  2284.         mov     ebx, eax
  2285.         xor     eax, eax
  2286.         jmp     .addpos
  2287. @@:
  2288.         ret
  2289. .native:
  2290.         push    70
  2291.         pop     eax
  2292.         int     0x40
  2293.         test    eax, eax
  2294.         jz      .addpos
  2295.         cmp     eax, 6
  2296.         jnz     @b
  2297.         xor     eax, eax
  2298. .addpos:
  2299.         add     dword [ecx+_FILE.fioffset], ebx
  2300.         adc     dword [ecx+_FILE.fioffset+4], 0
  2301.         ret
  2302.  
  2303. ; void __stdcall seek(HANDLE hFile, int method, __int64 newpos);
  2304. seek:
  2305.         pushad
  2306.         mov     ecx, [esp+36]
  2307.         mov     eax, [esp+44]
  2308.         mov     edx, [esp+48]
  2309.         cmp     dword [esp+40], 1
  2310.         jb      .set
  2311.         ja      .end
  2312.         add     eax, dword [ecx+_FILE.pos]
  2313.         adc     edx, dword [ecx+_FILE.pos+4]
  2314.         jmp     .set
  2315. .end:
  2316.         add     eax, dword [ecx+_FILE.attr+32]
  2317.         adc     edx, dword [ecx+_FILE.attr+36]
  2318. .set:
  2319.         mov     dword [ecx+_FILE.pos], eax
  2320.         mov     dword [ecx+_FILE.pos+4], edx
  2321.         and     eax, not 2047
  2322.         cmp     eax, dword [ecx+_FILE.bufpos]
  2323.         jnz     @f
  2324.         cmp     edx, dword [ecx+_FILE.bufpos+4]
  2325.         jz      .bufposok
  2326. @@:
  2327.         and     [ecx+_FILE.bufsize], 0
  2328.         mov     dword [ecx+_FILE.bufpos], eax
  2329.         mov     dword [ecx+_FILE.bufpos+4], edx
  2330. .bufposok:
  2331.         cmp     [ecx+_FILE.bufsize], 0
  2332.         jnz     .ret
  2333.         cmp     eax, dword [ecx+_FILE.fioffset]
  2334.         jnz     @f
  2335.         cmp     edx, dword [ecx+_FILE.fioffset+4]
  2336.         jz      .ret
  2337. @@:
  2338.         mov     dword [ecx+_FILE.fioffset], eax
  2339.         mov     dword [ecx+_FILE.fioffset+4], edx
  2340.         mov     eax, [ecx+_FILE.hPlugin]
  2341.         test    eax, eax
  2342.         jz      @f
  2343.         push    dword [ecx+_FILE.fioffset+4]
  2344.         push    dword [ecx+_FILE.fioffset]
  2345.         push    [ecx+_FILE.hFile]
  2346.         call    [eax+PluginInfo.setpos]
  2347. @@:
  2348. .ret:
  2349.         popad
  2350.         ret     16
  2351.  
  2352. setpos_default:
  2353.         push    dword [esp+12]
  2354.         push    dword [esp+12]
  2355.         push    0
  2356.         push    dword [esp+16]
  2357.         call    seek
  2358.         ret     12
  2359.  
  2360. ; __int64 __stdcall tell(HANDLE hFile);
  2361. tell:
  2362.         mov     eax, [esp+4]
  2363.         mov     edx, dword [eax+_FILE.pos+4]
  2364.         mov     eax, dword [eax+_FILE.pos]
  2365.         ret     4
  2366.  
  2367. ; __int64 __stdcall filesize(HANDLE hFile);
  2368. filesize:
  2369.         mov     eax, [esp+4]
  2370.         mov     edx, dword [eax+_FILE.attr+36]
  2371.         mov     eax, dword [eax+_FILE.attr+32]
  2372.         ret     4
  2373.  
  2374. ; void __stdcall close(HANDLE hFile);
  2375. close:
  2376.         pushad
  2377.         mov     ecx, [esp+24h]
  2378.         mov     eax, [ecx+_FILE.hPlugin]
  2379.         test    eax, eax
  2380.         jz      @f
  2381.         push    ecx
  2382.         push    [ecx+_FILE.hFile]
  2383.         call    [eax+PluginInfo.close]
  2384.         pop     ecx
  2385. @@:
  2386.         call    pgfree
  2387.         popad
  2388.         ret     4
  2389.  
  2390. getattr_default:
  2391.         mov     eax, 2
  2392.         ret     12
  2393.