├── Commons ├── include │ ├── CommonStructs.h │ └── CryptoUtils.h ├── lib │ └── CryptoUtils.lib └── src │ └── CryptoUtils │ ├── CryptoUtils.cpp │ ├── CryptoUtils.h │ ├── CryptoUtils.pro │ ├── stdafx.h │ └── targetver.h ├── Driver ├── driver27.VC.db ├── driver27.sln └── driver27 │ ├── cryptUtils.h │ ├── defi.h │ ├── driver27.c │ ├── driver27.inf │ ├── driver27.vcxproj │ ├── driver27.vcxproj.filters │ └── driver27.vcxproj.user └── EncryptedDisk ├── EncryptedDisk.pro ├── EncryptedDiskClientLib ├── DriverCommunication.cpp ├── DriverCommunication.h ├── EncryptedDiskClientLib.pro ├── IVirtualDiskControllerObserver.h ├── Transport.cpp ├── Transport.h ├── VirtualDiskController.cpp ├── VirtualDiskController.h ├── disk.h ├── stdafx.h └── targetver.h └── EncryptedDiskGui ├── CreateNewDiskDialog.cpp ├── CreateNewDiskDialog.h ├── CreateNewDiskDialog.ui ├── EncryptedDiskGui.pro ├── MainWindow.cpp ├── MainWindow.h ├── MainWindow.ui ├── MountDiskDialog.cpp ├── MountDiskDialog.h ├── MountDiskDialog.ui └── main.cpp /Commons/include/CommonStructs.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_STRUCTS_H 2 | #define COMMON_STRUCTS_H 3 | 4 | typedef struct _OPEN_FILE_INFORMATION 5 | { 6 | LARGE_INTEGER FileSize; 7 | LARGE_INTEGER SectorSize; 8 | USHORT DiskOffset; 9 | CHAR Password[16]; 10 | USHORT PasswordLength; 11 | CHAR DriveLetter; 12 | USHORT FileNameLength; 13 | CHAR FileName[260]; 14 | } OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION; 15 | 16 | typedef struct _DISK_INFO 17 | { 18 | USHORT DiskCount; 19 | OPEN_FILE_INFORMATION disks[26]; 20 | 21 | } DISK_INFO, *PDISK_INFO; 22 | 23 | #define IOCTL_FILE_DISK_OPEN_FILE CTL_CODE(FILE_DEVICE_DISK, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 24 | #define IOCTL_FILE_DISK_CLOSE_FILE CTL_CODE(FILE_DEVICE_DISK, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 25 | #define IOCTL_FILE_DISK_QUERY_FILE CTL_CODE(FILE_DEVICE_DISK, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS) 26 | #define IOCTL_FILE_DISK_UNMOUNT_ALL CTL_CODE(FILE_DEVICE_DISK, 0x803, METHOD_BUFFERED, FILE_READ_ACCESS) 27 | 28 | #endif // COMMON_STRUCTS_H 29 | -------------------------------------------------------------------------------- /Commons/include/CryptoUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | const size_t cAesKeySize256Bit = 32; 4 | 5 | struct AesKey 6 | { 7 | BCRYPT_KEY_HANDLE hKey; 8 | ULONG blockSize; 9 | }; 10 | 11 | bool MakeAesKey(AesKey *pAesKey, const char *password); 12 | size_t GetCryptedBlockSize(AesKey *pAesKey, size_t dataSize, bool encrypt); 13 | size_t EncrypDecryptData(AesKey *pAesKey, unsigned char *srcData, size_t srcDataSize, unsigned char *dstData, size_t dstDataSize, bool encrypt, unsigned char* iv = NULL); 14 | void PrepareIv(const AesKey* key, uint64_t ivValue, unsigned char* iv); 15 | -------------------------------------------------------------------------------- /Commons/lib/CryptoUtils.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArtDnpr/VirtualEncryptedDisk/8e35e57d6c9439b40ff269214199a6d6721483ca/Commons/lib/CryptoUtils.lib -------------------------------------------------------------------------------- /Commons/src/CryptoUtils/CryptoUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CryptoUtils.h" 3 | 4 | bool InitCBCAlg(BCRYPT_ALG_HANDLE *phAesAlg) 5 | { 6 | 7 | if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(phAesAlg, BCRYPT_AES_ALGORITHM, NULL, 0))) 8 | { 9 | goto cleanup; 10 | } 11 | 12 | if (!BCRYPT_SUCCESS(BCryptSetProperty(*phAesAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0))) 13 | { 14 | goto cleanup; 15 | } 16 | 17 | return true; 18 | 19 | cleanup: 20 | if (*phAesAlg) 21 | { 22 | BCryptCloseAlgorithmProvider(*phAesAlg, 0); 23 | } 24 | 25 | return false; 26 | } 27 | 28 | bool HashPassword(const char * pwdToHash, unsigned char *pHashData) 29 | { 30 | bool status = false; 31 | BCRYPT_ALG_HANDLE hHashAlg = NULL; 32 | BCRYPT_HASH_HANDLE hHash = NULL; 33 | PBYTE hData = NULL; 34 | DWORD hLen = 0; 35 | DWORD tmp = 0; 36 | 37 | if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hHashAlg, BCRYPT_SHA256_ALGORITHM, NULL, 0))) 38 | { 39 | goto cleanup; 40 | } 41 | 42 | if (!BCRYPT_SUCCESS(BCryptCreateHash(hHashAlg, &hHash, NULL, NULL, NULL, 0, 0))) 43 | { 44 | goto cleanup; 45 | } 46 | 47 | if (!BCRYPT_SUCCESS(BCryptHashData(hHash, (PUCHAR)pwdToHash, (ULONG)strlen(pwdToHash), 0))) 48 | { 49 | goto cleanup; 50 | } 51 | 52 | if (!BCRYPT_SUCCESS(BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (PBYTE)&hLen, sizeof(hLen), &tmp, 0))) 53 | { 54 | goto cleanup; 55 | } 56 | 57 | hData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hLen); 58 | if (!hData) 59 | { 60 | goto cleanup; 61 | } 62 | 63 | if (!BCRYPT_SUCCESS(BCryptFinishHash(hHash, hData, hLen, 0))) 64 | { 65 | goto cleanup; 66 | } 67 | 68 | memcpy(pHashData, hData, cAesKeySize256Bit); 69 | 70 | status = true; 71 | 72 | cleanup: 73 | if (hData) 74 | { 75 | HeapFree(GetProcessHeap(), 0, hData); 76 | } 77 | 78 | if (hHash) 79 | { 80 | BCryptDestroyHash(hHash); 81 | } 82 | 83 | if (hHashAlg) 84 | { 85 | BCryptCloseAlgorithmProvider(hHashAlg, 0); 86 | } 87 | 88 | return status; 89 | } 90 | 91 | bool MakeAesKey(AesKey *pAesKey, const char *password) 92 | { 93 | bool status = false; 94 | BCRYPT_ALG_HANDLE hAesAlg = NULL; 95 | PBYTE pHashData = NULL; 96 | 97 | if (!InitCBCAlg(&hAesAlg)) 98 | { 99 | goto cleanup; 100 | } 101 | 102 | pHashData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cAesKeySize256Bit); 103 | if (!pHashData) 104 | { 105 | goto cleanup; 106 | } 107 | 108 | if (!HashPassword(password, pHashData)) 109 | { 110 | goto cleanup; 111 | } 112 | 113 | if (!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey(hAesAlg, &pAesKey->hKey, NULL, NULL, pHashData, cAesKeySize256Bit, 0))) 114 | { 115 | goto cleanup; 116 | } 117 | 118 | ULONG tmp; 119 | if (!BCRYPT_SUCCESS(BCryptGetProperty(hAesAlg, BCRYPT_BLOCK_LENGTH, (PUCHAR)&pAesKey->blockSize, sizeof(pAesKey->blockSize), &tmp, 0))) 120 | { 121 | goto cleanup; 122 | } 123 | 124 | status = true; 125 | 126 | cleanup: 127 | if (pHashData) 128 | { 129 | HeapFree(GetProcessHeap(), 0, pHashData); 130 | } 131 | 132 | if (hAesAlg) 133 | { 134 | BCryptCloseAlgorithmProvider(hAesAlg, 0); 135 | } 136 | 137 | return status; 138 | } 139 | 140 | size_t GetCryptedBlockSize(AesKey *pAesKey, size_t dataSize, bool encrypt) 141 | { 142 | NTSTATUS bcryptResult = 0; 143 | size_t cryptedBlockSize = 0; 144 | bcryptResult = (encrypt ? BCryptEncrypt : BCryptDecrypt)(pAesKey->hKey, NULL, (ULONG)dataSize, NULL, NULL, NULL, NULL, 0, (ULONG*)&cryptedBlockSize, 0); 145 | 146 | return BCRYPT_SUCCESS(bcryptResult) ? cryptedBlockSize : 0; 147 | } 148 | 149 | size_t EncrypDecryptData(AesKey *pAesKey, unsigned char *srcData, size_t srcDataSize, unsigned char *dstData, size_t dstDataSize, bool encrypt, unsigned char* iv) 150 | { 151 | size_t writtenBytes = 0; 152 | if (!BCRYPT_SUCCESS((encrypt ? BCryptEncrypt : BCryptDecrypt)(pAesKey->hKey, 153 | srcData, (ULONG)srcDataSize, NULL, iv, pAesKey->blockSize, 154 | dstData, (ULONG)dstDataSize, (ULONG*)&writtenBytes, 0))) 155 | { 156 | return 0; 157 | } 158 | 159 | return writtenBytes; 160 | } 161 | 162 | void PrepareIv(const AesKey* key, uint64_t ivValue, unsigned char* iv) 163 | { 164 | memset(iv, 0, key->blockSize); 165 | memcpy(iv, &ivValue, sizeof(ivValue)); 166 | } 167 | 168 | -------------------------------------------------------------------------------- /Commons/src/CryptoUtils/CryptoUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | const size_t cAesKeySize256Bit = 32; 4 | 5 | struct AesKey 6 | { 7 | BCRYPT_KEY_HANDLE hKey; 8 | ULONG blockSize; 9 | }; 10 | 11 | bool MakeAesKey(AesKey *pAesKey, const char *password); 12 | size_t GetCryptedBlockSize(AesKey *pAesKey, size_t dataSize, bool encrypt); 13 | size_t EncrypDecryptData(AesKey *pAesKey, unsigned char *srcData, size_t srcDataSize, unsigned char *dstData, size_t dstDataSize, bool encrypt, unsigned char* iv = NULL); 14 | void PrepareIv(const AesKey* key, uint64_t ivValue, unsigned char* iv); 15 | -------------------------------------------------------------------------------- /Commons/src/CryptoUtils/CryptoUtils.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | CONFIG += staticlib 3 | 4 | INCLUDEPATH = \ 5 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt" 6 | 7 | SOURCES += \ 8 | CryptoUtils.cpp 9 | 10 | HEADERS += \ 11 | targetver.h \ 12 | CryptoUtils.h \ 13 | stdafx.h 14 | -------------------------------------------------------------------------------- /Commons/src/CryptoUtils/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | #include 13 | -------------------------------------------------------------------------------- /Commons/src/CryptoUtils/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /Driver/driver27.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArtDnpr/VirtualEncryptedDisk/8e35e57d6c9439b40ff269214199a6d6721483ca/Driver/driver27.VC.db -------------------------------------------------------------------------------- /Driver/driver27.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "driver27", "driver27\driver27.vcxproj", "{F27D11F5-D105-45F5-AFDF-E6FBF317DD99}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|ARM.Build.0 = Debug|ARM 22 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|x64.ActiveCfg = Debug|x64 27 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|x64.Build.0 = Debug|x64 28 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|x64.Deploy.0 = Debug|x64 29 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|x86.ActiveCfg = Debug|Win32 30 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|x86.Build.0 = Debug|Win32 31 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Debug|x86.Deploy.0 = Debug|Win32 32 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|ARM.ActiveCfg = Release|ARM 33 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|ARM.Build.0 = Release|ARM 34 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|ARM.Deploy.0 = Release|ARM 35 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|ARM64.Build.0 = Release|ARM64 37 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|x64.ActiveCfg = Release|x64 39 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|x64.Build.0 = Release|x64 40 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|x64.Deploy.0 = Release|x64 41 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|x86.ActiveCfg = Release|Win32 42 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|x86.Build.0 = Release|Win32 43 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | EndGlobal 49 | -------------------------------------------------------------------------------- /Driver/driver27/cryptUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //#include 3 | //const size_t cAesKeySize256Bit = 32; 4 | //#define uint64_t unsigned long long 5 | // 6 | //struct AesKey 7 | //{ 8 | // BCRYPT_KEY_HANDLE hKey; 9 | // ULONG blockSize; 10 | //}; 11 | // 12 | //bool MakeAesKey(AesKey *pAesKey, const char *password); 13 | //size_t GetCryptedBlockSize(AesKey *pAesKey, size_t dataSize, bool encrypt); 14 | //size_t EncrypDecryptData(AesKey *pAesKey, unsigned char *srcData, size_t srcDataSize, unsigned char *dstData, size_t dstDataSize, bool encrypt, unsigned char* iv = NULL); 15 | //void PrepareIv(const AesKey* key, uint64_t ivValue, unsigned char* iv); -------------------------------------------------------------------------------- /Driver/driver27/defi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #ifndef _FILE_DISK_ 5 | #define _FILE_DISK_ 6 | 7 | #define FILE_DISK_POOL_TAG 'ksiD' 8 | 9 | #ifndef __T 10 | #ifdef _NTDDK_ 11 | #define __T(x) L ## x 12 | #else 13 | #define __T(x) x 14 | #endif 15 | #endif 16 | 17 | #ifndef _T 18 | #define _T(x) __T(x) 19 | #endif 20 | 21 | #define DEVICE_BASE_NAME _T("\\FileDisk") 22 | #define DEVICE_DIR_NAME _T("\\Device") DEVICE_BASE_NAME 23 | #define DEVICE_NAME_PREFIX DEVICE_DIR_NAME 24 | #define SYMBLINK0 _T("\\DosDevices\\Global\\MyDevice") 25 | #define SYMBLINK1 _T("\\DosDevices\\Global\\K:") 26 | #define DEVICE_SYMB0_NAME DEVICE_NAME_PREFIX SYMBLINK0 27 | #define DEVICE_SYMB1_NAME DEVICE_NAME_PREFIX SYMBLINK1 28 | 29 | #define MAX_PATH1 260 30 | #define INVALID_NUMBER_DEV 150 31 | 32 | typedef struct _OPEN_FILE_INFORMATION 33 | { 34 | LARGE_INTEGER FileSize; 35 | LARGE_INTEGER SectorSize; 36 | USHORT DiskOffset; 37 | CHAR Password[16]; 38 | USHORT PasswordLength; 39 | UCHAR DriveLetter; 40 | USHORT FileNameLength; 41 | CHAR FileName[260]; 42 | } OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION; 43 | 44 | typedef struct _DISK_INFO 45 | { 46 | USHORT DiskCount; 47 | OPEN_FILE_INFORMATION disks[26]; 48 | } DISK_INFO, *PDISK_INFO; 49 | 50 | #define IOCTL_FILE_DISK_OPEN_FILE CTL_CODE(FILE_DEVICE_DISK, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 51 | #define IOCTL_FILE_DISK_CLOSE_FILE CTL_CODE(FILE_DEVICE_DISK, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 52 | #define IOCTL_FILE_DISK_QUERY_FILE CTL_CODE(FILE_DEVICE_DISK, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS) 53 | #define IOCTL_FILE_DISK_UNMOUNT_ALL CTL_CODE(FILE_DEVICE_DISK, 0x803, METHOD_BUFFERED, FILE_READ_ACCESS) 54 | 55 | 56 | #pragma once 57 | #include 58 | 59 | const size_t cAesKeySize256Bit = 32; 60 | 61 | typedef struct _AesKey 62 | { 63 | BCRYPT_KEY_HANDLE hKey; 64 | ULONG blockSize; 65 | } AesKey, *PAesKey; 66 | 67 | #define uint64_t unsigned long long 68 | #define bool BOOLEAN 69 | 70 | bool MakeAesKey(AesKey* pAesKey, const char *password); 71 | size_t GetCryptedBlockSize(AesKey* pAesKey, size_t dataSize, bool encrypt); 72 | size_t EncrypDecryptData(AesKey* pAesKey, unsigned char *srcData, size_t srcDataSize, unsigned char *dstData, size_t dstDataSize, bool encrypt, unsigned char* iv); 73 | void PrepareIv(const AesKey* key, uint64_t ivValue, unsigned char* iv); 74 | 75 | bool InitCBCAlg(BCRYPT_ALG_HANDLE *phAesAlg) 76 | { 77 | 78 | if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(phAesAlg, BCRYPT_AES_ALGORITHM, NULL, 0))) 79 | { 80 | goto cleanup; 81 | } 82 | 83 | if (!BCRYPT_SUCCESS(BCryptSetProperty(*phAesAlg, BCRYPT_CHAINING_MODE, (unsigned char*)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0))) 84 | { 85 | goto cleanup; 86 | } 87 | 88 | return TRUE; 89 | 90 | cleanup: 91 | if (*phAesAlg) 92 | { 93 | BCryptCloseAlgorithmProvider(*phAesAlg, 0); 94 | } 95 | 96 | return FALSE; 97 | } 98 | 99 | bool HashPassword(const char * pwdToHash, unsigned char *pHashData) 100 | { 101 | bool status = FALSE; 102 | BCRYPT_ALG_HANDLE hHashAlg = NULL; 103 | BCRYPT_HASH_HANDLE hHash = NULL; 104 | unsigned char* hData = NULL; 105 | SIZE_T hLen = 0; 106 | DWORD tmp = 0; 107 | 108 | if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hHashAlg, BCRYPT_SHA256_ALGORITHM, NULL, 0))) 109 | { 110 | goto cleanup; 111 | } 112 | 113 | if (!BCRYPT_SUCCESS(BCryptCreateHash(hHashAlg, &hHash, (PUCHAR)NULL, (ULONG)NULL, NULL, 0, 0))) 114 | { 115 | goto cleanup; 116 | } 117 | 118 | if (!BCRYPT_SUCCESS(BCryptHashData(hHash, (PUCHAR)pwdToHash, (ULONG)strlen(pwdToHash), 0))) 119 | { 120 | goto cleanup; 121 | } 122 | 123 | if (!BCRYPT_SUCCESS(BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (unsigned char*)&hLen, sizeof(hLen), &tmp, 0))) 124 | { 125 | goto cleanup; 126 | } 127 | 128 | //hData = (unsigned char*)HeapAlloc(GetProcessHeap(), 0, hLen); 129 | hData = (unsigned char*)MmAllocateNonCachedMemory(hLen); 130 | if (!hData) 131 | { 132 | goto cleanup; 133 | } 134 | 135 | if (!BCRYPT_SUCCESS(BCryptFinishHash(hHash, hData, hLen, 0))) 136 | { 137 | goto cleanup; 138 | } 139 | 140 | memcpy(pHashData, hData, cAesKeySize256Bit); 141 | 142 | status = TRUE; 143 | 144 | cleanup: 145 | if (hData) 146 | { 147 | //HeapFree(GetProcessHeap(), 0, hData); 148 | MmFreeNonCachedMemory(hData, hLen); 149 | } 150 | 151 | if (hHash) 152 | { 153 | BCryptDestroyHash(hHash); 154 | } 155 | 156 | if (hHashAlg) 157 | { 158 | BCryptCloseAlgorithmProvider(hHashAlg, 0); 159 | } 160 | 161 | return status; 162 | } 163 | 164 | bool MakeAesKey(AesKey *pAesKey, const char *password) 165 | { 166 | bool status = FALSE; 167 | BCRYPT_ALG_HANDLE hAesAlg = (BCRYPT_ALG_HANDLE)NULL; 168 | unsigned char* pHashData = (unsigned char*)NULL; 169 | 170 | if (!InitCBCAlg(&hAesAlg)) 171 | { 172 | goto cleanup; 173 | } 174 | 175 | //pHashData = (unsigned char*)HeapAlloc(GetProcessHeap(), 0, cAesKeySize256Bit); 176 | pHashData = (unsigned char*)MmAllocateNonCachedMemory(cAesKeySize256Bit); 177 | if (!pHashData) 178 | { 179 | goto cleanup; 180 | } 181 | 182 | if (!HashPassword(password, pHashData)) 183 | { 184 | goto cleanup; 185 | } 186 | 187 | if (!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey(hAesAlg, &pAesKey->hKey, (PUCHAR)NULL, (ULONG)NULL, pHashData, cAesKeySize256Bit, 0))) 188 | { 189 | goto cleanup; 190 | } 191 | 192 | ULONG tmp; 193 | if (!BCRYPT_SUCCESS(BCryptGetProperty(hAesAlg, BCRYPT_BLOCK_LENGTH, (PUCHAR)&pAesKey->blockSize, sizeof(pAesKey->blockSize), &tmp, 0))) 194 | { 195 | goto cleanup; 196 | } 197 | 198 | status = TRUE; 199 | 200 | cleanup: 201 | if (pHashData) 202 | { 203 | //HeapFree(GetProcessHeap(), 0, pHashData); 204 | MmFreeNonCachedMemory(pHashData, cAesKeySize256Bit); 205 | } 206 | 207 | if (hAesAlg) 208 | { 209 | BCryptCloseAlgorithmProvider(hAesAlg, 0); 210 | } 211 | 212 | return status; 213 | } 214 | 215 | size_t GetCryptedBlockSize(AesKey *pAesKey, size_t dataSize, bool encrypt) 216 | { 217 | NTSTATUS bcryptResult = 0; 218 | size_t cryptedBlockSize = 0; 219 | bcryptResult = (encrypt ? BCryptEncrypt : BCryptDecrypt)(pAesKey->hKey, (PUCHAR)NULL, (ULONG)dataSize, NULL, (PUCHAR)NULL, (ULONG)NULL, (PUCHAR)NULL, 0, (ULONG*)&cryptedBlockSize, 0); 220 | 221 | return BCRYPT_SUCCESS(bcryptResult) ? cryptedBlockSize : 0; 222 | } 223 | 224 | size_t EncrypDecryptData(AesKey *pAesKey, unsigned char *srcData, size_t srcDataSize, unsigned char *dstData, size_t dstDataSize, bool encrypt, unsigned char* iv) 225 | { 226 | size_t writtenBytes = 0; 227 | if (!BCRYPT_SUCCESS((encrypt ? BCryptEncrypt : BCryptDecrypt)(pAesKey->hKey, 228 | srcData, (ULONG)srcDataSize, NULL, iv, pAesKey->blockSize, 229 | dstData, (ULONG)dstDataSize, (ULONG*)&writtenBytes, 0))) 230 | { 231 | return 0; 232 | } 233 | 234 | return writtenBytes; 235 | } 236 | 237 | void PrepareIv(const AesKey* key, uint64_t ivValue, unsigned char* iv) 238 | { 239 | memset(iv, 0, key->blockSize); 240 | memcpy(iv, &ivValue, sizeof(ivValue)); 241 | } 242 | 243 | //#define IOCTL_FILE_DISK_OPEN_FILE CTL_CODE(FILE_DEVICE_DISK, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 244 | //#define IOCTL_FILE_DISK_CLOSE_FILE CTL_CODE(FILE_DEVICE_DISK, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 245 | //#define IOCTL_FILE_DISK_QUERY_FILE CTL_CODE(FILE_DEVICE_DISK, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS) 246 | //#define IOCTL_FILE_DISK_UNMOUNT_ALL CTL_CODE(FILE_DEVICE_DISK, 0x803, METHOD_BUFFERED, FILE_READ_ACCESS) 247 | 248 | //typedef struct _OPEN_FILE_INFORMATION { 249 | // LARGE_INTEGER FileSize; 250 | // BOOLEAN ReadOnly; 251 | // UCHAR DriveLetter; 252 | // USHORT FileNameLength; 253 | // CHAR FileName[1]; 254 | //} OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION; 255 | 256 | //typedef struct _OPEN_FILE_INFORMATION 257 | //{ 258 | // LARGE_INTEGER FileSize; 259 | // UCHAR DriveLetter; 260 | // USHORT FileNameLength; 261 | // LARGE_INTEGER SectorSize; 262 | // CHAR Password[16]; 263 | // USHORT DiskOffset; 264 | // CHAR FileName[1]; 265 | //} OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION; 266 | // 267 | //typedef struct _DISK_INFO 268 | //{ 269 | // USHORT DiskCount; 270 | // OPEN_FILE_INFORMATION disks[26]; 271 | //}DISK_INFO, *PDISK_INFO; 272 | // 273 | //const size_t cAesKeySize256Bit = 32; 274 | //#define uint64_t unsigned long long 275 | //#define bool BOOLEAN 276 | // 277 | //typedef struct _AesKey 278 | //{ 279 | // BCRYPT_KEY_HANDLE hKey; 280 | // ULONG blockSize; 281 | //} AesKey, *PAesKey; 282 | // 283 | //bool MakeAesKey(AesKey *pAesKey, const char *password); 284 | //size_t GetCryptedBlockSize(AesKey *pAesKey, size_t dataSize, bool encrypt); 285 | //size_t EncrypDecryptData(AesKey *pAesKey, unsigned char *srcData, size_t srcDataSize, unsigned char *dstData, size_t dstDataSize, bool encrypt, unsigned char* iv); 286 | //void PrepareIv(const AesKey* key, uint64_t ivValue, unsigned char* iv); 287 | 288 | #endif -------------------------------------------------------------------------------- /Driver/driver27/driver27.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArtDnpr/VirtualEncryptedDisk/8e35e57d6c9439b40ff269214199a6d6721483ca/Driver/driver27/driver27.c -------------------------------------------------------------------------------- /Driver/driver27/driver27.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; driver27.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=driver27.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | ; ================= Class section ===================== 17 | 18 | [ClassInstall32] 19 | Addreg=SampleClassReg 20 | 21 | [SampleClassReg] 22 | HKR,,,0,%ClassName% 23 | HKR,,Icon,,-5 24 | 25 | [SourceDisksNames] 26 | 1 = %DiskName%,,,"" 27 | 28 | [SourceDisksFiles] 29 | driver27.sys = 1,, 30 | 31 | ;***************************************** 32 | ; Install Section 33 | ;***************************************** 34 | 35 | [Manufacturer] 36 | %ManufacturerName%=Standard,NT$ARCH$ 37 | 38 | [Standard.NT$ARCH$] 39 | %driver27.DeviceDesc%=driver27_Device, Root\driver27 ; TODO: edit hw-id 40 | 41 | [driver27_Device.NT] 42 | CopyFiles=Drivers_Dir 43 | 44 | [Drivers_Dir] 45 | driver27.sys 46 | 47 | ;-------------- Service installation 48 | [driver27_Device.NT.Services] 49 | AddService = driver27,%SPSVCINST_ASSOCSERVICE%, driver27_Service_Inst 50 | 51 | ; -------------- driver27 driver install sections 52 | [driver27_Service_Inst] 53 | DisplayName = %driver27.SVCDESC% 54 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 55 | StartType = 3 ; SERVICE_DEMAND_START 56 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 57 | ServiceBinary = %12%\driver27.sys 58 | 59 | ; 60 | ;--- driver27_Device Coinstaller installation ------ 61 | ; 62 | 63 | [DestinationDirs] 64 | driver27_Device_CoInstaller_CopyFiles = 11 65 | 66 | [driver27_Device.NT.CoInstallers] 67 | AddReg=driver27_Device_CoInstaller_AddReg 68 | CopyFiles=driver27_Device_CoInstaller_CopyFiles 69 | 70 | [driver27_Device_CoInstaller_AddReg] 71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 72 | 73 | [driver27_Device_CoInstaller_CopyFiles] 74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 75 | 76 | [SourceDisksFiles] 77 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 78 | 79 | [driver27_Device.NT.Wdf] 80 | KmdfService = driver27, driver27_wdfsect 81 | [driver27_wdfsect] 82 | KmdfLibraryVersion = $KMDFVERSION$ 83 | 84 | [Strings] 85 | SPSVCINST_ASSOCSERVICE= 0x00000002 86 | ManufacturerName="" ;TODO: Replace with your manufacturer name 87 | ClassName="Samples" ; TODO: edit ClassName 88 | DiskName = "driver27 Installation Disk" 89 | driver27.DeviceDesc = "driver27 Device" 90 | driver27.SVCDESC = "driver27 Service" 91 | -------------------------------------------------------------------------------- /Driver/driver27/driver27.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {F27D11F5-D105-45F5-AFDF-E6FBF317DD99} 39 | {1bc93793-694f-48fe-9372-81e2b05556fd} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | driver27 45 | 46 | 47 | 48 | Windows7 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | KMDF 53 | Desktop 54 | 55 | 56 | Windows10 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | KMDF 61 | Universal 62 | 63 | 64 | Windows10 65 | true 66 | WindowsKernelModeDriver10.0 67 | Driver 68 | KMDF 69 | Universal 70 | 71 | 72 | Windows10 73 | false 74 | WindowsKernelModeDriver10.0 75 | Driver 76 | KMDF 77 | Universal 78 | 79 | 80 | Windows10 81 | true 82 | WindowsKernelModeDriver10.0 83 | Driver 84 | KMDF 85 | Universal 86 | 87 | 88 | Windows10 89 | false 90 | WindowsKernelModeDriver10.0 91 | Driver 92 | KMDF 93 | Universal 94 | 95 | 96 | Windows10 97 | true 98 | WindowsKernelModeDriver10.0 99 | Driver 100 | KMDF 101 | Universal 102 | 103 | 104 | Windows10 105 | false 106 | WindowsKernelModeDriver10.0 107 | Driver 108 | KMDF 109 | Universal 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | DbgengKernelDebugger 121 | false 122 | 123 | 124 | DbgengKernelDebugger 125 | 126 | 127 | DbgengKernelDebugger 128 | 129 | 130 | DbgengKernelDebugger 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | DbgengKernelDebugger 137 | 138 | 139 | DbgengKernelDebugger 140 | 141 | 142 | DbgengKernelDebugger 143 | 144 | 145 | 146 | $(DDK_LIB_PATH)\wdmsec.lib;$(DDK_LIB_PATH)\cng.lib;%(AdditionalDependencies) 147 | 148 | 149 | %(AdditionalIncludeDirectories) 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /Driver/driver27/driver27.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /Driver/driver27/driver27.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDisk.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS += \ 4 | EncryptedDiskGui \ 5 | EncryptedDiskClientLib 6 | 7 | EncryptedDiskGui.file = EncryptedDiskGui/EncryptedDiskGui.pro 8 | EncryptedDiskClientLib.file = EncryptedDiskClientLib/EncryptedDiskClientLib.pro 9 | 10 | EncryptedDiskClientLib.depend = CryptoUtils 11 | EncryptedDiskGui.depend = EncryptedDiskClientLib 12 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/DriverCommunication.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "DriverCommunication.h" 3 | 4 | #define DEVICE_BASE_NAME _T("\\FileDisk") 5 | #define DEVICE_DIR_NAME _T("\\Device") DEVICE_BASE_NAME 6 | #define DEVICE_NAME_PREFIX DEVICE_DIR_NAME 7 | 8 | int n = 1; 9 | 10 | int FileDiskMount(POPEN_FILE_INFORMATION pok) 11 | { 12 | char VolumeName[] = "\\\\.\\ :"; 13 | char DriveName[] = " :\\"; 14 | char DeviceName[255]; 15 | HANDLE Device; 16 | DWORD BytesReturned; 17 | 18 | VolumeName[4] = pok->DriveLetter; 19 | DriveName[0] = pok->DriveLetter; 20 | 21 | Device = CreateFile( 22 | "\\\\.\\MyDevice", 23 | GENERIC_READ | GENERIC_WRITE, 24 | FILE_SHARE_READ | FILE_SHARE_WRITE, 25 | NULL, 26 | OPEN_EXISTING, 27 | FILE_FLAG_NO_BUFFERING, 28 | NULL 29 | ); 30 | 31 | if (Device == INVALID_HANDLE_VALUE) 32 | { 33 | return -1; 34 | } 35 | 36 | if (!DeviceIoControl( 37 | Device, 38 | IOCTL_FILE_DISK_OPEN_FILE, 39 | pok, 40 | sizeof(OPEN_FILE_INFORMATION), 41 | NULL, 42 | 0, 43 | &BytesReturned, 44 | NULL)) 45 | { 46 | CloseHandle(Device); 47 | return -1; 48 | } 49 | 50 | sprintf(DeviceName, DEVICE_NAME_PREFIX "%u", n); 51 | if (!DefineDosDevice(DDD_RAW_TARGET_PATH, &VolumeName[4], DeviceName)) 52 | { 53 | printf("\n!Define \n"); 54 | } 55 | CloseHandle(Device); 56 | 57 | SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATH, DriveName, NULL); 58 | n++; 59 | 60 | return 0; 61 | } 62 | 63 | int FileDiskUmount(char DriveLetter) 64 | { 65 | char VolumeName[] = "\\\\.\\ :"; 66 | char DriveName[] = " :\\"; 67 | HANDLE Device; 68 | DWORD BytesReturned; 69 | 70 | VolumeName[4] = DriveLetter; 71 | DriveName[0] = DriveLetter; 72 | 73 | Device = CreateFile( 74 | VolumeName, 75 | GENERIC_READ | GENERIC_WRITE, 76 | FILE_SHARE_READ | FILE_SHARE_WRITE, 77 | NULL, 78 | OPEN_EXISTING, 79 | FILE_FLAG_NO_BUFFERING, 80 | NULL 81 | ); 82 | 83 | if (Device == INVALID_HANDLE_VALUE) 84 | { 85 | return -1; 86 | } 87 | 88 | if (!DeviceIoControl( 89 | Device, 90 | IOCTL_FILE_DISK_CLOSE_FILE, 91 | NULL, 92 | 0, 93 | NULL, 94 | 0, 95 | &BytesReturned, 96 | NULL 97 | )) 98 | { 99 | CloseHandle(Device); 100 | return -1; 101 | } 102 | 103 | CloseHandle(Device); 104 | 105 | if (!DefineDosDevice(DDD_REMOVE_DEFINITION,&VolumeName[4],NULL)) 106 | { 107 | return -1; 108 | } 109 | 110 | SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, DriveName, NULL); 111 | n--; 112 | 113 | return 0; 114 | } 115 | 116 | int FileDiskStatus(PDISK_INFO myDisk_info) 117 | { 118 | HANDLE Device; 119 | DWORD BytesReturned; 120 | 121 | Device = CreateFile( 122 | "\\\\.\\MyDevice", 123 | GENERIC_READ, 124 | FILE_SHARE_READ | FILE_SHARE_WRITE, 125 | NULL, 126 | OPEN_EXISTING, 127 | FILE_FLAG_NO_BUFFERING, 128 | NULL 129 | ); 130 | 131 | if (Device == INVALID_HANDLE_VALUE) 132 | { 133 | return -1; 134 | } 135 | 136 | if (!DeviceIoControl( 137 | Device, 138 | IOCTL_FILE_DISK_QUERY_FILE, 139 | NULL, 140 | 0, 141 | myDisk_info, 142 | sizeof(DISK_INFO), 143 | &BytesReturned, 144 | NULL 145 | )) 146 | { 147 | CloseHandle(Device); 148 | return -1; 149 | } 150 | 151 | CloseHandle(Device); 152 | 153 | return 0; 154 | } 155 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/DriverCommunication.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | int FileDiskMount(POPEN_FILE_INFORMATION OpenFileInformation); 6 | int FileDiskUmount(char DriveLetter); 7 | int FileDiskStatus(PDISK_INFO myDisk_info); 8 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/EncryptedDiskClientLib.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | CONFIG += staticlib 3 | 4 | DEFINES -= UNICODE 5 | 6 | INCLUDEPATH = \ 7 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt" 8 | 9 | INCLUDEPATH += \ 10 | ../../Commons/include 11 | 12 | SOURCES += \ 13 | Transport.cpp\ 14 | VirtualDiskController.cpp \ 15 | DriverCommunication.cpp 16 | 17 | HEADERS += \ 18 | targetver.h \ 19 | Transport.h \ 20 | Disk.h \ 21 | VirtualDiskController.h \ 22 | IVirtualDiskControllerObserver.h \ 23 | stdafx.h \ 24 | DriverCommunication.h 25 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/IVirtualDiskControllerObserver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class IVirtualDiskControllerObserver 4 | { 5 | public: 6 | virtual ~IVirtualDiskControllerObserver() {} 7 | virtual void virtualDiskControllerDidEncryptDisk(uint64_t encryptedSize, uint64_t totalSize) = 0; 8 | virtual void virtualDiskControllerDidFinishCreation(bool canceled) = 0; 9 | virtual void virtualDiskControllerDidFailDiskCreation(const std::string& error) = 0; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/Transport.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Transport.h" 3 | #include "DriverCommunication.h" 4 | 5 | namespace 6 | { 7 | std::string ConvertWstringToString(const std::wstring& wStr) 8 | { 9 | std::wstring_convert, wchar_t> converter; 10 | 11 | return converter.to_bytes(wStr); 12 | } 13 | 14 | std::wstring ConvertStringToWString(const std::string& str) 15 | { 16 | std::wstring_convert, wchar_t> converter; 17 | 18 | return converter.from_bytes(str); 19 | } 20 | 21 | const std::string cAdditionalSymbolsForDriverMount = "\\??\\"; 22 | 23 | OPEN_FILE_INFORMATION ConvertMountMessageToOpenStruct(const MountMessage* mountMessage) 24 | { 25 | OPEN_FILE_INFORMATION openInfo; 26 | memset(&openInfo, 0 , sizeof(openInfo)); 27 | 28 | openInfo.FileSize.QuadPart = mountMessage->diskInfo.size; 29 | openInfo.SectorSize.QuadPart = mountMessage->diskSectorSize; 30 | //Putting disk info in the beginning of the disk file and sending its offset to driver is implemented in client side. 31 | //But driver doesn not support disks that begins at non-zero offset. 32 | openInfo.DiskOffset = 0; // static_cast( mountMessage->diskOffset); 33 | memcpy(&openInfo.Password, mountMessage->password.c_str(), static_cast(mountMessage->password.length())); 34 | openInfo.PasswordLength = static_cast(mountMessage->password.length()); 35 | openInfo.DriveLetter = mountMessage->diskInfo.letter; 36 | const std::string& diskPath = cAdditionalSymbolsForDriverMount + ConvertWstringToString(mountMessage->diskInfo.fullDiskPath); 37 | openInfo.FileNameLength = static_cast(diskPath.length()); 38 | memcpy(&openInfo.FileName, diskPath.c_str(), openInfo.FileNameLength); 39 | 40 | return openInfo; 41 | } 42 | 43 | void MakeDiskInfo(const DISK_INFO* disksInfo, DiskInfoMessage* diskInfoMessage) 44 | { 45 | for (USHORT i = 0; i < disksInfo->DiskCount; i++) 46 | { 47 | const OPEN_FILE_INFORMATION& fileInfo = disksInfo->disks[i]; 48 | Disk disk; 49 | disk.size = fileInfo.FileSize.QuadPart; 50 | disk.letter = fileInfo.DriveLetter; 51 | disk.fullDiskPath = ConvertStringToWString(std::string(fileInfo.FileName, fileInfo.FileName + fileInfo.FileNameLength)); 52 | 53 | diskInfoMessage->disks.emplace_back(std::move(disk)); 54 | } 55 | } 56 | } 57 | 58 | bool SendData(MessageCode messageCode, const void* data, void* receivedData) 59 | { 60 | switch (messageCode) 61 | { 62 | case MessageMountDisk: 63 | { 64 | OPEN_FILE_INFORMATION info = ConvertMountMessageToOpenStruct(reinterpret_cast(data)); 65 | return !FileDiskMount(&info); 66 | } 67 | 68 | case MessageUnmountDisk: 69 | { 70 | return !FileDiskUmount(reinterpret_cast(data)->diskLetter); 71 | } 72 | 73 | case MessageDiskInfo: 74 | { 75 | return true; // This feature is not supported at the moment 76 | DISK_INFO disksInfo; 77 | memset(&disksInfo, 0 , sizeof(disksInfo)); 78 | if (FileDiskStatus(&disksInfo)) 79 | { 80 | return false; 81 | } 82 | 83 | MakeDiskInfo(&disksInfo, reinterpret_cast(receivedData)); 84 | return true; 85 | } 86 | 87 | default: 88 | break; 89 | } 90 | 91 | return false; 92 | } 93 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/Transport.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disk.h" 4 | 5 | enum MessageCode 6 | { 7 | MessageMountDisk, 8 | MessageUnmountDisk, 9 | MessageDiskInfo 10 | }; 11 | 12 | struct MountMessage 13 | { 14 | Disk diskInfo; 15 | size_t diskSectorSize; 16 | std::string password; 17 | size_t diskOffset; 18 | }; 19 | 20 | struct UnmountMessage 21 | { 22 | char diskLetter; 23 | }; 24 | 25 | struct DiskInfoMessage 26 | { 27 | std::vector disks; 28 | }; 29 | 30 | bool SendData(MessageCode messageCode, const void* data, void* receivedData = nullptr); 31 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/VirtualDiskController.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "VirtualDiskController.h" 3 | #include "IVirtualDiskControllerObserver.h" 4 | #include "Transport.h" 5 | 6 | namespace 7 | { 8 | const size_t cEncrypteBlockSize = 512; 9 | 10 | const size_t cVerificationStringSize = 16; 11 | char cVerification[] = "Verification"; 12 | 13 | struct DiskInfo 14 | { 15 | uint64_t diskSizeInBytes; 16 | char verification[cVerificationStringSize]; 17 | }; 18 | const size_t cDiskInfoSize = sizeof(DiskInfo::diskSizeInBytes) + sizeof(DiskInfo::verification); 19 | 20 | std::vector GetDiskInfoIv(size_t ivSize) 21 | { 22 | std::vector iv(ivSize); 23 | memset(iv.data(), 0xFF, iv.size()); 24 | 25 | return iv; 26 | } 27 | 28 | size_t GetAlignedDiskInfoSize(size_t blockSize) 29 | { 30 | return cDiskInfoSize + (cDiskInfoSize % blockSize); 31 | } 32 | 33 | bool WriteDiskInfo(const DiskInfo& diskInfo, AesKey *pAesKey, std::ofstream &fout) 34 | { 35 | std::vector serializedDiskInfo(GetAlignedDiskInfoSize(pAesKey->blockSize), 0x00); 36 | 37 | memcpy(serializedDiskInfo.data(), &diskInfo.diskSizeInBytes, sizeof(diskInfo.diskSizeInBytes)); 38 | const size_t offset = sizeof(diskInfo.diskSizeInBytes); 39 | memcpy(serializedDiskInfo.data() + offset, diskInfo.verification, sizeof(diskInfo.verification)); 40 | 41 | std::vector iv = GetDiskInfoIv(pAesKey->blockSize); 42 | 43 | std::vector encryptedDiskInfo; 44 | encryptedDiskInfo.resize(GetCryptedBlockSize(pAesKey, serializedDiskInfo.size(), true)); 45 | 46 | size_t cryptedDiskInfoSize = EncrypDecryptData(pAesKey, serializedDiskInfo.data(), serializedDiskInfo.size(), encryptedDiskInfo.data(), encryptedDiskInfo.size(), true, iv.data()); 47 | encryptedDiskInfo.resize(cryptedDiskInfoSize); 48 | 49 | fout.write(reinterpret_cast(encryptedDiskInfo.data()), encryptedDiskInfo.size()); 50 | 51 | return true; 52 | } 53 | 54 | DiskInfo ReadDiskInfo(AesKey *pAesKey, std::ifstream &fin) 55 | { 56 | const int64_t currentPos = fin.tellg(); 57 | fin.seekg(-static_cast(GetAlignedDiskInfoSize(pAesKey->blockSize)), std::ios::end); 58 | 59 | DiskInfo diskInfo = {}; 60 | 61 | std::vector encryptedDiskInfo; 62 | encryptedDiskInfo.resize(GetCryptedBlockSize(pAesKey, GetAlignedDiskInfoSize(pAesKey->blockSize), true)); 63 | 64 | fin.read(reinterpret_cast(encryptedDiskInfo.data()), encryptedDiskInfo.size()); 65 | 66 | std::vector serializedDiskInfo; 67 | serializedDiskInfo.resize(GetCryptedBlockSize(pAesKey, encryptedDiskInfo.size(), false)); 68 | 69 | std::vector iv = GetDiskInfoIv(pAesKey->blockSize); 70 | 71 | const size_t decryptedDiskInfoSize = EncrypDecryptData(pAesKey, encryptedDiskInfo.data(), encryptedDiskInfo.size(), serializedDiskInfo.data(), serializedDiskInfo.size(), false, iv.data()); 72 | if (!decryptedDiskInfoSize) 73 | { 74 | return diskInfo; 75 | } 76 | serializedDiskInfo.resize(decryptedDiskInfoSize); 77 | 78 | memcpy(&diskInfo.diskSizeInBytes, serializedDiskInfo.data(), sizeof(diskInfo.diskSizeInBytes)); 79 | const size_t offset = sizeof(diskInfo.diskSizeInBytes); 80 | memcpy(diskInfo.verification, serializedDiskInfo.data() + offset, sizeof(diskInfo.verification)); 81 | 82 | fin.seekg(currentPos); 83 | 84 | return diskInfo; 85 | } 86 | } 87 | 88 | VirtualDiskController::VirtualDiskController() 89 | {} 90 | 91 | const std::vector& VirtualDiskController::getDisks() 92 | { 93 | DiskInfoMessage disksInfo; 94 | if (!SendData(MessageDiskInfo, nullptr, &disksInfo)) 95 | { 96 | throw std::runtime_error("Unable to communicate with driver"); 97 | } 98 | 99 | m_disks = std::move(disksInfo.disks); 100 | 101 | return m_disks; 102 | } 103 | 104 | void VirtualDiskController::createNewDisk(const std::wstring &fullDiskPath, const uint64_t diskSize, const std::string &password, 105 | IVirtualDiskControllerObserver* observer, const std::atomic& canceled) 106 | { 107 | std::ifstream fin (fullDiskPath); 108 | 109 | if (fin.is_open()) 110 | { 111 | observer->virtualDiskControllerDidFailDiskCreation("The disk file is already exists."); 112 | return; 113 | } 114 | fin.close(); 115 | 116 | std::vector encryptedData; 117 | std::ofstream fout(fullDiskPath, std::ios::out | std::ios::binary); 118 | AesKey key; 119 | unsigned char emptyBlock[cEncrypteBlockSize] = { 0 }; 120 | DiskInfo diskInfo; 121 | memset(&diskInfo, 0, sizeof(diskInfo)); 122 | 123 | const uint64_t diskSizeInBytes = diskSize * 1024 * 1024; 124 | diskInfo.diskSizeInBytes = diskSizeInBytes; 125 | memcpy(diskInfo.verification, cVerification, std::min(sizeof(cVerification), cVerificationStringSize)); 126 | const uint64_t blocksCount = diskSizeInBytes / cEncrypteBlockSize; 127 | 128 | MakeAesKey(&key, password.c_str()); 129 | 130 | encryptedData.resize(GetCryptedBlockSize(&key, cEncrypteBlockSize, true)); 131 | 132 | std::vector iv(key.blockSize); 133 | 134 | size_t size = 0; 135 | for (uint64_t i = 0; i < blocksCount && !canceled; i++) 136 | { 137 | size+= encryptedData.size(); 138 | PrepareIv(&key, i, iv.data()); 139 | EncrypDecryptData(&key, emptyBlock, cEncrypteBlockSize, encryptedData.data(), encryptedData.size(), true, iv.data()); 140 | fout.write(reinterpret_cast(encryptedData.data()), encryptedData.size()); 141 | 142 | if (observer) 143 | { 144 | observer->virtualDiskControllerDidEncryptDisk((i + 1) * cEncrypteBlockSize, diskSizeInBytes); 145 | } 146 | } 147 | 148 | WriteDiskInfo(diskInfo, &key, fout); 149 | 150 | if (observer) 151 | { 152 | observer->virtualDiskControllerDidFinishCreation(canceled); 153 | } 154 | } 155 | 156 | const Disk& VirtualDiskController::mountDisk(const std::wstring &fullDiskPath, char diskLetter, const std::string &password) 157 | { 158 | std::ifstream fin (fullDiskPath); 159 | if (!fin.is_open()) 160 | { 161 | throw std::runtime_error("Invalid disk path"); 162 | } 163 | AesKey key; 164 | MakeAesKey(&key, password.c_str()); 165 | DiskInfo diskInfo = ReadDiskInfo(&key, fin); 166 | if (strncmp(diskInfo.verification, cVerification, cVerificationStringSize)) 167 | { 168 | throw std::runtime_error("Invalid password"); 169 | } 170 | 171 | fin.seekg(0, fin.end); 172 | uint64_t currentDiskSize = fin.tellg(); 173 | fin.seekg(0, fin.beg); 174 | 175 | if(currentDiskSize != diskInfo.diskSizeInBytes + GetAlignedDiskInfoSize(key.blockSize)) 176 | { 177 | throw std::runtime_error("Invalid disk size"); 178 | } 179 | 180 | MountMessage mount; 181 | mount.diskInfo.fullDiskPath = fullDiskPath; 182 | mount.diskInfo.letter = diskLetter; 183 | mount.diskInfo.size = diskInfo.diskSizeInBytes; 184 | mount.diskSectorSize = cEncrypteBlockSize; 185 | mount.password = password; 186 | mount.diskOffset = GetAlignedDiskInfoSize(key.blockSize); 187 | 188 | fin.close(); 189 | 190 | if (!SendData(MessageMountDisk, &mount)) 191 | { 192 | throw std::runtime_error("Unable to mount disk"); 193 | } 194 | 195 | m_disks.push_back(std::move(mount.diskInfo)); 196 | 197 | return m_disks.back(); 198 | } 199 | 200 | 201 | void VirtualDiskController::unmountDisk(const char diskLetter) 202 | { 203 | for (size_t i = 0; i < m_disks.size(); i++) 204 | { 205 | if (m_disks[i].letter == diskLetter) 206 | { 207 | UnmountMessage unmount; 208 | unmount.diskLetter = m_disks[i].letter; 209 | if (!SendData(MessageUnmountDisk, &unmount)) 210 | { 211 | throw std::runtime_error("Unable to unmount disk"); 212 | } 213 | 214 | m_disks.erase(m_disks.begin() + i); 215 | 216 | return; 217 | } 218 | } 219 | } 220 | 221 | void VirtualDiskController::unmountAllDisks() 222 | { 223 | while(!m_disks.empty()) 224 | { 225 | unmountDisk(m_disks.back().letter); 226 | Sleep(500); //for driver purposes 227 | } 228 | } 229 | 230 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/VirtualDiskController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disk.h" 4 | 5 | class IVirtualDiskControllerObserver; 6 | 7 | class VirtualDiskController 8 | { 9 | public: 10 | VirtualDiskController(); 11 | void createNewDisk(const std::wstring &fullDiskPath, const uint64_t diskSize, const std::string &password, 12 | IVirtualDiskControllerObserver* observer, const std::atomic& canceled); 13 | const Disk& mountDisk(const std::wstring &fullDiskPath, char diskLetter, const std::string &password); 14 | void unmountDisk(const char diskLetter); 15 | void unmountAllDisks(); 16 | 17 | const std::vector& getDisks(); 18 | 19 | private: 20 | std::vector m_disks; 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/disk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct Disk 6 | { 7 | std::wstring fullDiskPath; 8 | uint64_t size; 9 | char letter; 10 | }; 11 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #define NOMINMAX 9 | 10 | #include "targetver.h" 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskClientLib/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/CreateNewDiskDialog.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "CreateNewDiskDialog.h" 6 | 7 | CreateNewDiskDialog::CreateNewDiskDialog(QWidget *parent, const QString& diskExtension) 8 | : QDialog(parent) 9 | , m_inProgress(false) 10 | , m_diskExtension(diskExtension) 11 | { 12 | m_ui.setupUi(this); 13 | 14 | m_ui.lineSize->setValidator(new QIntValidator(this)); 15 | 16 | RefreshCreateButtonState(); 17 | ProgressStarted(false); 18 | 19 | connect(m_ui.linePath, &QLineEdit::textChanged, this, &CreateNewDiskDialog::RefreshCreateButtonState); 20 | connect(m_ui.lineSize, &QLineEdit::textChanged, this, &CreateNewDiskDialog::RefreshCreateButtonState); 21 | connect(m_ui.linePassword, &QLineEdit::textChanged, this, &CreateNewDiskDialog::RefreshCreateButtonState); 22 | connect(m_ui.lineName, &QLineEdit::textChanged, this, &CreateNewDiskDialog::RefreshCreateButtonState); 23 | } 24 | 25 | void CreateNewDiskDialog::Cleanup() 26 | { 27 | m_ui.linePath->clear(); 28 | m_ui.lineSize->clear(); 29 | m_ui.linePassword->clear(); 30 | m_ui.lineName->clear(); 31 | m_ui.progressBar->setValue(0); 32 | m_ui.checkShowPwd->setChecked(false); 33 | 34 | ProgressStarted(false); 35 | RefreshCreateButtonState(); 36 | } 37 | 38 | void CreateNewDiskDialog::OnProgressChange(uint64_t encryptedSize, uint64_t totalSize) 39 | { 40 | m_ui.progressBar->setValue(encryptedSize * 100 / totalSize); 41 | } 42 | 43 | void CreateNewDiskDialog::OnProgressFinished(bool canceled) 44 | { 45 | QString message; 46 | if (canceled) 47 | { 48 | message = "Disk creation has been canceled"; 49 | } 50 | else 51 | { 52 | message = "Disk creation has been finished successfully"; 53 | } 54 | 55 | QMessageBox::information(this, "New disk creation", message); 56 | m_inProgress = false; 57 | close(); 58 | } 59 | 60 | void CreateNewDiskDialog::OnProgressError(const QString& error) 61 | { 62 | QMessageBox::critical(this, "Error", error); 63 | ProgressStarted(false); 64 | } 65 | 66 | void CreateNewDiskDialog::showEvent(QShowEvent*) 67 | { 68 | setFixedSize(size()); 69 | } 70 | 71 | void CreateNewDiskDialog::closeEvent(QCloseEvent* event) 72 | { 73 | if (!m_inProgress) 74 | { 75 | event->accept(); 76 | return; 77 | } 78 | 79 | if (QMessageBox::Yes == QMessageBox::question(this, 80 | "Cancel operation", 81 | "Are you sure you want to cancel disk creation?", 82 | QMessageBox::Yes | QMessageBox::No)) 83 | { 84 | emit CancelCreation(); 85 | event->accept(); 86 | return; 87 | } 88 | 89 | event->ignore(); 90 | } 91 | 92 | void CreateNewDiskDialog::on_btnCancel_clicked() 93 | { 94 | if (!m_inProgress) 95 | { 96 | close(); 97 | return; 98 | } 99 | 100 | CancelWithQuestion(); 101 | } 102 | 103 | void CreateNewDiskDialog::on_btnCreate_clicked() 104 | { 105 | emit CreateDisk(GetFullPath(), GetPassword(), GetSize()); 106 | ProgressStarted(true); 107 | } 108 | 109 | void CreateNewDiskDialog::on_btnBrowse_clicked() 110 | { 111 | const QString& choosenPath = QFileDialog::getExistingDirectory(this, "Select folder to save disk file"); 112 | if (!choosenPath.isEmpty()) 113 | { 114 | m_ui.linePath->setText(choosenPath); 115 | } 116 | } 117 | 118 | void CreateNewDiskDialog::on_checkShowPwd_clicked() 119 | { 120 | const bool show = m_ui.checkShowPwd->isChecked(); 121 | m_ui.linePassword->setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password); 122 | } 123 | 124 | void CreateNewDiskDialog::RefreshCreateButtonState() 125 | { 126 | bool enabled = !GetFullPath().isEmpty() && !GetPassword().isEmpty(); 127 | enabled &= GetSize() > 0; 128 | m_ui.btnCreate->setEnabled(enabled); 129 | } 130 | 131 | void CreateNewDiskDialog::ProgressStarted(bool started) 132 | { 133 | m_inProgress = started; 134 | 135 | m_ui.linePath->setDisabled(started); 136 | m_ui.lineSize->setDisabled(started); 137 | m_ui.linePassword->setDisabled(started); 138 | m_ui.lineName->setDisabled(started); 139 | 140 | m_ui.btnCreate->setDisabled(started); 141 | m_ui.btnBrowse->setDisabled(started); 142 | m_ui.checkShowPwd->setDisabled(started); 143 | 144 | m_ui.progressBar->setEnabled(started); 145 | } 146 | 147 | void CreateNewDiskDialog::CancelWithQuestion() 148 | { 149 | if (QMessageBox::Yes == QMessageBox::question(this, 150 | "Cancel operation", 151 | "Are you sure you want to cancel disk creation?", 152 | QMessageBox::Yes | QMessageBox::No)) 153 | { 154 | emit CancelCreation(); 155 | } 156 | } 157 | 158 | uint64_t CreateNewDiskDialog::GetSize() 159 | { 160 | const QString& sizeStr = m_ui.lineSize->text(); 161 | 162 | return sizeStr.isEmpty() ? 0 : sizeStr.toULongLong(); 163 | } 164 | 165 | QString CreateNewDiskDialog::GetFullPath() 166 | { 167 | const QString& fullPath = m_ui.linePath->text() + QDir::separator() + m_ui.lineName->text() + m_diskExtension; 168 | 169 | return QDir::toNativeSeparators(fullPath); 170 | } 171 | 172 | QString CreateNewDiskDialog::GetPassword() 173 | { 174 | return m_ui.linePassword->text(); 175 | } 176 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/CreateNewDiskDialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ui_CreateNewDiskDialog.h" 5 | 6 | class CreateNewDiskDialog : public QDialog 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | explicit CreateNewDiskDialog(QWidget* parent, const QString& diskExtension); 12 | 13 | void Cleanup(); 14 | 15 | public slots: 16 | void OnProgressChange(uint64_t encryptedSize, uint64_t totalSize); 17 | void OnProgressFinished(bool canceled); 18 | void OnProgressError(const QString& error); 19 | 20 | signals: 21 | void CreateDisk(const QString& path, const QString& password, uint64_t size); 22 | void CancelCreation(); 23 | 24 | protected: 25 | virtual void showEvent(QShowEvent *); 26 | virtual void closeEvent(QCloseEvent* event); 27 | 28 | private slots: 29 | void on_btnCancel_clicked(); 30 | void on_btnCreate_clicked(); 31 | void on_btnBrowse_clicked(); 32 | void on_checkShowPwd_clicked(); 33 | 34 | private: 35 | void RefreshCreateButtonState(); 36 | void ProgressStarted(bool started); 37 | void CancelWithQuestion(); 38 | 39 | uint64_t GetSize(); 40 | QString GetFullPath(); 41 | QString GetPassword(); 42 | 43 | private: 44 | Ui::CreateNewDiskDialog m_ui; 45 | bool m_inProgress; 46 | QString m_diskExtension; 47 | }; 48 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/CreateNewDiskDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | CreateNewDiskDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 450 10 | 179 11 | 12 | 13 | 14 | Create new disk 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 16 26 | 27 | 28 | QLineEdit::Password 29 | 30 | 31 | 32 | 33 | 34 | 35 | Password 36 | 37 | 38 | 39 | 40 | 41 | 42 | Disk size, MB 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Disk path 53 | 54 | 55 | 56 | 57 | 58 | 59 | Browse... 60 | 61 | 62 | 63 | 64 | 65 | 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | Disk name 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Show password 84 | 85 | 86 | false 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 0 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | Qt::Horizontal 105 | 106 | 107 | 108 | 40 109 | 20 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Create 118 | 119 | 120 | 121 | 122 | 123 | 124 | Cancel 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/EncryptedDiskGui.pro: -------------------------------------------------------------------------------- 1 | 2 | QT += core gui widgets 3 | 4 | TARGET = EncryptedDiskGui 5 | TEMPLATE = app 6 | 7 | INCLUDEPATH += \ 8 | "C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt" 9 | LIBS += \ 10 | -L"C:/Program Files (x86)/Windows Kits/10/Lib/10.0.10240.0/ucrt/$$QMAKE_HOST.arch" \ 11 | -lbcrypt 12 | 13 | INCLUDEPATH += \ 14 | ../EncryptedDiskClientLib 15 | 16 | CONFIG(debug, debug|release) { 17 | CONFIGURATION = debug 18 | } else { 19 | CONFIGURATION = release 20 | } 21 | 22 | LIBS += \ 23 | -L../../Commons/lib -lCryptoUtils \ 24 | -L../EncryptedDiskClientLib/$$CONFIGURATION -lEncryptedDiskClientLib 25 | 26 | SOURCES += main.cpp\ 27 | MainWindow.cpp \ 28 | CreateNewDiskDialog.cpp \ 29 | MountDiskDialog.cpp 30 | 31 | HEADERS += MainWindow.h \ 32 | CreateNewDiskDialog.h \ 33 | MountDiskDialog.h 34 | 35 | FORMS += MainWindow.ui \ 36 | CreateNewDiskDialog.ui \ 37 | MountDiskDialog.ui 38 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | #include "CreateNewDiskDialog.h" 3 | #include "MountDiskDialog.h" 4 | #include "VirtualDiskController.h" 5 | #include 6 | 7 | namespace 8 | { 9 | size_t s_bytesInMb = 1024 * 1024; 10 | const QString s_diskExtension = ".evd"; 11 | 12 | enum class TableColumn 13 | { 14 | Letter = 0, 15 | Size, 16 | Path 17 | }; 18 | 19 | void ShowDisk(const Disk& newDisk, QTableWidget* tableWidget) 20 | { 21 | const int newRowIndex = tableWidget->model()->rowCount(); 22 | tableWidget->insertRow(newRowIndex); 23 | tableWidget->setItem(newRowIndex, static_cast(TableColumn::Letter), new QTableWidgetItem(QChar(newDisk.letter))); 24 | tableWidget->setItem(newRowIndex, static_cast(TableColumn::Size), new QTableWidgetItem(QString::number(newDisk.size / s_bytesInMb) + "MB")); 25 | tableWidget->setItem(newRowIndex, static_cast(TableColumn::Path), new QTableWidgetItem(QString::fromStdWString(newDisk.fullDiskPath))); 26 | } 27 | } 28 | 29 | MainWindow::MainWindow(QWidget *parent) 30 | : QMainWindow(parent) 31 | , m_dlgCreateDisk(new CreateNewDiskDialog(this, s_diskExtension)) 32 | , m_dlgMountDisk(new MountDiskDialog(this, s_diskExtension)) 33 | , m_diskController(new VirtualDiskController) 34 | , m_canceled(false) 35 | { 36 | m_ui.setupUi(this); 37 | 38 | connect(this, &MainWindow::ProgressChange, m_dlgCreateDisk, &CreateNewDiskDialog::OnProgressChange, Qt::BlockingQueuedConnection); 39 | connect(this, &MainWindow::ProgressFinished, m_dlgCreateDisk, &CreateNewDiskDialog::OnProgressFinished, Qt::BlockingQueuedConnection); 40 | connect(this, &MainWindow::ProgressError, m_dlgCreateDisk, &CreateNewDiskDialog::OnProgressError); 41 | connect(m_dlgCreateDisk, &CreateNewDiskDialog::CreateDisk, this, &MainWindow::OnCreateDisk); 42 | connect(m_dlgCreateDisk, &CreateNewDiskDialog::CancelCreation, this, &MainWindow::OnCancelCreation); 43 | connect(m_dlgMountDisk, &MountDiskDialog::MountDisk, this, &MainWindow::OnMountDisk); 44 | 45 | QHeaderView* header = m_ui.tableWidget->horizontalHeader(); 46 | header->setSectionResizeMode(static_cast(TableColumn::Letter), QHeaderView::ResizeToContents); 47 | header->setSectionResizeMode(static_cast(TableColumn::Size), QHeaderView::ResizeToContents); 48 | 49 | try 50 | { 51 | for (const Disk& disk : m_diskController->getDisks()) 52 | { 53 | ShowDisk(disk, m_ui.tableWidget); 54 | } 55 | } 56 | catch (const std::exception& ex) 57 | { 58 | QMessageBox::warning(0, "Warning", "Cannot communicate with device driver\n" + QString::fromStdString(ex.what())); 59 | } 60 | } 61 | 62 | MainWindow::~MainWindow() 63 | {} 64 | 65 | void MainWindow::virtualDiskControllerDidEncryptDisk(uint64_t encryptedSize, uint64_t totalSize) 66 | { 67 | emit ProgressChange(encryptedSize, totalSize); 68 | } 69 | 70 | void MainWindow::virtualDiskControllerDidFinishCreation(bool canceled) 71 | { 72 | emit ProgressFinished(canceled); 73 | } 74 | 75 | void MainWindow::virtualDiskControllerDidFailDiskCreation(const std::string& error) 76 | { 77 | emit ProgressError(QString::fromStdString(error)); 78 | } 79 | 80 | void MainWindow::OnCreateDisk(const QString& path, const QString& password, uint64_t size) 81 | { 82 | m_canceled = false; 83 | std::thread t(&VirtualDiskController::createNewDisk, m_diskController.get(), path.toStdWString(), size, password.toStdString(), this, std::ref(m_canceled)); 84 | t.detach(); 85 | } 86 | 87 | void MainWindow::OnCancelCreation() 88 | { 89 | m_canceled = true; 90 | } 91 | 92 | void MainWindow::OnMountDisk(const QString& path, char diskLetter, const QString& password) 93 | { 94 | for (int i = 0; i < m_ui.tableWidget->rowCount(); i++) 95 | { 96 | if(m_ui.tableWidget->item(i, static_cast(TableColumn::Path))->text() == path) 97 | { 98 | QMessageBox::information(this, "Information", "The disk is already mount"); 99 | return; 100 | } 101 | } 102 | 103 | try 104 | { 105 | const Disk& newDisk = m_diskController->mountDisk(path.toStdWString(), diskLetter, password.toStdString()); 106 | ShowDisk(newDisk, m_ui.tableWidget); 107 | m_dlgMountDisk->close(); 108 | } 109 | catch (const std::exception& ex) 110 | { 111 | QMessageBox::critical(m_dlgMountDisk, "Error", ex.what()); 112 | } 113 | } 114 | 115 | void MainWindow::closeEvent(QCloseEvent* event) 116 | { 117 | if (QMessageBox::Yes == QMessageBox::question(this, 118 | "Quit", 119 | "Are you sure you want to quit?\nAll disks will be unmounted", 120 | QMessageBox::Yes | QMessageBox::No)) 121 | { 122 | try 123 | { 124 | m_diskController->unmountAllDisks(); 125 | } 126 | catch (const std::exception& ex) 127 | { 128 | QMessageBox::warning(this, "Warning", "Cannot communicate with device driver\n" + QString::fromStdString(ex.what())); 129 | return; 130 | } 131 | event->accept(); 132 | return; 133 | } 134 | 135 | event->ignore(); 136 | } 137 | 138 | void MainWindow::on_btnCreateNewDisk_clicked() 139 | { 140 | m_dlgCreateDisk->Cleanup(); 141 | m_dlgCreateDisk->show(); 142 | } 143 | 144 | void MainWindow::on_btnUnmount_clicked() 145 | { 146 | const int selectedRow = m_ui.tableWidget->currentRow(); 147 | if (-1 == selectedRow) 148 | { 149 | return; 150 | } 151 | 152 | const char diskLetter = m_ui.tableWidget->item(selectedRow, static_cast(TableColumn::Letter))->text().at(0).toUpper().toLatin1(); 153 | 154 | try 155 | { 156 | m_diskController->unmountDisk(diskLetter); 157 | } 158 | catch (const std::exception& ex) 159 | { 160 | QMessageBox::warning(this, "Warning", "Cannot communicate with device driver\n" + QString::fromStdString(ex.what())); 161 | return; 162 | } 163 | 164 | m_ui.tableWidget->removeRow(selectedRow); 165 | } 166 | 167 | void MainWindow::on_btnMountDisk_clicked() 168 | { 169 | m_dlgMountDisk->Cleanup(); 170 | m_dlgMountDisk->show(); 171 | } 172 | 173 | void MainWindow::on_btnUnmountAll_clicked() 174 | { 175 | if (QMessageBox::No == QMessageBox::question(this, 176 | "Question", 177 | "Are you sure you want to unmount all disks?", 178 | QMessageBox::Yes | QMessageBox::No)) 179 | { 180 | return; 181 | } 182 | 183 | try 184 | { 185 | m_diskController->unmountAllDisks(); 186 | } 187 | catch (const std::exception& ex) 188 | { 189 | QMessageBox::warning(this, "Warning", "Cannot communicate with device driver\n" + QString::fromStdString(ex.what())); 190 | return; 191 | } 192 | 193 | int rawsCount = m_ui.tableWidget->rowCount(); 194 | if(!rawsCount) 195 | { 196 | return; 197 | } 198 | 199 | for (int i = 0; i < rawsCount; i++) 200 | { 201 | m_ui.tableWidget->removeRow(0); 202 | } 203 | } 204 | 205 | void MainWindow::on_actionCreate_triggered() 206 | { 207 | on_btnCreateNewDisk_clicked(); 208 | } 209 | 210 | void MainWindow::on_actionMount_triggered() 211 | { 212 | on_btnMountDisk_clicked(); 213 | } 214 | 215 | 216 | void MainWindow::on_actionUnmountAll_triggered() 217 | { 218 | on_btnUnmountAll_clicked(); 219 | } 220 | 221 | void MainWindow::on_actionQuit_triggered() 222 | { 223 | qApp->closeAllWindows(); 224 | } 225 | 226 | void MainWindow::on_actionAbout_triggered() 227 | { 228 | QMessageBox::information(this, "About", "Created by Artem and Sergey"); 229 | } 230 | 231 | void MainWindow::on_actionHow_to_use_triggered() 232 | { 233 | const QString str = "After user presses button \"Create\" and set pass and Path to this one, this programm, first of all encryptes this file. Then user can mount device on this file.\n\n" 234 | "After user presses button \"Mount\" and choose file(with right pass) the programm checkes is this file accessable or not, and create device. If file is not accessable - user will see " 235 | "appropriate message. Then user need to formate disk.Next step - user can use created device.\n\n" 236 | "After user presses button \"Unmount\" and choose appropriate device the programm checkes is this file accessable or not, if no - user " 237 | "will see appropriate message. The other way file would be closed and device would be deleted.\n\n" 238 | "Press \"Unmount all\" and the programm will unmount all accessible devices. After shut down the programm all mounted devices will be unmounted.\n\n" 239 | "The driver supported by the unload-routine(it can be unloaded).\n\n" 240 | "The driver works under next scheme: during start-up of driver, this one created Null_Device(Device Manager), and a symbolic link to it. It is Null_device who leads others " 241 | "devices and this one get general input controls(mount, status of all devices etc.)." 242 | "When the manager creates a new device, in user mode appears symbolic link to it. All mounted devices work in multithreading mode!"; 243 | 244 | QMessageBox::information(this, "How to use", str); 245 | } 246 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/MainWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "ui_MainWindow.h" 12 | #include "IVirtualDiskControllerObserver.h" 13 | 14 | class CreateNewDiskDialog; 15 | class VirtualDiskController; 16 | class MountDiskDialog; 17 | struct Disk; 18 | 19 | class MainWindow : public QMainWindow, public IVirtualDiskControllerObserver 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | explicit MainWindow(QWidget *parent = 0); 25 | virtual ~MainWindow(); 26 | 27 | virtual void virtualDiskControllerDidEncryptDisk(uint64_t encryptedSize, uint64_t totalSize); 28 | virtual void virtualDiskControllerDidFinishCreation(bool canceled); 29 | virtual void virtualDiskControllerDidFailDiskCreation(const std::string& error); 30 | 31 | public slots: 32 | void OnCreateDisk(const QString& path, const QString& password, uint64_t size); 33 | void OnCancelCreation(); 34 | void OnMountDisk (const QString& path, char diskLetter, const QString& password); 35 | 36 | signals: 37 | void ProgressChange(uint64_t encryptedSize, uint64_t totalSize); 38 | void ProgressFinished(bool canceled); 39 | void ProgressError(const QString& error); 40 | 41 | protected: 42 | virtual void closeEvent(QCloseEvent *event); 43 | 44 | private slots: 45 | void on_btnUnmount_clicked(); 46 | void on_btnCreateNewDisk_clicked(); 47 | void on_btnMountDisk_clicked(); 48 | void on_btnUnmountAll_clicked(); 49 | 50 | void on_actionCreate_triggered(); 51 | void on_actionMount_triggered(); 52 | void on_actionUnmountAll_triggered(); 53 | void on_actionQuit_triggered(); 54 | void on_actionAbout_triggered(); 55 | 56 | void on_actionHow_to_use_triggered(); 57 | 58 | private: 59 | Ui::MainWindow m_ui; 60 | CreateNewDiskDialog *m_dlgCreateDisk; 61 | MountDiskDialog *m_dlgMountDisk; 62 | 63 | std::auto_ptr m_diskController; 64 | std::atomic m_canceled; 65 | }; 66 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/MainWindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 546 10 | 416 11 | 12 | 13 | 14 | Encrypted virtual disk manager 15 | 16 | 17 | 18 | 19 | 20 | 21 | QAbstractItemView::NoEditTriggers 22 | 23 | 24 | QAbstractItemView::SingleSelection 25 | 26 | 27 | QAbstractItemView::SelectRows 28 | 29 | 30 | true 31 | 32 | 33 | 34 | Letter 35 | 36 | 37 | 38 | 39 | Size 40 | 41 | 42 | 43 | 44 | Path 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Create 55 | 56 | 57 | 58 | 59 | 60 | 61 | Qt::Horizontal 62 | 63 | 64 | 65 | 40 66 | 20 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Mount 75 | 76 | 77 | 78 | 79 | 80 | 81 | Unmount 82 | 83 | 84 | 85 | 86 | 87 | 88 | Unmount all 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 0 100 | 0 101 | 546 102 | 21 103 | 104 | 105 | 106 | 107 | File 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Info 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | Create 128 | 129 | 130 | 131 | 132 | Mount 133 | 134 | 135 | 136 | 137 | Quit 138 | 139 | 140 | 141 | 142 | About 143 | 144 | 145 | 146 | 147 | Unmount all 148 | 149 | 150 | 151 | 152 | How to use 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/MountDiskDialog.cpp: -------------------------------------------------------------------------------- 1 | #include "MountDiskDialog.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | MountDiskDialog::MountDiskDialog(QWidget *parent, const QString& diskExtension) 8 | : QDialog(parent) 9 | , m_diskExtension(diskExtension) 10 | { 11 | m_ui.setupUi(this); 12 | 13 | 14 | connect(m_ui.linePath, &QLineEdit::textChanged, this, &MountDiskDialog::RefreshMountButtonState); 15 | connect(m_ui.linePassword, &QLineEdit::textChanged, this, &MountDiskDialog::RefreshMountButtonState); 16 | 17 | Cleanup(); 18 | } 19 | 20 | void MountDiskDialog::Cleanup() 21 | { 22 | m_ui.linePassword->clear(); 23 | m_ui.linePath->clear(); 24 | m_ui.checkShowPwd->setChecked(false); 25 | 26 | RefreshMountButtonState(); 27 | RefreshAvailableDrives(); 28 | } 29 | 30 | void MountDiskDialog::showEvent(QShowEvent*) 31 | { 32 | setFixedSize(size()); 33 | } 34 | 35 | void MountDiskDialog::on_btnMount_clicked() 36 | { 37 | emit MountDisk(GetFullPath(), GetDiskLetter(), GetPassword()); 38 | } 39 | 40 | void MountDiskDialog::on_btnCancel_clicked() 41 | { 42 | close(); 43 | } 44 | 45 | void MountDiskDialog::on_btnBrowse_clicked() 46 | { 47 | QString choosenPath = QFileDialog::getOpenFileName(this, "Select disk file", "", QString("Encrypted disk files (*%1)").arg(m_diskExtension)); 48 | if (!choosenPath.isEmpty()) 49 | { 50 | choosenPath = ::QDir::toNativeSeparators(choosenPath); 51 | m_ui.linePath->setText(choosenPath); 52 | } 53 | } 54 | 55 | void MountDiskDialog::on_checkShowPwd_clicked() 56 | { 57 | const bool show = m_ui.checkShowPwd->isChecked(); 58 | m_ui.linePassword->setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password); 59 | } 60 | 61 | void MountDiskDialog::RefreshMountButtonState() 62 | { 63 | bool enabled = !GetFullPath().isEmpty() && !GetPassword().isEmpty(); 64 | m_ui.btnMount->setEnabled(enabled); 65 | } 66 | 67 | void MountDiskDialog::RefreshAvailableDrives() 68 | { 69 | const QFileInfoList& drives = QDir::drives(); 70 | QStringList busyLetters; 71 | for (const QFileInfo& driveInfo : drives) 72 | { 73 | busyLetters << driveInfo.absolutePath().at(0); 74 | } 75 | 76 | QStringList availableLetters; 77 | for (char c = 'A'; c <= 'Z'; c++) 78 | { 79 | QChar letter(c); 80 | if (!busyLetters.contains(letter)) 81 | { 82 | availableLetters << letter; 83 | } 84 | } 85 | 86 | m_ui.comboDiskLetter->clear(); 87 | m_ui.comboDiskLetter->addItems(availableLetters); 88 | m_ui.comboDiskLetter->setCurrentIndex(0); 89 | } 90 | 91 | QString MountDiskDialog::GetFullPath() 92 | { 93 | return m_ui.linePath->text(); 94 | } 95 | 96 | char MountDiskDialog::GetDiskLetter() 97 | { 98 | return m_ui.comboDiskLetter->currentText().at(0).toUpper().toLatin1(); 99 | } 100 | 101 | QString MountDiskDialog::GetPassword() 102 | { 103 | return m_ui.linePassword->text(); 104 | } 105 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/MountDiskDialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ui_MountDiskDialog.h" 5 | 6 | class MountDiskDialog : public QDialog 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | explicit MountDiskDialog(QWidget *parent, const QString& diskExtension); 12 | 13 | void Cleanup(); 14 | 15 | signals: 16 | void MountDisk(const QString &path, char diskLetter, const QString &password); 17 | 18 | protected: 19 | virtual void showEvent(QShowEvent*); 20 | 21 | private slots: 22 | void on_btnMount_clicked(); 23 | void on_btnCancel_clicked(); 24 | void on_btnBrowse_clicked(); 25 | void on_checkShowPwd_clicked(); 26 | 27 | private: 28 | void RefreshMountButtonState(); 29 | void RefreshAvailableDrives(); 30 | 31 | QString GetFullPath(); 32 | char GetDiskLetter(); 33 | QString GetPassword(); 34 | 35 | private: 36 | Ui::MountDiskDialog m_ui; 37 | QString m_diskExtension; 38 | }; 39 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/MountDiskDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MountDiskDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 435 10 | 128 11 | 12 | 13 | 14 | Mount disk 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Browse... 26 | 27 | 28 | 29 | 30 | 31 | 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 16 40 | 41 | 42 | QLineEdit::Password 43 | 44 | 45 | 46 | 47 | 48 | 49 | Password 50 | 51 | 52 | 53 | 54 | 55 | 56 | Show password 57 | 58 | 59 | false 60 | 61 | 62 | 63 | 64 | 65 | 66 | Path 67 | 68 | 69 | 70 | 71 | 72 | 73 | Disk letter: 74 | 75 | 76 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Qt::Horizontal 91 | 92 | 93 | 94 | 40 95 | 20 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | Mount 104 | 105 | 106 | 107 | 108 | 109 | 110 | Cancel 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /EncryptedDisk/EncryptedDiskGui/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MainWindow.h" 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | w.show(); 10 | 11 | return a.exec(); 12 | } 13 | --------------------------------------------------------------------------------