VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Dlgcode.c
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2020-07-02 02:10:26 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2020-07-02 02:20:58 +0200
commit9a804654f5e8588f039407aeaaaf24fd9f0062e5 (patch)
tree22773e2465c688f4e17e198c08b6f1b62aedabaa /src/Common/Dlgcode.c
parentac3cccdd2156403d66b32ef5ab35017caff43209 (diff)
downloadVeraCrypt-9a804654f5e8588f039407aeaaaf24fd9f0062e5.tar.gz
VeraCrypt-9a804654f5e8588f039407aeaaaf24fd9f0062e5.zip
Windows: Don't allow to encrypt the system drive if it is already encrypted by BitLocker
Diffstat (limited to 'src/Common/Dlgcode.c')
-rw-r--r--src/Common/Dlgcode.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 813f2b07..bd1f6f84 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -14372,3 +14372,105 @@ void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed)
burn (&tctx, sizeof(tctx));
}
#endif
+
+/*
+ * GetBitLockerEncryptionStatus: retuns the BitLocker encryption status of a given drive.
+ */
+
+typedef enum BitLockerProtectionState
+{
+ BL_State_FullyDecrypted = 0,
+ BL_State_FullyEncrypted = 1,
+ BL_State_EncryptionInProgress = 2,
+ BL_State_DecryptionInProgress = 3,
+ BL_State_EncryptionSuspended = 4,
+ BL_State_DecryptionSuspended = 5,
+ BL_State_FullyEncryptedWipeInProgress = 6,
+ BL_State_FullyEncryptedWipeSuspended = 7
+} BitLockerProtectionState;
+
+typedef HRESULT (WINAPI *SHCreateItemFromParsingNameFn)(
+ PCWSTR pszPath,
+ IBindCtx* pbc,
+ REFIID riid,
+ void** ppv
+);
+
+typedef HRESULT (WINAPI *PSGetPropertyKeyFromNameFn)(
+ _In_ PCWSTR pszName,
+ _Out_ PROPERTYKEY* ppropkey);
+
+
+/*
+ Code derived from https://stackoverflow.com/questions/23841973/how-to-tell-if-drive-is-bitlocker-encrypted-without-admin-privilege/47192128#47192128
+*/
+BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter)
+{
+ HRESULT hr;
+ BitLockerEncryptionStatus blStatus = BL_Status_Unknown;
+ wchar_t szDllPath[MAX_PATH] = { 0 };
+ HMODULE hShell32 = NULL;
+
+ CoInitialize(NULL);
+
+ if (GetSystemDirectory(szDllPath, MAX_PATH))
+ StringCchCatW(szDllPath, MAX_PATH, L"\\Shell32.dll");
+ else
+ StringCchCopyW(szDllPath, MAX_PATH, L"C:\\Windows\\System32\\Shell32.dll");
+
+ hShell32 = LoadLibrary(szDllPath);
+ if (hShell32)
+ {
+ SHCreateItemFromParsingNameFn SHCreateItemFromParsingNamePtr = (SHCreateItemFromParsingNameFn)GetProcAddress(hShell32, "SHCreateItemFromParsingName");
+ if (SHCreateItemFromParsingNamePtr)
+ {
+ HMODULE hPropsys = NULL;
+
+ if (GetSystemDirectory(szDllPath, MAX_PATH))
+ StringCchCatW(szDllPath, MAX_PATH, L"\\Propsys.dll");
+ else
+ StringCchCopyW(szDllPath, MAX_PATH, L"C:\\Windows\\System32\\Propsys.dll");
+
+ hPropsys = LoadLibrary(szDllPath);
+ if (hPropsys)
+ {
+ PSGetPropertyKeyFromNameFn PSGetPropertyKeyFromNamePtr = (PSGetPropertyKeyFromNameFn)GetProcAddress(hPropsys, "PSGetPropertyKeyFromName");
+ if (PSGetPropertyKeyFromNamePtr)
+ {
+ WCHAR parsingName[3] = {driveLetter, L':', 0};
+ IShellItem2* drive = NULL;
+ hr = SHCreateItemFromParsingNamePtr(parsingName, NULL, IID_PPV_ARGS(&drive));
+ if (SUCCEEDED(hr)) {
+ PROPERTYKEY pKey;
+ hr = PSGetPropertyKeyFromNamePtr(L"System.Volume.BitLockerProtection", &pKey);
+ if (SUCCEEDED(hr)) {
+ PROPVARIANT prop;
+ PropVariantInit(&prop);
+ hr = drive->GetProperty(pKey, &prop);
+ if (SUCCEEDED(hr)) {
+ int status = prop.intVal;
+ if (status == BL_State_FullyEncrypted || status == BL_State_DecryptionInProgress || status == BL_State_DecryptionSuspended)
+ blStatus = BL_Status_Protected;
+ else
+ blStatus = BL_Status_Unprotected;
+ }
+ }
+ }
+ if (drive)
+ drive->Release();
+ }
+
+ FreeLibrary(hPropsys);
+ }
+ }
+ else
+ {
+ blStatus = BL_Status_Unprotected; // before Vista, there was no Bitlocker
+ }
+
+ FreeLibrary(hShell32);
+ }
+
+ CoUninitialize();
+ return blStatus;
+}