Пример #1
0
Errors Misc_executeCommand(const char        *commandTemplate,
                           const TextMacro   macros[],
                           uint              macroCount,
                           ExecuteIOFunction stdoutExecuteIOFunction,
                           ExecuteIOFunction stderrExecuteIOFunction,
                           void              *executeIOUserData
                          )
{
  Errors          error;
  String          commandLine;
  StringTokenizer stringTokenizer;
  String          token;
  String          command;
  StringList      argumentList;
  const char      *path;
  String          fileName;
  bool            foundFlag;
  char const      **arguments;
  int             pipeStdin[2],pipeStdout[2],pipeStderr[2];
  int             pid;
  StringNode      *stringNode;
  uint            n,z;
  int             status;
  bool            sleepFlag;
  String          stdoutLine,stderrLine;
  int             exitcode;
  int             terminateSignal;

  error = ERROR_NONE;
  if (commandTemplate != NULL)
  {
    commandLine = String_new();
    command     = File_newFileName();
    StringList_init(&argumentList);

    // expand command line
    Misc_expandMacros(commandLine,commandTemplate,macros,macroCount);
    printInfo(3,"Execute command '%s'...",String_cString(commandLine));

    // parse command
    String_initTokenizer(&stringTokenizer,commandLine,STRING_BEGIN,STRING_WHITE_SPACES,STRING_QUOTES,FALSE);
    if (!String_getNextToken(&stringTokenizer,&token,NULL))
    {
      String_doneTokenizer(&stringTokenizer);
      StringList_done(&argumentList);
      String_delete(command);
      String_delete(commandLine);
      return ERRORX_(PARSE_COMMAND,0,String_cString(commandLine));
    }
    File_setFileName(command,token);

    // parse arguments
    while (String_getNextToken(&stringTokenizer,&token,NULL))
    {
      StringList_append(&argumentList,token);
    }
    String_doneTokenizer(&stringTokenizer);

    // find command in PATH
    path = getenv("PATH");
    if (path != NULL)
    {
      fileName  = File_newFileName();
      foundFlag = FALSE;
      String_initTokenizerCString(&stringTokenizer,path,":","",FALSE);
      while (String_getNextToken(&stringTokenizer,&token,NULL) && !foundFlag)
      {
        File_setFileName(fileName,token);
        File_appendFileName(fileName,command);
        if (File_exists(fileName))
        {
          File_setFileName(command,fileName);
          foundFlag = TRUE;
        }
      }
      String_doneTokenizer(&stringTokenizer);
      File_deleteFileName(fileName);
    }

#if 0
fprintf(stderr,"%s,%d: command %s\n",__FILE__,__LINE__,String_cString(command));
stringNode = argumentList.head;
while (stringNode != NULL)
{
fprintf(stderr,"%s,%d: argument %s\n",__FILE__,__LINE__,String_cString(stringNode->string));
stringNode = stringNode->next;
}
#endif /* 0 */

    #if defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
#if 1
      // create i/o pipes
      if (pipe(pipeStdin) != 0)
      {
        error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine));
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }
      if (pipe(pipeStdout) != 0)
      {
        error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine));
        close(pipeStdin[0]);
        close(pipeStdin[1]);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }
      if (pipe(pipeStderr) != 0)
      {
        error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine));
        close(pipeStdout[0]);
        close(pipeStdout[1]);
        close(pipeStdin[0]);
        close(pipeStdin[1]);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }

      // do fork to start separated process
      pid = fork();
      if      (pid == 0)
      {
        // close stdin, stdout, and stderr and reassign them to the pipes
        close(STDERR_FILENO);
        close(STDOUT_FILENO);
        close(STDIN_FILENO);

        // redirect stdin/stdout/stderr to pipe
        dup2(pipeStdin[0],STDIN_FILENO);
        dup2(pipeStdout[1],STDOUT_FILENO);
        dup2(pipeStderr[1],STDERR_FILENO);

        /* close unused pipe handles (the pipes are duplicated by fork(), thus
           there are two open ends of the pipes)
        */
        close(pipeStderr[0]);
        close(pipeStdout[0]);
        close(pipeStdin[1]);

        // execute of external program
        n = 1+StringList_count(&argumentList)+1;
        arguments = (char const**)malloc(n*sizeof(char*));
        if (arguments == NULL)
        {
          HALT_INSUFFICIENT_MEMORY();
        }
        z = 0;
        arguments[z] = String_cString(command); z++;
        stringNode = argumentList.head;
        while (stringNode != NULL)
        {
          assert(z < n);
          arguments[z] = String_cString(stringNode->string); z++;
          stringNode = stringNode->next;
        }
        assert(z < n);
        arguments[z] = NULL; z++;
        execvp(String_cString(command),(char**)arguments);

        // in case exec() fail, return a default exitcode
        HALT_INTERNAL_ERROR("execvp() returned");
      }
      else if (pid < 0)
      {
        error = ERRORX_(EXEC_FAIL,errno,String_cString(commandLine));
        printInfo(3,"FAIL!\n");

        close(pipeStderr[0]);
        close(pipeStderr[1]);
        close(pipeStdout[0]);
        close(pipeStdout[1]);
        close(pipeStdin[0]);
        close(pipeStdin[1]);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }

      // close unused pipe handles (the pipe is duplicated by fork(), thus there are two open ends of the pipe)
      close(pipeStderr[1]);
      close(pipeStdout[1]);
      close(pipeStdin[0]);
#else /* 0 */
error = ERROR_NONE;
#endif /* 0 */

      // wait until process terminate and read stdout/stderr
      stdoutLine = String_new();
      stderrLine = String_new();
      status = 0;
      while ((waitpid(pid,&status,WNOHANG) == 0) || (!WIFEXITED(status) && !WIFSIGNALED(status)))
      {
        sleepFlag = TRUE;

        if (readProcessIO(pipeStdout[0],stdoutLine))
        {
          if (stdoutExecuteIOFunction != NULL) stdoutExecuteIOFunction(executeIOUserData,stdoutLine);
          String_clear(stdoutLine);
          sleepFlag = FALSE;
        }
        if (readProcessIO(pipeStderr[0],stderrLine))
        {
          if (stderrExecuteIOFunction != NULL) stderrExecuteIOFunction(executeIOUserData,stderrLine);
          String_clear(stderrLine);
          sleepFlag = FALSE;
        }

        if (sleepFlag)
        {
          Misc_udelay(500LL*1000LL);
        }
      }
      while (readProcessIO(pipeStdout[0],stdoutLine))
      {
        if (stdoutExecuteIOFunction != NULL) stdoutExecuteIOFunction(executeIOUserData,stdoutLine);
        String_clear(stdoutLine);
      }
      while (readProcessIO(pipeStderr[0],stderrLine))
      {
        if (stderrExecuteIOFunction != NULL) stderrExecuteIOFunction(executeIOUserData,stderrLine);
        String_clear(stderrLine);
      }
      String_delete(stderrLine);
      String_delete(stdoutLine);

      // close i/o
      close(pipeStderr[0]);
      close(pipeStdout[0]);
      close(pipeStdin[1]);

      // check exit code
      exitcode = -1;
      if      (WIFEXITED(status))
      {
        exitcode = WEXITSTATUS(status);
        printInfo(3,"ok (exitcode %d)\n",exitcode);
        if (exitcode != 0)
        {
          error = ERRORX_(EXEC_FAIL,exitcode,String_cString(commandLine));
          StringList_done(&argumentList);
          String_delete(command);
          String_delete(commandLine);
          return error;
        }
      }
      else if (WIFSIGNALED(status))
      {
        terminateSignal = WTERMSIG(status);
        error = ERRORX_(EXEC_FAIL,terminateSignal,String_cString(commandLine));
        printInfo(3,"FAIL (signal %d)\n",terminateSignal);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }
      else
      {
        printInfo(3,"ok (unknown exit)\n");
      }
    #elif defined(WIN32)
#if 0
HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
      HANDLE hInputWriteTmp,hInputRead,hInputWrite;
      HANDLE hErrorWrite;
      HANDLE hThread;
      DWORD ThreadId;
      SECURITY_ATTRIBUTES sa;


      // Set up the security attributes struct.
      sa.nLength= sizeof(SECURITY_ATTRIBUTES);
      sa.lpSecurityDescriptor = NULL;
      sa.bInheritHandle = TRUE;


      // Create the child output pipe.
      if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
         DisplayError("CreatePipe");


      // Create a duplicate of the output write handle for the std error
      // write handle. This is necessary in case the child application
      // closes one of its std output handles.
      if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
                           GetCurrentProcess(),&hErrorWrite,0,
                           TRUE,DUPLICATE_SAME_ACCESS))
         DisplayError("DuplicateHandle");


      // Create the child input pipe.
      if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
         DisplayError("CreatePipe");


      // Create new output read handle and the input write handles. Set
      // the Properties to FALSE. Otherwise, the child inherits the
      // properties and, as a result, non-closeable handles to the pipes
      // are created.
      if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
                           GetCurrentProcess(),
                           &hOutputRead, // Address of new handle.
                           0,FALSE, // Make it uninheritable.
                           DUPLICATE_SAME_ACCESS))
         DisplayError("DupliateHandle");

      if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
                           GetCurrentProcess(),
                           &hInputWrite, // Address of new handle.
                           0,FALSE, // Make it uninheritable.
                           DUPLICATE_SAME_ACCESS))
      DisplayError("DupliateHandle");


      // Close inheritable copies of the handles you do not want to be
      // inherited.
      if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");


      // Get std input handle so you can close it and force the ReadFile to
      // fail when you want the input thread to exit.
      if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) ==
                                                INVALID_HANDLE_VALUE )
         DisplayError("GetStdHandle");

      PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite);


      // Close pipe handles (do not continue to modify the parent).
      // You need to make sure that no handles to the write end of the
      // output pipe are maintained in this process or else the pipe will
      // not close when the child process exits and the ReadFile will hang.
      if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
      if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");


      // Launch the thread that gets the input and sends it to the child.
      hThread = CreateThread(NULL,0,GetAndSendInputThread,
                              (LPVOID)hInputWrite,0,&ThreadId);
      if (hThread == NULL) DisplayError("CreateThread");


      // Read the child's output.
      ReadAndHandleOutput(hOutputRead);
      // Redirection is complete


      // Force the read on the input to return by closing the stdin handle.
      if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");


      // Tell the thread to exit and wait for thread to die.
      bRunThread = FALSE;

      if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED)
         DisplayError("WaitForSingleObject");

      if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
