4 #include <winpr/tchar.h>
5 #include <winpr/synch.h>
6 #include <winpr/thread.h>
7 #include <winpr/environment.h>
8 #include <winpr/pipe.h>
10 #define TESTENV_A "HELLO=WORLD"
11 #define TESTENV_T _T(TESTENV_A)
13 int TestThreadCreateProcess(
int argc,
char* argv[])
17 LPCTSTR lpApplicationName = NULL;
20 TCHAR lpCommandLine[200] = _T(
"cmd /C set");
22 TCHAR lpCommandLine[200] = _T(
"printenv");
26 LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL;
27 LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
28 BOOL bInheritHandles = 0;
29 DWORD dwCreationFlags = 0;
30 LPVOID lpEnvironment = NULL;
31 LPCTSTR lpCurrentDirectory = NULL;
33 PROCESS_INFORMATION ProcessInformation = { 0 };
34 LPTCH lpszEnvironmentBlock = NULL;
35 HANDLE pipe_read = NULL;
36 HANDLE pipe_write = NULL;
37 char buf[1024] = { 0 };
40 SECURITY_ATTRIBUTES saAttr;
45 lpszEnvironmentBlock = GetEnvironmentStrings();
47 lpApplicationName = NULL;
49 lpProcessAttributes = NULL;
50 lpThreadAttributes = NULL;
51 bInheritHandles = FALSE;
54 dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
56 lpEnvironment = lpszEnvironmentBlock;
57 lpCurrentDirectory = NULL;
60 status = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
61 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
62 lpCurrentDirectory, &StartupInfo, &ProcessInformation);
66 printf(
"CreateProcess failed. error=%" PRIu32
"\n", GetLastError());
70 if (WaitForSingleObject(ProcessInformation.hProcess, 5000) != WAIT_OBJECT_0)
72 printf(
"Failed to wait for first process. error=%" PRIu32
"\n", GetLastError());
77 status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
79 printf(
"GetExitCodeProcess status: %" PRId32
"\n", status);
80 printf(
"Process exited with code: 0x%08" PRIX32
"\n", exitCode);
82 (void)CloseHandle(ProcessInformation.hProcess);
83 (void)CloseHandle(ProcessInformation.hThread);
84 FreeEnvironmentStrings(lpszEnvironmentBlock);
88 saAttr.nLength =
sizeof(SECURITY_ATTRIBUTES);
89 saAttr.bInheritHandle = TRUE;
90 saAttr.lpSecurityDescriptor = NULL;
92 if (!CreatePipe(&pipe_read, &pipe_write, &saAttr, 0))
94 printf(
"Pipe creation failed. error=%" PRIu32
"\n", GetLastError());
98 bInheritHandles = TRUE;
102 StartupInfo.hStdOutput = pipe_write;
103 StartupInfo.hStdError = pipe_write;
104 StartupInfo.dwFlags = STARTF_USESTDHANDLES;
106 ZeroMemory(&ProcessInformation,
sizeof(PROCESS_INFORMATION));
108 if (!(lpEnvironment = calloc(1,
sizeof(TESTENV_T) +
sizeof(TCHAR))))
110 printf(
"Failed to allocate environment buffer. error=%" PRIu32
"\n", GetLastError());
113 memcpy(lpEnvironment, (
void*)TESTENV_T,
sizeof(TESTENV_T));
115 status = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
116 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
117 lpCurrentDirectory, &StartupInfo, &ProcessInformation);
123 (void)CloseHandle(pipe_read);
124 (void)CloseHandle(pipe_write);
125 printf(
"CreateProcess failed. error=%" PRIu32
"\n", GetLastError());
129 if (WaitForSingleObject(ProcessInformation.hProcess, 5000) != WAIT_OBJECT_0)
131 printf(
"Failed to wait for second process. error=%" PRIu32
"\n", GetLastError());
135 ZeroMemory(buf,
sizeof(buf));
136 ReadFile(pipe_read, buf,
sizeof(buf) - 1, &read_bytes, NULL);
137 if (!strstr((
const char*)buf, TESTENV_A))
139 printf(
"No or unexpected data read from pipe\n");
143 (void)CloseHandle(pipe_read);
144 (void)CloseHandle(pipe_write);
147 status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
149 printf(
"GetExitCodeProcess status: %" PRId32
"\n", status);
150 printf(
"Process exited with code: 0x%08" PRIX32
"\n", exitCode);
152 (void)CloseHandle(ProcessInformation.hProcess);
153 (void)CloseHandle(ProcessInformation.hThread);