[PATCH v5 1/3] winex11.drv: Preserve last error in x11drv_thread_data().
Rafał Harabień
rafalh1992 at o2.pl
Thu Nov 16 15:30:17 CST 2017
Issue was caused by TlsGetValue always resetting error to ERROR_SUCCESS.
This change fixes GetCursorPos resetting last-error randomly.
Signed-off-by: Rafał Harabień <rafalh1992 at o2.pl>
---
dlls/user32/dialog.c | 1 +
dlls/user32/menu.c | 3 +++
dlls/user32/tests/input.c | 11 ++++++++++-
dlls/user32/tests/win.c | 8 ++++++++
dlls/winex11.drv/x11drv.h | 7 ++++++-
5 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/dialog.c b/dlls/user32/dialog.c
index c2aad8d..46220b0 100644
--- a/dlls/user32/dialog.c
+++ b/dlls/user32/dialog.c
@@ -283,6 +283,7 @@ static BOOL DIALOG_CreateControls32( HWND hwnd, LPCSTR template, const DLG_TEMPL
WARN("control %s %s creation failed\n", debugstr_w(info.className),
debugstr_w(info.windowName));
if (dlgTemplate->style & DS_NOFAILCREATE) continue;
+ SetLastError(0);
return FALSE;
}
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index a5f2317..1ba9638 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -3505,8 +3505,10 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
GetClassLongW( hWnd, GCL_STYLE));
if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
+ {
ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
lpTpm ? &lpTpm->rcExclude : NULL );
+ }
MENU_ExitTracking(hWnd, TRUE);
if (menu->hWnd)
@@ -3518,6 +3520,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
SendMessageW( hWnd, WM_UNINITMENUPOPUP, (WPARAM)hMenu,
MAKELPARAM(0, IS_SYSTEM_MENU(menu)) );
}
+ SetLastError(0);
}
return ret;
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 8f2576d..6ce03f8 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -1928,8 +1928,17 @@ static void test_Input_mouse(void)
DWORD thread_id;
POINT pt, pt_org;
MSG msg;
+ BOOL ret;
- GetCursorPos(&pt_org);
+ SetLastError(0xdeadbeef);
+ ret = GetCursorPos(NULL);
+ ok(!ret, "GetCursorPos succeed\n");
+ ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_NOACCESS, "error %lu\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = GetCursorPos(&pt_org);
+ ok(ret, "GetCursorPos failed\n");
+ ok(GetLastError() == 0xdeadbeef, "error %lu\n", GetLastError());
button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
100, 100, 100, 100, 0, NULL, NULL, NULL);
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index b529284..8433e18 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -6261,6 +6261,14 @@ static void test_CreateWindow(void)
ok( rc.bottom <= expected_cy, "invalid rect bottom %u\n", rc.bottom );
DestroyWindow(hwnd);
+ /* invalid class */
+ SetLastError(0xdeadbeef);
+ hwnd = CreateWindowExA(0, "INVALID_CLASS", NULL, WS_CHILD, 10, 10, 100, 100, parent, 0, 0, NULL);
+ ok(hwnd == 0, "CreateWindowEx succeeded\n");
+ ok(GetLastError() == ERROR_CLASS_DOES_NOT_EXIST || GetLastError() == ERROR_CANNOT_FIND_WND_CLASS,
+ "invalid error %lu\n", GetLastError());
+ DestroyWindow(hwnd);
+
if (pGetLayout && pSetLayout)
{
HDC hdc = GetDC( parent );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 721c082..6786a08 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -345,7 +345,12 @@ extern DWORD thread_data_tls_index DECLSPEC_HIDDEN;
static inline struct x11drv_thread_data *x11drv_thread_data(void)
{
- return TlsGetValue( thread_data_tls_index );
+ /* TlsGetValue always resets last error */
+ unsigned long err = GetLastError();
+ struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
+ if (err != ERROR_SUCCESS && GetLastError() == ERROR_SUCCESS)
+ SetLastError(err);
+ return data;
}
/* retrieve the thread display, or NULL if not created yet */
--
2.7.4
More information about the wine-devel
mailing list