diff options
Diffstat (limited to 'src/Driver')
-rw-r--r-- | src/Driver/BuildDriver.cmd | 2 | ||||
-rw-r--r-- | src/Driver/DriveFilter.c | 427 | ||||
-rw-r--r-- | src/Driver/DriveFilter.h | 20 | ||||
-rw-r--r-- | src/Driver/Driver.rc | 8 | ||||
-rw-r--r-- | src/Driver/Driver.vcproj | 398 | ||||
-rw-r--r-- | src/Driver/Driver.vcxproj | 762 | ||||
-rw-r--r-- | src/Driver/Driver.vcxproj.filters | 369 | ||||
-rw-r--r-- | src/Driver/Driver.vcxproj.user | 18 | ||||
-rw-r--r-- | src/Driver/DumpFilter.c | 24 | ||||
-rw-r--r-- | src/Driver/DumpFilter.h | 2 | ||||
-rw-r--r-- | src/Driver/EncryptedIoQueue.c | 359 | ||||
-rw-r--r-- | src/Driver/EncryptedIoQueue.h | 44 | ||||
-rw-r--r-- | src/Driver/Fuse/Driver.make | 4 | ||||
-rw-r--r-- | src/Driver/Fuse/FuseService.cpp | 33 | ||||
-rw-r--r-- | src/Driver/Fuse/FuseService.h | 6 | ||||
-rw-r--r-- | src/Driver/Ntdriver.c | 2101 | ||||
-rw-r--r-- | src/Driver/Ntdriver.h | 26 | ||||
-rw-r--r-- | src/Driver/Ntvol.c | 260 | ||||
-rw-r--r-- | src/Driver/Ntvol.h | 2 | ||||
-rw-r--r-- | src/Driver/VolumeFilter.c | 68 | ||||
-rw-r--r-- | src/Driver/VolumeFilter.h | 2 | ||||
-rw-r--r-- | src/Driver/veracrypt.Inf | 91 |
22 files changed, 3529 insertions, 1497 deletions
diff --git a/src/Driver/BuildDriver.cmd b/src/Driver/BuildDriver.cmd index 197e41ca..54677df7 100644 --- a/src/Driver/BuildDriver.cmd +++ b/src/Driver/BuildDriver.cmd @@ -3,9 +3,9 @@ :: Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed :: by the TrueCrypt License 3.0. :: :: Modifications and additions to the original source code (contained in this file) -:: and all other portions of this file are Copyright (c) 2013-2016 IDRIX +:: and all other portions of this file are Copyright (c) 2013-2017 IDRIX :: and are governed by the Apache License 2.0 the full text of which is :: contained in the file License.txt included in VeraCrypt binary and source :: code distribution packages. :: diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index 8195fe35..a280d20e 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -27,14 +27,16 @@ #include "Wipe.h" #include "DriveFilter.h" #include "Boot/Windows/BootCommon.h" #include "cpu.h" +#include "rdrand.h" +#include "chachaRng.h" static BOOL DeviceFilterActive = FALSE; BOOL BootArgsValid = FALSE; BootArguments BootArgs; -byte* BootSecRegionData = NULL; +uint8* BootSecRegionData = NULL; uint32 BootSecRegionSize = 0; uint32 BootPkcs5 = 0; static uint64 BootLoaderArgsPtr; @@ -44,15 +46,15 @@ static KMUTEX MountMutex; static volatile BOOL BootDriveFound = FALSE; static DriveFilterExtension *BootDriveFilterExtension = NULL; static LARGE_INTEGER BootDriveLength; -static byte BootLoaderFingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE]; +static uint8 BootLoaderFingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE]; static BOOL CrashDumpEnabled = FALSE; static BOOL HibernationEnabled = FALSE; static BOOL LegacyHibernationDriverFilterActive = FALSE; -static byte *HibernationWriteBuffer = NULL; +static uint8 *HibernationWriteBuffer = NULL; static MDL *HibernationWriteBufferMdl = NULL; static uint32 HibernationPreventionCount = 0; @@ -72,25 +74,28 @@ static KSPIN_LOCK DecoySystemWipeStatusSpinLock; static int64 DecoySystemWipedAreaEnd; PKTHREAD DecoySystemWipeThread = NULL; static NTSTATUS DecoySystemWipeResult; -uint64 BootArgsRegions[] = { EFI_BOOTARGS_REGIONS }; +static uint64 BootArgsRegionsDefault[] = { EFI_BOOTARGS_REGIONS_DEFAULT }; +static uint64 BootArgsRegionsEFI[] = { EFI_BOOTARGS_REGIONS_EFI }; -NTSTATUS LoadBootArguments () +NTSTATUS LoadBootArguments (BOOL bIsEfi) { NTSTATUS status = STATUS_UNSUCCESSFUL; PHYSICAL_ADDRESS bootArgsAddr; - byte *mappedBootArgs; - byte *mappedCryptoInfo = NULL; + uint8 *mappedBootArgs; + uint8 *mappedCryptoInfo = NULL; uint16 bootLoaderArgsIndex; + uint64* BootArgsRegionsPtr = bIsEfi? BootArgsRegionsEFI : BootArgsRegionsDefault; + size_t BootArgsRegionsCount = bIsEfi? sizeof(BootArgsRegionsEFI)/ sizeof(BootArgsRegionsEFI[0]) : sizeof(BootArgsRegionsDefault)/ sizeof(BootArgsRegionsDefault[0]); KeInitializeMutex (&MountMutex, 0); // __debugbreak(); for (bootLoaderArgsIndex = 0; - bootLoaderArgsIndex < sizeof(BootArgsRegions)/ sizeof(BootArgsRegions[1]) && status != STATUS_SUCCESS; + bootLoaderArgsIndex < BootArgsRegionsCount && status != STATUS_SUCCESS; ++bootLoaderArgsIndex) { - bootArgsAddr.QuadPart = BootArgsRegions[bootLoaderArgsIndex] + TC_BOOT_LOADER_ARGS_OFFSET; + bootArgsAddr.QuadPart = BootArgsRegionsPtr[bootLoaderArgsIndex] + TC_BOOT_LOADER_ARGS_OFFSET; Dump ("Checking BootArguments at 0x%x\n", bootArgsAddr.LowPart); mappedBootArgs = MmMapIoSpace (bootArgsAddr, sizeof (BootArguments), MmCached); if (!mappedBootArgs) @@ -103,9 +108,9 @@ NTSTATUS LoadBootArguments () DumpMem (mappedBootArgs, sizeof (BootArguments)); if (bootArguments->BootLoaderVersion == VERSION_NUM - && bootArguments->BootArgumentsCrc32 != GetCrc32 ((byte *) bootArguments, (int) ((byte *) &bootArguments->BootArgumentsCrc32 - (byte *) bootArguments))) + && bootArguments->BootArgumentsCrc32 != GetCrc32 ((uint8 *) bootArguments, (int) ((uint8 *) &bootArguments->BootArgumentsCrc32 - (uint8 *) bootArguments))) { Dump ("BootArguments CRC incorrect\n"); burn (mappedBootArgs, sizeof (BootArguments)); MmUnmapIoSpace (mappedBootArgs, sizeof (BootArguments)); @@ -113,11 +118,11 @@ NTSTATUS LoadBootArguments () TC_BUG_CHECK (STATUS_CRC_ERROR); } // Sanity check: for valid boot argument, the password is less than 64 bytes long - if (bootArguments->BootPassword.Length <= MAX_PASSWORD) + if (bootArguments->BootPassword.Length <= MAX_LEGACY_PASSWORD) { - BootLoaderArgsPtr = BootArgsRegions[bootLoaderArgsIndex]; + BootLoaderArgsPtr = BootArgsRegionsPtr[bootLoaderArgsIndex]; BootArgs = *bootArguments; BootArgsValid = TRUE; burn (bootArguments, sizeof (*bootArguments)); @@ -160,15 +165,15 @@ NTSTATUS LoadBootArguments () if(BootArgs.CryptoInfoLength > (sizeof(BOOT_CRYPTO_HEADER) + sizeof(SECREGION_BOOT_PARAMS)) ) { uint32 crc; PHYSICAL_ADDRESS SecRegionAddress; SECREGION_BOOT_PARAMS* SecRegionParams = (SECREGION_BOOT_PARAMS*) (mappedCryptoInfo + sizeof(BOOT_CRYPTO_HEADER) + 2); - byte *secRegionData = NULL; + uint8 *secRegionData = NULL; SecRegionAddress.QuadPart = SecRegionParams->Ptr; Dump ("SecRegion memory 0x%x %d\n", SecRegionAddress.LowPart, SecRegionParams->Size); // SecRegion correct? if( (SecRegionParams->Ptr != 0) && (SecRegionParams->Size > 0)) { - crc = GetCrc32((byte*)SecRegionParams, 12); + crc = GetCrc32((uint8*)SecRegionParams, 12); if(crc == SecRegionParams->Crc) { Dump ("SecRegion crc ok\n"); secRegionData = MmMapIoSpace (SecRegionAddress, SecRegionParams->Size, MmCached); if(secRegionData) { @@ -214,9 +219,9 @@ NTSTATUS LoadBootArguments () NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) { - DriveFilterExtension *Extension; + DriveFilterExtension *Extension = NULL; NTSTATUS status; PDEVICE_OBJECT filterDeviceObject = NULL; PDEVICE_OBJECT attachedDeviceObject; @@ -269,9 +274,9 @@ NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) err: if (filterDeviceObject) { - if (Extension->LowerDeviceObject) + if (Extension && Extension->LowerDeviceObject) IoDetachDevice (Extension->LowerDeviceObject); IoDeleteDevice (filterDeviceObject); } @@ -287,18 +292,45 @@ static void DismountDrive (DriveFilterExtension *Extension, BOOL stopIoQueue) if (stopIoQueue && EncryptedIoQueueIsRunning (&Extension->Queue)) EncryptedIoQueueStop (&Extension->Queue); - crypto_close (Extension->Queue.CryptoInfo); + crypto_close ((PCRYPTO_INFO) Extension->Queue.CryptoInfo); Extension->Queue.CryptoInfo = NULL; - crypto_close (Extension->HeaderCryptoInfo); + crypto_close ((PCRYPTO_INFO) Extension->HeaderCryptoInfo); Extension->HeaderCryptoInfo = NULL; Extension->DriveMounted = FALSE; + + Dump ("Drive dismount done!\n"); +} + +static void InvalidateVolumeKeys (EXTENSION *Extension) +{ + Dump ("Invalidating volume encryption keys\n"); + + Extension->Queue.ThreadBlockReadWrite = TRUE; + + crypto_eraseKeys ((PCRYPTO_INFO) Extension->Queue.CryptoInfo); + crypto_eraseKeys ((PCRYPTO_INFO) Extension->cryptoInfo); + + Dump ("Volume encryption keys invalidated!\n"); +} + +static void InvalidateDriveFilterKeys (DriveFilterExtension *Extension) +{ + Dump ("Invalidating drive filter encryption keys\n"); + ASSERT (Extension->DriveMounted); + + Extension->Queue.ThreadBlockReadWrite = TRUE; + + crypto_eraseKeys ((PCRYPTO_INFO) Extension->Queue.CryptoInfo); + crypto_eraseKeys ((PCRYPTO_INFO) Extension->HeaderCryptoInfo); + + Dump ("Drive filter encryption keys invalidated!\n"); } -static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* ioBuffer /* ioBuffer must be at least 512 bytes long */) +static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, uint8* ioBuffer /* ioBuffer must be at least 512 bytes long */) { NTSTATUS status; LARGE_INTEGER offset; WHIRLPOOL_CTX whirlpool; @@ -326,13 +358,13 @@ static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* status = TCReadDevice (LowerDeviceObject, ioBuffer, offset, TC_SECTOR_SIZE_BIOS); if (NT_SUCCESS (status)) { -#if !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - NTSTATUS saveStatus = STATUS_SUCCESS; - if (HasISSE()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); +#ifndef _M_ARM64 + NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; + XSTATE_SAVE SaveState; + if (IsCpuIntel() && HasSAVX()) + saveStatus = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState); #endif WHIRLPOOL_add (ioBuffer, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &whirlpool); WHIRLPOOL_add (ioBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &whirlpool); @@ -366,11 +398,11 @@ static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* WHIRLPOOL_finalize (&whirlpool, BootLoaderFingerprint); sha512_end (&BootLoaderFingerprint [WHIRLPOOL_DIGESTSIZE], &sha2); } -#if !defined (_WIN64) - if (NT_SUCCESS (saveStatus) && HasISSE()) - KeRestoreFloatingPointState (&floatingPointState); +#ifndef _M_ARM64 + if (NT_SUCCESS(saveStatus)) + KeRestoreExtendedProcessorState(&SaveState); #endif } else { @@ -378,15 +410,15 @@ static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* } } -static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, uint32 *headerSaltCrc32) +static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, __unaligned uint32 *headerSaltCrc32) { BOOL hiddenVolume = (BootArgs.HiddenSystemPartitionStart != 0); int64 hiddenHeaderOffset = BootArgs.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET; NTSTATUS status; LARGE_INTEGER offset; - char *header; + unsigned char *header; int pkcs5_prf = 0, pim = 0; PARTITION_INFORMATION_EX pi; BOOL bIsGPT = FALSE; @@ -394,9 +426,9 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); // Check disk MBR id and GPT ID if BootSecRegion is available to detect boot drive if (BootSecRegionData != NULL && BootSecRegionSize >= 1024) { - byte mbr[TC_SECTOR_SIZE_BIOS]; + uint8 mbr[TC_SECTOR_SIZE_BIOS]; DCS_DISK_ENTRY_LIST* DeList = (DCS_DISK_ENTRY_LIST*)(BootSecRegionData + 512); offset.QuadPart = 0; status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS); @@ -420,9 +452,9 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, } else { // Check boot drive signature first (header CRC search could fail if a user restored the header to a non-boot drive) if (BootDriveSignatureValid) { - byte mbr[TC_SECTOR_SIZE_BIOS]; + uint8 mbr[TC_SECTOR_SIZE_BIOS]; offset.QuadPart = 0; status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS); @@ -481,14 +513,20 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, } pim = (int) (BootArgs.Flags >> 16); - if (ReadVolumeHeader (!hiddenVolume, header, password, pkcs5_prf, pim, FALSE, &Extension->Queue.CryptoInfo, Extension->HeaderCryptoInfo) == 0) + if (ReadVolumeHeader (!hiddenVolume, header, password, pkcs5_prf, pim, &Extension->Queue.CryptoInfo, Extension->HeaderCryptoInfo) == 0) { - // Header decrypted + // Header decrypted status = STATUS_SUCCESS; Dump ("Header decrypted\n"); + if (Extension->HeaderCryptoInfo->bVulnerableMasterKey) + { + // The volume header master key is vulnerable + Dump ("The volume header master key is vulnerable\n"); + } + // calculate Fingerprint ComputeBootLoaderFingerprint (Extension->LowerDeviceObject, header); if (Extension->Queue.CryptoInfo->hiddenVolume) @@ -546,9 +584,9 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, uint32 crc; uint32 crcSaved; crcSaved = DeList->CRC32; DeList->CRC32 = 0; - crc = GetCrc32((byte*)DeList, 512); + crc = GetCrc32((uint8*)DeList, 512); if(crc == crcSaved){ if(DeList->DE[DE_IDX_PWDCACHE].Type == DE_PwdCache) { uint64 sector = 0; DCS_DEP_PWD_CACHE* pwdCache = (DCS_DEP_PWD_CACHE*)(BootSecRegionData + DeList->DE[DE_IDX_PWDCACHE].Sectors.Offset); @@ -560,9 +598,9 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, uint32 i; for(i = 0; i<pwdCache->Count; ++i){ if (CacheBootPassword && pwdCache->Pwd[i].Length > 0) { int cachedPim = CacheBootPim? (int) (pwdCache->Pim[i]) : 0; - AddPasswordToCache (&pwdCache->Pwd[i], cachedPim); + AddLegacyPasswordToCache (&pwdCache->Pwd[i], cachedPim); } } burn(pwdCache, sizeof(*pwdCache)); } @@ -572,9 +610,9 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, if (CacheBootPassword && BootArgs.BootPassword.Length > 0) { int cachedPim = CacheBootPim? pim : 0; - AddPasswordToCache (&BootArgs.BootPassword, cachedPim); + AddLegacyPasswordToCache (&BootArgs.BootPassword, cachedPim); } burn (&BootArgs.BootPassword, sizeof (BootArgs.BootPassword)); @@ -603,20 +641,26 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, Extension->Queue.MaxReadAheadOffset.QuadPart = 0; } else Extension->Queue.MaxReadAheadOffset = BootDriveLength; + + /* encrypt keys */ + if (IsRamEncryptionEnabled()) + { + VcProtectKeys (Extension->HeaderCryptoInfo, VcGetEncryptionID (Extension->HeaderCryptoInfo)); + VcProtectKeys (Extension->Queue.CryptoInfo, VcGetEncryptionID (Extension->Queue.CryptoInfo)); + } status = EncryptedIoQueueStart (&Extension->Queue); if (!NT_SUCCESS (status)) TC_BUG_CHECK (status); - if (IsOSAtLeast (WIN_VISTA)) + CrashDumpEnabled = TRUE; + HibernationEnabled = TRUE; + if (IsRamEncryptionEnabled()) { - CrashDumpEnabled = TRUE; - HibernationEnabled = TRUE; + HibernationEnabled = FALSE; } - else if (!LegacyHibernationDriverFilterActive) - StartLegacyHibernationDriverFilter(); // Hidden system hibernation is not supported if an extra boot partition is present as the system is not allowed to update the boot partition if (IsHiddenSystemRunning() && (BootArgs.Flags & TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION)) { @@ -642,9 +686,9 @@ ret: static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension) { NTSTATUS status = STATUS_SUCCESS; LARGE_INTEGER offset; - byte *header; + uint8 *header; header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); if (!header) return STATUS_INSUFFICIENT_RESOURCES; @@ -673,11 +717,19 @@ static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension) else { uint32 headerCrc32; uint64 encryptedAreaLength = Extension->Queue.EncryptedAreaEnd + 1 - Extension->Queue.EncryptedAreaStart; - byte *fieldPos = header + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; + uint8 *fieldPos = header + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; + PCRYPTO_INFO pCryptoInfo = Extension->HeaderCryptoInfo; + CRYPTO_INFO tmpCI; + if (IsRamEncryptionEnabled()) + { + memcpy (&tmpCI, pCryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (pCryptoInfo)); + pCryptoInfo = &tmpCI; + } - DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, Extension->HeaderCryptoInfo); + DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo); if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241) { Dump ("Header not decrypted"); @@ -690,9 +742,13 @@ static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension) headerCrc32 = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC); fieldPos = header + TC_HEADER_OFFSET_HEADER_CRC; mputLong (fieldPos, headerCrc32); - EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, Extension->HeaderCryptoInfo); + EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo); + if (IsRamEncryptionEnabled()) + { + burn (&tmpCI, sizeof (CRYPTO_INFO)); + } } status = TCWriteDevice (Extension->LowerDeviceObject, header, offset, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); if (!NT_SUCCESS (status)) @@ -774,9 +830,15 @@ static void CheckDeviceTypeAndMount (DriveFilterExtension *filterExtension) if (!NT_SUCCESS (status)) TC_BUG_CHECK (status); if (!BootDriveFound) - MountDrive (filterExtension, &BootArgs.BootPassword, &BootArgs.HeaderSaltCrc32); + { + Password bootPass = {0}; + bootPass.Length = BootArgs.BootPassword.Length; + memcpy (bootPass.Text, BootArgs.BootPassword.Text, BootArgs.BootPassword.Length); + MountDrive (filterExtension, &bootPass, &BootArgs.HeaderSaltCrc32); + burn (&bootPass, sizeof (bootPass)); + } KeReleaseMutex (&MountMutex, FALSE); } } @@ -784,8 +846,9 @@ static void CheckDeviceTypeAndMount (DriveFilterExtension *filterExtension) static VOID MountDriveWorkItemRoutine (PDEVICE_OBJECT deviceObject, DriveFilterExtension *filterExtension) { + UNREFERENCED_PARAMETER(deviceObject); CheckDeviceTypeAndMount (filterExtension); KeSetEvent (&filterExtension->MountWorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } @@ -901,8 +964,9 @@ static NTSTATUS DispatchPnp (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterE static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { NTSTATUS status; + UNREFERENCED_PARAMETER(DeviceObject); Dump ("IRP_MJ_POWER minor=%d type=%d shutdown=%d\n", (int) irpSp->MinorFunction, (int) irpSp->Parameters.Power.Type, (int) irpSp->Parameters.Power.ShutdownType); if (SetupInProgress && irpSp->MinorFunction == IRP_MN_SET_POWER @@ -910,18 +974,19 @@ static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilte { while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP, NULL, 0, NULL, 0) == STATUS_INSUFFICIENT_RESOURCES); } -#if 0 // Dismount of the system drive is disabled until there is a way to do it without causing system errors (see the documentation for more info) + // Dismount the system drive on shutdown on Windows 7 and later if (DriverShuttingDown + && EraseKeysOnShutdown && Extension->BootDrive && Extension->DriveMounted && irpSp->MinorFunction == IRP_MN_SET_POWER && irpSp->Parameters.Power.Type == DevicePowerState) { DismountDrive (Extension, TRUE); + ClearSecurityParameters (); } -#endif // 0 PoStartNextPowerIrp (Irp); status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); @@ -934,8 +999,53 @@ static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilte IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } +static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterExtension *Extension, PIO_STACK_LOCATION irpSp) +{ + BOOL bBlockTrim = BlockSystemTrimCommand || IsHiddenSystemRunning(); + NTSTATUS status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); + UNREFERENCED_PARAMETER(DeviceObject); + if (!NT_SUCCESS (status)) + return TCCompleteIrp (Irp, status, 0); + + switch (irpSp->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: + Dump ("DriverFilter-DispatchControl: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); + if (bBlockTrim) + { + DWORD inputLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; + if (inputLength >= sizeof (DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) + { + PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pInputAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer; + DEVICE_DATA_MANAGEMENT_SET_ACTION action = pInputAttrs->Action; + if (action == DeviceDsmAction_Trim) + { + Dump ("DriverFilter-DispatchControl: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Trim.\n"); + + if (bBlockTrim) + { + Dump ("DriverFilter-DispatchControl:: TRIM command blocked.\n"); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); + } + } + } + } + break; + case IOCTL_DISK_GROW_PARTITION: + Dump ("DriverFilter-DispatchControl: IOCTL_DISK_GROW_PARTITION blocked\n"); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_UNSUCCESSFUL, 0); + break; + } + + status = PassIrp (Extension->LowerDeviceObject, Irp); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return status; +} + NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) { DriveFilterExtension *Extension = (DriveFilterExtension *) DeviceObject->DeviceExtension; @@ -963,8 +1073,11 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) return DispatchPnp (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_POWER: return DispatchPower (DeviceObject, Irp, Extension, irpSp); + + case IRP_MJ_DEVICE_CONTROL: + return DispatchControl (DeviceObject, Irp, Extension, irpSp); } status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) @@ -975,13 +1088,45 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } +void EmergencyClearAllKeys (PIRP irp) +{ + irp->IoStatus.Information = 0; -void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) + if (!IoIsSystemThread (PsGetCurrentThread()) && !UserCanAccessDriveDevice()) + { + irp->IoStatus.Status = STATUS_ACCESS_DENIED; + } + else + { + int drive; + for (drive = MIN_MOUNTED_VOLUME_DRIVE_NUMBER; drive <= MAX_MOUNTED_VOLUME_DRIVE_NUMBER; ++drive) + { + PDEVICE_OBJECT device = GetVirtualVolumeDeviceObject (drive); + if (device) + { + PEXTENSION extension = (PEXTENSION) device->DeviceExtension; + if (extension) + { + InvalidateVolumeKeys (extension); + } + } + } + + if (BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted) + InvalidateDriveFilterKeys (BootDriveFilterExtension); + + ClearSecurityParameters(); + + irp->IoStatus.Status = STATUS_SUCCESS; + } +} + +void ReopenBootVolumeHeader (PIRP irp) { LARGE_INTEGER offset; - char *header; + unsigned char *header; ReopenBootVolumeHeaderRequest *request = (ReopenBootVolumeHeaderRequest *) irp->AssociatedIrp.SystemBuffer; irp->IoStatus.Information = 0; @@ -994,9 +1139,9 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) if (!ValidateIOBufferSize (irp, sizeof (ReopenBootVolumeHeaderRequest), ValidateInput)) return; if (!BootDriveFound || !BootDriveFilterExtension || !BootDriveFilterExtension->DriveMounted || !BootDriveFilterExtension->HeaderCryptoInfo - || request->VolumePassword.Length > MAX_PASSWORD + || request->VolumePassword.Length > MAX_LEGACY_PASSWORD || request->pkcs5_prf < 0 || request->pkcs5_prf > LAST_PRF_ID || request->pim < 0 || request->pim > 65535 @@ -1024,14 +1169,24 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) Dump ("TCReadDevice error %x\n", irp->IoStatus.Status); goto ret; } - if (ReadVolumeHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, request->pkcs5_prf, request->pim, FALSE, NULL, BootDriveFilterExtension->HeaderCryptoInfo) == 0) + if (IsRamEncryptionEnabled()) + { + VcUnprotectKeys (BootDriveFilterExtension->HeaderCryptoInfo, VcGetEncryptionID (BootDriveFilterExtension->HeaderCryptoInfo)); + } + + if (ReadVolumeHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, request->pkcs5_prf, request->pim, NULL, BootDriveFilterExtension->HeaderCryptoInfo) == 0) { Dump ("Header reopened\n"); + + if (IsRamEncryptionEnabled()) + { + VcProtectKeys (BootDriveFilterExtension->HeaderCryptoInfo, VcGetEncryptionID(BootDriveFilterExtension->HeaderCryptoInfo)); + } + ComputeBootLoaderFingerprint (BootDriveFilterExtension->LowerDeviceObject, header); - - BootDriveFilterExtension->Queue.CryptoInfo->header_creation_time = BootDriveFilterExtension->HeaderCryptoInfo->header_creation_time; + BootDriveFilterExtension->Queue.CryptoInfo->pkcs5 = BootDriveFilterExtension->HeaderCryptoInfo->pkcs5; BootDriveFilterExtension->Queue.CryptoInfo->noIterations = BootDriveFilterExtension->HeaderCryptoInfo->noIterations; BootDriveFilterExtension->Queue.CryptoInfo->volumePim = BootDriveFilterExtension->HeaderCryptoInfo->volumePim; @@ -1059,39 +1214,25 @@ typedef NTSTATUS (*HiberDriverWriteFunctionA) (ULONG arg0, PLARGE_INTEGER writeO typedef NTSTATUS (*HiberDriverWriteFunctionB) (PLARGE_INTEGER writeOffset, PMDL dataMdl); typedef struct { -#ifdef _WIN64 - byte FieldPad1[64]; + uint8 FieldPad1[64]; HiberDriverWriteFunctionB WriteFunctionB; - byte FieldPad2[56]; -#else - byte FieldPad1[48]; - HiberDriverWriteFunctionB WriteFunctionB; - byte FieldPad2[32]; -#endif + uint8 FieldPad2[56]; HiberDriverWriteFunctionA WriteFunctionA; - byte FieldPad3[24]; + uint8 FieldPad3[24]; LARGE_INTEGER PartitionStartOffset; } HiberDriverContext; typedef NTSTATUS (*HiberDriverEntry) (PVOID arg0, HiberDriverContext *hiberDriverContext); typedef struct { LIST_ENTRY ModuleList; -#ifdef _WIN64 - byte FieldPad1[32]; -#else - byte FieldPad1[16]; -#endif + uint8 FieldPad1[32]; PVOID ModuleBaseAddress; HiberDriverEntry ModuleEntryAddress; -#ifdef _WIN64 - byte FieldPad2[24]; -#else - byte FieldPad2[12]; -#endif + uint8 FieldPad2[24]; UNICODE_STRING ModuleName; } ModuleTableItem; @@ -1144,9 +1285,9 @@ static NTSTATUS HiberDriverWriteFunctionFilter (int filterNumber, PLARGE_INTEGER if (BootDriveFilterExtension->Queue.RemapEncryptedArea) dataUnit.Value += BootDriveFilterExtension->Queue.RemappedAreaDataUnitOffset; - EncryptDataUnitsCurrentThread (HibernationWriteBuffer + (intersectStart - offset), + EncryptDataUnitsCurrentThreadEx (HibernationWriteBuffer + (intersectStart - offset), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, BootDriveFilterExtension->Queue.CryptoInfo); @@ -1278,8 +1419,10 @@ static VOID LoadImageNotifyRoutine (PUNICODE_STRING fullImageName, HANDLE proces { ModuleTableItem *moduleItem; LIST_ENTRY *listEntry; KIRQL origIrql; + UNREFERENCED_PARAMETER(fullImageName); + UNREFERENCED_PARAMETER(processId); if (!imageInfo || !imageInfo->SystemModeImage || !imageInfo->ImageBase || !TCDriverObject->DriverSection) return; @@ -1332,64 +1475,8 @@ static VOID LoadImageNotifyRoutine (PUNICODE_STRING fullImageName, HANDLE proces KeLowerIrql (origIrql); } -void StartLegacyHibernationDriverFilter () -{ - PHYSICAL_ADDRESS highestAcceptableWriteBufferAddr; - NTSTATUS status; - - ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); - ASSERT (!IsOSAtLeast (WIN_VISTA)); - - if (!TCDriverObject->DriverSection || !*(ModuleTableItem **) TCDriverObject->DriverSection) - goto err; - - // All buffers required for hibernation must be allocated here -#ifdef _WIN64 - highestAcceptableWriteBufferAddr.QuadPart = 0x7FFffffFFFFULL; -#else - highestAcceptableWriteBufferAddr.QuadPart = 0xffffFFFFULL; -#endif - - HibernationWriteBuffer = MmAllocateContiguousMemory (TC_HIBERNATION_WRITE_BUFFER_SIZE, highestAcceptableWriteBufferAddr); - if (!HibernationWriteBuffer) - goto err; - - HibernationWriteBufferMdl = IoAllocateMdl (HibernationWriteBuffer, TC_HIBERNATION_WRITE_BUFFER_SIZE, FALSE, FALSE, NULL); - if (!HibernationWriteBufferMdl) - goto err; - - MmBuildMdlForNonPagedPool (HibernationWriteBufferMdl); - - status = PsSetLoadImageNotifyRoutine (LoadImageNotifyRoutine); - if (!NT_SUCCESS (status)) - goto err; - - LegacyHibernationDriverFilterActive = TRUE; - CrashDumpEnabled = FALSE; - HibernationEnabled = TRUE; - return; - -err: - LegacyHibernationDriverFilterActive = FALSE; - CrashDumpEnabled = FALSE; - HibernationEnabled = FALSE; - - if (HibernationWriteBufferMdl) - { - IoFreeMdl (HibernationWriteBufferMdl); - HibernationWriteBufferMdl = NULL; - } - - if (HibernationWriteBuffer) - { - MmFreeContiguousMemory (HibernationWriteBuffer); - HibernationWriteBuffer = NULL; - } -} - - static VOID SetupThreadProc (PVOID threadArg) { DriveFilterExtension *Extension = BootDriveFilterExtension; @@ -1398,45 +1485,30 @@ static VOID SetupThreadProc (PVOID threadArg) ULONG setupBlockSize = TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE; BOOL headerUpdateRequired = FALSE; int64 bytesWrittenSinceHeaderUpdate = 0; - byte *buffer = NULL; - byte *wipeBuffer = NULL; - byte wipeRandChars[TC_WIPE_RAND_CHAR_COUNT]; - byte wipeRandCharsUpdate[TC_WIPE_RAND_CHAR_COUNT]; + uint8 *buffer = NULL; + uint8 *wipeBuffer = NULL; + uint8 wipeRandChars[TC_WIPE_RAND_CHAR_COUNT]; + uint8 wipeRandCharsUpdate[TC_WIPE_RAND_CHAR_COUNT]; KIRQL irql; NTSTATUS status; // generate real random values for wipeRandChars and // wipeRandCharsUpdate instead of relying on uninitialized stack memory - LARGE_INTEGER iSeed; - KeQuerySystemTime( &iSeed ); - if (KeGetCurrentIrql() < DISPATCH_LEVEL) - { - ULONG ulRandom; - ulRandom = RtlRandomEx( &iSeed.LowPart ); - memcpy (wipeRandChars, &ulRandom, TC_WIPE_RAND_CHAR_COUNT); - ulRandom = RtlRandomEx( &ulRandom ); - memcpy (wipeRandCharsUpdate, &ulRandom, TC_WIPE_RAND_CHAR_COUNT); - burn (&ulRandom, sizeof(ulRandom)); - } - else - { - byte digest[SHA512_DIGESTSIZE]; - sha512_ctx tctx; - sha512_begin (&tctx); - sha512_hash ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); - sha512_end (digest, &tctx); + ChaCha20RngCtx rngCtx; + uint8 pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ]; + UNREFERENCED_PARAMETER(threadArg); - memcpy (wipeRandChars, digest, TC_WIPE_RAND_CHAR_COUNT); - memcpy (wipeRandCharsUpdate, &digest[SHA512_DIGESTSIZE - TC_WIPE_RAND_CHAR_COUNT], TC_WIPE_RAND_CHAR_COUNT); + GetDriverRandomSeed (pbSeed, sizeof (pbSeed)); + ChaCha20RngInit (&rngCtx, pbSeed, GetDriverRandomSeed, 0); - burn (digest, SHA512_DIGESTSIZE); - burn (&tctx, sizeof (tctx)); - } - - burn (&iSeed, sizeof(iSeed)); + ChaCha20RngGetBytes (&rngCtx, wipeRandChars, TC_WIPE_RAND_CHAR_COUNT); + ChaCha20RngGetBytes (&rngCtx, wipeRandCharsUpdate, TC_WIPE_RAND_CHAR_COUNT); + + burn (&rngCtx, sizeof (rngCtx)); + FAST_ERASE64 (pbSeed, sizeof (pbSeed)); SetupResult = STATUS_UNSUCCESSFUL; // Make sure volume header can be updated @@ -1599,9 +1671,9 @@ static VOID SetupThreadProc (PVOID threadArg) EncryptDataUnits (buffer, &dataUnit, setupBlockSize / ENCRYPTION_DATA_UNIT_SIZE, Extension->Queue.CryptoInfo); if (SetupRequest.WipeAlgorithm != TC_WIPE_NONE) { - byte wipePass; + uint8 wipePass; int wipePassCount = GetWipePassCount (SetupRequest.WipeAlgorithm); if (wipePassCount <= 0) { SetupResult = STATUS_INVALID_PARAMETER; @@ -1787,9 +1859,9 @@ NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_ST return status; } -void GetBootDriveVolumeProperties (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootDriveVolumeProperties (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (VOLUME_PROPERTIES_STRUCT), ValidateOutput)) { DriveFilterExtension *Extension = BootDriveFilterExtension; @@ -1825,9 +1897,9 @@ void GetBootDriveVolumeProperties (PIRP irp, PIO_STACK_LOCATION irpSp) } } -void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootEncryptionStatus (PIRP irp) { /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */ if (ValidateIOBufferSize (irp, sizeof (BootEncryptionStatus), ValidateOutput)) @@ -1859,8 +1931,9 @@ void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp) bootEncStatus->ConfiguredEncryptedAreaStart = Extension->ConfiguredEncryptedAreaStart; bootEncStatus->ConfiguredEncryptedAreaEnd = Extension->ConfiguredEncryptedAreaEnd; bootEncStatus->EncryptedAreaStart = Extension->Queue.EncryptedAreaStart; + bootEncStatus->MasterKeyVulnerable = Extension->HeaderCryptoInfo->bVulnerableMasterKey; if (SetupInProgress) { KIRQL irql; @@ -1886,9 +1959,9 @@ void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp) } } -void GetBootLoaderVersion (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootLoaderVersion (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (uint16), ValidateOutput)) { if (BootArgsValid) @@ -1904,9 +1977,9 @@ void GetBootLoaderVersion (PIRP irp, PIO_STACK_LOCATION irpSp) } } } -void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootLoaderFingerprint (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (BootLoaderFingerprintRequest), ValidateOutput)) { irp->IoStatus.Information = 0; @@ -1914,9 +1987,9 @@ void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp) { BootLoaderFingerprintRequest *bootLoaderFingerprint = (BootLoaderFingerprintRequest *) irp->AssociatedIrp.SystemBuffer; /* compute the fingerprint again and check if it is the same as the one retrieved during boot */ - char *header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + unsigned char *header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); if (!header) { irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; } @@ -1946,19 +2019,19 @@ void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp) } } } -void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootEncryptionAlgorithmName (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (GetBootEncryptionAlgorithmNameRequest), ValidateOutput)) { if (BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted) { wchar_t BootEncryptionAlgorithmNameW[256]; wchar_t BootPrfAlgorithmNameW[256]; GetBootEncryptionAlgorithmNameRequest *request = (GetBootEncryptionAlgorithmNameRequest *) irp->AssociatedIrp.SystemBuffer; - EAGetName (BootEncryptionAlgorithmNameW, BootDriveFilterExtension->Queue.CryptoInfo->ea, 0); - HashGetName2 (BootPrfAlgorithmNameW, BootDriveFilterExtension->Queue.CryptoInfo->pkcs5); + EAGetName (BootEncryptionAlgorithmNameW, 256, BootDriveFilterExtension->Queue.CryptoInfo->ea, 0); + HashGetName2 (BootPrfAlgorithmNameW, 256, BootDriveFilterExtension->Queue.CryptoInfo->pkcs5); RtlStringCbPrintfA (request->BootEncryptionAlgorithmName, sizeof (request->BootEncryptionAlgorithmName), "%S", BootEncryptionAlgorithmNameW); RtlStringCbPrintfA (request->BootPrfAlgorithmName, sizeof (request->BootPrfAlgorithmName), "%S", BootPrfAlgorithmNameW); @@ -2028,18 +2101,19 @@ NTSTATUS AbortBootEncryptionSetup () static VOID DecoySystemWipeThreadProc (PVOID threadArg) { + UNREFERENCED_PARAMETER(threadArg); DriveFilterExtension *Extension = BootDriveFilterExtension; LARGE_INTEGER offset; UINT64_STRUCT dataUnit; ULONG wipeBlockSize = TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE; CRYPTO_INFO *wipeCryptoInfo = NULL; - byte *wipeBuffer = NULL; - byte *wipeRandBuffer = NULL; - byte wipeRandChars[TC_WIPE_RAND_CHAR_COUNT]; + uint8 *wipeBuffer = NULL; + uint8 *wipeRandBuffer = NULL; + uint8 wipeRandChars[TC_WIPE_RAND_CHAR_COUNT]; int wipePass, wipePassCount; int ea = Extension->Queue.CryptoInfo->ea; KIRQL irql; @@ -2075,17 +2149,18 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg) { DecoySystemWipeResult = STATUS_INVALID_PARAMETER; goto ret; } - - memcpy (wipeCryptoInfo->k2, WipeDecoyRequest.WipeKey + EAGetKeySize (ea), EAGetKeySize (ea)); - if (!EAInitMode (wipeCryptoInfo)) + if (!EAInitMode (wipeCryptoInfo, WipeDecoyRequest.WipeKey + EAGetKeySize (ea))) { DecoySystemWipeResult = STATUS_INVALID_PARAMETER; goto err; } + if (IsRamEncryptionEnabled ()) + VcProtectKeys (wipeCryptoInfo, VcGetEncryptionID (wipeCryptoInfo)); + EncryptDataUnits (wipeRandBuffer, &dataUnit, wipeBlockSize / ENCRYPTION_DATA_UNIT_SIZE, wipeCryptoInfo); memcpy (wipeRandChars, wipeRandBuffer, sizeof (wipeRandChars)); burn (WipeDecoyRequest.WipeKey, sizeof (WipeDecoyRequest.WipeKey)); @@ -2208,9 +2283,9 @@ BOOL IsDecoySystemWipeInProgress() return DecoySystemWipeInProgress; } -void GetDecoySystemWipeStatus (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetDecoySystemWipeStatus (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (DecoySystemWipeStatus), ValidateOutput)) { DecoySystemWipeStatus *wipeStatus = (DecoySystemWipeStatus *) irp->AssociatedIrp.SystemBuffer; diff --git a/src/Driver/DriveFilter.h b/src/Driver/DriveFilter.h index fbbfcac0..307880fb 100644 --- a/src/Driver/DriveFilter.h +++ b/src/Driver/DriveFilter.h @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -58,29 +58,29 @@ extern PKTHREAD DecoySystemWipeThread; NTSTATUS AbortBootEncryptionSetup (); NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo); NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp); -void GetBootDriveVolumeProperties (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootLoaderVersion (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp); +void GetBootDriveVolumeProperties (PIRP irp); +void GetBootEncryptionAlgorithmName (PIRP irp); +void GetBootEncryptionStatus (PIRP irp); +void GetBootLoaderVersion (PIRP irp); +void GetBootLoaderFingerprint (PIRP irp); NTSTATUS GetSetupResult (); DriveFilterExtension *GetBootDriveFilterExtension (); CRYPTO_INFO *GetSystemDriveCryptoInfo (); BOOL IsBootDriveMounted (); BOOL IsBootEncryptionSetupInProgress (); BOOL IsHiddenSystemRunning (); -NTSTATUS LoadBootArguments (); +NTSTATUS LoadBootArguments (BOOL bIsEfi); static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension); NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp); -void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp); +void EmergencyClearAllKeys (PIRP irp); +void ReopenBootVolumeHeader (PIRP irp); NTSTATUS StartDecoySystemWipe (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp); -void StartLegacyHibernationDriverFilter (); NTSTATUS AbortDecoySystemWipe (); BOOL IsDecoySystemWipeInProgress(); NTSTATUS GetDecoySystemWipeResult(); -void GetDecoySystemWipeStatus (PIRP irp, PIO_STACK_LOCATION irpSp); +void GetDecoySystemWipeStatus (PIRP irp); uint64 GetBootDriveLength (); NTSTATUS WriteBootDriveSector (PIRP irp, PIO_STACK_LOCATION irpSp); #define TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE (1536 * 1024) diff --git a/src/Driver/Driver.rc b/src/Driver/Driver.rc index c8cd3298..6d9bad20 100644 --- a/src/Driver/Driver.rc +++ b/src/Driver/Driver.rc @@ -26,10 +26,10 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Version // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,20,2,0 - PRODUCTVERSION 1,20,2,0 + FILEVERSION 1,26,17,2 + PRODUCTVERSION 1,26,17,2 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L #else @@ -44,13 +44,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "IDRIX" VALUE "FileDescription", "VeraCrypt Driver" - VALUE "FileVersion", "1.20-BETA2" + VALUE "FileVersion", "1.26.17" VALUE "LegalTrademarks", "VeraCrypt" VALUE "OriginalFilename", "veracrypt.sys" VALUE "ProductName", "VeraCrypt" - VALUE "ProductVersion", "1.20-BETA2" + VALUE "ProductVersion", "1.26.17" END END BLOCK "VarFileInfo" BEGIN diff --git a/src/Driver/Driver.vcproj b/src/Driver/Driver.vcproj deleted file mode 100644 index 4c474c36..00000000 --- a/src/Driver/Driver.vcproj +++ /dev/null @@ -1,398 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="9.00" - Name="Driver" - ProjectGUID="{EF5EF444-18D0-40D7-8DFA-775EC4448602}" - RootNamespace="Driver" - Keyword="MakeFileProj" - TargetFrameworkVersion="131072" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="Debug" - IntermediateDirectory="Debug" - ConfigurationType="0" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" - > - <Tool - Name="VCNMakeTool" - BuildCommandLine="echo ------ Building veracrypt.sys: Debug x86 ------
cmd.exe /c BuildDriver.cmd -build -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"
if errorlevel 1 exit %errorlevel%
echo.
echo ------ Building veracrypt.sys: Debug x64 ------
BuildDriver.cmd -build -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - ReBuildCommandLine="echo ------ Rebuilding veracrypt.sys: Debug x86 ------
cmd.exe /c BuildDriver.cmd -rebuild -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"
if errorlevel 1 exit %errorlevel%
echo.
echo ------ Rebuilding veracrypt.sys: Debug x64 ------
BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - CleanCommandLine="echo ------ Cleaning veracrypt.sys: Debug x86 ------
cmd.exe /c BuildDriver.cmd -clean -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"
if errorlevel 1 exit %errorlevel%
echo.
echo ------ Cleaning veracrypt.sys: Debug x64 ------
BuildDriver.cmd -clean -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - Output="" - PreprocessorDefinitions="DEBUG;_DEBUG;TC_WINDOWS_DRIVER" - IncludeSearchPath=""$(ProjectDir)";"$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(WINDDK_ROOT)\inc\ddk";"$(WINDDK_ROOT)\inc\api"" - ForcedIncludes="" - AssemblySearchPath="" - ForcedUsingAssemblies="" - CompileAsManaged="" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="Release" - IntermediateDirectory="Release" - ConfigurationType="0" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" - > - <Tool - Name="VCNMakeTool" - BuildCommandLine="echo ------ Building veracrypt.sys: Release x86 ------
cmd.exe /c BuildDriver.cmd -build -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"
if errorlevel 1 exit %errorlevel%
echo.
echo ------ Building veracrypt.sys: Release x64 ------
BuildDriver.cmd -build -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - ReBuildCommandLine="echo ------ Rebuilding veracrypt.sys: Release x86 ------
cmd.exe /c BuildDriver.cmd -rebuild -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"
if errorlevel 1 exit %errorlevel%
echo.
echo ------ Rebuilding veracrypt.sys: Release x64 ------
BuildDriver.cmd -rebuild -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - CleanCommandLine="echo ------ Cleaning veracrypt.sys: Release x86 ------
cmd.exe /c BuildDriver.cmd -clean -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"
if errorlevel 1 exit %errorlevel%
echo.
echo ------ Cleaning veracrypt.sys: Release x64 ------
BuildDriver.cmd -clean -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - Output="" - PreprocessorDefinitions="TC_WINDOWS_DRIVER" - IncludeSearchPath=""$(ProjectDir)";"$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(WINDDK_ROOT)\inc\ddk";"$(WINDDK_ROOT)\inc\api"" - ForcedIncludes="" - AssemblySearchPath="" - ForcedUsingAssemblies="" - CompileAsManaged="" - /> - </Configuration> - <Configuration - Name="Release x86|Win32" - OutputDirectory="$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="0" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" - > - <Tool - Name="VCNMakeTool" - BuildCommandLine="BuildDriver.cmd -build -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - ReBuildCommandLine="BuildDriver.cmd -rebuild -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - CleanCommandLine="BuildDriver.cmd -clean -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - Output="" - PreprocessorDefinitions="TC_WINDOWS_DRIVER" - IncludeSearchPath=""$(ProjectDir)";"$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(WINDDK_ROOT)\inc\ddk";"$(WINDDK_ROOT)\inc\api"" - ForcedIncludes="" - AssemblySearchPath="" - ForcedUsingAssemblies="" - CompileAsManaged="" - /> - </Configuration> - <Configuration - Name="Debug x86|Win32" - OutputDirectory="$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="0" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" - > - <Tool - Name="VCNMakeTool" - BuildCommandLine="if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL:
) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL: )

