Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
70a6495a
Commit
70a6495a
authored
Apr 01, 2008
by
Maarten Lankhorst
Committed by
Alexandre Julliard
Apr 03, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Implement BroadcastSystemMessage.
parent
f54570fd
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
530 additions
and
27 deletions
+530
-27
message.c
dlls/user32/message.c
+155
-19
Makefile.in
dlls/user32/tests/Makefile.in
+1
-0
broadcast.c
dlls/user32/tests/broadcast.c
+348
-0
user32.spec
dlls/user32/user32.spec
+2
-2
win.h
dlls/user32/win.h
+1
-0
winstation.c
dlls/user32/winstation.c
+11
-4
server_protocol.h
include/wine/server_protocol.h
+2
-1
protocol.def
server/protocol.def
+1
-0
trace.c
server/trace.c
+1
-0
winstation.c
server/winstation.c
+8
-1
No files found.
dlls/user32/message.c
View file @
70a6495a
...
...
@@ -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
);
ret
urn
-
1
;
EnumWindows
(
bcast_childwindow
,
(
LONG_PTR
)
&
parm
);
ret
=
parm
.
success
;
}
}
else
FIXME
(
"Recipients %08x not supported!
\n
"
,
*
recipients
);
return
ret
;
}
/***********************************************************************
* SetMessageQueue (USER32.@)
...
...
dlls/user32/tests/Makefile.in
View file @
70a6495a
...
...
@@ -6,6 +6,7 @@ TESTDLL = user32.dll
IMPORTS
=
user32 gdi32 advapi32 kernel32
CTESTS
=
\
broadcast.c
\
class.c
\
clipboard.c
\
combo.c
\
...
...
dlls/user32/tests/broadcast.c
0 → 100644
View file @
70a6495a
/*
* Unit tests for BroadcastSystemMessage
*
* 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
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#define _WIN32_WINNT 0x0501
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/test.h"
typedef
LONG
WINAPI
(
*
PBROADCAST
)(
DWORD
,
LPDWORD
,
UINT
,
WPARAM
,
LPARAM
);
typedef
LONG
WINAPI
(
*
PBROADCASTEX
)(
DWORD
,
LPDWORD
,
UINT
,
WPARAM
,
LPARAM
,
PBSMINFO
);
static
PBROADCAST
pBroadcastA
;
static
PBROADCAST
pBroadcastW
;
static
PBROADCASTEX
pBroadcastExA
;
static
PBROADCASTEX
pBroadcastExW
;
static
HANDLE
hevent
;
static
LRESULT
WINAPI
main_window_procA
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
if
(
msg
==
WM_NULL
)
{
trace
(
"main_window_procA: Sleeping for %lu ms
\n
"
,
wparam
);
if
(
wparam
)
{
if
(
WaitForSingleObject
(
hevent
,
wparam
)
==
WAIT_TIMEOUT
)
SetEvent
(
hevent
);
}
trace
(
"main_window_procA: Returning WM_NULL with parameter %08lx
\n
"
,
lparam
);
return
lparam
;
}
return
DefWindowProcA
(
hwnd
,
msg
,
wparam
,
lparam
);
}
static
BOOL
init_procs
(
void
)
{
WNDCLASSA
cls
;
HANDLE
user32
=
GetModuleHandle
(
"user32"
);
pBroadcastA
=
(
PBROADCAST
)
GetProcAddress
(
user32
,
"BroadcastSystemMessageA"
);
if
(
!
pBroadcastA
)
pBroadcastA
=
(
PBROADCAST
)
GetProcAddress
(
user32
,
"BroadcastSystemMessage"
);
ok
(
pBroadcastA
!=
NULL
,
"No BroadcastSystemMessage found
\n
"
);
if
(
!
pBroadcastA
)
return
FALSE
;
pBroadcastW
=
(
PBROADCAST
)
GetProcAddress
(
user32
,
"BroadcastSystemMessageW"
);
pBroadcastExA
=
(
PBROADCASTEX
)
GetProcAddress
(
user32
,
"BroadcastSystemMessageExA"
);
pBroadcastExW
=
(
PBROADCASTEX
)
GetProcAddress
(
user32
,
"BroadcastSystemMessageExW"
);
hevent
=
CreateEventA
(
NULL
,
TRUE
,
FALSE
,
"Asynchronous checking event"
);
cls
.
style
=
CS_DBLCLKS
;
cls
.
lpfnWndProc
=
main_window_procA
;
cls
.
cbClsExtra
=
0
;
cls
.
cbWndExtra
=
0
;
cls
.
hInstance
=
GetModuleHandleA
(
0
);
cls
.
hIcon
=
0
;
cls
.
hCursor
=
LoadCursorA
(
0
,
(
LPSTR
)
IDC_ARROW
);
cls
.
hbrBackground
=
GetStockObject
(
WHITE_BRUSH
);
cls
.
lpszMenuName
=
NULL
;
cls
.
lpszClassName
=
"MainWindowClass"
;
if
(
!
RegisterClassA
(
&
cls
))
return
0
;
if
(
!
CreateWindowExA
(
0
,
"MainWindowClass"
,
"Main window"
,
WS_CAPTION
|
WS_SYSMENU
|
WS_MINIMIZEBOX
|
WS_MAXIMIZEBOX
|
WS_POPUP
,
100
,
100
,
200
,
200
,
0
,
0
,
GetModuleHandle
(
0
),
NULL
))
return
FALSE
;
return
TRUE
;
}
static
void
test_parameters
(
PBROADCAST
broadcast
)
{
LONG
ret
;
DWORD
recips
;
SetLastError
(
0xcafebabe
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcast
(
0x80000000
,
&
recips
,
WM_NULL
,
0
,
0
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
!
ret
,
"Returned: %d
\n
"
,
ret
);
SetLastError
(
0xcafebabe
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcast
(
0x80000000
,
&
recips
,
WM_NULL
,
0
,
0
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
!
ret
,
"Returned: %d
\n
"
,
ret
);
#if 0 /* TODO: Check the hang flags */
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
#endif
recips
=
BSM_APPLICATIONS
;
ResetEvent
(
hevent
);
ret
=
broadcast
(
BSF_POSTMESSAGE
|
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
0
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcast
(
BSF_POSTMESSAGE
|
BSF_SENDNOTIFYMESSAGE
,
&
recips
,
WM_NULL
,
100
,
0
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_OBJECT_0
,
"Synchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcast
(
BSF_SENDNOTIFYMESSAGE
,
&
recips
,
WM_NULL
,
100
,
BROADCAST_QUERY_DENY
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcast
(
BSF_SENDNOTIFYMESSAGE
|
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
BROADCAST_QUERY_DENY
);
ok
(
!
ret
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcast
(
0
,
&
recips
,
WM_NULL
,
100
,
0
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
}
/* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process
* However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag
*/
static
void
test_parametersEx
(
PBROADCASTEX
broadcastex
)
{
LONG
ret
;
DWORD
recips
;
SetLastError
(
0xcafebabe
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcastex
(
0x80000000
,
&
recips
,
WM_NULL
,
0
,
0
,
NULL
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
!
ret
,
"Returned: %d
\n
"
,
ret
);
SetLastError
(
0xcafebabe
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcastex
(
0x80000000
,
&
recips
,
WM_NULL
,
0
,
0
,
NULL
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
!
ret
,
"Returned: %d
\n
"
,
ret
);
#if 0 /* TODO: Check the hang flags */
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0, NULL );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS;
ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
ok(0, "Last error: %08x\n", GetLastError());
ok(0, "Returned: %d\n", ret);
#endif
recips
=
BSM_APPLICATIONS
;
ResetEvent
(
hevent
);
ret
=
broadcastex
(
BSF_POSTMESSAGE
|
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
0
,
NULL
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcastex
(
BSF_POSTMESSAGE
|
BSF_SENDNOTIFYMESSAGE
,
&
recips
,
WM_NULL
,
100
,
0
,
NULL
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_OBJECT_0
,
"Synchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcastex
(
BSF_SENDNOTIFYMESSAGE
,
&
recips
,
WM_NULL
,
100
,
BROADCAST_QUERY_DENY
,
NULL
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcastex
(
BSF_SENDNOTIFYMESSAGE
|
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
BROADCAST_QUERY_DENY
,
NULL
);
ok
(
!
ret
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
recips
=
BSM_APPLICATIONS
;
ret
=
broadcastex
(
0
,
&
recips
,
WM_NULL
,
100
,
0
,
NULL
);
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
PulseEvent
(
hevent
);
}
static
BOOL
WINAPI
(
*
pOpenProcessToken
)(
HANDLE
,
DWORD
,
HANDLE
*
);
static
BOOL
WINAPI
(
*
pAdjustTokenPrivileges
)(
HANDLE
,
BOOL
,
PTOKEN_PRIVILEGES
,
DWORD
,
PTOKEN_PRIVILEGES
,
PDWORD
);
static
void
test_noprivileges
(
void
)
{
HANDLE
advapi32
=
GetModuleHandleA
(
"advapi32"
);
HANDLE
token
;
DWORD
recips
;
BOOL
ret
;
pOpenProcessToken
=
(
void
*
)
GetProcAddress
(
advapi32
,
"OpenProcessToken"
);
pAdjustTokenPrivileges
=
(
void
*
)
GetProcAddress
(
advapi32
,
"AdjustTokenPrivileges"
);
if
(
!
pOpenProcessToken
||
!
pAdjustTokenPrivileges
||
!
pOpenProcessToken
(
GetCurrentProcess
(),
TOKEN_ADJUST_PRIVILEGES
,
&
token
))
{
skip
(
"Can't open security token for process
\n
"
);
return
;
}
if
(
!
pAdjustTokenPrivileges
(
token
,
TRUE
,
NULL
,
0
,
NULL
,
NULL
))
{
skip
(
"Can't adjust security token for process
\n
"
);
return
;
}
trace
(
"Trying privileged edition!
\n
"
);
SetLastError
(
0xcafebabe
);
recips
=
BSM_ALLDESKTOPS
;
ResetEvent
(
hevent
);
ret
=
pBroadcastExW
(
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
0
,
NULL
);
todo_wine
ok
(
GetLastError
()
==
ERROR_PRIVILEGE_NOT_HELD
,
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
ok
(
recips
==
BSM_ALLDESKTOPS
,
"Received by: %08x
\n
"
,
recips
);
PulseEvent
(
hevent
);
/* Wine sets last error to 0, so just use that one as token here so it doesn't fail */
SetLastError
(
0
);
recips
=
BSM_ALLCOMPONENTS
;
ResetEvent
(
hevent
);
ret
=
pBroadcastExW
(
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
0
,
NULL
);
ok
(
!
GetLastError
(),
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
ok
(
recips
==
BSM_ALLCOMPONENTS
,
"Received by: %08x
\n
"
,
recips
);
PulseEvent
(
hevent
);
SetLastError
(
0xcafebabe
);
recips
=
BSM_ALLDESKTOPS
|
BSM_APPLICATIONS
;
ResetEvent
(
hevent
);
ret
=
pBroadcastExW
(
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
0
,
NULL
);
todo_wine
ok
(
GetLastError
()
==
ERROR_PRIVILEGE_NOT_HELD
,
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
ret
==
1
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
ok
(
recips
==
(
BSM_ALLDESKTOPS
|
BSM_APPLICATIONS
),
"Received by: %08x
\n
"
,
recips
);
PulseEvent
(
hevent
);
SetLastError
(
0xcafebabe
);
recips
=
BSM_ALLDESKTOPS
|
BSM_APPLICATIONS
;
ResetEvent
(
hevent
);
ret
=
pBroadcastExW
(
BSF_QUERY
,
&
recips
,
WM_NULL
,
100
,
BROADCAST_QUERY_DENY
,
NULL
);
todo_wine
ok
(
GetLastError
()
==
ERROR_PRIVILEGE_NOT_HELD
,
"Last error: %08x
\n
"
,
GetLastError
());
ok
(
!
ret
,
"Returned: %d
\n
"
,
ret
);
ok
(
WaitForSingleObject
(
hevent
,
0
)
!=
WAIT_TIMEOUT
,
"Asynchronous message sent instead
\n
"
);
ok
(
recips
==
(
BSM_ALLDESKTOPS
|
BSM_APPLICATIONS
),
"Received by: %08x
\n
"
,
recips
);
PulseEvent
(
hevent
);
}
START_TEST
(
broadcast
)
{
if
(
!
init_procs
())
return
;
trace
(
"Running BroadcastSystemMessageA tests
\n
"
);
test_parameters
(
pBroadcastA
);
if
(
pBroadcastW
)
{
trace
(
"Running BroadcastSystemMessageW tests
\n
"
);
test_parameters
(
pBroadcastW
);
}
else
skip
(
"No BroadcastSystemMessageW, skipping
\n
"
);
if
(
pBroadcastExA
)
{
trace
(
"Running BroadcastSystemMessageExA tests
\n
"
);
test_parametersEx
(
pBroadcastExA
);
}
else
skip
(
"No BroadcastSystemMessageExA, skipping
\n
"
);
if
(
pBroadcastExW
)
{
trace
(
"Running BroadcastSystemMessageExW tests
\n
"
);
test_parametersEx
(
pBroadcastExW
);
trace
(
"Attempting privileges checking tests
\n
"
);
test_noprivileges
();
}
else
skip
(
"No BroadcastSystemMessageExW, skipping
\n
"
);
}
dlls/user32/user32.spec
View file @
70a6495a
...
...
@@ -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)
...
...
dlls/user32/win.h
View file @
70a6495a
...
...
@@ -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
;
...
...
dlls/user32/winstation.c
View file @
70a6495a
...
...
@@ -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.@)
*/
...
...
include/wine/server_protocol.h
View file @
70a6495a
...
...
@@ -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 33
8
#define SERVER_PROTOCOL_VERSION 33
9
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
70a6495a
...
...
@@ -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 */
...
...
server/trace.c
View file @
70a6495a
...
...
@@ -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
);
...
...
server/winstation.c
View file @
70a6495a
...
...
@@ -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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment