reactos/base/applications/utilman/process.c
2019-08-19 13:05:28 +02:00

190 lines
5.3 KiB
C

/*
* PROJECT: ReactOS Utility Manager (Accessibility)
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Process handling functions
* COPYRIGHT: Copyright 2019 Bișoc George (fraizeraust99 at gmail dot com)
*/
/* INCLUDES *******************************************************************/
#include "precomp.h"
/* FUNCTIONS ******************************************************************/
/**
* @IsProcessRunning
*
* Checks if a process is running.
*
* @param[in] ProcName
* The name of the executable process.
*
* @return
* Returns TRUE if the given process' name is running,
* FALSE otherwise.
*
*/
BOOL IsProcessRunning(IN LPCWSTR lpProcessName)
{
BOOL bIsRunning = FALSE;
PROCESSENTRY32W Process = {0};
/* Create a snapshot and check whether the given process' executable name is running */
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return FALSE;
Process.dwSize = sizeof(Process);
/* Enumerate the processes */
if (Process32FirstW(hSnapshot, &Process))
{
do
{
if (_wcsicmp(Process.szExeFile, lpProcessName) == 0)
{
/* The process we are searching for is running */
bIsRunning = TRUE;
break;
}
}
while (Process32NextW(hSnapshot, &Process));
}
/* Free the handle and return */
CloseHandle(hSnapshot);
return bIsRunning;
}
/**
* @LaunchProcess
*
* Executes a process.
*
* @param[in] lpProcessName
* The name of the executable process.
*
* @return
* Returns TRUE if the process has been launched successfully,
* FALSE otherwise.
*
*/
BOOL LaunchProcess(LPCWSTR lpProcessName)
{
STARTUPINFOW si;
PROCESS_INFORMATION pi;
HANDLE hUserToken, hProcessToken;
BOOL bSuccess;
WCHAR ExpandedCmdLine[MAX_PATH];
/* Expand the process path string */
ExpandEnvironmentStringsW(lpProcessName, ExpandedCmdLine, ARRAYSIZE(ExpandedCmdLine));
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
/* Get the token of the parent (current) process of the application */
bSuccess = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hUserToken);
if (!bSuccess)
{
DPRINT("OpenProcessToken() failed with error -> %lu\n", GetLastError());
return FALSE;
}
/* Duplicate a new token so that we can use it to create our process */
bSuccess = DuplicateTokenEx(hUserToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hProcessToken);
if (!bSuccess)
{
DPRINT("DuplicateTokenEx() failed with error -> %lu\n", GetLastError());
CloseHandle(hUserToken);
return FALSE;
}
/* Finally create the process */
bSuccess = CreateProcessAsUserW(hProcessToken,
NULL,
ExpandedCmdLine,
NULL,
NULL,
FALSE,
0, // DETACHED_PROCESS, NORMAL_PRIORITY_CLASS
NULL,
NULL,
&si,
&pi);
if (!bSuccess)
{
DPRINT("CreateProcessAsUserW() failed with error -> %lu\n", GetLastError());
CloseHandle(hUserToken);
CloseHandle(hProcessToken);
return FALSE;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hUserToken);
CloseHandle(hProcessToken);
return TRUE;
}
/**
* @CloseProcess
*
* Closes a process.
*
* @param[in] lpProcessName
* The name of the executable process.
*
* @return
* Returns TRUE if the process has been terminated successfully,
* FALSE otherwise.
*
*/
BOOL CloseProcess(IN LPCWSTR lpProcessName)
{
BOOL bSuccess = FALSE;
PROCESSENTRY32W Process = {0};
/* Create a snapshot and check if the given process' executable name is running */
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return FALSE;
Process.dwSize = sizeof(Process);
/* Enumerate the processes */
if (Process32FirstW(hSnapshot, &Process))
{
do
{
if (_wcsicmp(Process.szExeFile, lpProcessName) == 0)
{
/*
* We have found the process. However we must make
* sure that we DO NOT kill ourselves (the process ID
* matching with the current parent process ID).
*/
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, Process.th32ProcessID);
if ((hProcess != NULL) && (Process.th32ProcessID != GetCurrentProcessId()))
{
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
}
bSuccess = TRUE;
break;
}
}
while (Process32NextW(hSnapshot, &Process));
}
/* Free the handle and return */
CloseHandle(hSnapshot);
return bSuccess;
}