-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Use newly added LinkTarget property #15960
Conversation
case IO_REPARSE_TAG_MOUNT_POINT: | ||
REPARSE_DATA_BUFFER_MOUNTPOINT reparseMountPointDataBuffer = Marshal.PtrToStructure<REPARSE_DATA_BUFFER_MOUNTPOINT>(outBuffer); | ||
targetDir = Encoding.Unicode.GetString(reparseMountPointDataBuffer.PathBuffer, reparseMountPointDataBuffer.SubstituteNameOffset, reparseMountPointDataBuffer.SubstituteNameLength); | ||
break; | ||
|
||
case IO_REPARSE_TAG_APPEXECLINK: | ||
REPARSE_DATA_BUFFER_APPEXECLINK reparseAppExeDataBuffer = Marshal.PtrToStructure<REPARSE_DATA_BUFFER_APPEXECLINK>(outBuffer); | ||
// The target file is at index 2 | ||
if (reparseAppExeDataBuffer.StringCount >= 3) | ||
{ | ||
string temp = Encoding.Unicode.GetString(reparseAppExeDataBuffer.StringList); | ||
targetDir = temp.Split('\0')[2]; | ||
} | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are currently only supporting symlinks, not mount points or apexeclinks. I don't think this should be deleted yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can defer merging after .NET 6 RC1 is released (and consumed by pwsh), which will include that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it already in a PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (InternalSymbolicLinkLinkCodeMethods.IsReparsePointLikeSymlink(fileInfo)) | ||
{ | ||
return $"{PSStyle.Instance.FileInfo.SymbolicLink}{fileInfo.Name}{PSStyle.Instance.Reset} -> {InternalSymbolicLinkLinkCodeMethods.GetTarget(instance)}"; | ||
return $"{PSStyle.Instance.FileInfo.SymbolicLink}{fileInfo.Name}{PSStyle.Instance.Reset} -> {fileInfo.LinkTarget}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to get rid of IsReparsePointLikeSymlink() call and check fileInfo.LinkTarget is not null
but .Net API has slightly different behavior - can we enhance the .Net API?
PowerShell/src/System.Management.Automation/namespaces/FileSystemProvider.cs
Lines 8301 to 8308 in 176303d
// The name surrogate bit 0x20000000 is defined in https://docs.microsoft.com/windows/win32/fileio/reparse-point-tags | |
// Name surrogates (0x20000000) are reparse points that point to other named entities local to the filesystem | |
// (like symlinks and mount points). | |
// In the case of OneDrive, they are not name surrogates and would be safe to recurse into. | |
if ((data.dwReserved0 & 0x20000000) == 0 && (data.dwReserved0 != IO_REPARSE_TAG_APPEXECLINK)) | |
{ | |
return false; | |
} |
(Also you can see as IsReparsePointLikeSymlink() is used in other places. It seems it work the same for directory removal scenario but directory enumeration requires enhaсing of .Net API)
case IO_REPARSE_TAG_MOUNT_POINT: | ||
REPARSE_DATA_BUFFER_MOUNTPOINT reparseMountPointDataBuffer = Marshal.PtrToStructure<REPARSE_DATA_BUFFER_MOUNTPOINT>(outBuffer); | ||
targetDir = Encoding.Unicode.GetString(reparseMountPointDataBuffer.PathBuffer, reparseMountPointDataBuffer.SubstituteNameOffset, reparseMountPointDataBuffer.SubstituteNameLength); | ||
break; | ||
|
||
case IO_REPARSE_TAG_APPEXECLINK: | ||
REPARSE_DATA_BUFFER_APPEXECLINK reparseAppExeDataBuffer = Marshal.PtrToStructure<REPARSE_DATA_BUFFER_APPEXECLINK>(outBuffer); | ||
// The target file is at index 2 | ||
if (reparseAppExeDataBuffer.StringCount >= 3) | ||
{ | ||
string temp = Encoding.Unicode.GetString(reparseAppExeDataBuffer.StringList); | ||
targetDir = temp.Split('\0')[2]; | ||
} | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it already in a PR?
@jozkee We are not moving to .NET 6 preview.7 due to a couple bugs in that preview (dotnet/roslyn#55609, dotnet/runtime#57107), and that's why #15896 stays as a draft. For the new According to @carlossanlop, the functionality of |
PR Summary
Replace the current logic of retrieving a Link's Target with the newly added API
LinkTarget
.PR Context
From a libraries perspective, I wanted to get validation from product code that can implement this API so we can confirm that it works as expected in real world scenarios.
I'm sending this as draft as it builds on top of #15896.
cc @iSazonov @mklement0
PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
or[ WIP ]
to the beginning of the title (theWIP
bot will keep its status check atPending
while the prefix is present) and remove the prefix when the PR is ready.(which runs in a different PS Host).