/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, Interop.Sys.OpenFlags flags, int mode) { Debug.Assert(path != null); SafeFileHandle handle = new SafeFileHandle(ownsHandle: true); // If we fail to open the file due to a path not existing, we need to know whether to blame // the file itself or its directory. If we're creating the file, then we blame the directory, // otherwise we blame the file. bool enoentDueToDirectory = (flags & Interop.Sys.OpenFlags.O_CREAT) != 0; // Open the file. int fd; while (Interop.CheckIo(fd = Interop.Sys.Open(path, flags, mode), path, isDirectory: enoentDueToDirectory, errorRewriter: e => (e.Error == Interop.Error.EISDIR) ? Interop.Error.EACCES.Info() : e)) ; handle.SetHandle(fd); // Make sure it's not a directory; we do this after opening it once we have a file descriptor // to avoid race conditions. Interop.Sys.FileStatus status; if (Interop.Sys.FStat(fd, out status) != 0) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), path); } if ((status.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Error.EACCES.Info(), path, isDirectory: true); } return handle; }
/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, Interop.Sys.OpenFlags flags, int mode) { Debug.Assert(path != null); // SafeFileHandle wraps a file descriptor rather than a pointer, and a file descriptor is always 4 bytes // rather than being pointer sized, which means we can't utilize the runtime's ability to marshal safe handles. // Ideally this would be a constrained execution region, but we don't have access to PrepareConstrainedRegions. // We still use a finally block to house the code that opens the file and stores the handle in hopes // of making it as non-interruptable as possible. The SafeFileHandle is also allocated first to avoid // the allocation after getting the file descriptor but before storing it. SafeFileHandle handle = new SafeFileHandle(ownsHandle: true); try { } finally { // If we fail to open the file due to a path not existing, we need to know whether to blame // the file itself or its directory. If we're creating the file, then we blame the directory, // otherwise we blame the file. bool enoentDueToDirectory = (flags & Interop.Sys.OpenFlags.O_CREAT) != 0; // Open the file. int fd; while (Interop.CheckIo(fd = Interop.Sys.Open(path, flags, mode), path, isDirectory: enoentDueToDirectory, errorRewriter: e => (e.Error == Interop.Error.EISDIR) ? Interop.Error.EACCES.Info() : e)) ; Debug.Assert(fd >= 0); handle.SetHandle((IntPtr)fd); Debug.Assert(!handle.IsInvalid); // Make sure it's not a directory; we do this after opening it once we have a file descriptor // to avoid race conditions. Interop.Sys.FileStatus status; if (Interop.Sys.FStat(fd, out status) != 0) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), path); } if ((status.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Error.EACCES.Info(), path, isDirectory: true); } } return handle; }
private static unsafe void Preallocate(string fullPath, long preallocationSize, SafeFileHandle fileHandle) { // preallocationSize must be ignored for non-seekable files, unsupported file systems // and other failures other than ERROR_DISK_FULL and ERROR_FILE_TOO_LARGE if (!FileStreamHelpers.TrySetFileLength(fileHandle, preallocationSize, out int errorCode) && errorCode == Interop.Errors.ERROR_DISK_FULL || errorCode == Interop.Errors.ERROR_FILE_TOO_LARGE) { // Windows does not modify the file size if the request can't be satisfied in atomic way. // posix_fallocate (Unix) implementation might consume all available disk space and fail after that. // To ensure that the behaviour is the same for every OS (no incomplete or empty file), we close the handle and delete the file. fileHandle.Dispose(); Interop.Kernel32.DeleteFile(fullPath); throw new IOException(SR.Format(errorCode == Interop.Errors.ERROR_DISK_FULL ? SR.IO_DiskFull_Path_AllocationSize : SR.IO_FileTooLarge_Path_AllocationSize, fullPath, preallocationSize)); } }
private static FileStream CreateSharedBackingObject( Interop.libc.MemoryMappedProtections protections, long capacity) { // The POSIX shared memory object name must begin with '/'. After that we just want something short and unique. string mapName = "/corefx_map_" + Guid.NewGuid().ToString("N"); // Determine the flags to use when creating the shared memory object Interop.Sys.OpenFlags flags = (protections & Interop.libc.MemoryMappedProtections.PROT_WRITE) != 0 ? Interop.Sys.OpenFlags.O_RDWR : Interop.Sys.OpenFlags.O_RDONLY; flags |= Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_EXCL; // CreateNew // Determine the permissions with which to create the file Interop.Sys.Permissions perms = default(Interop.Sys.Permissions); if ((protections & Interop.libc.MemoryMappedProtections.PROT_READ) != 0) perms |= Interop.Sys.Permissions.S_IRUSR; if ((protections & Interop.libc.MemoryMappedProtections.PROT_WRITE) != 0) perms |= Interop.Sys.Permissions.S_IWUSR; if ((protections & Interop.libc.MemoryMappedProtections.PROT_EXEC) != 0) perms |= Interop.Sys.Permissions.S_IXUSR; // Create the shared memory object. int fd; Interop.CheckIo(fd = Interop.Sys.ShmOpen(mapName, flags, (int)perms), mapName); SafeFileHandle fileHandle = new SafeFileHandle((IntPtr)fd, ownsHandle: true); try { // Unlink the shared memory object immediatley so that it'll go away once all handles // to it are closed (as with opened then unlinked files, it'll remain usable via // the open handles even though it's unlinked and can't be opened anew via its name). Interop.CheckIo(Interop.Sys.ShmUnlink(mapName)); // Give it the right capacity. We do this directly with ftruncate rather // than via FileStream.SetLength after the FileStream is created because, on some systems, // lseek fails on shared memory objects, causing the FileStream to think it's unseekable, // causing it to preemptively throw from SetLength. Interop.CheckIo(Interop.libc.ftruncate(fd, capacity)); // Wrap the file descriptor in a stream and return it. return new FileStream(fileHandle, TranslateProtectionsToFileAccess(protections)); } catch { fileHandle.Dispose(); throw; } }
public void Open() { try { _deviceHandle = NativeInterface.CreateFile_SafeFileHandle(_devicePath, (NativeInterface.GENERIC_WRITE | NativeInterface.GENERIC_READ), NativeInterface.FILE_SHARE_READ | NativeInterface.FILE_SHARE_WRITE, IntPtr.Zero, NativeInterface.OPEN_EXISTING, NativeInterface.FILE_ATTRIBUTE_NORMAL | NativeInterface.FILE_FLAG_OVERLAPPED, 0); if (_deviceHandle.IsInvalid) { throw new Win32Exception("Failed to open WinUSB device handle."); } _InitializeDevice(); } catch (Exception) { if (_deviceHandle != null) { _deviceHandle.Dispose(); _deviceHandle = null; } _FreeWinUSB(); throw; } }
private void OpenSqlFileStream ( string path, byte[] transactionContext, System.IO.FileAccess access, System.IO.FileOptions options, Int64 allocationSize ) { //----------------------------------------------------------------- // precondition validation // these should be checked by any caller of this method // ensure we have validated and normalized the path before Debug.Assert(path != null); Debug.Assert(transactionContext != null); if (access != FileAccess.Read && access != FileAccess.Write && access != FileAccess.ReadWrite) { throw ADP.ArgumentOutOfRange("access"); } // FileOptions is a set of flags, so AND the given value against the set of values we do not support if ((options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.SequentialScan)) != 0) { throw ADP.ArgumentOutOfRange("options"); } //----------------------------------------------------------------- // normalize the provided path // * compress path to remove any occurences of '.' or '..' // * trim whitespace from the beginning and end of the path // * ensure that the path starts with '\\' // * ensure that the path does not start with '\\.\' // * ensure that the path is not longer than Int16.MaxValue path = GetFullPathInternal(path); // ensure the running code has permission to read/write the file DemandAccessPermission(path, access); FileFullEaInformation eaBuffer = null; SecurityQualityOfService qos = null; UnicodeString objectName = null; Microsoft.Win32.SafeHandles.SafeFileHandle hFile = null; int nDesiredAccess = UnsafeNativeMethods.FILE_READ_ATTRIBUTES | UnsafeNativeMethods.SYNCHRONIZE; UInt32 dwCreateOptions = 0; UInt32 dwCreateDisposition = 0; System.IO.FileShare shareAccess = System.IO.FileShare.None; switch (access) { case System.IO.FileAccess.Read: nDesiredAccess |= UnsafeNativeMethods.FILE_READ_DATA; shareAccess = System.IO.FileShare.Delete | System.IO.FileShare.ReadWrite; dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OPEN; break; case System.IO.FileAccess.Write: nDesiredAccess |= UnsafeNativeMethods.FILE_WRITE_DATA; shareAccess = System.IO.FileShare.Delete | System.IO.FileShare.Read; dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE; break; case System.IO.FileAccess.ReadWrite: default: // we validate the value of 'access' parameter in the beginning of this method Debug.Assert(access == System.IO.FileAccess.ReadWrite); nDesiredAccess |= UnsafeNativeMethods.FILE_READ_DATA | UnsafeNativeMethods.FILE_WRITE_DATA; shareAccess = System.IO.FileShare.Delete | System.IO.FileShare.Read; dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE; break; } if ((options & System.IO.FileOptions.WriteThrough) != 0) { dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_WRITE_THROUGH; } if ((options & System.IO.FileOptions.Asynchronous) == 0) { dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_SYNCHRONOUS_IO_NONALERT; } if ((options & System.IO.FileOptions.SequentialScan) != 0) { dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_SEQUENTIAL_ONLY; } if ((options & System.IO.FileOptions.RandomAccess) != 0) { dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_RANDOM_ACCESS; } try { eaBuffer = new FileFullEaInformation(transactionContext); qos = new SecurityQualityOfService(UnsafeNativeMethods.SecurityImpersonationLevel.SecurityAnonymous, false, false); // NOTE: the Name property is intended to reveal the publicly available moniker for the // FILESTREAM attributed column data. We will not surface the internal processing that // takes place to create the mappedPath. string mappedPath = InitializeNtPath(path); objectName = new UnicodeString(mappedPath); UnsafeNativeMethods.OBJECT_ATTRIBUTES oa; oa.length = Marshal.SizeOf(typeof(UnsafeNativeMethods.OBJECT_ATTRIBUTES)); oa.rootDirectory = IntPtr.Zero; oa.attributes = (int)UnsafeNativeMethods.Attributes.CaseInsensitive; oa.securityDescriptor = IntPtr.Zero; oa.securityQualityOfService = qos; oa.objectName = objectName; UnsafeNativeMethods.IO_STATUS_BLOCK ioStatusBlock; uint oldMode; uint retval = 0; UnsafeNativeMethods.SetErrorModeWrapper(UnsafeNativeMethods.SEM_FAILCRITICALERRORS, out oldMode); try { Bid.Trace("<sc.SqlFileStream.OpenSqlFileStream|ADV> %d#, desiredAccess=0x%08x, allocationSize=%I64d, fileAttributes=0x%08x, shareAccess=0x%08x, dwCreateDisposition=0x%08x, createOptions=0x%08x\n", ObjectID, (int)nDesiredAccess, allocationSize, 0, (int)shareAccess, dwCreateDisposition, dwCreateOptions); retval = UnsafeNativeMethods.NtCreateFile(out hFile, nDesiredAccess, ref oa, out ioStatusBlock, ref allocationSize, 0, shareAccess, dwCreateDisposition, dwCreateOptions, eaBuffer, (uint)eaBuffer.Length); } finally { UnsafeNativeMethods.SetErrorModeWrapper(oldMode, out oldMode); } switch (retval) { case 0: break; case UnsafeNativeMethods.STATUS_SHARING_VIOLATION: throw ADP.InvalidOperation(Res.GetString(Res.SqlFileStream_FileAlreadyInTransaction)); case UnsafeNativeMethods.STATUS_INVALID_PARAMETER: throw ADP.Argument(Res.GetString(Res.SqlFileStream_InvalidParameter)); case UnsafeNativeMethods.STATUS_OBJECT_NAME_NOT_FOUND: { System.IO.DirectoryNotFoundException e = new System.IO.DirectoryNotFoundException(); ADP.TraceExceptionAsReturnValue(e); throw e; } default: { uint error = UnsafeNativeMethods.RtlNtStatusToDosError(retval); if (error == UnsafeNativeMethods.ERROR_MR_MID_NOT_FOUND) { // status code could not be mapped to a Win32 error code error = retval; } System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(unchecked ((int)error)); ADP.TraceExceptionAsReturnValue(e); throw e; } } if (hFile.IsInvalid) { System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(UnsafeNativeMethods.ERROR_INVALID_HANDLE); ADP.TraceExceptionAsReturnValue(e); throw e; } UnsafeNativeMethods.FileType fileType = UnsafeNativeMethods.GetFileType(hFile); if (fileType != UnsafeNativeMethods.FileType.Disk) { hFile.Dispose(); throw ADP.Argument(Res.GetString(Res.SqlFileStream_PathNotValidDiskResource)); } // if the user is opening the SQL FileStream in read/write mode, we assume that they want to scan // through current data and then append new data to the end, so we need to tell SQL Server to preserve // the existing file contents. if (access == System.IO.FileAccess.ReadWrite) { uint ioControlCode = UnsafeNativeMethods.CTL_CODE(UnsafeNativeMethods.FILE_DEVICE_FILE_SYSTEM, IoControlCodeFunctionCode, (byte)UnsafeNativeMethods.Method.METHOD_BUFFERED, (byte)UnsafeNativeMethods.Access.FILE_ANY_ACCESS); uint cbBytesReturned = 0; if (!UnsafeNativeMethods.DeviceIoControl(hFile, ioControlCode, IntPtr.Zero, 0, IntPtr.Zero, 0, out cbBytesReturned, IntPtr.Zero)) { System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); ADP.TraceExceptionAsReturnValue(e); throw e; } } // now that we've successfully opened a handle on the path and verified that it is a file, // use the SafeFileHandle to initialize our internal System.IO.FileStream instance // NOTE: need to assert UnmanagedCode permissions for this constructor. This is relatively benign // in that we've done much the same validation as in the FileStream(string path, ...) ctor case // most notably, validating that the handle type corresponds to an on-disk file. bool bRevertAssert = false; try { SecurityPermission sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); sp.Assert(); bRevertAssert = true; System.Diagnostics.Debug.Assert(m_fs == null); m_fs = new System.IO.FileStream(hFile, access, DefaultBufferSize, ((options & System.IO.FileOptions.Asynchronous) != 0)); } finally { if (bRevertAssert) { SecurityPermission.RevertAssert(); } } } catch { if (hFile != null && !hFile.IsInvalid) { hFile.Dispose(); } throw; } finally { if (eaBuffer != null) { eaBuffer.Dispose(); eaBuffer = null; } if (qos != null) { qos.Dispose(); qos = null; } if (objectName != null) { objectName.Dispose(); objectName = null; } } }
public void OpenDevice(string devicePathName) { try { _deviceHandle = FileIO.CreateFile(devicePathName, (FileIO.GENERIC_WRITE | FileIO.GENERIC_READ), FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, FileIO.FILE_ATTRIBUTE_NORMAL | FileIO.FILE_FLAG_OVERLAPPED, 0); if (_deviceHandle.IsInvalid) throw APIException.Win32("Failed to open WinUSB device handle."); InitializeDevice(); } catch(Exception) { if (_deviceHandle != null) { _deviceHandle.Dispose(); _deviceHandle = null; } FreeWinUSB(); throw; } }
/// <summary> /// Constructs a new USN helper instance /// </summary> /// <param name="path">The path to the folder to perform USN services</param> /// <param name="volumeRoot">The root volume where the USN lookup is performed</param> internal USNHelper(string path, string volumeRoot) { if (Utility.Utility.IsClientLinux) throw new Exception(Strings.USNHelper.LinuxNotSupportedError); if (!System.IO.Path.IsPathRooted(path)) throw new Exception(string.Format("Path {0} is not rooted", path)); m_path = Utility.Utility.AppendDirSeparator(path); try { string devicename = @"\\.\" + System.IO.Path.GetPathRoot(path).TrimEnd('\\'); if (volumeRoot != null) volumeRoot = volumeRoot.TrimEnd('\\'); m_volumeHandle = Win32USN.CreateFile(volumeRoot == null ? devicename : volumeRoot, Win32USN.EFileAccess.GenericRead, Win32USN.EFileShare.ReadWrite, IntPtr.Zero, Win32USN.ECreationDisposition.OpenExisting, Win32USN.EFileAttributes.BackupSemantics, IntPtr.Zero); if (m_volumeHandle == null || m_volumeHandle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); uint bytesReturned = 0; if (!Win32USN.DeviceIoControl(m_volumeHandle, Win32USN.EIOControlCode.FsctlQueryUsnJournal, null, 0, out m_journal, (uint)Marshal.SizeOf(typeof(Win32USN.USN_JOURNAL_DATA)), ref bytesReturned, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); Win32USN.BY_HANDLE_FILE_INFORMATION fileInfo; using (SafeFileHandle driveHandle = Win32USN.CreateFile(System.IO.Path.GetPathRoot(path), Win32USN.EFileAccess.GenericRead, Win32USN.EFileShare.ReadWrite, IntPtr.Zero, Win32USN.ECreationDisposition.OpenExisting, Win32USN.EFileAttributes.BackupSemantics, IntPtr.Zero)) if (!Win32USN.GetFileInformationByHandle(driveHandle, out fileInfo)) throw new Win32Exception(Marshal.GetLastWin32Error()); m_volumeRootFileNameReferenceNumber = ((ulong)fileInfo.FileIndexHigh << 32) | ((ulong)fileInfo.FileIndexLow); } catch { if (m_volumeHandle != null) { m_volumeHandle.Dispose(); m_volumeHandle = null; } throw; } if (this.FileSystemEntries.Count == 0) throw new Exception(Strings.USNHelper.SafeGuardError); }
public bool SetFeature(byte[] data) { if (!IsConnected && !Connect()) return false; GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); int length = data.Length; SafeFileHandle safe = new SafeFileHandle(OpenDeviceIO(DeviceInfo.Path, DeviceMode.NonOverlapped, NativeMethods.GENERIC_WRITE), true); try { IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); NativeMethods.HidD_SetFeature(safe, buffer, length); } finally { handle.Free(); safe.Dispose(); } return true; }
// ----------------------------- // ---- PAL layer ends here ---- // ----------------------------- private static FileStream CreateSharedBackingObjectUsingMemory( Interop.Sys.MemoryMappedProtections protections, long capacity) { // The POSIX shared memory object name must begin with '/'. After that we just want something short and unique. string mapName = "/corefx_map_" + Guid.NewGuid().ToString("N"); // Determine the flags to use when creating the shared memory object Interop.Sys.OpenFlags flags = (protections & Interop.Sys.MemoryMappedProtections.PROT_WRITE) != 0 ? Interop.Sys.OpenFlags.O_RDWR : Interop.Sys.OpenFlags.O_RDONLY; flags |= Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_EXCL; // CreateNew // Determine the permissions with which to create the file Interop.Sys.Permissions perms = default(Interop.Sys.Permissions); if ((protections & Interop.Sys.MemoryMappedProtections.PROT_READ) != 0) perms |= Interop.Sys.Permissions.S_IRUSR; if ((protections & Interop.Sys.MemoryMappedProtections.PROT_WRITE) != 0) perms |= Interop.Sys.Permissions.S_IWUSR; if ((protections & Interop.Sys.MemoryMappedProtections.PROT_EXEC) != 0) perms |= Interop.Sys.Permissions.S_IXUSR; // Create the shared memory object. int fd = Interop.Sys.ShmOpen(mapName, flags, (int)perms); if (fd < 0) { Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo(); if (errorInfo.Error == Interop.Error.ENOTSUP) { // If ShmOpen is not supported, fall back to file backing object. // Note that the System.Native shim will force this failure on platforms where // the result of native shm_open does not work well with our subsequent call // to mmap. return null; } throw Interop.GetExceptionForIoErrno(errorInfo); } SafeFileHandle fileHandle = new SafeFileHandle((IntPtr)fd, ownsHandle: true); try { // Unlink the shared memory object immediatley so that it'll go away once all handles // to it are closed (as with opened then unlinked files, it'll remain usable via // the open handles even though it's unlinked and can't be opened anew via its name). Interop.CheckIo(Interop.Sys.ShmUnlink(mapName)); // Give it the right capacity. We do this directly with ftruncate rather // than via FileStream.SetLength after the FileStream is created because, on some systems, // lseek fails on shared memory objects, causing the FileStream to think it's unseekable, // causing it to preemptively throw from SetLength. Interop.CheckIo(Interop.Sys.FTruncate(fd, capacity)); // Wrap the file descriptor in a stream and return it. return new FileStream(fileHandle, TranslateProtectionsToFileAccess(protections)); } catch { fileHandle.Dispose(); throw; } }
private static void _CloseHandle(SafeFileHandle h) { try { if (h != null) { h.Close(); h.Dispose(); } } catch { //Eat... } }