From 9a804654f5e8588f039407aeaaaf24fd9f0062e5 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 2 Jul 2020 02:10:26 +0200 Subject: Windows: Don't allow to encrypt the system drive if it is already encrypted by BitLocker --- src/Common/Dlgcode.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'src/Common/Dlgcode.c') 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; +} -- cgit v1.2.3