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
92fec7b6
Commit
92fec7b6
authored
Jun 28, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Keep track of the windows and hooks used by a thread to properly
refuse to change the thread desktop when it's in use.
parent
52736b47
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
53 additions
and
12 deletions
+53
-12
winstation.c
dlls/user/tests/winstation.c
+3
-6
hook.c
server/hook.c
+7
-1
thread.c
server/thread.c
+1
-0
thread.h
server/thread.h
+1
-0
window.c
server/window.c
+4
-0
winstation.c
server/winstation.c
+37
-5
No files found.
dlls/user/tests/winstation.c
View file @
92fec7b6
...
...
@@ -64,12 +64,9 @@ static DWORD CALLBACK thread( LPVOID arg )
trace
(
"created desktop %p
\n
"
,
d2
);
ok
(
d2
!=
0
,
"CreateDesktop failed
\n
"
);
todo_wine
{
SetLastError
(
0xdeadbeef
);
ok
(
!
SetThreadDesktop
(
d2
),
"set thread desktop succeeded with existing window
\n
"
);
ok
(
GetLastError
()
==
ERROR_BUSY
,
"bad last error %ld
\n
"
,
GetLastError
()
);
}
SetLastError
(
0xdeadbeef
);
ok
(
!
SetThreadDesktop
(
d2
),
"set thread desktop succeeded with existing window
\n
"
);
ok
(
GetLastError
()
==
ERROR_BUSY
,
"bad last error %ld
\n
"
,
GetLastError
()
);
DestroyWindow
(
hwnd
);
ok
(
SetThreadDesktop
(
d2
),
"set thread desktop failed
\n
"
);
...
...
server/hook.c
View file @
92fec7b6
...
...
@@ -125,6 +125,7 @@ static struct hook *add_hook( struct thread *thread, int index, int global )
hook
->
thread
=
thread
?
(
struct
thread
*
)
grab_object
(
thread
)
:
NULL
;
hook
->
index
=
index
;
list_add_head
(
&
table
->
hooks
[
index
],
&
hook
->
chain
);
if
(
thread
)
thread
->
desktop_users
++
;
return
hook
;
}
...
...
@@ -133,7 +134,12 @@ static void free_hook( struct hook *hook )
{
free_user_handle
(
hook
->
handle
);
if
(
hook
->
module
)
free
(
hook
->
module
);
if
(
hook
->
thread
)
release_object
(
hook
->
thread
);
if
(
hook
->
thread
)
{
assert
(
hook
->
thread
->
desktop_users
>
0
);
hook
->
thread
->
desktop_users
--
;
release_object
(
hook
->
thread
);
}
if
(
hook
->
process
)
release_object
(
hook
->
process
);
release_object
(
hook
->
owner
);
list_remove
(
&
hook
->
chain
);
...
...
server/thread.c
View file @
92fec7b6
...
...
@@ -140,6 +140,7 @@ inline static void init_thread_structure( struct thread *thread )
thread
->
suspend
=
0
;
thread
->
creation_time
=
time
(
NULL
);
thread
->
exit_time
=
0
;
thread
->
desktop_users
=
0
;
list_init
(
&
thread
->
mutex_list
);
list_init
(
&
thread
->
system_apc
);
...
...
server/thread.h
View file @
92fec7b6
...
...
@@ -83,6 +83,7 @@ struct thread
int
affinity
;
/* affinity mask */
int
suspend
;
/* suspend count */
obj_handle_t
desktop
;
/* desktop handle */
int
desktop_users
;
/* number of objects using the thread desktop */
time_t
creation_time
;
/* Thread creation time */
time_t
exit_time
;
/* Thread exit time */
struct
token
*
token
;
/* security token associated with this thread */
...
...
server/window.c
View file @
92fec7b6
...
...
@@ -311,6 +311,8 @@ static void destroy_window( struct window *win )
if
(
win
==
shell_listview
)
shell_listview
=
NULL
;
if
(
win
==
progman_window
)
progman_window
=
NULL
;
if
(
win
==
taskman_window
)
taskman_window
=
NULL
;
assert
(
win
->
thread
->
desktop_users
>
0
);
win
->
thread
->
desktop_users
--
;
free_user_handle
(
win
->
handle
);
destroy_properties
(
win
);
list_remove
(
&
win
->
entry
);
...
...
@@ -376,6 +378,7 @@ static struct window *create_window( struct window *parent, struct window *owner
/* put it on parent unlinked list */
if
(
parent
)
list_add_head
(
&
parent
->
unlinked
,
&
win
->
entry
);
current
->
desktop_users
++
;
return
win
;
failed:
...
...
@@ -1303,6 +1306,7 @@ DECL_HANDLER(create_window)
if
(
!
top_window
)
{
if
(
!
(
top_window
=
create_window
(
NULL
,
NULL
,
req
->
atom
,
req
->
instance
)))
return
;
current
->
desktop_users
--
;
top_window
->
thread
=
NULL
;
/* no thread owns the desktop */
top_window
->
style
=
WS_POPUP
|
WS_VISIBLE
|
WS_CLIPSIBLINGS
|
WS_CLIPCHILDREN
;
}
...
...
server/winstation.c
View file @
92fec7b6
...
...
@@ -175,6 +175,13 @@ static WCHAR *build_desktop_name( const WCHAR *name, size_t len,
return
full_name
;
}
/* retrieve a pointer to a desktop object */
inline
static
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
);
}
/* create a desktop object */
static
struct
desktop
*
create_desktop
(
const
WCHAR
*
name
,
size_t
len
,
unsigned
int
flags
,
struct
winstation
*
winstation
)
...
...
@@ -426,14 +433,39 @@ DECL_HANDLER(get_thread_desktop)
/* set the thread current desktop */
DECL_HANDLER
(
set_thread_desktop
)
{
struct
desktop
*
desktop
;
struct
desktop
*
old_desktop
,
*
new_desktop
;
struct
winstation
*
winstation
;
if
((
desktop
=
(
struct
desktop
*
)
get_handle_obj
(
current
->
process
,
req
->
handle
,
0
,
&
desktop_ops
)))
if
(
!
(
winstation
=
get_process_winstation
(
current
->
process
,
0
/* FIXME: access rights? */
)))
return
;
if
(
!
(
new_desktop
=
get_desktop_obj
(
current
->
process
,
req
->
handle
,
0
)))
{
/* FIXME: should we close the old one? */
current
->
desktop
=
req
->
handle
;
release_object
(
desktop
);
release_object
(
winstation
);
return
;
}
if
(
new_desktop
->
winstation
!=
winstation
)
{
set_error
(
STATUS_ACCESS_DENIED
);
release_object
(
new_desktop
);
release_object
(
winstation
);
return
;
}
/* check if we are changing to a new desktop */
if
(
!
(
old_desktop
=
get_desktop_obj
(
current
->
process
,
current
->
desktop
,
0
)))
clear_error
();
/* ignore error */
/* when changing desktop, we can't have any users on the current one */
if
(
old_desktop
!=
new_desktop
&&
current
->
desktop_users
>
0
)
set_error
(
STATUS_DEVICE_BUSY
);
else
current
->
desktop
=
req
->
handle
;
/* FIXME: should we close the old one? */
if
(
old_desktop
)
release_object
(
old_desktop
);
release_object
(
new_desktop
);
release_object
(
winstation
);
}
...
...
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