/// <summary> /// Opens the specified file. /// </summary> /// <param name="path">The full path of the file to open.</param> /// <param name="mode">The file mode for the created stream.</param> /// <param name="access">The access permissions for the returned stream.</param> /// <param name="options">Options controlling attributes of a new file, or <c>null</c> for defaults (ignored if file exists).</param> /// <returns>The new stream.</returns> public SparseStream OpenFile(string path, FileMode mode, FileAccess access, NewFileOptions options) { using (new NtfsTransaction()) { string attributeName; AttributeType attributeType; string dirEntryPath = ParsePath(path, out attributeName, out attributeType); DirectoryEntry entry = GetDirectoryEntry(dirEntryPath); if (entry == null) { if (mode == FileMode.Open) { throw new FileNotFoundException("No such file", path); } else { entry = CreateNewFile(dirEntryPath, options); } } else if (mode == FileMode.CreateNew) { throw new IOException("File already exists"); } if ((entry.Details.FileAttributes & FileAttributes.Directory) != 0 && attributeType == AttributeType.Data) { throw new IOException("Attempt to open directory as a file"); } else { File file = GetFile(entry.Reference); NtfsStream ntfsStream = file.GetStream(attributeType, attributeName); if (ntfsStream == null) { if (mode == FileMode.Create || mode == FileMode.OpenOrCreate) { ntfsStream = file.CreateStream(attributeType, attributeName); } else { throw new FileNotFoundException("No such attribute on file", path); } } SparseStream stream = new NtfsFileStream(this, entry, attributeType, attributeName, access); if (mode == FileMode.Create || mode == FileMode.Truncate) { stream.SetLength(0); } return stream; } } }
/// <summary> /// Opens the specified file. /// </summary> /// <param name="path">The full path of the file to open.</param> /// <param name="mode">The file mode for the created stream.</param> /// <param name="access">The access permissions for the returned stream.</param> /// <returns>The new stream.</returns> public override Stream OpenFile(string path, FileMode mode, FileAccess access) { using (new NtfsTransaction()) { string fileName = Utilities.GetFileFromPath(path); string attributeName = null; AttributeType attributeType = AttributeType.Data; string[] fileNameElements = fileName.Split(new char[]{':'}, 3); fileName = fileNameElements[0]; if(fileNameElements.Length > 1) { attributeName = fileNameElements[1]; if(string.IsNullOrEmpty(attributeName)) { attributeName = null; } } if(fileNameElements.Length > 2) { string typeName = fileNameElements[2]; AttributeDefinitionRecord typeDefn = _context.AttributeDefinitions.Lookup(typeName); if(typeDefn == null) { throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "No such attribute type '{0}'", typeName), path); } attributeType = typeDefn.Type; } string dirName; try { dirName = Utilities.GetDirectoryFromPath(path); } catch (ArgumentException) { throw new IOException("Invalid path: " + path); } string dirEntryPath; try { dirEntryPath = Path.Combine(dirName, fileName); } catch (ArgumentException) { throw new IOException("Invalid path: " + path); } DirectoryEntry entry = GetDirectoryEntry(dirEntryPath); if (entry == null) { if (mode == FileMode.Open) { throw new FileNotFoundException("No such file", path); } else { File file = File.CreateNew(_context); try { DirectoryEntry parentDirEntry = GetDirectoryEntry(Path.GetDirectoryName(path)); Directory parentDir = GetDirectory(parentDirEntry.Reference); entry = AddFileToDirectory(file, parentDir, Path.GetFileName(path)); RawSecurityDescriptor sd = DoGetSecurity(parentDir); DoSetSecurity(file, SecurityDescriptor.CalcNewObjectDescriptor(sd, false)); entry.UpdateFrom(file); parentDirEntry.UpdateFrom(parentDir); } finally { if (file.HardLinkCount == 0) { file.Delete(); } } } } else if (mode == FileMode.CreateNew) { throw new IOException("File already exists"); } if ((entry.Details.FileAttributes & FileAttributes.Directory) != 0 && attributeType == AttributeType.Data) { throw new IOException("Attempt to open directory as a file"); } else { File file = GetFile(entry.Reference); NtfsStream ntfsStream = file.GetStream(attributeType, attributeName); if (ntfsStream == null) { if (mode == FileMode.Create || mode == FileMode.OpenOrCreate) { ntfsStream = file.CreateStream(attributeType, attributeName); } else { throw new FileNotFoundException("No such attribute on file", path); } } SparseStream stream = new NtfsFileStream(this, entry, attributeType, attributeName, access); if (mode == FileMode.Create || mode == FileMode.Truncate) { stream.SetLength(0); } return stream; } } }