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
5cbdbe62
Commit
5cbdbe62
authored
Sep 26, 2007
by
Rob Shearman
Committed by
Alexandre Julliard
Oct 01, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineboot: Add a timeout dialog when any WM_QUERYENDSESSION or WM_ENDSESSION messages take too long.
parent
7fb98bfb
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
278 additions
and
17 deletions
+278
-17
.gitignore
.gitignore
+1
-0
Makefile.in
programs/wineboot/Makefile.in
+2
-0
resource.h
programs/wineboot/resource.h
+20
-0
shutdown.c
programs/wineboot/shutdown.c
+190
-17
wineboot.rc
programs/wineboot/wineboot.rc
+30
-0
wineboot_En.rc
programs/wineboot/wineboot_En.rc
+35
-0
No files found.
.gitignore
View file @
5cbdbe62
...
...
@@ -652,6 +652,7 @@ programs/view/view
programs/view/viewrc.res
programs/wineapploader
programs/wineboot/wineboot
programs/wineboot/wineboot.res
programs/winebrowser/winebrowser
programs/winecfg/winecfg
programs/winecfg/winecfg.res
...
...
programs/wineboot/Makefile.in
View file @
5cbdbe62
...
...
@@ -11,6 +11,8 @@ C_SRCS = \
shutdown.c
\
wineboot.c
RC_SRCS
=
wineboot.rc
@MAKE_PROG_RULES@
@DEPENDENCIES@
# everything below this line is overwritten by make depend
programs/wineboot/resource.h
0 → 100644
View file @
5cbdbe62
/*
* Copyright (C) 2007 Robert Shearman for CodeWeavers
*
* 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
*/
#define IDC_STATIC -1
#define IDD_ENDTASK 100
programs/wineboot/shutdown.c
View file @
5cbdbe62
...
...
@@ -23,10 +23,16 @@
#include "winbase.h"
#include "winuser.h"
#include "tlhelp32.h"
#include "wine/debug.h"
#include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
wineboot
);
#define MESSAGE_TIMEOUT 5000
#define PROCQUIT_TIMEOUT 20000
struct
window_info
{
HWND
hwnd
;
...
...
@@ -80,36 +86,203 @@ static BOOL get_all_windows(void)
return
TRUE
;
}
struct
callback_data
{
UINT
window_count
;
BOOL
timed_out
;
LRESULT
result
;
};
static
void
CALLBACK
end_session_message_callback
(
HWND
hwnd
,
UINT
msg
,
ULONG_PTR
data
,
LRESULT
lresult
)
{
struct
callback_data
*
cb_data
=
(
struct
callback_data
*
)
data
;
WINE_TRACE
(
"received response %s hwnd %p lresult %ld
\n
"
,
msg
==
WM_QUERYENDSESSION
?
"WM_QUERYENDSESSION"
:
(
msg
==
WM_ENDSESSION
?
"WM_ENDSESSION"
:
"Unknown"
),
hwnd
,
lresult
);
/* we only care if a WM_QUERYENDSESSION response is FALSE */
cb_data
->
result
=
cb_data
->
result
&&
lresult
;
/* cheap way of ref-counting callback_data whilst freeing memory at correct
* time */
if
(
!
(
cb_data
->
window_count
--
)
&&
cb_data
->
timed_out
)
HeapFree
(
GetProcessHeap
(),
0
,
cb_data
);
}
struct
endtask_dlg_data
{
struct
window_info
*
win
;
BOOL
cancelled
;
};
static
INT_PTR
CALLBACK
endtask_dlg_proc
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
struct
endtask_dlg_data
*
data
;
HANDLE
handle
;
switch
(
msg
)
{
case
WM_INITDIALOG
:
SetWindowLongPtrW
(
hwnd
,
DWLP_USER
,
lparam
);
data
=
(
struct
endtask_dlg_data
*
)
lparam
;
ShowWindow
(
hwnd
,
SW_SHOWNORMAL
);
return
TRUE
;
case
WM_COMMAND
:
data
=
(
struct
endtask_dlg_data
*
)
GetWindowLongPtrW
(
hwnd
,
DWLP_USER
);
switch
(
wparam
)
{
case
MAKEWPARAM
(
IDOK
,
BN_CLICKED
):
handle
=
OpenProcess
(
PROCESS_TERMINATE
,
FALSE
,
data
->
win
[
0
].
pid
);
if
(
handle
)
{
WINE_TRACE
(
"terminating process %04x
\n
"
,
data
->
win
[
0
].
pid
);
TerminateProcess
(
handle
,
0
);
CloseHandle
(
handle
);
}
return
TRUE
;
case
MAKEWPARAM
(
IDCANCEL
,
BN_CLICKED
):
data
->
cancelled
=
TRUE
;
return
TRUE
;
}
break
;
}
return
FALSE
;
}
/* Sends a message to a set of windows, displaying a dialog if the window
* doesn't respond to the message within a set amount of time.
* If the process has already been terminated, the function returns -1.
* If the user or application cancels the process, the function returns 0.
* Otherwise the function returns 0. */
static
LRESULT
send_messages_with_timeout_dialog
(
struct
window_info
*
win
,
UINT
count
,
HANDLE
process_handle
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
unsigned
int
i
;
DWORD
ret
;
DWORD
start_time
;
struct
callback_data
*
cb_data
;
HWND
hwnd_endtask
=
NULL
;
struct
endtask_dlg_data
dlg_data
;
LRESULT
result
;
cb_data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
cb_data
)
);
if
(
!
cb_data
)
return
1
;
cb_data
->
result
=
TRUE
;
/* we only care if a WM_QUERYENDSESSION response is FALSE */
cb_data
->
timed_out
=
FALSE
;
cb_data
->
window_count
=
count
;
dlg_data
.
win
=
win
;
dlg_data
.
cancelled
=
FALSE
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
!
SendMessageCallbackW
(
win
[
i
].
hwnd
,
msg
,
wparam
,
lparam
,
end_session_message_callback
,
(
ULONG_PTR
)
cb_data
))
cb_data
->
window_count
--
;
}
start_time
=
GetTickCount
();
while
(
TRUE
)
{
DWORD
current_time
=
GetTickCount
();
ret
=
MsgWaitForMultipleObjects
(
1
,
&
process_handle
,
FALSE
,
MESSAGE_TIMEOUT
-
(
current_time
-
start_time
),
QS_ALLINPUT
);
if
(
ret
==
WAIT_OBJECT_0
)
/* process exited */
{
HeapFree
(
GetProcessHeap
(),
0
,
cb_data
);
result
=
1
;
goto
cleanup
;
}
else
if
(
ret
==
WAIT_OBJECT_0
+
1
)
/* window message */
{
MSG
msg
;
while
(
PeekMessageW
(
&
msg
,
NULL
,
0
,
0
,
PM_REMOVE
))
{
if
(
!
hwnd_endtask
||
!
IsDialogMessageW
(
hwnd_endtask
,
&
msg
))
{
TranslateMessage
(
&
msg
);
DispatchMessageW
(
&
msg
);
}
}
if
(
!
cb_data
->
window_count
)
{
result
=
cb_data
->
result
;
HeapFree
(
GetProcessHeap
(),
0
,
cb_data
);
if
(
!
result
)
goto
cleanup
;
break
;
}
if
(
dlg_data
.
cancelled
)
{
cb_data
->
timed_out
=
TRUE
;
result
=
0
;
goto
cleanup
;
}
}
else
if
((
ret
==
WAIT_TIMEOUT
)
&&
!
hwnd_endtask
)
{
hwnd_endtask
=
CreateDialogParamW
(
GetModuleHandle
(
NULL
),
MAKEINTRESOURCEW
(
IDD_ENDTASK
),
NULL
,
endtask_dlg_proc
,
(
LPARAM
)
&
dlg_data
);
}
else
break
;
}
result
=
1
;
cleanup:
if
(
hwnd_endtask
)
DestroyWindow
(
hwnd_endtask
);
return
result
;
}
/* send WM_QUERYENDSESSION and WM_ENDSESSION to all windows of a given process */
/* FIXME: should display a confirmation dialog if process doesn't respond to the messages */
static
DWORD_PTR
send_end_session_messages
(
struct
window_info
*
win
,
UINT
count
,
UINT
flags
)
{
unsigned
int
i
;
DWORD_PTR
result
,
ret
=
1
;
LRESULT
result
,
end_session
;
HANDLE
process_handle
;
DWORD
ret
;
/* don't kill the desktop process */
if
(
win
[
0
].
pid
==
desktop_pid
)
return
1
;
for
(
i
=
0
;
ret
&&
i
<
count
;
i
++
)
{
if
(
SendMessageTimeoutW
(
win
[
i
].
hwnd
,
WM_QUERYENDSESSION
,
0
,
0
,
flags
,
0
,
&
result
))
process_handle
=
OpenProcess
(
SYNCHRONIZE
,
FALSE
,
win
[
0
].
pid
);
if
(
!
process_handle
)
return
1
;
end_session
=
send_messages_with_timeout_dialog
(
win
,
count
,
process_handle
,
WM_QUERYENDSESSION
,
0
,
0
);
if
(
end_session
==
-
1
)
{
WINE_TRACE
(
"sent MW_QUERYENDSESSION hwnd %p pid %04x result %ld
\n
"
,
win
[
i
].
hwnd
,
win
[
i
].
pid
,
result
);
ret
=
result
;
}
else
win
[
i
].
hwnd
=
0
;
/* ignore this window */
CloseHandle
(
process_handle
);
return
1
;
}
for
(
i
=
0
;
i
<
count
;
i
++
)
result
=
send_messages_with_timeout_dialog
(
win
,
count
,
process_handle
,
WM_ENDSESSION
,
end_session
,
0
);
if
(
end_session
==
0
)
{
CloseHandle
(
process_handle
);
return
0
;
}
if
(
result
==
-
1
)
{
if
(
!
win
[
i
].
hwnd
)
continue
;
WINE_TRACE
(
"sending WM_ENDSESSION hwnd %p pid %04x wp %ld
\n
"
,
win
[
i
].
hwnd
,
win
[
i
].
pid
,
ret
);
SendMessageTimeoutW
(
win
[
i
].
hwnd
,
WM_ENDSESSION
,
ret
,
0
,
flags
,
0
,
&
result
);
CloseHandle
(
process_handle
);
return
1
;
}
if
(
ret
)
/* wait for app to quit on its own for a while */
ret
=
WaitForSingleObject
(
process_handle
,
PROCQUIT_TIMEOUT
);
CloseHandle
(
process_handle
);
if
(
ret
==
WAIT_TIMEOUT
)
{
/* it didn't quit by itself in time, so terminate it with extreme prejudice */
HANDLE
handle
=
OpenProcess
(
PROCESS_TERMINATE
,
FALSE
,
win
[
0
].
pid
);
if
(
handle
)
{
...
...
@@ -118,7 +291,7 @@ static DWORD_PTR send_end_session_messages( struct window_info *win, UINT count,
CloseHandle
(
handle
);
}
}
return
ret
;
return
1
;
}
/* close all top-level windows and terminate processes cleanly */
...
...
programs/wineboot/wineboot.rc
0 → 100644
View file @
5cbdbe62
/*
* WineBoot resources
*
* Copyright (C) 2007 Robert Shearman for CodeWeavers
*
* 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 "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "winuser.h"
#include "commctrl.h"
#include "resource.h"
#include "wineboot_En.rc"
programs/wineboot/wineboot_En.rc
0 → 100644
View file @
5cbdbe62
/*
* WineBoot resources
*
* Copyright (C) 2007 Robert Shearman for CodeWeavers
*
* 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
*
*/
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDD_ENDTASK DIALOG DISCARDABLE 0, 0, 186, 71
STYLE DS_MODALFRAME | DS_NOIDLEMSG | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Waiting for Program"
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Terminate Process",IDOK,51,49,71,15
PUSHBUTTON "Cancel",IDCANCEL,129,49,50,15
LTEXT "A simulated log-off or shutdown is in progress, but this program isn't responding.",
IDC_STATIC,7,7,172,19
LTEXT "If you terminate the process you may lose all unsaved data.",
IDC_STATIC,7,28,172,15
END
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