Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -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 = nullptr;
#ifdef _WIN32
TCHAR lpCommandLine[200] = _T("cmd /C set");
#else
TCHAR lpCommandLine[200] = _T("printenv");
#endif
// LPTSTR lpCommandLine;
LPSECURITY_ATTRIBUTES lpProcessAttributes = nullptr;
LPSECURITY_ATTRIBUTES lpThreadAttributes = nullptr;
BOOL bInheritHandles = 0;
DWORD dwCreationFlags = 0;
LPVOID lpEnvironment = nullptr;
LPCTSTR lpCurrentDirectory = nullptr;
STARTUPINFO StartupInfo = WINPR_C_ARRAY_INIT;
PROCESS_INFORMATION ProcessInformation = WINPR_C_ARRAY_INIT;
LPTCH lpszEnvironmentBlock = nullptr;
HANDLE pipe_read = nullptr;
HANDLE pipe_write = nullptr;
char buf[1024] = WINPR_C_ARRAY_INIT;
DWORD read_bytes = 0;
int ret = 0;
SECURITY_ATTRIBUTES saAttr;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
lpszEnvironmentBlock = GetEnvironmentStrings();
lpApplicationName = nullptr;
lpProcessAttributes = nullptr;
lpThreadAttributes = nullptr;
bInheritHandles = FALSE;
dwCreationFlags = 0;
#ifdef _UNICODE
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
#endif
lpEnvironment = lpszEnvironmentBlock;
lpCurrentDirectory = nullptr;
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);
(void)CloseHandle(ProcessInformation.hProcess);
(void)CloseHandle(ProcessInformation.hThread);
FreeEnvironmentStrings(lpszEnvironmentBlock);
/* Test stdin,stdout,stderr redirection */
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = nullptr;
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)
{
(void)CloseHandle(pipe_read);
(void)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, nullptr);
if (!strstr((const char*)buf, TESTENV_A))
{
printf("No or unexpected data read from pipe\n");
ret = 1;
}
(void)CloseHandle(pipe_read);
(void)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);
(void)CloseHandle(ProcessInformation.hProcess);
(void)CloseHandle(ProcessInformation.hThread);
return ret;
}