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

user32: Implement BroadcastSystemMessage.

parent f54570fd
......@@ -2,6 +2,7 @@
* Window messaging support
*
* Copyright 2001 Alexandre Julliard
* Copyright 2008 Maarten Lankhorst
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -3343,24 +3344,113 @@ UINT WINAPI RegisterWindowMessageW( LPCWSTR str )
return ret;
}
typedef struct BroadcastParm
{
DWORD flags;
LPDWORD recipients;
UINT msg;
WPARAM wp;
LPARAM lp;
DWORD success;
HWINSTA winsta;
} BroadcastParm;
/***********************************************************************
* BroadcastSystemMessageA (USER32.@)
* BroadcastSystemMessage (USER32.@)
*/
LONG WINAPI BroadcastSystemMessageA( DWORD flags, LPDWORD recipients, UINT msg, WPARAM wp, LPARAM lp )
static BOOL CALLBACK bcast_childwindow( HWND hw, 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 );
PostMessageA( HWND_BROADCAST, msg, wp, lp );
return 1;
TRACE("Telling window %p using PostMessage\n", hw);
PostMessageW( hw, parm->msg, parm->wp, parm->lp );
}
else
{
FIXME( "(%08x,%08x,%08x,%08lx,%08lx): stub!\n", flags, *recipients, msg, wp, lp);
return -1;
TRACE("Telling window %p using SendNotifyMessage\n", hw);
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,
*/
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 );
PostMessageW( HWND_BROADCAST, msg, wp, lp );
return 1;
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
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 );
return -1;
EnumWindows(bcast_childwindow, (LONG_PTR)&parm);
ret = parm.success;
}
}
else
FIXME("Recipients %08x not supported!\n", *recipients);
return ret;
}
/***********************************************************************
* SetMessageQueue (USER32.@)
......
......@@ -6,6 +6,7 @@ TESTDLL = user32.dll
IMPORTS = user32 gdi32 advapi32 kernel32
CTESTS = \
broadcast.c \
class.c \
clipboard.c \
combo.c \
......
......@@ -16,8 +16,8 @@
@ stdcall BringWindowToTop(long)
@ stdcall BroadcastSystemMessage(long ptr long long long) BroadcastSystemMessageA
@ stdcall BroadcastSystemMessageA(long ptr long long long)
# @ stub BroadcastSystemMessageExA
# @ stub BroadcastSystemMessageExW
@ stdcall BroadcastSystemMessageExA(long ptr long long long ptr)
@ stdcall BroadcastSystemMessageExW(long ptr long long long ptr)
@ stdcall BroadcastSystemMessageW(long ptr long long long)
# @ stub BuildReasonArray
@ stdcall CalcChildScroll(long long)
......
......@@ -89,6 +89,7 @@ extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ) 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 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 */
extern void USER_Lock(void) DECLSPEC_HIDDEN;
......
......@@ -317,10 +317,7 @@ HDESK WINAPI OpenDesktopA( LPCSTR name, DWORD flags, BOOL inherit, ACCESS_MASK a
}
/******************************************************************************
* OpenDesktopW (USER32.@)
*/
HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
HDESK open_winstation_desktop( HWINSTA hwinsta, LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access )
{
HANDLE ret = 0;
DWORD len = name ? strlenW(name) : 0;
......@@ -331,6 +328,7 @@ HDESK WINAPI OpenDesktopW( LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK
}
SERVER_START_REQ( open_desktop )
{
req->winsta = hwinsta;
req->flags = flags;
req->access = access;
req->attributes = OBJ_CASE_INSENSITIVE | (inherit ? OBJ_INHERIT : 0);
......@@ -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.@)
*/
......
......@@ -3299,6 +3299,7 @@ struct create_desktop_reply
struct open_desktop_request
{
struct request_header __header;
obj_handle_t winsta;
unsigned int flags;
unsigned int access;
unsigned int attributes;
......@@ -4995,6 +4996,6 @@ union generic_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 */
......@@ -2399,6 +2399,7 @@ enum message_type
/* Open a handle to a desktop */
@REQ(open_desktop)
obj_handle_t winsta; /* window station to open (null allowed) */
unsigned int flags; /* desktop flags */
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
......
......@@ -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 )
{
fprintf( stderr, " winsta=%p,", req->winsta );
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes );
......
......@@ -508,7 +508,14 @@ DECL_HANDLER(open_desktop)
struct 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;
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