public void GetFileLength() { NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem(); ntfs.OpenFile(@"AFILE.TXT", FileMode.Create).Dispose(); Assert.Equal(0, ntfs.GetFileLength("AFILE.TXT")); using (var stream = ntfs.OpenFile(@"AFILE.TXT", FileMode.Open)) { stream.Write(new byte[14325], 0, 14325); } Assert.Equal(14325, ntfs.GetFileLength("AFILE.TXT")); using (var attrStream = ntfs.OpenFile(@"AFILE.TXT:altstream", FileMode.Create)) { attrStream.Write(new byte[122], 0, 122); } Assert.Equal(122, ntfs.GetFileLength("AFILE.TXT:altstream")); // Test NTFS options for hardlink behaviour ntfs.CreateDirectory("Dir"); ntfs.CreateHardLink("AFILE.TXT", @"Dir\OtherLink.txt"); using (var stream = ntfs.OpenFile("AFILE.TXT", FileMode.Open, FileAccess.ReadWrite)) { stream.SetLength(50); } Assert.Equal(50, ntfs.GetFileLength("AFILE.TXT")); Assert.Equal(14325, ntfs.GetFileLength(@"Dir\OtherLink.txt")); ntfs.NtfsOptions.FileLengthFromDirectoryEntries = false; Assert.Equal(50, ntfs.GetFileLength(@"Dir\OtherLink.txt")); }
public void HardLinkCount() { NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem(); using (Stream s = ntfs.OpenFile("ALongFileName.txt", FileMode.CreateNew)) { } Assert.Equal(1, ntfs.GetHardLinkCount("ALongFileName.txt")); ntfs.CreateHardLink("ALongFileName.txt", "AHardLink.TXT"); Assert.Equal(2, ntfs.GetHardLinkCount("ALongFileName.txt")); ntfs.CreateDirectory("DIR"); ntfs.CreateHardLink(@"ALongFileName.txt", @"DIR\SHORTLNK.TXT"); Assert.Equal(3, ntfs.GetHardLinkCount("ALongFileName.txt")); // If we enumerate short names, then the initial long name results in two 'hardlinks' ntfs.NtfsOptions.HideDosFileNames = false; Assert.Equal(4, ntfs.GetHardLinkCount("ALongFileName.txt")); }
public void HasHardLink() { NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem(); using (Stream s = ntfs.OpenFile("ALongFileName.txt", FileMode.CreateNew)) { } Assert.False(ntfs.HasHardLinks("ALongFileName.txt")); ntfs.CreateHardLink("ALongFileName.txt", "AHardLink.TXT"); Assert.True(ntfs.HasHardLinks("ALongFileName.txt")); using (Stream s = ntfs.OpenFile("ALongFileName2.txt", FileMode.CreateNew)) { } // If we enumerate short names, then the initial long name results in two 'hardlinks' ntfs.NtfsOptions.HideDosFileNames = false; Assert.True(ntfs.HasHardLinks("ALongFileName2.txt")); }
public void ManyAttributes() { NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem(); using (Stream s = ntfs.OpenFile(@"file", FileMode.Create, FileAccess.ReadWrite)) { s.WriteByte(32); } for (int i = 0; i < 50; ++i) { ntfs.CreateHardLink("file", "hl" + i); } using (Stream s = ntfs.OpenFile("hl35", FileMode.Open, FileAccess.ReadWrite)) { Assert.Equal(32, s.ReadByte()); s.Position = 0; s.WriteByte(12); } using (Stream s = ntfs.OpenFile("hl5", FileMode.Open, FileAccess.ReadWrite)) { Assert.Equal(12, s.ReadByte()); } for (int i = 0; i < 50; ++i) { ntfs.DeleteFile("hl" + i); } Assert.Equal(1, ntfs.GetFiles(@"\").Length); ntfs.DeleteFile("file"); Assert.Equal(0, ntfs.GetFiles(@"\").Length); }
private void CopyFiles(NtfsFileSystem sourceNtfs, NtfsFileSystem destNtfs, string path, bool subs) { if (subs) { foreach (var dir in sourceNtfs.GetDirectories(path)) { if (!IsExcluded(dir)) { int hardLinksRemaining = sourceNtfs.GetHardLinkCount(dir) - 1; bool newDir = false; long sourceFileId = sourceNtfs.GetFileId(dir); string refPath; if (_uniqueFiles.TryGetValue(sourceFileId, out refPath)) { // If this is another name for a known dir, recreate the hard link destNtfs.CreateHardLink(refPath, dir); } else { destNtfs.CreateDirectory(dir); newDir = true; FileAttributes fileAttrs = sourceNtfs.GetAttributes(dir); if ((fileAttrs & FileAttributes.ReparsePoint) != 0) { destNtfs.SetReparsePoint(dir, sourceNtfs.GetReparsePoint(dir)); } destNtfs.SetAttributes(dir, fileAttrs); destNtfs.SetSecurity(dir, sourceNtfs.GetSecurity(dir)); } // File may have a short name string shortName = sourceNtfs.GetShortName(dir); if (!string.IsNullOrEmpty(shortName) && shortName != dir) { destNtfs.SetShortName(dir, shortName); --hardLinksRemaining; } if (newDir) { if (hardLinksRemaining > 0) { _uniqueFiles[sourceFileId] = dir; } CopyFiles(sourceNtfs, destNtfs, dir, subs); } // Set standard information last (includes modification timestamps) destNtfs.SetFileStandardInformation(dir, sourceNtfs.GetFileStandardInformation(dir)); } } } foreach (var file in sourceNtfs.GetFiles(path)) { Console.WriteLine(file); int hardLinksRemaining = sourceNtfs.GetHardLinkCount(file) - 1; long sourceFileId = sourceNtfs.GetFileId(file); string refPath; if (_uniqueFiles.TryGetValue(sourceFileId, out refPath)) { // If this is another name for a known file, recreate the hard link destNtfs.CreateHardLink(refPath, file); } else { CopyFile(sourceNtfs, destNtfs, file); if (hardLinksRemaining > 0) { _uniqueFiles[sourceFileId] = file; } } // File may have a short name string shortName = sourceNtfs.GetShortName(file); if (!string.IsNullOrEmpty(shortName) && shortName != file) { destNtfs.SetShortName(file, shortName); } } }
protected override void NewItem(string path, string itemTypeName, object newItemValue) { string parentPath = GetParentPath(path, null); if (string.IsNullOrEmpty(itemTypeName)) { WriteError(new ErrorRecord( new InvalidOperationException("No type specified. Specify \"file\" or \"directory\" as the type."), "NoTypeForNewItem", ErrorCategory.InvalidArgument, itemTypeName)); return; } string itemTypeUpper = itemTypeName.ToUpperInvariant(); object obj = FindItemByPath(Utilities.NormalizePath(parentPath), true, false); if (obj is DiscDirectoryInfo) { DiscDirectoryInfo dirInfo = (DiscDirectoryInfo)obj; if (itemTypeUpper == "FILE") { using (dirInfo.FileSystem.OpenFile(Path.Combine(dirInfo.FullName, GetChildName(path)), FileMode.Create)) { } } else if (itemTypeUpper == "DIRECTORY") { dirInfo.FileSystem.CreateDirectory(Path.Combine(dirInfo.FullName, GetChildName(path))); } else if (itemTypeUpper == "HARDLINK") { NtfsFileSystem ntfs = dirInfo.FileSystem as NtfsFileSystem; if (ntfs != null) { NewHardLinkDynamicParameters hlParams = (NewHardLinkDynamicParameters)DynamicParameters; var srcItems = SessionState.InvokeProvider.Item.Get(hlParams.SourcePath); if (srcItems.Count != 1) { WriteError(new ErrorRecord( new InvalidOperationException("The type is unknown for this provider. Only \"file\" and \"directory\" can be specified."), "UnknownTypeForNewItem", ErrorCategory.InvalidArgument, itemTypeName)); return; } DiscFileSystemInfo srcFsi = srcItems[0].BaseObject as DiscFileSystemInfo; ntfs.CreateHardLink(srcFsi.FullName, Path.Combine(dirInfo.FullName, GetChildName(path))); } } else { WriteError(new ErrorRecord( new InvalidOperationException("The type is unknown for this provider. Only \"file\" and \"directory\" can be specified."), "UnknownTypeForNewItem", ErrorCategory.InvalidArgument, itemTypeName)); return; } } else { WriteError(new ErrorRecord( new InvalidOperationException("Cannot create items in an object of this type: " + (obj != null ? obj.GetType() : null)), "UnknownObjectTypeForNewItemParent", ErrorCategory.InvalidOperation, obj)); return; } }