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]); }
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)); }
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); }
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)); } }
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)); }
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); }