Kill all wine processes when doing ExitWindowsEx.
This commit is contained in:
parent
09a2eab38d
commit
e1d1d34c9d
122
windows/user.c
122
windows/user.c
|
@ -30,6 +30,7 @@
|
|||
#include "wine/winuser16.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
#include "tlhelp32.h"
|
||||
#include "user.h"
|
||||
#include "win.h"
|
||||
#include "controls.h"
|
||||
|
@ -293,6 +294,124 @@ BOOL16 WINAPI ExitWindowsExec16( LPCSTR lpszExe, LPCSTR lpszParams )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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 outselves */
|
||||
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.@)
|
||||
*/
|
||||
|
@ -325,6 +444,9 @@ BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reserved )
|
|||
}
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
|
||||
/* USER_DoShutdown will kill all processes except the current process */
|
||||
USER_DoShutdown();
|
||||
|
||||
if (result) ExitKernel16();
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue