Commit e1d1d34c authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Kill all wine processes when doing ExitWindowsEx.

parent 09a2eab3
......@@ -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"
......@@ -294,6 +295,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.@)
*/
BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reserved )
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment