示例#1
0
        /// <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;
        }
示例#2
0
        /// <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;
            }
        }
示例#5
0
        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;
              }
        }
示例#6
0
        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;
                }
            }
        }
示例#7
0
        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;
            }
        }
示例#8
0
        /// <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);
        }
示例#9
0
文件: Device.cs 项目: HaKDMoDz/GNet
		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;
		}
示例#10
0
        // -----------------------------
        // ---- 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;
            }
        }
示例#11
0
 private static void _CloseHandle(SafeFileHandle h)
 {
     try
       {
     if (h != null)
     {
       h.Close();
       h.Dispose();
     }
       }
       catch
       {
     //Eat...
       }
 }