Blame winpr/libwinpr/thread/test/TestThreadCreateProcess.c

Packit 1fb8d4
Packit 1fb8d4
#include <stdio.h>
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/tchar.h>
Packit 1fb8d4
#include <winpr/synch.h>
Packit 1fb8d4
#include <winpr/thread.h>
Packit 1fb8d4
#include <winpr/environment.h>
Packit 1fb8d4
#include <winpr/pipe.h>
Packit 1fb8d4
Packit 1fb8d4
#define TESTENV_A "HELLO=WORLD"
Packit 1fb8d4
#define TESTENV_T _T(TESTENV_A)
Packit 1fb8d4
Packit 1fb8d4
int TestThreadCreateProcess(int argc, char* argv[])
Packit 1fb8d4
{
Packit 1fb8d4
	BOOL status;
Packit 1fb8d4
	DWORD exitCode;
Packit 1fb8d4
	LPCTSTR lpApplicationName;
Packit 1fb8d4
	LPTSTR lpCommandLine;
Packit 1fb8d4
	LPSECURITY_ATTRIBUTES lpProcessAttributes;
Packit 1fb8d4
	LPSECURITY_ATTRIBUTES lpThreadAttributes;
Packit 1fb8d4
	BOOL bInheritHandles;
Packit 1fb8d4
	DWORD dwCreationFlags;
Packit 1fb8d4
	LPVOID lpEnvironment;
Packit 1fb8d4
	LPCTSTR lpCurrentDirectory;
Packit 1fb8d4
	STARTUPINFO StartupInfo;
Packit 1fb8d4
	PROCESS_INFORMATION ProcessInformation;
Packit 1fb8d4
	LPTCH lpszEnvironmentBlock;
Packit 1fb8d4
	HANDLE pipe_read = NULL;
Packit 1fb8d4
	HANDLE pipe_write = NULL;
Packit 1fb8d4
	char buf[1024];
Packit 1fb8d4
	DWORD read_bytes;
Packit 1fb8d4
	int ret = 0;
Packit 1fb8d4
	SECURITY_ATTRIBUTES saAttr;
Packit 1fb8d4
Packit 1fb8d4
	lpszEnvironmentBlock = GetEnvironmentStrings();
Packit 1fb8d4
Packit 1fb8d4
	lpApplicationName = NULL;
Packit 1fb8d4
Packit 1fb8d4
#ifdef _WIN32
Packit 1fb8d4
	lpCommandLine = _T("cmd /C set");
Packit 1fb8d4
#else
Packit 1fb8d4
	lpCommandLine = _T("printenv");
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
	lpProcessAttributes = NULL;
Packit 1fb8d4
	lpThreadAttributes = NULL;
Packit 1fb8d4
	bInheritHandles = FALSE;
Packit 1fb8d4
	dwCreationFlags = 0;
Packit 1fb8d4
#ifdef _UNICODE
Packit 1fb8d4
	dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
Packit 1fb8d4
#endif
Packit 1fb8d4
	lpEnvironment = lpszEnvironmentBlock;
Packit 1fb8d4
	lpCurrentDirectory = NULL;
Packit 1fb8d4
	ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
Packit 1fb8d4
	StartupInfo.cb = sizeof(STARTUPINFO);
Packit 1fb8d4
	ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
Packit 1fb8d4
Packit Service 5a9772
	status = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
Packit Service 5a9772
	                       lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
Packit Service 5a9772
	                       lpCurrentDirectory, &StartupInfo, &ProcessInformation);
Packit 1fb8d4
Packit 1fb8d4
	if (!status)
