public static TrueCryptResizeStatus ExtendVolumeAndFileSystem(Disk disk, byte[] password, long additionalNumberOfSectors) { Volume partition = VolumeSelectionHelper.GetLastPartition(disk); TrueCryptVolume volume; try { volume = new TrueCryptVolume(partition, password); } catch (InvalidDataException) { return(TrueCryptResizeStatus.InvalidDisk); } catch (NotSupportedException) { return(TrueCryptResizeStatus.UnsupportedFormatVersion); } if (volume.IsHiddenVolume) { return(TrueCryptResizeStatus.HiddenVolume); } NTFSVolume ntfsVolume; try { ntfsVolume = new NTFSVolume(volume); } catch (InvalidDataException) { return(TrueCryptResizeStatus.UnsupportedFileSystem); } catch (NotSupportedException) { return(TrueCryptResizeStatus.UnsupportedFileSystem); } TrueCryptResizeStatus status = ExtendVolume(disk, password, additionalNumberOfSectors); if (status == TrueCryptResizeStatus.Success) { // Reinitialize the partition / volume partition = VolumeSelectionHelper.GetLastPartition(disk); volume = new TrueCryptVolume(partition, password); ntfsVolume = new NTFSVolume(volume); long availableBytes = ntfsVolume.GetMaximumSizeToExtend(); long availableSectors = availableBytes / disk.BytesPerSector; ntfsVolume.Extend(availableSectors); return(TrueCryptResizeStatus.Success); } else { return(status); } }
private static void DeleteFiles(NTFSVolume volume, string directoryName, int count) { for (int index = 1; index <= count; index++) { string fileName = "File" + index.ToString("000000"); string filePath = "\\" + directoryName + "\\" + fileName; FileRecord fileRecord = volume.GetFileRecord(filePath); volume.DeleteFile(fileRecord); } }
private static void CreateFiles(NTFSVolume volume, string directoryName, int count) { FileRecord parentDirectoryRecord = volume.CreateFile(NTFSVolume.RootDirSegmentReference, directoryName, true); for (int index = 1; index <= count; index++) { string fileName = "File" + index.ToString("000000"); FileRecord fileRecord = volume.CreateFile(parentDirectoryRecord.BaseSegmentReference, fileName, false); } }
private static void TestCreateAndDeleteFiles(string path, long size, int count) { int bytesPerCluster = 512; while (bytesPerCluster <= 65536) { string volumeLabel = "CreateFilesTest_" + bytesPerCluster.ToString(); VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size); disk.ExclusiveLock(); Partition partition = NTFSFormatTests.CreatePrimaryPartition(disk); NTFSVolume volume = NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel); string directoryName = "Directory"; CreateFiles(volume, directoryName, count); disk.ReleaseLock(); VHDMountHelper.MountVHD(path); string driveName = MountHelper.WaitForDriveToMount(volumeLabel); if (driveName == null) { throw new Exception("Timeout waiting for volume to mount"); } bool isErrorFree = ChkdskHelper.Chkdsk(driveName); if (!isErrorFree) { throw new InvalidDataException("CHKDSK reported errors"); } if (count != Directory.GetFiles(driveName + directoryName).Length) { throw new InvalidDataException("Test failed"); } VHDMountHelper.UnmountVHD(path); disk.ExclusiveLock(); volume = new NTFSVolume(partition); DeleteFiles(volume, directoryName, count); disk.ReleaseLock(); VHDMountHelper.MountVHD(path); isErrorFree = ChkdskHelper.Chkdsk(driveName); if (!isErrorFree) { throw new InvalidDataException("CHKDSK reported errors"); } if (Directory.GetFiles(driveName + directoryName).Length > 0) { throw new InvalidDataException("Test failed"); } VHDMountHelper.UnmountVHD(path); File.Delete(path); bytesPerCluster = bytesPerCluster * 2; } }
private void Init_Volume() { if (Vol == null) { if (_LastJournal.NextUsn != 0) { Vol = new NTFSVolume(SourcePath.Substring(0, 1), _LastJournal); } else { Vol = new NTFSVolume(SourcePath.Substring(0, 1)); } } }
private static void TestMove(string path, long size) { int bytesPerCluster = 512; while (bytesPerCluster <= 65536) { string volumeLabel = "MoveTest_" + bytesPerCluster.ToString(); VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size); disk.ExclusiveLock(); Partition partition = NTFSFormatTests.CreatePrimaryPartition(disk); NTFSVolume volume = NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel); string directory1Name = "Directory1"; string directory2Name = "Directory2"; FileRecord directory1Record = volume.CreateFile(NTFSVolume.RootDirSegmentReference, directory1Name, true); FileRecord directory2Record = volume.CreateFile(NTFSVolume.RootDirSegmentReference, directory2Name, true); string fileNameBefore = "Test1.txt"; string fileNameAfter = "Test2.txt"; FileRecord fileRecord = volume.CreateFile(directory1Record.BaseSegmentReference, fileNameBefore, false); NTFSFile file = new NTFSFile(volume, fileRecord); byte[] fileData = System.Text.Encoding.ASCII.GetBytes("Test"); file.Data.WriteBytes(0, fileData); volume.UpdateFileRecord(fileRecord); volume.MoveFile(fileRecord, directory2Record.BaseSegmentReference, fileNameAfter); disk.ReleaseLock(); VHDMountHelper.MountVHD(path); string driveName = MountHelper.WaitForDriveToMount(volumeLabel); if (driveName == null) { throw new Exception("Timeout waiting for volume to mount"); } bool isErrorFree = ChkdskHelper.Chkdsk(driveName); if (!isErrorFree) { throw new InvalidDataException("CHKDSK reported errors"); } byte[] bytesRead = File.ReadAllBytes(driveName + directory2Name + "\\" + fileNameAfter); if (!ByteUtils.AreByteArraysEqual(fileData, bytesRead)) { throw new InvalidDataException("Test failed"); } VHDMountHelper.UnmountVHD(path); File.Delete(path); bytesPerCluster = bytesPerCluster * 2; } }
public static void CreateVolumeWithPendingFileCreation(string path, long size, int bytesPerCluster, string volumeLabel, string fileName, byte[] fileData) { VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size); disk.ExclusiveLock(); Partition partition = NTFSFormatTests.CreatePrimaryPartition(disk); NTFSVolume volume = NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel); long segmentNumber = MasterFileTable.FirstUserSegmentNumber; FileNameRecord fileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, fileName, false, DateTime.Now); FileRecordSegment fileRecordSegment = CreateFileRecordSegment(segmentNumber, fileNameRecord, fileData); ulong dataStreamOffset = (ulong)(segmentNumber * volume.BytesPerFileRecordSegment); byte[] redoData = fileRecordSegment.GetBytes(volume.BytesPerFileRecordSegment, volume.MinorVersion, false); MftSegmentReference mftFileReference = new MftSegmentReference(0, 1); AttributeRecord mftDataRecord = volume.GetFileRecord(mftFileReference).GetAttributeRecord(AttributeType.Data, String.Empty); AttributeRecord mftBitmapRecord = volume.GetFileRecord(mftFileReference).GetAttributeRecord(AttributeType.Bitmap, String.Empty); uint transactionID = volume.LogClient.AllocateTransactionID(); volume.LogClient.WriteLogRecord(mftFileReference, mftDataRecord, dataStreamOffset, volume.BytesPerFileRecordSegment, NTFSLogOperation.InitializeFileRecordSegment, redoData, NTFSLogOperation.Noop, new byte[0], transactionID); long bitmapVCN = segmentNumber / (volume.BytesPerCluster * 8); int bitOffsetInCluster = (int)(segmentNumber % (volume.BytesPerCluster * 8)); BitmapRange bitmapRange = new BitmapRange((uint)bitOffsetInCluster, 1); ulong bitmapStreamOffset = (ulong)(bitmapVCN * volume.BytesPerCluster); volume.LogClient.WriteLogRecord(mftFileReference, mftBitmapRecord, bitmapStreamOffset, volume.BytesPerCluster, NTFSLogOperation.SetBitsInNonResidentBitMap, bitmapRange.GetBytes(), NTFSLogOperation.Noop, new byte[0], transactionID); FileRecord parentDirectoryRecord = volume.GetFileRecord(MasterFileTable.RootDirSegmentReference); IndexData parentDirectoryIndex = new IndexData(volume, parentDirectoryRecord, AttributeType.FileName); byte[] fileNameRecordBytes = fileNameRecord.GetBytes(); long leafRecordVBN = 0; IndexRecord leafRecord = parentDirectoryIndex.ReadIndexRecord(leafRecordVBN); ulong indexAllocationOffset = (ulong)parentDirectoryIndex.ConvertToDataOffset(leafRecordVBN); int insertIndex = CollationHelper.FindIndexForSortedInsert(leafRecord.IndexEntries, fileNameRecordBytes, CollationRule.Filename); int insertOffset = leafRecord.GetEntryOffset(volume.BytesPerIndexRecord, insertIndex); AttributeRecord rootDirIndexAllocation = volume.GetFileRecord(MasterFileTable.RootDirSegmentReference).GetAttributeRecord(AttributeType.IndexAllocation, IndexHelper.GetIndexName(AttributeType.FileName)); IndexEntry indexEntry = new IndexEntry(fileRecordSegment.SegmentReference, fileNameRecord.GetBytes()); volume.LogClient.WriteLogRecord(MasterFileTable.RootDirSegmentReference, rootDirIndexAllocation, indexAllocationOffset, volume.BytesPerIndexRecord, 0, insertOffset, NTFSLogOperation.AddIndexEntryToAllocationBuffer, indexEntry.GetBytes(), NTFSLogOperation.Noop, new byte[0], transactionID, false); volume.LogClient.WriteForgetTransactionRecord(transactionID, true); disk.ReleaseLock(); }
private void ListDiskDetails() { listDetails.Items.Clear(); AddRowToListDetails("Location", txtVolumeFile.Text); AddRowToListDetails("Container type", m_disk is VirtualHardDisk ? "VHD" : (m_disk is VirtualMachineDisk ? "VMDK" : "Raw Disk Image")); bool partitionTablePresent = m_partition is MBRPartition || m_partition is GPTPartition; AddRowToListDetails("Partition table present", partitionTablePresent ? "Yes" : "No"); AddRowToListDetails("Volume size", m_volume.Header.VolumeSize.ToString("#,0") + " bytes"); AddRowToListDetails("Volume type", m_volume.IsHiddenVolume ? "Hidden" : "Normal"); NTFSVolume ntfsVolume = null; try { ntfsVolume = new NTFSVolume(m_volume); } catch { } m_isSupportedFileSystem = (ntfsVolume != null); AddRowToListDetails("File system", (ntfsVolume != null) ? "NTFS" : "Unsupported"); }