mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Windows: enhance secure desktop handling to try to workaround Windows 11 issue
Several enhancements implemented: - replace CreateThread by _beginthreadex to avoid potential issues when using C runtime - use an event to notify monitoring thread to stop instead of a volatile boolean - perform switch to the regular desktop in the main thread and not in the secure desktop thread
This commit is contained in:
@@ -14085,13 +14085,14 @@ typedef struct
|
|||||||
DLGPROC lpDialogFunc;
|
DLGPROC lpDialogFunc;
|
||||||
LPARAM dwInitParam;
|
LPARAM dwInitParam;
|
||||||
INT_PTR retValue;
|
INT_PTR retValue;
|
||||||
|
BOOL bDlgDisplayed; // set to TRUE if the dialog was displayed on secure desktop
|
||||||
} SecureDesktopThreadParam;
|
} SecureDesktopThreadParam;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LPCWSTR szVCDesktopName;
|
LPCWSTR szVCDesktopName;
|
||||||
HDESK hVcDesktop;
|
HDESK hVcDesktop;
|
||||||
volatile BOOL* pbStopMonitoring;
|
HANDLE hStopEvent; // event to signal when to stop monitoring
|
||||||
} SecureDesktopMonitoringThreadParam;
|
} SecureDesktopMonitoringThreadParam;
|
||||||
|
|
||||||
#define SECUREDESKTOP_MONOTIR_PERIOD 500
|
#define SECUREDESKTOP_MONOTIR_PERIOD 500
|
||||||
@@ -14103,11 +14104,12 @@ static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadPara
|
|||||||
SecureDesktopMonitoringThreadParam* pMonitorParam = (SecureDesktopMonitoringThreadParam*) lpThreadParameter;
|
SecureDesktopMonitoringThreadParam* pMonitorParam = (SecureDesktopMonitoringThreadParam*) lpThreadParameter;
|
||||||
if (pMonitorParam)
|
if (pMonitorParam)
|
||||||
{
|
{
|
||||||
volatile BOOL* pbStopMonitoring = pMonitorParam->pbStopMonitoring;
|
HANDLE hStopEvent = pMonitorParam->hStopEvent;
|
||||||
LPCWSTR szVCDesktopName = pMonitorParam->szVCDesktopName;
|
LPCWSTR szVCDesktopName = pMonitorParam->szVCDesktopName;
|
||||||
HDESK hVcDesktop = pMonitorParam->hVcDesktop;
|
HDESK hVcDesktop = pMonitorParam->hVcDesktop;
|
||||||
|
|
||||||
while (!*pbStopMonitoring)
|
// loop until the stop event is signaled
|
||||||
|
while (WaitForSingleObject (hStopEvent, SECUREDESKTOP_MONOTIR_PERIOD) == WAIT_TIMEOUT)
|
||||||
{
|
{
|
||||||
// check that our secure desktop is still the input desktop
|
// check that our secure desktop is still the input desktop
|
||||||
// otherwise, switch to it
|
// otherwise, switch to it
|
||||||
@@ -14135,22 +14137,18 @@ static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadPara
|
|||||||
|
|
||||||
if (bPerformSwitch)
|
if (bPerformSwitch)
|
||||||
SwitchDesktop (hVcDesktop);
|
SwitchDesktop (hVcDesktop);
|
||||||
|
|
||||||
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter)
|
static unsigned int __stdcall SecureDesktopThread( LPVOID lpThreadParameter )
|
||||||
{
|
{
|
||||||
volatile BOOL bStopMonitoring = FALSE;
|
|
||||||
HANDLE hMonitoringThread = NULL;
|
HANDLE hMonitoringThread = NULL;
|
||||||
unsigned int monitoringThreadID = 0;
|
unsigned int monitoringThreadID = 0;
|
||||||
SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter;
|
SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter;
|
||||||
SecureDesktopMonitoringThreadParam monitorParam;
|
SecureDesktopMonitoringThreadParam monitorParam;
|
||||||
HDESK hOriginalDesk = GetThreadDesktop (GetCurrentThreadId ());
|
|
||||||
BOOL bNewDesktopSet = FALSE;
|
BOOL bNewDesktopSet = FALSE;
|
||||||
|
|
||||||
// wait for SwitchDesktop to succeed before using it for current thread
|
// wait for SwitchDesktop to succeed before using it for current thread
|
||||||
@@ -14158,38 +14156,48 @@ static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter)
|
|||||||
{
|
{
|
||||||
if (SwitchDesktop (pParam->hDesk))
|
if (SwitchDesktop (pParam->hDesk))
|
||||||
{
|
{
|
||||||
bNewDesktopSet = TRUE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
|
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bNewDesktopSet = SetThreadDesktop (pParam->hDesk);
|
||||||
|
|
||||||
if (bNewDesktopSet)
|
if (bNewDesktopSet)
|
||||||
{
|
{
|
||||||
SetThreadDesktop (pParam->hDesk);
|
|
||||||
|
|
||||||
// create the thread that will ensure that VeraCrypt secure desktop has always user input
|
// create the thread that will ensure that VeraCrypt secure desktop has always user input
|
||||||
monitorParam.szVCDesktopName = pParam->szDesktopName;
|
// this is done only if the stop event is created successfully
|
||||||
monitorParam.hVcDesktop = pParam->hDesk;
|
HANDLE hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
monitorParam.pbStopMonitoring = &bStopMonitoring;
|
if (hStopEvent)
|
||||||
hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID);
|
{
|
||||||
|
monitorParam.szVCDesktopName = pParam->szDesktopName;
|
||||||
|
monitorParam.hVcDesktop = pParam->hDesk;
|
||||||
|
monitorParam.hStopEvent = hStopEvent;
|
||||||
|
hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID);
|
||||||
|
}
|
||||||
|
|
||||||
|
pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName,
|
||||||
|
NULL, pParam->lpDialogFunc, pParam->dwInitParam);
|
||||||
|
|
||||||
|
if (hMonitoringThread)
|
||||||
|
{
|
||||||
|
// notify the monitoring thread to stop
|
||||||
|
SetEvent(hStopEvent);
|
||||||
|
|
||||||
|
WaitForSingleObject (hMonitoringThread, INFINITE);
|
||||||
|
CloseHandle (hMonitoringThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hStopEvent)
|
||||||
|
{
|
||||||
|
CloseHandle (hStopEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
pParam->bDlgDisplayed = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName,
|
|
||||||
NULL, pParam->lpDialogFunc, pParam->dwInitParam);
|
|
||||||
|
|
||||||
if (hMonitoringThread)
|
|
||||||
{
|
{
|
||||||
bStopMonitoring = TRUE;
|
pParam->bDlgDisplayed = FALSE;
|
||||||
|
|
||||||
WaitForSingleObject (hMonitoringThread, INFINITE);
|
|
||||||
CloseHandle (hMonitoringThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bNewDesktopSet)
|
|
||||||
{
|
|
||||||
SetThreadDesktop (hOriginalDesk);
|
|
||||||
SwitchDesktop (hOriginalDesk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -14249,6 +14257,7 @@ INT_PTR SecureDesktopDialogBoxParam(
|
|||||||
map<DWORD, BOOL> ctfmonBeforeList, ctfmonAfterList;
|
map<DWORD, BOOL> ctfmonBeforeList, ctfmonAfterList;
|
||||||
DWORD desktopAccess = DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS;
|
DWORD desktopAccess = DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS;
|
||||||
HDESK hSecureDesk;
|
HDESK hSecureDesk;
|
||||||
|
HDESK hOriginalDesk = GetThreadDesktop (GetCurrentThreadId());
|
||||||
|
|
||||||
HDESK hInputDesk = NULL;
|
HDESK hInputDesk = NULL;
|
||||||
|
|
||||||
@@ -14280,8 +14289,10 @@ INT_PTR SecureDesktopDialogBoxParam(
|
|||||||
param.lpDialogFunc = lpDialogFunc;
|
param.lpDialogFunc = lpDialogFunc;
|
||||||
param.dwInitParam = dwInitParam;
|
param.dwInitParam = dwInitParam;
|
||||||
param.retValue = 0;
|
param.retValue = 0;
|
||||||
|
param.bDlgDisplayed = FALSE;
|
||||||
|
|
||||||
HANDLE hThread = ::CreateThread (NULL, 0, SecureDesktopThread, (LPVOID) ¶m, 0, NULL);
|
// use _beginthreadex instead of CreateThread because lpDialogFunc may be using the C runtime library
|
||||||
|
HANDLE hThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopThread, (LPVOID) ¶m, 0, NULL);
|
||||||
if (hThread)
|
if (hThread)
|
||||||
{
|
{
|
||||||
StringCbCopy(SecureDesktopName, sizeof (SecureDesktopName), szDesktopName);
|
StringCbCopy(SecureDesktopName, sizeof (SecureDesktopName), szDesktopName);
|
||||||
@@ -14289,8 +14300,15 @@ INT_PTR SecureDesktopDialogBoxParam(
|
|||||||
WaitForSingleObject (hThread, INFINITE);
|
WaitForSingleObject (hThread, INFINITE);
|
||||||
CloseHandle (hThread);
|
CloseHandle (hThread);
|
||||||
|
|
||||||
retValue = param.retValue;
|
if (param.bDlgDisplayed)
|
||||||
bSuccess = TRUE;
|
{
|
||||||
|
// dialog box was indeed displayed in Secure Desktop
|
||||||
|
retValue = param.retValue;
|
||||||
|
bSuccess = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch back to original desktop
|
||||||
|
SwitchDesktop (hOriginalDesk);
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseDesktop (hSecureDesk);
|
CloseDesktop (hSecureDesk);
|
||||||
@@ -14311,6 +14329,7 @@ INT_PTR SecureDesktopDialogBoxParam(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseDesktop(hOriginalDesk);
|
||||||
burn (szDesktopName, sizeof (szDesktopName));
|
burn (szDesktopName, sizeof (szDesktopName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user