HRESULT CTCPStunThread::Init(const TransportAddressSet& tsaListen, const TransportAddressSet& tsaHandler, IStunAuth* pAuth, int maxConnections, boost::shared_ptr<RateLimiter>& spLimiter) { HRESULT hr = S_OK; int ret; int countListen = 0; int countHandler = 0; // we shouldn't be initialized at this point ChkIfA(_pipe[0] != -1, E_UNEXPECTED); ChkIfA(_fThreadIsValid, E_UNEXPECTED); _maxConnections = (maxConnections > 0) ? maxConnections : c_MaxNumberOfConnectionsDefault; // Max sure we didn't accidently pass in anything crazy ChkIfA(_maxConnections >= 100000, E_INVALIDARG); for (size_t i = 0; i < ARRAYSIZE(_tsa.set); i++) { countListen += tsaListen.set[i].fValid ? 1 : 0; countHandler += tsaHandler.set[i].fValid ? 1 : 0; } ChkIfA(countListen == 0, E_INVALIDARG); ChkIfA(countHandler == 0, E_INVALIDARG); _tsaListen = tsaListen; _tsa = tsaHandler; _spAuth.Attach(pAuth); ChkA(CreateListenSockets()); ChkA(CreatePipes()); // +5 for listening sockets and pipe ChkA(CreatePollingInstance(IPOLLING_TYPE_BEST, (size_t)(_maxConnections + 5), _spPolling.GetPointerPointer())); // add listen socket to epoll ASSERT(_fListenSocketsOnEpoll == false); ChkA(SetListenSocketsOnEpoll(true)); // add read end of pipe to epoll so we can get notified of when a signal to exit has occurred ChkA(_spPolling->Add(_pipe[0], EPOLL_PIPE_EVENT_SET)); ret = _hashConnections1.InitTable(_maxConnections, 0); ChkIfA(ret == -1, E_FAIL); ret = _hashConnections2.InitTable(_maxConnections, 0); ChkIfA(ret == -1, E_FAIL); _pNewConnList = &_hashConnections1; _pOldConnList = &_hashConnections2; _spLimiter = spLimiter; _fNeedToExit = false; Cleanup: if (FAILED(hr)) { Reset(); } return hr; }
BOOL DLL_EXPORT FormatDrive(BYTE DriveLetter, LPSTR szLabel, DWORD dwFileSystem, HWND hWnd) { HANDLE hChildStdinRd, hChildStdinWr,hChildStdinWrDup, hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup, hChildStderrRd, hChildStderrWr, hChildStderrRdDup; TCHAR szCommand[MAX_PATH]; DWORD dwExitCode, dwWrited;; TCHAR szEnter[] = "\x0d\x0a"; TCHAR szDrive[] = "X:"; TCHAR szYes[] = "y\x0d\x0a"; TCHAR szFileSystem[16]; TCHAR sz[MAX_PATH]; PROCESS_INFORMATION pi; STARTUPINFO si; if(!( ( DriveLetter >= 'A' && DriveLetter <= 'Z') || ( DriveLetter >= 'a' && DriveLetter <= 'z') )) { return FALSE; }else { szDrive[0] = DriveLetter; } switch(dwFileSystem) { // case FORMAT_FAT_12: // strcpy(szFileSystem,"FAT"); // break; case FORMAT_FAT_16: strcpy(szFileSystem,"FAT"); break; case FORMAT_FAT_32: strcpy(szFileSystem,"FAT32"); break; case FORMAT_NTFS: strcpy(szFileSystem,"NTFS"); break; default: //un known format return FALSE; } ZeroMemory(szCommand, MAX_PATH* sizeof(TCHAR)); //construct format command // sprintf(szCommand,"format.com %s /q /x /v:\"%s\" /fs:%s",szDrive,szLabel,szFileSystem); sprintf(szCommand,"format.com %s /q /x /fs:%s",szDrive,szFileSystem); if(!CreatePipes(hChildStdinRd,hChildStdinWr,hChildStdinWrDup, hChildStdoutRd,hChildStdoutWr,hChildStdoutRdDup, hChildStderrRd,hChildStderrWr,hChildStderrRdDup)) return FALSE; //create format process ZeroMemory(&pi,sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.hStdInput = hChildStdinRd; si.hStdOutput = hChildStdoutWr; si.hStdError = hChildStderrWr; si.dwFlags = STARTF_USESTDHANDLES; CreateProcess(NULL,szCommand,NULL,NULL,TRUE, // 0,NULL,NULL,&si,&pi); CREATE_NO_WINDOW,NULL,NULL,&si,&pi); //write format input ZeroMemory(sz,MAX_PATH); GetVolumeInformation(szDrive,sz,MAX_PATH, NULL, NULL, NULL, NULL, NULL); if(strlen(sz)>0) { strcat(sz,szEnter); WriteFile(hChildStdinWrDup,sz,strlen(sz),&dwWrited,NULL); } WriteFile(hChildStdinWrDup,szYes,strlen(szYes),&dwWrited,NULL); //set label WriteFile(hChildStdinWrDup,szLabel,strlen(szLabel),&dwWrited,NULL); WriteFile(hChildStdinWrDup,szEnter,strlen(szEnter),&dwWrited,NULL); #ifdef _DEBUG ReadFile(hChildStdoutRdDup,sz,MAX_PATH,&dwWrited,NULL); #endif //write additional Enter to avoid invalid volume label WriteFile(hChildStdinWrDup,szEnter,strlen(szEnter),&dwWrited,NULL); WriteFile(hChildStdinWrDup,szEnter,strlen(szEnter),&dwWrited,NULL); //wait for format dwExitCode = QueryFormatProcess(hChildStdoutRdDup, pi.hProcess,hWnd); //close all pipes handle ClosePipes( hChildStdinRd,hChildStdinWr, hChildStdoutRd,hChildStdoutWr, hChildStderrRd,hChildStderrWr); //close duplicate handles CloseHandle(hChildStdinWrDup); CloseHandle(hChildStdoutRdDup); CloseHandle(hChildStderrRdDup); if(dwExitCode == 0) return TRUE; else return FALSE; }
static void StartExternalProcess (TRI_external_t* external, bool usePipes) { int pipe_server_to_child[2]; int pipe_child_to_server[2]; int processPid; if (usePipes) { bool ok; ok = CreatePipes(pipe_server_to_child, pipe_child_to_server); if (! ok) { external->_status = TRI_EXT_PIPE_FAILED; return; } } processPid = fork(); // child process if (processPid == 0) { // set stdin and stdout of child process if (usePipes) { dup2(pipe_server_to_child[0], 0); dup2(pipe_child_to_server[1], 1); fcntl(0, F_SETFD, 0); fcntl(1, F_SETFD, 0); fcntl(2, F_SETFD, 0); // close pipes close(pipe_server_to_child[0]); close(pipe_server_to_child[1]); close(pipe_child_to_server[0]); close(pipe_child_to_server[1]); } else { close(0); fcntl(1, F_SETFD, 0); fcntl(2, F_SETFD, 0); } // ignore signals in worker process signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGUSR1, SIG_IGN); // execute worker execvp(external->_executable, external->_arguments); _exit(1); } // parent if (processPid == -1) { LOG_ERROR("fork failed"); if (usePipes) { close(pipe_server_to_child[0]); close(pipe_server_to_child[1]); close(pipe_child_to_server[0]); close(pipe_child_to_server[1]); } external->_status = TRI_EXT_FORK_FAILED; return; } LOG_DEBUG("fork succeeded, child pid: %d", (int) processPid); if (usePipes) { close(pipe_server_to_child[0]); close(pipe_child_to_server[1]); external->_writePipe = pipe_server_to_child[1]; external->_readPipe = pipe_child_to_server[0]; } else { external->_writePipe = -1; external->_readPipe = -1; } external->_pid = processPid; external->_status = TRI_EXT_RUNNING; }
BOOL Go(const char *commandLine) { HANDLE stdInRead, stdInWrite; if (!CreatePipes(&stdInRead, &stdInWrite)) return FALSE; PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdInput = stdInRead; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; siStartInfo.wShowWindow = SW_HIDE; siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; // Create the child process. if (!CreateProcess(NULL, const_cast<char *>(commandLine), // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited CREATE_BREAKAWAY_FROM_JOB, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo)) // receives PROCESS_INFORMATION { return FALSE; } HANDLE ghJob = CreateJobObject( NULL, NULL); JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if( ghJob == NULL || SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)) == FALSE) { std::cerr << "Error initializing close-process job"; return 1; } if (!AssignProcessToJobObject( ghJob, piProcInfo.hProcess)) { DWORD error = GetLastError(); std::cerr << "AssignProcessToJobObject failed: " << error << std::endl; return FALSE; } // Close handles to the child process and its primary thread. // Some applications might keep these handles to monitor the status // of the child process, for example. CloseHandle(piProcInfo.hThread); MonitorProcessClose(piProcInfo.hProcess); WriteToPipe(stdInWrite, piProcInfo.hProcess); CloseHandle(piProcInfo.hProcess); CloseHandle(stdInRead); CloseHandle(stdInWrite); return 0; }
HRESULT WIXAPI QuietExecEx( __inout_z LPWSTR wzCommand, __in DWORD dwTimeout, __in BOOL fLogCommand, __in BOOL fLogOutput ) { HRESULT hr = S_OK; PROCESS_INFORMATION oProcInfo; STARTUPINFOW oStartInfo; DWORD dwExitCode = ERROR_SUCCESS; HANDLE hOutRead = INVALID_HANDLE_VALUE; HANDLE hOutWrite = INVALID_HANDLE_VALUE; HANDLE hErrWrite = INVALID_HANDLE_VALUE; HANDLE hInRead = INVALID_HANDLE_VALUE; HANDLE hInWrite = INVALID_HANDLE_VALUE; memset(&oProcInfo, 0, sizeof(oProcInfo)); memset(&oStartInfo, 0, sizeof(oStartInfo)); // Create output redirect pipes hr = CreatePipes(&hOutRead, &hOutWrite, &hErrWrite, &hInRead, &hInWrite); ExitOnFailure(hr, "Failed to create output pipes"); // Set up startup structure oStartInfo.cb = sizeof(STARTUPINFOW); oStartInfo.dwFlags = STARTF_USESTDHANDLES; oStartInfo.hStdInput = hInRead; oStartInfo.hStdOutput = hOutWrite; oStartInfo.hStdError = hErrWrite; // Log command if we were asked to do so if (fLogCommand) { WcaLog(LOGMSG_VERBOSE, "%ls", wzCommand); } #pragma prefast(suppress:25028) if (::CreateProcessW(NULL, wzCommand, // command line NULL, // security info NULL, // thread info TRUE, // inherit handles ::GetPriorityClass(::GetCurrentProcess()) | CREATE_NO_WINDOW, // creation flags NULL, // environment NULL, // cur dir &oStartInfo, &oProcInfo)) { ReleaseFile(oProcInfo.hThread); // Close child output/input handles so it doesn't hang ReleaseFile(hOutWrite); ReleaseFile(hErrWrite); ReleaseFile(hInRead); // Log output if we were asked to do so; otherwise just read the output handle HandleOutput(fLogOutput, hOutRead); // Wait for everything to finish ::WaitForSingleObject(oProcInfo.hProcess, dwTimeout); if (!::GetExitCodeProcess(oProcInfo.hProcess, &dwExitCode)) { dwExitCode = ERROR_SEM_IS_SET; } ReleaseFile(hOutRead); ReleaseFile(hInWrite); ReleaseFile(oProcInfo.hProcess); } else { ExitOnLastError(hr, "Command failed to execute."); } ExitOnWin32Error(dwExitCode, hr, "Command line returned an error."); LExit: return hr; }