Blame winpr/libwinpr/thread/process.c

Packit Service fa4841
/**
Packit Service fa4841
 * WinPR: Windows Portable Runtime
Packit Service fa4841
 * Process Thread Functions
Packit Service fa4841
 *
Packit Service fa4841
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit Service fa4841
 * Copyright 2014 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
Packit Service fa4841
 *
Packit Service fa4841
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit Service fa4841
 * you may not use this file except in compliance with the License.
Packit Service fa4841
 * You may obtain a copy of the License at
Packit Service fa4841
 *
Packit Service fa4841
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit Service fa4841
 *
Packit Service fa4841
 * Unless required by applicable law or agreed to in writing, software
Packit Service fa4841
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit Service fa4841
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit Service fa4841
 * See the License for the specific language governing permissions and
Packit Service fa4841
 * limitations under the License.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#ifdef HAVE_CONFIG_H
Packit Service fa4841
#include "config.h"
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include <winpr/handle.h>
Packit Service fa4841
#include "../handle/nonehandle.h"
Packit Service fa4841
Packit Service fa4841
#include <winpr/thread.h>
Packit Service fa4841
Packit Service fa4841
/**
Packit Service fa4841
 * CreateProcessA
Packit Service fa4841
 * CreateProcessW
Packit Service fa4841
 * CreateProcessAsUserA
Packit Service fa4841
 * CreateProcessAsUserW
Packit Service fa4841
 * ExitProcess
Packit Service fa4841
 * GetCurrentProcess
Packit Service fa4841
 * GetCurrentProcessId
Packit Service fa4841
 * GetExitCodeProcess
Packit Service fa4841
 * GetProcessHandleCount
Packit Service fa4841
 * GetProcessId
Packit Service fa4841
 * GetProcessIdOfThread
Packit Service fa4841
 * GetProcessMitigationPolicy
Packit Service fa4841
 * GetProcessTimes
Packit Service fa4841
 * GetProcessVersion
Packit Service fa4841
 * OpenProcess
Packit Service fa4841
 * OpenProcessToken
Packit Service fa4841
 * ProcessIdToSessionId
Packit Service fa4841
 * SetProcessAffinityUpdateMode
Packit Service fa4841
 * SetProcessMitigationPolicy
Packit Service fa4841
 * SetProcessShutdownParameters
Packit Service fa4841
 * TerminateProcess
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#ifndef _WIN32
Packit Service fa4841
Packit Service fa4841
#include <winpr/crt.h>
Packit Service fa4841
#include <winpr/path.h>
Packit Service fa4841
#include <winpr/environment.h>
Packit Service fa4841
Packit Service fa4841
#include <grp.h>
Packit Service fa4841
Packit Service fa4841
#include <signal.h>
Packit Service fa4841
Packit Service fa4841
#include "thread.h"
Packit Service fa4841
Packit Service fa4841
#include "../security/security.h"
Packit Service fa4841
Packit Service fa4841
#ifndef NSIG
Packit Service fa4841
#ifdef SIGMAX
Packit Service fa4841
#define NSIG SIGMAX
Packit Service fa4841
#else
Packit Service fa4841
#define NSIG 64
Packit Service fa4841
#endif
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
/**
Packit Service fa4841
 * If the file name does not contain a directory path, the system searches for the executable file
Packit Service fa4841
 * in the following sequence:
Packit Service fa4841
 *
Packit Service fa4841
 * 1) The directory from which the application loaded.
Packit Service fa4841
 * 2) The current directory for the parent process.
Packit Service fa4841
 * 3) The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of
Packit Service fa4841
 * this directory. 4) The 16-bit Windows system directory. There is no function that obtains the
Packit Service fa4841
 * path of this directory, but it is searched. The name of this directory is System. 5) The Windows
Packit Service fa4841
 * directory. Use the GetWindowsDirectory function to get the path of this directory. 6) The
Packit Service fa4841
 * directories that are listed in the PATH environment variable. Note that this function does not
Packit Service fa4841
 * search the per-application path specified by the App Paths registry key. To include this
Packit Service fa4841
 * per-application path in the search sequence, use the ShellExecute function.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
static char* FindApplicationPath(char* application)
Packit Service fa4841
{
Packit Service fa4841
	LPCSTR pathName = "PATH";
Packit Service fa4841
	char* path;
Packit Service fa4841
	char* save;
Packit Service fa4841
	DWORD nSize;
Packit Service fa4841
	LPSTR lpSystemPath;
Packit Service fa4841
	char* filename = NULL;
Packit Service fa4841
Packit Service fa4841
	if (!application)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	if (application[0] == '/')
Packit Service fa4841
		return _strdup(application);
Packit Service fa4841
Packit Service fa4841
	nSize = GetEnvironmentVariableA(pathName, NULL, 0);
Packit Service fa4841
Packit Service fa4841
	if (!nSize)
Packit Service fa4841
		return _strdup(application);
Packit Service fa4841
Packit Service fa4841
	lpSystemPath = (LPSTR)malloc(nSize);
Packit Service fa4841
Packit Service fa4841
	if (!lpSystemPath)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	if (GetEnvironmentVariableA(pathName, lpSystemPath, nSize) != nSize - 1)
Packit Service fa4841
	{
Packit Service fa4841
		free(lpSystemPath);
Packit Service fa4841
		return NULL;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	save = NULL;
Packit Service fa4841
	path = strtok_s(lpSystemPath, ":", &save);
Packit Service fa4841
Packit Service fa4841
	while (path)
Packit Service fa4841
	{
Packit Service fa4841
		filename = GetCombinedPath(path, application);
Packit Service fa4841
Packit Service fa4841
		if (PathFileExistsA(filename))
Packit Service fa4841
		{
Packit Service fa4841
			break;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		free(filename);
Packit Service fa4841
		filename = NULL;
Packit Service fa4841
		path = strtok_s(NULL, ":", &save);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	free(lpSystemPath);
Packit Service fa4841
	return filename;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static HANDLE CreateProcessHandle(pid_t pid);
Packit Service fa4841
static BOOL ProcessHandleCloseHandle(HANDLE handle);
Packit Service fa4841
Packit Service fa4841
static BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, LPCSTR lpApplicationName,
Packit Service fa4841
                              LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
Packit Service fa4841
                              LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
Packit Service fa4841
                              DWORD dwCreationFlags, LPVOID lpEnvironment,
Packit Service fa4841
                              LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo,
Packit Service fa4841
                              LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	pid_t pid;
Packit Service fa4841
	int numArgs;
Packit Service fa4841
	LPSTR* pArgs = NULL;
Packit Service fa4841
	char** envp = NULL;
Packit Service fa4841
	char* filename = NULL;
Packit Service fa4841
	HANDLE thread;
Packit Service fa4841
	HANDLE process;
Packit Service fa4841
	WINPR_ACCESS_TOKEN* token;
Packit Service fa4841
	LPTCH lpszEnvironmentBlock;
Packit Service fa4841
	BOOL ret = FALSE;
Packit Service fa4841
	sigset_t oldSigMask;
Packit Service fa4841
	sigset_t newSigMask;
Packit Service fa4841
	BOOL restoreSigMask = FALSE;
Packit Service fa4841
	numArgs = 0;
Packit Service fa4841
	lpszEnvironmentBlock = NULL;
Packit Service fa4841
	pArgs = CommandLineToArgvA(lpCommandLine, &numArgs);
Packit Service fa4841
Packit Service fa4841
	if (!pArgs)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	token = (WINPR_ACCESS_TOKEN*)hToken;
Packit Service fa4841
Packit Service fa4841
	if (lpEnvironment)
Packit Service fa4841
	{
Packit Service fa4841
		envp = EnvironmentBlockToEnvpA(lpEnvironment);
Packit Service fa4841
	}
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service fa4841
		lpszEnvironmentBlock = GetEnvironmentStrings();
Packit Service fa4841
Packit Service fa4841
		if (!lpszEnvironmentBlock)
Packit Service fa4841
			goto finish;
Packit Service fa4841
Packit Service fa4841
		envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (!envp)
Packit Service fa4841
		goto finish;
Packit Service fa4841
Packit Service fa4841
	filename = FindApplicationPath(pArgs[0]);
Packit Service fa4841
Packit Service fa4841
	if (NULL == filename)
Packit Service fa4841
		goto finish;
Packit Service fa4841
Packit Service fa4841
	/* block all signals so that the child can safely reset the caller's handlers */
Packit Service fa4841
	sigfillset(&newSigMask);
Packit Service fa4841
	restoreSigMask = !pthread_sigmask(SIG_SETMASK, &newSigMask, &oldSigMask);
Packit Service fa4841
	/* fork and exec */
Packit Service fa4841
	pid = fork();
Packit Service fa4841
Packit Service fa4841
	if (pid < 0)
Packit Service fa4841
	{
Packit Service fa4841
		/* fork failure */
Packit Service fa4841
		goto finish;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (pid == 0)
Packit Service fa4841
	{
Packit Service fa4841
		/* child process */
Packit Service fa4841
#ifndef __sun
Packit Service fa4841
		int maxfd;
Packit Service fa4841
#endif
Packit Service fa4841
		int fd;
Packit Service fa4841
		int sig;
Packit Service fa4841
		sigset_t set;
Packit Service fa4841
		struct sigaction act;
Packit Service fa4841
		/* set default signal handlers */
Packit Service fa4841
		memset(&act, 0, sizeof(act));
Packit Service fa4841
		act.sa_handler = SIG_DFL;
Packit Service fa4841
		act.sa_flags = 0;
Packit Service fa4841
		sigemptyset(&act.sa_mask);
Packit Service fa4841
Packit Service fa4841
		for (sig = 1; sig < NSIG; sig++)
Packit Service fa4841
			sigaction(sig, &act, NULL);
Packit Service fa4841
Packit Service fa4841
		/* unblock all signals */
Packit Service fa4841
		sigfillset(&set);
Packit Service fa4841
		pthread_sigmask(SIG_UNBLOCK, &set, NULL);
Packit Service fa4841
Packit Service fa4841
		if (lpStartupInfo)
Packit Service fa4841
		{
Packit Service fa4841
			int handle_fd;
Packit Service fa4841
			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdOutput);
Packit Service fa4841
Packit Service fa4841
			if (handle_fd != -1)
Packit Service fa4841
				dup2(handle_fd, STDOUT_FILENO);
Packit Service fa4841
Packit Service fa4841
			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdError);
Packit Service fa4841
Packit Service fa4841
			if (handle_fd != -1)
Packit Service fa4841
				dup2(handle_fd, STDERR_FILENO);
Packit Service fa4841
Packit Service fa4841
			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdInput);
Packit Service fa4841
Packit Service fa4841
			if (handle_fd != -1)
Packit Service fa4841
				dup2(handle_fd, STDIN_FILENO);
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
#ifdef __sun
Packit Service fa4841
		closefrom(3);
Packit Service fa4841
#else
Packit Service fa4841
#ifdef F_MAXFD // on some BSD derivates
Packit Service fa4841
		maxfd = fcntl(0, F_MAXFD);
Packit Service fa4841
#else
Packit Service fa4841
		maxfd = sysconf(_SC_OPEN_MAX);
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
		for (fd = 3; fd < maxfd; fd++)
Packit Service fa4841
			close(fd);
Packit Service fa4841
Packit Service fa4841
#endif // __sun
Packit Service fa4841
Packit Service fa4841
		if (token)
Packit Service fa4841
		{
Packit Service fa4841
			if (token->GroupId)
Packit Service fa4841
			{
Packit Service fa4841
				int rc = setgid((gid_t)token->GroupId);
Packit Service fa4841
Packit Service fa4841
				if (rc < 0)
Packit Service fa4841
				{
Packit Service fa4841
				}
Packit Service fa4841
				else
Packit Service fa4841
				{
Packit Service fa4841
					initgroups(token->Username, (gid_t)token->GroupId);
Packit Service fa4841
				}
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
			if (token->UserId)
Packit Service fa4841
				setuid((uid_t)token->UserId);
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		/* TODO: add better cwd handling and error checking */
Packit Service fa4841
		if (lpCurrentDirectory && strlen(lpCurrentDirectory) > 0)
Packit Service fa4841
			chdir(lpCurrentDirectory);
Packit Service fa4841
Packit Service fa4841
		if (execve(filename, pArgs, envp) < 0)
Packit Service fa4841
		{
Packit Service fa4841
			/* execve failed - end the process */
Packit Service fa4841
			_exit(1);
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service fa4841
		/* parent process */
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	process = CreateProcessHandle(pid);
Packit Service fa4841
Packit Service fa4841
	if (!process)
Packit Service fa4841
	{
Packit Service fa4841
		goto finish;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	thread = CreateNoneHandle();
Packit Service fa4841
Packit Service fa4841
	if (!thread)
Packit Service fa4841
	{
Packit Service fa4841
		ProcessHandleCloseHandle(process);
Packit Service fa4841
		goto finish;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	lpProcessInformation->hProcess = process;
Packit Service fa4841
	lpProcessInformation->hThread = thread;
Packit Service fa4841
	lpProcessInformation->dwProcessId = (DWORD)pid;
Packit Service fa4841
	lpProcessInformation->dwThreadId = (DWORD)pid;
Packit Service fa4841
	ret = TRUE;
Packit Service fa4841
finish:
Packit Service fa4841
Packit Service fa4841
	/* restore caller's original signal mask */
Packit Service fa4841
	if (restoreSigMask)
Packit Service fa4841
		pthread_sigmask(SIG_SETMASK, &oldSigMask, NULL);
Packit Service fa4841
Packit Service fa4841
	free(filename);
Packit Service fa4841
Packit Service fa4841
	if (pArgs)
Packit Service fa4841
	{
Packit Service fa4841
		HeapFree(GetProcessHeap(), 0, pArgs);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (lpszEnvironmentBlock)
Packit Service fa4841
		FreeEnvironmentStrings(lpszEnvironmentBlock);
Packit Service fa4841
Packit Service fa4841
	if (envp)
Packit Service fa4841
	{
Packit Service fa4841
		int i = 0;
Packit Service fa4841
Packit Service fa4841
		while (envp[i])
Packit Service fa4841
		{
Packit Service fa4841
			free(envp[i]);
Packit Service fa4841
			i++;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		free(envp);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return ret;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
Packit Service fa4841
                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
Packit Service fa4841
                    LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
Packit Service fa4841
                    DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
Packit Service fa4841
                    LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return _CreateProcessExA(NULL, 0, lpApplicationName, lpCommandLine, lpProcessAttributes,
Packit Service fa4841
	                         lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
Packit Service fa4841
	                         lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
Packit Service fa4841
                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
Packit Service fa4841
                    LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
Packit Service fa4841
                    DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
Packit Service fa4841
                    LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine,
Packit Service fa4841
                          LPSECURITY_ATTRIBUTES lpProcessAttributes,
Packit Service fa4841
                          LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
Packit Service fa4841
                          DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
Packit Service fa4841
                          LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return _CreateProcessExA(hToken, 0, lpApplicationName, lpCommandLine, lpProcessAttributes,
Packit Service fa4841
	                         lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
Packit Service fa4841
	                         lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
Packit Service fa4841
                          LPSECURITY_ATTRIBUTES lpProcessAttributes,
Packit Service fa4841
                          LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
Packit Service fa4841
                          DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
Packit Service fa4841
                          LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessWithLogonA(LPCSTR lpUsername, LPCSTR lpDomain, LPCSTR lpPassword,
Packit Service fa4841
                             DWORD dwLogonFlags, LPCSTR lpApplicationName, LPSTR lpCommandLine,
Packit Service fa4841
                             DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
Packit Service fa4841
                             LPSTARTUPINFOA lpStartupInfo,
Packit Service fa4841
                             LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessWithLogonW(LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword,
Packit Service fa4841
                             DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
Packit Service fa4841
                             DWORD dwCreationFlags, LPVOID lpEnvironment,
Packit Service fa4841
                             LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo,
Packit Service fa4841
                             LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessWithTokenA(HANDLE hToken, DWORD dwLogonFlags, LPCSTR lpApplicationName,
Packit Service fa4841
                             LPSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
Packit Service fa4841
                             LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo,
Packit Service fa4841
                             LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return _CreateProcessExA(NULL, 0, lpApplicationName, lpCommandLine, NULL, NULL, FALSE,
Packit Service fa4841
	                         dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
Packit Service fa4841
	                         lpProcessInformation);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL CreateProcessWithTokenW(HANDLE hToken, DWORD dwLogonFlags, LPCWSTR lpApplicationName,
Packit Service fa4841
                             LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
Packit Service fa4841
                             LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo,
Packit Service fa4841
                             LPPROCESS_INFORMATION lpProcessInformation)
Packit Service fa4841
{
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
VOID ExitProcess(UINT uExitCode)
Packit Service fa4841
{
Packit Service fa4841
	exit((int)uExitCode);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode)
Packit Service fa4841
{
Packit Service fa4841
	WINPR_PROCESS* process;
Packit Service fa4841
Packit Service fa4841
	if (!hProcess)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!lpExitCode)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	process = (WINPR_PROCESS*)hProcess;
Packit Service fa4841
	*lpExitCode = process->dwExitCode;
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
HANDLE _GetCurrentProcess(VOID)
Packit Service fa4841
{
Packit Service fa4841
	return NULL;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
DWORD GetCurrentProcessId(VOID)
Packit Service fa4841
{
Packit Service fa4841
	return ((DWORD)getpid());
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode)
Packit Service fa4841
{
Packit Service fa4841
	WINPR_PROCESS* process;
Packit Service fa4841
	process = (WINPR_PROCESS*)hProcess;
Packit Service fa4841
Packit Service fa4841
	if (!process || (process->pid <= 0))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (kill(process->pid, SIGTERM))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL ProcessHandleCloseHandle(HANDLE handle)
Packit Service fa4841
{
Packit Service fa4841
	WINPR_PROCESS* process = (WINPR_PROCESS*)handle;
Packit Service fa4841
	free(process);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL ProcessHandleIsHandle(HANDLE handle)
Packit Service fa4841
{
Packit Service fa4841
	WINPR_PROCESS* process = (WINPR_PROCESS*)handle;
Packit Service fa4841
Packit Service fa4841
	if (!process || process->Type != HANDLE_TYPE_PROCESS)
Packit Service fa4841
	{
Packit Service fa4841
		SetLastError(ERROR_INVALID_HANDLE);
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static int ProcessGetFd(HANDLE handle)
Packit Service fa4841
{
Packit Service fa4841
	WINPR_PROCESS* process = (WINPR_PROCESS*)handle;
Packit Service fa4841
Packit Service fa4841
	if (!ProcessHandleIsHandle(handle))
Packit Service fa4841
		return -1;
Packit Service fa4841
Packit Service fa4841
	/* TODO: Process does not support fd... */
Packit Service fa4841
	(void)process;
Packit Service fa4841
	return -1;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static HANDLE_OPS ops = { ProcessHandleIsHandle,
Packit Service fa4841
	                      ProcessHandleCloseHandle,
Packit Service fa4841
	                      ProcessGetFd,
Packit Service fa4841
	                      NULL, /* CleanupHandle */
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL,
Packit Service fa4841
	                      NULL };
Packit Service fa4841
Packit Service fa4841
HANDLE CreateProcessHandle(pid_t pid)
Packit Service fa4841
{
Packit Service fa4841
	WINPR_PROCESS* process;
Packit Service fa4841
	process = (WINPR_PROCESS*)calloc(1, sizeof(WINPR_PROCESS));
Packit Service fa4841
Packit Service fa4841
	if (!process)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	process->pid = pid;
Packit Service fa4841
	process->Type = HANDLE_TYPE_PROCESS;
Packit Service fa4841
	process->ops = &ops;
Packit Service fa4841
	return (HANDLE)process;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
#endif