#endif
    #else /* not defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID) || WIN32 */
      #error pipe()/fork()/waitpid() not available nor Win32 system!
    #endif /* defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID) || WIN32 */

    // free resources
    StringList_done(&argumentList);
    String_delete(command);
    String_delete(commandLine);
  }

  return error;
}
Пример #2
0
BOOL Redirector::StartChildProcess(LPCTSTR lpszCmdLine, BOOL bShowChildWindow)
{
	if (m_bWorking) return TRUE;

	Handle hProcess = ::GetCurrentProcess();

	// Set up the security attributes struct.
	SECURITY_ATTRIBUTES sa = {0};
	sa.nLength= sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;

	Handle hStdInWriteTmp, hStdOutReadTmp, hStdErrReadTmp;

	// Create the child stdin pipe.
	if (! ::CreatePipe(&m_hStdIn, &hStdInWriteTmp, &sa, 0)) return FALSE;

	// Create the child stdout pipe.
	if (! ::CreatePipe(&hStdOutReadTmp, &m_hStdOut, &sa, 0)) return FALSE;

	// Create the child stderr pipe.
	if (! ::CreatePipe(&hStdErrReadTmp, &m_hStdErr, &sa, 0)) return FALSE;

	// Create new stdin write, stdout and stderr read handles.
	// Set the properties to FALSE. Otherwise, the child inherits the
	// properties and, as a result, non-closeable handles to the pipes
	// are created.

	if (! ::DuplicateHandle(hProcess, hStdInWriteTmp,
		hProcess, &m_hStdInWrite, 0, FALSE, DUPLICATE_SAME_ACCESS)) return FALSE;

	if (! ::DuplicateHandle(hProcess, hStdOutReadTmp,
		hProcess, &m_hStdOutRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) return FALSE;

	if (! ::DuplicateHandle(hProcess, hStdErrReadTmp,
		hProcess, &m_hStdErrRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) return FALSE;

	// Close inheritable copies of the handles you do not want to be
	// inherited.

	hStdInWriteTmp.Close();
	hStdOutReadTmp.Close();
	hStdErrReadTmp.Close();

	// Start child process with redirected stdout, stdin & stderr
	BOOL bCreateOK = PrepAndLaunchRedirectedChild(lpszCmdLine,
		m_hStdOut, m_hStdIn, m_hStdErr, bShowChildWindow,
		&m_hChildProcess);

	if (! bCreateOK)
	{
		CHAR lpszBuffer[BUFFER_SIZE];
		sprintf_s(lpszBuffer, "Unable to start %s", t2a(lpszCmdLine));
		OnChildStdOutWrite(lpszBuffer);

		// close all handles and return FALSE
		m_hStdIn.Close();
		m_hStdOut.Close();
		m_hStdErr.Close();

		return FALSE;
	}

	DWORD dwThreadID;
	m_bRunThread = TRUE;

	// Create Exit event
	m_hExitEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
	if (! m_hExitEvent.IsValid()) return FALSE;

	// Launch the thread that read the child stdout.
	m_hStdOutThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)staticStdOutThread,
		(LPVOID)this, 0, &dwThreadID);
	if (! m_hStdOutThread.IsValid()) return FALSE;

	// Launch the thread that read the child stderr.
	m_hStdErrThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)staticStdErrThread,
		(LPVOID)this, 0, &dwThreadID);
	if (! m_hStdErrThread.IsValid()) return FALSE;

	// Launch the thread that monitoring the child process.
	m_hProcessThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)staticProcessThread,
		(LPVOID)this, 0, &dwThreadID);
	if (! m_hProcessThread.IsValid()) return FALSE;

	// Virtual function to notify derived class that the child is started.
	OnChildStarted(t2a(lpszCmdLine));

	m_bWorking = TRUE;

	return TRUE;
}
Пример #3
0
bool System::call(const char *command,bool capt_stdout)
{
  hOutputRead=NULL;
  hInputWrite=NULL;
  capture_stdout=capt_stdout;
  hChildProcess = NULL;

  HANDLE hOutputWrite=GetStdHandle(STD_OUTPUT_HANDLE);
  HANDLE hInputRead=GetStdHandle(STD_INPUT_HANDLE);
  SECURITY_ATTRIBUTES sa;


  // Set up the security attributes struct.
  sa.nLength= sizeof(SECURITY_ATTRIBUTES);
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;

  if (capture_stdout)
  {
     HANDLE hOutputReadTmp=NULL;
     HANDLE hInputWriteTmp=NULL;

    // Create the child output pipe.
    if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
    {
      ERROR2("CreatePipe errno:%i\n",GetLastError());
      return false;
    }


    // Create the child input pipe.
    if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
    {
      ERROR2("CreatePipe errno:%i\n",GetLastError());
      return false;
    }


    // Create new output read handle and the input write handles. Set
    // the Properties to FALSE. Otherwise, the child inherits the
    // properties and, as a result, non-closeable handles to the pipes
    // are created.
    if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
          GetCurrentProcess(),
          &hOutputRead, // Address of new handle.
          0,FALSE, // Make it uninheritable.
          DUPLICATE_SAME_ACCESS))
    {
      ERROR2("DupliateHandle errno:%i\n",GetLastError());
      return false;
    }

    if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
          GetCurrentProcess(),
          &hInputWrite, // Address of new handle.
          0,FALSE, // Make it uninheritable.
          DUPLICATE_SAME_ACCESS))
    {
      ERROR2("DupliateHandle errno:%i\n",GetLastError());
      return false;
    }


    // Close inheritable copies of the handles you do not want to be
    // inherited.
    if (!CloseHandle(hOutputReadTmp)) 
    {
      ERROR2("CloseHandle errno:%i\n",GetLastError());
      return false;
    }
    if (!CloseHandle(hInputWriteTmp)) 
    {
      ERROR2("CloseHandle errno:%i\n",GetLastError());
      return false;
    }

  }

  hChildProcess = PrepAndLaunchRedirectedChild(command,hOutputWrite,hInputRead,GetStdHandle(STD_ERROR_HANDLE));


  if (capt_stdout)
  {
    // Close pipe handles (do not continue to modify the parent).
    // You need to make sure that no handles to the write end of the
    // output pipe are maintained in this process or else the pipe will
    // not close when the child process exits and the ReadFile will hang.
    if (!CloseHandle(hOutputWrite)) 
    {
      ERROR2("CloseHandle errno:%i\n",GetLastError());
      return false;
    }
    if (!CloseHandle(hInputRead )) 
    {
      ERROR2("CloseHandle errno:%i\n",GetLastError());
      return false;
    }
  }

  return true;
}
Пример #4
0
BOOL StartChildProcess(void* handle, char* lpszCmdLine, BOOL bShowChildWindow, PROCESS_INFORMATION* ppi)
{
	pcmd_backend_data local = handle;
	HANDLE hProcess = GetCurrentProcess();
	HANDLE hStdInWriteTmp, hStdOutReadTmp, hStdErrReadTmp;
	DWORD dwThreadID;
	// Set up the security attributes struct.
	SECURITY_ATTRIBUTES sa;
	ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
	sa.nLength= sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;


	// Create the child stdin pipe.
	VERIFY(CreatePipe(&local->m_hStdIn, &hStdInWriteTmp, &sa, 0));

	// Create the child stdout pipe.
	VERIFY(CreatePipe(&hStdOutReadTmp, &local->m_hStdOut, &sa, 0));

	// Create the child stderr pipe.
	VERIFY(CreatePipe(&hStdErrReadTmp, &local->m_hStdErr, &sa, 0));

	// Create new stdin write, stdout and stderr read handles.
	// Set the properties to FALSE. Otherwise, the child inherits the
	// properties and, as a result, non-closeable handles to the pipes
	// are created.

	VERIFY(DuplicateHandle(hProcess, hStdInWriteTmp,
		hProcess, &local->m_hStdInWrite, 0, FALSE, DUPLICATE_SAME_ACCESS));

	VERIFY(DuplicateHandle(hProcess, hStdOutReadTmp,
		hProcess, &local->m_hStdOutRead, 0, FALSE, DUPLICATE_SAME_ACCESS));

	VERIFY(DuplicateHandle(hProcess, hStdErrReadTmp,
		hProcess, &local->m_hStdErrRead, 0, FALSE, DUPLICATE_SAME_ACCESS));

	// Close inheritable copies of the handles you do not want to be
	// inherited.

	VERIFY(CloseHandle(hStdInWriteTmp));
	VERIFY(CloseHandle(hStdOutReadTmp));
	VERIFY(CloseHandle(hStdErrReadTmp));

	// Start child process with redirected stdout, stdin & stderr
	local->m_hChildProcess = PrepAndLaunchRedirectedChild(lpszCmdLine, ppi,
		local->m_hStdOut, local->m_hStdIn, local->m_hStdErr, bShowChildWindow);

	if (local->m_hChildProcess == NULL)
	{
		// close all handles and return FALSE
		VERIFY(CloseHandle(local->m_hStdIn));
		local->m_hStdIn = NULL;
		VERIFY(CloseHandle(local->m_hStdOut));
		local->m_hStdOut = NULL;
		VERIFY(CloseHandle(local->m_hStdErr));
		local->m_hStdErr = NULL;

		return FALSE;
	}


	local->m_bRunThread = TRUE;

	// Create Exit event
	local->m_hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	VERIFY(local->m_hExitEvent != NULL);

	// Launch the thread that read the child stdout.
	local->m_hStdOutThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)cygterm_readstdin_thread,
		(LPVOID)local, 0, &dwThreadID);
	VERIFY(local->m_hStdOutThread != NULL);

	SetStdHandle(STD_OUTPUT_HANDLE, local->m_hStdInWrite);
	SetStdHandle(STD_INPUT_HANDLE, local->m_hStdOutRead);
	//// Launch the thread that read the child stderr.
	local->m_hStdErrThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)cygterm_readstderr_thread,
		(LPVOID)local, 0, &dwThreadID);
	VERIFY(local->m_hStdErrThread != NULL);

	// Launch the thread that monitoring the child process.
	local->m_hProcessThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)cygterm_watch_child_process,
		(LPVOID)local, 0, &dwThreadID);
	VERIFY(local->m_hProcessThread != NULL);

	local->m_hWriteEvent = CreateEvent(NULL, FALSE, TRUE, NULL);

	return TRUE;

}
void main ()
{
	HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
	HANDLE hInputWriteTmp,hInputRead,hInputWrite;
	HANDLE hErrorWrite;
	HANDLE hThread;
	DWORD ThreadId;
	SECURITY_ATTRIBUTES sa;


	// Set up the security attributes struct.
	sa.nLength= sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;


	// Create the child output pipe.
	if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
		DisplayError("CreatePipe");


	// Create a duplicate of the output write handle for the std error
	// write handle. This is necessary in case the child application
	// closes one of its std output handles.
	if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
		GetCurrentProcess(),&hErrorWrite,0,
		TRUE,DUPLICATE_SAME_ACCESS))
		DisplayError("DuplicateHandle");


	// Create the child input pipe.
	if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
		DisplayError("CreatePipe");


	// Create new output read handle and the input write handles. Set
	// the Properties to FALSE. Otherwise, the child inherits the
	// properties and, as a result, non-closeable handles to the pipes
	// are created.
	if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
		GetCurrentProcess(),
		&hOutputRead, // Address of new handle.
		0,FALSE, // Make it uninheritable.
		DUPLICATE_SAME_ACCESS))
		DisplayError("DupliateHandle");

	if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
		GetCurrentProcess(),
		&hInputWrite, // Address of new handle.
		0,FALSE, // Make it uninheritable.
		DUPLICATE_SAME_ACCESS))
		DisplayError("DupliateHandle");


	// Close inheritable copies of the handles you do not want to be
	// inherited.
	if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
	if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");


	// Get std input handle so you can close it and force the ReadFile to
	// fail when you want the input thread to exit.
	if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) ==
		INVALID_HANDLE_VALUE )
		DisplayError("GetStdHandle");

	PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite);


	// Close pipe handles (do not continue to modify the parent).
	// You need to make sure that no handles to the write end of the
	// output pipe are maintained in this process or else the pipe will
	// not close when the child process exits and the ReadFile will hang.
	if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
	if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
	if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");


	// Launch the thread that gets the input and sends it to the child.
	hThread = CreateThread(NULL,0,GetAndSendInputThread,
		(LPVOID)hInputWrite,0,&ThreadId);
	if (hThread == NULL) DisplayError("CreateThread");


	// Read the child's output.
	ReadAndHandleOutput(hOutputRead);
	// Redirection is complete


	// Force the read on the input to return by closing the stdin handle.
	Sleep(5000);
	if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");
	printf("closed hStdIn\n");


	// Tell the thread to exit and wait for thread to die.
	bRunThread = FALSE;

	if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED)
		DisplayError("WaitForSingleObject");

	if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
	if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
}
Пример #6
0
BOOL CExecutor::Execute(CString strCmdLine, CMemFile* pInput)
{
	HANDLE hOutputReadTmp,hOutputWrite;
	HANDLE hInputWriteTmp,hInputRead;
	HANDLE hErrorWrite;

	// Set up the security attributes struct.
	SECURITY_ATTRIBUTES sa;
	sa.nLength= sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;

	// Create the child output pipe.
	if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
	{
		//theApp.FormatMessage("CExecutor::Execute::CreatePipe");
	}

	// Create a duplicate of the output write handle for the std error
	// write handle. This is necessary in case the child application
	// closes one of its std output handles.
	if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
					   GetCurrentProcess(),&hErrorWrite,0,
					   TRUE,DUPLICATE_SAME_ACCESS))
	{
		//theApp.FormatMessage("CExecutor::Execute::DuplicateHandle");
	}


	// Create the child input pipe.
	if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
	{
		//theApp.FormatMessage("CExecutor::Execute::CreatePipe");
	}


	// Create new output read handle and the input write handles. Set
	// the Properties to FALSE. Otherwise, the child inherits the
	// properties and, as a result, non-closeable handles to the pipes
	// are created.
	if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
					   GetCurrentProcess(),
					   &m_hOutputRead, // Address of new handle.
					   0,FALSE, // Make it uninheritable.
					   DUPLICATE_SAME_ACCESS))
	{
		//theApp.FormatMessage("CExecutor::Execute::DupliateHandle");
	}

	if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
					   GetCurrentProcess(),
					   &m_hInputWrite, // Address of new handle.
					   0,FALSE, // Make it uninheritable.
					   DUPLICATE_SAME_ACCESS))
	{
		//theApp.FormatMessage("DupliateHandle");
	}


	// Close inheritable copies of the handles you do not want to be
	// inherited.
	if (!CloseHandle(hOutputReadTmp))
	{
		//theApp.FormatMessage("CExecutor::Execute::CloseHandle");
	}
	if (!CloseHandle(hInputWriteTmp))
	{
		//theApp.FormatMessage("CExecutor::Execute::CloseHandle");
	}

	PrepAndLaunchRedirectedChild(hOutputWrite, hInputRead, hErrorWrite, strCmdLine);

	// Close pipe handles (do not continue to modify the parent).
	// You need to make sure that no handles to the write end of the
	// output pipe are maintained in this process or else the pipe will
	// not close when the child process exits and the ReadFile will hang.
	if (!CloseHandle(hOutputWrite))
	{
		//theApp.FormatMessage("CExecutor::Execute::CloseHandle");
	}
	if (!CloseHandle(hInputRead ))
	{
		//theApp.FormatMessage("CExecutor::Execute::CloseHandle");
	}
	if (!CloseHandle(hErrorWrite))
	{
		//theApp.FormatMessage("CExecutor::Execute::CloseHandle");
	}

	// Launch the thread that gets the input and sends it to the child.
	DWORD ThreadId;
	m_hThread = CreateThread(NULL, 0, ReadAndHandleOutput, (LPVOID)this, 0, &ThreadId);
	if (m_hThread == NULL)
	{
		//theApp.FormatMessage("CExecutor::Execute::CreateThread");
	}

	if ( pInput!=NULL )
	{
		LPBYTE buf = (LPBYTE)malloc(pInput->GetLength());
		pInput->SeekToBegin();
		pInput->Read(buf, pInput->GetLength());

		Write(buf, pInput->GetLength());
		Close();

		free(buf);
	}
	else
		Close();

	return TRUE;
}
Пример #7
0
BOOL CGravador::RodaConsole(DWORD * pdwExitCode, CString strRun)
{
	HANDLE hOutputReadTmp;
	HANDLE hOutputWrite;
	SECURITY_ATTRIBUTES sa;

	strReturn.Empty();

	// Set up the security attributes struct.
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;


	// Create the child output pipe.
	if (!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
		DisplayError(_T("CreatePipe"));


	// Create new output read handle and the input write handles. Set
	// the Properties to FALSE. Otherwise, the child inherits the
	// properties and, as a result, non-closeable handles to the pipes
	// are created.
	if (!DuplicateHandle(	GetCurrentProcess(),
							hOutputReadTmp,
							GetCurrentProcess(),
							&hOutputRead, // Address of new handle.
							0,
							FALSE, // Make it uninheritable.
							DUPLICATE_SAME_ACCESS))
		DisplayError(_T("DuplicateHandle"));


	// Close inheritable copies of the handles you do not want to be
	// inherited.
	if (!CloseHandle(hOutputReadTmp))
		DisplayError(_T("CloseHandle"));

	pWDlg->BeginWaitCursor();

	CHandleThread * pHandleThread;
	pHandleThread = new CHandleThread();
	pHandleThread->IniciaThread((void *) this, ReadAndHandleOutput);

	PrepAndLaunchRedirectedChild(hOutputWrite, NULL, NULL, strRun); // o child neste caso será o osql.exe


	// Close pipe handles (do not continue to modify the parent).
	// You need to make sure that no handles to the write end of the
	// output pipe are maintained in this process or else the pipe will
	// not close when the child process exits and the ReadFile will hang.
	if (!CloseHandle(hOutputWrite))
		DisplayError(_T("CloseHandle"));


	// Read the child's output.
	// ReadAndHandleOutput(hOutputRead);

	// Redirection is complete

	// espera finalização do osql.exe
	DWORD dwRet;
	dwRet = WaitForSingleObject(hChildProcess, INFINITE);

	pHandleThread->FinalizaThread(10000);
	delete pHandleThread;

	if (dwRet == WAIT_FAILED)
		DisplayError(_T("WaitForSingleObject"));

	pWDlg->EndWaitCursor();

	if (!CloseHandle(hOutputRead))
		DisplayError(_T("CloseHandle"));

	BOOL bResult;
	bResult = GetExitCodeProcess(hChildProcess, pdwExitCode);
	if (!CloseHandle(hChildProcess))
		DisplayError(_T("CloseHandle"));

	return bResult;
}