예제 #1
0
        void ReCreateMbr(int x)
        {
            deviceHandles[x] = NativeDiskWrapper.GetHandleOnDevice(deviceIDs[x], NativeDisk.GENERIC_READ | NativeDisk.GENERIC_WRITE);
            var driveLayout = NativeDiskWrapper.DiskGetDriveLayoutEx(deviceHandles[x]);

            NativeDiskWrapper.DiskCreateDiskMBR(deviceHandles[x], 0xA5A5A5);
            NativeDiskWrapper.DiskUpdateProperties(deviceHandles[x]);
            driveLayout = NativeDiskWrapper.DiskGetDriveLayoutEx(deviceHandles[x]);
            driveLayout.PartitionEntry[0].PartitionNumber   = 1;
            driveLayout.PartitionEntry[0].StartingOffset    = 4 * 512;
            driveLayout.PartitionEntry[0].PartitionLength   = (long)GetDeviceLength(deviceHandles[x]) - driveLayout.PartitionEntry[0].StartingOffset;
            driveLayout.PartitionEntry[0].RewritePartition  = true;
            driveLayout.PartitionEntry[0].Mbr.PartitionType = (byte)PARTITION_TYPE.PARTITION_FAT32;
            NativeDiskWrapper.DiskSetDriveLayoutEx(deviceHandles[x], driveLayout);
            NativeDiskWrapper.DiskUpdateProperties(deviceHandles[x]);
            driveLayout = NativeDiskWrapper.DiskGetDriveLayoutEx(deviceHandles[x]);
        }
예제 #2
0
        public override InitOperationResult InitReadImageFromDevice(string imagePath, bool skipUnallocated)
        {
            ulong fileSize;
            ulong spaceNeeded;

            availibleSectors = 0;
            sectorSize       = 0;
            numSectors       = 0;
            ulong freeSpace = 0;

            Dispose();

            volumeHandles[0] = NativeDiskWrapper.GetHandleOnVolume(volumeIDs[0], NativeDisk.GENERIC_WRITE);
            NativeDiskWrapper.GetLockOnVolume(volumeHandles[0]);
            NativeDiskWrapper.UnmountVolume(volumeHandles[0]);

            fileHandle       = NativeDiskWrapper.GetHandleOnFile(imagePath, NativeDisk.GENERIC_WRITE | NativeDisk.GENERIC_READ);
            deviceHandles[0] = NativeDiskWrapper.GetHandleOnDevice(deviceIDs[0], NativeDisk.GENERIC_READ);

            numSectors = NativeDiskWrapper.GetNumberOfSectors(deviceHandles[0], ref sectorSize);

            _imagePath = imagePath;

            if (skipUnallocated)
            {
                numSectors = GetLastUsedPartition();
            }

            fileSize = NativeDiskWrapper.GetFilesizeInSectors(fileHandle, sectorSize);
            if (fileSize >= numSectors)
            {
                spaceNeeded = 0;
            }
            else
            {
                spaceNeeded = (numSectors - fileSize) * sectorSize;
            }

            if (!NativeDiskWrapper.SpaceAvailible(imagePath.Substring(0, 3), spaceNeeded, out freeSpace))
            {
                return(new InitOperationResult(false, spaceNeeded, freeSpace, false));
            }

            return(new InitOperationResult(true, spaceNeeded, freeSpace, false));
        }
예제 #3
0
        public static ulong GetDeviceLength(int deviceID)
        {
            ulong length = 0;

            IntPtr deviceHandle = NativeDiskWrapper.GetHandleOnDevice(deviceID, NativeDisk.GENERIC_READ);

            unsafe
            {
                int    returnLength = 0;
                IntPtr lengthPtr    = new IntPtr(&length);

                NativeDisk.DeviceIoControl(deviceHandle, NativeDisk.IOCTL_DISK_GET_LENGTH_INFO, IntPtr.Zero, 0, lengthPtr, sizeof(ulong), ref returnLength, IntPtr.Zero);
            }

            NativeDisk.CloseHandle(deviceHandle);

            return(length);
        }
