FreeRDP
Loading...
Searching...
No Matches
TestThreadCreateProcess.c
1
2#include <stdio.h>
3#include <winpr/crt.h>
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>
9
10#define TESTENV_A "HELLO=WORLD"
11#define TESTENV_T _T(TESTENV_A)
12
13int TestThreadCreateProcess(int argc, char* argv[])
14{
15 BOOL status = 0;
16 DWORD exitCode = 0;
17 LPCTSTR lpApplicationName = NULL;
18
19#ifdef _WIN32
20 TCHAR lpCommandLine[200] = _T("cmd /C set");
21#else
22 TCHAR lpCommandLine[200] = _T("printenv");
23#endif
24
25 // LPTSTR lpCommandLine;
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;
32 STARTUPINFO StartupInfo = { 0 };
33 PROCESS_INFORMATION ProcessInformation = { 0 };
34 LPTCH lpszEnvironmentBlock = NULL;
35 HANDLE pipe_read = NULL;
36 HANDLE pipe_write = NULL;
37 char buf[1024] = { 0 };
38 DWORD read_bytes = 0;
39 int ret = 0;
41
42 WINPR_UNUSED(argc);
43 WINPR_UNUSED(argv);
44
45 lpszEnvironmentBlock = GetEnvironmentStrings();
46
47 lpApplicationName = NULL;
48
49 lpProcessAttributes = NULL;
50 lpThreadAttributes = NULL;
51 bInheritHandles = FALSE;
52 dwCreationFlags = 0;
53#ifdef _UNICODE
54 dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
55#endif
56 lpEnvironment = lpszEnvironmentBlock;
57 lpCurrentDirectory = NULL;
58 StartupInfo.cb = sizeof(STARTUPINFO);
59
60 status = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
61 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
62 lpCurrentDirectory, &StartupInfo, &ProcessInformation);
63
64 if (!status)
65 {
66 printf("CreateProcess failed. error=%" PRIu32 "\n", GetLastError());
67 return 1;
68 }
69
70 if (WaitForSingleObject(ProcessInformation.hProcess, 5000) != WAIT_OBJECT_0)
71 {
72 printf("Failed to wait for first process. error=%" PRIu32 "\n", GetLastError());
73 return 1;
74 }
75
76 exitCode = 0;
77 status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
78
79 printf("GetExitCodeProcess status: %" PRId32 "\n", status);
80 printf("Process exited with code: 0x%08" PRIX32 "\n", exitCode);
81
82 (void)CloseHandle(ProcessInformation.hProcess);
83 (void)CloseHandle(ProcessInformation.hThread);
84 FreeEnvironmentStrings(lpszEnvironmentBlock);
85
86 /* Test stdin,stdout,stderr redirection */
87
88 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
89 saAttr.bInheritHandle = TRUE;
90 saAttr.lpSecurityDescriptor = NULL;
91
92 if (!CreatePipe(&pipe_read, &pipe_write, &saAttr, 0))
93 {
94 printf("Pipe creation failed. error=%" PRIu32 "\n", GetLastError());
95 return 1;
96 }
97
98 bInheritHandles = TRUE;
99
100 ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
101 StartupInfo.cb = sizeof(STARTUPINFO);
102 StartupInfo.hStdOutput = pipe_write;
103 StartupInfo.hStdError = pipe_write;
104 StartupInfo.dwFlags = STARTF_USESTDHANDLES;
105
106 ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
107
108 if (!(lpEnvironment = calloc(1, sizeof(TESTENV_T) + sizeof(TCHAR))))
109 {
110 printf("Failed to allocate environment buffer. error=%" PRIu32 "\n", GetLastError());
111 return 1;
112 }
113 memcpy(lpEnvironment, (void*)TESTENV_T, sizeof(TESTENV_T));
114
115 status = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
116 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
117 lpCurrentDirectory, &StartupInfo, &ProcessInformation);
118
119 free(lpEnvironment);
120
121 if (!status)
122 {
123 (void)CloseHandle(pipe_read);
124 (void)CloseHandle(pipe_write);
125 printf("CreateProcess failed. error=%" PRIu32 "\n", GetLastError());
126 return 1;
127 }
128
129 if (WaitForSingleObject(ProcessInformation.hProcess, 5000) != WAIT_OBJECT_0)
130 {
131 printf("Failed to wait for second process. error=%" PRIu32 "\n", GetLastError());
132 return 1;
133 }
134
135 ZeroMemory(buf, sizeof(buf));
136 ReadFile(pipe_read, buf, sizeof(buf) - 1, &read_bytes, NULL);
137 if (!strstr((const char*)buf, TESTENV_A))
138 {
139 printf("No or unexpected data read from pipe\n");
140 ret = 1;
141 }
142
143 (void)CloseHandle(pipe_read);
144 (void)CloseHandle(pipe_write);
145
146 exitCode = 0;
147 status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
148
149 printf("GetExitCodeProcess status: %" PRId32 "\n", status);
150 printf("Process exited with code: 0x%08" PRIX32 "\n", exitCode);
151
152 (void)CloseHandle(ProcessInformation.hProcess);
153 (void)CloseHandle(ProcessInformation.hThread);
154
155 return ret;
156}