[WFX] How to show empty (root) directory?

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: Hacker, petermad, Stefan2, white

Post Reply
User avatar
Dalai
Power Member
Power Member
Posts: 9960
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

[WFX] How to show empty (root) directory?

Post by *Dalai »

Hey there :).

Although the heat here in Germany is slowly killing me, I'm trying to fix some bugs in my plugins which I've stumpled upon recently.

Simple question: Is it possible to make TC show an empty directory when entering a plugin?

Here's what I tried:
In FsFindFirstW
  • return INVALID_HANDLE_VALUE and call SetLastError(ERROR_NO_MORE_FILES) => TC doesn't open the plugin at all.
  • return 0 (zero) and call SetLastError(ERROR_NO_MORE_FILES) => TC opens the plugin, but it shows a file without name, date, size etc.
What did I miss?

[EDIT] Fixed typo: SetError => SetLastError [/EDIT]

Regards
Dalai
Last edited by Dalai on 2015-07-06, 11:43 UTC, edited 1 time in total.
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

Return only one item - a directory with name ".". TC will ignore it (because it is a current folder item) and show empty directory.
User avatar
Dalai
Power Member
Power Member
Posts: 9960
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

That works indeed. Thanks! Seems like it's another (undocumented) trick to work with the plugin interface...

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50421
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Actually a call to SetLastError(ERROR_NO_MORE_FILES) should work just fine! What is SetError()?
Author of Total Commander
https://www.ghisler.com
User avatar
Dalai
Power Member
Power Member
Posts: 9960
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

ghisler(Author) wrote:Actually a call to SetLastError(ERROR_NO_MORE_FILES) should work just fine! What is SetError()?
Oops, that's a typo (must've been due to the heat). I'm using SetLastError(ERROR_NO_MORE_FILES) of course. I'll correct it in the OP. But no, a call to SetLastError is not enough. TC behaves as described in the OP.

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50421
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Hmm, this makes no sense - I have just added
hdl:=INVALID_HANDLE_VALUE;
SetLastError(ERROR_NO_MORE_FILES);
just behind the call to FsFindFirst/FsFindFirstW, and I do not get any error - TC opens an empty directory.
Author of Total Commander
https://www.ghisler.com
User avatar
Dalai
Power Member
Power Member
Posts: 9960
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

OK, I've tracked it down a little further. It works on normal Windows (tested Win2k and XP), but it does NOT work on BartPE. On normal Windows, TC calls FsFindFirst twice (which is strange to me anyway, but whatever). On BartPE, TC calls FsFindFirst only once and doesn't open the plugin.

This is the code I used (just for testing):

Code: Select all

function FsFindFirstW(...)
begin
    Result:= INVALID_HANDLE_VALUE;
    MessageBox(0, 'one', '', MB_OK);
    Result:= StartupMgr.StartupCount;
    if Result > 0 then begin
        //...
    end else begin
        MessageBox(0, 'two', '', MB_OK);
        Result:= INVALID_HANDLE_VALUE;
        SetLastError(ERROR_NO_MORE_FILES);
    end;
end;
I get both message boxes only once on BartPE but twice on regular Windows systems.

Any hint on why TC behaves like this?

[EDIT]
Seems like there's more to it. It has something to do with the debugging my plugin does by using the OutputDebugString function. When using SimpleProgramDebugger to catch these messages, the issue is reproducible on normal Windows systems, too; but unfortunately not on all systems. I can't reproduce it using Sysinternals DebugView.
And now comes the really strange part: when using DebugView on BartPE, TC behaves just like on regular Windows systems! When I disable the use of OutputDebugString, TC behaves normally on BartPE, too.
[/EDIT]

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50421
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

On normal Windows, TC calls FsFindFirst twice
Strange, I cannot reproduce that. Does this happen only when the plugin returns an error?
Author of Total Commander
https://www.ghisler.com
User avatar
Dalai
Power Member
Power Member
Posts: 9960
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

ghisler(Author) wrote:
On normal Windows, TC calls FsFindFirst twice
Strange, I cannot reproduce that. Does this happen only when the plugin returns an error?
No, it is also called twice when the plugin returns success (1 or greater). Strangely this only applies to Startups plugin, I've not been able to reproduce it in Services2. Might have something to do with FsStatusInfo which is not exported by Startups (but Services2).

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50421
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Can you try to export FsStatusInfo and just add an empty function to verify that?
Author of Total Commander
https://www.ghisler.com
User avatar
Dalai
Power Member
Power Member
Posts: 9960
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Sorry, false alarm about the FsFindFirst/FsFindNext loop being called twice. I was using MessageBox(0, ...) to be able to "debug" on another machine and this caused TC to queue a refresh because of the "window switching" => loop called twice :oops:. I guess I should use GetActiveWindow more often...

However, the problem with the empty root directory remains. As soon as I enable OutputDebugString in FsFindFirst/FsFindNext functions TC doesn't open the plugin. Strangely, I can only reproduce this on WinXP, not on Win7.

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50421
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Maybe OutputDebugString resets the last error? Can you try to call SetLastError AFTER OutputDebugString?
Author of Total Commander
https://www.ghisler.com
User avatar
Dalai
Power Member
Power Member
Posts: 9960
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

ghisler(Author) wrote:Maybe OutputDebugString resets the last error?
Indeed it looks like it. MS seems to have changed the function's behavior on NT 6.x systems, not resetting the last error anymore.
Can you try to call SetLastError AFTER OutputDebugString?
Yes, this works. Thanks!

So, to conclude this topic and answer the thread's question, there're two options to show an empty directory:
  • Return INVALID_HANDLE_VALUE and set last error to ERROR_NO_MORE_FILES. Just make sure that no function resets the last error code as I had to struggle with ;).
  • Return one item with "." as name and FILE_ATTRIBUTE_DIRECTORY as attributes.
Thanks again for the help. :)

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Post Reply