win32u: Implement NtUserBuildHwndList.
Fixes Quake Champions, spotted by Paul Gofman. Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d96975d649
commit
2d56b0a93c
|
@ -103,6 +103,7 @@ static void * const syscalls[] =
|
|||
NtGdiTransformPoints,
|
||||
NtUserAddClipboardFormatListener,
|
||||
NtUserAttachThreadInput,
|
||||
NtUserBuildHwndList,
|
||||
NtUserCloseDesktop,
|
||||
NtUserCloseWindowStation,
|
||||
NtUserCreateDesktopEx,
|
||||
|
|
|
@ -104,12 +104,90 @@ static void test_window_props(void)
|
|||
DestroyWindow( hwnd );
|
||||
}
|
||||
|
||||
static BOOL WINAPI count_win( HWND hwnd, LPARAM lparam )
|
||||
{
|
||||
ULONG *cnt = (ULONG *)lparam;
|
||||
(*cnt)++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_NtUserBuildHwndList(void)
|
||||
{
|
||||
ULONG size, desktop_windows_cnt;
|
||||
HWND buf[512], hwnd;
|
||||
NTSTATUS status;
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( 0, 0, 0, 0, GetCurrentThreadId(), ARRAYSIZE(buf), buf, &size );
|
||||
ok( !status, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == 1, "size = %u\n", size );
|
||||
ok( buf[0] == HWND_BOTTOM, "buf[0] = %p\n", buf[0] );
|
||||
|
||||
hwnd = CreateWindowExA( 0, "static", NULL, WS_POPUP, 0,0,0,0,GetDesktopWindow(),0,0, NULL );
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( 0, 0, 0, 0, GetCurrentThreadId(), ARRAYSIZE(buf), buf, &size );
|
||||
ok( !status, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == 3, "size = %u\n", size );
|
||||
ok( buf[0] == hwnd, "buf[0] = %p\n", buf[0] );
|
||||
ok( buf[2] == HWND_BOTTOM, "buf[0] = %p\n", buf[2] );
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( 0, 0, 0, 0, GetCurrentThreadId(), 3, buf, &size );
|
||||
ok( !status, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == 3, "size = %u\n", size );
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( 0, 0, 0, 0, GetCurrentThreadId(), 2, buf, &size );
|
||||
ok( status == STATUS_BUFFER_TOO_SMALL, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == 3, "size = %u\n", size );
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( 0, 0, 0, 0, GetCurrentThreadId(), 1, buf, &size );
|
||||
ok( status == STATUS_BUFFER_TOO_SMALL, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == 3, "size = %u\n", size );
|
||||
|
||||
desktop_windows_cnt = 0;
|
||||
EnumDesktopWindows( 0, count_win, (LPARAM)&desktop_windows_cnt );
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( 0, 0, 0, 1, 0, ARRAYSIZE(buf), buf, &size );
|
||||
ok( !status, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == desktop_windows_cnt + 1, "size = %u, expected %u\n", size, desktop_windows_cnt + 1 );
|
||||
|
||||
desktop_windows_cnt = 0;
|
||||
EnumDesktopWindows( GetThreadDesktop( GetCurrentThreadId() ), count_win, (LPARAM)&desktop_windows_cnt );
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( GetThreadDesktop(GetCurrentThreadId()), 0, 0, 1, 0,
|
||||
ARRAYSIZE(buf), buf, &size );
|
||||
ok( !status, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == desktop_windows_cnt + 1, "size = %u, expected %u\n", size, desktop_windows_cnt + 1 );
|
||||
|
||||
size = 0;
|
||||
status = NtUserBuildHwndList( GetThreadDesktop(GetCurrentThreadId()), 0, 0, 0, 0,
|
||||
ARRAYSIZE(buf), buf, &size );
|
||||
ok( !status, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
todo_wine
|
||||
ok( size > desktop_windows_cnt + 1, "size = %u, expected %u\n", size, desktop_windows_cnt + 1 );
|
||||
|
||||
size = 0xdeadbeef;
|
||||
status = NtUserBuildHwndList( UlongToHandle(0xdeadbeef), 0, 0, 0, 0,
|
||||
ARRAYSIZE(buf), buf, &size );
|
||||
ok( status == STATUS_INVALID_HANDLE, "NtUserBuildHwndList failed: %#x\n", status );
|
||||
ok( size == 0xdeadbeef, "size = %u\n", size );
|
||||
|
||||
DestroyWindow( hwnd );
|
||||
}
|
||||
|
||||
START_TEST(win32u)
|
||||
{
|
||||
/* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */
|
||||
GetDesktopWindow();
|
||||
|
||||
test_NtUserEnumDisplayDevices(); /* Must run before test_NtUserCloseWindowStation. */
|
||||
test_NtUserCloseWindowStation();
|
||||
test_NtUserEnumDisplayDevices();
|
||||
test_window_props();
|
||||
test_NtUserBuildHwndList();
|
||||
|
||||
test_NtUserCloseWindowStation();
|
||||
}
|
||||
|
|
|
@ -763,7 +763,7 @@
|
|||
@ stub NtUserBlockInput
|
||||
@ stub NtUserBroadcastThemeChangeEvent
|
||||
@ stub NtUserBuildHimcList
|
||||
@ stub NtUserBuildHwndList
|
||||
@ stdcall -syscall NtUserBuildHwndList(long long long long long long ptr ptr)
|
||||
@ stub NtUserBuildNameList
|
||||
@ stub NtUserBuildPropList
|
||||
@ stub NtUserCalcMenuBar
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "win32u_private.h"
|
||||
#include "wine/server.h"
|
||||
|
||||
|
@ -115,3 +117,32 @@ BOOL WINAPI NtUserGetLayeredWindowAttributes( HWND hwnd, COLORREF *key, BYTE *al
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* NtUserBuildHwndList (win32u.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtUserBuildHwndList( HDESK desktop, ULONG unk2, ULONG unk3, ULONG unk4,
|
||||
ULONG thread_id, ULONG count, HWND *buffer, ULONG *size )
|
||||
{
|
||||
user_handle_t *list = (user_handle_t *)buffer;
|
||||
int i;
|
||||
NTSTATUS status;
|
||||
|
||||
SERVER_START_REQ( get_window_children )
|
||||
{
|
||||
req->desktop = wine_server_obj_handle( desktop );
|
||||
req->tid = thread_id;
|
||||
if (count) wine_server_set_reply( req, list, (count - 1) * sizeof(user_handle_t) );
|
||||
status = wine_server_call( req );
|
||||
if (status && status != STATUS_BUFFER_TOO_SMALL) return status;
|
||||
*size = reply->count + 1;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (*size > count) return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
/* start from the end since HWND is potentially larger than user_handle_t */
|
||||
for (i = *size - 2; i >= 0; i--)
|
||||
buffer[i] = wine_server_ptr_handle( list[i] );
|
||||
buffer[*size - 1] = HWND_BOTTOM;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
MODULE = wow64win.dll
|
||||
IMPORTS = win32u ntdll winecrt0
|
||||
IMPORTS = wow64 win32u ntdll winecrt0
|
||||
|
||||
EXTRADLLFLAGS = -nodefaultlibs -Wl,--image-base,0x6f200000
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
SYSCALL_ENTRY( NtGdiTransformPoints ) \
|
||||
SYSCALL_ENTRY( NtUserAddClipboardFormatListener ) \
|
||||
SYSCALL_ENTRY( NtUserAttachThreadInput ) \
|
||||
SYSCALL_ENTRY( NtUserBuildHwndList ) \
|
||||
SYSCALL_ENTRY( NtUserCloseDesktop ) \
|
||||
SYSCALL_ENTRY( NtUserCloseWindowStation ) \
|
||||
SYSCALL_ENTRY( NtUserCreateDesktopEx ) \
|
||||
|
|
|
@ -181,6 +181,31 @@ NTSTATUS WINAPI wow64_NtUserRemoveProp( UINT *args )
|
|||
return HandleToUlong( NtUserRemoveProp( hwnd, str ));
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserBuildHwndList( UINT *args )
|
||||
{
|
||||
HDESK desktop = get_handle( &args );
|
||||
ULONG unk2 = get_ulong( &args );
|
||||
ULONG unk3 = get_ulong( &args );
|
||||
ULONG unk4 = get_ulong( &args );
|
||||
ULONG thread_id = get_ulong( &args );
|
||||
ULONG count = get_ulong( &args );
|
||||
UINT32 *buffer32 = get_ptr( &args );
|
||||
ULONG *size = get_ptr( &args );
|
||||
|
||||
HWND *buffer;
|
||||
ULONG i;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!(buffer = Wow64AllocateTemp( count * sizeof(*buffer) ))) return STATUS_NO_MEMORY;
|
||||
|
||||
if ((status = NtUserBuildHwndList( desktop, unk2, unk3, unk4, thread_id, count, buffer, size )))
|
||||
return status;
|
||||
|
||||
for (i = 0; i < *size; i++)
|
||||
buffer32[i] = HandleToUlong( buffer[i] );
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserGetLayeredWindowAttributes( UINT *args )
|
||||
{
|
||||
HWND hwnd = get_handle( &args );
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
ALL_WIN32_SYSCALLS
|
||||
#undef SYSCALL_ENTRY
|
||||
|
||||
void * WINAPI Wow64AllocateTemp( SIZE_T size );
|
||||
|
||||
struct object_attr64
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
|
|
|
@ -105,6 +105,8 @@ C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo)
|
|||
HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags );
|
||||
BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd );
|
||||
BOOL WINAPI NtUserAttachThreadInput( DWORD from, DWORD to, BOOL attach );
|
||||
NTSTATUS WINAPI NtUserBuildHwndList( HDESK desktop, ULONG unk2, ULONG unk3, ULONG unk4,
|
||||
ULONG thread_id, ULONG count, HWND *buffer, ULONG *size );
|
||||
ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code );
|
||||
ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code );
|
||||
LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd,
|
||||
|
|
Loading…
Reference in New Issue