mirror of
https://github.com/reactos/reactos.git
synced 2024-09-06 02:37:06 +00:00
223 lines
5.9 KiB
C
223 lines
5.9 KiB
C
/*
|
|
* PROJECT: ReactOS Utility Manager Resources DLL (UManDlg.dll)
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: Process handling functions
|
|
* COPYRIGHT: Copyright 2019-2020 George Bișoc (george.bisoc@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include "umandlg.h"
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
/**
|
|
* @GetProcessID
|
|
*
|
|
* Returns the process executable ID based on the given executable name.
|
|
*
|
|
* @param[in] lpszProcessName
|
|
* The name of the executable process.
|
|
*
|
|
* @return
|
|
* Returns the ID number of the process, otherwise 0.
|
|
*
|
|
*/
|
|
DWORD GetProcessID(IN LPCWSTR lpszProcessName)
|
|
{
|
|
PROCESSENTRY32W Process;
|
|
|
|
/* Create a snapshot and check if the given process name matches with the one from the process entry structure */
|
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
|
if (hSnapshot == INVALID_HANDLE_VALUE)
|
|
return 0;
|
|
|
|
/* Get the whole size of the structure */
|
|
Process.dwSize = sizeof(Process);
|
|
|
|
/* Enumerate the processes */
|
|
if (Process32FirstW(hSnapshot, &Process))
|
|
{
|
|
do
|
|
{
|
|
if (_wcsicmp(Process.szExeFile, lpszProcessName) == 0)
|
|
{
|
|
/* The names match, return the process ID we're interested */
|
|
CloseHandle(hSnapshot);
|
|
return Process.th32ProcessID;
|
|
}
|
|
}
|
|
while (Process32NextW(hSnapshot, &Process));
|
|
}
|
|
|
|
CloseHandle(hSnapshot);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @IsProcessRunning
|
|
*
|
|
* Checks if a process is running.
|
|
*
|
|
* @param[in] lpszProcessName
|
|
* The name of the executable process.
|
|
*
|
|
* @return
|
|
* Returns TRUE if the given process' name is running,
|
|
* FALSE otherwise.
|
|
*
|
|
*/
|
|
BOOL IsProcessRunning(IN LPCWSTR lpszProcessName)
|
|
{
|
|
DWORD dwReturn, dwProcessID;
|
|
HANDLE hProcess;
|
|
|
|
/* Get the process ID */
|
|
dwProcessID = GetProcessID(lpszProcessName);
|
|
if (dwProcessID == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/* Synchronize the process to get its signaling state */
|
|
hProcess = OpenProcess(SYNCHRONIZE, FALSE, dwProcessID);
|
|
if (!hProcess)
|
|
{
|
|
DPRINT("IsProcessRunning(): Failed to open the process! (Error: %lu)\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
/* Wait for the process */
|
|
dwReturn = WaitForSingleObject(hProcess, 0);
|
|
if (dwReturn == WAIT_TIMEOUT)
|
|
{
|
|
/* The process is still running */
|
|
CloseHandle(hProcess);
|
|
return TRUE;
|
|
}
|
|
|
|
CloseHandle(hProcess);
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* @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(IN LPCWSTR lpszProcessName)
|
|
{
|
|
STARTUPINFOW si;
|
|
PROCESS_INFORMATION pi;
|
|
HANDLE hUserToken, hProcessToken;
|
|
BOOL bSuccess;
|
|
WCHAR ExpandedCmdLine[MAX_PATH];
|
|
|
|
/* Expand the process path string */
|
|
ExpandEnvironmentStringsW(lpszProcessName, 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] lpszProcessName
|
|
* The name of the executable process.
|
|
*
|
|
* @return
|
|
* Returns TRUE if the process has been terminated successfully,
|
|
* FALSE otherwise.
|
|
*
|
|
*/
|
|
BOOL CloseProcess(IN LPCWSTR lpszProcessName)
|
|
{
|
|
HANDLE hProcess;
|
|
DWORD dwProcessID;
|
|
|
|
/* Get the process ID */
|
|
dwProcessID = GetProcessID(lpszProcessName);
|
|
if (dwProcessID == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/* Make sure that the given process ID is not ours, the parent process, so that we do not kill ourselves */
|
|
if (dwProcessID == GetCurrentProcessId())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/* Open the process so that we can terminate it */
|
|
hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
|
|
if (!hProcess)
|
|
{
|
|
DPRINT("CloseProcess(): Failed to open the process for termination! (Error: %lu)\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
/* Terminate it */
|
|
TerminateProcess(hProcess, 0);
|
|
CloseHandle(hProcess);
|
|
return TRUE;
|
|
}
|