예제 #4
0
        public override VerifyInitOperationResult InitVerifyImageAndDevice(string imagePath, bool skipUnallocated)
        {
            ulong fileSize;

            availibleSectors = 0;
            sectorSize       = 0;
            numSectors       = 0;

            Dispose();

            for (int i = 0; i < volumeHandles.Length; i++)
            {
                volumeHandles[i] = NativeDiskWrapper.GetHandleOnVolume(volumeIDs[i], NativeDisk.GENERIC_WRITE);
                NativeDiskWrapper.GetLockOnVolume(volumeHandles[i]);
                NativeDiskWrapper.UnmountVolume(volumeHandles[i]);
            }

            fileHandle = NativeDiskWrapper.GetHandleOnFile(imagePath, NativeDisk.GENERIC_READ);

            for (int i = 0; i < volumeHandles.Length; i++)
            {
                deviceHandles[i] = NativeDiskWrapper.GetHandleOnDevice(deviceIDs[i], NativeDisk.GENERIC_READ);
            }

            _imagePath = imagePath;

            numSectors = NativeDiskWrapper.GetNumberOfSectors(deviceHandles[0], ref sectorSize);

            if (skipUnallocated)
            {
                numSectors = GetLastUsedPartition();
            }
            else
            {
                for (int i = 0; i < deviceHandles.Length; i++)
                {
                    var sectors = NativeDiskWrapper.GetNumberOfSectors(deviceHandles[i], ref sectorSize);
                    if (sectors < numSectors)
                    {
                        numSectors = sectors;
                    }
                }
            }

            if (useEncryption)
            {
                int paddingSize = 16 - ((1 + password.Length) % 16);
                fileSize = NativeDiskWrapper.GetFilesizeInSectors(fileHandle, sectorSize, encryptionSignature.Length + 33 + password.Length + paddingSize);
            }
            else
            {
                fileSize = NativeDiskWrapper.GetFilesizeInSectors(fileHandle, sectorSize);
            }

            if (fileSize == numSectors)
            {
                return(new VerifyInitOperationResult(true, fileSize * sectorSize, numSectors * sectorSize));
            }
            else
            {
                return(new VerifyInitOperationResult(false, fileSize * sectorSize, numSectors * sectorSize));
            }
        }
