Beispiel #1
0
        public static char GetFirstDriveLetterFromMask(uint driveMask, bool checkDriveType = true)
        {
            for (int i = 0; driveMask != 0; i++)
            {
                if ((driveMask & 0x01) != 0)
                {
                    try
                    {
                        if (checkDriveType)
                        {
                            if (NativeDiskWrapper.CheckDriveType(string.Format(@"\\.\{0}:\", (char)('A' + i))) != 0)
                            {
                                return((char)('A' + i));
                            }
                        }
                        else
                        {
                            return((char)('A' + i));
                        }
                    }
                    catch { }
                }
                driveMask >>= 1;
            }

            return((char)0);
        }
Beispiel #2
0
        public static bool CheckZipFileEncryption(string path)
        {
            if (File.Exists(path))
            {
                using (FileStream fileStream = new FileStream(path, FileMode.Open))
                    using (ZipArchive archive = new ZipArchive(fileStream, ZipArchiveMode.Read))
                    {
                        ZipArchiveEntry zipEntry = null;
                        byte[]          buffer   = new byte[encryptionSignature.Length];

                        foreach (var entry in archive.Entries)
                        {
                            if (entry.FullName.EndsWith(".eimg"))
                            {
                                zipEntry = entry;
                                break;
                            }
                        }

                        if (zipEntry != null)
                        {
                            using (var zipEntryStream = zipEntry.Open())
                            {
                                zipEntryStream.Read(buffer, 0, encryptionSignature.Length);
                            }

                            if (NativeDiskWrapper.ByteArrayCompare(buffer, encryptionSignature))
                            {
                                return(true);
                            }
                        }
                    }
            }
            return(false);
        }
Beispiel #3
0
        public void Dispose()
        {
            for (int i = 0; i < volumeHandles.Length; i++)
            {
                if (volumeHandles[i] != IntPtr.Zero)
                {
                    try
                    {
                        NativeDiskWrapper.RemoveLockOnVolume(volumeHandles[i]);
                    }
                    catch { }
                    NativeDisk.CloseHandle(volumeHandles[i]);
                    volumeHandles[i] = IntPtr.Zero;
                }
            }

            if (fileHandle != IntPtr.Zero)
            {
                NativeDisk.CloseHandle(fileHandle);
                fileHandle = IntPtr.Zero;
            }

            for (int i = 0; i < deviceHandles.Length; i++)
            {
                if (deviceHandles[i] != IntPtr.Zero)
                {
                    NativeDisk.CloseHandle(deviceHandles[i]);
                    deviceHandles[i] = IntPtr.Zero;
                }
            }

            Utils.AllowComputerSleep();
        }
Beispiel #4
0
        public static bool CheckZipFilePassword(string path, string password)
        {
            using (FileStream fileStream = new FileStream(path, FileMode.Open))
                using (ZipArchive archive = new ZipArchive(fileStream, ZipArchiveMode.Read))
                {
                    Stream zipEntryStream = null;
                    byte[] passwordBytes  = Encoding.UTF8.GetBytes(password);
                    byte[] salt           = new byte[32];

                    foreach (var entry in archive.Entries)
                    {
                        if (entry.FullName.EndsWith(".eimg"))
                        {
                            zipEntryStream = entry.Open();
                            break;
                        }
                    }

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

                    using (RijndaelManaged rijndael = new RijndaelManaged())
                    {
                        rijndael.KeySize   = 256;
                        rijndael.BlockSize = 128;
                        using (var key = new Rfc2898DeriveBytes(passwordBytes, salt, Crypto_Iterations))
                        {
                            rijndael.Key = key.GetBytes(rijndael.KeySize / 8);
                            rijndael.IV  = key.GetBytes(rijndael.BlockSize / 8);
                        }
                        rijndael.Padding = PaddingMode.Zeros;
                        rijndael.Mode    = CipherMode.CFB;

                        try
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(zipEntryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
                            {
                                int passwordLength = cryptoStream.ReadByte();

                                if (passwordBytes.Length != passwordLength)
                                {
                                    return(false);
                                }

                                byte[] buff = new byte[passwordLength];
                                cryptoStream.Read(buff, 0, passwordLength);
                                return(NativeDiskWrapper.ByteArrayCompare(buff, passwordBytes));
                            }
                        }
                        catch (CryptographicException)
                        {
                            return(false);
                        }
                    }
                }
        }
Beispiel #5
0
        protected override bool ReadImageFromDeviceWorker(ulong sectorSize, ulong numSectors)
        {
            Stopwatch sw = new Stopwatch();
            Stopwatch percentStopwatch = new Stopwatch();

            byte[] deviceData            = new byte[1024 * sectorSize];
            ulong  totalBytesReaded      = 0;
            ulong  bytesReaded           = 0;
            ulong  bytesToRead           = sectorSize * numSectors;
            ulong  bytesReadedPerPercent = 0;
            int    lastProgress          = 0;
            int    progress = 0;
            int    readed   = 0;

            sw.Start();
            percentStopwatch.Start();

            for (ulong i = 0; i < numSectors; i += 1024)
            {
                if (cancelPending)
                {
                    return(false);
                }

                readed = NativeDiskWrapper.ReadSectorDataFromHandle(deviceHandles[0], deviceData, i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize);
                NativeDiskWrapper.WriteSectorDataToHandle(fileHandle, deviceData, i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize, readed);

                totalBytesReaded      += (ulong)readed;
                bytesReaded           += (ulong)readed;
                bytesReadedPerPercent += (ulong)readed;
                bytesToRead           -= (ulong)readed;

                progress = (int)(i / (numSectors / 100.0)) + 1;

                if (progress != lastProgress)
                {
                    ulong averageBps = (ulong)(bytesReadedPerPercent / (percentStopwatch.ElapsedMilliseconds / 1000.0));
                    OperationProgressChanged?.Invoke(this, new OperationProgressChangedEventArgs(progress, averageBps, currentDiskOperation));
                    lastProgress          = progress;
                    bytesReadedPerPercent = 0;
                    percentStopwatch.Restart();
                }

                if (sw.ElapsedMilliseconds >= 1000)
                {
                    ulong averageBps = (ulong)(bytesReaded / (sw.ElapsedMilliseconds / 1000.0));
                    OperationProgressReport?.Invoke(this, new OperationProgressReportEventArgs(averageBps, totalBytesReaded, bytesToRead));
                    bytesReaded = 0;
                    sw.Restart();
                }
            }

            return(true);
        }
Beispiel #6
0
        public static bool IsDriveReadOnly(string drive)
        {
            bool result = false;

            try
            {
                result = NativeDiskWrapper.CheckReadOnly(drive);
            }
            catch
            {
            }
            return(result);
        }
Beispiel #7
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]);
        }
