Subversion Repositories Kolibri OS

Rev

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