diff options
author | Marek Safar <marek.safar@gmail.com> | 2018-09-19 15:19:22 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-19 15:19:22 +0300 |
commit | efd29b5cf854679349066e22ef9038b8cfe76d94 (patch) | |
tree | 2de750c1ac8a487d7f6d149592a6362ade6a5a77 /src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs | |
parent | f9124d69e41d42196510dd7234b2d53fed48ad4c (diff) | |
parent | 49f9ed0e66fc2d4cd682821396c6af5e80182048 (diff) |
Merge pull request #25 from ntherning/bump-corert
Bump to latest upstream
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs')
-rw-r--r-- | src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs index 304088eea..b326525a7 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs @@ -40,5 +40,58 @@ namespace System.IO pCreateExParams: ref parameters)); } } + + private static bool GetDefaultIsAsync(SafeFileHandle handle) => handle.IsAsync ?? DefaultIsAsync; + + private static unsafe bool? IsHandleSynchronous(SafeFileHandle handle, FileAccess access) + { + // Do NOT use this method on any type other than DISK. Reading or writing to a pipe may + // cause an app to block incorrectly, introducing a deadlock (depending on whether a write + // will wake up an already-blocked thread or this Win32FileStream's thread). + + byte* bytes = stackalloc byte[1]; + int numBytesReadWritten; + int r = -1; + + // If the handle is a pipe, ReadFile will block until there + // has been a write on the other end. We'll just have to deal with it, + // For the read end of a pipe, you can mess up and + // accidentally read synchronously from an async pipe. + if ((access & FileAccess.Read) != 0) + { + r = Interop.Kernel32.ReadFile(handle, bytes, 0, out numBytesReadWritten, IntPtr.Zero); + } + else if ((access & FileAccess.Write) != 0) + { + r = Interop.Kernel32.WriteFile(handle, bytes, 0, out numBytesReadWritten, IntPtr.Zero); + } + + if (r == 0) + { + int errorCode = Marshal.GetLastWin32Error(); + switch (errorCode) + { + case Interop.Errors.ERROR_INVALID_PARAMETER: + return false; + case Interop.Errors.ERROR_INVALID_HANDLE: + throw Win32Marshal.GetExceptionForWin32Error(errorCode); + } + } + + return true; + } + + private static void VerifyHandleIsSync(SafeFileHandle handle, int fileType, FileAccess access) + { + // The technique here only really works for FILE_TYPE_DISK. FileMode is the right thing to check, but it currently + // isn't available in WinRT. + + if (fileType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK) + { + // If we can't check the handle, just assume it is ok. + if (!(IsHandleSynchronous(handle, access) ?? true)) + throw new ArgumentException(SR.Arg_HandleNotSync, nameof(handle)); + } + } } } |