Beispiel #8
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 #9
0
        public static bool CheckRawFilePassword(string path, string password)
        {
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
            byte[] salt          = new byte[32];

            using (FileStream fsCrypt = new FileStream(path, FileMode.Open))
            {
                fsCrypt.Read(salt, 0, encryptionSignature.Length);
                fsCrypt.Read(salt, 0, salt.Length);

                using (RijndaelManaged rijndael = new RijndaelManaged())
                {
                    rijndael.KeySize   = 256;
                    rijndael.BlockSize = 128;
                    using (var key = new Rfc2898DeriveBytes(passwordBytes, salt, Crypto_Iterations))
                    {
                        rijndael.Key = key.GetBytes(rijndael.KeySize / 8);
                        rijndael.IV  = key.GetBytes(rijndael.BlockSize / 8);
                    }
                    rijndael.Padding = PaddingMode.Zeros;
                    rijndael.Mode    = CipherMode.CFB;

                    try
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(fsCrypt, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
                        {
                            int passwordLength = cryptoStream.ReadByte();

                            if (passwordBytes.Length != passwordLength)
                            {
                                return(false);
                            }

                            byte[] buff = new byte[passwordLength];
                            cryptoStream.Read(buff, 0, passwordLength);
                            return(NativeDiskWrapper.ByteArrayCompare(buff, passwordBytes));
                        }
                    }
                    catch (CryptographicException)
                    {
                        return(false);
                    }
                }
            }
        }
