private FileObject.FileMemoryStream OpenStreamInternal(AbsolutePath path, FileAccess accessMode, FileMode mode, FileShare share) { if (mode == FileMode.CreateNew && accessMode == FileAccess.Read) { throw new ArgumentException("FileMode.CreateNew and FileAccess.Read is an invalid combination."); } lock (_drives) { FileObject fileObj = FindFileObjectAndParent(path, out var parent); if (parent == null) { return(null); } switch (mode) { case FileMode.Create: if (fileObj != null) { fileObj.DeleteLink(path, false); parent.Children.Remove(path.FileName); } fileObj = new FileObject(path, this, new byte[] {}); parent.Children[path.FileName] = fileObj; break; case FileMode.Open: if (fileObj == null) { return(null); } break; case FileMode.OpenOrCreate: if (fileObj == null) { fileObj = new FileObject(path, this, new byte[] {}); parent.Children[path.FileName] = fileObj; } break; case FileMode.CreateNew: if (fileObj != null) { unchecked { throw new IOException("File already exists", new IOException("File exists", (int)Hresult.FileExists)); } } fileObj = new FileObject(path, this, new byte[] {}); parent.Children[path.FileName] = fileObj; break; default: throw new NotImplementedException($"Mode '{mode}' is not supported."); } var file = fileObj.Open(path, accessMode, share); if (accessMode.HasFlag(FileAccess.Write)) { _currentStatistics.FileOpensForWrite++; } else { _currentStatistics.FileOpensForRead++; } return(file); } }
/// <inheritdoc /> /// <remarks>Ref count limit is not implemented for the In Memory file system.</remarks> public CreateHardLinkResult CreateHardLink(AbsolutePath sourceFileName, AbsolutePath destinationFileName, bool replaceExisting) { lock (_drives) { if (!_useHardLinks) { return(CreateHardLinkResult.FailedNotSupported); } FileObject fileObj = FindFileObject(sourceFileName); if (fileObj == null) { return(CreateHardLinkResult.FailedSourceDoesNotExist); } if (destinationFileName.Length >= FileSystemConstants.MaxPath) { // Please note, we use FileSystemConstants.MaxPath that returns // ShortMaxPath or LongMaxPath depending on whether the system supports long paths or not. return(CreateHardLinkResult.FailedPathTooLong); } FileObject destination = FindFileObjectAndParent(destinationFileName, out var parentDestination); if (parentDestination == null) { throw new IOException( string.Format(CultureInfo.InvariantCulture, "Parent of destination {0} does not exist", destinationFileName.Path)); } // ReSharper disable PossibleNullReferenceException char sourceDrive = sourceFileName.DriveLetter; char destinationDrive = destinationFileName.DriveLetter; // ReSharper restore PossibleNullReferenceException if (sourceDrive != destinationDrive) { return(CreateHardLinkResult.FailedSourceAndDestinationOnDifferentVolumes); } if (!fileObj.CanAddLink()) { return(CreateHardLinkResult.FailedMaxHardLinkLimitReached); } if (destination != null) { if (!replaceExisting) { return(CreateHardLinkResult.FailedDestinationExists); } try { destination.DeleteLink(destinationFileName, false, true); } catch (UnauthorizedAccessException) { return(CreateHardLinkResult.FailedAccessDenied); } } fileObj.AddLink(destinationFileName); parentDestination.Children[destinationFileName.FileName] = fileObj; } return(CreateHardLinkResult.Success); }