private byte[] ExtractFileFromVHD(string filename, string referenceVHD) { byte[] file = null; using (VirtualDisk vhdx = DiscUtils.Vhd.Disk.OpenDisk(referenceVHD, FileAccess.Read)) { NtfsFileSystem vhdbNtfs = new NtfsFileSystem(vhdx.Partitions[0].Open()); using (Stream bootStream = vhdbNtfs.OpenFile(filename, FileMode.Open, FileAccess.Read)) { file = new byte[bootStream.Length]; int totalRead = 0; while (totalRead < file.Length) { totalRead += bootStream.Read(file, totalRead, file.Length - totalRead); } } } return file; }
public NtfsFileStream(NtfsFileSystem fileSystem, DirectoryEntry entry, AttributeType attrType, string attrName, FileAccess access) { _entry = entry; _file = fileSystem.GetFile(entry.Reference); _baseStream = _file.OpenStream(attrType, attrName, access); }
IEnumerable <DiscUtils.DiscFileInfo> IterateFilesystem(int partitionNumber) { IEnumerable <DiscUtils.DiscFileInfo> IterateSubdir(DiscUtils.DiscDirectoryInfo subdir) { foreach (var dir in subdir.GetDirectories()) { foreach (var subfile in IterateSubdir(dir)) { yield return(subfile); } } var files = subdir.GetFiles(); foreach (var f in files) { yield return(f); } } PartitionTable disk = OpenDisk(); if (disk == null) { Debug.WriteLine("IterateFilesystem: Failed to open disk"); yield break; } else if (disk.Partitions.Count - 1 < partitionNumber) { Debug.WriteLine($"IterateFilesystem: Partition {partitionNumber} does not exist"); yield break; } using (var fsStream = disk.Partitions[partitionNumber].Open()) { var partitionStream = GetPatchedNtfsPartitionStream(fsStream); NtfsFileSystem fs = new DiscUtils.Ntfs.NtfsFileSystem(partitionStream); foreach (var file in IterateSubdir(fs.Root)) { yield return(file); } fs.Dispose(); partitionStream.Dispose(); } }
private void FileCopy(iSCSI iscsi, DiscDirectoryInfo[] DirInfos, WimFileSystem w, NtfsFileSystem ntfs) { foreach (DiscDirectoryInfo dir in DirInfos) { if (IsExcluded(dir.FullName)) { log.InfoFormat("Directory Skip {0}", dir.FullName); continue; } FileAttributes attr = dir.Attributes; if ((dir.Attributes & FileAttributes.ReparsePoint) == 0) { ntfs.CreateDirectory(dir.FullName); if ((attr & FileAttributes.Temporary) == FileAttributes.Temporary) attr = attr & ~FileAttributes.Temporary; if ((attr & FileAttributes.Offline) == FileAttributes.Offline) attr = attr & ~FileAttributes.Offline; ntfs.SetAttributes(dir.FullName, attr); FileCopy(iscsi, dir.GetDirectories(), w, ntfs); FileCopy(iscsi, dir.GetFiles(), w, ntfs); } else { traceLog.InfoFormat("Directory ReparsePoint {0}", dir.FullName); ReparsePoint rp = w.GetReparsePoint(dir.FullName); ntfs.CreateDirectory(dir.FullName); ntfs.SetReparsePoint(dir.FullName, rp); } } }
public void Format_SmallDisk() { long size = 8 * 1024 * 1024; SparseMemoryStream partStream = new SparseMemoryStream(); //VirtualDisk disk = Vhd.Disk.InitializeDynamic(partStream, Ownership.Dispose, size); NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512); NtfsFileSystem ntfs = new NtfsFileSystem(partStream); ntfs.Dump(TextWriter.Null, ""); }
public void Format_LargeDisk() { long size = 1024L * 1024 * 1024L * 1024; // 1 TB SparseMemoryStream partStream = new SparseMemoryStream(); NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512); NtfsFileSystem ntfs = new NtfsFileSystem(partStream); ntfs.Dump(TextWriter.Null, ""); }
private void DoCheck() { _context.RawStream.Position = 0; byte[] bytes = Utilities.ReadFully(_context.RawStream, 512); _context.BiosParameterBlock = BiosParameterBlock.FromBytes(bytes, 0); //----------------------------------------------------------------------- // MASTER FILE TABLE // // Bootstrap the Master File Table _context.Mft = new MasterFileTable(_context); File mftFile = new File(_context, _context.Mft.GetBootstrapRecord()); // Verify basic MFT records before initializing the Master File Table PreVerifyMft(mftFile); _context.Mft.Initialize(mftFile); // Now the MFT is up and running, do more detailed analysis of it's contents - double-accounted clusters, etc VerifyMft(); _context.Mft.Dump(_report, "INFO: "); //----------------------------------------------------------------------- // INDEXES // // Need UpperCase in order to verify some indexes (i.e. directories). File ucFile = new File(_context, _context.Mft.GetRecord(MasterFileTable.UpCaseIndex, false)); _context.UpperCase = new UpperCase(ucFile); SelfCheckIndexes(); //----------------------------------------------------------------------- // DIRECTORIES // VerifyDirectories(); //----------------------------------------------------------------------- // WELL KNOWN FILES // VerifyWellKnownFilesExist(); //----------------------------------------------------------------------- // OBJECT IDS // VerifyObjectIds(); //----------------------------------------------------------------------- // FINISHED // // Temporary... using (NtfsFileSystem fs = new NtfsFileSystem(_context.RawStream)) { if ((_reportLevels & ReportLevels.Information) != 0) { ReportDump(fs); } } }
private void CopyFile(NtfsFileSystem sourceNtfs, NtfsFileSystem destNtfs, string path) { if (IsExcluded(path)) { return; } using (Stream s = sourceNtfs.OpenFile(path, FileMode.Open, FileAccess.Read)) using (Stream d = destNtfs.OpenFile(path, FileMode.Create, FileAccess.ReadWrite)) { d.SetLength(s.Length); int numRead = s.Read(s_copyBuffer, 0, s_copyBuffer.Length); while (numRead > 0) { d.Write(s_copyBuffer, 0, numRead); numRead = s.Read(s_copyBuffer, 0, s_copyBuffer.Length); } } destNtfs.SetSecurity(path, sourceNtfs.GetSecurity(path)); destNtfs.SetFileStandardInformation(path, sourceNtfs.GetFileStandardInformation(path)); }
protected override void DoRun() { VolumeManager volMgr = new VolumeManager(); foreach (string disk in _diskFiles.Values) { volMgr.AddDisk(VirtualDisk.OpenDisk(disk, FileAccess.Read, UserName, Password)); } Stream partitionStream = null; if (!string.IsNullOrEmpty(VolumeId)) { partitionStream = volMgr.GetVolume(VolumeId).Open(); } else if (Partition >= 0) { partitionStream = volMgr.GetPhysicalVolumes()[Partition].Open(); } else { partitionStream = volMgr.GetLogicalVolumes()[0].Open(); } SparseStream cacheStream = SparseStream.FromStream(partitionStream, Ownership.None); cacheStream = new BlockCacheStream(cacheStream, Ownership.None); NtfsFileSystem fs = new NtfsFileSystem(cacheStream); fs.NtfsOptions.HideHiddenFiles = !_showHidden.IsPresent; fs.NtfsOptions.HideSystemFiles = !_showSystem.IsPresent; fs.NtfsOptions.HideMetafiles = !_showMeta.IsPresent; fs.Dump(Console.Out, ""); }
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); }
public NtfsFileSystem Format(Stream stream) { _context = new NtfsContext(); _context.Options = new NtfsOptions(); _context.RawStream = stream; _context.AttributeDefinitions = new AttributeDefinitions(); string localAdminString = (ComputerAccount == null) ? "LA" : new SecurityIdentifier(WellKnownSidType.AccountAdministratorSid, ComputerAccount).ToString(); using (new NtfsTransaction()) { _clusterSize = 4096; _mftRecordSize = 1024; _indexBufferSize = 4096; long totalClusters = ((SectorCount - 1) * Sizes.Sector) / _clusterSize; // Allocate a minimum of 8KB for the boot loader, but allow for more int numBootClusters = Utilities.Ceil(Math.Max((int)(8 * Sizes.OneKiB), BootCode == null ? 0 : BootCode.Length), _clusterSize); // Place MFT mirror in the middle of the volume _mftMirrorCluster = totalClusters / 2; uint numMftMirrorClusters = 1; // The bitmap is also near the middle _bitmapCluster = _mftMirrorCluster + 13; int numBitmapClusters = (int)Utilities.Ceil((totalClusters / 8), _clusterSize); // The MFT bitmap goes 'near' the start - approx 10% in - but ensure we avoid the bootloader long mftBitmapCluster = Math.Max(3 + (totalClusters / 10), numBootClusters); int numMftBitmapClusters = 1; // The MFT follows it's bitmap _mftCluster = mftBitmapCluster + numMftBitmapClusters; int numMftClusters = 8; if (_mftCluster + numMftClusters > _mftMirrorCluster || _bitmapCluster + numBitmapClusters >= totalClusters) { throw new IOException("Unable to determine initial layout of NTFS metadata - disk may be too small"); } CreateBiosParameterBlock(stream, numBootClusters * _clusterSize); _context.Mft = new MasterFileTable(_context); File mftFile = _context.Mft.InitializeNew(_context, mftBitmapCluster, (ulong)numMftBitmapClusters, (long)_mftCluster, (ulong)numMftClusters); File bitmapFile = CreateFixedSystemFile(MasterFileTable.BitmapIndex, _bitmapCluster, (ulong)numBitmapClusters, true); _context.ClusterBitmap = new ClusterBitmap(bitmapFile); _context.ClusterBitmap.MarkAllocated(0, numBootClusters); _context.ClusterBitmap.MarkAllocated(_bitmapCluster, numBitmapClusters); _context.ClusterBitmap.MarkAllocated(mftBitmapCluster, numMftBitmapClusters); _context.ClusterBitmap.MarkAllocated(_mftCluster, numMftClusters); _context.ClusterBitmap.SetTotalClusters(totalClusters); bitmapFile.UpdateRecordInMft(); File mftMirrorFile = CreateFixedSystemFile(MasterFileTable.MftMirrorIndex, _mftMirrorCluster, numMftMirrorClusters, true); File logFile = CreateSystemFile(MasterFileTable.LogFileIndex); using (Stream s = logFile.OpenStream(AttributeType.Data, null, FileAccess.ReadWrite)) { s.SetLength(Math.Min(Math.Max(2 * Sizes.OneMiB, (totalClusters / 500) * (long)_clusterSize), 64 * Sizes.OneMiB)); byte[] buffer = new byte[1024 * 1024]; for (int i = 0; i < buffer.Length; ++i) { buffer[i] = 0xFF; } long totalWritten = 0; while (totalWritten < s.Length) { int toWrite = (int)Math.Min(s.Length - totalWritten, buffer.Length); s.Write(buffer, 0, toWrite); totalWritten += toWrite; } } File volumeFile = CreateSystemFile(MasterFileTable.VolumeIndex); NtfsStream volNameStream = volumeFile.CreateStream(AttributeType.VolumeName, null); volNameStream.SetContent(new VolumeName(Label ?? "New Volume")); NtfsStream volInfoStream = volumeFile.CreateStream(AttributeType.VolumeInformation, null); volInfoStream.SetContent(new VolumeInformation(3, 1, VolumeInformationFlags.None)); SetSecurityAttribute(volumeFile, "O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)"); volumeFile.UpdateRecordInMft(); _context.GetFileByIndex = delegate(long index) { return new File(_context, _context.Mft.GetRecord(index, false)); }; _context.AllocateFile = delegate(FileRecordFlags frf) { return new File(_context, _context.Mft.AllocateRecord(frf, false)); }; File attrDefFile = CreateSystemFile(MasterFileTable.AttrDefIndex); _context.AttributeDefinitions.WriteTo(attrDefFile); SetSecurityAttribute(attrDefFile, "O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"); attrDefFile.UpdateRecordInMft(); File bootFile = CreateFixedSystemFile(MasterFileTable.BootIndex, 0, (uint)numBootClusters, false); SetSecurityAttribute(bootFile, "O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"); bootFile.UpdateRecordInMft(); File badClusFile = CreateSystemFile(MasterFileTable.BadClusIndex); badClusFile.CreateStream(AttributeType.Data, "$Bad"); badClusFile.UpdateRecordInMft(); File secureFile = CreateSystemFile(MasterFileTable.SecureIndex, FileRecordFlags.HasViewIndex); secureFile.RemoveStream(secureFile.GetStream(AttributeType.Data, null)); _context.SecurityDescriptors = SecurityDescriptors.Initialize(secureFile); secureFile.UpdateRecordInMft(); File upcaseFile = CreateSystemFile(MasterFileTable.UpCaseIndex); _context.UpperCase = UpperCase.Initialize(upcaseFile); upcaseFile.UpdateRecordInMft(); File objIdFile = File.CreateNew(_context, FileRecordFlags.IsMetaFile | FileRecordFlags.HasViewIndex, FileAttributeFlags.None); objIdFile.RemoveStream(objIdFile.GetStream(AttributeType.Data, null)); objIdFile.CreateIndex("$O", (AttributeType)0, AttributeCollationRule.MultipleUnsignedLongs); objIdFile.UpdateRecordInMft(); File reparseFile = File.CreateNew(_context, FileRecordFlags.IsMetaFile | FileRecordFlags.HasViewIndex, FileAttributeFlags.None); reparseFile.CreateIndex("$R", (AttributeType)0, AttributeCollationRule.MultipleUnsignedLongs); reparseFile.UpdateRecordInMft(); File quotaFile = File.CreateNew(_context, FileRecordFlags.IsMetaFile | FileRecordFlags.HasViewIndex, FileAttributeFlags.None); Quotas.Initialize(quotaFile); Directory extendDir = CreateSystemDirectory(MasterFileTable.ExtendIndex); extendDir.AddEntry(objIdFile, "$ObjId", FileNameNamespace.Win32AndDos); extendDir.AddEntry(reparseFile, "$Reparse", FileNameNamespace.Win32AndDos); extendDir.AddEntry(quotaFile, "$Quota", FileNameNamespace.Win32AndDos); extendDir.UpdateRecordInMft(); Directory rootDir = CreateSystemDirectory(MasterFileTable.RootDirIndex); rootDir.AddEntry(mftFile, "$MFT", FileNameNamespace.Win32AndDos); rootDir.AddEntry(mftMirrorFile, "$MFTMirr", FileNameNamespace.Win32AndDos); rootDir.AddEntry(logFile, "$LogFile", FileNameNamespace.Win32AndDos); rootDir.AddEntry(volumeFile, "$Volume", FileNameNamespace.Win32AndDos); rootDir.AddEntry(attrDefFile, "$AttrDef", FileNameNamespace.Win32AndDos); rootDir.AddEntry(rootDir, ".", FileNameNamespace.Win32AndDos); rootDir.AddEntry(bitmapFile, "$Bitmap", FileNameNamespace.Win32AndDos); rootDir.AddEntry(bootFile, "$Boot", FileNameNamespace.Win32AndDos); rootDir.AddEntry(badClusFile, "$BadClus", FileNameNamespace.Win32AndDos); rootDir.AddEntry(secureFile, "$Secure", FileNameNamespace.Win32AndDos); rootDir.AddEntry(upcaseFile, "$UpCase", FileNameNamespace.Win32AndDos); rootDir.AddEntry(extendDir, "$Extend", FileNameNamespace.Win32AndDos); SetSecurityAttribute(rootDir, "O:" + localAdminString + "G:BUD:(A;OICI;FA;;;BA)(A;OICI;FA;;;SY)(A;OICIIO;GA;;;CO)(A;OICI;0x1200a9;;;BU)(A;CI;LC;;;BU)(A;CIIO;DC;;;BU)(A;;0x1200a9;;;WD)"); rootDir.UpdateRecordInMft(); // A number of records are effectively 'reserved' for (long i = MasterFileTable.ExtendIndex + 1; i <= 15; i++) { File f = CreateSystemFile(i); SetSecurityAttribute(f, "O:S-1-5-21-1708537768-746137067-1060284298-1003G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)"); f.UpdateRecordInMft(); } } // XP-style security permissions setup NtfsFileSystem ntfs = new NtfsFileSystem(stream); ntfs.SetSecurity(@"$MFT", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)")); ntfs.SetSecurity(@"$MFTMirr", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)")); ntfs.SetSecurity(@"$LogFile", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)")); ntfs.SetSecurity(@"$Bitmap", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)")); ntfs.SetSecurity(@"$BadClus", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)")); ntfs.SetSecurity(@"$UpCase", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)")); ntfs.SetSecurity(@"$Secure", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)")); ntfs.SetSecurity(@"$Extend", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)")); ntfs.SetSecurity(@"$Extend\$Quota", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)")); ntfs.SetSecurity(@"$Extend\$ObjId", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)")); ntfs.SetSecurity(@"$Extend\$Reparse", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)")); ntfs.CreateDirectory("System Volume Information"); ntfs.SetAttributes("System Volume Information", FileAttributes.Hidden | FileAttributes.System | FileAttributes.Directory); ntfs.SetSecurity("System Volume Information", new RawSecurityDescriptor("O:BAG:SYD:(A;OICI;FA;;;SY)")); using (Stream s = ntfs.OpenFile(@"System Volume Information\MountPointManagerRemoteDatabase", FileMode.Create)) { } ntfs.SetAttributes(@"System Volume Information\MountPointManagerRemoteDatabase", FileAttributes.Hidden | FileAttributes.System | FileAttributes.Archive); ntfs.SetSecurity(@"System Volume Information\MountPointManagerRemoteDatabase", new RawSecurityDescriptor("O:BAG:SYD:(A;;FA;;;SY)")); return ntfs; }
protected override void DoRun() { VolumeManager volMgr = new VolumeManager(); foreach (string disk in _diskFiles.Values) { volMgr.AddDisk(VirtualDisk.OpenDisk(disk, FileAccess.Read, UserName, Password)); } VolumeInfo volInfo = null; if (!string.IsNullOrEmpty(VolumeId)) { volInfo = volMgr.GetVolume(VolumeId); } else if (Partition >= 0) { volInfo = volMgr.GetPhysicalVolumes()[Partition]; } else { volInfo = volMgr.GetLogicalVolumes()[0]; } using (NtfsFileSystem fs = new NtfsFileSystem(volInfo.Open())) { MasterFileTable mft = fs.GetMasterFileTable(); if (_recoverFile.IsPresent) { MasterFileTableEntry entry = mft[long.Parse(_recoverFile.Value)]; IBuffer content = GetContent(entry); if (content == null) { Console.WriteLine("Sorry, unable to recover content"); Environment.Exit(1); } string outFile = _recoverFile.Value + "__recovered.bin"; if (File.Exists(outFile)) { Console.WriteLine("Sorry, the file already exists: " + outFile); Environment.Exit(1); } using (FileStream outFileStream = new FileStream(outFile, FileMode.CreateNew, FileAccess.Write)) { Pump(content, outFileStream); } Console.WriteLine("Possible file contents saved as: " + outFile); Console.WriteLine(); Console.WriteLine("Caution! It is rare for the file contents of deleted files to be intact - most"); Console.WriteLine("likely the contents recovered are corrupt as the space has been reused."); } else { foreach (var entry in mft.GetEntries(EntryStates.NotInUse)) { // Skip entries with no attributes, they've probably never been used. We're certainly // not going to manage to recover any useful data from them. if (entry.Attributes.Count == 0) continue; // Skip directories - any useful files inside will be found separately if ((entry.Flags & MasterFileTableEntryFlags.IsDirectory) != 0) continue; long size = GetSize(entry); string path = GetPath(mft, entry); if (!_showMeta.IsPresent && path.StartsWith(@"<root>\$Extend")) continue; if (!_showZeroSize.IsPresent && size == 0) continue; Console.WriteLine("Index: {0,-4} Size: {1,-8} Path: {2}", entry.Index, Utilities.ApproximateDiskSize(size), path); } } } }
protected override void DoRun() { if (DiskSize <= 0) { DisplayHelp(); return; } using (VirtualDisk sourceDisk = VirtualDisk.OpenDisk(_sourceFile.Value, FileAccess.Read, UserName, Password)) using (VirtualDisk destDisk = VirtualDisk.CreateDisk(OutputDiskType, OutputDiskVariant, _destFile.Value, DiskParameters, UserName, Password)) { if (destDisk is DiscUtils.Vhd.Disk) { ((DiscUtils.Vhd.Disk)destDisk).AutoCommitFooter = false; } // Copy the MBR from the source disk, and invent a new signature for this new disk destDisk.SetMasterBootRecord(sourceDisk.GetMasterBootRecord()); destDisk.Signature = new Random().Next(); SparseStream sourcePartStream = SparseStream.FromStream(sourceDisk.Partitions[0].Open(), Ownership.None); NtfsFileSystem sourceNtfs = new NtfsFileSystem(sourcePartStream); // Copy the OS boot code into memory, so we can apply it when formatting the new disk byte[] bootCode; using (Stream bootStream = sourceNtfs.OpenFile("$Boot", FileMode.Open, FileAccess.Read)) { bootCode = new byte[bootStream.Length]; int totalRead = 0; while (totalRead < bootCode.Length) { totalRead += bootStream.Read(bootCode, totalRead, bootCode.Length - totalRead); } } // Partition the new disk with a single NTFS partition BiosPartitionTable.Initialize(destDisk, WellKnownPartitionType.WindowsNtfs); VolumeManager volMgr = new VolumeManager(destDisk); string label = _labelSwitch.IsPresent ? _labelSwitch.Value : sourceNtfs.VolumeLabel; using (NtfsFileSystem destNtfs = NtfsFileSystem.Format(volMgr.GetLogicalVolumes()[0], label, bootCode)) { destNtfs.SetSecurity(@"\", sourceNtfs.GetSecurity(@"\")); destNtfs.NtfsOptions.ShortNameCreation = ShortFileNameOption.Disabled; sourceNtfs.NtfsOptions.HideHiddenFiles = false; sourceNtfs.NtfsOptions.HideSystemFiles = false; CopyFiles(sourceNtfs, destNtfs, @"\", true); if (destNtfs.FileExists(@"\boot\BCD")) { // Force all boot entries in the BCD to point to the newly created NTFS partition - does _not_ cope with // complex multi-volume / multi-boot scenarios at all. using (Stream bcdStream = destNtfs.OpenFile(@"\boot\BCD", FileMode.Open, FileAccess.ReadWrite)) { using (RegistryHive hive = new RegistryHive(bcdStream)) { Store store = new Store(hive.Root); foreach (var obj in store.Objects) { foreach (var elem in obj.Elements) { if (elem.Format == DiscUtils.BootConfig.ElementFormat.Device) { elem.Value = DiscUtils.BootConfig.ElementValue.ForDevice(elem.Value.ParentObject, volMgr.GetPhysicalVolumes()[0]); } } } } } } } } }
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); } } }
private void FileCopy(iSCSI iscsi, DiscFileInfo[] FileInfos, WimFileSystem w, NtfsFileSystem ntfs) { foreach (DiscFileInfo file in FileInfos) { if (IsExcluded(file.FullName)) { log.InfoFormat("File Skip {0}", file.FullName); continue; } FileAttributes attr = file.Attributes; if ((attr & FileAttributes.ReparsePoint) == 0) { using (Stream source = w.OpenFile(file.FullName, FileMode.Open, FileAccess.Read)) { using (Stream destin = ntfs.OpenFile(file.FullName, FileMode.Create, FileAccess.Write)) { iscsi.WimCopy(source, destin, Path.GetFileName(file.FullName), false, wimFileIndex++, wimFileCount); } } if ((attr & FileAttributes.Temporary) == FileAttributes.Temporary) attr = attr & ~FileAttributes.Temporary; if ((attr & FileAttributes.Offline) == FileAttributes.Offline) attr = attr & ~FileAttributes.Offline; ntfs.SetAttributes(file.FullName, attr); } else { traceLog.InfoFormat("Reparse Point: {0}", file.FullName); ReparsePoint rp = w.GetReparsePoint(file.FullName); ntfs.SetReparsePoint(file.FullName, rp); } } }
private void AddBootMgr(NtfsFileSystem ntfs, byte[] BootMgr) { if (!ntfs.FileExists(@"\bootmgr")) { using (Stream bcdStream = ntfs.OpenFile(@"\bootmgr", FileMode.CreateNew, FileAccess.ReadWrite)) { bcdStream.Write(BootMgr, 0, BootMgr.Length); } } }
private void AddBCD(NtfsFileSystem ntfs, byte[] BCD) { if (!ntfs.DirectoryExists(@"\boot")) { ntfs.CreateDirectory(@"\boot"); } if (!ntfs.FileExists(@"\boot\BCD")) { using (Stream bcdStream = ntfs.OpenFile(@"\boot\BCD", FileMode.CreateNew, FileAccess.ReadWrite)) { bcdStream.Write(BCD, 0, BCD.Length); } } }
private static void UpdateBiosGeometry(SparseStream contentStream, Geometry oldGeometry, Geometry newGeometry) { BiosPartitionTable partTable = new BiosPartitionTable(contentStream, oldGeometry); partTable.UpdateBiosGeometry(newGeometry); VolumeManager volMgr = new VolumeManager(contentStream); foreach (var volume in volMgr.GetLogicalVolumes()) { foreach (var fsInfo in FileSystemManager.DetectDefaultFileSystems(volume.Open())) { if (fsInfo.Name == "NTFS") { using (NtfsFileSystem fs = new NtfsFileSystem(volume.Open())) { fs.UpdateBiosGeometry(newGeometry); } } } } }
private void FixBCD(NtfsFileSystem ntfs, VolumeManager volMgr) { if (ntfs.FileExists(@"\boot\BCD")) { // Force all boot entries in the BCD to point to the newly created NTFS partition - does _not_ cope with // complex multi-volume / multi-boot scenarios at all. using (Stream bcdStream = ntfs.OpenFile(@"\boot\BCD", FileMode.Open, FileAccess.ReadWrite)) { using (RegistryHive hive = new RegistryHive(bcdStream)) { Store store = new Store(hive.Root); foreach (var obj in store.Objects) { foreach (var elem in obj.Elements) { if (elem.Format == DiscUtils.BootConfig.ElementFormat.Device) { elem.Value = DiscUtils.BootConfig.ElementValue.ForDevice(elem.Value.ParentObject, volMgr.GetPhysicalVolumes()[0]); } } } } } } }