Beispiel #10
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);
        }
Beispiel #11
0
        public Disk(char[] driveLetters)
        {
            deviceIDs     = new int[driveLetters.Length];
            volumeIDs     = new int[driveLetters.Length];
            volumeHandles = new IntPtr[driveLetters.Length];
            deviceHandles = new IntPtr[driveLetters.Length];

            DriveLetters = driveLetters;

            for (int i = 0; i < driveLetters.Length; i++)
            {
                deviceIDs[i]     = NativeDiskWrapper.CheckDriveType(string.Format(@"\\.\{0}:\", DriveLetters[i]));
                volumeIDs[i]     = DriveLetters[i] - 'A';
                volumeHandles[i] = deviceHandles[i] = IntPtr.Zero;
            }

            Utils.PreventComputerSleep();
        }
Beispiel #12
0
        public static bool CheckRawFileEncryption(string path)
        {
            if (File.Exists(path))
            {
                using (FileStream fs = new FileStream(path, FileMode.Open))
                {
                    byte[] buffer = new byte[encryptionSignature.Length];

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

                    if (NativeDiskWrapper.ByteArrayCompare(buffer, encryptionSignature))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #13
0
        public static char[] GetLogicalDrives()
        {
            List <char> drives     = new List <char>();
            uint        drivesMask = NativeDiskWrapper.GetLogicalDrives();

            for (int i = 0; drivesMask != 0; i++)
            {
                if ((drivesMask & 0x01) != 0)
                {
                    try
                    {
                        if (NativeDiskWrapper.CheckDriveType(string.Format(@"\\.\{0}:\", (char)('A' + i))) != 0)
                        {
                            drives.Add((char)('A' + i));
                        }
                    }
                    catch { }
                }
                drivesMask >>= 1;
            }

            return(drives.ToArray());
        }
Beispiel #14
0
        protected bool ReadImageFromDeviceCryptoWorker(ulong sectorSize, ulong numSectors)
        {
            Stopwatch sw = new Stopwatch();
            Stopwatch percentStopwatch = new Stopwatch();

            byte[] deviceData            = new byte[1024 * sectorSize];
            ulong  totalBytesReaded      = 0;
            ulong  bytesReaded           = 0;
            ulong  bytesToRead           = sectorSize * numSectors;
            ulong  bytesReadedPerPercent = 0;
            int    lastProgress          = 0;
            int    progress = 0;
            int    readed   = 0;

            sw.Start();
            percentStopwatch.Start();

            using (FileStream fileStream = new FileStream(new SafeFileHandle(fileHandle, false), FileAccess.ReadWrite))
                using (RijndaelManaged rijndael = new RijndaelManaged())
                {
                    byte[] salt          = GenerateRandomSalt();
                    byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

                    fileStream.Write(encryptionSignature, 0, encryptionSignature.Length);
                    fileStream.Write(salt, 0, salt.Length);

                    rijndael.KeySize   = 256;
                    rijndael.BlockSize = 128;
                    rijndael.Padding   = PaddingMode.Zeros;

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

                    using (CryptoStream cryptoStream = new CryptoStream(fileStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cryptoStream.WriteByte((byte)passwordBytes.Length);
                        cryptoStream.Write(passwordBytes, 0, passwordBytes.Length);

                        for (ulong i = 0; i < numSectors; i += 1024)
                        {
                            if (cancelPending)
                            {
                                return(false);
                            }

                            readed = NativeDiskWrapper.ReadSectorDataFromHandle(deviceHandles[0], deviceData, i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize);
                            cryptoStream.Write(deviceData, 0, readed);

                            totalBytesReaded      += (ulong)readed;
                            bytesReaded           += (ulong)readed;
                            bytesReadedPerPercent += (ulong)readed;
                            bytesToRead           -= (ulong)readed;

                            progress = (int)(i / (numSectors / 100.0)) + 1;

                            if (progress != lastProgress)
                            {
                                ulong averageBps = (ulong)(bytesReadedPerPercent / (percentStopwatch.ElapsedMilliseconds / 1000.0));
                                OperationProgressChanged?.Invoke(this, new OperationProgressChangedEventArgs(progress, averageBps, currentDiskOperation));
                                lastProgress          = progress;
                                bytesReadedPerPercent = 0;
                                percentStopwatch.Restart();
                            }

                            if (sw.ElapsedMilliseconds >= 1000)
                            {
                                ulong averageBps = (ulong)(bytesReaded / (sw.ElapsedMilliseconds / 1000.0));
                                OperationProgressReport?.Invoke(this, new OperationProgressReportEventArgs(averageBps, totalBytesReaded, bytesToRead));
                                bytesReaded = 0;
                                sw.Restart();
                            }
                        }
                    }
                }

            return(true);
        }
Beispiel #15
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 #16
0
        protected override async Task <bool> WriteImageToDeviceWorker(ulong sectorSize, ulong numSectors)
        {
            Stopwatch msStopwatch      = new Stopwatch();
            Stopwatch percentStopwatch = new Stopwatch();

            byte[]      imageData              = new byte[1024 * sectorSize];
            ulong       totalBytesWritten      = 0;
            ulong       bytesWritten           = 0;
            ulong       bytesToWrite           = sectorSize * numSectors;
            ulong       bytesWrittenPerPercent = 0;
            int         lastProgress           = 0;
            int         progress = 0;
            int         readed   = 0;
            List <Task> taskList = new List <Task>(deviceHandles.Length);

            msStopwatch.Start();
            percentStopwatch.Start();

            for (ulong i = 0; i < numSectors; i += 1024)
            {
                taskList.Clear();

                if (cancelPending)
                {
                    return(false);
                }

                readed = NativeDiskWrapper.ReadSectorDataFromHandle(fileHandle, imageData, i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize);

                foreach (var deviceHandle in deviceHandles)
                {
                    taskList.Add(NativeDiskWrapper.WriteSectorDataToHandleAsync(deviceHandle, imageData, i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize));
                }

                await Task.WhenAll(taskList);

                totalBytesWritten      += (ulong)readed;
                bytesWritten           += (ulong)readed;
                bytesWrittenPerPercent += (ulong)readed;
                bytesToWrite           -= (ulong)readed;

                progress = (int)(i / (numSectors / 100.0)) + 1;

                if (progress != lastProgress)
                {
                    ulong averageBps = (ulong)(bytesWrittenPerPercent / (percentStopwatch.ElapsedMilliseconds / 1000.0));
                    OperationProgressChanged?.Invoke(this, new OperationProgressChangedEventArgs(progress, averageBps, currentDiskOperation));
                    lastProgress           = progress;
                    bytesWrittenPerPercent = 0;
                    percentStopwatch.Restart();
                }

                if (msStopwatch.ElapsedMilliseconds >= 1000)
                {
                    ulong averageBps = (ulong)(bytesWritten / (msStopwatch.ElapsedMilliseconds / 1000.0));
                    OperationProgressReport?.Invoke(this, new OperationProgressReportEventArgs(averageBps, totalBytesWritten, bytesToWrite));
                    bytesWritten = 0;
                    msStopwatch.Restart();
                }
            }

            return(true);
        }
Beispiel #17
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));
        }
Beispiel #18
0
        protected override async Task <bool> VerifyImageAndDeviceWorkerAsync(IntPtr fileHandle, ulong sectorSize, ulong numSectors)
        {
            byte[]              fileData                = new byte[1024 * sectorSize];
            Stopwatch           msStopwatch             = new Stopwatch();
            Stopwatch           percentStopwatch        = new Stopwatch();
            ulong               totalBytesVerified      = 0;
            ulong               bytesVerified           = 0;
            ulong               bytesToVerify           = sectorSize * numSectors;
            ulong               bytesVerifiedPerPercent = 0;
            int                 lastProgress            = 0;
            int                 progress                = 0;
            int                 readed   = 0;
            List <Task <bool> > taskList = new List <Task <bool> >(deviceHandles.Length);

            byte[][] deviceData        = new byte[deviceHandles.Length][];
            int      failedDeviceIndex = 0;

            for (int i = 0; i < deviceHandles.Length; i++)
            {
                deviceData[i] = new byte[1024 * sectorSize];
            }

            msStopwatch.Start();
            percentStopwatch.Start();

            for (ulong i = 0; i < numSectors; i += 1024)
            {
                taskList.Clear();

                if (cancelPending)
                {
                    return(false);
                }

                readed = NativeDiskWrapper.ReadSectorDataFromHandle(fileHandle, fileData, i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize);
                for (int x = 0; x < deviceHandles.Length; x++)
                {
                    int index = x;
                    taskList.Add(Task.Run(() =>
                    {
                        NativeDiskWrapper.ReadSectorDataFromHandle(deviceHandles[index], deviceData[index], i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize);

                        if (!NativeDiskWrapper.ByteArrayCompare(fileData, deviceData[index]))
                        {
                            failedDeviceIndex = index;
                            return(false);
                        }
                        else
                        {
                            return(true);
                        }
                    }));
                }

                await Task.WhenAll(taskList);

                foreach (var task in taskList)
                {
                    if (!task.Result)
                    {
                        for (ulong x = 0; x < 1024 * sectorSize; x++)
                        {
                            if (deviceData[failedDeviceIndex][x] != fileData[x])
                            {
                                throw new Exception(string.Format("Verify found different data. Device {0}:\\ at byte {1:n0}, file data: 0x{2:X2}, device data: 0x{3:X2}", DriveLetters[failedDeviceIndex], i * sectorSize + x, deviceData[failedDeviceIndex][x], fileData[x]));
                            }
                        }
                        return(false);
                    }
                }

                totalBytesVerified      += (ulong)readed;
                bytesVerified           += (ulong)readed;
                bytesVerifiedPerPercent += (ulong)readed;
                bytesToVerify           -= (ulong)readed;

                progress = (int)(i / (numSectors / 100.0)) + 1;

                if (progress != lastProgress)
                {
                    ulong averageBps = (ulong)(bytesVerifiedPerPercent / (percentStopwatch.ElapsedMilliseconds / 1000.0));
                    OperationProgressChanged?.Invoke(this, new OperationProgressChangedEventArgs(progress, averageBps, currentDiskOperation));
                    lastProgress            = progress;
                    bytesVerifiedPerPercent = 0;
                    percentStopwatch.Restart();
                }

                if (msStopwatch.ElapsedMilliseconds >= 1000)
                {
                    ulong averageBps = (ulong)(bytesVerified / (msStopwatch.ElapsedMilliseconds / 1000.0));
                    OperationProgressReport?.Invoke(this, new OperationProgressReportEventArgs(averageBps, totalBytesVerified, bytesToVerify));
                    bytesVerified = 0;
                    msStopwatch.Restart();
                }
            }

            return(true);
        }
Beispiel #19
0
        protected async Task <bool> WriteImageToDeviceCryptoWorker(ulong sectorSize, ulong numSectors)
        {
            Stopwatch msStopwatch      = new Stopwatch();
            Stopwatch percentStopwatch = new Stopwatch();

            byte[]      imageData              = new byte[1024 * sectorSize];
            ulong       totalBytesWritten      = 0;
            ulong       bytesWritten           = 0;
            ulong       bytesToWrite           = sectorSize * numSectors;
            ulong       bytesWrittenPerPercent = 0;
            int         lastProgress           = 0;
            int         progress = 0;
            int         readed   = 0;
            List <Task> taskList = new List <Task>(deviceHandles.Length);

            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
            byte[] salt          = new byte[32];

            msStopwatch.Start();
            percentStopwatch.Start();

            using (FileStream inputFile = new FileStream(new SafeFileHandle(fileHandle, false), FileAccess.Read))
                using (RijndaelManaged rijndael = new RijndaelManaged())
                {
                    inputFile.Read(salt, 0, encryptionSignature.Length);
                    inputFile.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(inputFile, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
                    {
                        int passLen = cs.ReadByte();
                        cs.Read(imageData, 0, passLen);

                        for (ulong i = 0; i < numSectors; i += 1024)
                        {
                            taskList.Clear();

                            if (cancelPending)
                            {
                                return(false);
                            }

                            readed = cs.Read(imageData, 0, imageData.Length);

                            foreach (var deviceHandle in deviceHandles)
                            {
                                taskList.Add(NativeDiskWrapper.WriteSectorDataToHandleAsync(deviceHandle, imageData, i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize));
                            }

                            await Task.WhenAll(taskList);

                            totalBytesWritten      += (ulong)readed;
                            bytesWritten           += (ulong)readed;
                            bytesWrittenPerPercent += (ulong)readed;
                            bytesToWrite           -= (ulong)readed;

                            progress = (int)(i / (numSectors / 100.0)) + 1;

                            if (progress != lastProgress)
                            {
                                ulong averageBps = (ulong)(bytesWrittenPerPercent / (percentStopwatch.ElapsedMilliseconds / 1000.0));
                                OperationProgressChanged?.Invoke(this, new OperationProgressChangedEventArgs(progress, averageBps, currentDiskOperation));
                                lastProgress           = progress;
                                bytesWrittenPerPercent = 0;
                                percentStopwatch.Restart();
                            }

                            if (msStopwatch.ElapsedMilliseconds >= 1000)
                            {
                                ulong averageBps = (ulong)(bytesWritten / (msStopwatch.ElapsedMilliseconds / 1000.0));
                                OperationProgressReport?.Invoke(this, new OperationProgressReportEventArgs(averageBps, totalBytesWritten, bytesToWrite));
                                bytesWritten = 0;
                                msStopwatch.Restart();
                            }
                        }
                    }
                }
            return(true);
        }
Beispiel #20
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);
        }
Beispiel #21
0
        protected async Task <bool> VerifyImageAndDeviceCryptoWorkerAsync(IntPtr fileHandle, ulong sectorSize, ulong numSectors)
        {
            byte[]              fileData                = new byte[1024 * sectorSize];
            Stopwatch           msStopwatch             = new Stopwatch();
            Stopwatch           percentStopwatch        = new Stopwatch();
            ulong               totalBytesVerified      = 0;
            ulong               bytesVerified           = 0;
            ulong               bytesToVerify           = sectorSize * numSectors;
            ulong               bytesVerifiedPerPercent = 0;
            int                 lastProgress            = 0;
            int                 progress                = 0;
            int                 readed   = 0;
            List <Task <bool> > taskList = new List <Task <bool> >(deviceHandles.Length);

            byte[][] deviceData        = new byte[deviceHandles.Length][];
            int      failedDeviceIndex = 0;

            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
            byte[] salt          = new byte[32];

            for (int i = 0; i < deviceHandles.Length; i++)
            {
                deviceData[i] = new byte[1024 * sectorSize];
            }

            msStopwatch.Start();
            percentStopwatch.Start();

            using (FileStream inputFile = new FileStream(new SafeFileHandle(fileHandle, false), FileAccess.Read))
                using (RijndaelManaged rijndael = new RijndaelManaged())
                {
                    inputFile.Seek(0, SeekOrigin.Begin);
                    inputFile.Read(salt, 0, encryptionSignature.Length);
                    inputFile.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(inputFile, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
                    {
                        int passLen = cs.ReadByte();
                        cs.Read(fileData, 0, passLen);

                        for (ulong i = 0; i < numSectors; i += 1024)
                        {
                            taskList.Clear();

                            if (cancelPending)
                            {
                                return(false);
                            }

                            readed = cs.Read(fileData, 0, fileData.Length);

                            for (int x = 0; x < deviceHandles.Length; x++)
                            {
                                int index = x;
                                taskList.Add(Task.Run(() =>
                                {
                                    NativeDiskWrapper.ReadSectorDataFromHandle(deviceHandles[index], deviceData[index], i, (numSectors - i >= 1024) ? 1024 : (numSectors - i), sectorSize);

                                    if (!NativeDiskWrapper.ByteArrayCompare(fileData, deviceData[index]))
                                    {
                                        failedDeviceIndex = index;
                                        return(false);
                                    }
                                    else
                                    {
                                        return(true);
                                    }
                                }));
                            }

                            await Task.WhenAll(taskList);

                            foreach (var task in taskList)
                            {
                                if (!task.Result)
                                {
                                    for (ulong x = 0; x < 1024 * sectorSize; x++)
                                    {
                                        if (deviceData[failedDeviceIndex][x] != fileData[x])
                                        {
                                            throw new Exception(string.Format("Verify found different data. Device {0}:\\ at byte {1:n0}, file data: 0x{2:X2}, device data: 0x{3:X2}", DriveLetters[failedDeviceIndex], i * sectorSize + x, deviceData[failedDeviceIndex][x], fileData[x]));
                                        }
                                    }
                                    return(false);
                                }
                            }

                            totalBytesVerified      += (ulong)readed;
                            bytesVerified           += (ulong)readed;
                            bytesVerifiedPerPercent += (ulong)readed;
                            bytesToVerify           -= (ulong)readed;

                            progress = (int)(i / (numSectors / 100.0)) + 1;

                            if (progress != lastProgress)
                            {
                                ulong averageBps = (ulong)(bytesVerifiedPerPercent / (percentStopwatch.ElapsedMilliseconds / 1000.0));
                                OperationProgressChanged?.Invoke(this, new OperationProgressChangedEventArgs(progress, averageBps, currentDiskOperation));
                                lastProgress            = progress;
                                bytesVerifiedPerPercent = 0;
                                percentStopwatch.Restart();
                            }

                            if (msStopwatch.ElapsedMilliseconds >= 1000)
                            {
                                ulong averageBps = (ulong)(bytesVerified / (msStopwatch.ElapsedMilliseconds / 1000.0));
                                OperationProgressReport?.Invoke(this, new OperationProgressReportEventArgs(averageBps, totalBytesVerified, bytesToVerify));
                                bytesVerified = 0;
                                msStopwatch.Restart();
                            }
                        }
                    }
                }

            return(true);
        }
Beispiel #22
0
        public ulong GetLastUsedPartition()
        {
            ulong[] numSectorsArr = new ulong[deviceHandles.Length];

            for (int x = 0; x < deviceHandles.Length; x++)
            {
                var partitionInfo = NativeDiskWrapper.GetDiskPartitionInfo(deviceHandles[x]);

                if (partitionInfo.PartitionStyle == PARTITION_STYLE.MasterBootRecord)
                {
                    numSectorsArr[x] = 1;
                    unsafe
                    {
                        byte *data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandles[x], 0, 1, sectorSize);

                        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 > numSectorsArr[x])
                            {
                                numSectorsArr[x] = partitionStartSector + partitionNumSectors;
                            }
                        }
                    }
                }
                else if (partitionInfo.PartitionStyle == PARTITION_STYLE.GuidPartitionTable)
                {
                    numSectorsArr[x] = 1;
                    unsafe
                    {
                        byte *data            = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandles[x], 0, 1, sectorSize);
                        uint  gptHeaderOffset = (uint)Marshal.ReadInt32(new IntPtr(data), 0x1C6);
                        data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandles[x], gptHeaderOffset, 1, sectorSize);
                        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(deviceHandles[x], partitionTableSector, (sectorSize / sizeOfPartitionEntry) * noOfPartitionEntries, sectorSize);

                        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 > numSectorsArr[x])
                            {
                                numSectorsArr[x] = partitionStartSector + partitionNumSectors;
                            }
                        }
                    }
                }
            }

            for (int i = 1; i < deviceHandles.Length; i++)
            {
                if (numSectorsArr[0] != numSectorsArr[i])
                {
                    throw new Exception("Devices have different partitions size.\nVerifying will not be started.");
                }
            }

            return(numSectorsArr[0]);
        }