From f38c4cfee893ecb8ac213f7b2de974332835eee8 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 25 Mar 2018 21:40:07 +0200 Subject: Windows: handle rare case where call to SwitchDestop fails when trying to display password dialog in our secure desktop. This can happen for example if VeraCrypt process is launched early when user session is opened and it tries to load favorites before user workstation becomes visible. --- src/Common/Dlgcode.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 4f0c4af6..2e37a6a3 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -13211,15 +13211,32 @@ static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter) unsigned int monitoringThreadID = 0; SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter; SecureDesktopMonitoringThreadParam monitorParam; + HDESK hOriginalDesk = GetThreadDesktop (GetCurrentThreadId ()); + BOOL bNewDesktopSet = FALSE; + int counter = 0; - SetThreadDesktop (pParam->hDesk); - SwitchDesktop (pParam->hDesk); + // wait for SwitchDesktop to succeed before using it for current thread + // we wait a maximum of 5 seconds + for (counter = 0; counter < 10; counter++) + { + if (SwitchDesktop (pParam->hDesk)) + { + bNewDesktopSet = TRUE; + break; + } + Sleep (SECUREDESKTOP_MONOTIR_PERIOD); + } + + if (bNewDesktopSet) + { + SetThreadDesktop (pParam->hDesk); - // create the thread that will ensure that VeraCrypt secure desktop has always user input - monitorParam.szVCDesktopName = pParam->szDesktopName; - monitorParam.hVcDesktop = pParam->hDesk; - monitorParam.pbStopMonitoring = &bStopMonitoring; - hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID); + // create the thread that will ensure that VeraCrypt secure desktop has always user input + monitorParam.szVCDesktopName = pParam->szDesktopName; + monitorParam.hVcDesktop = pParam->hDesk; + monitorParam.pbStopMonitoring = &bStopMonitoring; + hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID); + } pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName, NULL, pParam->lpDialogFunc, pParam->dwInitParam); @@ -13232,6 +13249,12 @@ static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter) CloseHandle (hMonitoringThread); } + if (bNewDesktopSet) + { + SetThreadDesktop (hOriginalDesk); + SwitchDesktop (hOriginalDesk); + } + return 0; } @@ -13290,7 +13313,6 @@ INT_PTR SecureDesktopDialogBoxParam( hSecureDesk = CreateDesktop (szDesktopName, NULL, NULL, 0, desktopAccess, NULL); if (hSecureDesk) { - HDESK hOriginalDesk = GetThreadDesktop (GetCurrentThreadId ()); SecureDesktopThreadParam param; param.hDesk = hSecureDesk; @@ -13307,9 +13329,6 @@ INT_PTR SecureDesktopDialogBoxParam( WaitForSingleObject (hThread, INFINITE); CloseHandle (hThread); - SwitchDesktop (hOriginalDesk); - SetThreadDesktop (hOriginalDesk); - retValue = param.retValue; bSuccess = TRUE; } -- cgit v1.2.3