diff --git a/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs b/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs index 64f5aff727fa29..85284922454c94 100644 --- a/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs +++ b/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs @@ -130,7 +130,11 @@ internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? pa case Error.ENOTDIR: return !string.IsNullOrEmpty(path) ? +#if NET11_0_OR_GREATER + new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path), path) : +#else new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path)) : +#endif new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName); case Error.EACCES: diff --git a/src/libraries/Common/src/System/IO/Win32Marshal.cs b/src/libraries/Common/src/System/IO/Win32Marshal.cs index bd9e6aab8c2318..28c2b38a925d19 100644 --- a/src/libraries/Common/src/System/IO/Win32Marshal.cs +++ b/src/libraries/Common/src/System/IO/Win32Marshal.cs @@ -34,8 +34,13 @@ internal static Exception GetExceptionForWin32Error(int errorCode, string? path return new FileNotFoundException( string.IsNullOrEmpty(path) ? SR.IO_FileNotFound : SR.Format(SR.IO_FileNotFound_FileName, path), path); case Interop.Errors.ERROR_PATH_NOT_FOUND: +#if NET11_0_OR_GREATER + return new DirectoryNotFoundException( + string.IsNullOrEmpty(path) ? SR.IO_PathNotFound_NoPathName : SR.Format(SR.IO_PathNotFound_Path, path), path); +#else return new DirectoryNotFoundException( string.IsNullOrEmpty(path) ? SR.IO_PathNotFound_NoPathName : SR.Format(SR.IO_PathNotFound_Path, path)); +#endif case Interop.Errors.ERROR_ACCESS_DENIED: return new UnauthorizedAccessException( string.IsNullOrEmpty(path) ? SR.UnauthorizedAccess_IODenied_NoPathName : SR.Format(SR.UnauthorizedAccess_IODenied_Path, path)); diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs index ede1b40f391a23..2281871520648e 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs @@ -63,7 +63,11 @@ public PhysicalFileProvider(string root, ExclusionFilters filters) Root = PathUtils.EnsureTrailingSlash(fullRoot); if (!Directory.Exists(Root)) { +#if NET11_0_OR_GREATER + throw new DirectoryNotFoundException(null, Root); +#else throw new DirectoryNotFoundException(Root); +#endif } _filters = filters; diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs index ebcb8ccd40238f..ce6f5d28326626 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs @@ -34,7 +34,11 @@ public string TrustedCertificatesDirectory { if (!Directory.Exists(value)) { +#if NET11_0_OR_GREATER + throw new DirectoryNotFoundException(SR.Format(SR.DirectoryNotFound, value), value); +#else throw new DirectoryNotFoundException(SR.Format(SR.DirectoryNotFound, value)); +#endif } SetStringOptionHelper(LdapOption.LDAP_OPT_X_TLS_CACERTDIR, value); diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs index 8ed22d331fcfd2..978eb75cc6048e 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs @@ -67,7 +67,7 @@ public static void CreateFromDirectory(string sourceDirectoryName, Stream destin if (!Directory.Exists(sourceDirectoryName)) { - throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName)); + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName); } // Rely on Path.GetFullPath for validation of paths @@ -135,7 +135,7 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream d if (!Directory.Exists(sourceDirectoryName)) { - return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName))); + return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName)); } // Rely on Path.GetFullPath for validation of paths @@ -190,7 +190,7 @@ public static void CreateFromDirectory(string sourceDirectoryName, string destin if (!Directory.Exists(sourceDirectoryName)) { - throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName)); + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName); } // Throws if the destination file exists @@ -253,7 +253,7 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string d if (!Directory.Exists(sourceDirectoryName)) { - return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName))); + return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName)); } return CreateFromDirectoryInternalAsync(sourceDirectoryName, destinationFileName, includeBaseDirectory, options, cancellationToken); @@ -309,7 +309,7 @@ public static void ExtractToDirectory(Stream source, string destinationDirectory if (!Directory.Exists(destinationDirectoryName)) { - throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName)); + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName); } // Rely on Path.GetFullPath for validation of paths @@ -377,7 +377,7 @@ public static Task ExtractToDirectoryAsync(Stream source, string destinationDire if (!Directory.Exists(destinationDirectoryName)) { - return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName))); + return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName)); } // Rely on Path.GetFullPath for validation of paths @@ -440,7 +440,7 @@ public static void ExtractToDirectory(string sourceFileName, string destinationD if (!Directory.Exists(destinationDirectoryName)) { - throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName)); + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName); } using FileStream archive = File.OpenRead(sourceFileName); @@ -509,7 +509,7 @@ public static Task ExtractToDirectoryAsync(string sourceFileName, string destina if (!Directory.Exists(destinationDirectoryName)) { - return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName))); + return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName)); } return ExtractToDirectoryInternalAsync(sourceFileName, destinationDirectoryName, options, cancellationToken); diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs b/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs index cece82a21343a3..8d62770750f784 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs @@ -46,7 +46,7 @@ internal FileSystemSecurity(bool isContainer, SafeFileHandle? handle, AccessCont { // DirectorySecurity if ((name != null) && (name.Length != 0)) - exception = new DirectoryNotFoundException(name); + exception = new DirectoryNotFoundException(null, name); else exception = new DirectoryNotFoundException(); } diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs index c787c6939b72f5..04485d30b96dab 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs +++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs @@ -360,7 +360,7 @@ public void MoveDirectory(string sourceDirectoryName, string destinationDirector } catch (DirectoryNotFoundException) { - throw new DirectoryNotFoundException(SR.Format(SR.PathNotFound_Path, sourceDirectoryName)); + throw new DirectoryNotFoundException(SR.Format(SR.PathNotFound_Path, sourceDirectoryName), sourceDirectoryName); } catch (PathTooLongException) { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs index da01764dfe8fdd..df737a7564ddd0 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs @@ -277,7 +277,7 @@ internal SocketError DoOperationSendPackets(Socket socket, SafeSocketHandle _1 / string? dirname = Path.GetDirectoryName(fnfe.FileName); if (!string.IsNullOrEmpty(dirname) && !Directory.Exists(dirname)) { - throw new DirectoryNotFoundException(fnfe.Message); + throw new DirectoryNotFoundException(fnfe.Message, dirname); } } diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 26afeaea117eca..571a73528554a5 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -296,7 +296,7 @@ Decimal constructor requires an array or span of four valid decimal bytes. - Attempted to access a path that is not on the disk. + Unable to find the specified directory. Attempted to divide by zero. @@ -2840,6 +2840,12 @@ Could not load the file '{0}'. + + Directory path: '{0}' + + + Could not find directory '{0}'. + File name: '{0}' diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs b/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs index ca651ad4c27fc4..5cef1424b6ef9b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs @@ -35,11 +35,59 @@ public DirectoryNotFoundException(string? message, Exception? innerException) HResult = HResults.COR_E_DIRECTORYNOTFOUND; } + public DirectoryNotFoundException(string? message, string? directoryPath) + : this(message, directoryPath, innerException: null) + { + } + + public DirectoryNotFoundException(string? message, string? directoryPath, Exception? innerException) + : base(message ?? (directoryPath is not null + ? SR.Format(SR.IO_DirectoryNotFound_Path, directoryPath) + : SR.Arg_DirectoryNotFoundException), innerException) + { + HResult = HResults.COR_E_DIRECTORYNOTFOUND; + DirectoryPath = directoryPath; + } + + public string? DirectoryPath { get; } + + public override string ToString() + { + string s = GetType().ToString() + ": " + Message; + + if (!string.IsNullOrEmpty(DirectoryPath)) + s += Environment.NewLineConst + SR.Format(SR.IO_DirectoryName_Name, DirectoryPath); + + if (InnerException is not null) + s += Environment.NewLineConst + InnerExceptionPrefix + InnerException.ToString(); + + if (StackTrace is not null) + s += Environment.NewLineConst + StackTrace; + + return s; + } + [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] protected DirectoryNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { + foreach (SerializationEntry entry in info) + { + if (entry.Name == "DirectoryNotFound_DirectoryPath") + { + DirectoryPath = (string?)entry.Value; + break; + } + } + } + + [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("DirectoryNotFound_DirectoryPath", DirectoryPath, typeof(string)); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs index 7c2083cac3d7b3..ed5efa8f8116fb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs @@ -181,8 +181,9 @@ public void MoveTo(string destFileName, bool overwrite) // as it does on Windows.These checks can be removed if a solution to // https://github.com/dotnet/runtime/issues/14885 is found that doesn't require // validity checks before making an API call. - if (!System.IO.Directory.Exists(Path.GetDirectoryName(FullName))) - throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, FullName)); + string? directoryPath = Path.GetDirectoryName(FullName); + if (!System.IO.Directory.Exists(directoryPath)) + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, directoryPath), directoryPath); if (!Exists) throw new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, FullName), FullName); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs index 059118499d23f3..30a96c843d95c5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs @@ -418,7 +418,7 @@ private static void MoveDirectory(string sourceFullPath, string destFullPath, bo // Throw if the source doesn't exist. if (Interop.Sys.LStat(srcNoDirectorySeparator, out Interop.Sys.FileStatus sourceFileStatus) < 0) { - throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath)); + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath), sourceFullPath); } // Source and destination must not be the same file unless it is a case-sensitive rename. else if (sourceFileStatus.Dev == destFileStatus.Dev && @@ -454,7 +454,7 @@ private static void MoveDirectory(string sourceFullPath, string destFullPath, bo case Interop.Error.EACCES: // match Win32 exception throw new IOException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, sourceFullPath), errorInfo.RawErrno); case Interop.Error.ENOENT: - throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath)); + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath), sourceFullPath); case Interop.Error.ENOTDIR: // sourceFullPath exists and it's not a directory throw new IOException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath)); default: diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 6bb8a8766c5e88..b8c7dae142fe43 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -10300,6 +10300,13 @@ public DirectoryNotFoundException() { } protected DirectoryNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public DirectoryNotFoundException(string? message) { } public DirectoryNotFoundException(string? message, System.Exception? innerException) { } + public DirectoryNotFoundException(string? message, string? directoryPath) { } + public DirectoryNotFoundException(string? message, string? directoryPath, System.Exception? innerException) { } + public string? DirectoryPath { get { throw null; } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId="SYSLIB0051", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } + public override string ToString() { throw null; } } public partial class EndOfStreamException : System.IO.IOException { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs index 400e992503b32c..ad9992153b8411 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs @@ -3,6 +3,8 @@ using System; using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; using Xunit; using System.Tests; @@ -15,6 +17,7 @@ public static void Ctor_Empty() { var exception = new DirectoryNotFoundException(); ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, validateMessage: false); + Assert.Null(exception.DirectoryPath); } [Fact] @@ -23,6 +26,7 @@ public static void Ctor_String() string message = "That page was missing from the directory."; var exception = new DirectoryNotFoundException(message); ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message); + Assert.Null(exception.DirectoryPath); } [Fact] @@ -32,6 +36,114 @@ public static void Ctor_String_Exception() var innerException = new Exception("Inner exception"); var exception = new DirectoryNotFoundException(message, innerException); ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message); + Assert.Null(exception.DirectoryPath); + } + + [Theory] + [InlineData("That directory is gone.", @"C:\missing\dir")] + [InlineData("", @"/data/reports")] + [InlineData("Custom message", "")] + public static void Ctor_String_String(string message, string directoryPath) + { + var exception = new DirectoryNotFoundException(message, directoryPath); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message); + Assert.Equal(directoryPath, exception.DirectoryPath); + } + + [Theory] + [InlineData("That directory is gone.", @"C:\missing\dir")] + [InlineData("", @"/data/reports")] + [InlineData("Custom message", "")] + public static void Ctor_String_String_Exception(string message, string directoryPath) + { + var innerException = new Exception("Inner exception"); + var exception = new DirectoryNotFoundException(message, directoryPath, innerException); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message); + Assert.Equal(directoryPath, exception.DirectoryPath); + } + + [Fact] + public static void Ctor_NullDirectoryPath() + { + string message = "msg"; + var exception = new DirectoryNotFoundException(message, (string?)null); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message); + Assert.Null(exception.DirectoryPath); + + var innerException = new Exception(); + var exception2 = new DirectoryNotFoundException(message, (string?)null, innerException); + ExceptionHelpers.ValidateExceptionProperties(exception2, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message); + Assert.Null(exception2.DirectoryPath); + } + + [Fact] + public static void Ctor_NullMessageAndNullDirectoryPath() + { + var exception = new DirectoryNotFoundException(null, (string?)null); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, validateMessage: false); + Assert.Null(exception.DirectoryPath); + Assert.NotNull(exception.Message); + Assert.NotEmpty(exception.Message); + } + + [Fact] + public static void Message_AutoConstructed_WhenNullMessage_WithDirectoryPath() + { + string directoryPath = @"/data/reports"; + var exception = new DirectoryNotFoundException(null, directoryPath); + Assert.NotNull(exception.Message); + Assert.Contains(directoryPath, exception.Message); + } + + [Fact] + public static void ToString_WithDirectoryPath() + { + string message = "That directory is gone."; + string directoryPath = @"C:\missing\dir"; + var innerException = new Exception("Inner exception"); + var exception = new DirectoryNotFoundException(message, directoryPath, innerException); + + string toString = exception.ToString(); + Assert.Contains(": " + message, toString); + Assert.Contains(": '" + directoryPath + "'", toString); + Assert.Contains("---> " + innerException.ToString(), toString); + + try { throw exception; } + catch + { + Assert.False(string.IsNullOrEmpty(exception.StackTrace)); + Assert.Contains(exception.StackTrace, exception.ToString()); + } + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public static void ToString_WithoutDirectoryPath_OmitsDirectoryLine(string? directoryPath) + { + var exception = new DirectoryNotFoundException("message", directoryPath); + string toString = exception.ToString(); + Assert.DoesNotContain("Directory path:", toString); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] + public static void GetObjectData_Roundtrip() + { + string message = "dir not found"; + string directoryPath = @"C:\missing\dir"; + var original = new DirectoryNotFoundException(message, directoryPath); + +#pragma warning disable SYSLIB0011 + var formatter = new BinaryFormatter(); + using var stream = new MemoryStream(); + formatter.Serialize(stream, original); + stream.Position = 0; + var deserialized = (DirectoryNotFoundException)formatter.Deserialize(stream); +#pragma warning restore SYSLIB0011 + + Assert.Equal(message, deserialized.Message); + Assert.Equal(directoryPath, deserialized.DirectoryPath); + Assert.Equal(original.HResult, deserialized.HResult); } } } diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs index c7aeffb6c965d5..5ebdbc325cdd73 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs @@ -150,7 +150,7 @@ private static CommonSecurityDescriptor CreateInternal(ResourceType resourceType exception = isContainer switch { false => new FileNotFoundException(name), - true => new DirectoryNotFoundException(name) + true => new DirectoryNotFoundException(null, name) }; } else if (error == Interop.Errors.ERROR_NO_SECURITY_ON_OBJECT)