From 34fe91bf2b038806fcbe0caaa135aaf678e87410 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 18 Mar 2008 15:17:40 +0100 Subject: [PATCH] user32: Implemented EnumDesktopWindows. --- dlls/user32/win.c | 28 ++++++++++++++++++++++++---- dlls/user32/winstation.c | 10 ---------- include/wine/server_protocol.h | 3 ++- server/protocol.def | 1 + server/trace.c | 1 + server/user.h | 1 + server/window.c | 24 ++++++++++++++++-------- server/winstation.c | 3 +-- 8 files changed, 46 insertions(+), 25 deletions(-) diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 6d065bef41..f0de7691fd 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -212,7 +212,7 @@ static WND *free_window_handle( HWND hwnd ) * Build an array of the children of a given window. The array must be * freed with HeapFree. Returns NULL when no windows are found. */ -static HWND *list_window_children( HWND hwnd, LPCWSTR class, DWORD tid ) +static HWND *list_window_children( HDESK desktop, HWND hwnd, LPCWSTR class, DWORD tid ) { HWND *list; int size = 32; @@ -225,6 +225,7 @@ static HWND *list_window_children( HWND hwnd, LPCWSTR class, DWORD tid ) SERVER_START_REQ( get_window_children ) { + req->desktop = desktop; req->parent = hwnd; req->tid = tid; if (!(req->atom = get_int_atom_value( class )) && class) @@ -1522,7 +1523,7 @@ HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR t if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return 0; } - if (!(list = list_window_children( parent, className, 0 ))) goto done; + if (!(list = list_window_children( 0, parent, className, 0 ))) goto done; if (child) { @@ -2862,7 +2863,7 @@ HWND WINAPI GetLastActivePopup( HWND hwnd ) */ HWND *WIN_ListChildren( HWND hwnd ) { - return list_window_children( hwnd, NULL, 0 ); + return list_window_children( 0, hwnd, NULL, 0 ); } @@ -2906,7 +2907,7 @@ BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam ) USER_CheckNotLock(); - if (!(list = list_window_children( GetDesktopWindow(), NULL, id ))) return TRUE; + if (!(list = list_window_children( 0, GetDesktopWindow(), NULL, id ))) return TRUE; /* Now call the callback function for every window */ @@ -2917,6 +2918,25 @@ BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam ) } +/*********************************************************************** + * EnumDesktopWindows (USER32.@) + */ +BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam ) +{ + HWND *list; + int i; + + USER_CheckNotLock(); + + if (!(list = list_window_children( desktop, 0, NULL, 0 ))) return TRUE; + + for (i = 0; list[i]; i++) + if (!func( list[i], lparam )) break; + HeapFree( GetProcessHeap(), 0, list ); + return TRUE; +} + + /********************************************************************** * WIN_EnumChildWindows * diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index 906f2ba5cf..d836471546 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -454,16 +454,6 @@ HDESK WINAPI OpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access ) } -/*********************************************************************** - * EnumDesktopWindows (USER32.@) - */ -BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam ) -{ - FIXME( "(%p,%p,0x%lx): stub!\n", desktop, func, lparam ); - return TRUE; -} - - /*********************************************************************** * GetUserObjectInformationA (USER32.@) */ diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index a659d82d1d..eab9f9ce0f 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2901,6 +2901,7 @@ struct get_window_parents_reply struct get_window_children_request { struct request_header __header; + obj_handle_t desktop; user_handle_t parent; atom_t atom; thread_id_t tid; @@ -4994,6 +4995,6 @@ union generic_reply struct add_fd_completion_reply add_fd_completion_reply; }; -#define SERVER_PROTOCOL_VERSION 337 +#define SERVER_PROTOCOL_VERSION 338 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index ff8bf52e21..23aaed5af1 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2139,6 +2139,7 @@ enum message_type /* Get a list of the window children */ @REQ(get_window_children) + obj_handle_t desktop; /* handle to desktop */ user_handle_t parent; /* parent window */ atom_t atom; /* class atom for the listed children */ thread_id_t tid; /* thread owning the listed children */ diff --git a/server/trace.c b/server/trace.c index 61d0238d01..aa3293e702 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2656,6 +2656,7 @@ static void dump_get_window_parents_reply( const struct get_window_parents_reply static void dump_get_window_children_request( const struct get_window_children_request *req ) { + fprintf( stderr, " desktop=%p,", req->desktop ); fprintf( stderr, " parent=%p,", req->parent ); fprintf( stderr, " atom=%04x,", req->atom ); fprintf( stderr, " tid=%04x,", req->tid ); diff --git a/server/user.h b/server/user.h index 946b57864c..f58f4d4231 100644 --- a/server/user.h +++ b/server/user.h @@ -150,6 +150,7 @@ extern void *get_class_client_ptr( struct window_class *class ); /* windows station functions */ +extern struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access ); extern struct winstation *get_process_winstation( struct process *process, unsigned int access ); extern struct desktop *get_thread_desktop( struct thread *thread, unsigned int access ); extern void connect_process_winstation( struct process *process, struct thread *parent ); diff --git a/server/window.c b/server/window.c index e0c202edeb..e10f9a7ae5 100644 --- a/server/window.c +++ b/server/window.c @@ -1804,26 +1804,34 @@ DECL_HANDLER(get_window_parents) /* get a list of the window children */ DECL_HANDLER(get_window_children) { - struct window *ptr, *parent = get_window( req->parent ); + struct window *ptr, *parent; int total = 0; user_handle_t *data; data_size_t len; atom_t atom = req->atom; + if (req->desktop) + { + struct desktop *desktop = get_desktop_obj( current->process, req->desktop, DESKTOP_ENUMERATE ); + if (!desktop) return; + parent = desktop->top_window; + release_object( desktop ); + } + else parent = get_window( req->parent ); + + if (!parent) return; + if (get_req_data_size()) { atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) ); if (!atom) return; } - if (parent) + LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) { - LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) - { - if (atom && get_class_atom(ptr->class) != atom) continue; - if (req->tid && get_thread_id(ptr->thread) != req->tid) continue; - total++; - } + if (atom && get_class_atom(ptr->class) != atom) continue; + if (req->tid && get_thread_id(ptr->thread) != req->tid) continue; + total++; } reply->count = total; len = min( get_reply_max_size(), total * sizeof(user_handle_t) ); diff --git a/server/winstation.c b/server/winstation.c index 9ad65f0fd2..ee78ba71fc 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -203,8 +203,7 @@ static WCHAR *build_desktop_name( const struct unicode_str *name, } /* retrieve a pointer to a desktop object */ -static inline struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, - unsigned int access ) +struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access ) { return (struct desktop *)get_handle_obj( process, handle, access, &desktop_ops ); } -- 2.33.8