user32: Use a safer method of freeing user handles to prevent zeroing out a newly allocated handle.
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 4dd8962..cbc949c 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -107,7 +107,7 @@
assert( index < NB_USER_HANDLES );
ptr->handle = handle;
ptr->type = type;
- user_handles[index] = ptr;
+ InterlockedExchangePointer( &user_handles[index], ptr );
}
return handle;
}
@@ -161,8 +161,8 @@
SERVER_START_REQ( free_user_handle )
{
req->handle = wine_server_user_handle( handle );
- if (!wine_server_call( req )) user_handles[index] = NULL;
- else ptr = NULL;
+ if (wine_server_call( req )) ptr = NULL;
+ else InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr );
}
SERVER_END_REQ;
release_user_handle_ptr( ptr );
@@ -243,7 +243,6 @@
index = USER_HANDLE_TO_INDEX(handle);
assert( index < NB_USER_HANDLES );
- user_handles[index] = win;
win->obj.handle = handle;
win->obj.type = USER_WINDOW;
win->parent = full_parent;
@@ -251,6 +250,7 @@
win->class = class;
win->winproc = get_class_winproc( class );
win->cbWndExtra = extra_bytes;
+ InterlockedExchangePointer( &user_handles[index], win );
if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= WIN_ISUNICODE;
return win;
}
@@ -271,8 +271,8 @@
SERVER_START_REQ( destroy_window )
{
req->handle = wine_server_user_handle( hwnd );
- if (!wine_server_call_err( req )) user_handles[index] = NULL;
- else ptr = NULL;
+ if (wine_server_call_err( req )) ptr = NULL;
+ else InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr );
}
SERVER_END_REQ;
release_user_handle_ptr( ptr );
@@ -815,7 +815,7 @@
if ((wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD) menu = (HMENU)wndPtr->wIDmenu;
sys_menu = wndPtr->hSysMenu;
free_dce( wndPtr->dce, hwnd );
- user_handles[index] = NULL;
+ InterlockedCompareExchangePointer( &user_handles[index], NULL, wndPtr );
}
USER_Unlock();