예제 #5
0
        public override InitOperationResult InitWriteImageToDevice(string imagePath)
        {
            availibleSectors = 0;
            sectorSize       = 0;
            numSectors       = 0;
            int smallestDeviceIndex = 0;

            Dispose();

            for (int i = 0; i < volumeHandles.Length; i++)
            {
                volumeHandles[i] = NativeDiskWrapper.GetHandleOnVolume(volumeIDs[i], NativeDisk.GENERIC_WRITE);
                NativeDiskWrapper.GetLockOnVolume(volumeHandles[i]);
                NativeDiskWrapper.UnmountVolume(volumeHandles[i]);
            }

            fileHandle = NativeDiskWrapper.GetHandleOnFile(imagePath, NativeDisk.GENERIC_READ);

            for (int i = 0; i < volumeHandles.Length; i++)
            {
                deviceHandles[i] = NativeDiskWrapper.GetHandleOnDevice(deviceIDs[i], NativeDisk.GENERIC_WRITE | NativeDisk.GENERIC_READ);
            }

            availibleSectors = NativeDiskWrapper.GetNumberOfSectors(deviceHandles[0], ref sectorSize);

            for (int i = 1; i < deviceHandles.Length; i++)
            {
                var sectors = NativeDiskWrapper.GetNumberOfSectors(deviceHandles[i], ref sectorSize);

                if (sectors < availibleSectors)
                {
                    availibleSectors    = sectors;
                    smallestDeviceIndex = i;
                }
            }

            if (useEncryption)
            {
                int paddingSize = 16 - ((1 + password.Length) % 16);
                numSectors = NativeDiskWrapper.GetFilesizeInSectors(fileHandle, sectorSize, encryptionSignature.Length + 33 + password.Length + paddingSize);
            }
            else
            {
                numSectors = NativeDiskWrapper.GetFilesizeInSectors(fileHandle, sectorSize);
            }

            _imagePath = imagePath;

            if (numSectors > availibleSectors)
            {
                bool   dataFound     = false;
                ulong  i             = availibleSectors;
                ulong  nextChunkSize = 0;
                byte[] sectorData    = new byte[1024 * sectorSize];

                if (useEncryption)
                {
                    using (FileStream fs = new FileStream(new SafeFileHandle(fileHandle, false), FileAccess.Read))
                        using (RijndaelManaged rijndael = new RijndaelManaged())
                        {
                            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                            byte[] salt          = new byte[32];

                            fs.Read(salt, 0, encryptionSignature.Length);
                            fs.Read(salt, 0, salt.Length);

                            rijndael.KeySize   = 256;
                            rijndael.BlockSize = 128;

                            using (var key = new Rfc2898DeriveBytes(passwordBytes, salt, 1000))
                            {
                                rijndael.Key = key.GetBytes(rijndael.KeySize / 8);
                                rijndael.IV  = key.GetBytes(rijndael.BlockSize / 8);
                            }

                            rijndael.Padding = PaddingMode.Zeros;
                            rijndael.Mode    = CipherMode.CFB;

                            using (CryptoStream cs = new CryptoStream(fs, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
                            {
                                int passLen = cs.ReadByte();
                                cs.Read(sectorData, 0, passLen);

                                {
                                    while (i < numSectors && !dataFound)
                                    {
                                        nextChunkSize = ((numSectors - i) >= 1024) ? 1024 : (numSectors - i);
                                        int dataLength = cs.Read(sectorData, 0, (int)(nextChunkSize * sectorSize));

                                        for (int x = 0; x < dataLength; x++)
                                        {
                                            if (sectorData[x] != 0)
                                            {
                                                dataFound = true;
                                                break;
                                            }
                                        }

                                        i += nextChunkSize;
                                    }
                                }
                            }
                        }
                }
                else
                {
                    while (i < numSectors && !dataFound)
                    {
                        nextChunkSize = ((numSectors - i) >= 1024) ? 1024 : (numSectors - i);
                        int dataLength = NativeDiskWrapper.ReadSectorDataFromHandle(fileHandle, sectorData, i, nextChunkSize, sectorSize);

                        for (int x = 0; x < dataLength; x++)
                        {
                            if (sectorData[x] != 0)
                            {
                                dataFound = true;
                                break;
                            }
                        }

                        i += nextChunkSize;
                    }
                }

                return(new InitOperationResult(false, numSectors * sectorSize, availibleSectors * sectorSize, dataFound, DriveLetters[smallestDeviceIndex]));
            }

            return(new InitOperationResult(true, numSectors * sectorSize, availibleSectors * sectorSize, false));
        }
예제 #6
0
        public static DiskPartitionInfo GetDiskPartitionInfo(char driveLetter)
        {
            int    deviceID           = NativeDiskWrapper.CheckDriveType(string.Format(@"\\.\{0}:\", driveLetter));
            IntPtr deviceHandle       = NativeDiskWrapper.GetHandleOnDevice(deviceID, NativeDisk.GENERIC_READ);
            uint   partitionTableSize = 0;

            DiskPartitionInfo partitionsInfo = new DiskPartitionInfo();

            var partitionInfo = NativeDiskWrapper.GetDiskPartitionInfo(deviceHandle);

            partitionsInfo.DiskTotalSize = GetDeviceLength(deviceID);

            if (partitionInfo.PartitionStyle == PARTITION_STYLE.MasterBootRecord)
            {
                partitionsInfo.PartitionType = PartitionType.MBR;
                partitionTableSize           = 512;

                unsafe
                {
                    byte *data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, 0, 1, 512);

                    for (int i = 0; i < 4; i++)
                    {
                        ulong partitionStartSector = (uint)Marshal.ReadInt32(new IntPtr(data), 0x1BE + 8 + 16 * i);
                        ulong partitionNumSectors  = (uint)Marshal.ReadInt32(new IntPtr(data), 0x1BE + 12 + 16 * i);

                        if (partitionStartSector + partitionNumSectors > 0)
                        {
                            partitionsInfo.PartitionSizes.Add(partitionNumSectors * 512);
                        }
                    }
                }
            }
            else if (partitionInfo.PartitionStyle == PARTITION_STYLE.GuidPartitionTable)
            {
                partitionsInfo.PartitionType = PartitionType.GPT;
                partitionTableSize           = 17408;

                unsafe
                {
                    byte *data            = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, 0, 1, 512);
                    uint  gptHeaderOffset = (uint)Marshal.ReadInt32(new IntPtr(data), 0x1C6);
                    data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, gptHeaderOffset, 1, 512);
                    ulong partitionTableSector = (ulong)Marshal.ReadInt64(new IntPtr(data), 0x48);
                    uint  noOfPartitionEntries = (uint)Marshal.ReadInt32(new IntPtr(data), 0x50);
                    uint  sizeOfPartitionEntry = (uint)Marshal.ReadInt32(new IntPtr(data), 0x54);

                    data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, partitionTableSector, (512 / sizeOfPartitionEntry) * noOfPartitionEntries, 512);

                    for (int i = 0; i < noOfPartitionEntries; i++)
                    {
                        ulong partitionStartSector = (ulong)Marshal.ReadInt64(new IntPtr(data), (int)(0x20 + sizeOfPartitionEntry * i));
                        ulong partitionNumSectors  = (ulong)Marshal.ReadInt64(new IntPtr(data), (int)(0x28 + sizeOfPartitionEntry * i));

                        if (partitionStartSector + partitionNumSectors > 0)
                        {
                            partitionsInfo.PartitionSizes.Add(partitionNumSectors * 512);
                        }
                    }
                }
            }
            else
            {
                partitionsInfo.PartitionType = PartitionType.RAW;
            }

            NativeDisk.CloseHandle(deviceHandle);

            partitionsInfo.UnallocatedSize = partitionsInfo.DiskTotalSize - (partitionsInfo.PartitionSizes.Sum() + partitionTableSize);

            return(partitionsInfo);
        }