ReactOS  0.4.14-dev-608-gd495a4f
endproc.c
Go to the documentation of this file.
1 /*
2  * ReactOS Task Manager
3  *
4  * endproc.c
5  *
6  * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7  * 2005 Klemens Friedl <frik85@reactos.at>
8  * 2014 Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 #include "precomp.h"
26 
27 #define NTOS_MODE_USER
28 #include <ndk/psfuncs.h>
29 
31 {
32  DWORD dwProcessId;
34  WCHAR szTitle[256];
35  WCHAR strErrorText[260];
36 
37  dwProcessId = GetSelectedProcessId();
38 
39  if (dwProcessId == 0)
40  return;
41 
43 
44  /* forbid killing system processes even if we have privileges -- sigh, windows kludge! */
46  {
48  LoadStringW(hInst, IDS_MSG_CLOSESYSTEMPROCESS, strErrorText, 256);
51  return;
52  }
53 
54  /* if this is a standard process just ask for confirmation before doing it */
55  LoadStringW(hInst, IDS_MSG_WARNINGTERMINATING, strErrorText, 256);
58  {
60  return;
61  }
62 
63  /* no such process or not enough privileges to open its token */
64  if (!hProcess)
65  {
66  GetLastErrorText(strErrorText, 260);
69  return;
70  }
71 
72  /* try to kill it, and notify the user if didn't work */
73  if (!TerminateProcess(hProcess, 1))
74  {
75  GetLastErrorText(strErrorText, 260);
78  }
79 
81 }
82 
84 {
86  ULONG BreakOnTermination;
87 
88  /* return early if the process handle does not exist */
89  if (!hProcess)
90  return FALSE;
91 
92  /* the important system processes that we don't want to let the user
93  kill come marked as critical, this simplifies the check greatly.
94 
95  a critical process brings the system down when is terminated:
96  <http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm> */
97 
100  &BreakOnTermination,
101  sizeof(ULONG),
102  NULL);
103 
104  if (NT_SUCCESS(status) && BreakOnTermination)
105  return TRUE;
106 
107  return FALSE;
108 }
109 
110 BOOL ShutdownProcessTreeHelper(HANDLE hSnapshot, HANDLE hParentProcess, DWORD dwParentPID)
111 {
112  HANDLE hChildHandle;
113  PROCESSENTRY32W ProcessEntry = {0};
114  ProcessEntry.dwSize = sizeof(ProcessEntry);
115 
116  if (Process32FirstW(hSnapshot, &ProcessEntry))
117  {
118  do
119  {
120  if (ProcessEntry.th32ParentProcessID == dwParentPID)
121  {
123  FALSE,
124  ProcessEntry.th32ProcessID);
125  if (!hChildHandle || IsCriticalProcess(hChildHandle))
126  {
127  if (hChildHandle)
128  {
129  CloseHandle(hChildHandle);
130  }
131  continue;
132  }
133  if (!ShutdownProcessTreeHelper(hSnapshot, hChildHandle, ProcessEntry.th32ProcessID))
134  {
135  CloseHandle(hChildHandle);
136  return FALSE;
137  }
138  CloseHandle(hChildHandle);
139  }
140  } while (Process32NextW(hSnapshot, &ProcessEntry));
141  }
142 
143  return TerminateProcess(hParentProcess, 0);
144 }
145 
146 BOOL ShutdownProcessTree(HANDLE hParentProcess, DWORD dwParentPID)
147 {
149  BOOL bResult;
150 
151  if (!hSnapshot)
152  {
153  return FALSE;
154  }
155 
156  bResult = ShutdownProcessTreeHelper(hSnapshot, hParentProcess, dwParentPID);
157  CloseHandle(hSnapshot);
158  return bResult;
159 }
160 
162 {
163  DWORD dwProcessId;
165  WCHAR szTitle[256];
166  WCHAR strErrorText[260];
167 
168  dwProcessId = GetSelectedProcessId();
169 
170  if (dwProcessId == 0)
171  return;
172 
174 
175  /* forbid killing system processes even if we have privileges -- sigh, windows kludge! */
177  {
179  LoadStringW(hInst, IDS_MSG_CLOSESYSTEMPROCESS, strErrorText, 256);
182  return;
183  }
184 
185  LoadStringW(hInst, IDS_MSG_WARNINGTERMINATING, strErrorText, 256);
187  if (MessageBoxW(hMainWnd, strErrorText, szTitle, MB_YESNO|MB_ICONWARNING) != IDYES)
188  {
190  return;
191  }
192 
193  if (!hProcess)
194  {
195  GetLastErrorText(strErrorText, 260);
197  MessageBoxW(hMainWnd, strErrorText, szTitle, MB_OK|MB_ICONSTOP);
198  return;
199  }
200 
201  if (!ShutdownProcessTree(hProcess, dwProcessId))
202  {
203  GetLastErrorText(strErrorText, 260);
205  MessageBoxW(hMainWnd, strErrorText, szTitle, MB_OK|MB_ICONSTOP);
206  }
207 
209 }
#define TRUE
Definition: types.h:120
DWORD GetSelectedProcessId(void)
Definition: procpage.c:99
#define CloseHandle
Definition: compat.h:406
#define IDYES
Definition: winuser.h:829
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:158
void ProcessPage_OnEndProcessTree(void)
Definition: endproc.c:161
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
BOOL ShutdownProcessTree(HANDLE hParentProcess, DWORD dwParentPID)
Definition: endproc.c:146
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
#define MB_ICONSTOP
Definition: winuser.h:797
#define MB_TOPMOST
Definition: winuser.h:819
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define MB_ICONWARNING
Definition: winuser.h:780
DWORD th32ProcessID
Definition: tlhelp32.h:51
#define MB_YESNO
Definition: winuser.h:811
unsigned int BOOL
Definition: ntddk_ex.h:94
void ProcessPage_OnEndProcess(void)
Definition: endproc.c:30
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
Definition: toolhelp.c:984
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
HWND hMainWnd
Definition: magnifier.c:32
BOOL WINAPI Process32NextW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
Definition: toolhelp.c:1073
#define IDS_MSG_UNABLETERMINATEPRO
Definition: resource.h:248
#define IDS_MSG_TASKMGRWARNING
Definition: resource.h:246
BOOL IsCriticalProcess(HANDLE hProcess)
Definition: endproc.c:83
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1227
HINSTANCE hInst
Definition: dxdiag.c:13
#define PROCESS_TERMINATE
Definition: pstypes.h:149
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
#define TH32CS_SNAPPROCESS
Definition: tlhelp32.h:26
LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize)
Definition: taskmgr.c:1152
#define MB_OK
Definition: winuser.h:784
HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
Definition: toolhelp.c:1255
#define IDS_MSG_CLOSESYSTEMPROCESS
Definition: resource.h:252
unsigned int ULONG
Definition: retypes.h:1
#define IDS_MSG_WARNINGTERMINATING
Definition: resource.h:247
static SERVICE_STATUS status
Definition: service.c:31
DWORD th32ParentProcessID
Definition: tlhelp32.h:55
BOOL ShutdownProcessTreeHelper(HANDLE hSnapshot, HANDLE hParentProcess, DWORD dwParentPID)
Definition: endproc.c:110
Definition: ps.c:97