Closed schinagl closed 9 months ago
Sorry for the delay. I've been looking into this, and the symlink one, and both still have the issue where if the user is hiding hidden and system files, links get included in the left pane.
Looking further into this, part of the problem is WFMoveCopyDriverThread
calls WFSymbolicLink
or WFJunction
, then calls WFSetAttr
to apply attributes from the destination to the link. This is after ChangeFileSystem
is called, so it doesn't have the opportunity to perform any hiding. The WFSetAttr
behavior seemed a little strange to me, since it's not what the API will do; but since it was code you added when adding symlink/junction support, I assume this is something you want to keep.
As I see it, that means either moving the WFSetAttr
into WFSymbolicLink
/WFJunction
, or moving the ChangeFileSystem
out of those and into WFMoveCopyDriverThread
after it calls WFSetAttr
. Given that there are other similar functions that already call ChangeFileSystem
, I'm assuming it's more consistent to move the call to WFSetAttr
.
From there, InsertDirectory
can check for ATTR_HS
. Unfortunately it also needs to NULL
the output pointer (otherwise it will return freed memory) and the callers don't seem very diligent about checking for failure. ScanDirLevel
happens to be implementing the same checks as InsertDirectory
, so if they're in perfect sync it won't touch the output pointer, but I think ReadDirLevel
still can. At least, I watched it crash accessing a freed pointer before setting it to NULL
.
One odd quirk I found while looking into this is the root directory on NTFS has the hidden/system attributes set. Previously this didn't matter since it wouldn't be returned from file enumeration so would never be hidden, but it's important to not hide it in InsertDirectory
either. If it is hidden, the tree will have zero items, causing the program to enter an infinite loop trying to populate the tree forever (where InitFileManager
calls TC_SETDRIVE
.)
The changes I've been working with are at https://github.com/malxau-msft/winfile/commit/485bd11cb96681290780f893694b5055afb7038d . I'm not attached to anything here and am not very confident in the error handling from InsertDirectory
, although it appears to work for all of the cases I've tried so far.
Sorry for the delay. I've been looking into this, and the symlink one, and both still have the issue where if the user is hiding hidden and system files, links get included in the left pane.
You are mixing up things I gess. See my comment with #406.
Looking further into this, part of the problem is
WFMoveCopyDriverThread
callsWFSymbolicLink
orWFJunction
, then callsWFSetAttr
to apply attributes from the destination to the link. This is afterChangeFileSystem
is called, so it doesn't have the opportunity to perform any hiding. TheWFSetAttr
behavior seemed a little strange to me, since it's not what the API will do; but since it was code you added when adding symlink/junction support, I assume this is something you want to keep.As I see it, that means either moving the
WFSetAttr
intoWFSymbolicLink
/WFJunction
, or moving theChangeFileSystem
out of those and intoWFMoveCopyDriverThread
after it callsWFSetAttr
. Given that there are other similar functions that already callChangeFileSystem
, I'm assuming it's more consistent to move the call toWFSetAttr
.
Completley disagree! We must not mix up changing creation of symbolic links and changing attributes. This is bad design and no other function in Winfile does this.
From there,
InsertDirectory
can check forATTR_HS
. Unfortunately it also needs toNULL
the output pointer (otherwise it will return freed memory) and the callers don't seem very diligent about checking for failure.ScanDirLevel
happens to be implementing the same checks asInsertDirectory
, so if they're in perfect sync it won't touch the output pointer, but I thinkReadDirLevel
still can. At least, I watched it crash accessing a freed pointer before setting it toNULL
.
I only agree with measures on setting ppNode to nullptr as shown in your snippet, but a check for `ATTR_HS seems not related to this PR. Why woould you want to change ReadDirLevel()? Which problem are you addressing?
One odd quirk I found while looking into this is the root directory on NTFS has the hidden/system attributes set. Previously this didn't matter since it wouldn't be returned from file enumeration so would never be hidden, but it's important to not hide it in
InsertDirectory
either. If it is hidden, the tree will have zero items, causing the program to enter an infinite loop trying to populate the tree forever (whereInitFileManager
callsTC_SETDRIVE
.)
This was never a problem before, why should it be a problem now? Please describe a use-case of failure.
Summary Can you please tell me the problem with my solution. (except ppNode = nullptr, which I am about to add. Thx! ) To me it seems you are describing other problems not related to this PR with ATTR_HS & co
So please describe a use-case where my solutions fails.
So please describe a use-case where my solutions fails.
Without this PR:
With this PR:
Normally, Winfile applies ATTR_HS
filtration in WFFindFirst
and WFFindNext
. This happens before the reparse tag is inspected, and applies to symbolic links in the same way as junctions. Calling InsertDirectory
directly bypasses this filtration, so this PR is populating the left pane with things that it normally wouldn't contain.
Completley disagree! We must not mix up changing creation of symbolic links and changing attributes. This is bad design and no other function in Winfile does this.
Feel free to propose an alternative solution. Looking today, another valid approach would be to ensure WFSetAttr
refreshes the left pane (it's already calling ChangeFileSystem
.)
Thx for the repro description. Will dig into during this week
Runing your experiment
With this PR: The newly created junction will be displayed in the left pane but not the right pane.
It is shown on the left and right pane, as can be see from my screenshot video https://github.com/microsoft/winfile/assets/7418603/cea43c98-98d2-46ce-b6ff-77f97ee7675f
BTW: On the right pane is it shown with or without this PR. so 1) of 'With out this PR' from above is not correct!
And after quit and restart it looks like
But this obvious because you made sure '"Show Hidden/System Files" is not set.' You can't see hidden dirs and thus you can't see Junctions inside. BTW there is no difference in your statement 2) with or without this very PR
So what???? This is correct behaviour. This is why I set up this PR:
**After creating a junction or symlink it is not shown in the left pane**
In general showing junctions shall be completley unrelated to ATTR_HS. There is no need for an alternative solution or your proposal.
PS: But if you think the problem is, that junctions are shown in a freshly hidden directory, then this is a different story and the behaviour is the same with or without this PR. This problem is, that a freshly hidden directory does not vanish on the spot when you set it to hidden. But even this was ever since with and without this PR
This is the behavior I am seeing:
https://github.com/microsoft/winfile/assets/104935627/e79d3378-5297-4c2a-ad17-d1658f928182
This problem is, that a freshly hidden directory does not vanish on the spot when you set it to hidden
Yes, I agree. The issue is that Winfile will set these junctions to hidden at the time they are created (at https://github.com/microsoft/winfile/blob/7ad683989e178a8fe6f5f9abfecb9821d0b56958/src/wfcopy.c#L2822), so it creates this condition in a way that is hidden from the user. That's why I'm suggesting WFSetAttr
would be one way to fix it - it fixes the general case, which also fixes the case of a freshly created junction to a hidden directory.
My usecase up till now was: create a junction inside a hidden directory. This works correctly https://github.com/microsoft/winfile/assets/7418603/916d8bd1-57a1-4d18-9b9f-06d1ce8bd08a ok. So far so good
Your use-case was Create a junction to a freshly hidden directory, After playing around a long time I can reproduce this.
But to be honest this is a super rare hair in the soup scenario
This is 0.01%% scenario. In all other scnanrios it helps to see the left pane updated.
Anyhow: I would never ever introduce your proposed hack, because it mixes creation of Junctions and setting of attributes and introduces and furthermore brings in changes in many places and causes risk. We must not do this
And: I am not going to search for a solution on this. Will abandon this PR and the others I have, because it takes me way more time to discuss things than doing it.
I am leaving this Winfile Repo, no need to merge
Refresh left pane aka tree pane when junctions are created, but don't show them, if one has deselected junction appearance under View/File Type