public void ShortNames() { NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem(); // Check we can find a short name in the same directory using (Stream s = ntfs.OpenFile("ALongFileName.txt", FileMode.CreateNew)) {} ntfs.SetShortName("ALongFileName.txt", "ALONG~01.TXT"); Assert.Equal("ALONG~01.TXT", ntfs.GetShortName("ALongFileName.txt")); Assert.True(ntfs.FileExists("ALONG~01.TXT")); // Check path handling ntfs.CreateDirectory("DIR"); using (Stream s = ntfs.OpenFile(@"DIR\ALongFileName2.txt", FileMode.CreateNew)) { } ntfs.SetShortName(@"DIR\ALongFileName2.txt", "ALONG~02.TXT"); Assert.Equal("ALONG~02.TXT", ntfs.GetShortName(@"DIR\ALongFileName2.txt")); Assert.True(ntfs.FileExists(@"DIR\ALONG~02.TXT")); // Check we can open a file by the short name using (Stream s = ntfs.OpenFile("ALONG~01.TXT", FileMode.Open)) { } // Delete the long name, and make sure the file is gone ntfs.DeleteFile("ALONG~01.TXT"); Assert.False(ntfs.FileExists("ALONG~01.TXT")); // Delete the short name, and make sure the file is gone ntfs.DeleteFile(@"DIR\ALONG~02.TXT"); Assert.False(ntfs.FileExists(@"DIR\ALongFileName2.txt")); }
public void Fragmented() { NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem(); ntfs.CreateDirectory(@"DIR"); byte[] buffer = new byte[4096]; for (int i = 0; i < 2500; ++i) { using (var stream = ntfs.OpenFile(@"DIR\file" + i + ".bin", FileMode.Create, FileAccess.ReadWrite)) { stream.Write(buffer, 0, buffer.Length); } using (var stream = ntfs.OpenFile(@"DIR\" + i + ".bin", FileMode.Create, FileAccess.ReadWrite)) { stream.Write(buffer, 0, buffer.Length); } } for (int i = 0; i < 2500; ++i) { ntfs.DeleteFile(@"DIR\file" + i + ".bin"); } // Create fragmented file (lots of small writes) using (var stream = ntfs.OpenFile(@"DIR\fragmented.bin", FileMode.Create, FileAccess.ReadWrite)) { for (int i = 0; i < 2500; ++i) { stream.Write(buffer, 0, buffer.Length); } } // Try a large write byte[] largeWriteBuffer = new byte[200 * 1024]; for (int i = 0; i < largeWriteBuffer.Length / 4096; ++i) { largeWriteBuffer[i * 4096] = (byte)i; } using (var stream = ntfs.OpenFile(@"DIR\fragmented.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { stream.Position = stream.Length - largeWriteBuffer.Length; stream.Write(largeWriteBuffer, 0, largeWriteBuffer.Length); } // And a large read byte[] largeReadBuffer = new byte[largeWriteBuffer.Length]; using (var stream = ntfs.OpenFile(@"DIR\fragmented.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { stream.Position = stream.Length - largeReadBuffer.Length; stream.Read(largeReadBuffer, 0, largeReadBuffer.Length); } Assert.Equal(largeWriteBuffer, largeReadBuffer); }
public void DeleteAlternateDataStreams() { NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem(); ntfs.OpenFile("AFILE.TXT", FileMode.Create).Dispose(); ntfs.OpenFile("AFILE.TXT:ALTSTREAM", FileMode.Create).Dispose(); Assert.Equal(1, ntfs.GetAlternateDataStreams("AFILE.TXT").Length); ntfs.DeleteFile("AFILE.TXT:ALTSTREAM"); Assert.Equal(1, ntfs.GetFileSystemEntries("").Length); Assert.Equal(0, ntfs.GetAlternateDataStreams("AFILE.TXT").Length); }
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); }
protected override void DoRun() { if (!IsAdministrator()) { Console.WriteLine("\nThis utility must be run as an administrator!\n"); Environment.Exit(1); } DiskImageBuilder builder = DiskImageBuilder.GetBuilder(OutputDiskType, OutputDiskVariant); builder.GenericAdapterType = AdapterType; string[] sourceVolume = _volumes.Values; uint diskNumber; List <CloneVolume> cloneVolumes = GatherVolumes(sourceVolume, out diskNumber); if (!Quiet) { Console.WriteLine("Inspecting Disk..."); } // Construct a stream representing the contents of the cloned disk. BiosPartitionedDiskBuilder contentBuilder; Geometry biosGeometry; Geometry ideGeometry; long capacity; using (Disk disk = new Disk(diskNumber)) { contentBuilder = new BiosPartitionedDiskBuilder(disk); biosGeometry = disk.BiosGeometry; ideGeometry = disk.Geometry; capacity = disk.Capacity; } // Preserve the IDE (aka Physical) geometry builder.Geometry = ideGeometry; // Translate the BIOS (aka Logical) geometry GeometryTranslation translation = _translation.EnumValue; if (builder.PreservesBiosGeometry && translation == GeometryTranslation.Auto) { // If the new format preserves BIOS geometry, then take no action if asked for 'auto' builder.BiosGeometry = biosGeometry; translation = GeometryTranslation.None; } else { builder.BiosGeometry = ideGeometry.TranslateToBios(0, translation); } if (translation != GeometryTranslation.None) { contentBuilder.UpdateBiosGeometry(builder.BiosGeometry); } IVssBackupComponents backupCmpnts; int status; if (Marshal.SizeOf(typeof(IntPtr)) == 4) { status = NativeMethods.CreateVssBackupComponents(out backupCmpnts); } else { status = NativeMethods.CreateVssBackupComponents64(out backupCmpnts); } Guid snapshotSetId = CreateSnapshotSet(cloneVolumes, backupCmpnts); if (!Quiet) { Console.Write("Copying Disk..."); } foreach (var sv in cloneVolumes) { Volume sourceVol = new Volume(sv.SnapshotProperties.SnapshotDeviceObject, sv.SourceExtent.ExtentLength); SnapshotStream rawVolStream = new SnapshotStream(sourceVol.Content, Ownership.None); rawVolStream.Snapshot(); byte[] volBitmap; int clusterSize; using (NtfsFileSystem ntfs = new NtfsFileSystem(rawVolStream)) { ntfs.NtfsOptions.HideSystemFiles = false; ntfs.NtfsOptions.HideHiddenFiles = false; ntfs.NtfsOptions.HideMetafiles = false; // Remove VSS snapshot files (can be very large) foreach (string filePath in ntfs.GetFiles(@"\System Volume Information", "*{3808876B-C176-4e48-B7AE-04046E6CC752}")) { ntfs.DeleteFile(filePath); } // Remove the page file if (ntfs.FileExists(@"\Pagefile.sys")) { ntfs.DeleteFile(@"\Pagefile.sys"); } // Remove the hibernation file if (ntfs.FileExists(@"\hiberfil.sys")) { ntfs.DeleteFile(@"\hiberfil.sys"); } using (Stream bitmapStream = ntfs.OpenFile(@"$Bitmap", FileMode.Open)) { volBitmap = new byte[bitmapStream.Length]; int totalRead = 0; int numRead = bitmapStream.Read(volBitmap, 0, volBitmap.Length - totalRead); while (numRead > 0) { totalRead += numRead; numRead = bitmapStream.Read(volBitmap, totalRead, volBitmap.Length - totalRead); } } clusterSize = (int)ntfs.ClusterSize; if (translation != GeometryTranslation.None) { ntfs.UpdateBiosGeometry(builder.BiosGeometry); } } List <StreamExtent> extents = new List <StreamExtent>(BitmapToRanges(volBitmap, clusterSize)); SparseStream partSourceStream = SparseStream.FromStream(rawVolStream, Ownership.None, extents); for (int i = 0; i < contentBuilder.PartitionTable.Partitions.Count; ++i) { var part = contentBuilder.PartitionTable.Partitions[i]; if (part.FirstSector * 512 == sv.SourceExtent.StartingOffset) { contentBuilder.SetPartitionContent(i, partSourceStream); } } } SparseStream contentStream = contentBuilder.Build(); // Write out the disk images string dir = Path.GetDirectoryName(_destDisk.Value); string file = Path.GetFileNameWithoutExtension(_destDisk.Value); builder.Content = contentStream; DiskImageFileSpecification[] fileSpecs = builder.Build(file); for (int i = 0; i < fileSpecs.Length; ++i) { // Construct the destination file path from the directory of the primary file. string outputPath = Path.Combine(dir, fileSpecs[i].Name); // Force the primary file to the be one from the command-line. if (i == 0) { outputPath = _destDisk.Value; } using (SparseStream vhdStream = fileSpecs[i].OpenStream()) using (FileStream fs = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite)) { StreamPump pump = new StreamPump() { InputStream = vhdStream, OutputStream = fs, }; long totalBytes = 0; foreach (var se in vhdStream.Extents) { totalBytes += se.Length; } if (!Quiet) { Console.WriteLine(); DateTime now = DateTime.Now; pump.ProgressEvent += (o, e) => { ShowProgress(fileSpecs[i].Name, totalBytes, now, o, e); }; } pump.Run(); if (!Quiet) { Console.WriteLine(); } } } // Complete - tidy up CallAsyncMethod(backupCmpnts.BackupComplete); long numDeleteFailed; Guid deleteFailed; backupCmpnts.DeleteSnapshots(snapshotSetId, 2 /*VSS_OBJECT_SNAPSHOT_SET*/, true, out numDeleteFailed, out deleteFailed); Marshal.ReleaseComObject(backupCmpnts); }