diff --git a/dlls/user32/property.c b/dlls/user32/property.c index b6fb66a5e3e..e6877a3b3e0 100644 --- a/dlls/user32/property.c +++ b/dlls/user32/property.c @@ -24,7 +24,7 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" -#include "winuser.h" +#include "ntuser.h" #include "wine/server.h" /* size of buffer needed to store an atom string */ @@ -158,18 +158,7 @@ BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle ) */ BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle ) { - BOOL ret; - - SERVER_START_REQ( set_window_property ) - { - req->window = wine_server_user_handle( hwnd ); - req->data = (ULONG_PTR)handle; - if (IS_INTRESOURCE(str)) req->atom = LOWORD(str); - else wine_server_add_data( req, str, lstrlenW(str) * sizeof(WCHAR) ); - ret = !wine_server_call_err( req ); - } - SERVER_END_REQ; - return ret; + return NtUserSetProp( hwnd, str, handle ); } diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 8b74deb0be7..c718510bbc7 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -114,6 +114,7 @@ static void * const syscalls[] = NtUserOpenWindowStation, NtUserSetObjectInformation, NtUserSetProcessWindowStation, + NtUserSetProp, NtUserSetThreadDesktop, }; diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 2f5014b80b4..079c4eead23 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -32,6 +32,26 @@ static void test_NtUserCloseWindowStation(void) "NtUserCloseWindowStation returned %x %u\n", ret, GetLastError() ); } +static void test_window_props(void) +{ + HANDLE prop; + ATOM atom; + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowExA( 0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL ); + + atom = GlobalAddAtomW( L"test" ); + + ret = NtUserSetProp( hwnd, UlongToPtr(atom), UlongToHandle(0xdeadbeef) ); + ok( ret, "NtUserSetProp failed: %u\n", GetLastError() ); + + prop = GetPropW( hwnd, L"test" ); + ok( prop == UlongToHandle(0xdeadbeef), "prop = %p\n", prop ); + + GlobalDeleteAtom( atom ); + DestroyWindow( hwnd ); +} START_TEST(win32u) { @@ -39,4 +59,5 @@ START_TEST(win32u) GetDesktopWindow(); test_NtUserCloseWindowStation(); + test_window_props(); } diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 5c31b9017ee..97df44f3215 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1222,7 +1222,7 @@ @ stub NtUserSetProcessRestrictionExemption @ stub NtUserSetProcessUIAccessZorder @ stdcall -syscall NtUserSetProcessWindowStation(long) -@ stub NtUserSetProp +@ stdcall -syscall NtUserSetProp(long wstr ptr) @ stub NtUserSetScrollInfo @ stub NtUserSetSensorPresence @ stub NtUserSetSharedWindowData diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 03065c1a00a..9543d4c4a54 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -27,6 +27,28 @@ #include "wine/server.h" +/***************************************************************************** + * NtUserSetProp (win32u.@) + * + * NOTE Native allows only ATOMs as the second argument. We allow strings + * to save extra server call in SetPropW. + */ +BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle ) +{ + BOOL ret; + + SERVER_START_REQ( set_window_property ) + { + req->window = wine_server_user_handle( hwnd ); + req->data = (ULONG_PTR)handle; + if (IS_INTRESOURCE(str)) req->atom = LOWORD(str); + else wine_server_add_data( req, str, lstrlenW(str) * sizeof(WCHAR) ); + ret = !wine_server_call_err( req ); + } + SERVER_END_REQ; + return ret; +} + /***************************************************************************** * NtUserGetLayeredWindowAttributes (win32u.@) */ diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 7c6f00afe66..fb265638750 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -101,6 +101,7 @@ SYSCALL_ENTRY( NtUserOpenWindowStation ) \ SYSCALL_ENTRY( NtUserSetObjectInformation ) \ SYSCALL_ENTRY( NtUserSetProcessWindowStation ) \ + SYSCALL_ENTRY( NtUserSetProp ) \ SYSCALL_ENTRY( NtUserSetThreadDesktop ) #endif /* __WOW64WIN_SYSCALL_H */ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index c33ab4e4dff..d25f2271012 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -156,6 +156,15 @@ NTSTATUS WINAPI wow64_NtUserSetObjectInformation( UINT *args ) return NtUserSetObjectInformation( handle, index, info, len ); } +NTSTATUS WINAPI wow64_NtUserSetProp( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + const WCHAR *str = get_ptr( &args ); + HANDLE handle = get_handle( &args ); + + return NtUserSetProp( hwnd, str, handle ); +} + NTSTATUS WINAPI wow64_NtUserGetLayeredWindowAttributes( UINT *args ) { HWND hwnd = get_handle( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index a9b2ae65dad..c05c743b553 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -34,12 +34,15 @@ BOOL WINAPI NtUserGetLayeredWindowAttributes( HWND hwnd, COLORREF *key, BYTE BOOL WINAPI NtUserGetObjectInformation( HANDLE handle, INT index, void *info, DWORD len, DWORD *needed ); HWINSTA WINAPI NtUserGetProcessWindowStation(void); +HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str ); HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); HWINSTA WINAPI NtUserOpenWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK access ); BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DWORD len ); HDESK WINAPI NtUserOpenDesktop( OBJECT_ATTRIBUTES *attr, DWORD flags, ACCESS_MASK access ); HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access ); +HANDLE WINAPI NtUserRemoveProp( HWND hwnd, const WCHAR *str ); BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle ); +BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle ); BOOL WINAPI NtUserSetThreadDesktop( HDESK handle ); #endif /* _NTUSER_ */