diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 1ccd69f5a98..c068231cca7 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -651,8 +651,6 @@ BOOL WINAPI User32CallWinEventHook( const struct win_hook_proc_params *params, U WINEVENTPROC proc = params->proc; HMODULE free_module = 0; - USER_CheckNotLock(); /* FIXME: move to NtUserNotifyWinEvent */ - if (params->module[0] && !(proc = get_hook_proc( proc, params->module, &free_module ))) return FALSE; TRACE_(relay)( "\1Call winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n", diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index ea30772067d..47f7ec7513a 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -35,15 +35,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(graphics); HMODULE user32_module = 0; -static CRITICAL_SECTION user_section; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &user_section, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": user_section") } -}; -static CRITICAL_SECTION user_section = { &critsect_debug, -1, 0, 0, 0, 0 }; - static DWORD exiting_thread_id; extern void WDML_NotifyThreadDetach(void); @@ -53,7 +44,7 @@ extern void WDML_NotifyThreadDetach(void); */ void USER_Lock(void) { - EnterCriticalSection( &user_section ); + NtUserCallOneParam( 0, NtUserLock ); } @@ -62,7 +53,7 @@ void USER_Lock(void) */ void USER_Unlock(void) { - LeaveCriticalSection( &user_section ); + NtUserCallOneParam( 1, NtUserLock ); } @@ -73,11 +64,7 @@ void USER_Unlock(void) */ void USER_CheckNotLock(void) { - if (RtlIsCriticalSectionLockedByThread(&user_section)) - { - ERR( "BUG: holding USER lock\n" ); - DebugBreak(); - } + NtUserCallOneParam( 2, NtUserLock ); } @@ -237,7 +224,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) case DLL_PROCESS_DETACH: USER_unload_driver(); FreeLibrary(imm32_module); - DeleteCriticalSection(&user_section); break; } return ret; diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index b390676fc60..427f4cc8527 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -254,6 +254,8 @@ void WINAPI NtUserNotifyWinEvent( DWORD event, HWND hwnd, LONG object_id, LONG c TRACE( "%04x, %p, %d, %d\n", event, hwnd, object_id, child_id ); + user_check_not_lock(); + if (!hwnd) { SetLastError( ERROR_INVALID_WINDOW_HANDLE ); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 58bd22a3adf..c2b09689c2b 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -25,6 +25,8 @@ #endif #include +#include + #include "ntstatus.h" #define WIN32_NO_STATUS #include "ntgdi_private.h" @@ -360,6 +362,30 @@ static RECT work_area; static HDC display_dc; static pthread_mutex_t display_dc_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t user_mutex; +static unsigned int user_lock_thread, user_lock_rec; + +void user_lock(void) +{ + pthread_mutex_lock( &user_mutex ); + if (!user_lock_rec++) user_lock_thread = GetCurrentThreadId(); +} + +void user_unlock(void) +{ + if (!--user_lock_rec) user_lock_thread = 0; + pthread_mutex_unlock( &user_mutex ); +} + +void user_check_not_lock(void) +{ + if (user_lock_thread == GetCurrentThreadId()) + { + ERR( "BUG: holding USER lock\n" ); + assert( 0 ); + } +} + static HANDLE get_display_device_init_mutex( void ) { static const WCHAR display_device_initW[] = @@ -3008,6 +3034,7 @@ void sysparams_init(void) DWORD i, dispos, dpi_scaling; WCHAR layout[KL_NAMELENGTH]; + pthread_mutexattr_t attr; HKEY hkey; static const WCHAR software_wineW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e'}; @@ -3018,6 +3045,11 @@ void sysparams_init(void) static const WCHAR kl_preloadW[] = {'K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','\\','P','r','e','l','o','a','d'}; + pthread_mutexattr_init( &attr ); + pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); + pthread_mutex_init( &user_mutex, &attr ); + pthread_mutexattr_destroy( &attr ); + if ((hkey = reg_create_key( hkcu_key, kl_preloadW, sizeof(kl_preloadW), 0, NULL ))) { if (NtUserGetKeyboardLayoutName( layout )) @@ -4550,6 +4582,13 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) return get_entry( &entry_DESKPATTERN, 256, (WCHAR *)arg ); case NtUserIncrementKeyStateCounter: return InterlockedAdd( &global_key_state_counter, arg ); + case NtUserLock: + switch( arg ) + { + case 0: user_lock(); return 0; + case 1: user_unlock(); return 0; + default: user_check_not_lock(); return 0; + } case NtUserSetCallbacks: return (UINT_PTR)InterlockedExchangePointer( (void **)&user_callbacks, (void *)arg ); default: diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 3017b7e6a72..34b3b545129 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -263,6 +263,9 @@ extern HMONITOR monitor_from_rect( const RECT *rect, DWORD flags, UINT dpi ) DEC extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN; extern void register_window_surface( struct window_surface *old, struct window_surface *new ) DECLSPEC_HIDDEN; +extern void user_lock(void) DECLSPEC_HIDDEN; +extern void user_unlock(void) DECLSPEC_HIDDEN; +extern void user_check_not_lock(void) DECLSPEC_HIDDEN; extern void wrappers_init( unixlib_handle_t handle ) DECLSPEC_HIDDEN; extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN; diff --git a/include/ntuser.h b/include/ntuser.h index a54da6095f1..f36549250bd 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -87,6 +87,7 @@ enum NtUserFlushWindowSurfaces, NtUserGetDeskPattern, NtUserIncrementKeyStateCounter, + NtUserLock, NtUserSetCallbacks, };