Enable recursion into OneDrive (#9509)
This commit is contained in:
parent
346ab8c9d4
commit
1d28144e99
1 changed files with 57 additions and 1 deletions
|
@ -1848,9 +1848,11 @@ namespace Microsoft.PowerShell.Commands
|
||||||
// a) the user has asked to with the -FollowSymLinks switch parameter and
|
// a) the user has asked to with the -FollowSymLinks switch parameter and
|
||||||
// b) the directory pointed to by the symlink has not already been visited,
|
// b) the directory pointed to by the symlink has not already been visited,
|
||||||
// preventing symlink loops.
|
// preventing symlink loops.
|
||||||
|
// c) it is not a name surrogate making it not a symlink
|
||||||
if (tracker == null)
|
if (tracker == null)
|
||||||
{
|
{
|
||||||
if (InternalSymbolicLinkLinkCodeMethods.IsReparsePoint(recursiveDirectory))
|
if (InternalSymbolicLinkLinkCodeMethods.IsReparsePoint(recursiveDirectory) &&
|
||||||
|
InternalSymbolicLinkLinkCodeMethods.IsNameSurrogateReparsePoint(recursiveDirectory.FullName))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -7706,6 +7708,8 @@ namespace Microsoft.PowerShell.Commands
|
||||||
|
|
||||||
private const string NonInterpretedPathPrefix = @"\??\";
|
private const string NonInterpretedPathPrefix = @"\??\";
|
||||||
|
|
||||||
|
private const int MAX_PATH = 260;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
// dwDesiredAccess of CreateFile
|
// dwDesiredAccess of CreateFile
|
||||||
internal enum FileDesiredAccess : uint
|
internal enum FileDesiredAccess : uint
|
||||||
|
@ -7846,6 +7850,39 @@ namespace Microsoft.PowerShell.Commands
|
||||||
FileAttributes dwFlagsAndAttributes,
|
FileAttributes dwFlagsAndAttributes,
|
||||||
IntPtr hTemplateFile);
|
IntPtr hTemplateFile);
|
||||||
|
|
||||||
|
[DllImport(PinvokeDllNames.FindFirstFileDllName, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
|
private static extern SafeFileHandle FindFirstFileEx(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, ref WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, int dwAdditionalFlags);
|
||||||
|
|
||||||
|
internal enum FINDEX_INFO_LEVELS : uint
|
||||||
|
{
|
||||||
|
FindExInfoStandard = 0x0u,
|
||||||
|
FindExInfoBasic = 0x1u,
|
||||||
|
FindExInfoMaxInfoLevel = 0x2u,
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum FINDEX_SEARCH_OPS : uint
|
||||||
|
{
|
||||||
|
FindExSearchNameMatch = 0x0u,
|
||||||
|
FindExSearchLimitToDirectories = 0x1u,
|
||||||
|
FindExSearchLimitToDevices = 0x2u,
|
||||||
|
FindExSearchMaxSearchOp = 0x3u,
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||||
|
internal unsafe struct WIN32_FIND_DATA
|
||||||
|
{
|
||||||
|
internal uint dwFileAttributes;
|
||||||
|
internal System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
|
||||||
|
internal System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
|
||||||
|
internal System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
|
||||||
|
internal uint nFileSizeHigh;
|
||||||
|
internal uint nFileSizeLow;
|
||||||
|
internal uint dwReserved0;
|
||||||
|
internal uint dwReserved1;
|
||||||
|
internal fixed char cFileName[MAX_PATH];
|
||||||
|
internal fixed char cAlternateFileName[14];
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target of the specified reparse point.
|
/// Gets the target of the specified reparse point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -7993,6 +8030,25 @@ namespace Microsoft.PowerShell.Commands
|
||||||
: Platform.NonWindowsIsSymLink(fileInfo);
|
: Platform.NonWindowsIsSymLink(fileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool IsNameSurrogateReparsePoint(string filePath)
|
||||||
|
{
|
||||||
|
#if !UNIX
|
||||||
|
var data = new WIN32_FIND_DATA();
|
||||||
|
using (SafeFileHandle handle = FindFirstFileEx(filePath, FINDEX_INFO_LEVELS.FindExInfoBasic, ref data, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, 0))
|
||||||
|
{
|
||||||
|
// Name surrogates are reparse points that point to other named entities local to the filesystem (like symlinks)
|
||||||
|
// In the case of OneDrive, they are not surrogates and would be safe to recurse into.
|
||||||
|
// This code is equivalent to the IsReparseTagNameSurrogate macro: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/nf-ntifs-isreparsetagnamesurrogate
|
||||||
|
if (!handle.IsInvalid && (data.dwReserved0 & 0x20000000) == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// true means the reparse point is a symlink
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
internal static bool WinIsHardLink(FileSystemInfo fileInfo)
|
internal static bool WinIsHardLink(FileSystemInfo fileInfo)
|
||||||
{
|
{
|
||||||
bool isHardLink = false;
|
bool isHardLink = false;
|
||||||
|
|
Loading…
Reference in a new issue