Blame winpr/libwinpr/thread/process.c

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