https://git.reactos.org/?p=reactos.git;a=commitdiff;h=75a7cf89a71dbeacfc8b5…
commit 75a7cf89a71dbeacfc8b58855edfd0a0a0152071
Author: Bișoc George <fraizeraust99(a)gmail.com>
AuthorDate: Sun Mar 24 09:40:43 2019 +0100
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Mar 27 22:34:03 2019 +0100
[OSK] Fix an instance race condition
On-Screen Keyboard provides a mechanism to launch the application only once, to avoid
multiple entry point instances. Such mechanism is based upon mutex objects, although it
could happen that the program may end up creating two or more mutexes (a race condition).
CORE-15877
---
base/applications/osk/CMakeLists.txt | 2 +-
base/applications/osk/main.c | 53 +++++++++++++++++++++---------------
base/applications/osk/osk.h | 1 +
3 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/base/applications/osk/CMakeLists.txt b/base/applications/osk/CMakeLists.txt
index 5d5ddf76f9a..24b64eafa9e 100644
--- a/base/applications/osk/CMakeLists.txt
+++ b/base/applications/osk/CMakeLists.txt
@@ -3,5 +3,5 @@ file(GLOB osk_rc_deps res/*.*)
add_rc_deps(rsrc.rc ${osk_rc_deps})
add_executable(osk main.c settings.c rsrc.rc)
set_module_type(osk win32gui UNICODE)
-add_importlibs(osk comdlg32 shell32 user32 gdi32 advapi32 comctl32 msvcrt kernel32
winmm)
+add_importlibs(osk comdlg32 winmm shell32 user32 gdi32 advapi32 comctl32 msvcrt kernel32
ntdll)
add_cd_file(TARGET osk DESTINATION reactos/system32 FOR all)
diff --git a/base/applications/osk/main.c b/base/applications/osk/main.c
index 92e1a05b5b8..30e97941140 100644
--- a/base/applications/osk/main.c
+++ b/base/applications/osk/main.c
@@ -585,12 +585,36 @@ int WINAPI wWinMain(HINSTANCE hInstance,
int show)
{
HANDLE hMutex;
+ DWORD dwError;
INT LayoutResource;
UNREFERENCED_PARAMETER(prev);
UNREFERENCED_PARAMETER(cmdline);
UNREFERENCED_PARAMETER(show);
+ /*
+ Obtain a mutex for the program. This will ensure that
+ the program is launched only once.
+ */
+ hMutex = CreateMutexW(NULL, FALSE, L"OSKRunning");
+
+ if (hMutex)
+ {
+ /* Check if there's already a mutex for the program */
+ dwError = GetLastError();
+
+ if (dwError == ERROR_ALREADY_EXISTS)
+ {
+ /*
+ A mutex with the object name has been created previously.
+ Therefore, another instance is already running.
+ */
+ DPRINT("wWinMain(): Failed to create a mutex! The program instance is
already running.\n");
+ CloseHandle(hMutex);
+ return 0;
+ }
+ }
+
ZeroMemory(&Globals, sizeof(Globals));
Globals.hInstance = hInstance;
@@ -613,31 +637,16 @@ int WINAPI wWinMain(HINSTANCE hInstance,
LayoutResource = MAIN_DIALOG_STANDARD_KB;
}
- /* Rry to open a mutex for a single instance */
- hMutex = OpenMutexW(MUTEX_ALL_ACCESS, FALSE, L"osk");
+ /* Create the modal box based on the configuration registry */
+ DialogBoxW(hInstance,
+ MAKEINTRESOURCEW(LayoutResource),
+ GetDesktopWindow(),
+ OSK_DlgProc);
- if (!hMutex)
+ /* Delete the mutex */
+ if (hMutex)
{
- /* Mutex doesn't exist. This is the first instance so create the mutex. */
- hMutex = CreateMutexW(NULL, FALSE, L"osk");
-
- /* Create the modal box based on the configuration registry */
- DialogBoxW(hInstance,
- MAKEINTRESOURCEW(LayoutResource),
- GetDesktopWindow(),
- OSK_DlgProc);
-
- /* Delete the mutex */
- if (hMutex) CloseHandle(hMutex);
- }
- else
- {
- /* Programme already launched */
-
- /* Delete the mutex */
CloseHandle(hMutex);
-
- ExitProcess(0);
}
return 0;
diff --git a/base/applications/osk/osk.h b/base/applications/osk/osk.h
index ce7e0e19ad1..5de39d32115 100644
--- a/base/applications/osk/osk.h
+++ b/base/applications/osk/osk.h
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <windows.h>
+#include <debug.h>
#include "main.h"