Beispiel #1
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));
        }
Beispiel #2
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));
            }
        }
Beispiel #3
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));
        }