Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit b96c7b9

Browse files
JeremyKuhnejkotas
authored andcommitted
Update Corelib to use SetThreadErrorMode (#11625)
See #19738. Note that the enumerable is only used on Unix- but updated it anyway. Conditioned the set/unset for ! Unix. SetErrorMode in the PAL is a no-op, want to use the shared interop.
1 parent 2fbc698 commit b96c7b9

File tree

6 files changed

+43
-37
lines changed

6 files changed

+43
-37
lines changed

src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetErrorMode.cs renamed to src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetThreadErrorMode.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ internal partial class Interop
88
{
99
internal partial class Kernel32
1010
{
11-
[DllImport(Libraries.Kernel32, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
12-
internal static extern uint SetErrorMode(uint newMode);
11+
[DllImport(Libraries.Kernel32, SetLastError = true, ExactSpelling = true)]
12+
internal static extern bool SetThreadErrorMode(uint dwNewMode, out uint lpOldMode);
1313

1414
internal const uint SEM_FAILCRITICALERRORS = 1;
1515
}

src/mscorlib/shared/System.Private.CoreLib.Shared.projitems

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@
491491
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SECURITY_ATTRIBUTES.cs"/>
492492
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SecurityOptions.cs"/>
493493
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetEndOfFile.cs"/>
494-
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetErrorMode.cs"/>
494+
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetThreadErrorMode.cs"/>
495495
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetFilePointerEx.cs"/>
496496
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WideCharToMultiByte.cs"/>
497497
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_IntPtr.cs"/>

src/mscorlib/shared/System/IO/FileStream.Win32.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
using System.Buffers;
6-
using System.Diagnostics;
7-
using System.Runtime.InteropServices;
8-
using System.Threading;
9-
using System.Threading.Tasks;
105
using Microsoft.Win32.SafeHandles;
11-
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
127

138
namespace System.IO
149
{
@@ -38,7 +33,8 @@ private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions op
3833
flagsAndAttributes |= (Interop.Kernel32.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.Kernel32.SecurityOptions.SECURITY_ANONYMOUS);
3934

4035
// Don't pop up a dialog for reading from an empty floppy drive
41-
uint oldMode = Interop.Kernel32.SetErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS);
36+
uint oldMode;
37+
bool success = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
4238
try
4339
{
4440
SafeFileHandle fileHandle = Interop.Kernel32.CreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
@@ -70,7 +66,8 @@ private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions op
7066
}
7167
finally
7268
{
73-
Interop.Kernel32.SetErrorMode(oldMode);
69+
if (success)
70+
Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
7471
}
7572
}
7673
}

src/mscorlib/src/Microsoft/Win32/Win32Native.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,6 @@ internal unsafe struct MEMORY_BASIC_INFORMATION
473473
internal const String SECUR32 = "secur32.dll";
474474
internal const String MSCORWKS = "coreclr.dll";
475475

476-
// From WinBase.h
477-
internal const int SEM_FAILCRITICALERRORS = 1;
478-
479476
[DllImport(KERNEL32, CharSet = CharSet.Auto, BestFitMapping = true)]
480477
internal static extern int FormatMessage(int dwFlags, IntPtr lpSource,
481478
int dwMessageId, int dwLanguageId, [Out]StringBuilder lpBuffer,
@@ -776,18 +773,6 @@ internal static extern bool FindNextFile(
776773
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
777774
internal static extern bool SetCurrentDirectory(String path);
778775

779-
[DllImport(KERNEL32, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
780-
private static extern int SetErrorMode_VistaAndOlder(int newMode);
781-
782-
// RTM versions of Win7 and Windows Server 2008 R2
783-
private static readonly Version ThreadErrorModeMinOsVersion = new Version(6, 1, 7600);
784-
785-
// this method uses the thread-safe version of SetErrorMode on Windows 7 / Windows Server 2008 R2 operating systems.
786-
internal static int SetErrorMode(int newMode)
787-
{
788-
return SetErrorMode_VistaAndOlder(newMode);
789-
}
790-
791776
internal const int LCID_SUPPORTED = 0x00000002; // supported locale ids
792777

793778
[DllImport(KERNEL32)]

src/mscorlib/src/System/IO/File.cs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,16 @@ internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_AT
150150
// Remove trialing slash since this can cause grief to FindFirstFile. You will get an invalid argument error
151151
String tempPath = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
152152

153+
#if !PLATFORM_UNIX
153154
// For floppy drives, normally the OS will pop up a dialog saying
154155
// there is no disk in drive A:, please insert one. We don't want that.
155-
// SetErrorMode will let us disable this, but we should set the error
156+
// SetThreadErrorMode will let us disable this, but we should set the error
156157
// mode back, since this may have wide-ranging effects.
157-
int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
158+
uint oldMode;
159+
bool errorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
158160
try
159161
{
162+
#endif
160163
bool error = false;
161164
SafeFindHandle handle = Win32Native.FindFirstFile(tempPath, findData);
162165
try
@@ -197,31 +200,41 @@ internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_AT
197200
}
198201
}
199202
}
203+
#if !PLATFORM_UNIX
200204
}
201205
finally
202206
{
203-
Win32Native.SetErrorMode(oldMode);
207+
if (errorModeSuccess)
208+
Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
204209
}
210+
#endif
205211

206212
// Copy the information to data
207213
data.PopulateFrom(findData);
208214
}
209215
else
210216
{
217+
bool success = false;
218+
219+
#if !PLATFORM_UNIX
211220
// For floppy drives, normally the OS will pop up a dialog saying
212221
// there is no disk in drive A:, please insert one. We don't want that.
213-
// SetErrorMode will let us disable this, but we should set the error
222+
// SetThreadErrorMode will let us disable this, but we should set the error
214223
// mode back, since this may have wide-ranging effects.
215-
bool success = false;
216-
int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
224+
uint oldMode;
225+
bool errorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
217226
try
218227
{
228+
#endif
219229
success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
230+
#if !PLATFORM_UNIX
220231
}
221232
finally
222233
{
223-
Win32Native.SetErrorMode(oldMode);
234+
if (errorModeSuccess)
235+
Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
224236
}
237+
#endif
225238

226239
if (!success)
227240
{

src/mscorlib/src/System/IO/FileSystemEnumerable.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,10 @@ internal class FileSystemEnumerableIterator<TSource> : Iterator<TSource>
146146
private SearchOption searchOption;
147147
private String fullPath;
148148
private String normalizedSearchPath;
149-
private int oldMode;
150-
149+
#if !PLATFORM_UNIX
150+
private int _oldMode;
151+
private bool _setBackOldMode;
152+
#endif
151153
internal FileSystemEnumerableIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler<TSource> resultHandler, bool checkHost)
152154
{
153155
Contract.Requires(path != null);
@@ -156,7 +158,9 @@ internal FileSystemEnumerableIterator(String path, String originalUserPath, Stri
156158
Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
157159
Contract.Requires(resultHandler != null);
158160

159-
oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
161+
#if !PLATFORM_UNIX
162+
_setBackOldMode = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out _oldMode);
163+
#endif
160164

161165
searchStack = new List<Directory.SearchData>();
162166

@@ -284,7 +288,14 @@ protected override void Dispose(bool disposing)
284288
}
285289
finally
286290
{
287-
Win32Native.SetErrorMode(oldMode);
291+
#if !PLATFORM_UNIX
292+
if (_setBackOldMode)
293+
{
294+
uint _ignore;
295+
Interop.Kernel32.SetThreadErrorMode(_oldMode, out _ignore);
296+
}
297+
#endif
298+
288299
base.Dispose(disposing);
289300
}
290301
}

0 commit comments

Comments
 (0)