Commit 70a6495a authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

user32: Implement BroadcastSystemMessage.

parent f54570fd
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Window messaging support * Window messaging support
* *
* Copyright 2001 Alexandre Julliard * Copyright 2001 Alexandre Julliard
* Copyright 2008 Maarten Lankhorst
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -3343,24 +3344,113 @@ UINT WINAPI RegisterWindowMessageW( LPCWSTR str ) ...@@ -3343,24 +3344,113 @@ UINT WINAPI RegisterWindowMessageW( LPCWSTR str )
return ret; return ret;
} }
typedef struct BroadcastParm
{
DWORD flags;
LPDWORD recipients;
UINT msg;
WPARAM wp;
LPARAM lp;
DWORD success;
HWINSTA winsta;
} BroadcastParm;
/*********************************************************************** static BOOL CALLBACK bcast_childwindow( HWND hw, LPARAM lp )
* BroadcastSystemMessageA (USER32.@)
* BroadcastSystemMessage (USER32.@)
*/
LONG WINAPI BroadcastSystemMessageA( DWORD flags, LPDWORD recipients, UINT msg, WPARAM wp, LPARAM lp )
{ {
if ((*recipients & BSM_APPLICATIONS) || (*recipients == BSM_ALLCOMPONENTS)) BroadcastParm *parm = (BroadcastParm*)lp;
DWORD_PTR retval = 0;
LONG lresult;
if (parm->flags & BSF_IGNORECURRENTTASK && WIN_IsCurrentProcess(hw))
{
TRACE("Not telling myself %p\n", hw);
return TRUE;
}
/* I don't know 100% for sure if this is what Windows does, but it fits the tests */
if (parm->flags & BSF_QUERY)
{
TRACE("Telling window %p using SendMessageTimeout\n", hw);
/* Not tested for conflicting flags */
if (parm->flags & BSF_FORCEIFHUNG || parm->flags & BSF_NOHANG)
lresult = SendMessageTimeoutW( hw, parm->msg, parm->wp, parm->lp, SMTO_ABORTIFHUNG, 2000, &retval );
else if (parm->flags & BSF_NOTIMEOUTIFNOTHUNG)
lresult = SendMessageTimeoutW( hw, parm->msg, parm->wp, parm->lp, SMTO_NOTIMEOUTIFNOTHUNG, 2000, &retval );
else
lresult = SendMessageTimeoutW( hw, parm->msg, parm->wp, parm->lp, SMTO_NORMAL, 2000, &retval );
if (!lresult && GetLastError() == ERROR_TIMEOUT)
{
WARN("Timed out!\n");
if (!(parm->flags & BSF_FORCEIFHUNG))
goto fail;
}
if (retval == BROADCAST_QUERY_DENY)
goto fail;
return TRUE;
fail:
parm->success = 0;
return FALSE;
}
else if (parm->flags & BSF_POSTMESSAGE)
{ {
FIXME( "(%08x,%08x,%08x,%08lx,%08lx): semi-stub!\n", flags, *recipients, msg, wp, lp ); TRACE("Telling window %p using PostMessage\n", hw);
PostMessageA( HWND_BROADCAST, msg, wp, lp ); PostMessageW( hw, parm->msg, parm->wp, parm->lp );
return 1;
} }
else else
{ {
FIXME( "(%08x,%08x,%08x,%08lx,%08lx): stub!\n", flags, *recipients, msg, wp, lp); TRACE("Telling window %p using SendNotifyMessage\n", hw);
return -1; SendNotifyMessageW( hw, parm->msg, parm->wp, parm->lp );
} }
return TRUE;
}
static BOOL CALLBACK bcast_desktop( LPWSTR desktop, LPARAM lp )
{
BOOL ret;
HDESK hdesktop;
BroadcastParm *parm = (BroadcastParm*)lp;
TRACE("desktop: %s\n", debugstr_w( desktop ));
hdesktop = open_winstation_desktop( parm->winsta, desktop, 0, FALSE, DESKTOP_ENUMERATE|DESKTOP_WRITEOBJECTS|STANDARD_RIGHTS_WRITE );
if (!hdesktop)
{
FIXME("Could not open desktop %s\n", debugstr_w(desktop));
return TRUE;
}
ret = EnumDesktopWindows( hdesktop, bcast_childwindow, lp );
CloseDesktop(hdesktop);
TRACE("-->%d\n", ret);
return parm->success;
}
static BOOL CALLBACK bcast_winsta( LPWSTR winsta, LPARAM lp )
{
BOOL ret;
HWINSTA hwinsta = OpenWindowStationW( winsta, FALSE, WINSTA_ENUMDESKTOPS );
TRACE("hwinsta: %p/%s/%08x\n", hwinsta, debugstr_w( winsta ), GetLastError());
if (!hwinsta)
return TRUE;
((BroadcastParm *)lp)->winsta = hwinsta;
ret = EnumDesktopsW( hwinsta, bcast_desktop, lp );
CloseWindowStation( hwinsta );
TRACE("-->%d\n", ret);
return ret;
}
/***********************************************************************
* BroadcastSystemMessageA (USER32.@)
* BroadcastSystemMessage (USER32.@)
*/
LONG WINAPI BroadcastSystemMessageA( DWORD flags, LPDWORD recipients, UINT msg, WPARAM wp, LPARAM lp )
{
return BroadcastSystemMessageExA( flags, recipients, msg, wp, lp, NULL );
} }
...@@ -3369,19 +3459,65 @@ LONG WINAPI BroadcastSystemMessageA( DWORD flags, LPDWORD recipients, UINT msg, ...@@ -3369,19 +3459,65 @@ LONG WINAPI BroadcastSystemMessageA( DWORD flags, LPDWORD recipients, UINT msg,
*/ */
LONG WINAPI BroadcastSystemMessageW( DWORD flags, LPDWORD recipients, UINT msg, WPARAM wp, LPARAM lp ) LONG WINAPI BroadcastSystemMessageW( DWORD flags, LPDWORD recipients, UINT msg, WPARAM wp, LPARAM lp )
{ {
if ((*recipients & BSM_APPLICATIONS) || (*recipients == BSM_ALLCOMPONENTS)) return BroadcastSystemMessageExW( flags, recipients, msg, wp, lp, NULL );
}
/***********************************************************************
* BroadcastSystemMessageExA (USER32.@)
*/
LONG WINAPI BroadcastSystemMessageExA( DWORD flags, LPDWORD recipients, UINT msg, WPARAM wp, LPARAM lp, PBSMINFO pinfo )
{
map_wparam_AtoW( msg, &wp, WMCHAR_MAP_NOMAPPING );
return BroadcastSystemMessageExW( flags, recipients, msg, wp, lp, NULL );
}
/***********************************************************************
* BroadcastSystemMessageExW (USER32.@)
*/
LONG WINAPI BroadcastSystemMessageExW( DWORD flags, LPDWORD recipients, UINT msg, WPARAM wp, LPARAM lp, PBSMINFO pinfo )
{
BroadcastParm parm;
DWORD recips = BSM_ALLCOMPONENTS;
BOOL ret = TRUE;
static const DWORD all_flags = ( BSF_QUERY | BSF_IGNORECURRENTTASK | BSF_FLUSHDISK | BSF_NOHANG
| BSF_POSTMESSAGE | BSF_FORCEIFHUNG | BSF_NOTIMEOUTIFNOTHUNG
| BSF_ALLOWSFW | BSF_SENDNOTIFYMESSAGE | BSF_RETURNHDESK | BSF_LUID );
TRACE("Flags: %08x, recipients: %p(0x%x), msg: %04x, wparam: %08lx, lparam: %08lx\n", flags, recipients,
(recipients ? *recipients : recips), msg, wp, lp);
if (flags & ~all_flags)
{ {
FIXME( "(%08x,%08x,%08x,%08lx,%08lx): semi-stub!\n", flags, *recipients, msg, wp, lp ); SetLastError(ERROR_INVALID_PARAMETER);
PostMessageW( HWND_BROADCAST, msg, wp, lp ); return 0;
return 1;
} }
else
if (!recipients)
recipients = &recips;
if ( pinfo && flags & BSF_QUERY )
FIXME("Not returning PBSMINFO information yet\n");
parm.flags = flags;
parm.recipients = recipients;
parm.msg = msg;
parm.wp = wp;
parm.lp = lp;
parm.success = TRUE;
if (*recipients & BSM_ALLDESKTOPS || *recipients == BSM_ALLCOMPONENTS)
ret = EnumWindowStationsW(bcast_winsta, (LONG_PTR)&parm);
else if (*recipients & BSM_APPLICATIONS)
{ {
FIXME( "(%08x,%08x,%08x,%08lx,%08lx): stub!\n", flags, *recipients, msg, wp, lp ); EnumWindows(bcast_childwindow, (LONG_PTR)&parm);
return -1; ret = parm.success;
} }
} else
FIXME("Recipients %08x not supported!\n", *recipients);
return ret;
}
/*********************************************************************** /***********************************************************************
* SetMessageQueue (USER32.@) * SetMessageQueue (USER32.@)
......
...@@ -6,6 +6,7 @@ TESTDLL = user32.dll ...@@ -6,6 +6,7 @@ TESTDLL = user32.dll
IMPORTS = user32 gdi32 advapi32 kernel32 IMPORTS = user32 gdi32 advapi32 kernel32
CTESTS = \ CTESTS = \
broadcast.c \
class.c \ class.c \
clipboard.c \ clipboard.c \
combo.c \ combo.c \
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
@ stdcall BringWindowToTop(long) @ stdcall BringWindowToTop(long)
@ stdcall BroadcastSystemMessage(long ptr long long long) BroadcastSystemMessageA @ stdcall BroadcastSystemMessage(long ptr long long long) BroadcastSystemMessageA
@ stdcall BroadcastSystemMessageA(long ptr long long long) @ stdcall BroadcastSystemMessageA(long ptr long long long)
# @ stub BroadcastSystemMessageExA @ stdcall BroadcastSystemMessageExA(long ptr long long long ptr)
# @ stub BroadcastSystemMessageExW @ stdcall BroadcastSystemMessageExW(long ptr long long long ptr)
@ stdcall BroadcastSystemMessageW(long ptr long long long) @ stdcall BroadcastSystemMessageW(long ptr long long long)
# @ stub BuildReasonArray # @ stub BuildReasonArray
@ stdcall CalcChildScroll(long long) @ stdcall CalcChildScroll(long long)
......
...@@ -89,6 +89,7 @@ extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ) DECLSPEC_HIDDEN; ...@@ -89,6 +89,7 @@ extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ) DECLSPEC_HIDDEN;
extern HWND *WIN_ListChildren( HWND hwnd ) DECLSPEC_HIDDEN; extern HWND *WIN_ListChildren( HWND hwnd ) DECLSPEC_HIDDEN;
extern LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOOL unicode ) DECLSPEC_HIDDEN; extern LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOOL unicode ) DECLSPEC_HIDDEN;
extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id ) DECLSPEC_HIDDEN; extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id ) DECLSPEC_HIDDEN;
extern HDESK open_winstation_desktop( HWINSTA hwinsta, LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access ) DECLSPEC_HIDDEN;
/* user lock */ /* user lock */
extern void USER_Lock(void) DECLSPEC_HIDDEN; extern void USER_Lock(void) DECLSPEC_HIDDEN;
......
...@@ -317,10 +317,7 @@ HDESK WINAPI OpenDesktopA( LPCSTR name, DWORD flags, BOOL inherit, ACCESS_MASK a ...@@ -317,10 +317,7 @@ HDESK WINAPI OpenDesktopA( LPCSTR name, DWORD flags, BOOL inherit, ACCESS_MASK a
} }
/****************************************************************************** HDESK open_winstation_desktop( HWINSTA hwinsta, LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
* OpenDesktopW (USER32.@)
*/
HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
{ {
HANDLE ret = 0; HANDLE ret = 0;
DWORD len = name ? strlenW(name) : 0; DWORD len = name ? strlenW(name) : 0;
...@@ -331,6 +328,7 @@ HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK ...@@ -331,6 +328,7 @@ HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK
} }
SERVER_START_REQ( open_desktop ) SERVER_START_REQ( open_desktop )
{ {
req->winsta = hwinsta;
req->flags = flags; req->flags = flags;
req->access = access; req->access = access;
req->attributes = OBJ_CASE_INSENSITIVE | (inherit ? OBJ_INHERIT : 0); req->attributes = OBJ_CASE_INSENSITIVE | (inherit ? OBJ_INHERIT : 0);
...@@ -342,6 +340,15 @@ HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK ...@@ -342,6 +340,15 @@ HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK
} }
/******************************************************************************
* OpenDesktopW (USER32.@)
*/
HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
{
return open_winstation_desktop( NULL, name, flags, inherit, access );
}
/*********************************************************************** /***********************************************************************
* CloseDesktop (USER32.@) * CloseDesktop (USER32.@)
*/ */
......
...@@ -3299,6 +3299,7 @@ struct create_desktop_reply ...@@ -3299,6 +3299,7 @@ struct create_desktop_reply
struct open_desktop_request struct open_desktop_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t winsta;
unsigned int flags; unsigned int flags;
unsigned int access; unsigned int access;
unsigned int attributes; unsigned int attributes;
...@@ -4995,6 +4996,6 @@ union generic_reply ...@@ -4995,6 +4996,6 @@ union generic_reply
struct add_fd_completion_reply add_fd_completion_reply; struct add_fd_completion_reply add_fd_completion_reply;
}; };
#define SERVER_PROTOCOL_VERSION 338 #define SERVER_PROTOCOL_VERSION 339
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -2399,6 +2399,7 @@ enum message_type ...@@ -2399,6 +2399,7 @@ enum message_type
/* Open a handle to a desktop */ /* Open a handle to a desktop */
@REQ(open_desktop) @REQ(open_desktop)
obj_handle_t winsta; /* window station to open (null allowed) */
unsigned int flags; /* desktop flags */ unsigned int flags; /* desktop flags */
unsigned int access; /* wanted access rights */ unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */ unsigned int attributes; /* object attributes */
......
...@@ -2972,6 +2972,7 @@ static void dump_create_desktop_reply( const struct create_desktop_reply *req ) ...@@ -2972,6 +2972,7 @@ static void dump_create_desktop_reply( const struct create_desktop_reply *req )
static void dump_open_desktop_request( const struct open_desktop_request *req ) static void dump_open_desktop_request( const struct open_desktop_request *req )
{ {
fprintf( stderr, " winsta=%p,", req->winsta );
fprintf( stderr, " flags=%08x,", req->flags ); fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes ); fprintf( stderr, " attributes=%08x,", req->attributes );
......
...@@ -508,7 +508,14 @@ DECL_HANDLER(open_desktop) ...@@ -508,7 +508,14 @@ DECL_HANDLER(open_desktop)
struct unicode_str name; struct unicode_str name;
get_req_unicode_str( &name ); get_req_unicode_str( &name );
if ((winstation = get_process_winstation( current->process, 0 /* FIXME: access rights? */ )))
/* FIXME: check access rights */
if (!req->winsta)
winstation = get_process_winstation( current->process, 0 );
else
winstation = (struct winstation *)get_handle_obj( current->process, req->winsta, 0, &winstation_ops );
if (winstation)
{ {
struct unicode_str full_str; struct unicode_str full_str;
WCHAR *full_name; WCHAR *full_name;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment