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
8653598a
Commit
8653598a
authored
Aug 17, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user: Defer all ExitWindowsEx processing to wineboot.
parent
54da7fb8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
23 additions
and
193 deletions
+23
-193
user_main.c
dlls/user/user_main.c
+23
-186
desktop.c
programs/explorer/desktop.c
+0
-7
No files found.
dlls/user/user_main.c
View file @
8653598a
...
...
@@ -26,7 +26,6 @@
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "tlhelp32.h"
#include "controls.h"
#include "user_private.h"
...
...
@@ -284,201 +283,39 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
/***********************************************************************
* USER_GetProcessHandleList(Internal)
*/
static
HANDLE
*
USER_GetProcessHandleList
(
void
)
{
DWORD
count
,
i
,
n
;
HANDLE
*
list
;
PROCESSENTRY32
pe
;
HANDLE
hSnapshot
;
BOOL
r
;
hSnapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPPROCESS
,
0
);
if
(
!
hSnapshot
)
{
ERR
(
"cannot create snapshot
\n
"
);
return
FALSE
;
}
/* count the number of processes plus one */
for
(
count
=
0
;
;
count
++
)
{
pe
.
dwSize
=
sizeof
pe
;
if
(
count
)
r
=
Process32Next
(
hSnapshot
,
&
pe
);
else
r
=
Process32First
(
hSnapshot
,
&
pe
);
if
(
!
r
)
break
;
}
/* allocate memory make a list of the process handles */
list
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
count
+
1
)
*
sizeof
(
HANDLE
)
);
n
=
0
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
pe
.
dwSize
=
sizeof
pe
;
if
(
i
)
r
=
Process32Next
(
hSnapshot
,
&
pe
);
else
r
=
Process32First
(
hSnapshot
,
&
pe
);
if
(
!
r
)
break
;
/* don't kill ourselves */
if
(
GetCurrentProcessId
()
==
pe
.
th32ProcessID
)
continue
;
/* open the process so we don't can track it */
list
[
n
]
=
OpenProcess
(
PROCESS_QUERY_INFORMATION
|
PROCESS_TERMINATE
,
FALSE
,
pe
.
th32ProcessID
);
/* check it didn't terminate already */
if
(
list
[
n
]
)
n
++
;
}
list
[
n
]
=
0
;
CloseHandle
(
hSnapshot
);
if
(
!
r
)
ERR
(
"Error enumerating processes
\n
"
);
TRACE
(
"return %lu processes
\n
"
,
n
);
return
list
;
}
/***********************************************************************
* USER_KillProcesses (Internal)
*/
static
DWORD
USER_KillProcesses
(
void
)
{
DWORD
n
,
r
,
i
;
HANDLE
*
handles
;
const
DWORD
dwShutdownTimeout
=
10000
;
TRACE
(
"terminating other processes
\n
"
);
/* kill it and add it to our list of object to wait on */
handles
=
USER_GetProcessHandleList
();
for
(
n
=
0
;
handles
&&
handles
[
n
];
n
++
)
TerminateProcess
(
handles
[
n
],
0
);
/* wait for processes to exit */
for
(
i
=
0
;
i
<
n
;
i
+=
MAXIMUM_WAIT_OBJECTS
)
{
int
n_objs
=
((
n
-
i
)
>
MAXIMUM_WAIT_OBJECTS
)
?
MAXIMUM_WAIT_OBJECTS
:
(
n
-
i
);
r
=
WaitForMultipleObjects
(
n_objs
,
&
handles
[
i
],
TRUE
,
dwShutdownTimeout
);
if
(
r
==
WAIT_TIMEOUT
)
ERR
(
"wait failed!
\n
"
);
}
/* close the handles */
for
(
i
=
0
;
i
<
n
;
i
++
)
CloseHandle
(
handles
[
i
]
);
HeapFree
(
GetProcessHeap
(),
0
,
handles
);
return
n
;
}
/***********************************************************************
* USER_DoShutdown (Internal)
*/
static
void
USER_DoShutdown
(
void
)
{
DWORD
i
,
n
;
const
DWORD
nRetries
=
10
;
for
(
i
=
0
;
i
<
nRetries
;
i
++
)
{
n
=
USER_KillProcesses
();
TRACE
(
"Killed %ld processes, attempt %ld
\n
"
,
n
,
i
);
if
(
!
n
)
break
;
}
}
/***********************************************************************
* ExitWindowsEx (USER32.@)
*/
BOOL
WINAPI
ExitWindowsEx
(
UINT
flags
,
DWORD
reason
)
{
TRACE
(
"(%x,%lx)
\n
"
,
flags
,
reason
);
if
(
!
WIN_IsCurrentThread
(
GetDesktopWindow
()
))
{
BOOL
ret
=
PostMessageW
(
GetDesktopWindow
(),
WM_USER
+
666
,
MAKEWPARAM
(
flags
,
0xbabe
),
reason
);
if
(
ret
)
return
TRUE
;
/* this can happen if explorer hasn't been started or created the
* desktop window yet */
WARN
(
"PostMessage failed with error %ld
\n
"
,
GetLastError
());
/* fall through to doing it in the same process */
}
static
const
WCHAR
winebootW
[]
=
{
'\\'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
0
};
static
const
WCHAR
killW
[]
=
{
' '
,
'-'
,
'-'
,
'k'
,
'i'
,
'l'
,
'l'
,
0
};
static
const
WCHAR
end_sessionW
[]
=
{
' '
,
'-'
,
'-'
,
'e'
,
'n'
,
'd'
,
'-'
,
's'
,
'e'
,
's'
,
's'
,
'i'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
forceW
[]
=
{
' '
,
'-'
,
'-'
,
'f'
,
'o'
,
'r'
,
'c'
,
'e'
,
0
};
static
const
WCHAR
shutdownW
[]
=
{
' '
,
'-'
,
'-'
,
's'
,
'h'
,
'u'
,
't'
,
'd'
,
'o'
,
'w'
,
'n'
,
0
};
if
((
flags
&
EWX_FORCE
)
==
0
)
{
HWND
*
list
;
WCHAR
cmdline
[
MAX_PATH
+
64
];
PROCESS_INFORMATION
pi
;
STARTUPINFOW
si
;
/* We have to build a list of all windows first, as in EnumWindows */
list
=
WIN_ListChildren
(
GetDesktopWindow
()
);
if
(
list
)
{
HWND
*
phwnd
;
UINT
send_flags
;
DWORD_PTR
result
=
1
;
/* Send a WM_QUERYENDSESSION / WM_ENDSESSION message pair to
* each window. Note: it might be better to send all the
* WM_QUERYENDSESSION messages, aggregate the results and then
* send all the WM_ENDSESSION messages with the results but
* that's not what Windows does.
*/
send_flags
=
(
flags
&
EWX_FORCEIFHUNG
)
?
SMTO_ABORTIFHUNG
:
SMTO_NORMAL
;
for
(
phwnd
=
list
;
*
phwnd
;
phwnd
++
)
{
/* Make sure that the window still exists */
if
(
!
IsWindow
(
*
phwnd
))
continue
;
if
(
SendMessageTimeoutW
(
*
phwnd
,
WM_QUERYENDSESSION
,
0
,
0
,
send_flags
,
0
,
&
result
))
{
DWORD_PTR
dummy
;
SendMessageTimeoutW
(
*
phwnd
,
WM_ENDSESSION
,
result
,
0
,
send_flags
,
0
,
&
dummy
);
if
(
!
result
)
break
;
}
}
HeapFree
(
GetProcessHeap
(),
0
,
list
);
GetSystemDirectoryW
(
cmdline
,
MAX_PATH
);
lstrcatW
(
cmdline
,
winebootW
);
if
(
!
result
)
return
TRUE
;
}
if
(
flags
&
EWX_FORCE
)
lstrcatW
(
cmdline
,
killW
);
else
{
lstrcatW
(
cmdline
,
end_sessionW
);
if
(
flags
&
EWX_FORCEIFHUNG
)
lstrcatW
(
cmdline
,
forceW
);
}
if
(
!
(
flags
&
EWX_REBOOT
))
lstrcatW
(
cmdline
,
shutdownW
);
/* USER_DoShutdown will kill all processes except the current process */
USER_DoShutdown
();
if
(
flags
&
EWX_REBOOT
)
memset
(
&
si
,
0
,
sizeof
si
);
si
.
cb
=
sizeof
si
;
if
(
!
CreateProcessW
(
NULL
,
cmdline
,
NULL
,
NULL
,
FALSE
,
DETACHED_PROCESS
,
NULL
,
NULL
,
&
si
,
&
pi
))
{
WCHAR
winebootW
[]
=
{
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
0
};
PROCESS_INFORMATION
pi
;
STARTUPINFOW
si
;
memset
(
&
si
,
0
,
sizeof
si
);
si
.
cb
=
sizeof
si
;
if
(
CreateProcessW
(
NULL
,
winebootW
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
))
{
CloseHandle
(
pi
.
hProcess
);
CloseHandle
(
pi
.
hThread
);
}
else
MESSAGE
(
"wine: Failed to start wineboot
\n
"
);
ERR
(
"Failed to run %s
\n
"
,
debugstr_w
(
cmdline
)
);
return
FALSE
;
}
CloseHandle
(
pi
.
hProcess
);
CloseHandle
(
pi
.
hThread
);
return
TRUE
;
}
programs/explorer/desktop.c
View file @
8653598a
...
...
@@ -64,13 +64,6 @@ static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPAR
}
return
0
;
/* simple check to prevent applications accidentally triggering the
* ExitWindowsEx code if they send random messages to the desktop window */
case
WM_USER
+
666
:
if
(
HIWORD
(
wp
)
==
0xbabe
)
return
ExitWindowsEx
(
LOWORD
(
wp
),
lp
);
return
DefWindowProcW
(
hwnd
,
message
,
wp
,
lp
);
default:
return
DefWindowProcW
(
hwnd
,
message
,
wp
,
lp
);
}
...
...
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