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