Files
raven/testdata/native_loader/path_search_client.c
T
Raymond Bennett 29cb00c979 test: CreateProcess finds a program in the folders of PATH
A copy of the program in a folder added to PATH starts by its name alone.

Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: the test client and its registration

(cherry picked from commit 451226102dc3cd3f2447943b24e80ce5141e333e)
2026-10-30 08:25:23 -07:00

52 lines
1.7 KiB
C

#include <windows.h>
// CreateProcess finds a program named alone in the folders of PATH, after the program's folder, the current folder and the system
// folders, as Nim starts gcc.exe. The program copies itself into a folder it then adds to PATH, and starts the copy by its name; the
// copy (started with "child" on its command line) exits with 7. Returns 0, or the number of the check that failed.
static int contains(const WCHAR *text, const WCHAR *part)
{
for (; *text; ++text) {
int index = 0;
while (part[index] && text[index] == part[index])
++index;
if (!part[index])
return 1;
}
return 0;
}
int raven_entry(void)
{
static WCHAR self[MAX_PATH], folder[MAX_PATH + 32], copy[MAX_PATH + 64], path[4096], line[] = L"raven-on-path.exe child";
if (contains(GetCommandLineW(), L" child"))
ExitProcess(7);
if (!GetModuleFileNameW(NULL, self, MAX_PATH) || !GetTempPathW(MAX_PATH, folder))
return 1;
lstrcatW(folder, L"raven-path-search");
CreateDirectoryW(folder, NULL);
lstrcpyW(copy, folder);
lstrcatW(copy, L"\\raven-on-path.exe");
if (!CopyFileW(self, copy, FALSE))
return 2;
const DWORD used = GetEnvironmentVariableW(L"PATH", path, 4000);
if (used >= 4000)
return 3;
if (used)
lstrcatW(path, L";");
lstrcatW(path, folder);
if (!SetEnvironmentVariableW(L"PATH", path))
return 4;
STARTUPINFOW startup = {sizeof startup};
PROCESS_INFORMATION child;
if (!CreateProcessW(NULL, line, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &child))
return 5;
DWORD code = 0;
if (WaitForSingleObject(child.hProcess, 30000) != WAIT_OBJECT_0 || !GetExitCodeProcess(child.hProcess, &code) || code != 7)
return 6;
CloseHandle(child.hThread);
CloseHandle(child.hProcess);
DeleteFileW(copy);
RemoveDirectoryW(folder);
return 0;
}