Created
February 28, 2022 19:29
-
-
Save mbikovitsky/18a4339f690d86fc340bd4052e12d39a to your computer and use it in GitHub Desktop.
Passing arbitrary data to a child process. Inspired by https://github.com/microsoft/vscode-python/issues/18561#issuecomment-1054306197
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <Windows.h> | |
#pragma pack(push, 1) | |
typedef struct MAGIC_SAUCE | |
{ | |
INT nHandleCount; | |
HANDLE hEvent; | |
} MAGIC_SAUCE; | |
#pragma pack(pop) | |
INT wmain(VOID) | |
{ | |
HRESULT hrResult = E_FAIL; | |
DWORD eWaitStatus = WAIT_FAILED; | |
STARTUPINFOW tOriginalStartupInfo = {0}; | |
MAGIC_SAUCE UNALIGNED * ptSauce = NULL; | |
HANDLE hEventToSignal = NULL; | |
WCHAR wszExecutable[MAX_PATH + 1] = {L'\0'}; | |
DWORD cchCopied = 0; | |
SECURITY_ATTRIBUTES tEventAttributes = {0}; | |
HANDLE hEvent = NULL; | |
MAGIC_SAUCE tSauce = {0}; | |
STARTUPINFOW tNewStartupInfo = {0}; | |
PROCESS_INFORMATION tProcessInfo = {0}; | |
HANDLE ahObjectsToWaitOn[2] = {NULL}; | |
GetStartupInfoW(&tOriginalStartupInfo); | |
if (sizeof(MAGIC_SAUCE) == tOriginalStartupInfo.cbReserved2) | |
{ | |
ptSauce = (MAGIC_SAUCE UNALIGNED *)tOriginalStartupInfo.lpReserved2; | |
if (NULL != ptSauce && 0 == ptSauce->nHandleCount) | |
{ | |
// This is the child process. | |
hEventToSignal = ptSauce->hEvent; | |
if (NULL == hEventToSignal) | |
{ | |
hrResult = E_INVALIDARG; | |
goto lblCleanup; | |
} | |
if (!SetEvent(hEventToSignal)) | |
{ | |
hrResult = HRESULT_FROM_WIN32(GetLastError()); | |
goto lblCleanup; | |
} | |
hrResult = S_OK; | |
goto lblCleanup; | |
} | |
} | |
cchCopied = GetModuleFileNameW(NULL, wszExecutable, ARRAYSIZE(wszExecutable)); | |
if (0 == cchCopied) | |
{ | |
hrResult = HRESULT_FROM_WIN32(GetLastError()); | |
goto lblCleanup; | |
} | |
else if (ARRAYSIZE(wszExecutable) == cchCopied) | |
{ | |
hrResult = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); | |
goto lblCleanup; | |
} | |
tEventAttributes.nLength = sizeof(tEventAttributes); | |
tEventAttributes.bInheritHandle = TRUE; | |
hEvent = CreateEventW(&tEventAttributes, TRUE, FALSE, NULL); | |
if (NULL == hEvent) | |
{ | |
hrResult = HRESULT_FROM_WIN32(GetLastError()); | |
goto lblCleanup; | |
} | |
tSauce.nHandleCount = 0; | |
tSauce.hEvent = hEvent; | |
tNewStartupInfo.cb = sizeof(tNewStartupInfo); | |
tNewStartupInfo.cbReserved2 = sizeof(tSauce); | |
tNewStartupInfo.lpReserved2 = (PBYTE)&tSauce; | |
if (!CreateProcessW(wszExecutable, | |
NULL, | |
NULL, | |
NULL, | |
TRUE, | |
CREATE_UNICODE_ENVIRONMENT, | |
NULL, | |
NULL, | |
&tNewStartupInfo, | |
&tProcessInfo)) | |
{ | |
hrResult = HRESULT_FROM_WIN32(GetLastError()); | |
goto lblCleanup; | |
} | |
ahObjectsToWaitOn[0] = hEvent; | |
ahObjectsToWaitOn[1] = tProcessInfo.hProcess; | |
eWaitStatus = | |
WaitForMultipleObjects(ARRAYSIZE(ahObjectsToWaitOn), ahObjectsToWaitOn, TRUE, INFINITE); | |
if (WAIT_OBJECT_0 != eWaitStatus) | |
{ | |
hrResult = HRESULT_FROM_WIN32(GetLastError()); | |
assert(WAIT_FAILED == eWaitStatus); | |
goto lblCleanup; | |
} | |
hrResult = S_OK; | |
lblCleanup: | |
if (NULL != tProcessInfo.hThread) | |
{ | |
(VOID) CloseHandle(tProcessInfo.hThread); | |
tProcessInfo.hThread = NULL; | |
} | |
if (NULL != tProcessInfo.hProcess) | |
{ | |
(VOID) CloseHandle(tProcessInfo.hProcess); | |
tProcessInfo.hProcess = NULL; | |
} | |
if (NULL != hEvent) | |
{ | |
(VOID) CloseHandle(hEvent); | |
hEvent = NULL; | |
} | |
if (NULL != hEventToSignal) | |
{ | |
(VOID) CloseHandle(hEventToSignal); | |
hEventToSignal = NULL; | |
} | |
return (INT)hrResult; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment