Skip to content

Commit

Permalink
When junctions are hidden, also hide from left pane (#297)
Browse files Browse the repository at this point in the history
* When junctions are hidden, also hide from left pane

* FindFirst should only filter ATTR_USED, as FindNext does

* Address PR feedback
  • Loading branch information
malxau authored Feb 23, 2022
1 parent b2bed22 commit 48164be
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 33 deletions.
26 changes: 21 additions & 5 deletions src/lfn.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

BOOL IsFATName(LPTSTR pName);


/* WFFindFirst -
*
* returns:
Expand Down Expand Up @@ -86,8 +85,16 @@ WFFindFirst(

if (lpFind->hFindFile != INVALID_HANDLE_VALUE) {
lpFind->dwAttrFilter = dwAttrFilter;
if ((~dwAttrFilter & lpFind->fd.dwFileAttributes) == 0L ||
WFFindNext(lpFind)) {
if ((~dwAttrFilter & lpFind->fd.dwFileAttributes) == 0L) {
if (lpFind->fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
if (lpFind->fd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) {
lpFind->fd.dwFileAttributes |= ATTR_JUNCTION;
} else if (lpFind->fd.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
lpFind->fd.dwFileAttributes |= ATTR_SYMBOLIC;
}
}
return(TRUE);
} else if (WFFindNext(lpFind)) {
return(TRUE);
} else {
WFFindClose(lpFind);
Expand All @@ -103,8 +110,8 @@ WFFindFirst(
/* WFFindNext -
*
* Performs a single file FindNext operation. Only returns TRUE if a
* file matching the dwAttrFilter is found. On failure WFFindClose is
* called.
* file matching the dwAttrFilter is found. On failure the caller is
* expected to call WFFindClose.
*/
BOOL
WFFindNext(LPLFNDTA lpFind)
Expand Down Expand Up @@ -139,7 +146,16 @@ WFFindNext(LPLFNDTA lpFind)
lstrcpy(lpFind->fd.cFileName, lpFind->fd.cAlternateFileName);
}

if (lpFind->fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
if (lpFind->fd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) {
lpFind->fd.dwFileAttributes |= ATTR_JUNCTION;
} else if (lpFind->fd.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
lpFind->fd.dwFileAttributes |= ATTR_SYMBOLIC;
}
}

Wow64RevertWow64FsRedirection(oldValue);

lpFind->err = 0;
return TRUE;
}
Expand Down
81 changes: 72 additions & 9 deletions src/treectl.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ ScanDirLevel(PDNODE pParentNode, LPTSTR szPath, DWORD view)
{
BOOL bFound;
LFNDTA lfndta;
BOOL bExclude;

/* Add '*.*' to the current path. */
lstrcpy(szMessage, szPath);
Expand All @@ -178,9 +179,18 @@ ScanDirLevel(PDNODE pParentNode, LPTSTR szPath, DWORD view)

while (bFound)
{
/* Is this a junction and are those displayed? */
bExclude = FALSE;
if ((view & ATTR_JUNCTION) == 0 &&
(lfndta.fd.dwFileAttributes & ATTR_JUNCTION)) {

bExclude = TRUE;
}

/* Is this not a '.' or '..' directory? */
if (!ISDOTDIR(lfndta.fd.cFileName) &&
(lfndta.fd.dwFileAttributes & ATTR_DIR)) {
(lfndta.fd.dwFileAttributes & ATTR_DIR) &&
!bExclude) {

pParentNode->wFlags |= TF_HASCHILDREN;
bFound = FALSE;
Expand Down Expand Up @@ -482,6 +492,39 @@ wfYield()
}
}

/////////////////////////////////////////////////////////////////////
//
// Name: WFFindNextNonJunction
//
// Synopsis: Returns the next non-junction entry, which may be the
// current entry. Continually calls WFFindNext so long as
// the current entry is a junction.
//
// lpFind Pointer to the find context, which may (or may
// not) be advanced to a later entry.
//
// Return: TRUE = non-junction successfully found
// FALSE = no non-junction remaining.
BOOL
WFFindNextNonJunction(LPLFNDTA lpFind)
{
BOOL bFound;

bFound = TRUE;

while (bFound)
{
// If it's not a junction, return it.
if (!(lpFind->fd.dwFileAttributes & ATTR_JUNCTION))
{
return bFound;
}

bFound = WFFindNext(lpFind);
}

return bFound;
}


/////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -663,6 +706,14 @@ ReadDirLevel(
lstrcpy(szMessage, szPath);

bFound = WFFindFirst(&lfndta, szMessage, dwAttribs);

//
// if junctions are not displayed, continue to the next non-junction
//
if (bFound && !(dwAttribs & ATTR_JUNCTION))
{
bFound = WFFindNextNonJunction(&lfndta);
}
}

// for net drive case where we can't actually see what is in these
Expand Down Expand Up @@ -787,7 +838,7 @@ ReadDirLevel(
goto DONE;
}
} else if (dwView & VIEW_PLUSES) {
ScanDirLevel(pNode, szPath, dwAttribs & ATTR_HS);
ScanDirLevel(pNode, szPath, dwAttribs & (ATTR_HS | ATTR_JUNCTION));
}
}

Expand Down Expand Up @@ -837,6 +888,14 @@ ReadDirLevel(
else
{
bFound = WFFindNext(&lfndta); // get it from dos

//
// if junctions are not displayed, continue to the next non-junction
//
if (bFound && !(dwAttribs & ATTR_JUNCTION))
{
bFound = WFFindNextNonJunction(&lfndta);
}
}
}

Expand Down Expand Up @@ -932,7 +991,7 @@ StealTreeData(
// we need to match on these attributes as well as the name
//
dwView = GetWindowLongPtr(GetParent(hwndTC), GWL_VIEW) & VIEW_PLUSES;
dwAttribs = GetWindowLongPtr(GetParent(hwndTC), GWL_ATTRIBS) & ATTR_HS;
dwAttribs = GetWindowLongPtr(GetParent(hwndTC), GWL_ATTRIBS) & (ATTR_HS | ATTR_JUNCTION);

//
// get the dir of this new window for compare below
Expand All @@ -948,7 +1007,7 @@ StealTreeData(
(hwndT != hwndTC) &&
!GetWindowLongPtr(hwndT, GWL_READLEVEL) &&
(dwView == (DWORD)(GetWindowLongPtr(hwndSrc, GWL_VIEW) & VIEW_PLUSES)) &&
(dwAttribs == (DWORD)(GetWindowLongPtr(hwndSrc, GWL_ATTRIBS) & ATTR_HS))) {
(dwAttribs == (DWORD)(GetWindowLongPtr(hwndSrc, GWL_ATTRIBS) & (ATTR_HS | ATTR_JUNCTION)))) {

SendMessage(hwndSrc, FS_GETDIRECTORY, COUNTOF(szSrc), (LPARAM)szSrc);
StripBackslash(szSrc);
Expand Down Expand Up @@ -1084,7 +1143,8 @@ FillTreeListbox(HWND hwndTC,

if (pNode) {

dwAttribs = ATTR_DIR | (GetWindowLongPtr(GetParent(hwndTC), GWL_ATTRIBS) & ATTR_HS);
dwAttribs = GetWindowLongPtr(GetParent(hwndTC), GWL_ATTRIBS);
dwAttribs = ATTR_DIR | (dwAttribs & (ATTR_HS | ATTR_JUNCTION));
cNodes = 0;
bCancelTree = FALSE;

Expand Down Expand Up @@ -1155,7 +1215,8 @@ FillOutTreeList(HWND hwndTC,

SendMessage(hwndLB, WM_SETREDRAW, FALSE, 0L);

dwAttribs = ATTR_DIR | (GetWindowLongPtr(GetParent(hwndTC), GWL_ATTRIBS) & ATTR_HS);
dwAttribs = GetWindowLongPtr(GetParent(hwndTC), GWL_ATTRIBS);
dwAttribs = ATTR_DIR | (dwAttribs & (ATTR_HS | ATTR_JUNCTION));

// get path to node that already exists in tree; will start reading from there
GetTreePath(pNode, szExists);
Expand Down Expand Up @@ -1861,6 +1922,7 @@ ExpandLevel(HWND hWnd, WPARAM wParam, INT nIndex, LPTSTR szPath)
INT iExpandInView;
INT iCurrentIndex;
RECT rc;
DWORD dwAttribs;

//
// Don't do anything while the tree is being built.
Expand Down Expand Up @@ -1916,8 +1978,9 @@ ExpandLevel(HWND hWnd, WPARAM wParam, INT nIndex, LPTSTR szPath)

if (IsTheDiskReallyThere(hWnd, szPath, FUNC_EXPAND, FALSE))
{
ReadDirLevel(hWnd, pNode, szPath, pNode->nLevels + 1, nIndex,
(DWORD)(ATTR_DIR | (GetWindowLongPtr(GetParent(hWnd), GWL_ATTRIBS) & ATTR_HS)),
dwAttribs = GetWindowLongPtr(GetParent(hWnd), GWL_ATTRIBS);
dwAttribs = ATTR_DIR | (dwAttribs & (ATTR_HS | ATTR_JUNCTION));
ReadDirLevel(hWnd, pNode, szPath, pNode->nLevels + 1, nIndex, dwAttribs,
(BOOL)wParam, NULL, IS_PARTIALSORT(DRIVEID(szPath)));
}

Expand Down Expand Up @@ -2355,7 +2418,7 @@ TreeControlWndProc(
lstrcpy(szPath, (LPTSTR)lParam);
ScanDirLevel( (PDNODE)pNodeT,
szPath,
(GetWindowLongPtr(hwndParent, GWL_ATTRIBS) & ATTR_HS));
(GetWindowLongPtr(hwndParent, GWL_ATTRIBS) & (ATTR_HS | ATTR_JUNCTION)));

//
// Invalidate the window so the plus gets drawn if needed
Expand Down
20 changes: 1 addition & 19 deletions src/wfdirrd.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,25 +906,7 @@ CreateDTABlockWorker(
//
// be safe, zero unused DOS dta bits
//
lfndta.fd.dwFileAttributes &= ATTR_USED;

//
// if reparse point, figure out whether it is a junction point
if (lfndta.fd.dwFileAttributes & ATTR_REPARSE_POINT)
{
DWORD tag = DecodeReparsePoint(szPath, pName, szLinkDest, COUNTOF(szLinkDest));

if (tag == IO_REPARSE_TAG_MOUNT_POINT)
lfndta.fd.dwFileAttributes |= ATTR_JUNCTION;

else if (tag == IO_REPARSE_TAG_SYMLINK)
lfndta.fd.dwFileAttributes |= ATTR_SYMBOLIC;

else
{
// DebugBreak();
}
}
lfndta.fd.dwFileAttributes &= (ATTR_USED | ATTR_JUNCTION | ATTR_SYMBOLIC);

//
// filter unwanted stuff here based on current view settings
Expand Down

0 comments on commit 48164be

Please sign in to comment.