BuildDriver.cmd -build -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - ReBuildCommandLine="if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL:
) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL: )

BuildDriver.cmd -rebuild -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - CleanCommandLine="BuildDriver.cmd -clean -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - Output="$(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe" - PreprocessorDefinitions="DEBUG;_DEBUG;TC_WINDOWS_DRIVER" - IncludeSearchPath=""$(ProjectDir)";"$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(WINDDK_ROOT)\inc\ddk";"$(WINDDK_ROOT)\inc\api"" - ForcedIncludes="" - AssemblySearchPath="" - ForcedUsingAssemblies="" - CompileAsManaged="" - /> - </Configuration> - <Configuration - Name="Release x64|Win32" - OutputDirectory="$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="0" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" - > - <Tool - Name="VCNMakeTool" - BuildCommandLine="BuildDriver.cmd -build -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - ReBuildCommandLine="BuildDriver.cmd -rebuild -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - CleanCommandLine="BuildDriver.cmd -clean -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - Output="" - PreprocessorDefinitions="TC_WINDOWS_DRIVER" - IncludeSearchPath=""$(ProjectDir)";"$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(WINDDK_ROOT)\inc\ddk";"$(WINDDK_ROOT)\inc\api"" - ForcedIncludes="" - AssemblySearchPath="" - ForcedUsingAssemblies="" - CompileAsManaged="" - /> - </Configuration> - <Configuration - Name="Debug x64|Win32" - OutputDirectory="$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="0" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" - > - <Tool - Name="VCNMakeTool" - BuildCommandLine="if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL:
) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL: )

BuildDriver.cmd -build -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - ReBuildCommandLine="if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL:
) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL: )

BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - CleanCommandLine="BuildDriver.cmd -clean -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"" - Output="$(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe" - PreprocessorDefinitions="DEBUG;_DEBUG;TC_WINDOWS_DRIVER" - IncludeSearchPath=""$(ProjectDir)";"$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(WINDDK_ROOT)\inc\ddk";"$(WINDDK_ROOT)\inc\api"" - ForcedIncludes="" - AssemblySearchPath="" - ForcedUsingAssemblies="" - CompileAsManaged="" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" - > - <File - RelativePath=".\DriveFilter.c" - > - </File> - <File - RelativePath=".\DumpFilter.c" - > - </File> - <File - RelativePath=".\EncryptedIoQueue.c" - > - </File> - <File - RelativePath=".\Ntdriver.c" - > - </File> - <File - RelativePath=".\Ntvol.c" - > - </File> - <File - RelativePath=".\VolumeFilter.c" - > - </File> - <Filter - Name="Common" - > - <File - RelativePath="..\Common\Cache.c" - > - </File> - <File - RelativePath="..\Common\Crc.c" - > - </File> - <File - RelativePath="..\Common\Crypto.c" - > - </File> - <File - RelativePath="..\Common\EncryptionThreadPool.c" - > - </File> - <File - RelativePath="..\Common\Endian.c" - > - </File> - <File - RelativePath="..\Common\GfMul.c" - > - </File> - <File - RelativePath="..\Common\Pkcs5.c" - > - </File> - <File - RelativePath="..\Common\Tests.c" - > - </File> - <File - RelativePath="..\Common\Volumes.c" - > - </File> - <File - RelativePath="..\Common\Wipe.c" - > - </File> - <File - RelativePath="..\Common\Xts.c" - > - </File> - </Filter> - <Filter - Name="Crypto" - > - <File - RelativePath="..\Crypto\Aes_hw_cpu.asm" - > - </File> - <File - RelativePath="..\Crypto\Aes_x64.asm" - > - </File> - <File - RelativePath="..\Crypto\Aes_x86.asm" - > - </File> - <File - RelativePath="..\Crypto\Aeskey.c" - > - </File> - <File - RelativePath="..\Crypto\Aestab.c" - > - </File> - <File - RelativePath="..\Crypto\Rmd160.c" - > - </File> - <File - RelativePath="..\Crypto\Serpent.c" - > - </File> - <File - RelativePath="..\Crypto\Sha2.c" - > - </File> - <File - RelativePath="..\Crypto\Twofish.c" - > - </File> - <File - RelativePath="..\Crypto\Whirlpool.c" - > - </File> - </Filter> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" - > - <File - RelativePath="..\Common\Apidrvr.h" - > - </File> - <File - RelativePath="..\Common\Cache.h" - > - </File> - <File - RelativePath="..\Common\Common.h" - > - </File> - <File - RelativePath=".\DriveFilter.h" - > - </File> - <File - RelativePath=".\DumpFilter.h" - > - </File> - <File - RelativePath=".\EncryptedIoQueue.h" - > - </File> - <File - RelativePath="..\Common\EncryptionThreadPool.h" - > - </File> - <File - RelativePath="..\Common\GfMul.h" - > - </File> - <File - RelativePath=".\Ntdriver.h" - > - </File> - <File - RelativePath=".\Ntvol.h" - > - </File> - <File - RelativePath=".\resource.h" - > - </File> - <File - RelativePath="..\Common\Tcdefs.h" - > - </File> - <File - RelativePath=".\VolumeFilter.h" - > - </File> - <File - RelativePath="..\Common\Volumes.h" - > - </File> - <File - RelativePath="..\Common\Wipe.h" - > - </File> - <File - RelativePath="..\Common\Xts.h" - > - </File> - </Filter> - <Filter - Name="Resource Files" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" - > - <File - RelativePath=".\Driver.rc" - > - </File> - </Filter> - <Filter - Name="Build Files" - > - <File - RelativePath=".\BuildDriver.cmd" - > - </File> - <File - RelativePath=".\Makefile" - > - </File> - <File - RelativePath=".\Sources" - > - </File> - <Filter - Name="Common" - > - <File - RelativePath="..\Common\Makefile" - > - </File> - <File - RelativePath="..\Common\Sources" - > - </File> - </Filter> - <Filter - Name="Crypto" - > - <File - RelativePath="..\Crypto\Makefile" - > - </File> - <File - RelativePath="..\Crypto\Makefile.inc" - > - </File> - <File - RelativePath="..\Crypto\Sources" - > - </File> - </Filter> - </Filter> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/src/Driver/Driver.vcxproj b/src/Driver/Driver.vcxproj index f534a0ee..60585351 100644 --- a/src/Driver/Driver.vcxproj +++ b/src/Driver/Driver.vcxproj @@ -1,207 +1,213 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug x64|Win32"> - <Configuration>Debug x64</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug x86|Win32"> - <Configuration>Debug x86</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> + <ProjectConfiguration Include="Debug|x64"> <Configuration>Debug</Configuration> - <Platform>Win32</Platform> + <Platform>x64</Platform> </ProjectConfiguration> - <ProjectConfiguration Include="Release x64|Win32"> - <Configuration>Release x64</Configuration> - <Platform>Win32</Platform> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> </ProjectConfiguration> - <ProjectConfiguration Include="Release x86|Win32"> - <Configuration>Release x86</Configuration> - <Platform>Win32</Platform> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> + <ProjectConfiguration Include="Release|ARM64"> <Configuration>Release</Configuration> - <Platform>Win32</Platform> + <Platform>ARM64</Platform> </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{EF5EF444-18D0-40D7-8DFA-775EC4448602}</ProjectGuid> - <RootNamespace>Driver</RootNamespace> - <Keyword>MakeFileProj</Keyword> + <ProjectGuid>{B5F6C878-6C9E-48A7-91E3-7137A7B85896}</ProjectGuid> + <TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <Configuration>Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">x64</Platform> + <RootNamespace>veracrypt</RootNamespace> + <ProjectName>Driver</ProjectName> + <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'" Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <_NT_TARGET_VERSION>0xA000006</_NT_TARGET_VERSION> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <_NT_TARGET_VERSION>0xA000006</_NT_TARGET_VERSION> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'" Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <_NT_TARGET_VERSION>0xA000006</_NT_TARGET_VERSION> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'" Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <_NT_TARGET_VERSION>0xA000006</_NT_TARGET_VERSION> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <ImportGroup Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> - <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo ------ Building veracrypt.sys: Debug x86 ------ -cmd.exe /c BuildDriver.cmd -build -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)" -if errorlevel 1 exit %errorlevel% -echo. -echo ------ Building veracrypt.sys: Debug x64 ------ -BuildDriver.cmd -build -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeBuildCommandLine> - <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo ------ Rebuilding veracrypt.sys: Debug x86 ------ -cmd.exe /c BuildDriver.cmd -rebuild -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)" -if errorlevel 1 exit %errorlevel% -echo. -echo ------ Rebuilding veracrypt.sys: Debug x64 ------ -BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeReBuildCommandLine> - <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo ------ Cleaning veracrypt.sys: Debug x86 ------ -cmd.exe /c BuildDriver.cmd -clean -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)" -if errorlevel 1 exit %errorlevel% -echo. -echo ------ Cleaning veracrypt.sys: Debug x64 ------ -BuildDriver.cmd -clean -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeCleanCommandLine> - <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> - <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">DEBUG;_DEBUG;TC_WINDOWS_DRIVER;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> - <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir);$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(WINDDK_ROOT)\inc\ddk;$(WINDDK_ROOT)\inc\api;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> - <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> - <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> - <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> - <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo ------ Building veracrypt.sys: Release x86 ------ -cmd.exe /c BuildDriver.cmd -build -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)" -if errorlevel 1 exit %errorlevel% -echo. -echo ------ Building veracrypt.sys: Release x64 ------ -BuildDriver.cmd -build -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeBuildCommandLine> - <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo ------ Rebuilding veracrypt.sys: Release x86 ------ -cmd.exe /c BuildDriver.cmd -rebuild -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)" -if errorlevel 1 exit %errorlevel% -echo. -echo ------ Rebuilding veracrypt.sys: Release x64 ------ -BuildDriver.cmd -rebuild -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeReBuildCommandLine> - <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo ------ Cleaning veracrypt.sys: Release x86 ------ -cmd.exe /c BuildDriver.cmd -clean -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)" -if errorlevel 1 exit %errorlevel% -echo. -echo ------ Cleaning veracrypt.sys: Release x64 ------ -BuildDriver.cmd -clean -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeCleanCommandLine> - <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> - <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TC_WINDOWS_DRIVER;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> - <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir);$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(WINDDK_ROOT)\inc\ddk;$(WINDDK_ROOT)\inc\api;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> - <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> - <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> - <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">$(Configuration)\</IntDir> - <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">BuildDriver.cmd -build -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeBuildCommandLine> - <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">BuildDriver.cmd -rebuild -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeReBuildCommandLine> - <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">BuildDriver.cmd -clean -release -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeCleanCommandLine> - <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'" /> - <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">TC_WINDOWS_DRIVER;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> - <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">$(ProjectDir);$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(WINDDK_ROOT)\inc\ddk;$(WINDDK_ROOT)\inc\api;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> - <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> - <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> - <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release x86|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">$(Configuration)\</IntDir> - <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL: -) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL: ) - -BuildDriver.cmd -build -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeBuildCommandLine> - <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL: -) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe >NUL: ) - -BuildDriver.cmd -rebuild -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeReBuildCommandLine> - <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">BuildDriver.cmd -clean -debug -x86 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeCleanCommandLine> - <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">$(ProjectDir)\obj_driver_debug\i386\VeraCrypt.exe</NMakeOutput> - <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">DEBUG;_DEBUG;TC_WINDOWS_DRIVER;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> - <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">$(ProjectDir);$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(WINDDK_ROOT)\inc\ddk;$(WINDDK_ROOT)\inc\api;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> - <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> - <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> - <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug x86|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">$(Configuration)\</IntDir> - <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">BuildDriver.cmd -build -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeBuildCommandLine> - <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">BuildDriver.cmd -rebuild -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeReBuildCommandLine> - <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">BuildDriver.cmd -clean -release -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeCleanCommandLine> - <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" /> - <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">TC_WINDOWS_DRIVER;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> - <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">$(ProjectDir);$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(WINDDK_ROOT)\inc\ddk;$(WINDDK_ROOT)\inc\api;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> - <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> - <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> - <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">$(Configuration)\</IntDir> - <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL: -) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL: ) - -BuildDriver.cmd -build -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeBuildCommandLine> - <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">if exist $(SolutionDir)\Mount\Debug\VeraCrypt.exe ( copy $(SolutionDir)\Mount\Debug\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL: -) else ( copy $(SolutionDir)\Mount\Release\VeraCrypt.exe $(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe >NUL: ) - -BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeReBuildCommandLine> - <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">BuildDriver.cmd -clean -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Crypto" "$(ProjectDir)"</NMakeCleanCommandLine> - <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">$(ProjectDir)\obj_driver_debug\amd64\VeraCrypt.exe</NMakeOutput> - <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">DEBUG;_DEBUG;TC_WINDOWS_DRIVER;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> - <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">$(ProjectDir);$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(WINDDK_ROOT)\inc\ddk;$(WINDDK_ROOT)\inc\api;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> - <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> - <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> - <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug x64|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> + <PropertyGroup /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + <TargetName>veracrypt</TargetName> + <OutDir>$(ProjectDir)$(Platform)\$(ConfigurationName)\</OutDir> </PropertyGroup> - <ItemDefinitionGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + <TargetName>veracrypt</TargetName> + <OutDir>$(ProjectDir)$(Platform)\$(ConfigurationName)\</OutDir> + <EnableInf2cat>false</EnableInf2cat> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + <TargetName>veracrypt</TargetName> + <OutDir>$(ProjectDir)$(Platform)\$(ConfigurationName)\</OutDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + <TargetName>veracrypt</TargetName> + <OutDir>$(ProjectDir)$(Platform)\$(ConfigurationName)\</OutDir> + <EnableInf2cat>false</EnableInf2cat> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_NO_CRT_STDIO_INLINE;UNICODE;_UNICODE;DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Inf> + <CatalogFileName>veracrypt.cat</CatalogFileName> + </Inf> + <Inf> + <ProviderName> + </ProviderName> + <TimeStamp>1.26.17.2</TimeStamp> + </Inf> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>copy $(OutDir)veracrypt.sys "$(SolutionDir)Debug\Setup Files\veracrypt-x64.sys" +copy $(OutDir)veracrypt.pdb "$(SolutionDir)Debug\Setup Files\veracrypt-x64.pdb" +copy $(OutDir)vc143.pdb "$(SolutionDir)Debug\Setup Files\vc143-x64.pdb" +copy $(OutDir)veracrypt.inf "$(SolutionDir)Debug\Setup Files\veracrypt.inf"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_NO_CRT_STDIO_INLINE;UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Inf> + <CatalogFileName>veracrypt.cat</CatalogFileName> + </Inf> + <Inf> + <ProviderName> + </ProviderName> + <TimeStamp>1.26.17.2</TimeStamp> + </Inf> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>copy $(OutDir)veracrypt.sys "$(SolutionDir)Release\Setup Files\veracrypt-x64.sys" +copy $(OutDir)veracrypt.pdb "$(SolutionDir)Release\Setup Files\veracrypt-x64.pdb" +copy $(OutDir)vc143.pdb "$(SolutionDir)Release\Setup Files\vc143-x64.pdb" +copy $(OutDir)veracrypt.inf "$(SolutionDir)Release\Setup Files\veracrypt.inf"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + <ClCompile> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_NO_CRT_STDIO_INLINE;UNICODE;_UNICODE;_ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Inf> + <CatalogFileName>veracrypt.cat</CatalogFileName> + </Inf> + <Inf> + <ProviderName> + </ProviderName> + <TimeStamp>1.26.17.2</TimeStamp> + </Inf> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>copy $(OutDir)veracrypt.sys "$(SolutionDir)Release\Setup Files\veracrypt-arm64.sys" +copy $(OutDir)veracrypt.pdb "$(SolutionDir)Release\Setup Files\veracrypt-arm64.pdb" +copy $(OutDir)vc143.pdb "$(SolutionDir)Release\Setup Files\vc143-arm64.pdb" +copy $(OutDir)veracrypt.inf "$(SolutionDir)Release\Setup Files\veracrypt.inf"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + <ClCompile> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_NO_CRT_STDIO_INLINE;UNICODE;_UNICODE;DEBUG;_DEBUG;_ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Inf> + <CatalogFileName>veracrypt.cat</CatalogFileName> + </Inf> + <Inf> + <ProviderName> + </ProviderName> + <TimeStamp>1.26.17.2</TimeStamp> + </Inf> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command>copy $(OutDir)veracrypt.sys "$(SolutionDir)Debug\Setup Files\veracrypt-arm64.sys" +copy $(OutDir)veracrypt.pdb "$(SolutionDir\Debug\Setup Files\veracrypt-arm64.pdb" +copy $(OutDir)vc143.pdb "$(SolutionDir)Debug\Setup Files\vc143-arm64.pdb" +copy $(OutDir)veracrypt.inf "$(SolutionDir)Debug\Setup Files\veracrypt.inf"</Command> + </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> - <ClCompile Include="..\Crypto\Camellia.c" /> - <ClCompile Include="..\Crypto\SerpentFast.c" /> - <ClCompile Include="..\Crypto\SerpentFast_simd.cpp" /> - <ClCompile Include="DriveFilter.c" /> - <ClCompile Include="DumpFilter.c" /> - <ClCompile Include="EncryptedIoQueue.c" /> - <ClCompile Include="Ntdriver.c" /> - <ClCompile Include="Ntvol.c" /> - <ClCompile Include="VolumeFilter.c" /> + <Inf Include="veracrypt.inf" /> + </ItemGroup> + <ItemGroup> + <FilesToPackage Include="$(TargetPath)" /> + </ItemGroup> + <ItemGroup> <ClCompile Include="..\Common\Cache.c" /> <ClCompile Include="..\Common\Crc.c" /> <ClCompile Include="..\Common\Crypto.c" /> <ClCompile Include="..\Common\EncryptionThreadPool.c" /> @@ -211,54 +217,388 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry <ClCompile Include="..\Common\Tests.c" /> <ClCompile Include="..\Common\Volumes.c" /> <ClCompile Include="..\Common\Wipe.c" /> <ClCompile Include="..\Common\Xts.c" /> + <ClCompile Include="..\Crypto\Aescrypt.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\Crypto\Aeskey.c" /> <ClCompile Include="..\Crypto\Aestab.c" /> - <ClCompile Include="..\Crypto\Rmd160.c" /> + <ClCompile Include="..\Crypto\blake2s.c" /> + <ClCompile Include="..\Crypto\blake2s_SSE2.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSE41.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSSE3.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\Camellia.c" /> + <ClCompile Include="..\Crypto\chacha-xmm.c" /> + <ClCompile Include="..\Crypto\chacha256.c" /> + <ClCompile Include="..\Crypto\chachaRng.c" /> + <ClCompile Include="..\Crypto\cpu.c" /> + <ClCompile Include="..\Crypto\jitterentropy-base.c" /> + <ClCompile Include="..\Crypto\kuznyechik.c" /> + <ClCompile Include="..\Crypto\kuznyechik_simd.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\rdrand.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\SerpentFast.c" /> + <ClCompile Include="..\Crypto\SerpentFast_simd.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\Crypto\Sha2.c" /> + <ClCompile Include="..\Crypto\Sha2Intel.c" /> + <ClCompile Include="..\Crypto\Streebog.c" /> + <ClCompile Include="..\Crypto\t1ha2.c" /> + <ClCompile Include="..\Crypto\t1ha2_selfcheck.c" /> + <ClCompile Include="..\Crypto\t1ha_selfcheck.c" /> <ClCompile Include="..\Crypto\Twofish.c" /> <ClCompile Include="..\Crypto\Whirlpool.c" /> + <ClCompile Include="..\Driver\DriveFilter.c" /> + <ClCompile Include="..\Driver\DumpFilter.c" /> + <ClCompile Include="..\Driver\EncryptedIoQueue.c" /> + <ClCompile Include="..\Driver\Ntdriver.c" /> + <ClCompile Include="..\Driver\Ntvol.c" /> + <ClCompile Include="..\Driver\VolumeFilter.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Common\Tcdefs.h" /> + <ClInclude Include="..\Crypto\Aes.h" /> + <ClInclude Include="..\Crypto\Aesopt.h" /> + <ClInclude Include="..\Crypto\AesSmall.h" /> + <ClInclude Include="..\Crypto\Aestab.h" /> + <ClInclude Include="..\Crypto\Aes_hw_cpu.h" /> + <ClInclude Include="..\Crypto\Camellia.h" /> + <ClInclude Include="..\Crypto\chacha256.h" /> + <ClInclude Include="..\Crypto\chachaRng.h" /> + <ClInclude Include="..\Crypto\chacha_u1.h" /> + <ClInclude Include="..\Crypto\chacha_u4.h" /> + <ClInclude Include="..\Crypto\config.h" /> + <ClInclude Include="..\Crypto\cpu.h" /> + <ClInclude Include="..\Crypto\GostCipher.h" /> + <ClInclude Include="..\Crypto\jitterentropy-base-user.h" /> + <ClInclude Include="..\Crypto\jitterentropy.h" /> + <ClInclude Include="..\Crypto\kuznyechik.h" /> + <ClInclude Include="..\Crypto\misc.h" /> + <ClInclude Include="..\Crypto\rdrand.h" /> + <ClInclude Include="..\Crypto\Rmd160.h" /> + <ClInclude Include="..\Crypto\SerpentFast.h" /> + <ClInclude Include="..\Crypto\SerpentFast_sbox.h" /> + <ClInclude Include="..\Crypto\Sha2.h" /> + <ClInclude Include="..\Crypto\Streebog.h" /> + <ClInclude Include="..\Crypto\t1ha.h" /> + <ClInclude Include="..\Crypto\t1ha_bits.h" /> + <ClInclude Include="..\Crypto\t1ha_selfcheck.h" /> + <ClInclude Include="..\Crypto\Twofish.h" /> + <ClInclude Include="..\Crypto\Whirlpool.h" /> + <ClInclude Include="..\Driver\DriveFilter.h" /> + <ClInclude Include="..\Driver\DumpFilter.h" /> + <ClInclude Include="..\Driver\EncryptedIoQueue.h" /> + <ClInclude Include="..\Driver\Ntdriver.h" /> + <ClInclude Include="..\Driver\Ntvol.h" /> + <ClInclude Include="..\Driver\Resource.h" /> + <ClInclude Include="..\Driver\VolumeFilter.h" /> </ItemGroup> <ItemGroup> - <None Include="..\Crypto\Aes_hw_cpu.asm" /> - <None Include="..\Crypto\Aes_x64.asm" /> - <None Include="..\Crypto\Aes_x86.asm" /> - <None Include="BuildDriver.cmd" /> - <None Include="Makefile" /> - <None Include="Sources" /> - <None Include="..\Common\Makefile" /> - <None Include="..\Common\Sources" /> - <None Include="..\Crypto\Makefile" /> - <None Include="..\Crypto\Makefile.inc" /> - <None Include="..\Crypto\Sources" /> + <CustomBuild Include="..\Crypto\Aes_hw_cpu.asm"> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </CustomBuild> </ItemGroup> <ItemGroup> - <ClInclude Include="..\Common\Apidrvr.h" /> - <ClInclude Include="..\Common\Cache.h" /> - <ClInclude Include="..\Common\Common.h" /> - <ClInclude Include="DriveFilter.h" /> - <ClInclude Include="DumpFilter.h" /> - <ClInclude Include="EncryptedIoQueue.h" /> - <ClInclude Include="..\Common\EncryptionThreadPool.h" /> - <ClInclude Include="..\Common\GfMul.h" /> - <ClInclude Include="Ntdriver.h" /> - <ClInclude Include="Ntvol.h" /> - <ClInclude Include="resource.h" /> - <ClInclude Include="..\Common\Tcdefs.h" /> - <ClInclude Include="VolumeFilter.h" /> - <ClInclude Include="..\Common\Volumes.h" /> - <ClInclude Include="..\Common\Wipe.h" /> - <ClInclude Include="..\Common\Xts.h" /> + <CustomBuild Include="..\Crypto\Aes_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Aes_x86.asm"> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Twofish_x64.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Camellia_aesni_x64.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Camellia_x64.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256-x86-nayuki.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256_avx1_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256_avx2_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256_sse4_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512-x86-nayuki.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512-x64-nayuki.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512_avx1_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512_avx2_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512_sse4_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\rdrand_ml.asm"> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </CustomBuild> </ItemGroup> <ItemGroup> - <ResourceCompile Include="Driver.rc" /> + <CustomBuild Include="..\Crypto\rdseed_ml.asm"> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </CustomBuild> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\Boot\Windows\Boot.vcxproj"> - <Project>{8b7f059f-e4c7-4e11-88f5-ee8b8433072e}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> + <ResourceCompile Include="..\Driver\Driver.rc" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> diff --git a/src/Driver/Driver.vcxproj.filters b/src/Driver/Driver.vcxproj.filters index dfb7edac..478432fa 100644 --- a/src/Driver/Driver.vcxproj.filters +++ b/src/Driver/Driver.vcxproj.filters @@ -2,201 +2,336 @@ <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="Source Files"> <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Source Files\Common"> - <UniqueIdentifier>{d1f5a533-0da8-4ea8-a749-2fd9725c3666}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Crypto"> - <UniqueIdentifier>{93a4143b-9d2d-4bab-9532-3f00fe0ae55a}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> </Filter> <Filter Include="Header Files"> <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> </Filter> <Filter Include="Resource Files"> <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="Driver Files"> + <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier> + <Extensions>inf;inv;inx;mof;mc;</Extensions> </Filter> - <Filter Include="Build Files"> - <UniqueIdentifier>{0e1fab74-bfc9-4968-87d7-a46cde3b4fb6}</UniqueIdentifier> + <Filter Include="Common"> + <UniqueIdentifier>{a57937a1-39b7-4056-8a0d-91007f1df0dc}</UniqueIdentifier> </Filter> - <Filter Include="Build Files\Common"> - <UniqueIdentifier>{0385fc55-db3b-4dde-aa34-8396d25af075}</UniqueIdentifier> + <Filter Include="Crypto"> + <UniqueIdentifier>{4faf760c-3bff-4dcc-b99d-cde043309fcd}</UniqueIdentifier> </Filter> - <Filter Include="Build Files\Crypto"> - <UniqueIdentifier>{6d92b0d0-a99e-46f0-a1d0-9297ae3795f5}</UniqueIdentifier> + <Filter Include="Crypto\Source Files"> + <UniqueIdentifier>{724c69a8-c0a8-4c7b-83f3-f303bc8733eb}</UniqueIdentifier> + </Filter> + <Filter Include="Crypto\Header Files"> + <UniqueIdentifier>{1cc3d97e-dee8-429c-88d1-893306f9ec32}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> - <ClCompile Include="DriveFilter.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="DumpFilter.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="EncryptedIoQueue.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Ntdriver.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Ntvol.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="VolumeFilter.c"> - <Filter>Source Files</Filter> - </ClCompile> + <Inf Include="veracrypt.inf"> + <Filter>Driver Files</Filter> + </Inf> + </ItemGroup> + <ItemGroup> <ClCompile Include="..\Common\Cache.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Crc.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Crypto.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\EncryptionThreadPool.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Endian.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\GfMul.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Pkcs5.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Tests.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Volumes.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Wipe.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> </ClCompile> <ClCompile Include="..\Common\Xts.c"> - <Filter>Source Files\Common</Filter> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Aescrypt.c"> + <Filter>Crypto\Source Files</Filter> </ClCompile> <ClCompile Include="..\Crypto\Aeskey.c"> - <Filter>Source Files\Crypto</Filter> + <Filter>Crypto\Source Files</Filter> </ClCompile> <ClCompile Include="..\Crypto\Aestab.c"> - <Filter>Source Files\Crypto</Filter> + <Filter>Crypto\Source Files</Filter> </ClCompile> - <ClCompile Include="..\Crypto\Rmd160.c"> - <Filter>Source Files\Crypto</Filter> + <ClCompile Include="..\Crypto\blake2s.c"> + <Filter>Crypto\Source Files</Filter> </ClCompile> - <ClCompile Include="..\Crypto\Sha2.c"> - <Filter>Source Files\Crypto</Filter> + <ClCompile Include="..\Crypto\blake2s_SSE2.c"> + <Filter>Crypto\Source Files</Filter> </ClCompile> - <ClCompile Include="..\Crypto\Twofish.c"> - <Filter>Source Files\Crypto</Filter> + <ClCompile Include="..\Crypto\blake2s_SSE41.c"> + <Filter>Crypto\Source Files</Filter> </ClCompile> - <ClCompile Include="..\Crypto\Whirlpool.c"> - <Filter>Source Files\Crypto</Filter> + <ClCompile Include="..\Crypto\blake2s_SSSE3.c"> + <Filter>Crypto\Source Files</Filter> </ClCompile> <ClCompile Include="..\Crypto\Camellia.c"> - <Filter>Source Files\Crypto</Filter> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chacha-xmm.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chacha256.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chachaRng.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\cpu.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\jitterentropy-base.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\kuznyechik.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\kuznyechik_simd.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\rdrand.c"> + <Filter>Crypto\Source Files</Filter> </ClCompile> <ClCompile Include="..\Crypto\SerpentFast.c"> - <Filter>Source Files\Crypto</Filter> + <Filter>Crypto\Source Files</Filter> </ClCompile> <ClCompile Include="..\Crypto\SerpentFast_simd.cpp"> - <Filter>Source Files\Crypto</Filter> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Sha2.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Sha2Intel.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Streebog.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha2.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha2_selfcheck.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha_selfcheck.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Twofish.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Whirlpool.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Driver\DriveFilter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Driver\DumpFilter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Driver\EncryptedIoQueue.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Driver\Ntdriver.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Driver\Ntvol.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Driver\VolumeFilter.c"> + <Filter>Source Files</Filter> </ClCompile> </ItemGroup> <ItemGroup> - <None Include="..\Crypto\Aes_hw_cpu.asm"> - <Filter>Source Files\Crypto</Filter> - </None> - <None Include="..\Crypto\Aes_x64.asm"> - <Filter>Source Files\Crypto</Filter> - </None> - <None Include="..\Crypto\Aes_x86.asm"> - <Filter>Source Files\Crypto</Filter> - </None> - <None Include="BuildDriver.cmd"> - <Filter>Build Files</Filter> - </None> - <None Include="Makefile"> - <Filter>Build Files</Filter> - </None> - <None Include="Sources"> - <Filter>Build Files</Filter> - </None> - <None Include="..\Common\Makefile"> - <Filter>Build Files\Common</Filter> - </None> - <None Include="..\Common\Sources"> - <Filter>Build Files\Common</Filter> - </None> - <None Include="..\Crypto\Makefile"> - <Filter>Build Files\Crypto</Filter> - </None> - <None Include="..\Crypto\Makefile.inc"> - <Filter>Build Files\Crypto</Filter> - </None> - <None Include="..\Crypto\Sources"> - <Filter>Build Files\Crypto</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Common\Apidrvr.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Common\Tcdefs.h"> + <Filter>Common</Filter> </ClInclude> - <ClInclude Include="..\Common\Cache.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\Aes.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="..\Common\Common.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\Aesopt.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="DriveFilter.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\AesSmall.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="DumpFilter.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\Aestab.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="EncryptedIoQueue.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\Aes_hw_cpu.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="..\Common\EncryptionThreadPool.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\Camellia.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="..\Common\GfMul.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\chacha256.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="Ntdriver.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\Crypto\chachaRng.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\chacha_u1.h"> + <Filter>Crypto\Header Files</Filter> </ClInclude> - <ClInclude Include="Ntvol.h"> + <ClInclude Include="..\Crypto\chacha_u4.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\config.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\cpu.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\GostCipher.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\jitterentropy-base-user.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\jitterentropy.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\kuznyechik.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\misc.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\rdrand.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Rmd160.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\SerpentFast.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\SerpentFast_sbox.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Sha2.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Streebog.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\t1ha.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\t1ha_bits.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\t1ha_selfcheck.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Twofish.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Whirlpool.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Driver\DriveFilter.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="resource.h"> + <ClInclude Include="..\Driver\DumpFilter.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\Common\Tcdefs.h"> + <ClInclude Include="..\Driver\EncryptedIoQueue.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="VolumeFilter.h"> + <ClInclude Include="..\Driver\Ntdriver.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\Common\Volumes.h"> + <ClInclude Include="..\Driver\Ntvol.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\Common\Wipe.h"> + <ClInclude Include="..\Driver\Resource.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\Common\Xts.h"> + <ClInclude Include="..\Driver\VolumeFilter.h"> <Filter>Header Files</Filter> </ClInclude> </ItemGroup> <ItemGroup> - <ResourceCompile Include="Driver.rc"> + <CustomBuild Include="..\Crypto\Aes_hw_cpu.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Aes_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Aes_x86.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Twofish_x64.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Camellia_aesni_x64.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Camellia_x64.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256-x86-nayuki.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256_avx1_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256_avx2_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256_sse4_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512-x86-nayuki.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512-x64-nayuki.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512_avx1_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512_avx2_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512_sse4_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\rdrand_ml.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\rdseed_ml.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\Driver\Driver.rc"> <Filter>Resource Files</Filter> </ResourceCompile> </ItemGroup> </Project>
\ No newline at end of file diff --git a/src/Driver/Driver.vcxproj.user b/src/Driver/Driver.vcxproj.user index ace9a86a..9724a753 100644 --- a/src/Driver/Driver.vcxproj.user +++ b/src/Driver/Driver.vcxproj.user @@ -1,3 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <RemoveDriver>True</RemoveDriver> + <InstallMode>None</InstallMode> + <HardwareIdString /> + <CommandLine /> + <ScriptPath>C:\Program Files (x86)\Windows Kits\10\Testing\Tests\Utilities\DefaultDriverPackageInstallationTask.dll</ScriptPath> + <DbgengRemoteMachineName>VM11</DbgengRemoteMachineName> + <DbgengKernelMachineName>VM11</DbgengKernelMachineName> + <DeployFiles /> + <ScriptName>Microsoft.DriverKit.DefaultDriverPackageInstallationClass.PerformDefaultDriverPackageInstallation</ScriptName> + <ScriptDeviceQuery /> + <SignMode>Off</SignMode> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <SignMode>Off</SignMode> + </PropertyGroup> </Project>
\ No newline at end of file diff --git a/src/Driver/DumpFilter.c b/src/Driver/DumpFilter.c index ff570b1e..f858bb7c 100644 --- a/src/Driver/DumpFilter.c +++ b/src/Driver/DumpFilter.c @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -13,12 +13,13 @@ #include "DumpFilter.h" #include "DriveFilter.h" #include "Ntdriver.h" #include "Tests.h" +#include "cpu.h" static DriveFilterExtension *BootDriveFilterExtension = NULL; static LARGE_INTEGER DumpPartitionOffset; -static byte *WriteFilterBuffer = NULL; +static uint8 *WriteFilterBuffer = NULL; static SIZE_T WriteFilterBufferSize; NTSTATUS DumpFilterEntry (PFILTER_EXTENSION filterExtension, PFILTER_INITIALIZATION_DATA filterInitData) @@ -59,13 +60,8 @@ NTSTATUS DumpFilterEntry (PFILTER_EXTENSION filterExtension, PFILTER_INITIALIZAT status = STATUS_CRC_ERROR; goto err; } - // KeSaveFloatingPointState() may generate a bug check during crash dump -#if !defined (_WIN64) - if (filterExtension->DumpType == DumpTypeCrashdump) - dumpConfig.HwEncryptionEnabled = FALSE; -#endif EnableHwEncryption (dumpConfig.HwEncryptionEnabled); if (!AutoTestAlgorithms()) @@ -121,15 +117,11 @@ NTSTATUS DumpFilterEntry (PFILTER_EXTENSION filterExtension, PFILTER_INITIALIZAT status = STATUS_INVALID_PARAMETER; goto err; } - WriteFilterBufferSize = filterInitData->MaxPagesPerWrite * PAGE_SIZE; + WriteFilterBufferSize = ((SIZE_T)filterInitData->MaxPagesPerWrite) * PAGE_SIZE; -#ifdef _WIN64 highestAcceptableWriteBufferAddr.QuadPart = 0x7FFffffFFFFLL; -#else - highestAcceptableWriteBufferAddr.QuadPart = 0xffffFFFFLL; -#endif WriteFilterBuffer = MmAllocateContiguousMemory (WriteFilterBufferSize, highestAcceptableWriteBufferAddr); if (!WriteFilterBuffer) { @@ -152,8 +144,9 @@ err: static NTSTATUS DumpFilterStart (PFILTER_EXTENSION filterExtension) { + UNREFERENCED_PARAMETER(filterExtension); Dump ("DumpFilterStart type=%d\n", filterExtension->DumpType); if (BootDriveFilterExtension->MagicNumber != TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER) TC_BUG_CHECK (STATUS_CRC_ERROR); @@ -169,8 +162,9 @@ static NTSTATUS DumpFilterWrite (PFILTER_EXTENSION filterExtension, PLARGE_INTEG uint64 intersectStart; uint32 intersectLength; PVOID writeBuffer; CSHORT origMdlFlags; + UNREFERENCED_PARAMETER(filterExtension); if (BootDriveFilterExtension->MagicNumber != TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER) TC_BUG_CHECK (STATUS_CRC_ERROR); @@ -188,9 +182,9 @@ static NTSTATUS DumpFilterWrite (PFILTER_EXTENSION filterExtension, PLARGE_INTEG if ((offset & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); - writeBuffer = MmGetSystemAddressForMdlSafe (writeMdl, HighPagePriority); + writeBuffer = MmGetSystemAddressForMdlSafe (writeMdl, (HighPagePriority | MdlMappingNoExecute)); if (!writeBuffer) TC_BUG_CHECK (STATUS_INSUFFICIENT_RESOURCES); memcpy (WriteFilterBuffer, writeBuffer, dataLength); @@ -212,9 +206,9 @@ static NTSTATUS DumpFilterWrite (PFILTER_EXTENSION filterExtension, PLARGE_INTEG diskWriteOffset->QuadPart += BootDriveFilterExtension->Queue.RemappedAreaOffset; dataUnit.Value += BootDriveFilterExtension->Queue.RemappedAreaDataUnitOffset; } - EncryptDataUnitsCurrentThread (WriteFilterBuffer + (intersectStart - offset), + EncryptDataUnitsCurrentThreadEx (WriteFilterBuffer + (intersectStart - offset), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, BootDriveFilterExtension->Queue.CryptoInfo); } @@ -236,16 +230,18 @@ static NTSTATUS DumpFilterWrite (PFILTER_EXTENSION filterExtension, PLARGE_INTEG static NTSTATUS DumpFilterFinish (PFILTER_EXTENSION filterExtension) { + UNREFERENCED_PARAMETER(filterExtension); Dump ("DumpFilterFinish type=%d\n", filterExtension->DumpType); return STATUS_SUCCESS; } static NTSTATUS DumpFilterUnload (PFILTER_EXTENSION filterExtension) { + UNREFERENCED_PARAMETER(filterExtension); Dump ("DumpFilterUnload type=%d\n", filterExtension->DumpType); if (WriteFilterBuffer) { diff --git a/src/Driver/DumpFilter.h b/src/Driver/DumpFilter.h index 7582e939..c72115a2 100644 --- a/src/Driver/DumpFilter.h +++ b/src/Driver/DumpFilter.h @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c index 7f50ec30..de1e4fdc 100644 --- a/src/Driver/EncryptedIoQueue.c +++ b/src/Driver/EncryptedIoQueue.c @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -190,9 +190,9 @@ static NTSTATUS CompleteOriginalIrp (EncryptedIoQueueItem *item, NTSTATUS status return status; } -static void AcquireFragmentBuffer (EncryptedIoQueue *queue, byte *buffer) +static void AcquireFragmentBuffer (EncryptedIoQueue *queue, uint8 *buffer) { NTSTATUS status = STATUS_INVALID_PARAMETER; if (buffer == queue->FragmentBufferA) @@ -208,9 +208,9 @@ static void AcquireFragmentBuffer (EncryptedIoQueue *queue, byte *buffer) TC_BUG_CHECK (status); } -static void ReleaseFragmentBuffer (EncryptedIoQueue *queue, byte *buffer) +static void ReleaseFragmentBuffer (EncryptedIoQueue *queue, uint8 *buffer) { if (buffer == queue->FragmentBufferA) { KeSetEvent (&queue->FragmentBufferAFreeEvent, IO_DISK_INCREMENT, FALSE); @@ -224,101 +224,214 @@ static void ReleaseFragmentBuffer (EncryptedIoQueue *queue, byte *buffer) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); } } -BOOL +BOOL UpdateBuffer( - byte* buffer, - byte* secRegion, - uint64 bufferDiskOffset, - uint32 bufferLength, - BOOL doUpadte - ) + uint8* buffer, + uint8* secRegion, + SIZE_T secRegionSize, + uint64 bufferDiskOffset, + uint32 bufferLength, + BOOL doUpadte +) { uint64 intersectStart; uint32 intersectLength; uint32 i; - DCS_DISK_ENTRY_LIST *DeList = (DCS_DISK_ENTRY_LIST*)(secRegion + 512); + DCS_DISK_ENTRY_LIST *DeList = NULL; BOOL updated = FALSE; - if (secRegion == NULL) return FALSE; + if (secRegion == NULL) + return FALSE; + + // Check if secRegion is large enough to hold the DCS_DISK_ENTRY_LIST structure + // starting at offset 512 + if (secRegionSize < (512 + sizeof(DCS_DISK_ENTRY_LIST))) + return FALSE; + + DeList = (DCS_DISK_ENTRY_LIST*)(secRegion + 512); + + // Ensure Count doesn't exceed the fixed array size + if (DeList->Count > 15) + return FALSE; + for (i = 0; i < DeList->Count; ++i) { if (DeList->DE[i].Type == DE_Sectors) { + uint64 sectorStart = DeList->DE[i].Sectors.Start; + uint64 sectorLength = DeList->DE[i].Sectors.Length; + uint64 sectorOffset = DeList->DE[i].Sectors.Offset; + + // Check that sectorOffset and sectorLength are valid within secRegion + if (sectorOffset > secRegionSize || + sectorLength == 0 || + (sectorOffset + sectorLength) > secRegionSize) + { + // Invalid entry - skip + continue; + } + GetIntersection( bufferDiskOffset, bufferLength, - DeList->DE[i].Sectors.Start, DeList->DE[i].Sectors.Start + DeList->DE[i].Sectors.Length - 1, + sectorStart, sectorStart + sectorLength - 1, &intersectStart, &intersectLength - ); + ); + if (intersectLength != 0) { + uint64 bufferPos = intersectStart - bufferDiskOffset; + uint64 regionPos = sectorOffset + (intersectStart - sectorStart); + + // Check buffer boundaries + if (bufferPos + intersectLength > bufferLength) + continue; // Intersection out of buffer range + + // Check secRegion boundaries + if (regionPos + intersectLength > secRegionSize) + continue; // Intersection out of secRegion range + updated = TRUE; - if(doUpadte && buffer != NULL) { -// Dump("Subst data\n"); + if (doUpadte && buffer != NULL) { memcpy( - buffer + (intersectStart - bufferDiskOffset), - secRegion + DeList->DE[i].Sectors.Offset + (intersectStart - DeList->DE[i].Sectors.Start), + buffer + bufferPos, + secRegion + regionPos, intersectLength - ); - } else { + ); + } + else { + // If no update is needed but intersection found return TRUE; } } } } return updated; } +static VOID CompleteIrpWorkItemRoutine(PDEVICE_OBJECT DeviceObject, PVOID Context) +{ + PCOMPLETE_IRP_WORK_ITEM workItem = (PCOMPLETE_IRP_WORK_ITEM)Context; + EncryptedIoQueueItem* item = (EncryptedIoQueueItem * ) workItem->Item; + EncryptedIoQueue* queue = item->Queue; + KIRQL oldIrql; + UNREFERENCED_PARAMETER(DeviceObject); + + __try + { + // Complete the IRP + TCCompleteDiskIrp(workItem->Irp, workItem->Status, workItem->Information); + + item->Status = workItem->Status; + OnItemCompleted(item, FALSE); // Do not free item here; it will be freed below + } + __finally + { + // If no active work items remain, signal the event + if (InterlockedDecrement(&queue->ActiveWorkItems) == 0) + { + KeSetEvent(&queue->NoActiveWorkItemsEvent, IO_DISK_INCREMENT, FALSE); + } + + // Return the work item to the free list + KeAcquireSpinLock(&queue->WorkItemLock, &oldIrql); + InsertTailList(&queue->FreeWorkItemsList, &workItem->ListEntry); + KeReleaseSpinLock(&queue->WorkItemLock, oldIrql); + + // Release the semaphore to signal that a work item is available + KeReleaseSemaphore(&queue->WorkItemSemaphore, IO_DISK_INCREMENT, 1, FALSE); + + // Free the item + ReleasePoolBuffer(queue, item); + } +} + +// Handles the completion of the original IRP. +static VOID HandleCompleteOriginalIrp(EncryptedIoQueue* queue, EncryptedIoRequest* request) +{ + NTSTATUS status = KeWaitForSingleObject(&queue->WorkItemSemaphore, Executive, KernelMode, FALSE, NULL); + if (queue->ThreadExitRequested) + return; -static VOID CompletionThreadProc (PVOID threadArg) + if (!NT_SUCCESS(status)) + { + // Handle wait failure: we call the completion routine directly. + // This is not ideal since it can cause deadlock that we are trying to fix but it is better than losing the IRP. + CompleteOriginalIrp(request->Item, STATUS_INSUFFICIENT_RESOURCES, 0); + } + else + { + // Obtain a work item from the free list. + KIRQL oldIrql; + KeAcquireSpinLock(&queue->WorkItemLock, &oldIrql); + PLIST_ENTRY freeEntry = RemoveHeadList(&queue->FreeWorkItemsList); + KeReleaseSpinLock(&queue->WorkItemLock, oldIrql); + + PCOMPLETE_IRP_WORK_ITEM workItem = CONTAINING_RECORD(freeEntry, COMPLETE_IRP_WORK_ITEM, ListEntry); + + // Increment ActiveWorkItems. + InterlockedIncrement(&queue->ActiveWorkItems); + KeResetEvent(&queue->NoActiveWorkItemsEvent); + + // Prepare the work item. + workItem->Irp = request->Item->OriginalIrp; + workItem->Status = request->Item->Status; + workItem->Information = NT_SUCCESS(request->Item->Status) ? request->Item->OriginalLength : 0; + workItem->Item = request->Item; + + // Queue the work item. + IoQueueWorkItem(workItem->WorkItem, CompleteIrpWorkItemRoutine, DelayedWorkQueue, workItem); + } +} + +static VOID CompletionThreadProc(PVOID threadArg) { - EncryptedIoQueue *queue = (EncryptedIoQueue *) threadArg; + EncryptedIoQueue* queue = (EncryptedIoQueue*)threadArg; PLIST_ENTRY listEntry; - EncryptedIoRequest *request; + EncryptedIoRequest* request; UINT64_STRUCT dataUnit; if (IsEncryptionThreadPoolRunning()) - KeSetPriorityThread (KeGetCurrentThread(), LOW_REALTIME_PRIORITY); + KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY); while (!queue->ThreadExitRequested) { - if (!NT_SUCCESS (KeWaitForSingleObject (&queue->CompletionThreadQueueNotEmptyEvent, Executive, KernelMode, FALSE, NULL))) + if (!NT_SUCCESS(KeWaitForSingleObject(&queue->CompletionThreadQueueNotEmptyEvent, Executive, KernelMode, FALSE, NULL))) continue; if (queue->ThreadExitRequested) break; - while ((listEntry = ExInterlockedRemoveHeadList (&queue->CompletionThreadQueue, &queue->CompletionThreadQueueLock))) + while ((listEntry = ExInterlockedRemoveHeadList(&queue->CompletionThreadQueue, &queue->CompletionThreadQueueLock))) { - request = CONTAINING_RECORD (listEntry, EncryptedIoRequest, CompletionListEntry); + request = CONTAINING_RECORD(listEntry, EncryptedIoRequest, CompletionListEntry); - if (request->EncryptedLength > 0 && NT_SUCCESS (request->Item->Status)) + if (request->EncryptedLength > 0 && NT_SUCCESS(request->Item->Status)) { - ASSERT (request->EncryptedOffset + request->EncryptedLength <= request->Offset.QuadPart + request->Length); + ASSERT(request->EncryptedOffset + request->EncryptedLength <= request->Offset.QuadPart + request->Length); dataUnit.Value = (request->Offset.QuadPart + request->EncryptedOffset) / ENCRYPTION_DATA_UNIT_SIZE; if (queue->CryptoInfo->bPartitionInInactiveSysEncScope) dataUnit.Value += queue->CryptoInfo->FirstDataUnitNo.Value; else if (queue->RemapEncryptedArea) dataUnit.Value += queue->RemappedAreaDataUnitOffset; - DecryptDataUnits (request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo); + DecryptDataUnits(request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo); } // Dump("Read sector %lld count %d\n", request->Offset.QuadPart >> 9, request->Length >> 9); // Update subst sectors if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) { - UpdateBuffer(request->Data, queue->SecRegionData, request->Offset.QuadPart, request->Length, TRUE); + UpdateBuffer(request->Data, queue->SecRegionData, queue->SecRegionSize, request->Offset.QuadPart, request->Length, TRUE); } if (request->CompleteOriginalIrp) { - CompleteOriginalIrp (request->Item, request->Item->Status, - NT_SUCCESS (request->Item->Status) ? request->Item->OriginalLength : 0); + HandleCompleteOriginalIrp(queue, request); } - ReleasePoolBuffer (queue, request); + ReleasePoolBuffer(queue, request); } } - PsTerminateSystemThread (STATUS_SUCCESS); + PsTerminateSystemThread(STATUS_SUCCESS); } static NTSTATUS TCCachedRead (EncryptedIoQueue *queue, IO_STATUS_BLOCK *ioStatus, PVOID buffer, LARGE_INTEGER offset, ULONG length) @@ -382,22 +495,24 @@ static VOID IoThreadProc (PVOID threadArg) // Perform IO request if no preceding request of the item failed if (NT_SUCCESS (request->Item->Status)) { - if (queue->IsFilterDevice) + if (queue->ThreadBlockReadWrite) + request->Item->Status = STATUS_DEVICE_BUSY; + else if (queue->IsFilterDevice) { if (queue->RemapEncryptedArea && request->EncryptedLength > 0) { if (request->EncryptedLength != request->Length) { // Up to three subfragments may be required to handle a partially remapped fragment int subFragment; - byte *subFragmentData = request->Data; + uint8 *subFragmentData = request->Data; for (subFragment = 0 ; subFragment < 3; ++subFragment) { LARGE_INTEGER subFragmentOffset; - ULONG subFragmentLength; + ULONG subFragmentLength = 0; subFragmentOffset.QuadPart = request->Offset.QuadPart; switch (subFragment) { @@ -468,10 +583,9 @@ static VOID IoThreadProc (PVOID threadArg) ReleaseFragmentBuffer (queue, request->Data); if (request->CompleteOriginalIrp) { - CompleteOriginalIrp (request->Item, request->Item->Status, - NT_SUCCESS (request->Item->Status) ? request->Item->OriginalLength : 0); + HandleCompleteOriginalIrp(queue, request); } ReleasePoolBuffer (queue, request); } @@ -612,9 +726,9 @@ static VOID MainThreadProc (PVOID threadArg) && item->OriginalLength > 0 && (item->OriginalLength & (ENCRYPTION_DATA_UNIT_SIZE - 1)) == 0 && (item->OriginalOffset.QuadPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0) { - byte *buffer; + uint8 *buffer; ULONG alignedLength; LARGE_INTEGER alignedOffset; hResult = ULongAdd(item->OriginalLength, ENCRYPTION_DATA_UNIT_SIZE, &alignedLength); if (hResult != S_OK) @@ -637,9 +751,9 @@ static VOID MainThreadProc (PVOID threadArg) if (NT_SUCCESS (item->Status)) { UINT64_STRUCT dataUnit; - dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, HighPagePriority); + dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, (HighPagePriority | MdlMappingNoExecute)); if (!dataBuffer) { TCfree (buffer); CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0); @@ -656,9 +770,9 @@ static VOID MainThreadProc (PVOID threadArg) } } // Update subst sectors if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) { - UpdateBuffer(buffer, queue->SecRegionData, alignedOffset.QuadPart, alignedLength, TRUE); + UpdateBuffer(buffer, queue->SecRegionData, queue->SecRegionSize, alignedOffset.QuadPart, alignedLength, TRUE); } memcpy (dataBuffer, buffer + (item->OriginalOffset.LowPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)), item->OriginalLength); } @@ -749,17 +863,17 @@ static VOID MainThreadProc (PVOID threadArg) continue; } else if (item->Write && (queue->SecRegionData != NULL) && (queue->SecRegionSize > 512) - && UpdateBuffer (NULL, queue->SecRegionData, item->OriginalOffset.QuadPart, (uint32)(item->OriginalOffset.QuadPart + item->OriginalLength - 1), FALSE)) + && UpdateBuffer (NULL, queue->SecRegionData, queue->SecRegionSize, item->OriginalOffset.QuadPart, (uint32)(item->OriginalOffset.QuadPart + item->OriginalLength - 1), FALSE)) { // Prevent inappropriately designed software from damaging important data Dump ("Preventing write to the system GPT area\n"); CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0); continue; } - dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, HighPagePriority); + dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, (HighPagePriority | MdlMappingNoExecute)); if (dataBuffer == NULL) { CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0); @@ -772,11 +886,12 @@ static VOID MainThreadProc (PVOID threadArg) fragmentOffset = item->OriginalOffset; while (dataRemaining > 0) { - BOOL isLastFragment = dataRemaining <= TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + ULONG queueFragmentSize = queue->FragmentSize; + BOOL isLastFragment = dataRemaining <= queueFragmentSize; - ULONG dataFragmentLength = isLastFragment ? dataRemaining : TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + ULONG dataFragmentLength = isLastFragment ? dataRemaining : queueFragmentSize; activeFragmentBuffer = (activeFragmentBuffer == queue->FragmentBufferA ? queue->FragmentBufferB : queue->FragmentBufferA); InterlockedIncrement (&queue->IoThreadPendingRequestCount); @@ -793,9 +908,9 @@ static VOID MainThreadProc (PVOID threadArg) request->Data = activeFragmentBuffer; request->OrigDataBufferFragment = dataBuffer; request->Length = dataFragmentLength; - if (queue->IsFilterDevice) + if (queue->IsFilterDevice || queue->bSupportPartialEncryption) { if (queue->EncryptedAreaStart == -1 || queue->EncryptedAreaEnd == -1) { request->EncryptedLength = 0; @@ -844,11 +959,11 @@ static VOID MainThreadProc (PVOID threadArg) if (isLastFragment) break; - dataRemaining -= TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; - dataBuffer += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; - fragmentOffset.QuadPart += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + dataRemaining -= queueFragmentSize; + dataBuffer += queueFragmentSize; + fragmentOffset.QuadPart += queueFragmentSize; } } } @@ -968,9 +1083,13 @@ NTSTATUS EncryptedIoQueueResumeFromHold (EncryptedIoQueue *queue) NTSTATUS EncryptedIoQueueStart (EncryptedIoQueue *queue) { NTSTATUS status; EncryptedIoQueueBuffer *buffer; - int i; + int i, j, preallocatedIoRequestCount, preallocatedItemCount, fragmentSize; + + preallocatedIoRequestCount = EncryptionIoRequestCount; + preallocatedItemCount = EncryptionItemCount; + fragmentSize = EncryptionFragmentSize; queue->StartPending = TRUE; queue->ThreadExitRequested = FALSE; @@ -983,39 +1102,128 @@ NTSTATUS EncryptedIoQueueStart (EncryptedIoQueue *queue) KeInitializeEvent (&queue->NoOutstandingIoEvent, SynchronizationEvent, FALSE); KeInitializeEvent (&queue->PoolBufferFreeEvent, SynchronizationEvent, FALSE); KeInitializeEvent (&queue->QueueResumedEvent, SynchronizationEvent, FALSE); - queue->FragmentBufferA = TCalloc (TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE); +retry_fragmentAllocate: + queue->FragmentBufferA = TCalloc (fragmentSize); if (!queue->FragmentBufferA) - goto noMemory; + { + if (fragmentSize > TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE) + { + fragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + goto retry_fragmentAllocate; + } + else + goto noMemory; + } - queue->FragmentBufferB = TCalloc (TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE); + queue->FragmentBufferB = TCalloc (fragmentSize); if (!queue->FragmentBufferB) - goto noMemory; - - KeInitializeEvent (&queue->FragmentBufferAFreeEvent, SynchronizationEvent, TRUE); - KeInitializeEvent (&queue->FragmentBufferBFreeEvent, SynchronizationEvent, TRUE); + { + if (fragmentSize > TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE) + { + fragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + TCfree (queue->FragmentBufferA); + queue->FragmentBufferA = NULL; + goto retry_fragmentAllocate; + } + else + goto noMemory; + } queue->ReadAheadBufferValid = FALSE; - queue->ReadAheadBuffer = TCalloc (TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE); + queue->ReadAheadBuffer = TCalloc (fragmentSize); if (!queue->ReadAheadBuffer) - goto noMemory; + { + if (fragmentSize > TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE) + { + fragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + TCfree (queue->FragmentBufferA); + TCfree (queue->FragmentBufferB); + queue->FragmentBufferA = NULL; + queue->FragmentBufferB = NULL; + goto retry_fragmentAllocate; + } + else + goto noMemory; + } + + queue->FragmentSize = fragmentSize; + KeInitializeEvent (&queue->FragmentBufferAFreeEvent, SynchronizationEvent, TRUE); + KeInitializeEvent (&queue->FragmentBufferBFreeEvent, SynchronizationEvent, TRUE); + +retry_preallocated: // Preallocate buffers - for (i = 0; i < TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT; ++i) + for (i = 0; i < preallocatedIoRequestCount; ++i) { - if (i < TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT && !GetPoolBuffer (queue, sizeof (EncryptedIoQueueItem))) - goto noMemory; + if (i < preallocatedItemCount && !GetPoolBuffer (queue, sizeof (EncryptedIoQueueItem))) + { + if (preallocatedItemCount > TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT) + { + preallocatedItemCount = TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT; + preallocatedIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT; + FreePoolBuffers (queue); + goto retry_preallocated; + } + else + goto noMemory; + } if (!GetPoolBuffer (queue, sizeof (EncryptedIoRequest))) - goto noMemory; + { + if (preallocatedIoRequestCount > TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT) + { + preallocatedItemCount = TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT; + preallocatedIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT; + FreePoolBuffers (queue); + goto retry_preallocated; + } + else + goto noMemory; + } } for (buffer = queue->FirstPoolBuffer; buffer != NULL; buffer = buffer->NextBuffer) { buffer->InUse = FALSE; } + // Initialize the free work item list + InitializeListHead(&queue->FreeWorkItemsList); + KeInitializeSemaphore(&queue->WorkItemSemaphore, EncryptionMaxWorkItems, EncryptionMaxWorkItems); + KeInitializeSpinLock(&queue->WorkItemLock); + + queue->MaxWorkItems = EncryptionMaxWorkItems; + queue->WorkItemPool = (PCOMPLETE_IRP_WORK_ITEM)TCalloc(sizeof(COMPLETE_IRP_WORK_ITEM) * queue->MaxWorkItems); + if (!queue->WorkItemPool) + { + goto noMemory; + } + + // Allocate and initialize work items + for (i = 0; i < (int) queue->MaxWorkItems; ++i) + { + queue->WorkItemPool[i].WorkItem = IoAllocateWorkItem(queue->DeviceObject); + if (!queue->WorkItemPool[i].WorkItem) + { + // Handle allocation failure + // Free previously allocated work items + for (j = 0; j < i; ++j) + { + IoFreeWorkItem(queue->WorkItemPool[j].WorkItem); + } + TCfree(queue->WorkItemPool); + goto noMemory; + } + + // Insert the work item into the free list + ExInterlockedInsertTailList(&queue->FreeWorkItemsList, &queue->WorkItemPool[i].ListEntry, &queue->WorkItemLock); + } + + queue->ActiveWorkItems = 0; + KeInitializeEvent(&queue->NoActiveWorkItemsEvent, NotificationEvent, FALSE); + // Main thread InitializeListHead (&queue->MainThreadQueue); KeInitializeSpinLock (&queue->MainThreadQueueLock); KeInitializeEvent (&queue->MainThreadQueueNotEmptyEvent, SynchronizationEvent, FALSE); @@ -1096,8 +1304,29 @@ NTSTATUS EncryptedIoQueueStop (EncryptedIoQueue *queue) TCStopThread (queue->MainThread, &queue->MainThreadQueueNotEmptyEvent); TCStopThread (queue->IoThread, &queue->IoThreadQueueNotEmptyEvent); TCStopThread (queue->CompletionThread, &queue->CompletionThreadQueueNotEmptyEvent); + // Wait for active work items to complete + KeResetEvent(&queue->NoActiveWorkItemsEvent); + Dump("Queue stopping active work items=%d\n", queue->ActiveWorkItems); + while (InterlockedCompareExchange(&queue->ActiveWorkItems, 0, 0) > 0) + { + KeWaitForSingleObject(&queue->NoActiveWorkItemsEvent, Executive, KernelMode, FALSE, NULL); + // reset the event again in case multiple work items are completing + KeResetEvent(&queue->NoActiveWorkItemsEvent); + } + + // Free pre-allocated work items + for (ULONG i = 0; i < queue->MaxWorkItems; ++i) + { + if (queue->WorkItemPool[i].WorkItem) + { + IoFreeWorkItem(queue->WorkItemPool[i].WorkItem); + queue->WorkItemPool[i].WorkItem = NULL; + } + } + TCfree(queue->WorkItemPool); + TCfree (queue->FragmentBufferA); TCfree (queue->FragmentBufferB); TCfree (queue->ReadAheadBuffer); diff --git a/src/Driver/EncryptedIoQueue.h b/src/Driver/EncryptedIoQueue.h index fe9365ed..3738065a 100644 --- a/src/Driver/EncryptedIoQueue.h +++ b/src/Driver/EncryptedIoQueue.h @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -23,9 +23,11 @@ #define TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE (256 * 1024) #define TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT 8 #define TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT 16 +#define TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_MAX_COUNT 8192 +#define VC_MAX_WORK_ITEMS 1024 typedef struct EncryptedIoQueueBufferStruct { struct EncryptedIoQueueBufferStruct *NextBuffer; @@ -35,8 +37,17 @@ typedef struct EncryptedIoQueueBufferStruct BOOL InUse; } EncryptedIoQueueBuffer; +typedef struct _COMPLETE_IRP_WORK_ITEM +{ + PIO_WORKITEM WorkItem; + PIRP Irp; + NTSTATUS Status; + ULONG_PTR Information; + void* Item; + LIST_ENTRY ListEntry; // For managing free work items +} COMPLETE_IRP_WORK_ITEM, * PCOMPLETE_IRP_WORK_ITEM; typedef struct { PDEVICE_OBJECT DeviceObject; @@ -47,8 +58,9 @@ typedef struct CRYPTO_INFO *CryptoInfo; // File-handle-based IO HANDLE HostFileHandle; + BOOL bSupportPartialEncryption; int64 VirtualDeviceLength; SECURITY_CLIENT_CONTEXT *SecurityClientContext; // Filter device @@ -80,10 +92,10 @@ typedef struct KSPIN_LOCK CompletionThreadQueueLock; KEVENT CompletionThreadQueueNotEmptyEvent; // Fragment buffers - byte *FragmentBufferA; - byte *FragmentBufferB; + uint8 *FragmentBufferA; + uint8 *FragmentBufferB; KEVENT FragmentBufferAFreeEvent; KEVENT FragmentBufferBFreeEvent; // Read-ahead buffer @@ -91,14 +103,14 @@ typedef struct LARGE_INTEGER LastReadOffset; ULONG LastReadLength; LARGE_INTEGER ReadAheadOffset; ULONG ReadAheadLength; - byte *ReadAheadBuffer; + uint8 *ReadAheadBuffer; LARGE_INTEGER MaxReadAheadOffset; - LONG OutstandingIoCount; + volatile LONG OutstandingIoCount; KEVENT NoOutstandingIoEvent; - LONG IoThreadPendingRequestCount; + volatile LONG IoThreadPendingRequestCount; KEVENT PoolBufferFreeEvent; __int64 TotalBytesRead; @@ -116,10 +128,24 @@ typedef struct #ifdef TC_TRACE_IO_QUEUE LARGE_INTEGER LastPerformanceCounter; #endif - byte* SecRegionData; + uint8* SecRegionData; SIZE_T SecRegionSize; + + volatile BOOL ThreadBlockReadWrite; + + int FragmentSize; + + // Pre-allocated work items + PCOMPLETE_IRP_WORK_ITEM WorkItemPool; + ULONG MaxWorkItems; + LIST_ENTRY FreeWorkItemsList; + KSEMAPHORE WorkItemSemaphore; + KSPIN_LOCK WorkItemLock; + + volatile LONG ActiveWorkItems; + KEVENT NoActiveWorkItemsEvent; } EncryptedIoQueue; typedef struct @@ -146,10 +172,10 @@ typedef struct LARGE_INTEGER Offset; ULONG Length; int64 EncryptedOffset; ULONG EncryptedLength; - byte *Data; - byte *OrigDataBufferFragment; + uint8 *Data; + uint8 *OrigDataBufferFragment; LIST_ENTRY ListEntry; LIST_ENTRY CompletionListEntry; } EncryptedIoRequest; diff --git a/src/Driver/Fuse/Driver.make b/src/Driver/Fuse/Driver.make index 169d0354..47f3c2cd 100644 --- a/src/Driver/Fuse/Driver.make +++ b/src/Driver/Fuse/Driver.make @@ -3,9 +3,9 @@ # Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed # by the TrueCrypt License 3.0. # # Modifications and additions to the original source code (contained in this file) -# and all other portions of this file are Copyright (c) 2013-2016 IDRIX +# and all other portions of this file are Copyright (c) 2013-2017 IDRIX # and are governed by the Apache License 2.0 the full text of which is # contained in the file License.txt included in VeraCrypt binary and source # code distribution packages. # @@ -14,7 +14,7 @@ NAME := Driver OBJS := OBJS += FuseService.o -CXXFLAGS += $(shell pkg-config fuse --cflags) +CXXFLAGS += $(shell $(PKG_CONFIG) $(VC_FUSE_PACKAGE) --cflags) include $(BUILD_INC)/Makefile.inc diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp index 97316532..5b12ba4d 100644 --- a/src/Driver/Fuse/FuseService.cpp +++ b/src/Driver/Fuse/FuseService.cpp @@ -3,15 +3,20 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ +#ifdef TC_OPENBSD +#define FUSE_USE_VERSION 26 +#else #define FUSE_USE_VERSION 25 +#endif + #include <errno.h> #include <fcntl.h> #include <fuse.h> #include <iostream> @@ -50,9 +55,13 @@ namespace VeraCrypt return 0; } +#ifdef TC_OPENBSD + static void *fuse_service_init (struct fuse_conn_info *) +#else static void *fuse_service_init () +#endif { try { // Termination signals are handled by a separate process to allow clean dismount on shutdown @@ -213,16 +222,16 @@ namespace VeraCrypt SecureBuffer alignedBuffer (alignedSize); FuseService::ReadVolumeSectors (alignedBuffer, alignedOffset); - BufferPtr ((byte *) buf, size).CopyFrom (alignedBuffer.GetRange (offset % sectorSize, size)); + BufferPtr ((uint8 *) buf, size).CopyFrom (alignedBuffer.GetRange (offset % sectorSize, size)); } else { - FuseService::ReadVolumeSectors (BufferPtr ((byte *) buf, size), offset); + FuseService::ReadVolumeSectors (BufferPtr ((uint8 *) buf, size), offset); } } - catch (MissingVolumeData) + catch (MissingVolumeData&) { return 0; } @@ -231,9 +240,9 @@ namespace VeraCrypt if (strcmp (path, FuseService::GetControlPath()) == 0) { shared_ptr <Buffer> infoBuf = FuseService::GetVolumeInfo(); - BufferPtr outBuf ((byte *)buf, size); + BufferPtr outBuf ((uint8 *)buf, size); if (offset >= (off_t) infoBuf->Size()) return 0; @@ -283,18 +292,18 @@ namespace VeraCrypt return -EACCES; if (strcmp (path, FuseService::GetVolumeImagePath()) == 0) { - FuseService::WriteVolumeSectors (BufferPtr ((byte *) buf, size), offset); + FuseService::WriteVolumeSectors (BufferPtr ((uint8 *) buf, size), offset); return size; } if (strcmp (path, FuseService::GetControlPath()) == 0) { if (FuseService::AuxDeviceInfoReceived()) return -EACCES; - FuseService::ReceiveAuxDeviceInfo (ConstBufferPtr ((const byte *)buf, size)); + FuseService::ReceiveAuxDeviceInfo (ConstBufferPtr ((const uint8 *)buf, size)); return size; } } #ifdef TC_FREEBSD @@ -349,9 +358,9 @@ namespace VeraCrypt try { throw; } - catch (std::bad_alloc) + catch (std::bad_alloc&) { return -ENOMEM; } catch (ParameterIncorrect &e) @@ -574,23 +583,27 @@ namespace VeraCrypt sigaction (SIGQUIT, &action, nullptr); sigaction (SIGTERM, &action, nullptr); // Wait for the exit of the main service - byte buf[1]; + uint8 buf[1]; if (read (SignalHandlerPipe->GetReadFD(), buf, sizeof (buf))) { } // Errors ignored _exit (0); } SignalHandlerPipe->GetWriteFD(); +#ifdef TC_OPENBSD + _exit (fuse_main (argc, argv, &fuse_service_oper, NULL)); +#else _exit (fuse_main (argc, argv, &fuse_service_oper)); +#endif } VolumeInfo FuseService::OpenVolumeInfo; Mutex FuseService::OpenVolumeInfoMutex; shared_ptr <Volume> FuseService::MountedVolume; VolumeSlotNumber FuseService::SlotNumber; uid_t FuseService::UserId; gid_t FuseService::GroupId; - auto_ptr <Pipe> FuseService::SignalHandlerPipe; + unique_ptr <Pipe> FuseService::SignalHandlerPipe; } diff --git a/src/Driver/Fuse/FuseService.h b/src/Driver/Fuse/FuseService.h index 0498a42a..d09a40db 100644 --- a/src/Driver/Fuse/FuseService.h +++ b/src/Driver/Fuse/FuseService.h @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -37,9 +37,9 @@ namespace VeraCrypt shared_ptr <Volume> MountedVolume; VolumeSlotNumber SlotNumber; }; - friend class ExecFunctor; + friend struct ExecFunctor; public: static bool AuxDeviceInfoReceived () { return !OpenVolumeInfo.VirtualDevice.IsEmpty(); } static bool CheckAccessRights (); @@ -69,9 +69,9 @@ namespace VeraCrypt static shared_ptr <Volume> MountedVolume; static VolumeSlotNumber SlotNumber; static uid_t UserId; static gid_t GroupId; - static auto_ptr <Pipe> SignalHandlerPipe; + static unique_ptr <Pipe> SignalHandlerPipe; }; } #endif // TC_HEADER_Driver_Fuse_FuseService diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index eaa8fa8c..12943dc8 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -5,19 +5,22 @@ governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "TCdefs.h" #include <ntddk.h> +#include <initguid.h> +#include <Ntddstor.h> #include "Crypto.h" #include "Fat.h" #include "Tests.h" #include "cpu.h" +#include "Crc.h" #include "Apidrvr.h" #include "Boot/Windows/BootDefs.h" #include "EncryptedIoQueue.h" @@ -28,8 +31,11 @@ #include "DumpFilter.h" #include "Cache.h" #include "Volumes.h" #include "VolumeFilter.h" +#include "cpu.h" +#include "rdrand.h" +#include "jitterentropy.h" #include <tchar.h> #include <initguid.h> #include <mountmgr.h> @@ -38,12 +44,82 @@ #include <Ntstrsafe.h> #include <Intsafe.h> +#ifndef IOCTL_DISK_GET_CLUSTER_INFO +#define IOCTL_DISK_GET_CLUSTER_INFO CTL_CODE(IOCTL_DISK_BASE, 0x0085, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif + +#ifndef IOCTL_DISK_ARE_VOLUMES_READY +#define IOCTL_DISK_ARE_VOLUMES_READY CTL_CODE(IOCTL_DISK_BASE, 0x0087, METHOD_BUFFERED, FILE_READ_ACCESS) +#endif + +#ifndef FT_BALANCED_READ_MODE +#define FTTYPE ((ULONG)'f') +#define FT_BALANCED_READ_MODE CTL_CODE(FTTYPE, 6, METHOD_NEITHER, FILE_ANY_ACCESS) +#endif + +#ifndef IOCTL_VOLUME_QUERY_ALLOCATION_HINT +#define IOCTL_VOLUME_QUERY_ALLOCATION_HINT CTL_CODE(IOCTL_VOLUME_BASE, 20, METHOD_OUT_DIRECT, FILE_READ_ACCESS) +#endif + +#ifndef IOCTL_DISK_IS_CLUSTERED +#define IOCTL_DISK_IS_CLUSTERED CTL_CODE(IOCTL_DISK_BASE, 0x003e, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif + +#ifndef IOCTL_VOLUME_POST_ONLINE +#define IOCTL_VOLUME_POST_ONLINE CTL_CODE(IOCTL_VOLUME_BASE, 25, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#endif + +#ifndef IOCTL_VOLUME_IS_DYNAMIC +#define IOCTL_VOLUME_IS_DYNAMIC CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif + +#ifndef StorageDeviceLBProvisioningProperty +#define StorageDeviceLBProvisioningProperty 11 +#endif + +#ifndef DeviceDsmAction_OffloadRead +#define DeviceDsmAction_OffloadRead ( 3 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_OffloadWrite +#define DeviceDsmAction_OffloadWrite 4 +#endif + +#ifndef DeviceDsmAction_Allocation +#define DeviceDsmAction_Allocation ( 5 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_Repair +#define DeviceDsmAction_Repair ( 6 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_Scrub +#define DeviceDsmAction_Scrub ( 7 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_DrtQuery +#define DeviceDsmAction_DrtQuery ( 8 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_DrtClear +#define DeviceDsmAction_DrtClear ( 9 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_DrtDisable +#define DeviceDsmAction_DrtDisable (10 | DeviceDsmActionFlag_NonDestructive) +#endif + /* Init section, which is thrown away as soon as DriverEntry returns */ #pragma alloc_text(INIT,DriverEntry) #pragma alloc_text(INIT,TCCreateRootDeviceObject) +/* We need to silence 'type cast' warning in order to use MmGetSystemRoutineAddress. + * MmGetSystemRoutineAddress() should have been declare FARPROC instead of PVOID. + */ +#pragma warning(disable:4055) + PDRIVER_OBJECT TCDriverObject; PDEVICE_OBJECT RootDeviceObject = NULL; static KMUTEX RootDeviceControlMutex; BOOL DriverShuttingDown = FALSE; @@ -56,66 +132,203 @@ BOOL PortableMode = FALSE; BOOL VolumeClassFilterRegistered = FALSE; BOOL CacheBootPassword = FALSE; BOOL CacheBootPim = FALSE; BOOL NonAdminSystemFavoritesAccessDisabled = FALSE; +BOOL BlockSystemTrimCommand = FALSE; +BOOL AllowWindowsDefrag = FALSE; +BOOL EraseKeysOnShutdown = TRUE; // by default, we erase encryption keys on system shutdown static size_t EncryptionThreadPoolFreeCpuCountLimit = 0; static BOOL SystemFavoriteVolumeDirty = FALSE; static BOOL PagingFileCreationPrevented = FALSE; static BOOL EnableExtendedIoctlSupport = FALSE; +static BOOL AllowTrimCommand = FALSE; +static BOOL RamEncryptionActivated = FALSE; +int EncryptionIoRequestCount = 0; +int EncryptionItemCount = 0; +int EncryptionFragmentSize = 0; +int EncryptionMaxWorkItems = 0; PDEVICE_OBJECT VirtualVolumeDeviceObjects[MAX_MOUNTED_VOLUME_DRIVE_NUMBER + 1]; +BOOL AlignValue (ULONG ulValue, ULONG ulAlignment, ULONG *pulResult) +{ + BOOL bRet = FALSE; + HRESULT hr; + if (ulAlignment == 0) + { + *pulResult = ulValue; + bRet = TRUE; + } + else + { + ulAlignment -= 1; + hr = ULongAdd (ulValue, ulAlignment, &ulValue); + if (S_OK == hr) + { + *pulResult = ulValue & (~ulAlignment); + bRet = TRUE; + } + } + + return bRet; +} + +BOOL IsUefiBoot () +{ + BOOL bStatus = FALSE; + NTSTATUS ntStatus = STATUS_NOT_IMPLEMENTED; + + Dump ("IsUefiBoot BEGIN\n"); + ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); + + ULONG valueLengh = 0; + UNICODE_STRING emptyName; + GUID guid; + RtlInitUnicodeString(&emptyName, L""); + memset (&guid, 0, sizeof(guid)); + Dump ("IsUefiBoot calling ExGetFirmwareEnvironmentVariable\n"); + ntStatus = ExGetFirmwareEnvironmentVariable (&emptyName, &guid, NULL, &valueLengh, NULL); + Dump ("IsUefiBoot ExGetFirmwareEnvironmentVariable returned 0x%08x\n", ntStatus); + + if (STATUS_NOT_IMPLEMENTED != ntStatus) + bStatus = TRUE; + + Dump ("IsUefiBoot bStatus = %s END\n", bStatus? "TRUE" : "FALSE"); + return bStatus; +} + +void GetDriverRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed) +{ + LARGE_INTEGER iSeed, iSeed2; + uint8 digest[WHIRLPOOL_DIGESTSIZE]; + WHIRLPOOL_CTX tctx; + size_t count; + + while (cbRandSeed) + { + WHIRLPOOL_init (&tctx); + // we hash current content of digest buffer which is uninitialized the first time + WHIRLPOOL_add (digest, WHIRLPOOL_DIGESTSIZE, &tctx); + + // we use various time information as source of entropy + KeQuerySystemTime( &iSeed ); + WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); + iSeed = KeQueryPerformanceCounter (&iSeed2); + WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); + WHIRLPOOL_add ((unsigned char *) &(iSeed2.QuadPart), sizeof(iSeed2.QuadPart), &tctx); + + iSeed.QuadPart = KeQueryInterruptTimePrecise ((PULONG64) & iSeed2.QuadPart); + WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); + WHIRLPOOL_add ((unsigned char *) &(iSeed2.QuadPart), sizeof(iSeed2.QuadPart), &tctx); + + /* use JitterEntropy library to get good quality random bytes based on CPU timing jitter */ + if (0 == jent_entropy_init ()) + { + struct rand_data *ec = jent_entropy_collector_alloc (1, 0); + if (ec) + { + ssize_t rndLen = jent_read_entropy (ec, (char*) digest, sizeof (digest)); + if (rndLen > 0) + WHIRLPOOL_add (digest, (unsigned int) rndLen, &tctx); + jent_entropy_collector_free (ec); + } + } + + // use RDSEED or RDRAND from CPU as source of entropy if enabled + if ( IsCpuRngEnabled() && + ( (HasRDSEED() && RDSEED_getBytes (digest, sizeof (digest))) + || (HasRDRAND() && RDRAND_getBytes (digest, sizeof (digest))) + )) + { + WHIRLPOOL_add (digest, sizeof(digest), &tctx); + } + WHIRLPOOL_finalize (&tctx, digest); + + count = VC_MIN (cbRandSeed, sizeof (digest)); + + // copy digest value to seed buffer + memcpy (pbRandSeed, digest, count); + cbRandSeed -= count; + pbRandSeed += count; + } + + FAST_ERASE64 (digest, sizeof (digest)); + FAST_ERASE64 (&iSeed.QuadPart, 8); + FAST_ERASE64 (&iSeed2.QuadPart, 8); + burn (&tctx, sizeof(tctx)); +} + -NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) +NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { PKEY_VALUE_PARTIAL_INFORMATION startKeyValue; LONG version; int i; - Dump ("DriverEntry " TC_APP_NAME " " VERSION_STRING "\n"); + Dump("DriverEntry " TC_APP_NAME " " VERSION_STRING VERSION_STRING_SUFFIX "\n"); - DetectX86Features (); + DetectX86Features(); - PsGetVersion (&OsMajorVersion, &OsMinorVersion, NULL, NULL); + PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL); - Dump ("OsMajorVersion=%d OsMinorVersion=%d\n", OsMajorVersion, OsMinorVersion); + Dump("OsMajorVersion=%d OsMinorVersion=%d\n", OsMajorVersion, OsMinorVersion); // Load dump filter if the main driver is already loaded - if (NT_SUCCESS (TCDeviceIoControl (NT_ROOT_PREFIX, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &version, sizeof (version)))) - return DumpFilterEntry ((PFILTER_EXTENSION) DriverObject, (PFILTER_INITIALIZATION_DATA) RegistryPath); + if (NT_SUCCESS(TCDeviceIoControl(NT_ROOT_PREFIX, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &version, sizeof(version)))) + return DumpFilterEntry((PFILTER_EXTENSION)DriverObject, (PFILTER_INITIALIZATION_DATA)RegistryPath); TCDriverObject = DriverObject; - memset (VirtualVolumeDeviceObjects, 0, sizeof (VirtualVolumeDeviceObjects)); + memset(VirtualVolumeDeviceObjects, 0, sizeof(VirtualVolumeDeviceObjects)); - ReadRegistryConfigFlags (TRUE); - EncryptionThreadPoolStart (EncryptionThreadPoolFreeCpuCountLimit); + ReadRegistryConfigFlags(TRUE); + EncryptionThreadPoolStart(EncryptionThreadPoolFreeCpuCountLimit); SelfTestsPassed = AutoTestAlgorithms(); // Enable device class filters and load boot arguments if the driver is set to start at system boot - if (NT_SUCCESS (TCReadRegistryKey (RegistryPath, L"Start", &startKeyValue))) + if (NT_SUCCESS(TCReadRegistryKey(RegistryPath, L"Start", &startKeyValue))) { - if (startKeyValue->Type == REG_DWORD && *((uint32 *) startKeyValue->Data) == SERVICE_BOOT_START) + if (startKeyValue->Type == REG_DWORD && *((uint32*)startKeyValue->Data) == SERVICE_BOOT_START) { if (!SelfTestsPassed) - TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + { + // in case of system encryption, if self-tests fail, disable all extended CPU + // features and try again in order to workaround faulty configurations + DisableCPUExtendedFeatures(); + SelfTestsPassed = AutoTestAlgorithms(); + + // BUG CHECK if the self-tests still fail + if (!SelfTestsPassed) + TC_BUG_CHECK(STATUS_INVALID_PARAMETER); + } - LoadBootArguments(); + LoadBootArguments(IsUefiBoot()); VolumeClassFilterRegistered = IsVolumeClassFilterRegistered(); DriverObject->DriverExtension->AddDevice = DriverAddDevice; } - TCfree (startKeyValue); + TCfree(startKeyValue); + } + + + if (RamEncryptionActivated) + { + if (t1ha_selfcheck__t1ha2() != 0) + TC_BUG_CHECK(STATUS_INVALID_PARAMETER); + if (!InitializeSecurityParameters(GetDriverRandomSeed)) + TC_BUG_CHECK(STATUS_INVALID_PARAMETER); + + EnableRamEncryption(TRUE); } for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) { DriverObject->MajorFunction[i] = TCDispatchQueueIRP; } DriverObject->DriverUnload = TCUnloadDriver; - return TCCreateRootDeviceObject (DriverObject); + return TCCreateRootDeviceObject(DriverObject); } NTSTATUS DriverAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) @@ -146,9 +359,9 @@ NTSTATUS DriverAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) return DriveFilterAddDevice (driverObject, pdo); } - +#if defined (DEBUG) || defined (DEBUG_TRACE) // Dumps a memory region to debug output void DumpMemory (void *mem, int size) { unsigned char str[20]; @@ -171,9 +384,68 @@ void DumpMemory (void *mem, int size) m+=8; } } +#endif + +BOOL IsAllZeroes (unsigned char* pbData, DWORD dwDataLen) +{ + while (dwDataLen--) + { + if (*pbData) + return FALSE; + pbData++; + } + return TRUE; +} + +static wchar_t UpperCaseUnicodeChar (wchar_t c) +{ + if (c >= L'a' && c <= L'z') + return (c - L'a') + L'A'; + return c; +} + +static BOOL StringNoCaseCompare (const wchar_t* str1, const wchar_t* str2, size_t len) +{ + if (str1 && str2) + { + while (len) + { + if (UpperCaseUnicodeChar (*str1) != UpperCaseUnicodeChar (*str2)) + return FALSE; + str1++; + str2++; + len--; + } + } + return TRUE; +} + +static BOOL CheckStringLength (const wchar_t* str, size_t cchSize, size_t minLength, size_t maxLength, size_t* pcchLength) +{ + size_t actualLength; + for (actualLength = 0; actualLength < cchSize; actualLength++) + { + if (str[actualLength] == 0) + break; + } + + if (pcchLength) + *pcchLength = actualLength; + + if (actualLength == cchSize) + return FALSE; + + if ((minLength != ((size_t) -1)) && (actualLength < minLength)) + return FALSE; + + if ((maxLength != ((size_t) -1)) && (actualLength > maxLength)) + return FALSE; + + return TRUE; +} BOOL ValidateIOBufferSize (PIRP irp, size_t requiredBufferSize, ValidateIOBufferSizeType type) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (irp); @@ -235,10 +507,11 @@ NTSTATUS TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp) case IOCTL_DISK_CHECK_VERIFY: break; default: - Dump ("%ls (0x%x %d)\n", + Dump ("%ls 0x%.8X (0x%.4X %d)\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode), + (int) (irpSp->Parameters.DeviceIoControl.IoControlCode), (int) (irpSp->Parameters.DeviceIoControl.IoControlCode >> 16), (int) ((irpSp->Parameters.DeviceIoControl.IoControlCode & 0x1FFF) >> 2)); } } @@ -515,8 +788,9 @@ IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400 NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); + UNREFERENCED_PARAMETER(DeviceObject); switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { @@ -566,9 +840,9 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION } else { ULONG outLength; - UCHAR volId[128], tmp[] = { 0,0 }; + CHAR volId[128], tmp[] = { 0,0 }; PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer; RtlStringCbCopyA (volId, sizeof(volId),TC_UNIQUE_ID_PREFIX); tmp[0] = 'A' + (UCHAR) Extension->nDosDriveNo; @@ -633,8 +907,10 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; case IOCTL_DISK_GET_MEDIA_TYPES: case IOCTL_DISK_GET_DRIVE_GEOMETRY: + case IOCTL_STORAGE_GET_MEDIA_TYPES: + case IOCTL_DISK_UPDATE_DRIVE_SIZE: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_GEOMETRY)\n"); /* Return the drive geometry for the disk. Note that we return values which were made up to suit the disk size. */ if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY), ValidateOutput)) @@ -651,23 +927,137 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Irp->IoStatus.Information = sizeof (DISK_GEOMETRY); } break; + case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)\n"); + { + ULONG minOutputSize = sizeof (DISK_GEOMETRY_EX); + ULONG fullOutputSize = sizeof (DISK_GEOMETRY) + sizeof (LARGE_INTEGER) + sizeof (DISK_PARTITION_INFO) + sizeof (DISK_DETECTION_INFO); + + if (ValidateIOBufferSize (Irp, minOutputSize, ValidateOutput)) + { + BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= fullOutputSize)? TRUE : FALSE; + PDISK_GEOMETRY_EX outputBuffer = (PDISK_GEOMETRY_EX) Irp->AssociatedIrp.SystemBuffer; + + outputBuffer->Geometry.MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia; + outputBuffer->Geometry.Cylinders.QuadPart = Extension->NumberOfCylinders; + outputBuffer->Geometry.TracksPerCylinder = Extension->TracksPerCylinder; + outputBuffer->Geometry.SectorsPerTrack = Extension->SectorsPerTrack; + outputBuffer->Geometry.BytesPerSector = Extension->BytesPerSector; + // Add 1MB to the disk size to emulate the geometry of a real MBR disk + outputBuffer->DiskSize.QuadPart = Extension->DiskLength + BYTES_PER_MB; + + if (bFullBuffer) + { + PDISK_PARTITION_INFO pPartInfo = (PDISK_PARTITION_INFO)(((ULONG_PTR) outputBuffer) + sizeof (DISK_GEOMETRY) + sizeof (LARGE_INTEGER)); + PDISK_DETECTION_INFO pDetectInfo = ((PDISK_DETECTION_INFO)((((ULONG_PTR) pPartInfo) + sizeof (DISK_PARTITION_INFO)))); + + pPartInfo->SizeOfPartitionInfo = sizeof (DISK_PARTITION_INFO); + pPartInfo->PartitionStyle = PARTITION_STYLE_MBR; + pPartInfo->Mbr.Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); + + pDetectInfo->SizeOfDetectInfo = sizeof (DISK_DETECTION_INFO); + + Irp->IoStatus.Information = fullOutputSize; + } + else + { + if (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof (DISK_GEOMETRY_EX)) + Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_EX); + else + Irp->IoStatus.Information = minOutputSize; + } + + Irp->IoStatus.Status = STATUS_SUCCESS; + } + } + break; + + case IOCTL_STORAGE_GET_MEDIA_TYPES_EX: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_GET_MEDIA_TYPES_EX)\n"); + if (ValidateIOBufferSize (Irp, sizeof (GET_MEDIA_TYPES), ValidateOutput)) + { + PGET_MEDIA_TYPES outputBuffer = (PGET_MEDIA_TYPES) + Irp->AssociatedIrp.SystemBuffer; + PDEVICE_MEDIA_INFO mediaInfo = &outputBuffer->MediaInfo[0]; + + outputBuffer->DeviceType = FILE_DEVICE_DISK; + outputBuffer->MediaInfoCount = 1; + + if (Extension->bRemovable) + { + mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1; + if (Extension->bReadOnly) + mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_ONLY | MEDIA_WRITE_PROTECTED); + else + mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_WRITE); + mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = (STORAGE_MEDIA_TYPE) RemovableMedia; + mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = Extension->NumberOfCylinders; + mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = Extension->TracksPerCylinder; + mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = Extension->SectorsPerTrack; + mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = Extension->BytesPerSector; + } + else + { + mediaInfo->DeviceSpecific.DiskInfo.NumberMediaSides = 1; + if (Extension->bReadOnly) + mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_ONLY | MEDIA_WRITE_PROTECTED); + else + mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_WRITE); + mediaInfo->DeviceSpecific.DiskInfo.MediaType = (STORAGE_MEDIA_TYPE) FixedMedia; + mediaInfo->DeviceSpecific.DiskInfo.Cylinders.QuadPart = Extension->NumberOfCylinders; + mediaInfo->DeviceSpecific.DiskInfo.TracksPerCylinder = Extension->TracksPerCylinder; + mediaInfo->DeviceSpecific.DiskInfo.SectorsPerTrack = Extension->SectorsPerTrack; + mediaInfo->DeviceSpecific.DiskInfo.BytesPerSector = Extension->BytesPerSector; + } + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (GET_MEDIA_TYPES); + } + break; + case IOCTL_STORAGE_QUERY_PROPERTY: - Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_QUERY_PROPERTY)\n"); - if (EnableExtendedIoctlSupport) + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_QUERY_PROPERTY)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport || Extension->TrimEnabled) { if (ValidateIOBufferSize (Irp, sizeof (STORAGE_PROPERTY_QUERY), ValidateInput)) { PSTORAGE_PROPERTY_QUERY pStoragePropQuery = (PSTORAGE_PROPERTY_QUERY) Irp->AssociatedIrp.SystemBuffer; STORAGE_QUERY_TYPE type = pStoragePropQuery->QueryType; - /* return error if an unsupported type is encountered */ - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - Irp->IoStatus.Information = 0; + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - PropertyId = %d, type = %d, InputBufferLength = %d, OutputBufferLength = %d\n", pStoragePropQuery->PropertyId, type, (int) irpSp->Parameters.DeviceIoControl.InputBufferLength, (int) irpSp->Parameters.DeviceIoControl.OutputBufferLength); - if ( (pStoragePropQuery->PropertyId == StorageAccessAlignmentProperty) + if (Extension->bRawDevice && + (pStoragePropQuery->PropertyId == (STORAGE_PROPERTY_ID) StorageDeviceLBProvisioningProperty) + ) + { + IO_STATUS_BLOCK IoStatus; + Dump ("ProcessVolumeDeviceControlIrp: sending IOCTL_STORAGE_QUERY_PROPERTY (%d) to device\n", (int) pStoragePropQuery->PropertyId); + Irp->IoStatus.Status = ZwDeviceIoControlFile ( + Extension->hDeviceFile, + NULL, + NULL, + NULL, + &IoStatus, + IOCTL_STORAGE_QUERY_PROPERTY, + Irp->AssociatedIrp.SystemBuffer, + irpSp->Parameters.DeviceIoControl.InputBufferLength, + Irp->AssociatedIrp.SystemBuffer, + irpSp->Parameters.DeviceIoControl.OutputBufferLength); + Dump ("ProcessVolumeDeviceControlIrp: ZwDeviceIoControlFile returned 0x%.8X\n", (DWORD) Irp->IoStatus.Status); + if (Irp->IoStatus.Status == STATUS_SUCCESS) + { + Irp->IoStatus.Status = IoStatus.Status; + Irp->IoStatus.Information = IoStatus.Information; + } + } + else if ( (pStoragePropQuery->PropertyId == StorageAccessAlignmentProperty) || (pStoragePropQuery->PropertyId == StorageDeviceProperty) + || (pStoragePropQuery->PropertyId == StorageAdapterProperty) + || (pStoragePropQuery->PropertyId == StorageDeviceSeekPenaltyProperty) + || (pStoragePropQuery->PropertyId == StorageDeviceTrimProperty) ) { if (type == PropertyExistsQuery) { @@ -675,48 +1065,144 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Irp->IoStatus.Information = 0; } else if (type == PropertyStandardQuery) { + ULONG descriptorSize; switch (pStoragePropQuery->PropertyId) { case StorageDeviceProperty: { - if (ValidateIOBufferSize (Irp, sizeof (STORAGE_DEVICE_DESCRIPTOR), ValidateOutput)) + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceProperty\n"); + /* Add 0x00 for NULL terminating string used as ProductId, ProductRevision, SerialNumber, VendorId */ + descriptorSize = sizeof (STORAGE_DEVICE_DESCRIPTOR) + 1; + if (ValidateIOBufferSize (Irp, descriptorSize, ValidateOutput)) { PSTORAGE_DEVICE_DESCRIPTOR outputBuffer = (PSTORAGE_DEVICE_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; outputBuffer->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR); - outputBuffer->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR); + outputBuffer->Size = descriptorSize; outputBuffer->DeviceType = FILE_DEVICE_DISK; outputBuffer->RemovableMedia = Extension->bRemovable? TRUE : FALSE; + outputBuffer->ProductIdOffset = sizeof (STORAGE_DEVICE_DESCRIPTOR); + outputBuffer->SerialNumberOffset = sizeof (STORAGE_DEVICE_DESCRIPTOR); + outputBuffer->ProductRevisionOffset = sizeof (STORAGE_DEVICE_DESCRIPTOR); + outputBuffer->VendorIdOffset = sizeof (STORAGE_DEVICE_DESCRIPTOR); + outputBuffer->BusType = BusTypeVirtual; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = descriptorSize; + } + else if (irpSp->Parameters.DeviceIoControl.OutputBufferLength == sizeof (STORAGE_DESCRIPTOR_HEADER)) + { + PSTORAGE_DESCRIPTOR_HEADER outputBuffer = (PSTORAGE_DESCRIPTOR_HEADER) Irp->AssociatedIrp.SystemBuffer; + outputBuffer->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR); + outputBuffer->Size = descriptorSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (STORAGE_DESCRIPTOR_HEADER); + } + } + break; + case StorageAdapterProperty: + { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageAdapterProperty\n"); + descriptorSize = sizeof (STORAGE_ADAPTER_DESCRIPTOR); + if (ValidateIOBufferSize (Irp, descriptorSize, ValidateOutput)) + { + PSTORAGE_ADAPTER_DESCRIPTOR outputBuffer = (PSTORAGE_ADAPTER_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; + + outputBuffer->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + outputBuffer->Size = descriptorSize; + outputBuffer->MaximumTransferLength = Extension->HostMaximumTransferLength; + outputBuffer->MaximumPhysicalPages = Extension->HostMaximumPhysicalPages; + outputBuffer->AlignmentMask = Extension->HostAlignmentMask; + outputBuffer->BusType = BusTypeVirtual; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = descriptorSize; + } + else if (irpSp->Parameters.DeviceIoControl.OutputBufferLength == sizeof (STORAGE_DESCRIPTOR_HEADER)) + { + PSTORAGE_DESCRIPTOR_HEADER outputBuffer = (PSTORAGE_DESCRIPTOR_HEADER) Irp->AssociatedIrp.SystemBuffer; + outputBuffer->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + outputBuffer->Size = descriptorSize; Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof (STORAGE_DEVICE_DESCRIPTOR); + Irp->IoStatus.Information = sizeof (STORAGE_DESCRIPTOR_HEADER); } } break; case StorageAccessAlignmentProperty: { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageAccessAlignmentProperty\n"); if (ValidateIOBufferSize (Irp, sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), ValidateOutput)) { PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR outputBuffer = (PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; outputBuffer->Version = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); outputBuffer->Size = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); outputBuffer->BytesPerLogicalSector = Extension->BytesPerSector; - outputBuffer->BytesPerPhysicalSector = Extension->HostBytesPerPhysicalSector; - outputBuffer->BytesOffsetForSectorAlignment = Extension->BytesOffsetForSectorAlignment; + outputBuffer->BytesPerPhysicalSector = Extension->HostBytesPerPhysicalSector; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); } + else if (irpSp->Parameters.DeviceIoControl.OutputBufferLength == sizeof (STORAGE_DESCRIPTOR_HEADER)) + { + PSTORAGE_DESCRIPTOR_HEADER outputBuffer = (PSTORAGE_DESCRIPTOR_HEADER) Irp->AssociatedIrp.SystemBuffer; + outputBuffer->Version = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); + outputBuffer->Size = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (STORAGE_DESCRIPTOR_HEADER); + } + } + break; + case StorageDeviceSeekPenaltyProperty: + { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceSeekPenaltyProperty\n"); + if (ValidateIOBufferSize (Irp, sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR), ValidateOutput)) + { + PDEVICE_SEEK_PENALTY_DESCRIPTOR outputBuffer = (PDEVICE_SEEK_PENALTY_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceSeekPenaltyProperty: set IncursSeekPenalty to %s\n", Extension->IncursSeekPenalty? "TRUE" : "FALSE"); + outputBuffer->Version = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + outputBuffer->Size = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + outputBuffer->IncursSeekPenalty = (BOOLEAN) Extension->IncursSeekPenalty; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR); + } + else if (irpSp->Parameters.DeviceIoControl.OutputBufferLength == sizeof (STORAGE_DESCRIPTOR_HEADER)) + { + PSTORAGE_DESCRIPTOR_HEADER outputBuffer = (PSTORAGE_DESCRIPTOR_HEADER) Irp->AssociatedIrp.SystemBuffer; + outputBuffer->Version = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + outputBuffer->Size = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (STORAGE_DESCRIPTOR_HEADER); + } + } + break; + case StorageDeviceTrimProperty: + { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceTrimProperty\n"); + if (ValidateIOBufferSize (Irp, sizeof (DEVICE_TRIM_DESCRIPTOR), ValidateOutput)) + { + PDEVICE_TRIM_DESCRIPTOR outputBuffer = (PDEVICE_TRIM_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceTrimProperty: set TrimEnabled to %s\n", Extension->TrimEnabled? "TRUE" : "FALSE"); + outputBuffer->Version = sizeof(DEVICE_TRIM_DESCRIPTOR); + outputBuffer->Size = sizeof(DEVICE_TRIM_DESCRIPTOR); + outputBuffer->TrimEnabled = (BOOLEAN) Extension->TrimEnabled; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (DEVICE_TRIM_DESCRIPTOR); + } + else if (irpSp->Parameters.DeviceIoControl.OutputBufferLength == sizeof (STORAGE_DESCRIPTOR_HEADER)) + { + PSTORAGE_DESCRIPTOR_HEADER outputBuffer = (PSTORAGE_DESCRIPTOR_HEADER) Irp->AssociatedIrp.SystemBuffer; + outputBuffer->Version = sizeof(DEVICE_TRIM_DESCRIPTOR); + outputBuffer->Size = sizeof(DEVICE_TRIM_DESCRIPTOR); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (STORAGE_DESCRIPTOR_HEADER); + } } break; } } } - } - } - else - return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); + } + } break; case IOCTL_DISK_GET_PARTITION_INFO: @@ -729,10 +1215,11 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION outputBuffer->PartitionType = Extension->PartitionType; outputBuffer->BootIndicator = FALSE; outputBuffer->RecognizedPartition = TRUE; outputBuffer->RewritePartition = FALSE; - outputBuffer->StartingOffset.QuadPart = Extension->BytesPerSector; + outputBuffer->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; + outputBuffer->PartitionNumber = 1; outputBuffer->HiddenSectors = 0; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); } @@ -745,10 +1232,11 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION PPARTITION_INFORMATION_EX outputBuffer = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->RewritePartition = FALSE; - outputBuffer->StartingOffset.QuadPart = Extension->BytesPerSector; + outputBuffer->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; + outputBuffer->PartitionNumber = 1; outputBuffer->Mbr.PartitionType = Extension->PartitionType; outputBuffer->Mbr.BootIndicator = FALSE; outputBuffer->Mbr.RecognizedPartition = TRUE; outputBuffer->Mbr.HiddenSectors = 0; @@ -760,24 +1248,67 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION case IOCTL_DISK_GET_DRIVE_LAYOUT: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_LAYOUT)\n"); if (ValidateIOBufferSize (Irp, sizeof (DRIVE_LAYOUT_INFORMATION), ValidateOutput)) { + BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= (sizeof (DRIVE_LAYOUT_INFORMATION) + 3*sizeof(PARTITION_INFORMATION)))? TRUE : FALSE; PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION) Irp->AssociatedIrp.SystemBuffer; - outputBuffer->PartitionCount = 1; - outputBuffer->Signature = 0; + outputBuffer->PartitionCount = bFullBuffer? 4 : 1; + outputBuffer->Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType; outputBuffer->PartitionEntry->BootIndicator = FALSE; outputBuffer->PartitionEntry->RecognizedPartition = TRUE; outputBuffer->PartitionEntry->RewritePartition = FALSE; - outputBuffer->PartitionEntry->StartingOffset.QuadPart = Extension->BytesPerSector; + outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; - outputBuffer->PartitionEntry->HiddenSectors = 0; + outputBuffer->PartitionEntry->PartitionNumber = 1; + outputBuffer->PartitionEntry->HiddenSectors = 0; Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); + Irp->IoStatus.Information = sizeof (DRIVE_LAYOUT_INFORMATION); + if (bFullBuffer) + { + Irp->IoStatus.Information += 3*sizeof(PARTITION_INFORMATION); + memset (((BYTE*) Irp->AssociatedIrp.SystemBuffer) + sizeof (DRIVE_LAYOUT_INFORMATION), 0, 3*sizeof(PARTITION_INFORMATION)); + } + } + break; + + case IOCTL_DISK_GET_DRIVE_LAYOUT_EX: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_LAYOUT_EX)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + if (ValidateIOBufferSize (Irp, sizeof (DRIVE_LAYOUT_INFORMATION_EX), ValidateOutput)) + { + BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= (sizeof (DRIVE_LAYOUT_INFORMATION_EX) + 3*sizeof(PARTITION_INFORMATION_EX)))? TRUE : FALSE; + PDRIVE_LAYOUT_INFORMATION_EX outputBuffer = (PDRIVE_LAYOUT_INFORMATION_EX) + Irp->AssociatedIrp.SystemBuffer; + + outputBuffer->PartitionCount = bFullBuffer? 4 : 1; + outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; + outputBuffer->Mbr.Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); + + outputBuffer->PartitionEntry->PartitionStyle = PARTITION_STYLE_MBR; + outputBuffer->PartitionEntry->Mbr.BootIndicator = FALSE; + outputBuffer->PartitionEntry->Mbr.RecognizedPartition = TRUE; + outputBuffer->PartitionEntry->RewritePartition = FALSE; + outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk + outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; + outputBuffer->PartitionEntry->PartitionNumber = 1; + outputBuffer->PartitionEntry->Mbr.HiddenSectors = 0; + outputBuffer->PartitionEntry->Mbr.PartitionType = Extension->PartitionType; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (DRIVE_LAYOUT_INFORMATION_EX); + if (bFullBuffer) + { + Irp->IoStatus.Information += 3*sizeof(PARTITION_INFORMATION_EX); + } + } } break; case IOCTL_DISK_GET_LENGTH_INFO: @@ -818,24 +1349,40 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; else { IO_STATUS_BLOCK ioStatus; - PVOID buffer = TCalloc (max (pVerifyInformation->Length, PAGE_SIZE)); + DWORD dwBuffersize = min (pVerifyInformation->Length, 16 * PAGE_SIZE); + PVOID buffer = TCalloc (dwBuffersize); if (!buffer) { Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; } else { - LARGE_INTEGER offset = pVerifyInformation->StartingOffset; + LARGE_INTEGER offset; + DWORD dwRemainingBytes = pVerifyInformation->Length, dwReadCount; offset.QuadPart = ullNewOffset; - Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, pVerifyInformation->Length, &offset, NULL); - TCfree (buffer); + while (dwRemainingBytes) + { + dwReadCount = min (dwBuffersize, dwRemainingBytes); + Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, dwReadCount, &offset, NULL); + + if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != dwReadCount) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + break; + } + else if (!NT_SUCCESS (Irp->IoStatus.Status)) + break; - if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != pVerifyInformation->Length) - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + dwRemainingBytes -= dwReadCount; + offset.QuadPart += (ULONGLONG) dwReadCount; + } + + burn (buffer, dwBuffersize); + TCfree (buffer); } } Irp->IoStatus.Information = 0; @@ -843,8 +1390,9 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; case IOCTL_DISK_CHECK_VERIFY: case IOCTL_STORAGE_CHECK_VERIFY: + case IOCTL_STORAGE_CHECK_VERIFY2: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_CHECK_VERIFY)\n"); { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -874,29 +1422,156 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; break; - case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: - Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n"); - // Vista's filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed. - if (!(OsMajorVersion == 6 && OsMinorVersion == 0)) + case IOCTL_VOLUME_POST_ONLINE: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_POST_ONLINE)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) { - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; } - else if (ValidateIOBufferSize (Irp, sizeof (VOLUME_DISK_EXTENTS), ValidateOutput)) + break; + + case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n"); + // Vista's, Windows 8.1 and later filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed. + if (ValidateIOBufferSize(Irp, sizeof(VOLUME_DISK_EXTENTS), ValidateOutput)) { - VOLUME_DISK_EXTENTS *extents = (VOLUME_DISK_EXTENTS *) Irp->AssociatedIrp.SystemBuffer; + VOLUME_DISK_EXTENTS* extents = (VOLUME_DISK_EXTENTS*)Irp->AssociatedIrp.SystemBuffer; - // No extent data can be returned as this is not a physical drive. - memset (extents, 0, sizeof (*extents)); - extents->NumberOfDiskExtents = 0; + // Windows 10 filesystem defragmenter works only if we report an extent with a real disk number + // So in the case of a VeraCrypt disk based volume, we use the disk number + // of the underlaying physical disk and we report a single extent + extents->NumberOfDiskExtents = 1; + extents->Extents[0].DiskNumber = Extension->DeviceNumber; + extents->Extents[0].StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk + extents->Extents[0].ExtentLength.QuadPart = Extension->DiskLength; Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof (*extents); + Irp->IoStatus.Information = sizeof(*extents); + } + break; + + case IOCTL_STORAGE_READ_CAPACITY: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_READ_CAPACITY)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + if (ValidateIOBufferSize (Irp, sizeof (STORAGE_READ_CAPACITY), ValidateOutput)) + { + STORAGE_READ_CAPACITY *capacity = (STORAGE_READ_CAPACITY *) Irp->AssociatedIrp.SystemBuffer; + + capacity->Version = sizeof (STORAGE_READ_CAPACITY); + capacity->Size = sizeof (STORAGE_READ_CAPACITY); + capacity->BlockLength = Extension->BytesPerSector; + capacity->DiskLength.QuadPart = Extension->DiskLength + BYTES_PER_MB; // Add 1MB to the disk size to emulate the geometry of a real MBR disk + capacity->NumberOfBlocks.QuadPart = capacity->DiskLength.QuadPart / capacity->BlockLength; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (STORAGE_READ_CAPACITY); + } + } + break; + + /*case IOCTL_STORAGE_GET_DEVICE_NUMBER: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_GET_DEVICE_NUMBER)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + if (ValidateIOBufferSize (Irp, sizeof (STORAGE_DEVICE_NUMBER), ValidateOutput)) + { + STORAGE_DEVICE_NUMBER *storage = (STORAGE_DEVICE_NUMBER *) Irp->AssociatedIrp.SystemBuffer; + + storage->DeviceType = FILE_DEVICE_DISK; + storage->DeviceNumber = (ULONG) -1; + storage->PartitionNumber = 1; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (STORAGE_DEVICE_NUMBER); + } + } + break;*/ + + case IOCTL_STORAGE_GET_HOTPLUG_INFO: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_GET_HOTPLUG_INFO)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + if (ValidateIOBufferSize (Irp, sizeof (STORAGE_HOTPLUG_INFO), ValidateOutput)) + { + STORAGE_HOTPLUG_INFO *info = (STORAGE_HOTPLUG_INFO *) Irp->AssociatedIrp.SystemBuffer; + + info->Size = sizeof (STORAGE_HOTPLUG_INFO); + info->MediaRemovable = Extension->bRemovable? TRUE : FALSE; + info->MediaHotplug = FALSE; + info->DeviceHotplug = FALSE; + info->WriteCacheEnableOverride = FALSE; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (STORAGE_HOTPLUG_INFO); + } + } + break; + + case IOCTL_VOLUME_IS_DYNAMIC: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_IS_DYNAMIC)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + if (ValidateIOBufferSize (Irp, sizeof (BOOLEAN), ValidateOutput)) + { + BOOLEAN *pbDynamic = (BOOLEAN*) Irp->AssociatedIrp.SystemBuffer; + + *pbDynamic = FALSE; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (BOOLEAN); + } + } + break; + + case IOCTL_DISK_IS_CLUSTERED: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_IS_CLUSTERED)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + if (ValidateIOBufferSize (Irp, sizeof (BOOLEAN), ValidateOutput)) + { + BOOLEAN *pbIsClustered = (BOOLEAN*) Irp->AssociatedIrp.SystemBuffer; + + *pbIsClustered = FALSE; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (BOOLEAN); + } } break; + case IOCTL_VOLUME_GET_GPT_ATTRIBUTES: + Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_GPT_ATTRIBUTES)\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + if (ValidateIOBufferSize (Irp, sizeof (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION), ValidateOutput)) + { + VOLUME_GET_GPT_ATTRIBUTES_INFORMATION *pGptAttr = (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION*) Irp->AssociatedIrp.SystemBuffer; + + pGptAttr->GptAttributes = 0; // we are MBR not GPT + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION); + } + } + break; case IOCTL_UNKNOWN_WINDOWS10_EFS_ACCESS: // This undocumented IOCTL is sent when handling EFS data // We must return success otherwise EFS operations fail @@ -904,12 +1579,257 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; break; + + case IOCTL_DISK_UPDATE_PROPERTIES: + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_SUCCESS for IOCTL_DISK_UPDATE_PROPERTIES\n"); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + break; + + case IOCTL_DISK_MEDIA_REMOVAL: + case IOCTL_STORAGE_MEDIA_REMOVAL: + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_SUCCESS for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + break; + + case IOCTL_DISK_GET_CLUSTER_INFO: + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_NOT_SUPPORTED for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (EnableExtendedIoctlSupport) + { + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Information = 0; + } + break; + + case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (Extension->bRawDevice && Extension->TrimEnabled) + { + if (ValidateIOBufferSize (Irp, sizeof (DEVICE_MANAGE_DATA_SET_ATTRIBUTES), ValidateInput)) + { + DWORD inputLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; + PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pInputAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer; + DEVICE_DATA_MANAGEMENT_SET_ACTION action = pInputAttrs->Action; + BOOL bEntireSet = pInputAttrs->Flags & DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE? TRUE : FALSE; + ULONGLONG minSizedataSet = (ULONGLONG) pInputAttrs->DataSetRangesOffset + (ULONGLONG) pInputAttrs->DataSetRangesLength; + ULONGLONG minSizeParameter = (ULONGLONG) pInputAttrs->ParameterBlockOffset + (ULONGLONG) pInputAttrs->ParameterBlockLength; + ULONGLONG minSizeGeneric = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + (ULONGLONG) pInputAttrs->ParameterBlockLength + (ULONGLONG) pInputAttrs->DataSetRangesLength; + PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pNewSetAttrs = NULL; + ULONG ulNewInputLength = 0; + BOOL bForwardIoctl = FALSE; + + if (((ULONGLONG) inputLength) >= minSizeGeneric && ((ULONGLONG) inputLength) >= minSizedataSet && ((ULONGLONG) inputLength) >= minSizeParameter) + { + if (bEntireSet) + { + if (minSizedataSet) + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data set range specified=> Error.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + else + { + DWORD dwDataSetOffset; + DWORD dwDataSetLength = sizeof(DEVICE_DATA_SET_RANGE); + + if (AlignValue (inputLength, sizeof(DEVICE_DATA_SET_RANGE), &dwDataSetOffset)) + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set. Setting data range to all volume.\n"); + + if (S_OK == ULongAdd(dwDataSetOffset, dwDataSetLength, &ulNewInputLength)) + { + pNewSetAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) TCalloc (ulNewInputLength); + if (pNewSetAttrs) + { + PDEVICE_DATA_SET_RANGE pRange = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + dwDataSetOffset); + + memcpy (pNewSetAttrs, pInputAttrs, inputLength); + + pRange->StartingOffset = (ULONGLONG) Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset; + pRange->LengthInBytes = Extension->DiskLength; + + pNewSetAttrs->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES); + pNewSetAttrs->Action = action; + pNewSetAttrs->Flags = pInputAttrs->Flags & (~DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE); + pNewSetAttrs->ParameterBlockOffset = pInputAttrs->ParameterBlockOffset; + pNewSetAttrs->ParameterBlockLength = pInputAttrs->ParameterBlockLength; + pNewSetAttrs->DataSetRangesOffset = dwDataSetOffset; + pNewSetAttrs->DataSetRangesLength = dwDataSetLength; + + bForwardIoctl = TRUE; + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - Failed to allocate memory.\n"); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data range length computation overflowed.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data set offset computation overflowed.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - creating new data set range from input range.\n"); + ulNewInputLength = inputLength; + pNewSetAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) TCalloc (inputLength); + if (pNewSetAttrs) + { + PDEVICE_DATA_SET_RANGE pNewRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + pInputAttrs->DataSetRangesOffset); + PDEVICE_DATA_SET_RANGE pInputRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pInputAttrs) + pInputAttrs->DataSetRangesOffset); + DWORD dwInputRangesCount = 0, dwNewRangesCount = 0, i; + ULONGLONG ullStartingOffset, ullNewOffset, ullEndOffset; + HRESULT hResult; + + memcpy (pNewSetAttrs, pInputAttrs, inputLength); + + dwInputRangesCount = pInputAttrs->DataSetRangesLength / sizeof(DEVICE_DATA_SET_RANGE); + + for (i = 0; i < dwInputRangesCount; i++) + { + ullStartingOffset = (ULONGLONG) pInputRanges[i].StartingOffset; + hResult = ULongLongAdd(ullStartingOffset, + (ULONGLONG) Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset, + &ullNewOffset); + if (hResult != S_OK) + continue; + else if (S_OK != ULongLongAdd(ullStartingOffset, (ULONGLONG) pInputRanges[i].LengthInBytes, &ullEndOffset)) + continue; + else if (ullEndOffset > (ULONGLONG) Extension->DiskLength) + continue; + else if (ullNewOffset > 0) + { + pNewRanges[dwNewRangesCount].StartingOffset = (LONGLONG) ullNewOffset; + pNewRanges[dwNewRangesCount].LengthInBytes = pInputRanges[i].LengthInBytes; + + dwNewRangesCount++; + } + } + + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - %d valid range processed from %d range in input.\n", (int) dwNewRangesCount, (int) dwInputRangesCount); + + pNewSetAttrs->DataSetRangesLength = dwNewRangesCount * sizeof (DEVICE_DATA_SET_RANGE); + + bForwardIoctl = TRUE; + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - Failed to allocate memory.\n"); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + } + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - buffer containing DEVICE_MANAGE_DATA_SET_ATTRIBUTES has invalid length.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + + + if (bForwardIoctl) + { + if (action == DeviceDsmAction_Trim) + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Trim.\n"); + + if (Extension->cryptoInfo->hiddenVolume || !AllowTrimCommand) + { + Dump ("ProcessVolumeDeviceControlIrp: TRIM command filtered\n"); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + } + else + { + IO_STATUS_BLOCK IoStatus; + Dump ("ProcessVolumeDeviceControlIrp: sending TRIM to device\n"); + Irp->IoStatus.Status = ZwDeviceIoControlFile ( + Extension->hDeviceFile, + NULL, + NULL, + NULL, + &IoStatus, + IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, + (PVOID) pNewSetAttrs, + ulNewInputLength, + NULL, + 0); + Dump ("ProcessVolumeDeviceControlIrp: ZwDeviceIoControlFile returned 0x%.8X\n", (DWORD) Irp->IoStatus.Status); + if (Irp->IoStatus.Status == STATUS_SUCCESS) + { + Irp->IoStatus.Status = IoStatus.Status; + Irp->IoStatus.Information = IoStatus.Information; + } + else + Irp->IoStatus.Information = 0; + } + } + else + { + switch (action) + { + case DeviceDsmAction_Notification: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Notification\n"); break; + case DeviceDsmAction_OffloadRead: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_OffloadRead\n"); break; + case DeviceDsmAction_OffloadWrite: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_OffloadWrite\n"); break; + case DeviceDsmAction_Allocation: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Allocation\n"); break; + case DeviceDsmAction_Scrub: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Scrub\n"); break; + case DeviceDsmAction_DrtQuery: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_DrtQuery\n"); break; + case DeviceDsmAction_DrtClear: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_DrtClear\n"); break; + case DeviceDsmAction_DrtDisable: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_DrtDisable\n"); break; + default: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - unknown action %d\n", (int) action); break; + } + + } + } + + if (pNewSetAttrs) + TCfree (pNewSetAttrs); + } + } +#if defined (DEBUG) || defined (DEBUG_TRACE) + else + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_INVALID_DEVICE_REQUEST for IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); +#endif + break; + + case IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT: + case IOCTL_VOLUME_QUERY_ALLOCATION_HINT: + case FT_BALANCED_READ_MODE: + case IOCTL_STORAGE_GET_DEVICE_NUMBER: + case IOCTL_MOUNTDEV_LINK_CREATED: + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_INVALID_DEVICE_REQUEST for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + break; default: - Dump ("ProcessVolumeDeviceControlIrp (unknown code 0x%.8X)\n", irpSp->Parameters.DeviceIoControl.IoControlCode); - return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); - } + Dump ("ProcessVolumeDeviceControlIrp: unknown code 0x%.8X (0x%.4X %d)\n", irpSp->Parameters.DeviceIoControl.IoControlCode, + (int)(irpSp->Parameters.DeviceIoControl.IoControlCode >> 16), + (int)((irpSp->Parameters.DeviceIoControl.IoControlCode & 0x1FFF) >> 2)); + return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); + } #if defined(DEBUG) || defined (DEBG_TRACE) if (!NT_SUCCESS (Irp->IoStatus.Status)) { @@ -927,13 +1847,14 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); NTSTATUS ntStatus; + UNREFERENCED_PARAMETER(Extension); switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case TC_IOCTL_GET_DRIVER_VERSION: - case TC_IOCTL_LEGACY_GET_DRIVER_VERSION: + if (ValidateIOBufferSize (Irp, sizeof (LONG), ValidateOutput)) { LONG tmp = VERSION_NUM; memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4); @@ -953,9 +1874,9 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex case TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED: if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) { - LONG deviceObjectCount = 0; + ULONG deviceObjectCount = 0; *(int *) Irp->AssociatedIrp.SystemBuffer = DriverUnloadDisabled; if (IoEnumerateDeviceObjectList (TCDriverObject, NULL, 0, &deviceObjectCount) == STATUS_BUFFER_TOO_SMALL && deviceObjectCount > 1) @@ -1001,14 +1922,33 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (!ValidateIOBufferSize (Irp, sizeof (OPEN_TEST_STRUCT), ValidateInputOutput)) break; + if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (OPEN_TEST_STRUCT)) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + + // check that opentest->wszFileName is a device path that starts with "\\Device\\Harddisk" + // 16 is the length of "\\Device\\Harddisk" which is the minimum + if ( !CheckStringLength (opentest->wszFileName, TC_MAX_PATH, 16, (size_t) -1, NULL) + || (!StringNoCaseCompare (opentest->wszFileName, L"\\Device\\Harddisk", 16)) + ) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + + EnsureNullTerminatedString (opentest->wszFileName, sizeof (opentest->wszFileName)); RtlInitUnicodeString (&FullFileName, opentest->wszFileName); InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); - if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bMatchVolumeID) + if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bComputeVolumeIDs) access |= FILE_READ_DATA; ntStatus = ZwCreateFile (&NtFileHandle, SYNCHRONIZE | access, &ObjectAttributes, &IoStatus, NULL, @@ -1017,13 +1957,14 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (NT_SUCCESS (ntStatus)) { opentest->TCBootLoaderDetected = FALSE; opentest->FilesystemDetected = FALSE; - opentest->VolumeIDMatched = FALSE; + memset (opentest->VolumeIDComputed, 0, sizeof (opentest->VolumeIDComputed)); + memset (opentest->volumeIDs, 0, sizeof (opentest->volumeIDs)); - if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bMatchVolumeID) + if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bComputeVolumeIDs) { - byte *readBuffer = TCalloc (TC_MAX_VOLUME_SECTOR_SIZE); + uint8 *readBuffer = TCalloc (TC_MAX_VOLUME_SECTOR_SIZE); if (!readBuffer) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; } @@ -1065,25 +2006,32 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (opentest->DetectFilesystem && IoStatus.Information >= sizeof (int64)) { switch (BE64 (*(uint64 *) readBuffer)) { - case 0xEB52904E54465320: // NTFS - case 0xEB3C904D53444F53: // FAT16 - case 0xEB58904D53444F53: // FAT32 - case 0xEB76904558464154: // exFAT - + case 0xEB52904E54465320ULL: // NTFS + case 0xEB3C904D53444F53ULL: // FAT16/FAT32 + case 0xEB58904D53444F53ULL: // FAT32 + case 0xEB76904558464154ULL: // exFAT + case 0x0000005265465300ULL: // ReFS + case 0xEB58906D6B66732EULL: // FAT32 mkfs.fat + case 0xEB58906D6B646F73ULL: // FAT32 mkfs.vfat/mkdosfs + case 0xEB3C906D6B66732EULL: // FAT16/FAT12 mkfs.fat + case 0xEB3C906D6B646F73ULL: // FAT16/FAT12 mkfs.vfat/mkdosfs opentest->FilesystemDetected = TRUE; break; + case 0x0000000000000000ULL: + // all 512 bytes are zeroes => unencrypted filesystem like Microsoft reserved partition + if (IsAllZeroes (readBuffer + 8, TC_VOLUME_HEADER_EFFECTIVE_SIZE - 8)) + opentest->FilesystemDetected = TRUE; + break; } } } } - if (opentest->bMatchVolumeID) + if (opentest->bComputeVolumeIDs && (!opentest->DetectFilesystem || !opentest->FilesystemDetected)) { int volumeType; - BYTE volumeID[VOLUME_ID_SIZE]; - // Go through all volume types (e.g., normal, hidden) for (volumeType = TC_VOLUME_TYPE_NORMAL; volumeType < TC_VOLUME_TYPE_COUNT; volumeType++) @@ -1110,18 +2058,13 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex TC_MAX_VOLUME_SECTOR_SIZE, &offset, NULL); - if (NT_SUCCESS (ntStatus)) + if (NT_SUCCESS (ntStatus) && (IoStatus.Information >= TC_VOLUME_HEADER_EFFECTIVE_SIZE)) { /* compute the ID of this volume: SHA-256 of the effective header */ - sha256 (volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); - - if (0 == memcmp (volumeID, opentest->volumeID, VOLUME_ID_SIZE)) - { - opentest->VolumeIDMatched = TRUE; - break; - } + sha256 (opentest->volumeIDs[volumeType], readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); + opentest->VolumeIDComputed[volumeType] = TRUE; } } } @@ -1151,13 +2094,28 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex HANDLE NtFileHandle; UNICODE_STRING FullFileName; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER offset; - byte readBuffer [TC_SECTOR_SIZE_BIOS]; + size_t devicePathLen = 0; + WCHAR* wszPath = NULL; if (!ValidateIOBufferSize (Irp, sizeof (GetSystemDriveConfigurationRequest), ValidateInputOutput)) break; + // check that request->DevicePath has the expected format "\\Device\\HarddiskXXX\\Partition0" + // 28 is the length of "\\Device\\Harddisk0\\Partition0" which is the minimum + // 30 is the length of "\\Device\\Harddisk255\\Partition0" which is the maximum + wszPath = request->DevicePath; + if ( !CheckStringLength (wszPath, TC_MAX_PATH, 28, 30, &devicePathLen) + || (memcmp (wszPath, L"\\Device\\Harddisk", 16 * sizeof (WCHAR))) + || (memcmp (wszPath + (devicePathLen - 11), L"\\Partition0", 11 * sizeof (WCHAR))) + ) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + EnsureNullTerminatedString (request->DevicePath, sizeof (request->DevicePath)); RtlInitUnicodeString (&FullFileName, request->DevicePath); InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); @@ -1167,70 +2125,89 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_RANDOM_ACCESS, NULL, 0); if (NT_SUCCESS (ntStatus)) { - // Determine if the first sector contains a portion of the VeraCrypt Boot Loader - offset.QuadPart = 0; // MBR - - ntStatus = ZwReadFile (NtFileHandle, - NULL, - NULL, - NULL, - &IoStatus, - readBuffer, - sizeof(readBuffer), - &offset, - NULL); - - if (NT_SUCCESS (ntStatus)) + uint8 *readBuffer = TCalloc (TC_MAX_VOLUME_SECTOR_SIZE); + if (!readBuffer) { - size_t i; - - // Check for dynamic drive - request->DriveIsDynamic = FALSE; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + } + else + { + // Determine if the first sector contains a portion of the VeraCrypt Boot Loader + offset.QuadPart = 0; // MBR + + ntStatus = ZwReadFile (NtFileHandle, + NULL, + NULL, + NULL, + &IoStatus, + readBuffer, + TC_MAX_VOLUME_SECTOR_SIZE, + &offset, + NULL); - if (readBuffer[510] == 0x55 && readBuffer[511] == 0xaa) + if (NT_SUCCESS (ntStatus)) { - int i; - for (i = 0; i < 4; ++i) + // check that we could read all needed data + if (IoStatus.Information >= TC_SECTOR_SIZE_BIOS) { - if (readBuffer[446 + i * 16 + 4] == PARTITION_LDM) + size_t i; + + // Check for dynamic drive + request->DriveIsDynamic = FALSE; + + if (readBuffer[510] == 0x55 && readBuffer[511] == 0xaa) { - request->DriveIsDynamic = TRUE; - break; + for (i = 0; i < 4; ++i) + { + if (readBuffer[446 + i * 16 + 4] == PARTITION_LDM) + { + request->DriveIsDynamic = TRUE; + break; + } + } } - } - } - - request->BootLoaderVersion = 0; - request->Configuration = 0; - request->UserConfiguration = 0; - request->CustomUserMessage[0] = 0; - // Search for the string "VeraCrypt" - for (i = 0; i < sizeof (readBuffer) - strlen (TC_APP_NAME); ++i) - { - if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) - { - request->BootLoaderVersion = BE16 (*(uint16 *) (readBuffer + TC_BOOT_SECTOR_VERSION_OFFSET)); - request->Configuration = readBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET]; + request->BootLoaderVersion = 0; + request->Configuration = 0; + request->UserConfiguration = 0; + request->CustomUserMessage[0] = 0; - if (request->BootLoaderVersion != 0 && request->BootLoaderVersion <= VERSION_NUM) + // Search for the string "VeraCrypt" + for (i = 0; i < TC_SECTOR_SIZE_BIOS - strlen (TC_APP_NAME); ++i) { - request->UserConfiguration = readBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; - memcpy (request->CustomUserMessage, readBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); + if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) + { + request->BootLoaderVersion = BE16 (*(uint16 *) (readBuffer + TC_BOOT_SECTOR_VERSION_OFFSET)); + request->Configuration = readBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET]; + + if (request->BootLoaderVersion != 0 && request->BootLoaderVersion <= VERSION_NUM) + { + request->UserConfiguration = readBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; + memcpy (request->CustomUserMessage, readBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); + } + break; + } } - break; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (*request); + } + else + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; } } + else + { + Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Information = 0; + } - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof (*request); - } - else - { - Irp->IoStatus.Status = ntStatus; - Irp->IoStatus.Information = 0; + TCfree (readBuffer); } ZwClose (NtFileHandle); @@ -1307,32 +2284,16 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex else if (ListExtension->cryptoInfo->bProtectHiddenVolume) list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected) else list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume - list->truecryptMode[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->bTrueCryptMode; } } Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT); } break; - case TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES: - if (ValidateIOBufferSize (Irp, sizeof (uint32), ValidateOutput)) - { - // Prevent the user from downgrading to versions lower than 5.0 by faking mounted volumes. - // The user could render the system unbootable by downgrading when boot encryption - // is active or being set up. - - memset (Irp->AssociatedIrp.SystemBuffer, 0, irpSp->Parameters.DeviceIoControl.OutputBufferLength); - *(uint32 *) Irp->AssociatedIrp.SystemBuffer = 0xffffFFFF; - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = irpSp->Parameters.DeviceIoControl.OutputBufferLength; - } - break; - case TC_IOCTL_GET_VOLUME_PROPERTIES: if (ValidateIOBufferSize (Irp, sizeof (VOLUME_PROPERTIES_STRUCT), ValidateInputOutput)) { VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer; @@ -1363,8 +2324,9 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex #endif prop->volumeHeaderFlags = ListExtension->cryptoInfo->HeaderFlags; prop->readOnly = ListExtension->bReadOnly; prop->removable = ListExtension->bRemovable; + prop->mountDisabled = ListExtension->bMountManager? FALSE : TRUE; prop->partitionInInactiveSysEncScope = ListExtension->PartitionInInactiveSysEncScope; prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume; if (ListExtension->cryptoInfo->bProtectHiddenVolume) @@ -1388,18 +2350,18 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (ValidateIOBufferSize (Irp, sizeof (RESOLVE_SYMLINK_STRUCT), ValidateInputOutput)) { RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer; { - NTSTATUS ntStatus; + NTSTATUS ntStatusLocal; EnsureNullTerminatedString (resolve->symLinkName, sizeof (resolve->symLinkName)); - ntStatus = SymbolicLinkToTarget (resolve->symLinkName, + ntStatusLocal = SymbolicLinkToTarget (resolve->symLinkName, resolve->targetName, sizeof (resolve->targetName)); Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT); - Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Status = ntStatusLocal; } } break; @@ -1408,14 +2370,14 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex { DISK_PARTITION_INFO_STRUCT *info = (DISK_PARTITION_INFO_STRUCT *) Irp->AssociatedIrp.SystemBuffer; { PARTITION_INFORMATION_EX pi; - NTSTATUS ntStatus; + NTSTATUS ntStatusLocal; EnsureNullTerminatedString (info->deviceName, sizeof (info->deviceName)); - ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi)); - if (NT_SUCCESS(ntStatus)) + ntStatusLocal = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi)); + if (NT_SUCCESS(ntStatusLocal)) { memset (&info->partInfo, 0, sizeof (info->partInfo)); info->partInfo.PartitionLength = pi.PartitionLength; @@ -1432,35 +2394,35 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex } else { // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX - ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo)); + ntStatusLocal = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo)); info->IsGPT = FALSE; } - if (!NT_SUCCESS (ntStatus)) + if (!NT_SUCCESS (ntStatusLocal)) { GET_LENGTH_INFORMATION lengthInfo; - ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &lengthInfo, sizeof (lengthInfo)); + ntStatusLocal = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &lengthInfo, sizeof (lengthInfo)); - if (NT_SUCCESS (ntStatus)) + if (NT_SUCCESS (ntStatusLocal)) { memset (&info->partInfo, 0, sizeof (info->partInfo)); info->partInfo.PartitionLength = lengthInfo.Length; } } info->IsDynamic = FALSE; - if (NT_SUCCESS (ntStatus) && OsMajorVersion >= 6) + if (NT_SUCCESS (ntStatusLocal)) { # define IOCTL_VOLUME_IS_DYNAMIC CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS) if (!NT_SUCCESS (TCDeviceIoControl (info->deviceName, IOCTL_VOLUME_IS_DYNAMIC, NULL, 0, &info->IsDynamic, sizeof (info->IsDynamic)))) info->IsDynamic = FALSE; } Irp->IoStatus.Information = sizeof (DISK_PARTITION_INFO_STRUCT); - Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Status = ntStatusLocal; } } break; @@ -1468,18 +2430,84 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY_STRUCT), ValidateInputOutput)) { DISK_GEOMETRY_STRUCT *g = (DISK_GEOMETRY_STRUCT *) Irp->AssociatedIrp.SystemBuffer; { - NTSTATUS ntStatus; + NTSTATUS ntStatusLocal; EnsureNullTerminatedString (g->deviceName, sizeof (g->deviceName)); + Dump ("Calling IOCTL_DISK_GET_DRIVE_GEOMETRY on %ls\n", g->deviceName); - ntStatus = TCDeviceIoControl (g->deviceName, + ntStatusLocal = TCDeviceIoControl (g->deviceName, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &g->diskGeometry, sizeof (g->diskGeometry)); Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_STRUCT); - Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Status = ntStatusLocal; + } + } + break; + + case VC_IOCTL_GET_DRIVE_GEOMETRY_EX: + if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY_EX_STRUCT), ValidateInputOutput)) + { + DISK_GEOMETRY_EX_STRUCT *g = (DISK_GEOMETRY_EX_STRUCT *) Irp->AssociatedIrp.SystemBuffer; + { + NTSTATUS ntStatusLocal; + PVOID buffer = TCalloc (256); // enough for DISK_GEOMETRY_EX and padded data + if (buffer) + { + EnsureNullTerminatedString (g->deviceName, sizeof (g->deviceName)); + Dump ("Calling IOCTL_DISK_GET_DRIVE_GEOMETRY_EX on %ls\n", g->deviceName); + + ntStatusLocal = TCDeviceIoControl (g->deviceName, + IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, + NULL, 0, buffer, 256); + + if (NT_SUCCESS(ntStatusLocal)) + { + PDISK_GEOMETRY_EX pGeo = (PDISK_GEOMETRY_EX) buffer; + memcpy (&g->diskGeometry, &pGeo->Geometry, sizeof (DISK_GEOMETRY)); + g->DiskSize.QuadPart = pGeo->DiskSize.QuadPart; + } + else + { + DISK_GEOMETRY dg = {0}; + Dump ("Failed. Calling IOCTL_DISK_GET_DRIVE_GEOMETRY on %ls\n", g->deviceName); + ntStatusLocal = TCDeviceIoControl (g->deviceName, + IOCTL_DISK_GET_DRIVE_GEOMETRY, + NULL, 0, &dg, sizeof (dg)); + + if (NT_SUCCESS(ntStatusLocal)) + { + memcpy(&g->diskGeometry, &dg, sizeof(DISK_GEOMETRY)); + g->DiskSize.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector; + + STORAGE_READ_CAPACITY storage = { 0 }; + NTSTATUS lStatus; + storage.Version = sizeof(STORAGE_READ_CAPACITY); + Dump("Calling IOCTL_STORAGE_READ_CAPACITY on %ls\n", g->deviceName); + lStatus = TCDeviceIoControl(g->deviceName, + IOCTL_STORAGE_READ_CAPACITY, + NULL, 0, &storage, sizeof(STORAGE_READ_CAPACITY)); + if (NT_SUCCESS(lStatus) + && (storage.Size == sizeof(STORAGE_READ_CAPACITY)) + ) + { + g->DiskSize.QuadPart = storage.DiskLength.QuadPart; + } + } + } + + TCfree (buffer); + + Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_EX_STRUCT); + Irp->IoStatus.Status = ntStatusLocal; + } + else + { + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + } } } break; @@ -1530,13 +2558,13 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (ValidateIOBufferSize (Irp, sizeof (MOUNT_STRUCT), ValidateInputOutput)) { MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; - if (mount->VolumePassword.Length > MAX_PASSWORD || mount->ProtectedHidVolPassword.Length > MAX_PASSWORD + if ((irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (MOUNT_STRUCT)) + || mount->VolumePassword.Length > MAX_PASSWORD || mount->ProtectedHidVolPassword.Length > MAX_PASSWORD || mount->pkcs5_prf < 0 || mount->pkcs5_prf > LAST_PRF_ID || mount->VolumePim < -1 || mount->VolumePim == INT_MAX || mount->ProtectedHidVolPkcs5Prf < 0 || mount->ProtectedHidVolPkcs5Prf > LAST_PRF_ID - || (mount->bTrueCryptMode != FALSE && mount->bTrueCryptMode != TRUE) ) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; @@ -1552,9 +2580,8 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex burn (&mount->VolumePassword, sizeof (mount->VolumePassword)); burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword)); burn (&mount->pkcs5_prf, sizeof (mount->pkcs5_prf)); burn (&mount->VolumePim, sizeof (mount->VolumePim)); - burn (&mount->bTrueCryptMode, sizeof (mount->bTrueCryptMode)); burn (&mount->ProtectedHidVolPkcs5Prf, sizeof (mount->ProtectedHidVolPkcs5Prf)); burn (&mount->ProtectedHidVolPim, sizeof (mount->ProtectedHidVolPim)); } break; @@ -1564,8 +2591,15 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; PDEVICE_OBJECT ListDevice = GetVirtualVolumeDeviceObject (unmount->nDosDriveNo); + if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + unmount->nReturnCode = ERR_DRIVE_NOT_FOUND; if (ListDevice) { @@ -1584,15 +2618,27 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput)) { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; + if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + unmount->nReturnCode = UnmountAllDevices (unmount, unmount->ignoreOpenFiles); Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); Irp->IoStatus.Status = STATUS_SUCCESS; } break; + case VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS: + EmergencyClearAllKeys (Irp); + WipeCache(); + break; + case TC_IOCTL_BOOT_ENCRYPTION_SETUP: Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp); Irp->IoStatus.Information = 0; break; @@ -1602,34 +2648,34 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex Irp->IoStatus.Information = 0; break; case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS: - GetBootEncryptionStatus (Irp, irpSp); + GetBootEncryptionStatus (Irp); break; case TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT: Irp->IoStatus.Information = 0; Irp->IoStatus.Status = GetSetupResult(); break; case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES: - GetBootDriveVolumeProperties (Irp, irpSp); + GetBootDriveVolumeProperties (Irp); break; case TC_IOCTL_GET_BOOT_LOADER_VERSION: - GetBootLoaderVersion (Irp, irpSp); + GetBootLoaderVersion (Irp); break; case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER: - ReopenBootVolumeHeader (Irp, irpSp); + ReopenBootVolumeHeader (Irp); break; case VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT: - GetBootLoaderFingerprint (Irp, irpSp); + GetBootLoaderFingerprint (Irp); break; case TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME: - GetBootEncryptionAlgorithmName (Irp, irpSp); + GetBootEncryptionAlgorithmName (Irp); break; case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING: if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) @@ -1655,9 +2701,9 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex Irp->IoStatus.Information = 0; break; case TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS: - GetDecoySystemWipeStatus (Irp, irpSp); + GetDecoySystemWipeStatus (Irp); break; case TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR: Irp->IoStatus.Status = WriteBootDriveSector (Irp, irpSp); @@ -1717,8 +2763,30 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex } } break; + case VC_IOCTL_IS_RAM_ENCRYPTION_ENABLED: + if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) + { + *(int *) Irp->AssociatedIrp.SystemBuffer = IsRamEncryptionEnabled() ? 1 : 0; + Irp->IoStatus.Information = sizeof (int); + Irp->IoStatus.Status = STATUS_SUCCESS; + } + break; + + case VC_IOCTL_ENCRYPTION_QUEUE_PARAMS: + if (ValidateIOBufferSize (Irp, sizeof (EncryptionQueueParameters), ValidateOutput)) + { + EncryptionQueueParameters* pParams = (EncryptionQueueParameters*) Irp->AssociatedIrp.SystemBuffer; + pParams->EncryptionMaxWorkItems = EncryptionMaxWorkItems; + pParams->EncryptionFragmentSize = EncryptionFragmentSize; + pParams->EncryptionIoRequestCount = EncryptionIoRequestCount; + pParams->EncryptionItemCount = EncryptionItemCount; + Irp->IoStatus.Information = sizeof (EncryptionQueueParameters); + Irp->IoStatus.Status = STATUS_SUCCESS; + } + break; + default: return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); } @@ -1992,8 +3060,23 @@ VOID VolumeThreadProc (PVOID Context) Extension->Queue.CryptoInfo = Extension->cryptoInfo; Extension->Queue.HostFileHandle = Extension->hDeviceFile; Extension->Queue.VirtualDeviceLength = Extension->DiskLength; Extension->Queue.MaxReadAheadOffset.QuadPart = Extension->HostLength; + if (bDevice && pThreadBlock->mount->bPartitionInInactiveSysEncScope + && (!Extension->cryptoInfo->hiddenVolume) + && (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value) + ) + { + // Support partial encryption only in the case of system encryption + Extension->Queue.EncryptedAreaStart = 0; + Extension->Queue.EncryptedAreaEnd = Extension->cryptoInfo->EncryptedAreaLength.Value - 1; + if (Extension->Queue.CryptoInfo->EncryptedAreaLength.Value == 0) + { + Extension->Queue.EncryptedAreaStart = -1; + Extension->Queue.EncryptedAreaEnd = -1; + } + Extension->Queue.bSupportPartialEncryption = TRUE; + } if (Extension->SecurityClientContextValid) Extension->Queue.SecurityClientContext = &Extension->SecurityClientContext; else @@ -2124,123 +3207,90 @@ LPWSTR TCTranslateCode (ULONG ulCode) TC_CASE_RET_NAME (TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY); TC_CASE_RET_NAME (TC_IOCTL_START_DECOY_SYSTEM_WIPE); TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE); TC_CASE_RET_NAME (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR); + TC_CASE_RET_NAME (VC_IOCTL_GET_DRIVE_GEOMETRY_EX); + TC_CASE_RET_NAME (VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS); + TC_CASE_RET_NAME (VC_IOCTL_IS_RAM_ENCRYPTION_ENABLED); + TC_CASE_RET_NAME (VC_IOCTL_ENCRYPTION_QUEUE_PARAMS); TC_CASE_RET_NAME (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS); -#undef TC_CASE_RET_NAME - } + TC_CASE_RET_NAME(IOCTL_DISK_GET_DRIVE_GEOMETRY); + TC_CASE_RET_NAME(IOCTL_DISK_GET_DRIVE_GEOMETRY_EX); + TC_CASE_RET_NAME(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME); + TC_CASE_RET_NAME(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME); + TC_CASE_RET_NAME(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID); + TC_CASE_RET_NAME(IOCTL_VOLUME_ONLINE); + TC_CASE_RET_NAME(IOCTL_MOUNTDEV_LINK_CREATED); + TC_CASE_RET_NAME(IOCTL_MOUNTDEV_LINK_DELETED); + TC_CASE_RET_NAME(IOCTL_MOUNTMGR_QUERY_POINTS); + TC_CASE_RET_NAME(IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED); + TC_CASE_RET_NAME(IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED); + TC_CASE_RET_NAME(IOCTL_DISK_GET_LENGTH_INFO); + TC_CASE_RET_NAME(IOCTL_STORAGE_GET_DEVICE_NUMBER); + TC_CASE_RET_NAME(IOCTL_DISK_GET_PARTITION_INFO); + TC_CASE_RET_NAME(IOCTL_DISK_GET_PARTITION_INFO_EX); + TC_CASE_RET_NAME(IOCTL_DISK_SET_PARTITION_INFO); + TC_CASE_RET_NAME(IOCTL_DISK_GET_DRIVE_LAYOUT); + TC_CASE_RET_NAME(IOCTL_DISK_GET_DRIVE_LAYOUT_EX); + TC_CASE_RET_NAME(IOCTL_DISK_SET_DRIVE_LAYOUT_EX); + TC_CASE_RET_NAME(IOCTL_DISK_VERIFY); + TC_CASE_RET_NAME(IOCTL_DISK_FORMAT_TRACKS); + TC_CASE_RET_NAME(IOCTL_DISK_REASSIGN_BLOCKS); + TC_CASE_RET_NAME(IOCTL_DISK_PERFORMANCE); + TC_CASE_RET_NAME(IOCTL_DISK_IS_WRITABLE); + TC_CASE_RET_NAME(IOCTL_DISK_LOGGING); + TC_CASE_RET_NAME(IOCTL_DISK_FORMAT_TRACKS_EX); + TC_CASE_RET_NAME(IOCTL_DISK_HISTOGRAM_STRUCTURE); + TC_CASE_RET_NAME(IOCTL_DISK_HISTOGRAM_DATA); + TC_CASE_RET_NAME(IOCTL_DISK_HISTOGRAM_RESET); + TC_CASE_RET_NAME(IOCTL_DISK_REQUEST_STRUCTURE); + TC_CASE_RET_NAME(IOCTL_DISK_REQUEST_DATA); + TC_CASE_RET_NAME(IOCTL_DISK_CONTROLLER_NUMBER); + TC_CASE_RET_NAME(SMART_GET_VERSION); + TC_CASE_RET_NAME(SMART_SEND_DRIVE_COMMAND); + TC_CASE_RET_NAME(SMART_RCV_DRIVE_DATA); + TC_CASE_RET_NAME(IOCTL_DISK_INTERNAL_SET_VERIFY); + TC_CASE_RET_NAME(IOCTL_DISK_INTERNAL_CLEAR_VERIFY); + TC_CASE_RET_NAME(IOCTL_DISK_CHECK_VERIFY); + TC_CASE_RET_NAME(IOCTL_DISK_MEDIA_REMOVAL); + TC_CASE_RET_NAME(IOCTL_STORAGE_MEDIA_REMOVAL); + TC_CASE_RET_NAME(IOCTL_DISK_EJECT_MEDIA); + TC_CASE_RET_NAME(IOCTL_DISK_LOAD_MEDIA); + TC_CASE_RET_NAME(IOCTL_DISK_RESERVE); + TC_CASE_RET_NAME(IOCTL_DISK_RELEASE); + TC_CASE_RET_NAME(IOCTL_DISK_FIND_NEW_DEVICES); + TC_CASE_RET_NAME(IOCTL_DISK_GET_MEDIA_TYPES); + TC_CASE_RET_NAME(IOCTL_DISK_IS_CLUSTERED); + TC_CASE_RET_NAME(IOCTL_DISK_UPDATE_DRIVE_SIZE); + TC_CASE_RET_NAME(IOCTL_STORAGE_GET_MEDIA_TYPES); + TC_CASE_RET_NAME(IOCTL_STORAGE_GET_HOTPLUG_INFO); + TC_CASE_RET_NAME(IOCTL_STORAGE_SET_HOTPLUG_INFO); + TC_CASE_RET_NAME(IOCTL_STORAGE_QUERY_PROPERTY); + TC_CASE_RET_NAME(IOCTL_VOLUME_GET_GPT_ATTRIBUTES); + TC_CASE_RET_NAME(FT_BALANCED_READ_MODE); + TC_CASE_RET_NAME(IOCTL_VOLUME_QUERY_ALLOCATION_HINT); + TC_CASE_RET_NAME(IOCTL_DISK_GET_CLUSTER_INFO); + TC_CASE_RET_NAME(IOCTL_DISK_ARE_VOLUMES_READY); + TC_CASE_RET_NAME(IOCTL_VOLUME_IS_DYNAMIC); + TC_CASE_RET_NAME(IOCTL_MOUNTDEV_QUERY_STABLE_GUID); + TC_CASE_RET_NAME(IOCTL_VOLUME_POST_ONLINE); + TC_CASE_RET_NAME(IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT); + TC_CASE_RET_NAME(IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES); + TC_CASE_RET_NAME(IOCTL_DISK_GROW_PARTITION); + TC_CASE_RET_NAME(IRP_MJ_READ); + TC_CASE_RET_NAME(IRP_MJ_WRITE); + TC_CASE_RET_NAME(IRP_MJ_CREATE); + TC_CASE_RET_NAME(IRP_MJ_CLOSE); + TC_CASE_RET_NAME(IRP_MJ_CLEANUP); + TC_CASE_RET_NAME(IRP_MJ_FLUSH_BUFFERS); + TC_CASE_RET_NAME(IRP_MJ_SHUTDOWN); + TC_CASE_RET_NAME(IRP_MJ_DEVICE_CONTROL); + default: + return (LPWSTR) L"IOCTL"; - if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) - return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY"); - else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) - return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX"); - else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) - return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME"); - else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) - return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME"); - else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID) - return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID"); - else if (ulCode == IOCTL_VOLUME_ONLINE) - return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE"); - else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED) - return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED"); - else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED) - return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED"); - else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS) - return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS"); - else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED) - return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED"); - else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED) - return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED"); - else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO) - return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO"); - else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER) - return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER"); - else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO) - return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO"); - else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX) - return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX"); - else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO) - return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO"); - else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT) - return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT"); - else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX) - return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX"); - else if (ulCode == IOCTL_DISK_VERIFY) - return (LPWSTR) _T ("IOCTL_DISK_VERIFY"); - else if (ulCode == IOCTL_DISK_FORMAT_TRACKS) - return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS"); - else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS) - return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS"); - else if (ulCode == IOCTL_DISK_PERFORMANCE) - return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE"); - else if (ulCode == IOCTL_DISK_IS_WRITABLE) - return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE"); - else if (ulCode == IOCTL_DISK_LOGGING) - return (LPWSTR) _T ("IOCTL_DISK_LOGGING"); - else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX) - return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX"); - else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE) - return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE"); - else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA) - return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA"); - else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET) - return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET"); - else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE) - return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE"); - else if (ulCode == IOCTL_DISK_REQUEST_DATA) - return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA"); - else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER) - return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER"); - else if (ulCode == SMART_GET_VERSION) - return (LPWSTR) _T ("SMART_GET_VERSION"); - else if (ulCode == SMART_SEND_DRIVE_COMMAND) - return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND"); - else if (ulCode == SMART_RCV_DRIVE_DATA) - return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA"); - else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY) - return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY"); - else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY) - return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY"); - else if (ulCode == IOCTL_DISK_CHECK_VERIFY) - return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY"); - else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL) - return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL"); - else if (ulCode == IOCTL_DISK_EJECT_MEDIA) - return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA"); - else if (ulCode == IOCTL_DISK_LOAD_MEDIA) - return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA"); - else if (ulCode == IOCTL_DISK_RESERVE) - return (LPWSTR) _T ("IOCTL_DISK_RESERVE"); - else if (ulCode == IOCTL_DISK_RELEASE) - return (LPWSTR) _T ("IOCTL_DISK_RELEASE"); - else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES) - return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES"); - else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES) - return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES"); - else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO) - return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO"); - else if (ulCode == IRP_MJ_READ) - return (LPWSTR) _T ("IRP_MJ_READ"); - else if (ulCode == IRP_MJ_WRITE) - return (LPWSTR) _T ("IRP_MJ_WRITE"); - else if (ulCode == IRP_MJ_CREATE) - return (LPWSTR) _T ("IRP_MJ_CREATE"); - else if (ulCode == IRP_MJ_CLOSE) - return (LPWSTR) _T ("IRP_MJ_CLOSE"); - else if (ulCode == IRP_MJ_CLEANUP) - return (LPWSTR) _T ("IRP_MJ_CLEANUP"); - else if (ulCode == IRP_MJ_FLUSH_BUFFERS) - return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS"); - else if (ulCode == IRP_MJ_SHUTDOWN) - return (LPWSTR) _T ("IRP_MJ_SHUTDOWN"); - else if (ulCode == IRP_MJ_DEVICE_CONTROL) - return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL"); - else - { - return (LPWSTR) _T ("IOCTL"); +#undef TC_CASE_RET_NAME } } #endif @@ -2270,33 +3320,25 @@ void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) TCfree (Extension->UserSid); if (Extension->SecurityClientContextValid) { - if (OsMajorVersion == 5 && OsMinorVersion == 0) - { - ObDereferenceObject (Extension->SecurityClientContext.ClientToken); - } - else - { - // Windows 2000 does not support PsDereferenceImpersonationToken() used by SeDeleteClientSecurity(). - // TODO: Use only SeDeleteClientSecurity() once support for Windows 2000 is dropped. + typedef VOID (*PsDereferenceImpersonationTokenDType) (PACCESS_TOKEN ImpersonationToken); - VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken); - UNICODE_STRING name; - RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken"); + PsDereferenceImpersonationTokenDType PsDereferenceImpersonationTokenD; + UNICODE_STRING name; + RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken"); - PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name); - if (!PsDereferenceImpersonationTokenD) - TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED); + PsDereferenceImpersonationTokenD = (PsDereferenceImpersonationTokenDType) MmGetSystemRoutineAddress (&name); + if (!PsDereferenceImpersonationTokenD) + TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED); -# define PsDereferencePrimaryToken -# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD +# define PsDereferencePrimaryToken +# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD - SeDeleteClientSecurity (&Extension->SecurityClientContext); + SeDeleteClientSecurity (&Extension->SecurityClientContext); -# undef PsDereferencePrimaryToken -# undef PsDereferenceImpersonationToken - } +# undef PsDereferencePrimaryToken +# undef PsDereferenceImpersonationToken } VirtualVolumeDeviceObjects[Extension->nDosDriveNo] = NULL; } @@ -2309,9 +3351,9 @@ void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) VOID TCUnloadDriver (PDRIVER_OBJECT DriverObject) { Dump ("TCUnloadDriver BEGIN\n"); - + UNREFERENCED_PARAMETER(DriverObject); OnShutdownPending(); if (IsBootDriveMounted()) TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE); @@ -2334,8 +3376,21 @@ void OnShutdownPending () while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0) == STATUS_INSUFFICIENT_RESOURCES); } +typedef struct +{ + PWSTR deviceName; ULONG IoControlCode; void *InputBuffer; ULONG InputBufferSize; void *OutputBuffer; ULONG OutputBufferSize; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} TCDeviceIoControlWorkItemArgs; + +static VOID TCDeviceIoControlWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCDeviceIoControlWorkItemArgs *arg) +{ + UNREFERENCED_PARAMETER(rootDeviceObject); + arg->Status = TCDeviceIoControl (arg->deviceName, arg->IoControlCode, arg->InputBuffer, arg->InputBufferSize, arg->OutputBuffer, arg->OutputBufferSize); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, void *InputBuffer, ULONG InputBufferSize, void *OutputBuffer, ULONG OutputBufferSize) { IO_STATUS_BLOCK ioStatusBlock; @@ -2345,8 +3400,32 @@ NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, void *InputBu PDEVICE_OBJECT deviceObject; KEVENT event; UNICODE_STRING name; + if ((KeGetCurrentIrql() >= APC_LEVEL) || KeAreAllApcsDisabled()) + { + TCDeviceIoControlWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.deviceName = deviceName; + args.IoControlCode = IoControlCode; + args.InputBuffer = InputBuffer; + args.InputBufferSize = InputBufferSize; + args.OutputBuffer = OutputBuffer; + args.OutputBufferSize = OutputBufferSize; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, TCDeviceIoControlWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + RtlInitUnicodeString(&name, deviceName); ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject); if (!NT_SUCCESS (ntStatus)) @@ -2393,8 +3472,9 @@ typedef struct static VOID SendDeviceIoControlRequestWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, SendDeviceIoControlRequestWorkItemArgs *arg) { + UNREFERENCED_PARAMETER(rootDeviceObject); arg->Status = SendDeviceIoControlRequest (arg->deviceObject, arg->ioControlCode, arg->inputBuffer, arg->inputBufferSize, arg->outputBuffer, arg->outputBufferSize); KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } @@ -2405,9 +3485,9 @@ NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioContro NTSTATUS status; PIRP irp; KEVENT event; - if (KeGetCurrentIrql() > APC_LEVEL) + if ((KeGetCurrentIrql() >= APC_LEVEL) || KeAreAllApcsDisabled()) { SendDeviceIoControlRequestWorkItemArgs args; PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); @@ -2456,15 +3536,20 @@ NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *dr { NTSTATUS status; LARGE_INTEGER sysLength; LARGE_INTEGER offset; - byte *sectorBuffer; + uint8 *sectorBuffer; ULONGLONG startTime; + ULONG sectorSize; if (!UserCanAccessDriveDevice()) return STATUS_ACCESS_DENIED; - sectorBuffer = TCalloc (TC_SECTOR_SIZE_BIOS); + status = GetDeviceSectorSize (driveDeviceObject, §orSize); + if (!NT_SUCCESS (status)) + return status; + + sectorBuffer = TCalloc (sectorSize); if (!sectorBuffer) return STATUS_INSUFFICIENT_RESOURCES; status = SendDeviceIoControlRequest (driveDeviceObject, IOCTL_DISK_GET_LENGTH_INFO, @@ -2477,14 +3562,14 @@ NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *dr return status; } startTime = KeQueryInterruptTime (); - for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += TC_SECTOR_SIZE_BIOS) + for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += sectorSize) { - status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, TC_SECTOR_SIZE_BIOS); + status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, sectorSize); if (NT_SUCCESS (status)) - status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, TC_SECTOR_SIZE_BIOS); + status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, sectorSize); if (!NT_SUCCESS (status)) { driveSize->QuadPart = offset.QuadPart; @@ -2721,8 +3806,139 @@ NTSTATUS MountManagerUnmount (int nDosDriveNo) return ntStatus; } +typedef struct +{ + MOUNT_STRUCT* mount; PEXTENSION NewExtension; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} UpdateFsVolumeInformationWorkItemArgs; + +static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewExtension); + +static VOID UpdateFsVolumeInformationWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, UpdateFsVolumeInformationWorkItemArgs *arg) +{ + UNREFERENCED_PARAMETER(rootDeviceObject); + arg->Status = UpdateFsVolumeInformation (arg->mount, arg->NewExtension); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} + +static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewExtension) +{ + HANDLE volumeHandle; + PFILE_OBJECT volumeFileObject; + ULONG labelLen = (ULONG) wcslen (mount->wszLabel); + BOOL bIsNTFS = FALSE; + ULONG labelMaxLen, labelEffectiveLen; + + if ((KeGetCurrentIrql() >= APC_LEVEL) || KeAreAllApcsDisabled()) + { + UpdateFsVolumeInformationWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.mount = mount; + args.NewExtension = NewExtension; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, UpdateFsVolumeInformationWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + + __try + { + if (NT_SUCCESS (TCOpenFsVolume (NewExtension, &volumeHandle, &volumeFileObject))) + { + __try + { + ULONG fsStatus; + + if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &fsStatus, sizeof (fsStatus))) + && (fsStatus & VOLUME_IS_DIRTY)) + { + mount->FilesystemDirty = TRUE; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + mount->FilesystemDirty = TRUE; + } + + // detect if the filesystem is NTFS or FAT + __try + { + NTFS_VOLUME_DATA_BUFFER ntfsData; + if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &ntfsData, sizeof (ntfsData)))) + { + bIsNTFS = TRUE; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + bIsNTFS = FALSE; + } + + NewExtension->bIsNTFS = bIsNTFS; + mount->bIsNTFS = bIsNTFS; + + if (labelLen > 0) + { + if (bIsNTFS) + labelMaxLen = 32; // NTFS maximum label length + else + labelMaxLen = 11; // FAT maximum label length + + // calculate label effective length + labelEffectiveLen = labelLen > labelMaxLen? labelMaxLen : labelLen; + + // correct the label in the device + memset (&NewExtension->wszLabel[labelEffectiveLen], 0, 33 - labelEffectiveLen); + memcpy (mount->wszLabel, NewExtension->wszLabel, 33); + + // set the volume label + __try + { + IO_STATUS_BLOCK ioblock; + ULONG labelInfoSize = sizeof(FILE_FS_LABEL_INFORMATION) + (labelEffectiveLen * sizeof(WCHAR)); + FILE_FS_LABEL_INFORMATION* labelInfo = (FILE_FS_LABEL_INFORMATION*) TCalloc (labelInfoSize); + if (labelInfo) + { + labelInfo->VolumeLabelLength = labelEffectiveLen * sizeof(WCHAR); + memcpy (labelInfo->VolumeLabel, mount->wszLabel, labelInfo->VolumeLabelLength); + + if (STATUS_SUCCESS == ZwSetVolumeInformationFile (volumeHandle, &ioblock, labelInfo, labelInfoSize, FileFsLabelInformation)) + { + mount->bDriverSetLabel = TRUE; + NewExtension->bDriverSetLabel = TRUE; + } + + TCfree(labelInfo); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + + } + } + + TCCloseFsVolume (volumeHandle, volumeFileObject); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + + } + + return STATUS_SUCCESS; +} + NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) { PDEVICE_OBJECT NewDeviceObject; @@ -2744,8 +3960,9 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) } if (!SelfTestsPassed) { + Dump ("Failure of built-in automatic self-tests! Mounting not allowed.\n"); mount->nReturnCode = ERR_SELF_TESTS_FAILED; return ERR_SELF_TESTS_FAILED; } @@ -2807,14 +4024,8 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) else { if (mount->nReturnCode == 0) { - HANDLE volumeHandle; - PFILE_OBJECT volumeFileObject; - ULONG labelLen = (ULONG) wcslen (mount->wszLabel); - BOOL bIsNTFS = FALSE; - ULONG labelMaxLen, labelEffectiveLen; - Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode, NewExtension->bReadOnly); if (NewExtension->bReadOnly) NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; @@ -2833,90 +4044,26 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) return ERR_DRIVE_NOT_FOUND; } if (mount->bMountManager) + { MountManagerMount (mount); + // We create symbolic link even if mount manager is notified of + // arriving volume as it apparently sometimes fails to create the link + CreateDriveLink (mount->nDosDriveNo); + } NewExtension->bMountManager = mount->bMountManager; - // We create symbolic link even if mount manager is notified of - // arriving volume as it apparently sometimes fails to create the link - CreateDriveLink (mount->nDosDriveNo); - mount->FilesystemDirty = FALSE; - if (NT_SUCCESS (TCOpenFsVolume (NewExtension, &volumeHandle, &volumeFileObject))) + if (mount->bMountManager) { - __try + NTSTATUS updateStatus = UpdateFsVolumeInformation (mount, NewExtension); + if (!NT_SUCCESS (updateStatus)) { - ULONG fsStatus; - - if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &fsStatus, sizeof (fsStatus))) - && (fsStatus & VOLUME_IS_DIRTY)) - { - mount->FilesystemDirty = TRUE; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - mount->FilesystemDirty = TRUE; - } - - // detect if the filesystem is NTFS or FAT - __try - { - NTFS_VOLUME_DATA_BUFFER ntfsData; - if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &ntfsData, sizeof (ntfsData)))) - { - bIsNTFS = TRUE; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - bIsNTFS = FALSE; - } - - NewExtension->bIsNTFS = bIsNTFS; - mount->bIsNTFS = bIsNTFS; - - if (labelLen > 0) - { - if (bIsNTFS) - labelMaxLen = 32; // NTFS maximum label length - else - labelMaxLen = 11; // FAT maximum label length - - // calculate label effective length - labelEffectiveLen = labelLen > labelMaxLen? labelMaxLen : labelLen; - - // correct the label in the device - memset (&NewExtension->wszLabel[labelEffectiveLen], 0, 33 - labelEffectiveLen); - memcpy (mount->wszLabel, NewExtension->wszLabel, 33); - - // set the volume label - __try - { - IO_STATUS_BLOCK ioblock; - ULONG labelInfoSize = sizeof(FILE_FS_LABEL_INFORMATION) + (labelEffectiveLen * sizeof(WCHAR)); - FILE_FS_LABEL_INFORMATION* labelInfo = (FILE_FS_LABEL_INFORMATION*) TCalloc (labelInfoSize); - labelInfo->VolumeLabelLength = labelEffectiveLen * sizeof(WCHAR); - memcpy (labelInfo->VolumeLabel, mount->wszLabel, labelInfo->VolumeLabelLength); - - if (STATUS_SUCCESS == ZwSetVolumeInformationFile (volumeHandle, &ioblock, labelInfo, labelInfoSize, FileFsLabelInformation)) - { - mount->bDriverSetLabel = TRUE; - NewExtension->bDriverSetLabel = TRUE; - } - - TCfree(labelInfo); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - - } + Dump ("MountDevice: UpdateFsVolumeInformation failed with status 0x%08x\n", updateStatus); } - - TCCloseFsVolume (volumeHandle, volumeFileObject); } } else { @@ -2928,15 +4075,51 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) } } } +typedef struct +{ + UNMOUNT_STRUCT *unmountRequest; PDEVICE_OBJECT deviceObject; BOOL ignoreOpenFiles; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} UnmountDeviceWorkItemArgs; + + +static VOID UnmountDeviceWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, UnmountDeviceWorkItemArgs *arg) +{ + UNREFERENCED_PARAMETER(rootDeviceObject); + arg->Status = UnmountDevice (arg->unmountRequest, arg->deviceObject, arg->ignoreOpenFiles); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} + NTSTATUS UnmountDevice (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles) { PEXTENSION extension = deviceObject->DeviceExtension; NTSTATUS ntStatus; HANDLE volumeHandle; PFILE_OBJECT volumeFileObject; + if ((KeGetCurrentIrql() >= APC_LEVEL) || KeAreAllApcsDisabled()) + { + UnmountDeviceWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.deviceObject = deviceObject; + args.unmountRequest = unmountRequest; + args.ignoreOpenFiles = ignoreOpenFiles; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, UnmountDeviceWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + Dump ("UnmountDevice %d\n", extension->nDosDriveNo); ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject); @@ -2944,9 +4127,9 @@ NTSTATUS UnmountDevice (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT deviceObj { int dismountRetry; // Dismounting a writable NTFS filesystem prevents the driver from being unloaded on Windows 7 - if (IsOSAtLeast (WIN_7) && !extension->bReadOnly) + if (!extension->bReadOnly) { NTFS_VOLUME_DATA_BUFFER ntfsData; if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &ntfsData, sizeof (ntfsData)))) @@ -3205,28 +4388,49 @@ NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information) return status; } -size_t GetCpuCount () +size_t GetCpuCount (WORD* pGroupCount) { - KAFFINITY activeCpuMap = KeQueryActiveProcessors(); - size_t mapSize = sizeof (activeCpuMap) * 8; size_t cpuCount = 0; - - while (mapSize--) + USHORT i, groupCount = KeQueryActiveGroupCount (); + for (i = 0; i < groupCount; i++) { - if (activeCpuMap & 1) - ++cpuCount; - - activeCpuMap >>= 1; + cpuCount += (size_t) KeQueryActiveProcessorCountEx (i); } + if (pGroupCount) + *pGroupCount = groupCount; + if (cpuCount == 0) return 1; return cpuCount; } +USHORT GetCpuGroup (size_t index) +{ + USHORT i, groupCount = KeQueryActiveGroupCount (); + size_t cpuCount = 0; + for (i = 0; i < groupCount; i++) + { + cpuCount += (size_t) KeQueryActiveProcessorCountEx (i); + if (cpuCount >= index) + { + return i; + } + } + + return 0; +} + +void SetThreadCpuGroupAffinity (USHORT index) +{ + GROUP_AFFINITY groupAffinity = {0}; + groupAffinity.Mask = ~0ULL; + groupAffinity.Group = index; + KeSetSystemGroupAffinityThread (&groupAffinity, NULL); +} void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes) { ASSERT ((maxSizeInBytes & 1) == 0); @@ -3236,9 +4440,9 @@ void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes) void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout) { LARGE_INTEGER waitInterval; - waitInterval.QuadPart = retryDelay * -10000; + waitInterval.QuadPart = ((LONGLONG)retryDelay) * -10000; ASSERT (KeGetCurrentIrql() <= APC_LEVEL); ASSERT (retryDelay > 0 && retryDelay <= timeout); @@ -3384,13 +4588,28 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry) NonAdminSystemFavoritesAccessDisabled = TRUE; if (flags & TC_DRIVER_CONFIG_CACHE_BOOT_PIM) CacheBootPim = TRUE; + + if (flags & VC_DRIVER_CONFIG_BLOCK_SYS_TRIM) + BlockSystemTrimCommand = TRUE; + + /* clear VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION if it is set */ + if (flags & VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION) + { + flags ^= VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION; + WriteRegistryConfigFlags (flags); + } + + RamEncryptionActivated = (flags & VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION) ? TRUE : FALSE; } EnableHwEncryption ((flags & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE); + EnableCpuRng ((flags & VC_DRIVER_CONFIG_ENABLE_CPU_RNG) ? TRUE : FALSE); EnableExtendedIoctlSupport = (flags & TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL)? TRUE : FALSE; + AllowTrimCommand = (flags & VC_DRIVER_CONFIG_ALLOW_NONSYS_TRIM)? TRUE : FALSE; + AllowWindowsDefrag = (flags & VC_DRIVER_CONFIG_ALLOW_WINDOWS_DEFRAG)? TRUE : FALSE; } else status = STATUS_INVALID_PARAMETER; @@ -3404,8 +4623,78 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry) TCfree (data); } + if (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ENCRYPTION_IO_REQUEST_COUNT, &data))) + { + if (data->Type == REG_DWORD) + EncryptionIoRequestCount = *(uint32 *) data->Data; + + TCfree (data); + } + + if (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ENCRYPTION_ITEM_COUNT, &data))) + { + if (data->Type == REG_DWORD) + EncryptionItemCount = *(uint32 *) data->Data; + + TCfree (data); + } + + if (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ENCRYPTION_FRAGMENT_SIZE, &data))) + { + if (data->Type == REG_DWORD) + EncryptionFragmentSize = *(uint32 *) data->Data; + + TCfree (data); + } + + if (driverEntry && NT_SUCCESS(TCReadRegistryKey(&name, VC_ENCRYPTION_MAX_WORK_ITEMS, &data))) + { + if (data->Type == REG_DWORD) + EncryptionMaxWorkItems = *(uint32*)data->Data; + + TCfree(data); + } + + if (driverEntry) + { + if (EncryptionIoRequestCount < TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT) + EncryptionIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT; + else if (EncryptionIoRequestCount > TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_MAX_COUNT) + EncryptionIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_MAX_COUNT; + + if ((EncryptionItemCount == 0) || (EncryptionItemCount > (EncryptionIoRequestCount / 2))) + EncryptionItemCount = EncryptionIoRequestCount / 2; + + /* EncryptionFragmentSize value in registry is expressed in KiB */ + /* Maximum allowed value for EncryptionFragmentSize is 2048 KiB */ + EncryptionFragmentSize *= 1024; + if (EncryptionFragmentSize == 0) + EncryptionFragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + else if (EncryptionFragmentSize > (8 * TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE)) + EncryptionFragmentSize = 8 * TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE; + + if (EncryptionMaxWorkItems == 0) + EncryptionMaxWorkItems = VC_MAX_WORK_ITEMS; + + + } + + if (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ERASE_KEYS_SHUTDOWN, &data))) + { + if (data->Type == REG_DWORD) + { + if (*((uint32 *) data->Data)) + EraseKeysOnShutdown = TRUE; + else + EraseKeysOnShutdown = FALSE; + } + + TCfree (data); + } + + return status; } @@ -3423,13 +4712,13 @@ NTSTATUS GetDeviceSectorSize (PDEVICE_OBJECT deviceObject, ULONG *bytesPerSector NTSTATUS status; DISK_GEOMETRY geometry; status = SendDeviceIoControlRequest (deviceObject, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry)); - if (!NT_SUCCESS (status)) return status; *bytesPerSector = geometry.BytesPerSector; + return STATUS_SUCCESS; } @@ -3437,9 +4726,9 @@ NTSTATUS ZeroUnreadableSectors (PDEVICE_OBJECT deviceObject, LARGE_INTEGER start { NTSTATUS status; ULONG sectorSize; ULONG sectorCount; - byte *sectorBuffer = NULL; + uint8 *sectorBuffer = NULL; *zeroedSectorCount = 0; status = GetDeviceSectorSize (deviceObject, §orSize); @@ -3475,9 +4764,9 @@ err: return status; } -NTSTATUS ReadDeviceSkipUnreadableSectors (PDEVICE_OBJECT deviceObject, byte *buffer, LARGE_INTEGER startOffset, ULONG size, uint64 *badSectorCount) +NTSTATUS ReadDeviceSkipUnreadableSectors (PDEVICE_OBJECT deviceObject, uint8 *buffer, LARGE_INTEGER startOffset, ULONG size, uint64 *badSectorCount) { NTSTATUS status; ULONG sectorSize; ULONG sectorCount; diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h index 2c5f13da..b03b5e93 100644 --- a/src/Driver/Ntdriver.h +++ b/src/Driver/Ntdriver.h @@ -5,9 +5,9 @@ governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -62,9 +62,15 @@ typedef struct EXTENSION UCHAR PartitionType; /* Partition info */ uint32 HostBytesPerSector; uint32 HostBytesPerPhysicalSector; - ULONG BytesOffsetForSectorAlignment; + ULONG HostMaximumTransferLength; + ULONG HostMaximumPhysicalPages; + ULONG HostAlignmentMask; + ULONG DeviceNumber; + + BOOL IncursSeekPenalty; + BOOL TrimEnabled; KEVENT keVolumeEvent; /* Event structure used when setting up a device */ EncryptedIoQueue Queue; @@ -116,9 +122,15 @@ extern ULONG OsMajorVersion; extern ULONG OsMinorVersion; extern BOOL VolumeClassFilterRegistered; extern BOOL CacheBootPassword; extern BOOL CacheBootPim; - +extern BOOL BlockSystemTrimCommand; +extern BOOL AllowWindowsDefrag; +extern int EncryptionIoRequestCount; +extern int EncryptionItemCount; +extern int EncryptionFragmentSize; +extern int EncryptionMaxWorkItems; +extern BOOL EraseKeysOnShutdown; /* Helper macro returning x seconds in units of 100 nanoseconds */ #define WAIT_SECONDS(x) ((x)*10000000) NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); @@ -165,9 +177,11 @@ void GetIntersection (uint64 start1, uint32 length1, uint64 start2, uint64 end2, NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information); NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information); NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize); BOOL UserCanAccessDriveDevice (); -size_t GetCpuCount (); +size_t GetCpuCount (WORD* pGroupCount); +USHORT GetCpuGroup (size_t index); +void SetThreadCpuGroupAffinity (USHORT index); void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes); void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout); BOOL IsDriveLetterAvailable (int nDosDriveNo, DeviceNamespaceType namespaceType); NTSTATUS TCReadRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, PKEY_VALUE_PARTIAL_INFORMATION *keyData); @@ -177,13 +191,15 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry); NTSTATUS WriteRegistryConfigFlags (uint32 flags); BOOL ValidateIOBufferSize (PIRP irp, size_t requiredBufferSize, ValidateIOBufferSizeType type); NTSTATUS GetDeviceSectorSize (PDEVICE_OBJECT deviceObject, ULONG *bytesPerSector); NTSTATUS ZeroUnreadableSectors (PDEVICE_OBJECT deviceObject, LARGE_INTEGER startOffset, ULONG size, uint64 *zeroedSectorCount); -NTSTATUS ReadDeviceSkipUnreadableSectors (PDEVICE_OBJECT deviceObject, byte *buffer, LARGE_INTEGER startOffset, ULONG size, uint64 *badSectorCount); +NTSTATUS ReadDeviceSkipUnreadableSectors (PDEVICE_OBJECT deviceObject, uint8 *buffer, LARGE_INTEGER startOffset, ULONG size, uint64 *badSectorCount); BOOL IsVolumeAccessibleByCurrentUser (PEXTENSION volumeDeviceExtension); void GetElapsedTimeInit (LARGE_INTEGER *lastPerfCounter); int64 GetElapsedTime (LARGE_INTEGER *lastPerfCounter); BOOL IsOSAtLeast (OSVersionEnum reqMinOS); +PDEVICE_OBJECT GetVirtualVolumeDeviceObject (int driveNumber); +void GetDriverRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed); #define TC_BUG_CHECK(status) KeBugCheckEx (SECURITY_SYSTEM, __LINE__, (ULONG_PTR) status, 0, 'VC') #endif // TC_HEADER_NTDRIVER diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c index cfcc45e6..0376033f 100644 --- a/src/Driver/Ntvol.c +++ b/src/Driver/Ntvol.c @@ -5,9 +5,9 @@ governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -42,28 +42,41 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount, PWSTR pwszMountVolume, BOOL bRawDevice) { - FILE_STANDARD_INFORMATION FileStandardInfo; + FILE_STANDARD_INFORMATION FileStandardInfo = { 0 }; FILE_BASIC_INFORMATION FileBasicInfo; OBJECT_ATTRIBUTES oaFileAttributes; UNICODE_STRING FullFileName; IO_STATUS_BLOCK IoStatusBlock; PCRYPTO_INFO cryptoInfoPtr = NULL; PCRYPTO_INFO tmpCryptoInfo = NULL; - LARGE_INTEGER lDiskLength; + LARGE_INTEGER lDiskLength = { 0 }; __int64 partitionStartingOffset = 0; int volumeType; - char *readBuffer = 0; + unsigned char *readBuffer = 0; NTSTATUS ntStatus = 0; - BOOL forceAccessCheck = (!bRawDevice && !(OsMajorVersion == 5 &&OsMinorVersion == 0)); // Windows 2000 does not support OBJ_FORCE_ACCESS_CHECK attribute + BOOL forceAccessCheck = !bRawDevice; BOOL disableBuffering = TRUE; BOOL exclusiveAccess = mount->bExclusiveAccess; + /* when mounting with hidden volume protection, we cache the passwords after both outer and hidden volumes are mounted successfully*/ + BOOL bAutoCachePassword = mount->bProtectHiddenVolume? FALSE : mount->bCache; Extension->pfoDeviceFile = NULL; Extension->hDeviceFile = NULL; Extension->bTimeStampValid = FALSE; + /* default value for storage alignment */ + Extension->HostMaximumTransferLength = 65536; + Extension->HostMaximumPhysicalPages = 17; + Extension->HostAlignmentMask = 0; + + /* default values for non-SSD drives */ + Extension->IncursSeekPenalty = TRUE; + Extension->TrimEnabled = FALSE; + + Extension->DeviceNumber = (ULONG) -1; + RtlInitUnicodeString (&FullFileName, pwszMountVolume); InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL); KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE); @@ -74,70 +87,156 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, goto error; } mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = FALSE; + mount->VolumeMountedReadOnlyAfterPartialSysEnc = FALSE; + mount->VolumeMasterKeyVulnerable = FALSE; // If we are opening a device, query its size first if (bRawDevice) { PARTITION_INFORMATION pi; PARTITION_INFORMATION_EX pix; LARGE_INTEGER diskLengthInfo; - DISK_GEOMETRY dg; - STORAGE_PROPERTY_QUERY storagePropertyQuery = {0}; - STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR storageDescriptor = {0}; + DISK_GEOMETRY_EX dg; + STORAGE_PROPERTY_QUERY storagePropertyQuery = { 0 }; + uint8* dgBuffer; + STORAGE_DEVICE_NUMBER storageDeviceNumber; - ntStatus = IoGetDeviceObjectPointer (&FullFileName, + ntStatus = IoGetDeviceObjectPointer(&FullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES, &Extension->pfoDeviceFile, &Extension->pFsdDevice); - if (!NT_SUCCESS (ntStatus)) + if (!NT_SUCCESS(ntStatus)) goto error; - ntStatus = TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char *) &dg, sizeof (dg)); - if (!NT_SUCCESS (ntStatus)) + dgBuffer = TCalloc(256); + if (!dgBuffer) + { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto error; + } + + ntStatus = TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, (char*)dgBuffer, 256); + if (!NT_SUCCESS(ntStatus)) + { + DISK_GEOMETRY geo; + ntStatus = TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char*)&geo, sizeof(geo)); + if (!NT_SUCCESS(ntStatus)) + { + TCfree(dgBuffer); + goto error; + } + memset(&dg, 0, sizeof(dg)); + memcpy(&dg.Geometry, &geo, sizeof(geo)); + dg.DiskSize.QuadPart = geo.Cylinders.QuadPart * geo.SectorsPerTrack * geo.TracksPerCylinder * geo.BytesPerSector; + + STORAGE_READ_CAPACITY storage = { 0 }; + NTSTATUS lStatus; + + storage.Version = sizeof(STORAGE_READ_CAPACITY); + storage.Size = sizeof(STORAGE_READ_CAPACITY); + lStatus = TCSendHostDeviceIoControlRequest(DeviceObject, Extension, + IOCTL_STORAGE_READ_CAPACITY, + (char*)&storage, sizeof(STORAGE_READ_CAPACITY)); + if (NT_SUCCESS(lStatus) + && (storage.Size == sizeof(STORAGE_READ_CAPACITY)) + ) + { + dg.DiskSize.QuadPart = storage.DiskLength.QuadPart; + } + } + else + memcpy(&dg, dgBuffer, sizeof(DISK_GEOMETRY_EX)); + + TCfree(dgBuffer); - lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector; - Extension->HostBytesPerSector = dg.BytesPerSector; + if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, + IOCTL_STORAGE_GET_DEVICE_NUMBER, + (char*)&storageDeviceNumber, sizeof(storageDeviceNumber)))) + { + Extension->DeviceNumber = storageDeviceNumber.DeviceNumber; + } + + lDiskLength.QuadPart = dg.DiskSize.QuadPart; + Extension->HostBytesPerSector = dg.Geometry.BytesPerSector; + Extension->HostBytesPerPhysicalSector = dg.Geometry.BytesPerSector; + + STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR alignmentDesc = { 0 }; + STORAGE_ADAPTER_DESCRIPTOR adapterDesc = { 0 }; + DEVICE_SEEK_PENALTY_DESCRIPTOR penaltyDesc = { 0 }; + DEVICE_TRIM_DESCRIPTOR trimDesc = { 0 }; storagePropertyQuery.PropertyId = StorageAccessAlignmentProperty; storagePropertyQuery.QueryType = PropertyStandardQuery; - /* IOCTL_STORAGE_QUERY_PROPERTY supported only on Vista and above */ - if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, - (char*) &storagePropertyQuery, sizeof(storagePropertyQuery), - (char *) &storageDescriptor, sizeof (storageDescriptor)))) + alignmentDesc.Version = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); + alignmentDesc.Size = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); + + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&alignmentDesc, sizeof(alignmentDesc)))) { - Extension->HostBytesPerPhysicalSector = storageDescriptor.BytesPerPhysicalSector; + Extension->HostBytesPerPhysicalSector = alignmentDesc.BytesPerPhysicalSector; } - else + + storagePropertyQuery.PropertyId = StorageAdapterProperty; + adapterDesc.Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + adapterDesc.Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&adapterDesc, sizeof(adapterDesc)))) { - Extension->HostBytesPerPhysicalSector = dg.BytesPerSector; + Extension->HostMaximumTransferLength = adapterDesc.MaximumTransferLength; + Extension->HostMaximumPhysicalPages = adapterDesc.MaximumPhysicalPages; + Extension->HostAlignmentMask = adapterDesc.AlignmentMask; + } + + storagePropertyQuery.PropertyId = StorageDeviceSeekPenaltyProperty; + penaltyDesc.Version = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + penaltyDesc.Size = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&penaltyDesc, sizeof(penaltyDesc)))) + { + Extension->IncursSeekPenalty = penaltyDesc.IncursSeekPenalty; + } + + storagePropertyQuery.PropertyId = StorageDeviceTrimProperty; + trimDesc.Version = sizeof(DEVICE_TRIM_DESCRIPTOR); + trimDesc.Size = sizeof(DEVICE_TRIM_DESCRIPTOR); + + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&trimDesc, sizeof(trimDesc)))) + { + Extension->TrimEnabled = trimDesc.TrimEnabled; } // Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails - if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char *) &pix, sizeof (pix)))) + if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char*)&pix, sizeof(pix)))) { lDiskLength.QuadPart = pix.PartitionLength.QuadPart; partitionStartingOffset = pix.StartingOffset.QuadPart; } - // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX - else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char *) &pi, sizeof (pi)))) + // If IOCTL_DISK_GET_PARTITION_INFO_EX fails, switch to IOCTL_DISK_GET_PARTITION_INFO + else if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char*)&pi, sizeof(pi)))) { lDiskLength.QuadPart = pi.PartitionLength.QuadPart; partitionStartingOffset = pi.StartingOffset.QuadPart; } - else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_LENGTH_INFO, &diskLengthInfo, sizeof (diskLengthInfo)))) + else if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_LENGTH_INFO, &diskLengthInfo, sizeof(diskLengthInfo)))) { lDiskLength = diskLengthInfo; } ProbingHostDeviceForWrite = TRUE; if (!mount->bMountReadOnly - && TCSendHostDeviceIoControlRequest (DeviceObject, Extension, + && TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IsHiddenSystemRunning() ? TC_IOCTL_DISK_IS_WRITABLE : IOCTL_DISK_IS_WRITABLE, NULL, 0) == STATUS_MEDIA_WRITE_PROTECTED) { mount->bMountReadOnly = TRUE; DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; @@ -163,8 +262,11 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, } Extension->HostBytesPerSector = mount->BytesPerSector; Extension->HostBytesPerPhysicalSector = mount->BytesPerPhysicalSector; + Extension->HostMaximumTransferLength = mount->MaximumTransferLength; + Extension->HostMaximumPhysicalPages = mount->MaximumPhysicalPages; + Extension->HostAlignmentMask = mount->AlignmentMask; if (Extension->HostBytesPerSector != TC_SECTOR_SIZE_FILE_HOSTED_VOLUME) disableBuffering = FALSE; } @@ -197,9 +299,9 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, if (mount->bMountReadOnly || ntStatus == STATUS_ACCESS_DENIED) { ntStatus = ZwCreateFile (&Extension->hDeviceFile, - GENERIC_READ | SYNCHRONIZE, + GENERIC_READ | (!bRawDevice && mount->bPreserveTimestamp? FILE_WRITE_ATTRIBUTES : 0) | SYNCHRONIZE, &oaFileAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL | @@ -212,8 +314,28 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); + if (!NT_SUCCESS (ntStatus) && !bRawDevice && mount->bPreserveTimestamp) + { + /* try again without FILE_WRITE_ATTRIBUTES */ + ntStatus = ZwCreateFile (&Extension->hDeviceFile, + GENERIC_READ | SYNCHRONIZE, + &oaFileAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL | + FILE_ATTRIBUTE_SYSTEM, + exclusiveAccess ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_RANDOM_ACCESS | + FILE_WRITE_THROUGH | + (disableBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0) | + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + } + if (NT_SUCCESS (ntStatus) && !mount->bMountReadOnly) mount->VolumeMountedReadOnlyAfterAccessDenied = TRUE; Extension->bReadOnly = TRUE; @@ -256,8 +378,20 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->fileLastAccessTime = FileBasicInfo.LastAccessTime; Extension->fileLastWriteTime = FileBasicInfo.LastWriteTime; Extension->fileLastChangeTime = FileBasicInfo.ChangeTime; Extension->bTimeStampValid = TRUE; + + // we tell the system not to update LastAccessTime, LastWriteTime, and ChangeTime + FileBasicInfo.CreationTime.QuadPart = 0; + FileBasicInfo.LastAccessTime.QuadPart = -1; + FileBasicInfo.LastWriteTime.QuadPart = -1; + FileBasicInfo.ChangeTime.QuadPart = -1; + + ZwSetInformationFile (Extension->hDeviceFile, + &IoStatusBlock, + &FileBasicInfo, + sizeof (FileBasicInfo), + FileBasicInformation); } ntStatus = ZwQueryInformationFile (Extension->hDeviceFile, &IoStatusBlock, @@ -346,9 +480,9 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, { // Header of a volume that is not within the scope of system encryption, or // header of a system hidden volume (containing a hidden OS) - LARGE_INTEGER headerOffset; + LARGE_INTEGER headerOffset = {0}; if (mount->UseBackupHeader && lDiskLength.QuadPart <= TC_TOTAL_VOLUME_HEADERS_SIZE) continue; @@ -464,28 +598,26 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, if ((volumeType == TC_VOLUME_TYPE_HIDDEN) && mount->bProtectHiddenVolume) { mount->nReturnCode = ReadVolumeHeaderWCache ( FALSE, - mount->bCache, + bAutoCachePassword, mount->bCachePim, readBuffer, &mount->ProtectedHidVolPassword, mount->ProtectedHidVolPkcs5Prf, mount->ProtectedHidVolPim, - mount->bTrueCryptMode, &tmpCryptoInfo); } else { mount->nReturnCode = ReadVolumeHeaderWCache ( mount->bPartitionInInactiveSysEncScope && volumeType == TC_VOLUME_TYPE_NORMAL, - mount->bCache, + bAutoCachePassword, mount->bCachePim, readBuffer, &mount->VolumePassword, mount->pkcs5_prf, mount->VolumePim, - mount->bTrueCryptMode, &Extension->cryptoInfo); } ReadVolumeHeaderRecoveryMode = FALSE; @@ -501,11 +633,17 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, ntStatus = STATUS_SUCCESS; goto error; } + if (IsRamEncryptionEnabled() && (volumeType == TC_VOLUME_TYPE_NORMAL || !mount->bProtectHiddenVolume)) + VcProtectKeys (Extension->cryptoInfo, VcGetEncryptionID (Extension->cryptoInfo)); + Dump ("Volume header decrypted\n"); Dump ("Required program version = %x\n", (int) Extension->cryptoInfo->RequiredProgramVersion); Dump ("Legacy volume = %d\n", (int) Extension->cryptoInfo->LegacyVolume); + Dump ("Master key vulnerable = %d\n", (int) Extension->cryptoInfo->bVulnerableMasterKey); + + mount->VolumeMasterKeyVulnerable = Extension->cryptoInfo->bVulnerableMasterKey; if (IsHiddenSystemRunning() && !Extension->cryptoInfo->hiddenVolume) { Extension->bReadOnly = mount->bMountReadOnly = TRUE; @@ -516,9 +654,9 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->cryptoInfo->bHiddenVolProtectionAction = FALSE; Extension->cryptoInfo->bPartitionInInactiveSysEncScope = mount->bPartitionInInactiveSysEncScope; - /* compute the ID of this volume: SHA-512 of the effective header */ + /* compute the ID of this volume: SHA-256 of the effective header */ sha256 (Extension->volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (volumeType == TC_VOLUME_TYPE_NORMAL) { @@ -534,12 +672,11 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, } if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value) { - // Partial encryption is not supported for volumes mounted as regular - mount->nReturnCode = ERR_ENCRYPTION_NOT_COMPLETED; - ntStatus = STATUS_SUCCESS; - goto error; + // mount as readonly in case of partial system encryption + Extension->bReadOnly = mount->bMountReadOnly = TRUE; + mount->VolumeMountedReadOnlyAfterPartialSysEnc = TRUE; } } else if (Extension->cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) { @@ -557,9 +694,9 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, if (Extension->cryptoInfo->hiddenVolume && IsHiddenSystemRunning()) { // Prevent mount of a hidden system partition if the system hosted on it is currently running - if (memcmp (Extension->cryptoInfo->master_keydata, GetSystemDriveCryptoInfo()->master_keydata, EAGetKeySize (Extension->cryptoInfo->ea)) == 0) + if (memcmp (Extension->cryptoInfo->master_keydata_hash, GetSystemDriveCryptoInfo()->master_keydata_hash, sizeof(Extension->cryptoInfo->master_keydata_hash)) == 0) { mount->nReturnCode = ERR_VOL_ALREADY_MOUNTED; ntStatus = STATUS_SUCCESS; goto error; @@ -661,9 +798,9 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->bRawDevice = bRawDevice; memset (Extension->wszVolume, 0, sizeof (Extension->wszVolume)); - if (wcsstr (pwszMountVolume, WIDE ("\\??\\UNC\\")) == pwszMountVolume) + if ((wcslen (pwszMountVolume) > 8) && (0 == memcmp (pwszMountVolume, WIDE ("\\??\\UNC\\"), 8 * sizeof (WCHAR)))) { /* UNC path */ RtlStringCbPrintfW (Extension->wszVolume, sizeof (Extension->wszVolume), @@ -682,8 +819,15 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, // If we are to protect a hidden volume we cannot exit yet, for we must also // decrypt the hidden volume header. if (!(volumeType == TC_VOLUME_TYPE_NORMAL && mount->bProtectHiddenVolume)) { + /* in case of mounting with hidden volume protection, we cache both passwords manually after bother outer and hidden volumes are mounted*/ + if (mount->bProtectHiddenVolume && mount->bCache) + { + AddPasswordToCache(&mount->VolumePassword, mount->VolumePim, mount->bCachePim); + AddPasswordToCache(&mount->ProtectedHidVolPassword, mount->ProtectedHidVolPim, mount->bCachePim); + } + TCfree (readBuffer); if (tmpCryptoInfo != NULL) { @@ -774,8 +918,21 @@ void TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) Extension->cryptoInfo = NULL; } } +typedef struct +{ + PDEVICE_OBJECT deviceObject; PEXTENSION Extension; ULONG ioControlCode; void *inputBuffer; int inputBufferSize; void *outputBuffer; int outputBufferSize; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} TCSendHostDeviceIoControlRequestExWorkItemArgs; + +static VOID TCSendHostDeviceIoControlRequestExWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCSendHostDeviceIoControlRequestExWorkItemArgs *arg) +{ + UNREFERENCED_PARAMETER(rootDeviceObject); /* Remove compiler warning */ + arg->Status = TCSendHostDeviceIoControlRequestEx (arg->deviceObject, arg->Extension, arg->ioControlCode, arg->inputBuffer, arg->inputBufferSize, arg->outputBuffer, arg->outputBufferSize); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, ULONG IoControlCode, @@ -789,8 +946,33 @@ NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject, PIRP Irp; UNREFERENCED_PARAMETER(DeviceObject); /* Remove compiler warning */ + if ((KeGetCurrentIrql() >= APC_LEVEL) || KeAreAllApcsDisabled()) + { + TCSendHostDeviceIoControlRequestExWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.deviceObject = DeviceObject; + args.Extension = Extension; + args.ioControlCode = IoControlCode; + args.inputBuffer = InputBuffer; + args.inputBufferSize = InputBufferSize; + args.outputBuffer = OutputBuffer; + args.outputBufferSize = OutputBufferSize; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, TCSendHostDeviceIoControlRequestExWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + KeClearEvent (&Extension->keVolumeEvent); Irp = IoBuildDeviceIoControlRequest (IoControlCode, Extension->pFsdDevice, diff --git a/src/Driver/Ntvol.h b/src/Driver/Ntvol.h index ae7d9cb3..1d80b7de 100644 --- a/src/Driver/Ntvol.h +++ b/src/Driver/Ntvol.h @@ -5,9 +5,9 @@ governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ diff --git a/src/Driver/VolumeFilter.c b/src/Driver/VolumeFilter.c index 50ac74da..b4bc8d2e 100644 --- a/src/Driver/VolumeFilter.c +++ b/src/Driver/VolumeFilter.c @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ @@ -24,9 +24,9 @@ uint32 HiddenSysLeakProtectionCount = 0; NTSTATUS VolumeFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) { - VolumeFilterExtension *Extension; + VolumeFilterExtension *Extension = NULL; NTSTATUS status; PDEVICE_OBJECT filterDeviceObject = NULL; PDEVICE_OBJECT attachedDeviceObject; @@ -71,9 +71,9 @@ NTSTATUS VolumeFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) err: if (filterDeviceObject) { - if (Extension->LowerDeviceObject) + if (Extension && Extension->LowerDeviceObject) IoDetachDevice (Extension->LowerDeviceObject); IoDeleteDevice (filterDeviceObject); } @@ -124,12 +124,39 @@ static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return STATUS_CONTINUE_COMPLETION; } +static BOOL IsSystemVolumePartition (VolumeFilterExtension *Extension) +{ + NTSTATUS status; + BOOL bRet = FALSE; + DriveFilterExtension *bootDriveExtension = GetBootDriveFilterExtension(); + STORAGE_DEVICE_NUMBER storageDeviceNumber; + + if (!bootDriveExtension->SystemStorageDeviceNumberValid) + TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + + status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof (storageDeviceNumber)); + + if (NT_SUCCESS (status) && bootDriveExtension->SystemStorageDeviceNumber == storageDeviceNumber.DeviceNumber) + { + PARTITION_INFORMATION_EX partition; + status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partition, sizeof (partition)); + + if (NT_SUCCESS (status) && partition.StartingOffset.QuadPart == bootDriveExtension->ConfiguredEncryptedAreaStart) + { + bRet = TRUE; + } + } + + return bRet; +} + static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { NTSTATUS status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); + UNREFERENCED_PARAMETER(DeviceObject); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); if (IsHiddenSystemRunning()) @@ -138,27 +165,12 @@ static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFi { case IOCTL_DISK_IS_WRITABLE: { // All volumes except the system volume must be read-only - - DriveFilterExtension *bootDriveExtension = GetBootDriveFilterExtension(); - STORAGE_DEVICE_NUMBER storageDeviceNumber; - - if (!bootDriveExtension->SystemStorageDeviceNumberValid) - TC_BUG_CHECK (STATUS_INVALID_PARAMETER); - - status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof (storageDeviceNumber)); - - if (NT_SUCCESS (status) && bootDriveExtension->SystemStorageDeviceNumber == storageDeviceNumber.DeviceNumber) + if (IsSystemVolumePartition(Extension)) { - PARTITION_INFORMATION_EX partition; - status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partition, sizeof (partition)); - - if (NT_SUCCESS (status) && partition.StartingOffset.QuadPart == bootDriveExtension->ConfiguredEncryptedAreaStart) - { - IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); - return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); - } + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); } IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); @@ -193,8 +205,17 @@ static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFi // Filter IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES to enable potential future use of hidden systems on drives that use the trim operation but not wear-leveling (if any appear in future). The documentation forbids users to create hidden volumes/systems on drives that use wear-leveling and consequently also on drives that use trim (as trim is used only by drives that use wear-leveling, as of 2010). IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); + + case IOCTL_DISK_GROW_PARTITION: + if (IsSystemVolumePartition(Extension)) + { + Dump ("VolumeFilter-DispatchControl: IOCTL_DISK_GROW_PARTITION blocked\n"); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_UNSUCCESSFUL, 0); + } + break; } } status = PassIrp (Extension->LowerDeviceObject, Irp); @@ -249,11 +270,12 @@ static NTSTATUS DispatchPnp (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilter return status; } -static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) +static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension) { NTSTATUS status; + UNREFERENCED_PARAMETER(DeviceObject); PoStartNextPowerIrp (Irp); status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) @@ -283,9 +305,9 @@ NTSTATUS VolumeFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) case IRP_MJ_PNP: return DispatchPnp (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_POWER: - return DispatchPower (DeviceObject, Irp, Extension, irpSp); + return DispatchPower (DeviceObject, Irp, Extension); default: status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) diff --git a/src/Driver/VolumeFilter.h b/src/Driver/VolumeFilter.h index b73b4f48..f3e53237 100644 --- a/src/Driver/VolumeFilter.h +++ b/src/Driver/VolumeFilter.h @@ -3,9 +3,9 @@ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ diff --git a/src/Driver/veracrypt.Inf b/src/Driver/veracrypt.Inf new file mode 100644 index 00000000..d2cef1b4 --- /dev/null +++ b/src/Driver/veracrypt.Inf @@ -0,0 +1,91 @@ +;;; +;;; VeraCrypt +;;; +;;; +;;; Copyright (c) 2024, IDRIX +;;; + +[Version] +signature = "$Windows NT$" +Class = "Encryption" ;This is determined by the work this filter driver does +ClassGuid = {a0a701c0-a511-42ff-aa6c-06dc0395576f} ;This value is determined by the Class +Provider = %ProviderString% +DriverVer = ; +CatalogFile = veracrypt.cat +PnpLockdown = 1 + +[DestinationDirs] +DefaultDestDir = 12 +veracrypt.DriverFiles = 12 ;%windir%\system32\drivers + +;; +;; Default install sections +;; + +[DefaultInstall.NTx86] +OptionDesc = %ServiceDescription% +CopyFiles = veracrypt.DriverFiles +AddReg = veracrypt.AddReg + +[DefaultInstall.NTamd64] +OptionDesc = %ServiceDescription% +CopyFiles = veracrypt.DriverFiles +AddReg = veracrypt.AddReg + +[DefaultInstall.NTarm64] +OptionDesc = %ServiceDescription% +CopyFiles = veracrypt.DriverFiles +AddReg = veracrypt.AddReg + +[DefaultInstall.NTx86.Services] +AddService = veracrypt,,veracrypt.Service + +[DefaultInstall.NTamd64.Services] +AddService = veracrypt,,veracrypt.Service + +[DefaultInstall.NTarm64.Services] +AddService = veracrypt,,veracrypt.Service + +; +; Services Section +; + +[veracrypt.Service] +DisplayName = %ServiceDescription% +Description = %ServiceDescription% +ServiceBinary = %12%\veracrypt.sys ;%windir%\system32\drivers\ +ServiceType = 2 ;SERVICE_FILE_SYSTEM_DRIVER +StartType = 0 ;SERVICE_BOOT_START +ErrorControl = 1 ;SERVICE_ERROR_NORMAL +LoadOrderGroup = "Filter" + +; +; Copy Files +; + +[veracrypt.DriverFiles] +veracrypt.sys + +[SourceDisksFiles] +veracrypt.sys = 1,, + +[SourceDisksNames] +1 = %DiskId1%,,, + +; +; Registry Entries +; + +[veracrypt.AddReg] +HKLM, System\CurrentControlSet\Control\Class\{4d36e967-e325-11ce-bfc1-08002be10318}, UpperFilters, 0x00010008, veracrypt +HKLM, System\CurrentControlSet\Control\Class\{4d36e967-e325-11ce-bfc1-08002be10318}, UpperFilters, 0x00010008, PartMgr + +;; +;; String Section +;; + +[Strings] +ProviderString = "IDRIX" +ServiceDescription = "veracrypt" +DiskId1 = "VeraCrypt Device Installation Disk" + |