https://git.reactos.org/?p=reactos.git;a=commitdiff;h=75a7cf89a71dbeacfc8b58...
commit 75a7cf89a71dbeacfc8b58855edfd0a0a0152071 Author: Bișoc George fraizeraust99@gmail.com AuthorDate: Sun Mar 24 09:40:43 2019 +0100 Commit: Hermès BÉLUSCA - MAÏTO hermes.belusca-maito@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"