/* PID: procexec(const commandline[]) * Executes a program. Returns an "id" representing the new process (or 0 on * failure). */ static cell AMX_NATIVE_CALL n_procexec(AMX *amx, const cell *params) { TCHAR *pgmname; #if defined __WIN32__ || defined _WIN32 || defined WIN32 BOOL IsWinNT; OSVERSIONINFO VerInfo; STARTUPINFO si; SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; PROCESS_INFORMATION pi; #elif defined _Windows HINSTANCE hinst; #elif defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ pid_t pid; #endif amx_StrParam(amx,params[1],pgmname); #if defined __WIN32__ || defined _WIN32 || defined WIN32 /* most of this code comes from a "Borland Network" article, combined * with some knowledge gained from a CodeProject article */ closepipe(); VerInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); GetVersionEx(&VerInfo); IsWinNT = VerInfo.dwPlatformId==VER_PLATFORM_WIN32_NT; if (IsWinNT) { //initialize security descriptor (Windows NT) InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); sa.lpSecurityDescriptor = &sd; } else { sa.lpSecurityDescriptor = NULL; } /* if */ sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; //allow inheritable handles if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) { //create stdin pipe amx_RaiseError(amx, AMX_ERR_NATIVE); return 0; } /* if */ if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) { //create stdout pipe closepipe(); amx_RaiseError(amx, AMX_ERR_NATIVE); return 0; } /* if */ GetStartupInfo(&si); //set startupinfo for the spawned process si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; si.hStdOutput = newstdout; si.hStdError = newstdout; //set the new handles for the child process si.hStdInput = newstdin; /* spawn the child process */ if (!CreateProcess(NULL,(TCHAR*)pgmname,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) { closepipe(); return 0; } /* if */ CloseHandle(pi.hThread); CloseHandle(pi.hProcess); Sleep(100); return pi.dwProcessId; #elif defined _Windows hinst=WinExec(pgmname,SW_SHOW); if (hinst<=32) hinst=0; return (cell)hinst; #elif defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ /* set up communication pipes first */ closepipe(); if (pipe(pipe_to)!=0 || pipe(pipe_from)!=0) { closepipe(); amx_RaiseError(amx, AMX_ERR_NATIVE); return 0; } /* if */ /* attempt to fork */ if ((pid=fork())<0) { closepipe(); amx_RaiseError(amx, AMX_ERR_NATIVE); return 0; } /* if */ if (pid==0) { /* this is the child process */ #define MAX_ARGS 10 TCHAR *args[MAX_ARGS]; int i; dup2(pipe_to[0],STDIN_FILENO); /* replace stdin with the in side of the pipe */ dup2(pipe_from[1],STDOUT_FILENO); /* replace stdout with the out side of the pipe */ close(pipe_to[0]); /* the pipes are no longer needed */ close(pipe_to[1]); close(pipe_from[0]); close(pipe_from[1]); pipe_to[0]=-1; pipe_to[1]=-1; pipe_from[0]=-1; pipe_from[1]=-1; /* split off the option(s) */ assert(MAX_ARGS>=2); /* args[0] is reserved */ memset(args,0,MAX_ARGS*sizeof(TCHAR*)); args[0]=pgmname; for (i=1; i<MAX_ARGS && args[i-1]!=NULL; i++) { if ((args[i]=strchr(args[i-1],' '))!=NULL) { args[i][0]='\0'; args[i]+=1; } /* if */ } /* for */ /* replace the child fork with a new process */ if(execvp(pgmname,args)<0) return 0; } else { close(pipe_to[0]); /* close unused pipes */ close(pipe_from[1]); pipe_to[0]=-1; pipe_from[1]=-1; } /* if */ return pid; #else return (system(pgmname)==0); #endif }
int main(int argc, char **argv) { #ifdef WINDOWS HANDLE event; char cmdline[128]; if (argc == 1) { /* parent process */ STARTUPINFO si = { sizeof(STARTUPINFO) }; PROCESS_INFORMATION pi; HANDLE job, job2, job3; JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit = {0,}; DWORD exitcode = (DWORD)-1; /* For synchronization we create an inherited event */ SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE/*inherit*/}; event = CreateEvent(&sa, FALSE/*manual reset*/, FALSE/*start unset*/, NULL); if (event == NULL) print("Failed to create event"); _snprintf(cmdline, BUFFER_SIZE_ELEMENTS(cmdline), "%s %p", argv[0], event); print("creating child #1\n"); if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/, 0, NULL, NULL, &si, &pi)) print("CreateProcess failure\n"); WaitForSingleObject(event, INFINITE); print("terminating child #1 by NtTerminateProcess\n"); TerminateProcess(pi.hProcess, 42); WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &exitcode); print("child #1 exit code = %d\n", exitcode); if (!ResetEvent(event)) print("Failed to reset event\n"); print("creating child #2\n"); if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) print("CreateProcess failure\n"); job = CreateJobObject(NULL, "drx-test job"); AssignProcessToJobObject(job, pi.hProcess); ResumeThread(pi.hThread); CloseHandle(pi.hThread); WaitForSingleObject(event, INFINITE); print("terminating child #2 by NtTerminateJobObject\n"); TerminateJobObject(job, 123456); CloseHandle(job); WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &exitcode); print("child #2 exit code = %d\n", exitcode); if (!ResetEvent(event)) print("Failed to reset event\n"); print("creating child #3\n"); if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) print("CreateProcess failure\n"); job = CreateJobObject(NULL, "drx-test job"); AssignProcessToJobObject(job, pi.hProcess); limit.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit, sizeof(limit))) print("SetInformationJobObject failed\n"); ResumeThread(pi.hThread); CloseHandle(pi.hThread); WaitForSingleObject(event, INFINITE); print("terminating child #3 by closing job handle\n"); CloseHandle(job); WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &exitcode); print("child #3 exit code = %d\n", exitcode); /* Test DuplicateHandle (DrMem i#1401) */ print("creating child #4\n"); if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) print("CreateProcess failure\n"); job = CreateJobObject(NULL, "drx-test job"); AssignProcessToJobObject(job, pi.hProcess); limit.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit, sizeof(limit))) print("SetInformationJobObject failed\n"); if (!DuplicateHandle(GetCurrentProcess(), job, GetCurrentProcess(), &job2, 0, FALSE, DUPLICATE_SAME_ACCESS)) print("DuplicateHandle failed\n"); if (!DuplicateHandle(GetCurrentProcess(), job, GetCurrentProcess(), &job3, 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) print("DuplicateHandle failed\n"); ResumeThread(pi.hThread); CloseHandle(pi.hThread); WaitForSingleObject(event, INFINITE); print("terminating child #4 by closing both job handles\n"); CloseHandle(job2); CloseHandle(job3); WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &exitcode); print("child #4 exit code = %d\n", exitcode); } else { /* child process */ int iter = 0; if (sscanf(argv[1], "%p", &event) != 1) { print("Failed to obtain event handle from %s\n", argv[1]); return -1; } if (!SetEvent(event)) print("Failed to set event\n"); /* spin until parent kills us or we time out */ while (iter++ < 12) { Sleep(5000); } } CloseHandle(event); #else /* WINDOWS */ int pipefd[2]; pid_t cpid; char buf = 0; if (pipe(pipefd) == -1) { perror("pipe"); exit(1); } print("creating child\n"); cpid = fork(); if (cpid == -1) { perror("fork"); exit(1); } else if (cpid > 0) { /* parent */ int status; close(pipefd[1]); /* close unused write end */ if (read(pipefd[0], &buf, sizeof(buf)) <= 0) { perror("pipe read failed"); exit(1); } print("terminating child by sending SIGKILL\n"); kill(cpid, SIGKILL); wait(&status); /* wait for child */ close(pipefd[0]); print("child exit code = %d\n", status); } else { /* child */ int iter = 0; close(pipefd[0]); /* close unused read end */ write(pipefd[1], &buf, sizeof(buf)); close(pipefd[1]); /* spin until parent kills us or we time out */ while (iter++ < 12) { sleep(5); } } #endif /* UNIX */ return 0; }
INT WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow) { LPCTSTR lpCmd = GetCommandLine(); TCHAR szAppPath[MAX_PATH], szData[MAX_PATH]; DWORD dwIndex, dwSize, dwType, dwData; PROCESS_INFORMATION pi; STARTUPINFOW si; BOOL bRunApps = FALSE; HKEY hKey; while (*lpCmd) { while (*lpCmd && *lpCmd != _T('/') && *lpCmd != _T('-')) lpCmd++; if (!*lpCmd) break; if (*++lpCmd == _T('r')) bRunApps = TRUE; lpCmd++; } if (bRunApps) { if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { for (dwIndex = 0; ; dwIndex++) { dwSize = sizeof(szAppPath); dwData = sizeof(szData) / sizeof(TCHAR); if (RegEnumValue(hKey, dwIndex, szAppPath, &dwSize, NULL, &dwType, (LPBYTE)szData, &dwData) == ERROR_SUCCESS) { RegDeleteValue(hKey, szAppPath); if (dwType != REG_SZ) continue; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOW; if (!CreateProcess(NULL, szData, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) continue; WaitForSingleObjectEx(pi.hProcess, INFINITE, TRUE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } } RegCloseKey(hKey); } return 1; } DialogBox(hInst, MAKEINTRESOURCE(IDD_RUNONCE_DLG), NULL, RunOnceDlgProc); return 0; }
bool CCommonAppUtils::LaunchApplication(const CString& sCommandLine, UINT idErrMessageFormat, bool bWaitForStartup, CString *cwd, bool uac) { CString theCWD = sOrigCWD; if (cwd != NULL) theCWD = *cwd; if (uac) { CString file, param; SHELLEXECUTEINFO shellinfo; memset(&shellinfo, 0, sizeof(shellinfo)); shellinfo.cbSize = sizeof(shellinfo); shellinfo.hwnd = NULL; shellinfo.lpVerb = _T("runas"); shellinfo.nShow = SW_SHOWNORMAL; shellinfo.fMask = SEE_MASK_NOCLOSEPROCESS; shellinfo.lpDirectory = theCWD; int pos = sCommandLine.Find('"'); if (pos == 0) { pos = sCommandLine.Find('"', 2); if (pos > 1) { file = sCommandLine.Mid(1, pos - 1); param = sCommandLine.Mid(pos + 1); } else { if (idErrMessageFormat != 0) { CString temp; temp.Format(idErrMessageFormat, CFormatMessageWrapper()); MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); } return false; } } else { pos = sCommandLine.Find(' ', 1); if (pos > 0) { file = sCommandLine.Mid(0, pos); param = sCommandLine.Mid(pos + 1); } else file = sCommandLine; } shellinfo.lpFile = file; shellinfo.lpParameters = param; if (!ShellExecuteEx(&shellinfo)) { if (idErrMessageFormat != 0) { CString temp; temp.Format(idErrMessageFormat, (CString)CFormatMessageWrapper()); MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); } return false; } if (bWaitForStartup) { WaitForInputIdle(shellinfo.hProcess, 10000); } CloseHandle(shellinfo.hProcess); } else { STARTUPINFO startup; PROCESS_INFORMATION process; memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); memset(&process, 0, sizeof(process)); CString cleanCommandLine(sCommandLine); if (CreateProcess(NULL, const_cast<TCHAR*>((LPCTSTR)cleanCommandLine), NULL, NULL, FALSE, 0, 0, theCWD, &startup, &process)==0) { if(idErrMessageFormat != 0) { CString temp; temp.Format(idErrMessageFormat, (CString)CFormatMessageWrapper()); MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION); } return false; } AllowSetForegroundWindow(process.dwProcessId); if (bWaitForStartup) { WaitForInputIdle(process.hProcess, 10000); } CloseHandle(process.hThread); CloseHandle(process.hProcess); } return true; }
/* Run a command and redirect its input and output handles to a pair of anonymous pipes. The process handle and pipe handles are returned in the info struct. Returns the PID of the new process, or -1 on error. */ static int run_command_redirected(char *cmdexec, struct subprocess_info *info) { /* Each named pipe we create has to have a unique name. */ static int pipe_serial_no = 0; char pipe_name[32]; SECURITY_ATTRIBUTES sa; STARTUPINFO si; PROCESS_INFORMATION pi; /* Make the pipe handles inheritable. */ sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; /* The child's input pipe is an ordinary blocking pipe. */ if (CreatePipe(&info->child_in_r, &info->child_in_w, &sa, 0) == 0) { if (o.verbose) logdebug("Error in CreatePipe: %d\n", GetLastError()); return -1; } /* Pipe names must have this special form. */ Snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\ncat-%d-%d", GetCurrentProcessId(), pipe_serial_no); if (o.debug > 1) logdebug("Creating named pipe \"%s\"\n", pipe_name); /* The output pipe has to be nonblocking, which requires this complicated setup. */ info->child_out_r = CreateNamedPipe(pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 4096, 4096, 1000, &sa); if (info->child_out_r == 0) { if (o.verbose) logdebug("Error in CreateNamedPipe: %d\n", GetLastError()); CloseHandle(info->child_in_r); CloseHandle(info->child_in_w); return -1; } info->child_out_w = CreateFile(pipe_name, GENERIC_WRITE, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (info->child_out_w == 0) { CloseHandle(info->child_in_r); CloseHandle(info->child_in_w); CloseHandle(info->child_out_r); return -1; } pipe_serial_no++; /* Don't inherit our end of the pipes. */ SetHandleInformation(info->child_in_w, HANDLE_FLAG_INHERIT, 0); SetHandleInformation(info->child_out_r, HANDLE_FLAG_INHERIT, 0); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdInput = info->child_in_r; si.hStdOutput = info->child_out_w; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; memset(&pi, 0, sizeof(pi)); if (CreateProcess(NULL, cmdexec, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == 0) { if (o.verbose) logdebug("Error in CreateProcess: %d\n", GetLastError()); CloseHandle(info->child_in_r); CloseHandle(info->child_in_w); CloseHandle(info->child_out_r); CloseHandle(info->child_out_w); return -1; } /* Close hThread here because we have no use for it. hProcess is closed in subprocess_info_close. */ CloseHandle(pi.hThread); info->proc = pi.hProcess; return pi.dwProcessId; }
int ExecFile(const char *pszFilePath, char *lpFile) { DWORD dwBytes; void *lpImageBase = NULL; // check the image dos header IMAGE_DOS_HEADER *pImageDosHeader = (IMAGE_DOS_HEADER *) lpFile; if(pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return FALSE; } // check the image nt headers IMAGE_NT_HEADERS *pImageNtHeaders = (IMAGE_NT_HEADERS *)(lpFile + pImageDosHeader->e_lfanew); if(pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) { return FALSE; } // start the new process which we will overwrite later STARTUPINFOA StartupInfo = {sizeof(STARTUPINFOA)}; PROCESS_INFORMATION ProcessInformation = {0}; if(CreateProcess(pszFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInformation) == FALSE) { return FALSE; } // read the base address of the executable loaded in the // process which we will inject CONTEXT ctx = {CONTEXT_FULL}; DWORD dwImageBase; if(GetThreadContext(ProcessInformation.hThread, &ctx) == FALSE || ReadProcessMemory(ProcessInformation.hProcess, (void *)(ctx.Ebx + 8), &dwImageBase, 4, &dwBytes) == FALSE || dwBytes != 4) { goto cleanup; } // unmap the loaded binary if the base address conflicts // with the binary which we want to load if(dwImageBase == pImageNtHeaders->OptionalHeader.ImageBase) { LP_NtUnmapViewOfSection pNtUnmapViewOfSection = (LP_NtUnmapViewOfSection) GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"); pNtUnmapViewOfSection(ProcessInformation.hProcess, dwImageBase); } // allocate memory in the remote process for our binary lpImageBase = VirtualAllocEx(ProcessInformation.hProcess, (void *) pImageNtHeaders->OptionalHeader.ImageBase, pImageNtHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if(lpImageBase == NULL) { goto cleanup; } // write the headers of our binary to the process if(WriteProcessMemory(ProcessInformation.hProcess, lpImageBase, lpFile, pImageNtHeaders->OptionalHeader.SizeOfHeaders, &dwBytes) == FALSE || dwBytes != pImageNtHeaders->OptionalHeader.SizeOfHeaders) { goto cleanup; } // enumerate all the sections in this binary IMAGE_SECTION_HEADER *pImageSectionHeader = (IMAGE_SECTION_HEADER *)( lpFile + pImageDosHeader->e_lfanew + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD) + pImageNtHeaders->FileHeader.SizeOfOptionalHeader); for (int i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++, pImageSectionHeader++) { // if this section has no size_of_raw_data, then we skip it because // there is nothing to write if(pImageSectionHeader->SizeOfRawData == 0) continue; // and write each section to the correct address in the process if(WriteProcessMemory(ProcessInformation.hProcess, (char *) lpImageBase + pImageSectionHeader->VirtualAddress, lpFile + pImageSectionHeader->PointerToRawData, pImageSectionHeader->SizeOfRawData, &dwBytes) == FALSE || pImageSectionHeader->SizeOfRawData != dwBytes) { goto cleanup; } } // write the new image base address if(WriteProcessMemory(ProcessInformation.hProcess, (void *)(ctx.Ebx + 8), &lpImageBase, 4, &dwBytes) == FALSE || dwBytes != 4) { goto cleanup; } // store the new entry point ctx.Eax = (DWORD) lpImageBase + pImageNtHeaders->OptionalHeader.AddressOfEntryPoint; // write the new context containing the updated entry point to the process SetThreadContext(ProcessInformation.hThread, &ctx); // resume the main thread, start the application ResumeThread(ProcessInformation.hThread); // clean up our resources CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); return TRUE; cleanup: // clean up our resources if(lpImageBase != NULL) { VirtualFreeEx(ProcessInformation.hProcess, lpImageBase, 0, MEM_RELEASE); } CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); return FALSE; }
int main (int argc, char *argv[]) { char psBuffer[BUFFER_SIZE]; char psGnuplotCommandLine[MAX_PATH] = PROGNAME; LPTSTR psCmdLine; BOOL bSuccess; BOOL bPersist = FALSE; int i; #if !defined(_O_BINARY) && defined(O_BINARY) # define _O_BINARY O_BINARY # define _setmode setmode /* this is for BC4.5 ... */ #endif _setmode(fileno(stdout), _O_BINARY); for (i = 1; i < argc; i++) { if (!argv[i]) continue; if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) { printf("gnuplot %s patchlevel %s\n", gnuplot_version, gnuplot_patchlevel); return 0; } else if ((!stricmp(argv[i], "-noend")) || (!stricmp(argv[i], "/noend")) || (!stricmp(argv[i], "-persist"))) { bPersist = TRUE; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { printf("Usage: gnuplot [OPTION] [FILE] [-]\n" " -V, --version show gnuplot version\n" " -h, --help show this help\n" " -e \"cmd; cmd; ...\" prepand additional commands\n" " -persist don't close the plot after executing FILE\n" " -noend, /noend like -persist (non-portable Windows-only options)\n" " - allow work in interactive mode after executing FILE\n" "Only on Windows, -persist and - have the same effect.\n" "This is gnuplot %s patchlevel %s\n" "Report bugs to <*****@*****.**>\n", gnuplot_version, gnuplot_patchlevel); return 0; } } /* for(argc) */ /* CRS: create the new command line, passing all of the command * line options to wgnuplot so that it can process them: * first, get the command line, * then move past the name of the program (e.g., 'pgnuplot'), * finally, add what's left of the line onto the gnuplot command line. */ psCmdLine = GetCommandLine(); #ifdef SHOWCMDLINE fprintf(stderr,"CmdLine: %s\n", psCmdLine); fprintf(stderr,"argv[0]: %s\n",argv[0]); #endif /* CRS 30061999: Search for the first unquoted space. This should separate the program name from the arguments. */ psCmdLine = FindUnquotedSpace(psCmdLine); strncat(psGnuplotCommandLine, psCmdLine, MAX_PATH - strlen(psGnuplotCommandLine)); #ifdef SHOWCMDLINE fprintf(stderr,"Arguments: %s\n", psCmdLine); fprintf(stderr,"GnuplotCommandLine: %s\n",psGnuplotCommandLine); #endif /* CRS: if stdin isn't redirected then just launch wgnuplot normally * and exit. */ if (isatty(fileno(stdin))) { if (WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31) { exit(EXIT_SUCCESS); } fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n", GetLastError(), psGnuplotCommandLine); exit(EXIT_FAILURE); } /* CRS: initialize the STARTUPINFO and call CreateProcess(). */ siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.lpReserved = NULL; siStartInfo.lpReserved2 = NULL; siStartInfo.cbReserved2 = 0; siStartInfo.lpDesktop = NULL; siStartInfo.dwFlags = STARTF_USESHOWWINDOW; siStartInfo.wShowWindow = SW_SHOWMINIMIZED; bSuccess = CreateProcess( NULL, /* pointer to name of executable module */ psGnuplotCommandLine, /* pointer to command line string */ NULL, /* pointer to process security attributes */ NULL, /* pointer to thread security attributes */ FALSE, /* handle inheritance flag */ 0, /* creation flags */ NULL, /* pointer to new environment block */ NULL, /* pointer to current directory name */ &siStartInfo, /* pointer to STARTUPINFO */ &piProcInfo /* pointer to PROCESS_INFORMATION */ ); /* if CreateProcess() failed, print a warning and exit. */ if (! bSuccess) { fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n", GetLastError(), psGnuplotCommandLine); exit(EXIT_FAILURE); } /* CRS: give gnuplot enough time to start (1 sec.) */ if (WaitForInputIdle(piProcInfo.hProcess, 1000)) { fprintf(stderr, "Timeout: gnuplot is not ready\n"); exit(EXIT_FAILURE); } /* CRS: get the HWND of the parent window and text windows */ EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0); if (! hwndParent || ! hwndText) { /* Still no gnuplot window? Problem! */ fprintf(stderr, "Can't find the gnuplot window"); /* CRS: free the process and thread handles */ CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); exit(EXIT_FAILURE); } /* wait for commands on stdin, and pass them on to the wgnuplot text * window */ while (fgets(psBuffer, BUFFER_SIZE, stdin) != NULL) { /* RWH: Check if wgnuplot is still alive */ if (!ProcessAlive(piProcInfo.hProcess)) break; PostString(hwndText, psBuffer); } /* exit gracefully, unless -persist is requested */ if (!bPersist && ProcessAlive(piProcInfo.hProcess)) { PostString(hwndText, "\nexit\n"); } /* CRS: free the process and thread handles */ CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); return EXIT_SUCCESS; }
NS_IMETHODIMP nsDebugImpl::Assertion(const char *aStr, const char *aExpr, const char *aFile, PRInt32 aLine) { InitLog(); char buf[1000]; PR_snprintf(buf, sizeof(buf), "###!!! ASSERTION: %s: '%s', file %s, line %d", aStr, aExpr, aFile, aLine); // Write out the assertion message to the debug log PR_LOG(gDebugLog, PR_LOG_ERROR, ("%s", buf)); PR_LogFlush(); // And write it out to the stderr fprintf(stderr, "%s\n", buf); fflush(stderr); #if defined(_WIN32) char* assertBehavior = getenv("XPCOM_DEBUG_BREAK"); if (assertBehavior && strcmp(assertBehavior, "warn") == 0) return NS_OK; if(!InDebugger()) { DWORD code = IDRETRY; /* Create the debug dialog out of process to avoid the crashes caused by * Windows events leaking into our event loop from an in process dialog. * We do this by launching windbgdlg.exe (built in xpcom/windbgdlg). * See http://bugzilla.mozilla.org/show_bug.cgi?id=54792 */ PROCESS_INFORMATION pi; STARTUPINFO si; char executable[MAX_PATH]; char* pName; memset(&pi, 0, sizeof(pi)); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.wShowWindow = SW_SHOW; if(GetModuleFileName(GetModuleHandle(XPCOM_DLL), executable, MAX_PATH) && NULL != (pName = strrchr(executable, '\\')) && NULL != strcpy(pName+1, "windbgdlg.exe") && #ifdef DEBUG_jband (printf("Launching %s\n", executable), PR_TRUE) && #endif CreateProcess(executable, buf, NULL, NULL, PR_FALSE, DETACHED_PROCESS | NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi) && WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE) && GetExitCodeProcess(pi.hProcess, &code)) { CloseHandle(pi.hProcess); } switch(code) { case IDABORT: //This should exit us raise(SIGABRT); //If we are ignored exit this way.. _exit(3); break; case IDIGNORE: return NS_OK; // Fall Through } } #endif #if defined(XP_OS2) char* assertBehavior = getenv("XPCOM_DEBUG_BREAK"); if (assertBehavior && strcmp(assertBehavior, "warn") == 0) return NS_OK; char msg[1200]; PR_snprintf(msg, sizeof(msg), "%s\n\nClick Cancel to Debug Application.\n" "Click Enter to continue running the Application.", buf); ULONG code = MBID_ERROR; code = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg, "nsDebug::Assertion", 0, MB_ERROR | MB_ENTERCANCEL); /* It is possible that we are executing on a thread that doesn't have a * message queue. In that case, the message won't appear, and code will * be 0xFFFF. We'll give the user a chance to debug it by calling * Break() * Actually, that's a really bad idea since this happens a lot with threadsafe * assertions and since it means that you can't actually run the debug build * outside a debugger without it crashing constantly. */ if(( code == MBID_ENTER ) || (code == MBID_ERROR)) { return NS_OK; // If Retry, Fall Through } #endif Break(aFile, aLine); return NS_OK; }
// *** Private methods *** STDMETHODIMP CShellExt::InvokeNPP(HWND /*hParent*/, LPCSTR /*pszWorkingDir*/, LPCSTR /*pszCmd*/, LPCSTR /*pszParam*/, int iShowCmd) { TCHAR szFilename[MAX_PATH]; TCHAR szCustom[MAX_PATH]; LPTSTR pszCommand; size_t bytesRequired = 1; TCHAR szKeyTemp[MAX_PATH + GUID_STRING_SIZE]; DWORD regSize = 0; DWORD pathSize = MAX_PATH; HKEY settingKey; LONG result; wsprintf(szKeyTemp, TEXT("CLSID\\%s\\Settings"), szGUID); result = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyTemp, 0, KEY_READ, &settingKey); if (result != ERROR_SUCCESS) { MsgBoxError(TEXT("Unable to open registry key.")); return E_FAIL; } result = RegQueryValueEx(settingKey, TEXT("Path"), NULL, NULL, NULL, ®Size); if (result == ERROR_SUCCESS) { bytesRequired += regSize+2; } else { MsgBoxError(TEXT("Cannot read path to executable.")); RegCloseKey(settingKey); return E_FAIL; } result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, NULL, ®Size); if (result == ERROR_SUCCESS) { bytesRequired += regSize; } for (UINT i = 0; i < m_cbFiles; i++) { bytesRequired += DragQueryFile((HDROP)m_stgMedium.hGlobal, i, NULL, 0); bytesRequired += 3; } bytesRequired *= sizeof(TCHAR); pszCommand = (LPTSTR)CoTaskMemAlloc(bytesRequired); if (!pszCommand) { MsgBoxError(TEXT("Insufficient memory available.")); RegCloseKey(settingKey); return E_FAIL; } *pszCommand = 0; regSize = (DWORD)MAX_PATH*sizeof(TCHAR); result = RegQueryValueEx(settingKey, TEXT("Path"), NULL, NULL, (LPBYTE)(szFilename), ®Size); szFilename[MAX_PATH-1] = 0; lstrcat(pszCommand, TEXT("\"")); lstrcat(pszCommand, szFilename); lstrcat(pszCommand, TEXT("\"")); result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, (LPBYTE)(szCustom), &pathSize); if (result == ERROR_SUCCESS) { lstrcat(pszCommand, TEXT(" ")); lstrcat(pszCommand, szCustom); } RegCloseKey(settingKey); for (UINT i = 0; i < m_cbFiles; i++) { DragQueryFile((HDROP)m_stgMedium.hGlobal, i, szFilename, MAX_PATH); lstrcat(pszCommand, TEXT(" \"")); lstrcat(pszCommand, szFilename); lstrcat(pszCommand, TEXT("\"")); } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = (WORD)iShowCmd; //SW_RESTORE; if (!CreateProcess (NULL, pszCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { DWORD errorCode = GetLastError(); if (errorCode == ERROR_ELEVATION_REQUIRED) //Fallback to shellexecute { CoInitializeEx(NULL, 0); HINSTANCE execVal = ShellExecute(NULL, TEXT("runas"), pszCommand, NULL, NULL, iShowCmd); CoUninitialize(); if (execVal <= (HINSTANCE)32) { TCHAR * message = new TCHAR[512+bytesRequired]; wsprintf(message, TEXT("ShellExecute failed (%d): Is this command correct?\r\n%s"), execVal, pszCommand); MsgBoxError(message); delete [] message; } } else { TCHAR * message = new TCHAR[512+bytesRequired]; wsprintf(message, TEXT("Error in CreateProcess (%d): Is this command correct?\r\n%s"), errorCode, pszCommand); MsgBoxError(message); delete [] message; } } CoTaskMemFree(pszCommand); return NOERROR; }
/* * @implemented */ FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */ { _TCHAR *szCmdLine=NULL; _TCHAR *szComSpec=NULL; _TCHAR *s; FILE *pf; HANDLE hReadPipe, hWritePipe; BOOL result; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; TRACE(MK_STR(_tpopen)"('%"sT"', '%"sT"')\n", cm, md); if (cm == NULL) return( NULL ); szComSpec = _tgetenv(_T("COMSPEC")); if (szComSpec == NULL) { szComSpec = _T("cmd.exe"); } s = max(_tcsrchr(szComSpec, '\\'), _tcsrchr(szComSpec, '/')); if (s == NULL) s = szComSpec; else s++; szCmdLine = malloc((_tcslen(s) + 4 + _tcslen(cm) + 1) * sizeof(_TCHAR)); if (szCmdLine == NULL) { return NULL; } _tcscpy(szCmdLine, s); s = _tcsrchr(szCmdLine, '.'); if (s) *s = 0; _tcscat(szCmdLine, _T(" /C ")); _tcscat(szCmdLine, cm); if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024)) { free (szCmdLine); return NULL; } memset(&StartupInfo, 0, sizeof(STARTUPINFO)); StartupInfo.cb = sizeof(STARTUPINFO); if (*md == 'r' ) { StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); StartupInfo.hStdOutput = hWritePipe; StartupInfo.dwFlags |= STARTF_USESTDHANDLES; } else if ( *md == 'w' ) { StartupInfo.hStdInput = hReadPipe; StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); StartupInfo.dwFlags |= STARTF_USESTDHANDLES; } if (StartupInfo.dwFlags & STARTF_USESTDHANDLES) StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); result = CreateProcess(szComSpec, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInformation); free (szCmdLine); if (result == FALSE) { CloseHandle(hReadPipe); CloseHandle(hWritePipe); return NULL; } CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); if ( *md == 'r' ) { pf = _tfdopen(msvcrt_alloc_fd(hReadPipe, split_oflags(_fmode)) , _T("r")); CloseHandle(hWritePipe); } else { pf = _tfdopen( msvcrt_alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w")); CloseHandle(hReadPipe); } return( pf ); }
int EDITAPI EDITConnect( void ) { char *szProg = "VIW.EXE"; char szCommandLine[ 80 ]; char *szService = "VIW"; // arbitrary - we pass these to char *szTopic = "Edit"; // viw on command line & it registers HSZ hszService, hszTopic; // under their names int rc; if( bConnected ) { return( TRUE ); } // initialize our idInstance in ddeml if( idInstance == 0 ) { if( DdeInitialize( &idInstance, (PFNCALLBACK) DdeCallback, APPCMD_CLIENTONLY, 0L ) != DMLERR_NO_ERROR ) { return( FALSE ); } } // get handles to access strings hszService = DdeCreateStringHandle( idInstance, (LPSTR)szService, CP_WINANSI ); hszTopic= DdeCreateStringHandle( idInstance, (LPSTR)szTopic, CP_WINANSI ); // attempt connection hConv = DdeConnect( idInstance, hszService, hszTopic, (PCONVCONTEXT) NULL ); if( hConv == 0 ) { // run editor (magically grabs focus) sprintf( szCommandLine, "%s -s ddesinit.vi -p \"%s %s\"", szProg, szService, szTopic ); // ddesinit.vi will now add an ide-activate button to the toolbar // this button will NOT be saved by saveconfig #ifdef __NT__ { STARTUPINFO si; PROCESS_INFORMATION pi; int n; // editor is up - try again (otherwise give up) memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); rc = CreateProcess( NULL, szCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ); if( rc ) { rc = WaitForInputIdle( pi.hProcess, INFINITE ); if( rc == 0 ) { // Now this is starting to get scary #define MAX_TRIES 100 for( n = 0; (hConv = DdeConnect( idInstance, hszService, hszTopic, (PCONVCONTEXT)NULL )) == 0 && n < MAX_TRIES; ++n ) { DWORD status; GetExitCodeProcess( pi.hProcess, &status ); if( status != STILL_ACTIVE ) break; Sleep( 250 ); } } /* // Carl Young 2004-01-27 // Close handles as they are no longer needed and nobody has been passed them anyway */ CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } } #else rc = WinExec( (LPSTR)szCommandLine, SW_RESTORE ); if( rc >= 32 ) { hConv = DdeConnect( idInstance, hszService, hszTopic, (PCONVCONTEXT) NULL ); } #endif } DdeFreeStringHandle( idInstance, hszService ); DdeFreeStringHandle( idInstance, hszTopic ); if( hConv != 0 ) { bConnected = TRUE; } return( bConnected ); }
bool ProcessLauncher::Launch(unsigned int &exitCode) { exitCode = 0; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; ZeroMemory( &pi, sizeof(pi) ); // Start the child process. if ( !CreateProcess( NULL, // No module name (use command line). command_line_.GetBuffer(0), // Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. 0, // No creation flags. NULL, // Use parent's environment block. working_directory_.GetBuffer(0), // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. &pi ) // Pointer to PROCESS_INFORMATION structure. ) { String errorMessage = Formatter::Format("There was an error launching external process {0}. Process start failed. Windows error code: {1}", command_line_, (int) GetLastError()); ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5401, "ProcessLauncher::Launch", errorMessage); return false; } command_line_.ReleaseBuffer(); working_directory_.ReleaseBuffer(); DWORD waitResult = 0; if (error_log_timeout_ > 0) { // If it takes too long time, we should report an error. After that, we // should continue to wait. waitResult = WaitForSingleObject( pi.hProcess, error_log_timeout_ ); switch (waitResult) { case WAIT_ABANDONED: ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5402, "ProcessLauncher::Launch", "Wait abandoned."); break; case WAIT_TIMEOUT: { String errorMessage = Formatter::Format("A launched process did not exit within an expected time. The command line is {0}. The timeout occurred after {1} milliseconds. hMailServer will continue to wait for process to finish.", command_line_, error_log_timeout_); ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5400, "ProcessLauncher::Launch", errorMessage); break; } case WAIT_FAILED: { String errorMessage = Formatter::Format("Failed to wait. Windows error code: {0}.", (int) GetLastError()); ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5403, "ProcessLauncher::Launch", errorMessage); break; } } } // Wait until child process exits. waitResult = WaitForSingleObject( pi.hProcess, INFINITE); switch (waitResult) { case WAIT_ABANDONED: { ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5404, "ProcessLauncher::Launch", "Wait abandoned (infinite wait)."); break; } case WAIT_FAILED: { String errorMessage = Formatter::Format("Failed to wait. Windows error code: {0}.", (int) GetLastError()); ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5405, "ProcessLauncher::Launch", errorMessage); break; } } int result = 0; ULONG rc; if (!GetExitCodeProcess(pi.hProcess, &rc)) { String errorMessage = Formatter::Format("There was an error determining the exit code of {0}. Windows error: {1}", command_line_, (int) GetLastError()); ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5400, "ProcessLauncher::Launch", errorMessage); rc = 0; } exitCode = rc; // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return true; }
/* Redirect to an executable located in a sub folder relative to this starter executable. Name of the stub executable has to match with the one in the sub folder. The command line parameters are passed along. */ int main( int argc, char *argv[] ) { int err = ERROR_SUCCESS; TCHAR szPath[MAX_PATH]; /* Get the full path of the running executable */ if ( GetModuleFileName( NULL, szPath, MAX_PATH ) ) { size_t len = _tcslen(szPath); size_t offset = len + CONST_STRLEN(SUBFOLDER) + 1; err = ERROR_BAD_PATHNAME; if (offset < MAX_PATH) { /* Move file name part of full path by length of sub folder name and thereafter fill in the sub folder name in the newly created gap. */ register TCHAR *p = szPath + len; register TCHAR *q = szPath + offset; while (p > szPath) { *(q--) = *(p--); if (*p == '\\') { /* Fill in sub folder name */ *q = *p; q = ++p; p = (TCHAR *)SUBFOLDER; while (*p) { *(q++) = *(p++); } err = ERROR_SUCCESS; break; } } } if (err) { _tprintf( _T("Path too long: %s\n"), szPath ); } else { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); /* Start and wait for a process with the same filename as ourself located in SUBFOLDER. WARNING: The subprocess can't parse GetCommandLine() to find its own path since we pass the wrong path! */ if ( CreateProcess( szPath, GetCommandLine(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) { WaitForSingleObject( pi.hProcess, INFINITE ); GetExitCodeProcess( pi.hProcess, &err ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); } else { err = GetLastError(); _tprintf( _T("CreateProcess (%s) failed (%d).\n"), szPath, err ); } } } else { err = GetLastError(); _tprintf( _T("GetModuleFileName failed (%d).\n"), err ); } return err; }
int __cdecl main( int argc, char **argv ) { const char* rgchChildFile = "childprocess"; STARTUPINFO si; PROCESS_INFORMATION pi; DWORD dwError; DWORD dwExitCode; DWORD dwFileLength; DWORD dwDirLength; DWORD dwSize; DWORD dwExpected = TEST_EXIT_CODE; char rgchDirName[_MAX_DIR]; char absPathBuf[_MAX_PATH]; char* rgchAbsPathName; /* initialize the PAL */ if( PAL_Initialize(argc, argv) != 0 ) { return( FAIL ); } /* zero our process and startup info structures */ ZeroMemory( &si, sizeof(si) ); si.cb = sizeof( si ); ZeroMemory( &pi, sizeof(pi) ); /* build the absolute path to the child process */ rgchAbsPathName = &absPathBuf[0]; dwFileLength = strlen( rgchChildFile ); dwDirLength = GetCurrentDirectory( _MAX_PATH, rgchDirName ); if( dwDirLength == 0 ) { dwError = GetLastError(); Fail( "GetCurrentDirectory call failed with error code %d\n", dwError ); } dwSize = mkAbsoluteFilename( rgchDirName, dwDirLength, rgchChildFile, dwFileLength, rgchAbsPathName ); if( dwSize == 0 ) { Fail( "Palsuite Code: mkAbsoluteFilename() call failed. Could ", "not build absolute path name to file\n. Exiting.\n" ); } /* launch the child process */ if( !CreateProcess( NULL, /* module name to execute */ rgchAbsPathName, /* command line */ NULL, /* process handle not */ /* inheritable */ NULL, /* thread handle not */ /* inheritable */ FALSE, /* handle inheritance */ CREATE_NEW_CONSOLE, /* dwCreationFlags */ NULL, /* use parent's environment */ NULL, /* use parent's starting */ /* directory */ &si, /* startup info struct */ &pi ) /* process info struct */ ) { dwError = GetLastError(); Fail( "CreateProcess call failed with error code %d\n", dwError ); } /* wait for the child process to complete */ WaitForSingleObject ( pi.hProcess, INFINITE ); /* check the exit code from the process */ if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) ) { dwError = GetLastError(); CloseHandle ( pi.hProcess ); CloseHandle ( pi.hThread ); Fail( "GetExitCodeProcess call failed with error code %d\n", dwError ); } /* close process and thread handle */ CloseHandle ( pi.hProcess ); CloseHandle ( pi.hThread ); /* check for the expected exit code */ /* exit code for some systems is as small as a char, so that's all */ /* we'll compare for checking success */ if( LOBYTE(LOWORD(dwExitCode)) != LOBYTE(LOWORD(dwExpected)) ) { Fail( "GetExitCodeProcess returned an incorrect exit code %d, " "expected value is %d\n", LOWORD(dwExitCode), dwExpected ); } /* terminate the PAL */ PAL_Terminate(); /* return success */ return PASS; }
void Process::run() { SECURITY_ATTRIBUTES saAttr; // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Create a pipe for the child process's STDOUT. if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) ErrorExit(TEXT("StdoutRd CreatePipe")); // Ensure the read handle to the pipe for STDOUT is not inherited. if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) ) ErrorExit(TEXT("Stdout SetHandleInformation")); // Create a pipe for the child process's STDIN. if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) ErrorExit(TEXT("Stdin CreatePipe")); // Ensure the write handle to the pipe for STDIN is not inherited. if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) ) ErrorExit(TEXT("Stdin SetHandleInformation")); std::string mycmd = "cmd.exe /D /c " + cmd; //Create child process PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; // Set up members of the PROCESS_INFORMATION structure. ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); // Set up members of the STARTUPINFO structure. // This structure specifies the STDIN and STDOUT handles for redirection. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = g_hChildStd_OUT_Wr; siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; siStartInfo.hStdInput = g_hChildStd_IN_Rd; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; // Create the child process. bSuccess = CreateProcess( NULL, (LPSTR)cmd.c_str(), // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION // If an error occurs, exit the application. if ( ! bSuccess ) ErrorExit(TEXT("CreateProcess")); else { running = true; /******************************************************************************** * IF YOU PLAN TO ATTACH TO YOUR'S BOTS PROCESS, UNCOMMENT OUT THIS CODE TO HELP. * IT WILL PAUSE UNTIL YOU TYPE A KEY AND HIT ENTER * ********************************************************************************/ //if( cmd == "C:\\planetwars\\cpp_framework\\albertz-planet_wars-cpp-2fc1dda\\VC\\Debug\\alcsbot.exe" ) //{ // std::cout << "Attach to mybot.exe process, type some char and hit enter when ready"; // char n; // std::cin >> n; //} //CloseHandle(piProcInfo.hProcess); hProcess = piProcInfo.hProcess; CloseHandle(piProcInfo.hThread); } }
HRESULT ExecData(PVOID &pvPEData) { HRESULT hr = S_OK; PROCESS_INFORMATION pi; STARTUPINFO si = { sizeof si }; LPTSTR cmdLine = _tcsdup(TEXT("cmd")); CreateProcess(NULL, cmdLine, 0, 0, FALSE, CREATE_SUSPENDED, 0, 0, &si, &pi); CONTEXT context = { CONTEXT_INTEGER }; #ifndef DEFER_INJECT GetThreadContext(pi.hThread, &context); PVOID x; /* Dynamic linking call: */ HMODULE hMod = GetModuleHandle(L"ntdll.dll"); pfnZwUnmapViewOfSection pZwUnmapViewOfSection = (pfnZwUnmapViewOfSection)GetProcAddress(hMod, "ZwUnmapViewOfSection"); hr = ReadProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, &x, sizeof x, 0); if (FAILED(hr)) { /* This is bad, abort! */ return hr; } pZwUnmapViewOfSection(pi.hProcess, x); PIMAGE_NT_HEADERS nt = PIMAGE_NT_HEADERS( PCHAR(pvPEData) + PIMAGE_DOS_HEADER(pvPEData)->e_lfanew); DWORD dwLastError = ::GetLastError(); PVOID q = VirtualAllocEx(pi.hProcess, PVOID(nt->OptionalHeader.ImageBase), nt->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_WRITECOPY); WriteProcessMemory(pi.hProcess, q, pvPEData, nt->OptionalHeader.SizeOfHeaders, 0); PIMAGE_SECTION_HEADER sect = IMAGE_FIRST_SECTION(nt); for (ULONG i = 0; i < nt->FileHeader.NumberOfSections; i++) { WriteProcessMemory(pi.hProcess, PCHAR(q) + sect[i].VirtualAddress, PCHAR(pvPEData) + sect[i].PointerToRawData, sect[i].SizeOfRawData, 0); ULONG x; VirtualProtectEx(pi.hProcess, PCHAR(q) + sect[i].VirtualAddress, sect[i].Misc.VirtualSize, protect(sect[i].Characteristics), &x ); } WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, &q, sizeof q, 0); context.Eax = ULONG(q) + nt->OptionalHeader.AddressOfEntryPoint; #endif SetThreadContext(pi.hThread, &context); ResumeThread(pi.hThread); return hr; }
int WINAPI WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow) { STARTUPINFO start; SECURITY_ATTRIBUTES sec_attrs; PROCESS_INFORMATION child; int wait_for_child = FALSE; DWORD priority_class = NORMAL_PRIORITY_CLASS; DWORD ret_code = 0; char *new_cmdline; char *p; char modname[MAX_PATH]; if (!ensure_unicows_dll ()) goto error; set_user_model_id (); if (!GetModuleFileName (NULL, modname, MAX_PATH)) goto error; if ((p = strrchr (modname, '\\')) == NULL) goto error; *p = 0; new_cmdline = alloca (MAX_PATH + strlen (cmdline) + 3); /* Quote executable name in case of spaces in the path. */ *new_cmdline = '"'; strcpy (new_cmdline + 1, modname); /* Detect and handle un-installed runemacs.exe in nt/ subdirectory, while emacs.exe is in src/. */ if ((p = strrchr (new_cmdline, '\\')) != NULL && stricmp (p, "\\nt") == 0) strcpy (p, "\\src"); #ifdef CHOOSE_NEWEST_EXE { /* Silly hack to allow new versions to be installed on server even when current version is in use. */ char * best_name = alloca (MAX_PATH + 1); FILETIME best_time = {0,0}; WIN32_FIND_DATA wfd; HANDLE fh; p = new_cmdline + strlen (new_cmdline); strcpy (p, "\\emacs*.exe\" "); fh = FindFirstFile (new_cmdline, &wfd); if (fh == INVALID_HANDLE_VALUE) goto error; do { if (wfd.ftLastWriteTime.dwHighDateTime > best_time.dwHighDateTime || (wfd.ftLastWriteTime.dwHighDateTime == best_time.dwHighDateTime && wfd.ftLastWriteTime.dwLowDateTime > best_time.dwLowDateTime)) { best_time = wfd.ftLastWriteTime; strcpy (best_name, wfd.cFileName); } } while (FindNextFile (fh, &wfd)); FindClose (fh); *p++ = '\\'; strcpy (p, best_name); strcat (p, " "); } #else strcat (new_cmdline, "\\emacs.exe\" "); #endif /* Append original arguments if any; first look for arguments we recognize (-wait, -high, and -low), and apply them ourselves. */ while (cmdline[0] == '-' || cmdline[0] == '/') { if (strncmp (cmdline+1, "wait", 4) == 0) { wait_for_child = TRUE; cmdline += 5; } else if (strncmp (cmdline+1, "high", 4) == 0) { priority_class = HIGH_PRIORITY_CLASS; cmdline += 5; } else if (strncmp (cmdline+1, "low", 3) == 0) { priority_class = IDLE_PRIORITY_CLASS; cmdline += 4; } else break; /* Look for next argument. */ while (*++cmdline == ' '); } strcat (new_cmdline, cmdline); /* Set emacs_dir variable if runemacs was in "%emacs_dir%\bin". */ if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0) { *p = 0; for (p = modname; *p; p++) if (*p == '\\') *p = '/'; SetEnvironmentVariable ("emacs_dir", modname); } memset (&start, 0, sizeof (start)); start.cb = sizeof (start); start.dwFlags = STARTF_USESHOWWINDOW | STARTF_USECOUNTCHARS; start.wShowWindow = SW_HIDE; /* Ensure that we don't waste memory if the user has specified a huge default screen buffer for command windows. */ start.dwXCountChars = 80; start.dwYCountChars = 25; sec_attrs.nLength = sizeof (sec_attrs); sec_attrs.lpSecurityDescriptor = NULL; sec_attrs.bInheritHandle = FALSE; if (CreateProcess (NULL, new_cmdline, &sec_attrs, NULL, TRUE, priority_class, NULL, NULL, &start, &child)) { if (wait_for_child) { WaitForSingleObject (child.hProcess, INFINITE); GetExitCodeProcess (child.hProcess, &ret_code); } CloseHandle (child.hThread); CloseHandle (child.hProcess); } else goto error; return (int) ret_code; error: MessageBox (NULL, "Could not start Emacs.", "Error", MB_ICONSTOP); return 1; }
void QProcessPrivate::startProcess() { Q_Q(QProcess); bool success = false; if (pid) { CloseHandle(pid->hThread); CloseHandle(pid->hProcess); delete pid; pid = 0; } pid = new PROCESS_INFORMATION; memset(pid, 0, sizeof(PROCESS_INFORMATION)); q->setProcessState(QProcess::Starting); QString args = qt_create_commandline(QString(), arguments); if (!nativeArguments.isEmpty()) { if (!args.isEmpty()) args += QLatin1Char(' '); args += nativeArguments; } #if defined QPROCESS_DEBUG qDebug("Creating process"); qDebug(" program : [%s]", program.toLatin1().constData()); qDebug(" args : %s", args.toLatin1().constData()); qDebug(" pass environment : %s", environment.isEmpty() ? "no" : "yes"); #endif QString fullPathProgram = program; if (!QDir::isAbsolutePath(fullPathProgram)) fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath(); fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\')); success = CreateProcess((wchar_t*)fullPathProgram.utf16(), (wchar_t*)args.utf16(), 0, 0, false, 0, 0, 0, 0, pid); if (!success) { cleanup(); setErrorAndEmit(QProcess::FailedToStart); q->setProcessState(QProcess::NotRunning); return; } q->setProcessState(QProcess::Running); // User can call kill()/terminate() from the stateChanged() slot // so check before proceeding if (!pid) return; if (threadData->hasEventDispatcher()) { processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q); QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied())); processFinishedNotifier->setEnabled(true); } // give the process a chance to start ... Sleep(20); _q_startupNotification(); }
bool Server_createProcess ( ServerStartupInfo *self, char *executableName ) { MySQLStartupInfo *sqlInfo = &self->workersInfo[0].sqlInfo; RedisStartupInfo *redisInfo = &self->workersInfo[0].redisInfo; char *globalServerIp = self->workersInfo[0].globalServerIp; int globalServerPort = self->workersInfo[0].globalServerPort; #ifdef WIN32 executableName = zsys_sprintf ("%s.exe", executableName); #endif char *commandLine = zsys_sprintf ("%s %d %s %d", executableName, self->routerInfo.routerId, self->routerInfo.ip, self->routerInfo.portsCount ); char *lastCommandLine; for (int i = 0; i < self->routerInfo.portsCount; i++) { lastCommandLine = zsys_sprintf ("%s %d", commandLine, self->routerInfo.ports[i]); zstr_free (&commandLine); commandLine = lastCommandLine; } lastCommandLine = zsys_sprintf ("%s %d %s %d %s %s %s %s %s %d %d", commandLine, self->routerInfo.workersCount, globalServerIp, globalServerPort, sqlInfo->hostname, sqlInfo->login, sqlInfo->password, sqlInfo->database, redisInfo->hostname, redisInfo->port, self->serverType ); zstr_free (&commandLine); commandLine = lastCommandLine; info ("CommandLine : %s", commandLine); #ifdef WIN32 STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; if (!CreateProcess (executableName, commandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { error ("Cannot launch Zone Server executable : %s.", executableName); char *errorReason; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &errorReason, 0, NULL ); error ("Error reason : %s", errorReason); return false; } #else char **argv = str_split (commandLine, ' '); if (fork () == 0) { if (execv (executableName, (char * const *) argv) == -1) { error ("Cannot launch Zone Server executable : %s.", executableName); return false; } } #endif zstr_free (&commandLine); return true; }
/* * Searches for the custom WM_COMMAND command ID and performs action. * Return TRUE if command is proccessed, FALSE otherwise. */ Bool HandleCustomWM_COMMAND (unsigned long hwndIn, int command) { HWND hwnd; int i, j; MENUPARSED *m; DWORD dwExStyle; hwnd = (HWND)hwndIn; if (!command) return FALSE; for (i=0; i<pref.menuItems; i++) { m = &(pref.menu[i]); for (j=0; j<m->menuItems; j++) { if (command==m->menuItem[j].commandID) { /* Match! */ switch(m->menuItem[j].cmd) { #ifdef __CYGWIN__ case CMD_EXEC: if (fork()==0) { struct rlimit rl; unsigned long i; /* Close any open descriptors except for STD* */ getrlimit (RLIMIT_NOFILE, &rl); for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++) close(i); /* Disassociate any TTYs */ setsid(); execl ("/bin/sh", "/bin/sh", "-c", m->menuItem[j].param, NULL); exit (0); } else return TRUE; break; #else case CMD_EXEC: { /* Start process without console window */ STARTUPINFO start; PROCESS_INFORMATION child; memset (&start, 0, sizeof (start)); start.cb = sizeof (start); start.dwFlags = STARTF_USESHOWWINDOW; start.wShowWindow = SW_HIDE; memset (&child, 0, sizeof (child)); if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0, NULL, NULL, &start, &child)) { CloseHandle (child.hThread); CloseHandle (child.hProcess); } else MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); } return TRUE; #endif case CMD_ALWAYSONTOP: if (!hwnd) return FALSE; /* Get extended window style */ dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); /* Handle topmost windows */ if (dwExStyle & WS_EX_TOPMOST) SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); else SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); #if XWIN_MULTIWINDOW /* Reflect the changed Z order */ winReorderWindowsMultiWindow (); #endif return TRUE; case CMD_RELOAD: ReloadPrefs(); return TRUE; default: return FALSE; } } /* match */ } /* for j */ } /* for i */ return FALSE; }
int Ns_ExecArgblk(char *exec, char *dir, int fdin, int fdout, char *args, Ns_Set *env) { #ifndef _WIN32 int pid; char **argv; Ns_DString vds; Ns_DStringInit(&vds); if (args == NULL) { argv = NULL; } else { while (*args != '\0') { Ns_DStringNAppend(&vds, (char *) &args, sizeof(args)); args += strlen(args) + 1; } args = NULL; Ns_DStringNAppend(&vds, (char *) &args, sizeof(args)); argv = (char **) vds.string; } pid = Ns_ExecArgv(exec, dir, fdin, fdout, argv, env); Ns_DStringFree(&vds); return pid; #else STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE hCurrentProcess; int pid; Ns_DString cds, xds, eds; char *envp; OSVERSIONINFO oinfo; char *cmd; if (exec == NULL) { return -1; } oinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&oinfo) == TRUE && oinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) { cmd = "command.com"; } else { cmd = "cmd.exe"; } /* * Setup STARTUPINFO with stdin, stdout, and stderr. */ memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdError = (HANDLE) _get_osfhandle(_fileno(stderr)); hCurrentProcess = GetCurrentProcess(); if (fdout < 0) { fdout = 1; } if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdout), hCurrentProcess, &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) { Ns_Log(Error, "exec: failed to duplicate handle: %s", NsWin32ErrMsg(GetLastError())); return -1; } if (fdin < 0) { fdin = 0; } if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdin), hCurrentProcess, &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) { Ns_Log(Error, "exec: failed to duplicate handle: %s", NsWin32ErrMsg(GetLastError())); (void) CloseHandle(si.hStdOutput); return -1; } /* * Setup the command line and environment block and create the new * subprocess. */ Ns_DStringInit(&cds); Ns_DStringInit(&xds); Ns_DStringInit(&eds); if (args == NULL) { /* NB: exec specifies a complete cmd.exe command string. */ Ns_DStringVarAppend(&cds, cmd, " /c ", exec, NULL); exec = NULL; } else { char *s; s = args; while (*s != '\0') { int len; len = strlen(s); Ns_DStringNAppend(&cds, s, len); s += len + 1; if (*s != '\0') { Ns_DStringNAppend(&cds, " ", 1); } } Ns_NormalizePath(&xds, exec); s = xds.string; while (*s != '\0') { if (*s == '/') { *s = '\\'; } ++s; } exec = xds.string; } if (env == NULL) { envp = NULL; } else { Set2Argv(&eds, env); envp = eds.string; } if (CreateProcess(exec, cds.string, NULL, NULL, TRUE, 0, envp, dir, &si, &pi) != TRUE) { Ns_Log(Error, "exec: failed to create process: %s: %s", exec ? exec : cds.string, NsWin32ErrMsg(GetLastError())); pid = -1; } else { CloseHandle(pi.hThread); pid = (int) pi.hProcess; } Ns_DStringFree(&cds); Ns_DStringFree(&xds); Ns_DStringFree(&eds); CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); return pid; #endif }
int main( int argc, char* argv[] ) { if ( argc < 3 ) { printf( "WaitAndRestart <seconds to wait> command line...\n" ); return 1; } DWORD timeToWait = (DWORD)atoi( argv[1] ); printf( "\n\nWaiting for %d seconds to launch ' ", timeToWait ); for ( int i=2; i < argc; i++ ) { printf( "%s ", argv[i] ); } printf( "'\n\nPress a key to cancel... " ); DWORD startTime = GetTickCount(); while ( GetTickCount() - startTime < (timeToWait*1000) ) { if ( kbhit() ) return 2; Sleep( 100 ); } // Ok, launch it! char commandLine[1024] = {0}; for ( i=2; i < argc; i++ ) { Q_strncat( commandLine, "\"", sizeof( commandLine ) ); Q_strncat( commandLine, argv[i], sizeof( commandLine ) ); Q_strncat( commandLine, "\" ", sizeof( commandLine ) ); } STARTUPINFO si; memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); PROCESS_INFORMATION pi; memset( &pi, 0, sizeof( pi ) ); if ( CreateProcess( NULL, commandLine, NULL, // security NULL, FALSE, CREATE_NEW_CONSOLE, // flags NULL, // environment NULL, // current directory &si, &pi ) ) { printf( "Process started.\n" ); CloseHandle( pi.hThread ); // We don't care what the process does. CloseHandle( pi.hProcess ); } else { printf( "CreateProcess error!\n" ); } return 0; }
int MprCmd::start(char *program, char **argv, char **envp, MprCmdProc completionFn, void *fnData, int userFlags) { PROCESS_INFORMATION procInfo; STARTUPINFO startInfo; char dirBuf[MPR_MAX_FNAME], *systemRoot; char *envBuf, **ep, *cmdBuf, **ap, *destp, *cp, *dir, *key; char progBuf[MPR_MAX_STRING], *localArgv[2], *saveArg0; int argc, len, inheritFiles; mprAssert(program); mprAssert(argv); reset(); flags |= (userFlags & MPR_CMD_USER_FLAGS); exitStatus = -1; mprStrcpy(progBuf, sizeof(progBuf), program); progBuf[sizeof(progBuf) - 1] = '\0'; program = progBuf; // // Sanitize the command line (program name only) // for (cp = program; *cp; cp++) { if (*cp == '/') { *cp = '\\'; } else if (*cp == '\r' || *cp == '\n') { *cp = ' '; } } if (*program == '"') { if ((cp = strrchr(++program, '"')) != 0) { *cp = '\0'; } } saveArg0 = argv[0]; if (argv == 0) { argv = localArgv; argv[1] = 0; } argv[0] = program; // // Determine the command line length and arg count // argc = 0; for (len = 0, ap = argv; *ap; ap++) { len += strlen(*ap) + 1 + 2; // Space and possible quotes argc++; } cmdBuf = (char*) mprMalloc(len + 1); cmdBuf[len] = '\0'; // // Add quotes to all args that have spaces in them including "program" // destp = cmdBuf; for (ap = &argv[0]; *ap; ) { cp = *ap; if ((strchr(cp, ' ') != 0) && cp[0] != '\"') { *destp++ = '\"'; strcpy(destp, cp); destp += strlen(cp); *destp++ = '\"'; } else { strcpy(destp, cp); destp += strlen(cp); } if (*++ap) { *destp++ = ' '; } } *destp = '\0'; mprAssert((int) strlen(destp) < (len - 1)); mprAssert(cmdBuf[len] == '\0'); argv[0] = saveArg0; envBuf = 0; if (envp) { for (len = 0, ep = envp; *ep; ep++) { len += strlen(*ep) + 1; } key = "SYSTEMROOT"; systemRoot = getenv(key); if (systemRoot) { len += strlen(key) + 1 + strlen(systemRoot) + 1; } envBuf = (char*) mprMalloc(len + 2); // Win requires two nulls destp = envBuf; for (ep = envp; *ep; ep++) { strcpy(destp, *ep); mprLog(6, log, "Set CGI variable: %s\n", destp); destp += strlen(*ep) + 1; } strcpy(destp, key); destp += strlen(key); *destp++ = '='; strcpy(destp, systemRoot); destp += strlen(systemRoot) + 1; *destp++ = '\0'; *destp++ = '\0'; // WIN requires two nulls } memset(&startInfo, 0, sizeof(startInfo)); startInfo.cb = sizeof(startInfo); startInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; if (flags & MPR_CMD_SHOW) { startInfo.wShowWindow = SW_SHOW; } else { startInfo.wShowWindow = SW_HIDE; } // // CMD_OUT is stdin for the client. CMD_IN is stdout for the client // if (files.clientFd[MPR_CMD_OUT] > 0) { startInfo.hStdInput = (HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_OUT]); } if (files.clientFd[MPR_CMD_IN] > 0) { startInfo.hStdOutput = (HANDLE)_get_osfhandle(files.clientFd[MPR_CMD_IN]); } #if UNUSED if (files.clientFd[MPR_CMD_ERR] > 0) { startInfo.hStdError = (HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_ERR]); } #endif #if UNUSED SECURITY_ATTRIBUTES secAtt; memset(&secAtt, 0, sizeof(secAtt)); secAtt.nLength = sizeof(SECURITY_ATTRIBUTES); secAtt.bInheritHandle = TRUE; #endif if (userFlags & MPR_CMD_CHDIR) { if (cwd) { dir = cwd; } else { mprGetDirName(dirBuf, sizeof(dirBuf), argv[0]); dir = dirBuf; } } else { dir = 0; } inheritFiles = (flags & MPR_CMD_STDIO_MADE) ? 1 : 0; flags &= ~(MPR_CMD_STDIO_MADE); mprLog(5, log, "Running: %s\n", cmdBuf); if (! CreateProcess(0, cmdBuf, 0, 0, inheritFiles, CREATE_NEW_CONSOLE, envBuf, dir, &startInfo, &procInfo)) { mprError(MPR_L, MPR_LOG, "Can't create process: %s, %d", cmdBuf, mprGetOsError()); return MPR_ERR_CANT_CREATE; } process = (int) procInfo.hProcess; // // Wait for the child to initialize // WaitForInputIdle((HANDLE) process, 1000); if (procInfo.hThread != 0) { CloseHandle(procInfo.hThread); } mprFree(cmdBuf); mprFree(envBuf); cmdDoneProc = completionFn; data = fnData; if (flags & MPR_CMD_DETACHED) { CloseHandle((HANDLE) process); process = 0; } else if (userFlags & MPR_CMD_WAIT) { waitForChild(INT_MAX); if (getExitCode() < 0) { return MPR_ERR_BAD_STATE; } return exitStatus; } else { mprGetMpr()->cmdService->startWatcher(); } return 0; }
static bool launch_server() { EZDBGONLYLOGGERPRINT("Launching weasel server."); // 從註冊表取得server位置 HKEY hKey; LSTATUS ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); if (ret != ERROR_SUCCESS) { error_message(L"註冊表信息無影了"); return false; } WCHAR value[MAX_PATH]; DWORD len = sizeof(value); DWORD type = 0; ret = RegQueryValueEx(hKey, L"WeaselRoot", NULL, &type, (LPBYTE)value, &len); if (ret != ERROR_SUCCESS) { error_message(L"未設置 WeaselRoot"); RegCloseKey(hKey); return false; } wpath weaselRoot(value); len = sizeof(value); type = 0; ret = RegQueryValueEx(hKey, L"ServerExecutable", NULL, &type, (LPBYTE)value, &len); if (ret != ERROR_SUCCESS) { error_message(L"未設置 ServerExecutable"); RegCloseKey(hKey); return false; } wpath serverPath(weaselRoot / value); RegCloseKey(hKey); // 啓動服務進程 wstring exe = serverPath.native_file_string(); wstring dir = weaselRoot.native_file_string(); STARTUPINFO startup_info = {0}; PROCESS_INFORMATION process_info = {0}; startup_info.cb = sizeof(startup_info); if (!CreateProcess(exe.c_str(), NULL, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startup_info, &process_info)) { EZDBGONLYLOGGERPRINT("ERROR: failed to launch weasel server."); error_message(L"服務進程啓動不起來 :("); return false; } if (!WaitForInputIdle(process_info.hProcess, 1500)) { EZDBGONLYLOGGERPRINT("WARNING: WaitForInputIdle() timed out; succeeding IPC messages might not be delivered."); } if (process_info.hProcess) CloseHandle(process_info.hProcess); if (process_info.hThread) CloseHandle(process_info.hThread); return true; }
bool CWebServer::CallCGI(CWebClientSocket* pClient, CStringA& hdr, CStringA& body, CStringA& mime) { CString path = pClient->m_path, redir = path; if(!ToLocalPath(path, redir)) return false; CString ext = CPath(path).GetExtension().MakeLower(); CPath dir(path); dir.RemoveFileSpec(); CString cgi; if(!m_cgi.Lookup(ext, cgi) || !CPath(cgi).FileExists()) return false; HANDLE hProcess = GetCurrentProcess(); HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup = NULL; HANDLE hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup = NULL; SECURITY_ATTRIBUTES saAttr; ZeroMemory(&saAttr, sizeof(saAttr)); saAttr.nLength = sizeof(saAttr); saAttr.bInheritHandle = TRUE; if(CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) { BOOL fSuccess = DuplicateHandle(hProcess, hChildStdoutRd, hProcess, &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(hChildStdoutRd); } if(CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) { BOOL fSuccess = DuplicateHandle(hProcess, hChildStdinWr, hProcess, &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(hChildStdinWr); } STARTUPINFO siStartInfo; ZeroMemory(&siStartInfo, sizeof(siStartInfo)); siStartInfo.cb = sizeof(siStartInfo); siStartInfo.hStdError = hChildStdoutWr; siStartInfo.hStdOutput = hChildStdoutWr; siStartInfo.hStdInput = hChildStdinRd; siStartInfo.dwFlags |= STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; siStartInfo.wShowWindow = SW_HIDE; PROCESS_INFORMATION piProcInfo; ZeroMemory(&piProcInfo, sizeof(piProcInfo)); CStringA envstr; if(LPVOID lpvEnv = GetEnvironmentStrings()) { CString str; CAtlList<CString> env; for(LPTSTR lpszVariable = (LPTSTR)lpvEnv; *lpszVariable; lpszVariable += _tcslen(lpszVariable)+1) if(lpszVariable != (LPTSTR)lpvEnv) env.AddTail(lpszVariable); env.AddTail(_T("GATEWAY_INTERFACE=CGI/1.1")); env.AddTail(_T("SERVER_SOFTWARE=Media Player Classic/6.4.x.y")); env.AddTail(_T("SERVER_PROTOCOL=") + pClient->m_ver); env.AddTail(_T("REQUEST_METHOD=") + pClient->m_cmd); env.AddTail(_T("PATH_INFO=") + redir); env.AddTail(_T("PATH_TRANSLATED=") + path); env.AddTail(_T("SCRIPT_NAME=") + redir); env.AddTail(_T("QUERY_STRING=") + pClient->m_query); if(pClient->m_hdrlines.Lookup(_T("content-type"), str)) env.AddTail(_T("CONTENT_TYPE=") + str); if(pClient->m_hdrlines.Lookup(_T("content-length"), str)) env.AddTail(_T("CONTENT_LENGTH=") + str); POSITION pos = pClient->m_hdrlines.GetStartPosition(); while(pos) { CString key = pClient->m_hdrlines.GetKeyAt(pos); CString value = pClient->m_hdrlines.GetNextValue(pos); key.Replace(_T("-"), _T("_")); key.MakeUpper(); env.AddTail(_T("HTTP_") + key + _T("=") + value); } CString name; UINT port; if(pClient->GetPeerName(name, port)) { str.Format(_T("%d"), port); env.AddTail(_T("REMOTE_ADDR=")+name); env.AddTail(_T("REMOTE_HOST=")+name); env.AddTail(_T("REMOTE_PORT=")+str); } if(pClient->GetSockName(name, port)) { str.Format(_T("%d"), port); env.AddTail(_T("SERVER_NAME=")+name); env.AddTail(_T("SERVER_PORT=")+str); } env.AddTail(_T("\0")); str = Implode(env, '\0'); envstr = CStringA(str, str.GetLength()); FreeEnvironmentStrings((LPTSTR)lpvEnv); } TCHAR* cmdln = new TCHAR[32768]; _sntprintf(cmdln, 32768, _T("\"%s\" \"%s\""), cgi, path); if(hChildStdinRd && hChildStdoutWr) if(CreateProcess( NULL, cmdln, NULL, NULL, TRUE, 0, envstr.GetLength() ? (LPVOID)(LPCSTR)envstr : NULL, dir, &siStartInfo, &piProcInfo)) { DWORD ThreadId; CreateThread(NULL, 0, KillCGI, (LPVOID)piProcInfo.hProcess, 0, &ThreadId); static const int BUFFSIZE = 1024; DWORD dwRead, dwWritten = 0; int i = 0, len = pClient->m_data.GetLength(); for(; i < len; i += dwWritten) if(!WriteFile(hChildStdinWrDup, (LPCSTR)pClient->m_data + i, min(len - i, BUFFSIZE), &dwWritten, NULL)) break; CloseHandle(hChildStdinWrDup); CloseHandle(hChildStdoutWr); body.Empty(); CStringA buff; while(i == len && ReadFile(hChildStdoutRdDup, buff.GetBuffer(BUFFSIZE), BUFFSIZE, &dwRead, NULL) && dwRead) { buff.ReleaseBufferSetLength(dwRead); body += buff; } int hdrend = body.Find("\r\n\r\n"); if(hdrend >= 0) { hdr = body.Left(hdrend+2); body = body.Mid(hdrend+4); } CloseHandle(hChildStdinRd); CloseHandle(hChildStdoutRdDup); CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); } else { body = _T("CGI Error"); } delete [] cmdln; return true; }
void MythSystemWindows::Fork(time_t timeout) { QString LOC_ERR = QString("myth_system('%1'): Error: ").arg(GetLogCmd()); // For use in the child char locerr[MAX_BUFLEN]; strncpy(locerr, (const char *)LOC_ERR.toUtf8().constData(), MAX_BUFLEN); locerr[MAX_BUFLEN-1] = '\0'; LOG(VB_SYSTEM, LOG_DEBUG, QString("Launching: %1").arg(GetLogCmd())); GetBuffer(0)->setBuffer(0); GetBuffer(1)->setBuffer(0); GetBuffer(2)->setBuffer(0); HANDLE p_stdin[2] = { NULL, NULL }; HANDLE p_stdout[2] = { NULL, NULL }; HANDLE p_stderr[2] = { NULL, NULL }; SECURITY_ATTRIBUTES saAttr; STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; /* set up pipes */ if( GetSetting("UseStdin") ) { if (!CreatePipe(&p_stdin[0], &p_stdin[1], &saAttr, 0)) { LOG(VB_GENERAL, LOG_ERR, "stdin pipe() failed"); SetStatus( GENERIC_EXIT_NOT_OK ); } else { // Ensure the write handle to the pipe for STDIN is not inherited. if (!SetHandleInformation(p_stdin[1], HANDLE_FLAG_INHERIT, 0)) { LOG(VB_SYSTEM, LOG_ERR, "stdin inheritance error"); SetStatus( GENERIC_EXIT_NOT_OK ); } else { si.hStdInput = p_stdin[0]; si.dwFlags |= STARTF_USESTDHANDLES; } } } if( GetSetting("UseStdout") ) { if (!CreatePipe(&p_stdout[0], &p_stdout[1], &saAttr, 0)) { LOG(VB_SYSTEM, LOG_ERR, "stdout pipe() failed"); SetStatus( GENERIC_EXIT_NOT_OK ); } else { // Ensure the read handle to the pipe for STDOUT is not inherited. if (!SetHandleInformation(p_stdout[0], HANDLE_FLAG_INHERIT, 0)) { LOG(VB_SYSTEM, LOG_ERR, "stdout inheritance error"); SetStatus( GENERIC_EXIT_NOT_OK ); } else { si.hStdOutput = p_stdout[1]; si.dwFlags |= STARTF_USESTDHANDLES; } } } if( GetSetting("UseStderr") ) { if (!CreatePipe(&p_stderr[0], &p_stderr[1], &saAttr, 0)) { LOG(VB_SYSTEM, LOG_ERR, "stderr pipe() failed"); SetStatus( GENERIC_EXIT_NOT_OK ); } else { // Ensure the read handle to the pipe for STDERR is not inherited. if (!SetHandleInformation(p_stderr[0], HANDLE_FLAG_INHERIT, 0)) { LOG(VB_SYSTEM, LOG_ERR, "stderr inheritance error"); SetStatus( GENERIC_EXIT_NOT_OK ); } else { si.hStdError = p_stderr[1]; si.dwFlags |= STARTF_USESTDHANDLES; } } } // set up command args QString cmd = GetCommand() + " " + GetArgs().join(" "); if (GetSetting("UseShell")) cmd.prepend("cmd.exe /c "); SetCommand( cmd ); QByteArray cmdUTF8 = GetCommand().toUtf8(); TCHAR *command = TEXT((char *)cmdUTF8.constData()); const char *directory = NULL; QString dir = GetDirectory(); if (GetSetting("SetDirectory") && !dir.isEmpty()) directory = strdup(dir.toUtf8().constData()); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); m_timeout = timeout; if( timeout ) m_timeout += time(NULL); bool success = CreateProcess(NULL, command, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment directory, // use parent's current directory &si, // STARTUPINFO pointer &pi); // receives PROCESS_INFORMATION if (!success) { LOG(VB_SYSTEM, LOG_ERR, "CreateProcess() failed"); SetStatus( GENERIC_EXIT_NOT_OK ); } else { /* parent */ m_child = pi.hProcess; SetStatus( GENERIC_EXIT_RUNNING ); LOG(VB_SYSTEM, LOG_INFO, QString("Managed child (Handle: %1) has started! " "%2%3 command=%4, timeout=%5") .arg((long long)m_child) .arg(GetSetting("UseShell") ? "*" : "") .arg(GetSetting("RunInBackground") ? "&" : "") .arg(GetLogCmd()) .arg(timeout)); /* close unused pipe ends */ CLOSE(p_stdin[0]); CLOSE(p_stdout[1]); CLOSE(p_stderr[1]); // store the rest m_stdpipe[0] = p_stdin[1]; m_stdpipe[1] = p_stdout[0]; m_stdpipe[2] = p_stderr[0]; // clean up the memory use if( directory ) free((void *)directory); } /* Parent */ if( GetStatus() != GENERIC_EXIT_RUNNING ) { CLOSE(p_stdin[0]); CLOSE(p_stdin[1]); CLOSE(p_stdout[0]); CLOSE(p_stdout[1]); CLOSE(p_stderr[0]); CLOSE(p_stderr[1]); } }
DWORD WINAPI DebugThread(LPVOID lpvParam) { DWORD nWait = WAIT_TIMEOUT; wchar_t szInfo[1024]; wchar_t szPID[20]; int iAttachedCount = 0; CEStr szOtherBitPids, szOtherDebugCmd; // Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело // к закрытию "отлаживаемой" программы pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop"); pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit"); // Affect GetProcessHandleForDebug gpSrv->DbgInfo.bDebuggerActive = TRUE; // If dump was requested if (gpSrv->DbgInfo.nDebugDumpProcess) { gpSrv->DbgInfo.bUserRequestDump = TRUE; } // "/DEBUGEXE" or "/DEBUGTREE" if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL) { STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi = {}; if (gpSrv->DbgInfo.bDebugProcessTree) { SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES); } if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE| DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS), NULL, NULL, &si, &pi)) { DWORD dwErr = GetLastError(); wchar_t szProc[64]; szProc[0] = 0; PROCESSENTRY32 pi = {sizeof(pi)}; if (GetProcessInfo(gpSrv->dwRootProcess, &pi)) _wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc)); _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr); CEStr lsInfo(lstrmerge(szInfo, gpSrv->DbgInfo.pszDebuggingCmdLine, L"\n")); _wprintf(lsInfo); return CERR_CANTSTARTDEBUGGER; } gpSrv->hRootProcess = pi.hProcess; gpSrv->hRootThread = pi.hThread; gpSrv->dwRootProcess = pi.dwProcessId; gpSrv->dwRootThread = pi.dwThreadId; gpSrv->dwRootStartTime = GetTickCount(); // Let's know that at least one process is debugging iAttachedCount++; } /* ************************* */ int iDbgIdx = 0; bool bSetKillOnExit = true; while (true) { HANDLE hDbgProcess = NULL; DWORD nDbgProcessID = 0; if ((iDbgIdx++) == 0) { hDbgProcess = gpSrv->hRootProcess; nDbgProcessID = gpSrv->dwRootProcess; } else { // Взять из pDebugAttachProcesses if (!gpSrv->DbgInfo.pDebugAttachProcesses) break; if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID)) break; hDbgProcess = GetProcessHandleForDebug(nDbgProcessID); if (!hDbgProcess) { _ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle"); continue; } } _ASSERTE(hDbgProcess!=NULL && "Process handle must be opened"); // Битность отладчика должна соответствовать битности приложения! if (IsWindows64()) { int nBits = GetProcessBits(nDbgProcessID, hDbgProcess); if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64))) { // If /DEBUGEXE or /DEBUGTREE was used if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL) { _printf("Bitness of ConEmuC and debugging program does not match\n"); continue; } // Добавить процесс в список для запуска альтернативного дебаггера соотвествующей битности // Force trailing "," even if only one PID specified ( --> bDebugMultiProcess = TRUE) lstrmerge(&szOtherBitPids.ms_Arg, _itow(nDbgProcessID, szPID, 10), L","); // Может там еще процессы в списке на дамп? continue; } } if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL) { if (DebugActiveProcess(nDbgProcessID)) { iAttachedCount++; } else { DWORD dwErr = GetLastError(); wchar_t szProc[64]; szProc[0] = 0; PROCESSENTRY32 pi = {sizeof(pi)}; if (GetProcessInfo(nDbgProcessID, &pi)) _wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc)); _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n", szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr); _wprintf(szInfo); // Может другие подцепить получится? continue; } } // To avoid debugged processes killing if (bSetKillOnExit && pfnDebugSetProcessKillOnExit) { // affects all current and future debuggees connected to the calling thread if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/)) { bSetKillOnExit = false; } } } // Different bitness, need to start appropriate debugger if (szOtherBitPids.ms_Arg && *szOtherBitPids.ms_Arg) { wchar_t szExe[MAX_PATH+5], *pszName; if (!GetModuleFileName(NULL, szExe, MAX_PATH)) { _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) failed. ErrCode=0x%08X\n", GetLastError()); _wprintf(szInfo); } else if (!(pszName = (wchar_t*)PointToName(szExe))) { _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) returns invalid path\n%s\n", szExe); _wprintf(szInfo); } else { *pszName = 0; // Reverted to current bitness wcscat_c(szExe, WIN3264TEST(L"ConEmuC64.exe", L"ConEmuC.exe")); szOtherDebugCmd.Attach(lstrmerge(L"\"", szExe, L"\" " L"/DEBUGPID=", szOtherBitPids.ms_Arg, (gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L" /DUMP" : (gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L" /MINIDUMP" : (gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L" /FULLDUMP" : L"")); STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi = {}; if (CreateProcess(NULL, szOtherDebugCmd.ms_Arg, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { // Ждать не будем } else { DWORD dwErr = GetLastError(); _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger, ErrCode=0x%08X\n", dwErr); CEStr lsInfo(lstrmerge(szInfo, szOtherDebugCmd, L"\n")); _wprintf(lsInfo); } } } //_ASSERTE(FALSE && "Continue to dump"); // If neither /DEBUG[EXE|TREE] nor /DEBUGPID was not succeeded if (iAttachedCount == 0) { gpSrv->DbgInfo.bDebuggerActive = FALSE; return CERR_CANTSTARTDEBUGGER; } else if (iAttachedCount > 1) { _ASSERTE(gpSrv->DbgInfo.bDebugMultiProcess && "Already must be set from arguments parser"); gpSrv->DbgInfo.bDebugMultiProcess = TRUE; } if (gpSrv->DbgInfo.bUserRequestDump) { gpSrv->DbgInfo.nWaitTreeBreaks = iAttachedCount; } /* **************** */ // To avoid debugged processes killing (JIC, must be called already) if (bSetKillOnExit && pfnDebugSetProcessKillOnExit) { // affects all current and future debuggees connected to the calling thread if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/)) { bSetKillOnExit = false; } } PrintDebugInfo(); SetEvent(gpSrv->DbgInfo.hDebugReady); while (nWait == WAIT_TIMEOUT) { ProcessDebugEvent(); if (ghExitQueryEvent) nWait = WaitForSingleObject(ghExitQueryEvent, 0); } //done: gbRootAliveLess10sec = FALSE; gbInShutdown = TRUE; gbAlwaysConfirmExit = FALSE; _ASSERTE(gbTerminateOnCtrlBreak==FALSE); if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep); SetTerminateEvent(ste_DebugThread); return 0; }
sLONG XWinProcessLauncher::Start(const EnvVarNamesAndValuesMap &inVarToUse) { sLONG err = 0; sLONG pathLen = 0; STARTUPINFO theStartupInfo; PROCESS_INFORMATION theProcessInformation; SECURITY_ATTRIBUTES theSecurityAttributes; char *envVarsBlock = NULL; char *argsAsCString= NULL; if(fBinaryPath == NULL) return -50; // Invalid parameter pathLen = (sLONG) strlen(fBinaryPath); if(pathLen == 0) return -50; // Invalid parameter // Sets the bInheritHandle flag so that pipes are inherited theSecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); theSecurityAttributes.bInheritHandle = TRUE; theSecurityAttributes.lpSecurityDescriptor = NULL; ::SetLastError(0); // ______________________________________________ STDIN pipes if(err == 0 && fRedirectStandardInput) { // Creates a pipe for the child process STDIN if(!CreatePipe(&fChildStdInRead, &fChildStdInWrite, &theSecurityAttributes, 0)) err = ::GetLastError(); // Duplicates the write handle so that it is not inherited if(err == 0) { if(!DuplicateHandle(GetCurrentProcess(), fChildStdInWrite, GetCurrentProcess(), &fChildStdInWriteDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) err = ::GetLastError(); } _CloseAndInvalidateHandle(&fChildStdInWrite); } // ______________________________________________ STDOUT/STDERR pipes if(err == 0 && fRedirectStandardOutput) { // Creates a pipe for the child process's STDOUT if(!CreatePipe(&fChildStdOutRead, &fChildStdOutWrite, &theSecurityAttributes, 0)) err = ::GetLastError(); if (err == 0) { DWORD mode = PIPE_NOWAIT; if (!SetNamedPipeHandleState(fChildStdOutRead, &mode, NULL, NULL)) err = ::GetLastError(); } // Duplicates the read handle to the pipe so that it is not inherited if(err == 0) { if(!DuplicateHandle(GetCurrentProcess(), fChildStdOutRead, GetCurrentProcess(), &fChildStdOutReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) err = ::GetLastError(); } _CloseAndInvalidateHandle(&fChildStdOutRead); // The same for STDERR if(err == 0) { if(!CreatePipe(&fChildStdErrRead, &fChildStdErrWrite, &theSecurityAttributes, 0)) err = ::GetLastError(); } if (err == 0) { DWORD mode = PIPE_NOWAIT; if (!SetNamedPipeHandleState(fChildStdErrRead, &mode, NULL, NULL)) err = ::GetLastError(); } if(err == 0) { if(!DuplicateHandle(GetCurrentProcess(), fChildStdErrRead, GetCurrentProcess(), &fChildStdErrReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) err = ::GetLastError(); } _CloseAndInvalidateHandle(&fChildStdErrRead); } // if(err == 0 && fRedirectStandardOutput) // ______________________________________________ Setup CreateProcess() parameters if(err == 0) { // Sets up members of the PROCESS_INFORMATION structure ZeroMemory(&theProcessInformation, sizeof(PROCESS_INFORMATION)); // Sets up members of the STARTUPINFO structure ZeroMemory(&theStartupInfo, sizeof(STARTUPINFO)); theStartupInfo.cb = sizeof(STARTUPINFO); if(fRedirectStandardInput || fRedirectStandardOutput) theStartupInfo.dwFlags |= STARTF_USESTDHANDLES; theStartupInfo.hStdInput = NULL; theStartupInfo.hStdOutput = NULL; theStartupInfo.hStdError = NULL; if(fRedirectStandardInput) theStartupInfo.hStdInput = fChildStdInRead; if(fRedirectStandardOutput) { theStartupInfo.hStdOutput = fChildStdOutWrite; theStartupInfo.hStdError = fChildStdErrWrite; } // Hides the command window if specified if(fHideWindow) { theStartupInfo.dwFlags |= STARTF_USESHOWWINDOW; theStartupInfo.wShowWindow = SW_HIDE; } // Create the environment variables block envVarsBlock = _CreateEnvironmentVariablesBlock(inVarToUse); // Create the CString arguments. See _CreateConcatenetedArguments(). argsAsCString = _CreateConcatenetedArguments(); if(argsAsCString == NULL) { assert(false); err = -108; } } // if(err == 0) // ______________________________________________ CreateProcess() if(err == 0) { sLONG argsLen = (sLONG) strlen(argsAsCString); sLONG commandFullSize = pathLen + 1; //'\0' if(argsLen > 0) commandFullSize += 1 + argsLen;// ' ' char *commandLine = NULL; if(argsLen > 0) { commandLine = new char[commandFullSize]; if(commandLine == NULL) { err = -108; } else { memcpy(commandLine, fBinaryPath, pathLen); if(argsLen > 0) { commandLine[pathLen] = ' '; memcpy(commandLine + pathLen + 1, argsAsCString, argsLen); } commandLine[commandFullSize - 1] = 0; } } else { sLONG theSize = (sLONG) strlen(fBinaryPath) + 1; commandLine = new char[theSize]; memcpy(commandLine, fBinaryPath, theSize); } if(err == 0) { bool bInheritHandles = fRedirectStandardInput || fRedirectStandardOutput ? TRUE : FALSE; char *lpCurrentDirectory = (fCurrentDirectory != NULL && fCurrentDirectory[0] > 0) ? fCurrentDirectory : NULL; SetLastError(0); long tempLastError = 0; long creaProcResult = CreateProcess(NULL, // Application name commandLine, // Command line NULL, // Process security attributes NULL, // Primary thread security attributes bInheritHandles, // Handles are inherited 0, // DETACHED_PROCESS creation flag envVarsBlock, // NULL == use parent's environment lpCurrentDirectory, // NULL == use parent's directory &theStartupInfo, // STARTUPINFO pointer &theProcessInformation // Receives PROCESS_INFORMATION ); tempLastError = GetLastError(); // For debug if(creaProcResult == 0) // "If the function succeeds, the return value is nonzero" { err = ::GetLastError(); fIsRunning = false; fProcessID = 0; ZeroMemory(&fProcInfo, sizeof(PROCESS_INFORMATION)); } else { fIsRunning = true; fProcInfo = theProcessInformation; fProcessID = fProcInfo.dwProcessId; // If process is independant and we don't need to retrieve exit status at // termination, immediatly close those handles from our part if(!fWaitClosingChildProcess && !fCanGetExitStatus) { CloseHandle(theProcessInformation.hProcess); CloseHandle(theProcessInformation.hThread); } } } // if(err == 0) delete [] commandLine; } // if(err == 0) if(err != 0) _CloseAllPipes(); delete [] argsAsCString; delete [] envVarsBlock; return err; }
DWORD CHooks::RunScript(CString cmd, LPCTSTR currentDir, CString& error, bool bWait, bool bShow) { DWORD exitcode = 0; SECURITY_ATTRIBUTES sa; SecureZeroMemory(&sa, sizeof(sa)); sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; CAutoFile hOut ; CAutoFile hRedir; CAutoFile hErr; // clear the error string error.Empty(); // Create Temp File for redirection TCHAR szTempPath[MAX_PATH] = {0}; TCHAR szOutput[MAX_PATH] = {0}; TCHAR szErr[MAX_PATH] = {0}; GetTortoiseGitTempPath(_countof(szTempPath), szTempPath); GetTempFileName(szTempPath, _T("git"), 0, szErr); // setup redirection handles // output handle must be WRITE mode, share READ // redirect handle must be READ mode, share WRITE hErr = CreateFile(szErr, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0); if (!hErr) { error = CFormatMessageWrapper(); return (DWORD)-1; } hRedir = CreateFile(szErr, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (!hRedir) { error = CFormatMessageWrapper(); return (DWORD)-1; } GetTempFileName(szTempPath, _T("git"), 0, szOutput); hOut = CreateFile(szOutput, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0); if (!hOut) { error = CFormatMessageWrapper(); return (DWORD)-1; } // setup startup info, set std out/err handles // hide window STARTUPINFO si; SecureZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.hStdOutput = hOut; si.hStdError = hErr; si.wShowWindow = bShow ? SW_SHOW : SW_HIDE; PROCESS_INFORMATION pi; SecureZeroMemory(&pi, sizeof(pi)); if (!CreateProcess(nullptr, cmd.GetBuffer(), nullptr, nullptr, TRUE, 0, nullptr, currentDir, &si, &pi)) { const DWORD err = GetLastError(); // preserve the CreateProcess error error = CFormatMessageWrapper(err); SetLastError(err); cmd.ReleaseBuffer(); return (DWORD)-1; } cmd.ReleaseBuffer(); CloseHandle(pi.hThread); // wait for process to finish, capture redirection and // send it to the parent window/console if (bWait) { DWORD dw; char buf[256] = { 0 }; do { while (ReadFile(hRedir, &buf, sizeof(buf)-1, &dw, NULL)) { if (dw == 0) break; error += CString(CStringA(buf,dw)); } Sleep(150); } while (WaitForSingleObject(pi.hProcess, 0) != WAIT_OBJECT_0); // perform any final flushing while (ReadFile(hRedir, &buf, sizeof(buf)-1, &dw, NULL)) { if (dw == 0) break; error += CString(CStringA(buf, dw)); } WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &exitcode); } CloseHandle(pi.hProcess); DeleteFile(szOutput); DeleteFile(szErr); return exitcode; }
HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, HB_FHANDLE * phStdin, HB_FHANDLE * phStdout, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; HB_BOOL fError = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFilename, phStdin, phStdout, phStderr, fDetach, pulPID ) ); if( phStdin != NULL ) fError = ! hb_fsPipeCreate( hPipeIn ); if( ! fError && phStdout != NULL ) fError = ! hb_fsPipeCreate( hPipeOut ); if( ! fError && phStderr != NULL ) { if( phStdout == phStderr ) { hPipeErr[ 0 ] = hPipeOut[ 0 ]; hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else fError = ! hb_fsPipeCreate( hPipeErr ); } if( ! fError ) { #if defined( HB_OS_WIN ) PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; LPTSTR lpCommand = HB_CHARDUP( pszFilename ); memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); # ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; # endif if( fDetach ) { # ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; # endif si.wShowWindow = SW_HIDE; si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); # ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; # endif } else { si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ TRUE, /* bInheritHandles */ dwFlags, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ &si, &pi ); hb_fsSetIOError( ! fError, 0 ); hb_xfree( lpCommand ); if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } #elif defined( HB_OS_UNIX ) && \ ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) pid_t pid = fork(); if( pid == -1 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } else /* child process */ { if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "/dev/null", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) hb_fsClose( hNull ); } if( phStdin != NULL ) { dup2( hPipeIn[ 0 ], 0 ); hb_fsClose( hPipeIn[ 1 ] ); } if( phStdout != NULL ) { dup2( hPipeOut[ 1 ], 1 ); hb_fsClose( hPipeOut[ 0 ] ); } if( phStderr != NULL ) { dup2( hPipeErr[ 1 ], 2 ); if( phStdout != phStderr ) hb_fsClose( hPipeErr[ 0 ] ); } /* close all non std* handles */ { int iMaxFD, i; iMaxFD = sysconf( _SC_OPEN_MAX ); if( iMaxFD < 3 ) iMaxFD = 1024; for( i = 3; i < iMaxFD; ++i ) hb_fsClose( i ); } /* reset extended process attributes */ setuid( getuid() ); setgid( getgid() ); /* execute command */ { char ** argv; argv = hb_buildArgs( pszFilename ); # if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); # else execvp( argv[ 0 ], argv ); # endif hb_freeArgs( argv ); exit( -1 ); } } #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) int hStdIn, hStdOut, hStdErr; char ** argv; int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); hStdErr = dup( 2 ); if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "NUL:", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) close( hNull ); } if( phStdin != NULL ) dup2( hPipeIn[ 0 ], 0 ); if( phStdout != NULL ) dup2( hPipeOut[ 1 ], 1 ); if( phStderr != NULL ) dup2( hPipeErr[ 1 ], 2 ); argv = hb_buildArgs( pszFilename ); #if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv ); #else pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_freeArgs( argv ); dup2( hStdIn, 0 ); close( hStdIn ); dup2( hStdOut, 1 ); close( hStdOut ); dup2( hStdErr, 2 ); close( hStdErr ); if( pid < 0 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } #else int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFilename ); HB_SYMBOL_UNUSED( fDetach ); HB_SYMBOL_UNUSED( pulPID ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); #endif } hb_fsSetIOError( ! fError, 0 ); if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 1 ] ); } return hResult; }