Packit 1fb8d4
	{
Packit Service 5a9772
		printf("CreateProcess failed. error=%" PRIu32 "\n", GetLastError());
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (WaitForSingleObject(ProcessInformation.hProcess, 5000) != WAIT_OBJECT_0)
Packit 1fb8d4
	{
Packit Service 5a9772
		printf("Failed to wait for first process. error=%" PRIu32 "\n", GetLastError());
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	exitCode = 0;
Packit 1fb8d4
	status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
Packit 1fb8d4
Packit Service 5a9772
	printf("GetExitCodeProcess status: %" PRId32 "\n", status);
Packit Service 5a9772
	printf("Process exited with code: 0x%08" PRIX32 "\n", exitCode);
Packit 1fb8d4
Packit 1fb8d4
	CloseHandle(ProcessInformation.hProcess);
Packit 1fb8d4
	CloseHandle(ProcessInformation.hThread);
Packit 1fb8d4
	FreeEnvironmentStrings(lpszEnvironmentBlock);
Packit 1fb8d4
Packit 1fb8d4
	/* Test stdin,stdout,stderr redirection */
Packit 1fb8d4
Packit 1fb8d4
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
Packit 1fb8d4
	saAttr.bInheritHandle = TRUE;
Packit 1fb8d4
	saAttr.lpSecurityDescriptor = NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (!CreatePipe(&pipe_read, &pipe_write, &saAttr, 0))
Packit 1fb8d4
	{
Packit Service 5a9772
		printf("Pipe creation failed. error=%" PRIu32 "\n", GetLastError());
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	bInheritHandles = TRUE;
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
Packit 1fb8d4
	StartupInfo.cb = sizeof(STARTUPINFO);
Packit 1fb8d4
	StartupInfo.hStdOutput = pipe_write;
Packit 1fb8d4
	StartupInfo.hStdError = pipe_write;
Packit 1fb8d4
	StartupInfo.dwFlags = STARTF_USESTDHANDLES;
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
Packit 1fb8d4
Packit 1fb8d4
	if (!(lpEnvironment = calloc(1, sizeof(TESTENV_T) + sizeof(TCHAR))))
Packit 1fb8d4
	{
Packit Service 5a9772
		printf("Failed to allocate environment buffer. error=%" PRIu32 "\n", GetLastError());
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
	memcpy(lpEnvironment, (void*)TESTENV_T, sizeof(TESTENV_T));
Packit 1fb8d4
Packit Service 5a9772
	status = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
Packit Service 5a9772
	                       lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
Packit Service 5a9772
	                       lpCurrentDirectory, &StartupInfo, &ProcessInformation);
Packit 1fb8d4
Packit 1fb8d4
	free(lpEnvironment);
Packit 1fb8d4
Packit 1fb8d4
	if (!status)
Packit 1fb8d4
	{
Packit 1fb8d4
		CloseHandle(pipe_read);
Packit 1fb8d4
		CloseHandle(pipe_write);
Packit Service 5a9772
		printf("CreateProcess failed. error=%" PRIu32 "\n", GetLastError());
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (WaitForSingleObject(ProcessInformation.hProcess, 5000) != WAIT_OBJECT_0)
Packit 1fb8d4
	{
Packit Service 5a9772
		printf("Failed to wait for second process. error=%" PRIu32 "\n", GetLastError());
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(buf, sizeof(buf));
Packit Service 5a9772
	ReadFile(pipe_read, buf, sizeof(buf) - 1, &read_bytes, NULL);
Packit 1fb8d4
	if (!strstr((const char*)buf, TESTENV_A))
Packit 1fb8d4
	{
Packit 1fb8d4
		printf("No or unexpected data read from pipe\n");
Packit 1fb8d4
		ret = 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	CloseHandle(pipe_read);
Packit 1fb8d4
	CloseHandle(pipe_write);
Packit 1fb8d4
Packit 1fb8d4
	exitCode = 0;
Packit 1fb8d4
	status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
Packit 1fb8d4
Packit Service 5a9772
	printf("GetExitCodeProcess status: %" PRId32 "\n", status);
Packit Service 5a9772
	printf("Process exited with code: 0x%08" PRIX32 "\n", exitCode);
Packit 1fb8d4
Packit 1fb8d4
	CloseHandle(ProcessInformation.hProcess);
Packit 1fb8d4
	CloseHandle(ProcessInformation.hThread);
Packit 1fb8d4
Packit 1fb8d4
	return ret;
Packit 1fb8d4
}