/****************************************************************** * init * * generates basic information like: * selfname: the way to reinvoke ourselves * returns: * -1 on error * 0 if parent * doesn't return if child */ static int init(void) { int argc; char** argv; HANDLE ev1, ev2, ev3, hThread; DWORD w, tid; argc = winetest_get_mainargs( &argv ); strcpy(selfname, argv[0]); switch (argc) { case 2: /* the test program */ return 0; case 4: /* the sub-process */ ev1 = (HANDLE)(INT_PTR)atoi(argv[2]); ev2 = (HANDLE)(INT_PTR)atoi(argv[3]); ev3 = CreateEvent(NULL, FALSE, FALSE, NULL); if (ev3 == NULL) ExitProcess(WAIT_ABANDONED); hThread = CreateThread(NULL, 0, sub_thread, ev3, 0, &tid); if (hThread == NULL) ExitProcess(WAIT_ABANDONED); if (!LoadLibraryA("shell32.dll")) ExitProcess(WAIT_ABANDONED); /* signal init of sub-process is done */ SetEvent(ev1); /* wait for parent to have done all its queries */ w = WaitForSingleObject(ev2, WAIT_TIME); if (w != WAIT_OBJECT_0) ExitProcess(w); /* signal sub-thread to terminate */ SetEvent(ev3); w = WaitForSingleObject(hThread, WAIT_TIME); if (w != WAIT_OBJECT_0) ExitProcess(w); GetExitCodeThread(hThread, &w); ExitProcess(w); default: return -1; } }
static BOOL runtime_is_usable(void) { static const char cmdline_format[] = "\"%s\" mscoree check_runtime"; char** argv; char cmdline[MAX_PATH + sizeof(cmdline_format)]; STARTUPINFOA si = {0}; PROCESS_INFORMATION pi; BOOL ret; DWORD exitcode; winetest_get_mainargs(&argv); sprintf(cmdline, cmdline_format, argv[0]); si.cb = sizeof(si); ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcessA failed\n"); if (!ret) return FALSE; CloseHandle(pi.hThread); WaitForSingleObject(pi.hProcess, INFINITE); ret = GetExitCodeProcess(pi.hProcess, &exitcode); CloseHandle(pi.hProcess); ok(ret, "GetExitCodeProcess failed\n"); if (!ret || exitcode != 0) { win_skip(".NET 4.0 runtime is not usable\n"); return FALSE; } return TRUE; }