/// <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; } } }
private DirectoryEntry AddFileToDirectory(File file, Directory dir, string name, NewFileOptions options) { DirectoryEntry entry; bool createShortNames; if (options != null && options.CreateShortNames.HasValue) { createShortNames = options.CreateShortNames.Value; } else { createShortNames = CreateShortNames; } if (createShortNames) { if (Utilities.Is8Dot3(name.ToUpperInvariant())) { entry = dir.AddEntry(file, name, FileNameNamespace.Win32AndDos); } else { entry = dir.AddEntry(file, name, FileNameNamespace.Win32); dir.AddEntry(file, dir.CreateShortName(name), FileNameNamespace.Dos); } } else { entry = dir.AddEntry(file, name, FileNameNamespace.Posix); } return entry; }
/// <summary> /// Creates a directory. /// </summary> /// <param name="path">The path of the new directory.</param> /// <param name="options">Options controlling attributes of the new Director, or <c>null</c> for defaults.</param> public void CreateDirectory(string path, NewFileOptions options) { using (new NtfsTransaction()) { string[] pathElements = path.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); Directory focusDir = GetDirectory(MasterFileTable.RootDirIndex); DirectoryEntry focusDirEntry = focusDir.DirectoryEntry; for (int i = 0; i < pathElements.Length; ++i) { DirectoryEntry childDirEntry = focusDir.GetEntryByName(pathElements[i]); if (childDirEntry == null) { FileAttributeFlags newDirAttrs = focusDir.StandardInformation.FileAttributes; if (options != null && options.Compressed.HasValue) { if (options.Compressed.Value) { newDirAttrs |= FileAttributeFlags.Compressed; } else { newDirAttrs &= ~FileAttributeFlags.Compressed; } } Directory childDir = Directory.CreateNew(_context, newDirAttrs); try { childDirEntry = AddFileToDirectory(childDir, focusDir, pathElements[i], options); RawSecurityDescriptor parentSd = DoGetSecurity(focusDir); RawSecurityDescriptor newSd; if (options != null && options.SecurityDescriptor != null) { newSd = options.SecurityDescriptor; } else { newSd = SecurityDescriptor.CalcNewObjectDescriptor(parentSd, false); } DoSetSecurity(childDir, newSd); childDirEntry.UpdateFrom(childDir); // Update the directory entry by which we found the directory we've just modified focusDirEntry.UpdateFrom(focusDir); focusDir = childDir; } finally { if (childDir.HardLinkCount == 0) { childDir.Delete(); } } } else { focusDir = GetDirectory(childDirEntry.Reference); } focusDirEntry = childDirEntry; } } }
private DirectoryEntry CreateNewFile(string path, NewFileOptions options) { DirectoryEntry result; DirectoryEntry parentDirEntry = GetDirectoryEntry(Utilities.GetDirectoryFromPath(path)); Directory parentDir = GetDirectory(parentDirEntry.Reference); FileAttributeFlags newFileAttrs = parentDir.StandardInformation.FileAttributes; if (options != null && options.Compressed.HasValue) { if (options.Compressed.Value) { newFileAttrs |= FileAttributeFlags.Compressed; } else { newFileAttrs &= ~FileAttributeFlags.Compressed; } } File file = File.CreateNew(_context, newFileAttrs); try { result = AddFileToDirectory(file, parentDir, Utilities.GetFileFromPath(path), options); RawSecurityDescriptor parentSd = DoGetSecurity(parentDir); RawSecurityDescriptor newSd; if (options != null && options.SecurityDescriptor != null) { newSd = options.SecurityDescriptor; } else { newSd = SecurityDescriptor.CalcNewObjectDescriptor(parentSd, false); } DoSetSecurity(file, newSd); result.UpdateFrom(file); parentDirEntry.UpdateFrom(parentDir); } finally { if (file.HardLinkCount == 0) { file.Delete(); } } return result; }