Skip to content

Commit c8b9a73

Browse files
committed
Windows: Fix rare cases being stuck in Secure Desktop after it is used for password entry
Cause seems to be IME as documented in KeePass project (https://keepass.info/help/kb/sec_desk.html#ime). We use the same approach as KeePass to disable IME in Secure Desktop. This commit also add few changes: - we switch to secure desktop only if SetThreadDesktop succeeds - we call SwitchDesktop to switch to original desktop only if we actually succeeded in displaying secure desktop
1 parent 71215f1 commit c8b9a73

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

src/Common/Dlgcode.c

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13921,20 +13921,33 @@ static unsigned int __stdcall SecureDesktopThread( LPVOID lpThreadParameter )
1392113921
StringCbCopy(SecureDesktopName, sizeof (SecureDesktopName), pParam->szDesktopName);
1392213922
pParam->hDesk = hSecureDesk;
1392313923

13924-
// wait for SwitchDesktop to succeed before using it for current thread
13925-
while (true)
13924+
bNewDesktopSet = SetThreadDesktop (hSecureDesk);
13925+
13926+
if (bNewDesktopSet)
1392613927
{
13927-
if (SwitchDesktop (hSecureDesk))
13928+
// call ImmDisableIME from imm32.dll to disable IME since it can create issue with secure desktop
13929+
// cf: https://keepass.info/help/kb/sec_desk.html#ime
13930+
HMODULE hImmDll = LoadLibraryEx (L"imm32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
13931+
if (hImmDll)
1392813932
{
13929-
break;
13933+
typedef BOOL (WINAPI *ImmDisableIME_t)(DWORD);
13934+
ImmDisableIME_t ImmDisableIME = (ImmDisableIME_t) GetProcAddress (hImmDll, "ImmDisableIME");
13935+
if (ImmDisableIME)
13936+
{
13937+
ImmDisableIME (0);
13938+
}
1393013939
}
13931-
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
13932-
}
1393313940

13934-
bNewDesktopSet = SetThreadDesktop (hSecureDesk);
13941+
// wait for SwitchDesktop to succeed before using it for current thread
13942+
while (true)
13943+
{
13944+
if (SwitchDesktop (hSecureDesk))
13945+
{
13946+
break;
13947+
}
13948+
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
13949+
}
1393513950

13936-
if (bNewDesktopSet)
13937-
{
1393813951
// create the thread that will ensure that VeraCrypt secure desktop has always user input
1393913952
// this is done only if the stop event is created successfully
1394013953
HANDLE hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -13964,6 +13977,12 @@ static unsigned int __stdcall SecureDesktopThread( LPVOID lpThreadParameter )
1396413977
}
1396513978

1396613979
pParam->bDlgDisplayed = TRUE;
13980+
13981+
// free imm32.dll handle
13982+
if (hImmDll)
13983+
{
13984+
FreeLibrary (hImmDll);
13985+
}
1396713986
}
1396813987
else
1396913988
{
@@ -14084,19 +14103,20 @@ INT_PTR SecureDesktopDialogBoxParam(
1408414103
// dialog box was indeed displayed in Secure Desktop
1408514104
retValue = param.retValue;
1408614105
bSuccess = TRUE;
14106+
14107+
// switch back to the original desktop
14108+
while (!SwitchDesktop (hOriginalDesk))
14109+
{
14110+
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
14111+
}
14112+
14113+
SetThreadDesktop (hOriginalDesk);
1408714114
}
14088-
}
1408914115

14090-
if (param.hDesk)
14091-
{
14092-
while (!SwitchDesktop (hOriginalDesk))
14116+
if (param.hDesk)
1409314117
{
14094-
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
14118+
CloseDesktop (param.hDesk);
1409514119
}
14096-
14097-
SetThreadDesktop (hOriginalDesk);
14098-
14099-
CloseDesktop (param.hDesk);
1410014120
}
1410114121

1410214122
// get the new list of ctfmon.exe processes in order to find the ID of the

0 commit comments

Comments
 (0)