From d032cb2c879ff906494071c63a5e73572127825c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20BARIZIEN?= Date: Mon, 4 Feb 2019 21:11:46 +0100 Subject: [PATCH] Expose file attributes of OneDrive placeholders (#8745) --- .../namespaces/FileSystemProvider.cs | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index dcb42ecff..c9f8d8057 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -341,7 +341,6 @@ namespace Microsoft.PowerShell.Commands #endregion #region CmdletProvider members - /// /// Starts the File System provider. This method sets the Home for the /// provider to providerInfo.Home if specified, and %USERPROFILE% @@ -373,6 +372,22 @@ namespace Microsoft.PowerShell.Commands } } + // OneDrive placeholder support (issue #8315) + // make it so OneDrive placeholders are perceived as such with *all* their attributes accessible +#if !UNIX + // The placeholder mode management APIs Rtl(Set|Query)(Process|Thread)PlaceholderCompatibilityMode + // are only supported starting with Windows 10 version 1803 (build 17134) + Version minBuildForPlaceHolderAPIs = new Version(10, 0, 17134, 0); + if (Environment.OSVersion.Version >= minBuildForPlaceHolderAPIs) + { + // let's be safe, don't change the PlaceHolderCompatibilityMode if the current one is not what we expect + if (NativeMethods.PHCM_DISGUISE_PLACEHOLDER == NativeMethods.RtlQueryProcessPlaceholderCompatibilityMode()) + { + NativeMethods.RtlSetProcessPlaceholderCompatibilityMode(NativeMethods.PHCM_EXPOSE_PLACEHOLDERS); + } + } +#endif + return providerInfo; } @@ -7061,6 +7076,31 @@ namespace Microsoft.PowerShell.Commands Hidden = 0x0002, Directory = 0x0010 } + + // OneDrive placeholder support +#if !UNIX + /// + /// Returns the placeholder compatibility mode for the current process. + /// + /// The process's placeholder compatibily mode (PHCM_xxx), or a negative value on error (PCHM_ERROR_xxx). + [DllImport("ntdll.dll")] + internal static extern sbyte RtlQueryProcessPlaceholderCompatibilityMode(); + + /// + /// Sets the placeholder compatibility mode for the current process. + /// + /// The placeholder compatibility mode to set. + /// The process's previous placeholder compatibily mode (PHCM_xxx), or a negative value on error (PCHM_ERROR_xxx). + [DllImport("ntdll.dll")] + internal static extern sbyte RtlSetProcessPlaceholderCompatibilityMode(sbyte pcm); + + internal const sbyte PHCM_APPLICATION_DEFAULT = 0; + internal const sbyte PHCM_DISGUISE_PLACEHOLDER = 1; + internal const sbyte PHCM_EXPOSE_PLACEHOLDERS = 2; + internal const sbyte PHCM_MAX = 2; + internal const sbyte PHCM_ERROR_INVALID_PARAMETER = -1; + internal const sbyte PHCM_ERROR_NO_TEB = -2; +#endif } /// @@ -7466,8 +7506,10 @@ namespace Microsoft.PowerShell.Commands /// Gets the status of the delimiter parameter. Returns true /// if the delimiter was explicitly specified by the user, false otherwise. /// - public bool DelimiterSpecified { get; private set; -// get + public bool DelimiterSpecified + { + get; private set; + // get } } @@ -7970,10 +8012,10 @@ namespace Microsoft.PowerShell.Commands { BY_HANDLE_FILE_INFORMATION infoOne; BY_HANDLE_FILE_INFORMATION infoTwo; - if ( GetFileInformationByHandle(sfOne.DangerousGetHandle(), out infoOne) + if (GetFileInformationByHandle(sfOne.DangerousGetHandle(), out infoOne) && GetFileInformationByHandle(sfTwo.DangerousGetHandle(), out infoTwo)) { - return infoOne.VolumeSerialNumber == infoTwo.VolumeSerialNumber + return infoOne.VolumeSerialNumber == infoTwo.VolumeSerialNumber && infoOne.FileIndexHigh == infoTwo.FileIndexHigh && infoOne.FileIndexLow == infoTwo.FileIndexLow; }