Beispiel #1
0
        /// <summary>Discover partitions</summary>
        internal unsafe void Discover()
        {
            VolumePartition fakePartition = new VolumePartition(_rawHandle, 0, 16);

            using (IPartitionClusterData rawData = fakePartition.ReadSectors(0)) {
                uint  minSector        = uint.MaxValue;
                uint  maxSector        = 0;
                byte *masterBootRecord = rawData.Data;
                if (0x55 != masterBootRecord[510])
                {
                    throw new ApplicationException();
                }
                if (0xAA != masterBootRecord[511])
                {
                    throw new ApplicationException();
                }
                // From http://thestarman.pcministry.com/asm/mbr/PartTables.htm
                // TODO : This is suitable for a Master Boot Record. Other types of boot records exist such
                // as the ExtendedBoot Record format.
                for (uint partitionIndex = 0; partitionIndex < 4; partitionIndex++)
                {
                    IntPtr partitionHandle;
                    if (!Natives.DuplicateHandle(new IntPtr(-1), _rawHandle,
                                                 new IntPtr(-1), out partitionHandle, 0 /* ignored because same access */,
                                                 false, 2 /*DUPLICATE_SAME_ACCESS*/))
                    {
                        throw new ApplicationException();
                    }
                    GenericPartition newPartition = GenericPartition.Create(partitionHandle, masterBootRecord, 446 + (16 * partitionIndex));
                    if (null == newPartition)
                    {
                        Natives.CloseHandle(partitionHandle);
                    }
                    else
                    {
                        // TODO : This algorithm doesn't let us witness the extra sectors after the last partition.
                        if (minSector > newPartition.StartSector)
                        {
                            minSector = newPartition.StartSector;
                        }
                        if (maxSector < (newPartition.StartSector + newPartition.SectorCount - 1))
                        {
                            maxSector = newPartition.StartSector + newPartition.SectorCount - 1;
                        }
                        _partitions.Add(newPartition);
                    }
                }
                Console.WriteLine("Found {0} partitions.", _partitions.Count);
                if (maxSector < minSector)
                {
                    throw new ApplicationException();
                }
                _volumePartition = new VolumePartition(_rawHandle, minSector, maxSector - minSector);
                return;
            }
        }
Beispiel #2
0
        public static unsafe int Main(string[] args)
        {
            InstallExceptionHandlers();
            using (PartitionDataDisposableBatch mainBatch = PartitionDataDisposableBatch.CreateNew()) {
                DisplayVersion();

                IntPtr       handle = IntPtr.Zero;
                int          nativeError;
                DiskGeometry geometry = new DiskGeometry();

                try {
                    handle = Natives.CreateFile2(@"\\.\PhysicalDrive0", 0x80000000 /* GENERIC_READ */,
                                                 0x02 /* FILE_SHARE_WRITE */, 3 /* OPEN_EXISTING */, IntPtr.Zero);
                    nativeError = Marshal.GetLastWin32Error();
                    if ((IntPtr.Zero == handle) || (0 != nativeError))
                    {
                        Console.WriteLine("Physical drive opening failed. Error 0x{0:X8}", nativeError);
                        return(1);
                    }
                    geometry.Acquire(handle);
                    _partitionManager = new PartitionManager(handle, geometry);
                    _partitionManager.Discover();
                    InterpretActivePartitions();
                    if (FeaturesContext.InvariantChecksEnabled)
                    {
                        NtfsMFTFileRecord.AssertMFTRecordCachingInvariance(_partitionManager);
                    }
                    // TODO : Configure TrackedPartitionIndex from command line arguments.
                    foreach (GenericPartition partition in _partitionManager.EnumeratePartitions())
                    {
                        if (!partition.ShouldCapture)
                        {
                            continue;
                        }
                        NtfsPartition ntfsPartition = partition as NtfsPartition;
                        NtfsPartition.Current = ntfsPartition;

                        // Basic functionnality tests. Don't remove.
                        //ntfsPartition.CountFiles();
                        //ntfsPartition.MonitorBadClusters();
                        //ntfsPartition.ReadBitmap();

                        // Dump bad clusters.
                        ntfsPartition.DumpBadClusters();

                        // Dump UsnJournal
                        PrototypeUsnJournal();
                        new NtfsUsnJournalReader(ntfsPartition).Run();

                        // Dump LogFile
                        // new NtfsLogFileReader(ntfsPartition).Run();

                        // Locate file.
                        // string fileName = @"TEMP\AsciiTes.txt";
                        string fileName = @"$Extend\$UsnJrnl";
                        NtfsIndexEntryHeader *fileDescriptor = ntfsPartition.FindFile(fileName);
                        if (null == fileDescriptor)
                        {
                            throw new System.IO.FileNotFoundException(fileName);
                        }
                        IPartitionClusterData fileData             = null;
                        NtfsFileRecord *      usnJournalFileRecord =
                            ntfsPartition.GetFileRecord(fileDescriptor->FileReference, ref fileData);
                        if ((null == usnJournalFileRecord) || (null == fileData))
                        {
                            throw new ApplicationException();
                        }
                        try {
                            usnJournalFileRecord->EnumerateRecordAttributes(
                                delegate(NtfsAttribute * attribute, Stream dataStream) {
                                attribute->Dump();
                                return(true);
                            });
                            // For debugging purpose.
                            // fileRecord->BinaryDumpContent();

                            // TODO : Do something with the file.
                        }
                        finally {
                            if (null != fileData)
                            {
                                fileData.Dispose();
                            }
                        }
                    }
                    return(0);
                }
                finally {
                    if (IntPtr.Zero == handle)
                    {
                        Natives.CloseHandle(handle);
                        handle = IntPtr.Zero;
                    }
                }
            }
        }