summaryrefslogtreecommitdiff
path: root/src/mscorlib/shared/System/IO/FileStream.WinRT.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/shared/System/IO/FileStream.WinRT.cs')
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.WinRT.cs78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/mscorlib/shared/System/IO/FileStream.WinRT.cs b/src/mscorlib/shared/System/IO/FileStream.WinRT.cs
new file mode 100644
index 0000000000..062b160b57
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStream.WinRT.cs
@@ -0,0 +1,78 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ private unsafe SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
+ {
+ Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
+
+ int fAccess =
+ ((_access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
+ ((_access & FileAccess.Write) == FileAccess.Write ? GENERIC_WRITE : 0);
+
+ // Our Inheritable bit was stolen from Windows, but should be set in
+ // the security attributes class. Don't leave this bit set.
+ share &= ~FileShare.Inheritable;
+
+ // Must use a valid Win32 constant here...
+ if (mode == FileMode.Append)
+ mode = FileMode.OpenOrCreate;
+
+ Interop.Kernel32.CREATEFILE2_EXTENDED_PARAMETERS parameters = new Interop.Kernel32.CREATEFILE2_EXTENDED_PARAMETERS();
+ parameters.dwSize = (uint)sizeof(Interop.Kernel32.CREATEFILE2_EXTENDED_PARAMETERS);
+ parameters.dwFileFlags = (uint)options;
+ parameters.lpSecurityAttributes = &secAttrs;
+
+ SafeFileHandle fileHandle = Interop.Kernel32.CreateFile2(
+ lpFileName: _path,
+ dwDesiredAccess: fAccess,
+ dwShareMode: share,
+ dwCreationDisposition: mode,
+ pCreateExParams: &parameters);
+
+ fileHandle.IsAsync = _useAsyncIO;
+
+ if (fileHandle.IsInvalid)
+ {
+ // Return a meaningful exception with the full path.
+
+ // NT5 oddity - when trying to open "C:\" as a Win32FileStream,
+ // we usually get ERROR_PATH_NOT_FOUND from the OS. We should
+ // probably be consistent w/ every other directory.
+ int errorCode = Marshal.GetLastWin32Error();
+
+ if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Length == PathInternal.GetRootLength(_path))
+ errorCode = Interop.Errors.ERROR_ACCESS_DENIED;
+
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode, $"{_path} {options} {fAccess} {share} {mode}");
+ }
+
+ return fileHandle;
+ }
+
+#if PROJECTN
+ // TODO: These internal methods should be removed once we start consuming updated CoreFX builds
+ public static FileStream InternalOpen(string path, int bufferSize = 4096, bool useAsync = true)
+ {
+ return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync);
+ }
+
+ public static FileStream InternalCreate(string path, int bufferSize = 4096, bool useAsync = true)
+ {
+ return new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
+ }
+
+ public static FileStream InternalAppend(string path, int bufferSize = 4096, bool useAsync = true)
+ {
+ return new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
+ }
+#endif
+ }
+}