|
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 |
}
|