2 * PROJECT: ReactOS Utility Manager (Accessibility)
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Process handling functions
5 * COPYRIGHT: Copyright 2019 Bișoc George (fraizeraust99 at gmail dot com)
8 /* INCLUDES *******************************************************************/
12 /* FUNCTIONS ******************************************************************/
17 * Checks if a process is running.
20 * The name of the executable process.
23 * Returns TRUE if the given process' name is running,
27 BOOL
IsProcessRunning(IN LPCWSTR lpProcessName
)
29 BOOL bIsRunning
= FALSE
;
30 PROCESSENTRY32W Process
= {0};
32 /* Create a snapshot and check whether the given process' executable name is running */
33 HANDLE hSnapshot
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
35 if (hSnapshot
== INVALID_HANDLE_VALUE
)
38 Process
.dwSize
= sizeof(Process
);
40 /* Enumerate the processes */
41 if (Process32FirstW(hSnapshot
, &Process
))
45 if (_wcsicmp(Process
.szExeFile
, lpProcessName
) == 0)
47 /* The process we are searching for is running */
52 while (Process32NextW(hSnapshot
, &Process
));
55 /* Free the handle and return */
56 CloseHandle(hSnapshot
);
65 * @param[in] lpProcessName
66 * The name of the executable process.
69 * Returns TRUE if the process has been launched successfully,
73 BOOL
LaunchProcess(LPCWSTR lpProcessName
)
76 PROCESS_INFORMATION pi
;
77 HANDLE hUserToken
, hProcessToken
;
79 WCHAR ExpandedCmdLine
[MAX_PATH
];
81 /* Expand the process path string */
82 ExpandEnvironmentStringsW(lpProcessName
, ExpandedCmdLine
, ARRAYSIZE(ExpandedCmdLine
));
84 ZeroMemory(&pi
, sizeof(pi
));
85 ZeroMemory(&si
, sizeof(si
));
87 si
.dwFlags
= STARTF_USESHOWWINDOW
;
88 si
.wShowWindow
= SW_SHOWNORMAL
;
90 /* Get the token of the parent (current) process of the application */
91 bSuccess
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
| TOKEN_DUPLICATE
, &hUserToken
);
94 DPRINT("OpenProcessToken() failed with error -> %lu\n", GetLastError());
98 /* Duplicate a new token so that we can use it to create our process */
99 bSuccess
= DuplicateTokenEx(hUserToken
, TOKEN_ALL_ACCESS
, NULL
, SecurityIdentification
, TokenPrimary
, &hProcessToken
);
102 DPRINT("DuplicateTokenEx() failed with error -> %lu\n", GetLastError());
103 CloseHandle(hUserToken
);
107 /* Finally create the process */
108 bSuccess
= CreateProcessAsUserW(hProcessToken
,
114 0, // DETACHED_PROCESS, NORMAL_PRIORITY_CLASS
122 DPRINT("CreateProcessAsUserW() failed with error -> %lu\n", GetLastError());
123 CloseHandle(hUserToken
);
124 CloseHandle(hProcessToken
);
128 CloseHandle(pi
.hProcess
);
129 CloseHandle(pi
.hThread
);
130 CloseHandle(hUserToken
);
131 CloseHandle(hProcessToken
);
140 * @param[in] lpProcessName
141 * The name of the executable process.
144 * Returns TRUE if the process has been terminated successfully,
148 BOOL
CloseProcess(IN LPCWSTR lpProcessName
)
150 BOOL bSuccess
= FALSE
;
151 PROCESSENTRY32W Process
= {0};
153 /* Create a snapshot and check if the given process' executable name is running */
154 HANDLE hSnapshot
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
156 if (hSnapshot
== INVALID_HANDLE_VALUE
)
159 Process
.dwSize
= sizeof(Process
);
161 /* Enumerate the processes */
162 if (Process32FirstW(hSnapshot
, &Process
))
166 if (_wcsicmp(Process
.szExeFile
, lpProcessName
) == 0)
169 * We have found the process. However we must make
170 * sure that we DO NOT kill ourselves (the process ID
171 * matching with the current parent process ID).
173 HANDLE hProcess
= OpenProcess(PROCESS_TERMINATE
, 0, Process
.th32ProcessID
);
174 if ((hProcess
!= NULL
) && (Process
.th32ProcessID
!= GetCurrentProcessId()))
176 TerminateProcess(hProcess
, 0);
177 CloseHandle(hProcess
);
183 while (Process32NextW(hSnapshot
, &Process
));
186 /* Free the handle and return */
187 CloseHandle(hSnapshot
);