Exemple #1
2
BOOL CIperfThread::InitInstance()
{
    // TODO:  スレッドごとの初期化をここで実行します。
    HANDLE hOldIn = GetStdHandle(STD_INPUT_HANDLE);
    HANDLE hOldOut = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE hOldErr = GetStdHandle(STD_ERROR_HANDLE);

    STARTUPINFOA si;
    memset(&si,0,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;


    m_uniqid = mkhash(m_CmdLine, m_uniqid) ;
    m_uniqid += (WORD)m_nThreadID;
    m_uniqid += (WORD)m_nThreadID >> 4;

    FreeConsole();
    AllocConsole();

    CreateIperfPipe();

    if(CreateProcess(NULL, m_CmdLine, NULL, NULL, TRUE, 0,
        NULL, NULL, &si, &m_ProcessInfo) == FALSE ) {
        return FALSE;
    }

    EnumWindows(WindowHidden, (LPARAM)(PROCESS_INFORMATION *)&m_ProcessInfo);
    WaitForInputIdle(m_ProcessInfo.hProcess, INFINITE);
    SetStdHandle(STD_OUTPUT_HANDLE,hOldOut);
    SetStdHandle(STD_INPUT_HANDLE,hOldIn);
    SetStdHandle(STD_ERROR_HANDLE,hOldErr);
    EnumWindows(WindowHidden, (LPARAM)(PROCESS_INFORMATION *)&m_ProcessInfo);
    return TRUE;
}
Exemple #2
0
unsigned SysRunCommandPipe( const char *cmd, int *readpipe )
{
    int                 rc;
    HANDLE              pipe_input;
    HANDLE              pipe_output;
    HANDLE              pipe_input_dup;
    SECURITY_ATTRIBUTES sa;

    sa.nLength = sizeof( sa );
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    if( !CreatePipe( &pipe_input, &pipe_output, &sa, 0 ) ) {
        return( GetLastError() );
    }
    SetStdHandle( STD_OUTPUT_HANDLE, pipe_output );
    SetStdHandle( STD_ERROR_HANDLE, pipe_output );
    DuplicateHandle( GetCurrentProcess(), pipe_input,
                GetCurrentProcess(), &pipe_input_dup, 0, FALSE,
                DUPLICATE_SAME_ACCESS );
    CloseHandle( pipe_input );
    rc = RunChildProcessCmdl( cmd );
    CloseHandle( pipe_output );
    *readpipe = _hdopen( ( int ) pipe_input_dup, O_RDONLY );
    return( rc );
}
Exemple #3
0
APIRET os2APIENTRY DosDupHandle(os2HFILE hFile,
                                PHFILE pHfile)
{
        int srcIdx = (int)hFile;
        FileTable.lock(srcIdx);
        if(!FileTable[srcIdx]) {
                FileTable.unlock(srcIdx);
                return 1; //FixMe
        }

        int dstIdx;
        if(*pHfile==(os2HFILE)-1) {
                dstIdx = FileTable.findAndLockFree();
                if(dstIdx==-1) {
                        FileTable.unlock(srcIdx);
                        return 4; //too many open files
                }
        } else {
                dstIdx = (int)*pHfile;
                FileTable.lock(dstIdx);
        }
        if(srcIdx==dstIdx) {
                //no-op
                FileTable.unlock(srcIdx);
                return 0;
        }
        if(FileTable[dstIdx]) {
                CloseHandle(FileTable[dstIdx]->ntFileHandle);
                delete FileTable[dstIdx];
                FileTable[dstIdx] = 0;
        }

        APIRET rc;
        HANDLE target;
        if(DuplicateHandle(GetCurrentProcess(),
                           FileTable[srcIdx]->ntFileHandle,
                           GetCurrentProcess(),
                           &target,
                           0,
                           TRUE,
                           DUPLICATE_SAME_ACCESS
                          ))
        {
                rc = 0;
                FileTable[dstIdx] = new ntFILE;
                FileTable[dstIdx]->ntFileHandle = target;
                FileTable[dstIdx]->mode = FileTable[srcIdx]->mode;
                if(dstIdx==0)
                        SetStdHandle(STD_INPUT_HANDLE,target);
                else if(dstIdx==1)
                        SetStdHandle(STD_OUTPUT_HANDLE,target);
                else if(dstIdx==2)
                        SetStdHandle(STD_ERROR_HANDLE,target);
        } else
                rc = 6; //invalid handle
        FileTable.unlock(srcIdx);
        FileTable.unlock(dstIdx);

        return rc;
}
/*
 * WIN32_strerror with argument for late notification */

const char *
WIN32_strerror(int err)
{
    static char xbstrerror_buf[BUFSIZ];

    if (err < 0 || err >= sys_nerr)
	strncpy(xbstrerror_buf, wsastrerror(err), BUFSIZ);
    else
	strncpy(xbstrerror_buf, strerror(err), BUFSIZ);
    return xbstrerror_buf;
}

int
WIN32_Close_FD_Socket(int fd)
{
    int result = 0;

    if (closesocket(_get_osfhandle(fd)) == SOCKET_ERROR) {
	errno = WSAGetLastError();
	result = 1;
    }
    _free_osfhnd(fd);
    _osfile(fd) = 0;
    return result;
}

#if defined(__MINGW32__)	/* MinGW environment */
int
_free_osfhnd(int filehandle)
{
    if (((unsigned) filehandle < SQUID_MAXFD) &&
	(_osfile(filehandle) & FOPEN) &&
	(_osfhnd(filehandle) != (long) INVALID_HANDLE_VALUE)) {
	switch (filehandle) {
	case 0:
	    SetStdHandle(STD_INPUT_HANDLE, NULL);
	    break;
	case 1:
	    SetStdHandle(STD_OUTPUT_HANDLE, NULL);
	    break;
	case 2:
	    SetStdHandle(STD_ERROR_HANDLE, NULL);
	    break;
	}
	_osfhnd(filehandle) = (long) INVALID_HANDLE_VALUE;
	return (0);
    } else {
	errno = EBADF;		/* bad handle */
	_doserrno = 0L;		/* not an OS error */
	return -1;
    }
}
Exemple #5
0
void CIperfThread::CreateIperfPipe()
{
    HANDLE hReadPipeOut;
    HANDLE hReadPipeErr;
    HANDLE hReadPipeInp;
    HANDLE hWritePipeOut;
    HANDLE hWritePipeErr;
    HANDLE hWritePipeInp;

    HANDLE hParent = GetCurrentProcess();

    SECURITY_ATTRIBUTES security;
    security.nLength = sizeof(SECURITY_ATTRIBUTES);
    security.lpSecurityDescriptor = NULL;
    security.bInheritHandle = TRUE;

    if(!CreatePipe(&hReadPipeOut,&hWritePipeOut,&security,0)) ASSERT(0);// ("CreatePipe");
    if(!CreatePipe(&hReadPipeErr,&hWritePipeErr,&security,0)) ASSERT(0);// ("CreatePipe");
    if(!CreatePipe(&hReadPipeInp,&hWritePipeInp,&security,0)) ASSERT(0);// ("CreatePipe");
    
    SetStdHandle(STD_OUTPUT_HANDLE,hWritePipeOut);
    SetStdHandle(STD_ERROR_HANDLE, hWritePipeErr);
    SetStdHandle(STD_INPUT_HANDLE, hReadPipeInp);
    
    DuplicateHandle(hParent,hReadPipeOut,hParent,&m_hPipeOut,0,FALSE,DUPLICATE_SAME_ACCESS);
    DuplicateHandle(hParent,hReadPipeErr,hParent,&m_hPipeErr,0,FALSE,DUPLICATE_SAME_ACCESS);
    DuplicateHandle(hParent,hWritePipeInp,hParent,&m_hPipeIn,0,FALSE,DUPLICATE_SAME_ACCESS);
    
    CloseHandle(hReadPipeOut);
    CloseHandle(hReadPipeErr);
    CloseHandle(hWritePipeInp);
}
Exemple #6
0
bool		ProcInOut::Exec(const std::string & cmd, std::string & out, DWORD timeout) {
	bool	fSuccess; 

	ZeroMemory(&saAttr, sizeof(saAttr));
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL; 
	hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
	if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 
		return false; 
	if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) 
		return false; 
	fSuccess = (DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
		GetCurrentProcess(), &hChildStdoutRdDup , 0,
		(FALSE ? false : true),
		(BOOL)DUPLICATE_SAME_ACCESS) != 0);
	if( !fSuccess )
		return false;
	CloseHandle(hChildStdoutRd);
	if (! CreateChildProcess(cmd)) {
		CloseHandle(hChildStdoutWr);
		CloseHandle(hChildStdoutRdDup);
		CloseHandle(piProcInfo.hProcess);
		CloseHandle(piProcInfo.hThread);
		return false;
	}
	if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) 
		return false;
	if (!CloseHandle(hChildStdoutWr)) 
		return false;
	HANDLE			lpHandles[] = { piProcInfo.hProcess, hChildStdoutRdDup, NULL};
	DWORD			dwWait;
	DWORD			timerStart = GetTickCount();
	DWORD			timerEnd;
	for (;;) {
		dwWait = WaitForMultipleObjects(2, lpHandles, false, timeout);
		// process finished
		if (dwWait == WAIT_OBJECT_0 || dwWait == WAIT_ABANDONED_0 || dwWait == (WAIT_ABANDONED_0 + 1)) {
			break;
		}
		if (dwWait == (WAIT_OBJECT_0 + 1)) {
			timerEnd = GetTickCount();
			// timeout
			if (timerEnd < timerStart && ((MAXDWORD - timerStart) + timerEnd) >= timeout) // counter has been reinitialized
				break ;
			if (timerStart < timerEnd && (timerEnd - timerStart) >= timeout)
				break ;
			ReadFromPipe(out); 
		}
		if (dwWait == WAIT_TIMEOUT) {
			break;			
		}
	}
	CloseHandle(hChildStdoutRdDup);
	CloseHandle(piProcInfo.hProcess);
	CloseHandle(piProcInfo.hThread);
	return true; 
}
Exemple #7
0
/* This function does file handle black magic.  Here, we create pipes,
   duplicate the ones we're going to pass on to the child process, and
   set the current process's stdin and stdout to be those pipes.  (###
   I'm not sure duplicating them is necessary, but it doesn't hurt...)

   inpipes, outpipes, and old_handles are 2 element arrays.  */
static void pipe_setup (STARTUPINFO *siStartInfo, int inpipes[], 
			int outpipes[], HANDLE old_handles[])
{
  const int pipe_size = 2000;
  HANDLE new_stdin, new_stdout;
  HANDLE parent = GetCurrentProcess();

  /* Create new file handles--in binary mode.
     _pipe sticks the read then the write handle in {in,out}pipes, and
     returns 0 on success and -1 on failure */
  if (_pipe(inpipes, pipe_size, O_BINARY) != 0
      || _pipe(outpipes, pipe_size, O_BINARY) != 0

      /* Duplicate the stdin and stdout handles.  False on failure. */
      || !DuplicateHandle(parent, /* source process */
			  /* next, handle to dup */
			  (HANDLE) _get_osfhandle(inpipes[0]),
			  parent,  /* Proc to give new handles to */
			  &new_stdin, /* Where new handle is stored */
			  0,  /* Parameter ignored */
			  TRUE, /* Make new handle inheritable */
			  DUPLICATE_SAME_ACCESS)
      || !DuplicateHandle(parent,  /* source process */
			  /* next, handle to dup */
			  (HANDLE)_get_osfhandle(outpipes[1]),
			  parent,   /* Proc to give new handles to */
			  &new_stdout,  /* Where new handle is stored */
			  0,  /* Parameter ignored */
			  TRUE, /* Make new handle inheritable */
			  DUPLICATE_SAME_ACCESS)) {
    fprintf(stderr, "Failed while doing pipe stuff for fd_exec");
    exit(1);
  }

  /* Save the old stdin and stdout handles to some place we can remember */
  old_handles[0] = GetStdHandle(STD_INPUT_HANDLE);
  old_handles[1] = GetStdHandle(STD_OUTPUT_HANDLE);

  /* Set stdin and stdout to the new handles */
  if (!SetStdHandle(STD_INPUT_HANDLE, new_stdin)
      || !SetStdHandle(STD_OUTPUT_HANDLE, new_stdout)) {
    fprintf(stderr, "Failed while doing pipe stuff for fd_exec");
    exit(1);
  }

  /* Now tell the StartInfo to use the handles we just created.  By
     default, child processes don't inherit the stdin and stdout of
     their parents. */
  siStartInfo->dwFlags = STARTF_USESTDHANDLES;
  siStartInfo->hStdInput = new_stdin;
  siStartInfo->hStdOutput = new_stdout;

  /* nothing funny with stderr, but we still have to initialize 
     the field anyway */
  siStartInfo->hStdError = GetStdHandle(STD_ERROR_HANDLE);
}
Exemple #8
0
static long doExec( const char *std_in, const char *std_out, const char *cmd )
{
    HANDLE      cp;
    long        st;
    HANDLE      old_in;
    HANDLE      new_in;
    HANDLE      old_out;
    HANDLE      new_out;

    old_in = INVALID_HANDLE_VALUE;
    new_in = INVALID_HANDLE_VALUE;
    old_out = INVALID_HANDLE_VALUE;
    new_out = INVALID_HANDLE_VALUE;
    preSpawn();
    cp = GetCurrentProcess();
    if( std_in != NULL ) {
        old_in = GetStdHandle( STD_INPUT_HANDLE );
        new_in = CreateFile( std_in, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
        if( new_in == INVALID_HANDLE_VALUE ) {
            return( -1L );
        }
        SetStdHandle( STD_INPUT_HANDLE, new_in );
    }
    if( std_out != NULL ) {
        old_out = GetStdHandle( STD_INPUT_HANDLE );
        new_out = CreateFile( std_out, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING | CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
        if( new_out == INVALID_HANDLE_VALUE ) {
            if( std_in != NULL ) {
                SetStdHandle( STD_INPUT_HANDLE, old_in );
                CloseHandle( new_in );
            }
            return( -1L );
        }
        SetStdHandle( STD_OUTPUT_HANDLE, new_out );
    }

    if( cmd == NULL ) {
        st = MySpawn( Comspec );
    } else {
        SetConsoleActiveScreenBuffer( GetStdHandle( STD_OUTPUT_HANDLE ) );
        st = system( cmd );
    }

    if( std_in != NULL ) {
        CloseHandle( new_in );
        SetStdHandle( STD_INPUT_HANDLE, old_in );
    }
    if( std_out != NULL ) {
        CloseHandle( new_out );
        SetStdHandle( STD_OUTPUT_HANDLE, old_out );
    }
    postSpawn( st );
    return( st );
}
void console_widget_NT_t::restore_console()
{
	FlushConsoleInputBuffer(saved_input);
	SetConsoleMode(saved_input, saved_mode);
	SetStdHandle(STD_INPUT_HANDLE, saved_input);
	SetStdHandle(STD_OUTPUT_HANDLE, saved_output);
	SetConsoleCursorInfo(saved_output, &saved_cursor);

	if (allocated_console) {
		FreeConsole();
	}
}
Exemple #10
0
/* Here we undo the hackery in the setup, and close any handles we
   know fd_exec doesn't use.
   */
static void pipe_cleanup (int inpipes[], int outpipes[], HANDLE old_handles[])
{
  /* Close unnecessary fd's--the ones the child uses */
  if (close(inpipes[0]) != 0
      || close(outpipes[1]) != 0

  /* close the handles we're pretending are our stdin and stdout */
      || !CloseHandle(GetStdHandle(STD_INPUT_HANDLE))
      || !CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE))

  /* now restore the real stdin and stdout */
      || !SetStdHandle(STD_INPUT_HANDLE, old_handles[0])
      || !SetStdHandle(STD_OUTPUT_HANDLE, old_handles[1])) {
    lose("Failed while doing pipe cleanup for fd_exec");
  }
}
CL_ConsoleWindow_Generic::CL_ConsoleWindow_Generic(
	const CL_StringRef &title,
	int width,
	int height)
{
#ifdef WIN32
	AllocConsole();
	SetConsoleTitle(CL_StringHelp::utf8_to_ucs2(title).c_str());
	COORD coord;
	coord.X = width;
	coord.Y = height;
	scrbuf =
		CreateConsoleScreenBuffer(
			GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE,
			NULL,
			CONSOLE_TEXTMODE_BUFFER,
			NULL);

	if(scrbuf == INVALID_HANDLE_VALUE)
		throw CL_Exception("Unable to allocate console screen buffer");

	SetStdHandle(STD_OUTPUT_HANDLE, scrbuf);
	SetConsoleActiveScreenBuffer(scrbuf);
	SetConsoleScreenBufferSize(scrbuf, coord);

#endif
}
Exemple #12
0
static VOID SetHandle(UINT Number, HANDLE Handle)
{
	if (Number < 3)
		SetStdHandle(STD_INPUT_HANDLE - Number, Handle);
	else
		ExtraHandles[Number - 3] = Handle;
}
void QConsolePrivate::setupStandardIO (DWORD stdHandleId, int targetFd,
                                       const char* name, const char* devName)
{
  log ("Opening %s...\n", devName);

  int fd = open (devName, _O_RDWR | _O_BINARY);

  if (fd != -1)
    {
      if (fd != targetFd)
        {
          log ("Opened %s is not at target file descriptor %d, "
               "duplicating...\n", name, targetFd);
          if (dup2 (fd, targetFd) == -1)
            log ("Failed to duplicate file descriptor: errno=%d.\n", errno);
          if (close (fd) == -1)
            log ("Failed to close original file descriptor: errno=%d.\n",
                 errno);
        }
      else
        log ("%s opened and assigned to file descriptor %d.\n", devName, fd);
      if (! SetStdHandle (stdHandleId, (HANDLE) _get_osfhandle (targetFd)))
        log ("Failed to re-assign %s: error=%08x.\n", name, GetLastError ());
    }
  else
    log ("Failed to open %s: errno=%d.\n", devName, errno);
}
Exemple #14
0
/* Start the reader thread and do all the file handle/descriptor redirection.
   Returns nonzero on success, zero on error. */
int win_stdin_start_thread(void) {
    int stdin_fd;
    int stdin_fmode;

    assert(stdin_thread == NULL);
    assert(stdin_pipe_r == NULL);
    assert(stdin_pipe_w == NULL);
    assert(thread_stdin_handle == NULL);

    /* Create the pipe that win_stdin_thread_func writes to. We reassign the
       read end to be the new stdin that the rest of the program sees. */
    if (CreatePipe(&stdin_pipe_r, &stdin_pipe_w, NULL, 0) == 0)
        return 0;

    /* Make a copy of the stdin handle to be used by win_stdin_thread_func.  It
       will remain a reference to the the true stdin after we fake stdin to read
       from the pipe instead. */
    if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
                        GetCurrentProcess(), &thread_stdin_handle,
                        0, FALSE, DUPLICATE_SAME_ACCESS) == 0) {
        CloseHandle(stdin_pipe_r);
        CloseHandle(stdin_pipe_w);
        return 0;
    }

    /* Set the stdin handle to read from the pipe. */
    if (SetStdHandle(STD_INPUT_HANDLE, stdin_pipe_r) == 0) {
        CloseHandle(stdin_pipe_r);
        CloseHandle(stdin_pipe_w);
        CloseHandle(thread_stdin_handle);
        return 0;
    }
    /* Need to redirect file descriptor 0 also. _open_osfhandle makes a new file
       descriptor from an existing handle. */
    /* Remember the newline translation mode (_O_TEXT or _O_BINARY), and
       restore it in the new file descriptor. */
    stdin_fmode = _getmode(STDIN_FILENO);
    stdin_fd = _open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_RDONLY | stdin_fmode);
    if (stdin_fd == -1) {
        CloseHandle(stdin_pipe_r);
        CloseHandle(stdin_pipe_w);
        CloseHandle(thread_stdin_handle);
        return 0;
    }
    dup2(stdin_fd, STDIN_FILENO);

    /* Finally, start up the thread. We don't bother keeping a reference to it
       because it runs until program termination. From here on out all reads
       from the stdin handle or file descriptor 0 will be reading from the
       anonymous pipe that is fed by the thread. */
    stdin_thread = CreateThread(NULL, 0, win_stdin_thread_func, NULL, 0, NULL);
    if (stdin_thread == NULL) {
        CloseHandle(stdin_pipe_r);
        CloseHandle(stdin_pipe_w);
        CloseHandle(thread_stdin_handle);
        return 0;
    }

    return 1;
}
// set_stdhandle_t
set_stdhandle_t::set_stdhandle_t( DWORD kind, HANDLE handle )
: m_kind( kind ), m_save_handle( GetStdHandle( kind ) ) 
{
    if( m_save_handle==INVALID_HANDLE_VALUE )
        throw os_error_t( "set_stdhandle_t::set_stdhandle_t: GetStdHandle() failed" );
    if( !SetStdHandle( kind, handle ) )
        throw os_error_t( "set_stdhandle_t::set_stdhandle_t: SetStdHandle() failed" );
}
Exemple #16
0
VALUE
rb_SetStdHandle( VALUE self, VALUE fd, VALUE hConsoleOutput )
{
   HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
   if (SetStdHandle(NUM2UINT(fd), handle))
      return NUM2UINT(1);
   return rb_getWin32Error();
}
Exemple #17
0
static int MnSetupStdHandles(void)
{
	HANDLE hInFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE,
				    FILE_SHARE_READ | FILE_SHARE_WRITE,
				    NULL, OPEN_EXISTING, 0, NULL);

	if (hInFile == INVALID_HANDLE_VALUE) {
		AddToMessageLog(_T("CreateFile"));
		return -1;
	}

	HANDLE hOutFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE,
				     FILE_SHARE_READ | FILE_SHARE_WRITE,
				     NULL, OPEN_EXISTING, 0, NULL);

	if (hOutFile == INVALID_HANDLE_VALUE) {
		AddToMessageLog(_T("CreateFile"));
		CloseHandle(hInFile);
		return -1;
	}

	HANDLE hErrFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE,
				     FILE_SHARE_READ | FILE_SHARE_WRITE,
				     NULL, OPEN_EXISTING, 0, NULL);

	if (hErrFile == INVALID_HANDLE_VALUE) {
		AddToMessageLog(_T("CreateFile"));
		CloseHandle(hOutFile);
		CloseHandle(hInFile);
		return -1;
	}

	if (!SetStdHandle(STD_INPUT_HANDLE, hInFile) ||
	    !SetStdHandle(STD_OUTPUT_HANDLE, hOutFile) ||
	    !SetStdHandle(STD_ERROR_HANDLE, hErrFile)) {
		AddToMessageLog(_T("SetStdHandle"));
		CloseHandle(hErrFile);
		CloseHandle(hOutFile);
		CloseHandle(hInFile);
		return -1;
	}

	return 0;
}
OutputLogger::~OutputLogger(void)
{
	// Replace fd with it's original details
	if (fileOld && fd >= 0) {
		_dup2(_fileno(fileOld),fd);
		fd = -1;
	}

	if (pThread) {
		// Wait for the thread to exit (the write handle is now invalid so it will have broken the pipe)
		SDL_WaitThread(pThread,NULL);
		pThread = NULL;
	}

	// Close the read end of the pipe, completely closing the pipe
	if (fdPipeRead >= 0) {
		_close(fdPipeRead);
		fdPipeRead = -1;
	}

	// Close the duplicated original file
	if (fileOld) {
		std::fclose(fileOld);
		fileOld = NULL;
	}

	// Close the log file
	if (fileLog) {

		// In the event that we did a freopen on the handle remove the windows
		// output std handle
#ifdef WIN32
		DWORD stdhandle = 0;
		if (fileLog == stdout) 
			stdhandle = STD_OUTPUT_HANDLE;
		else if (fileLog == stderr) 
			stdhandle = STD_ERROR_HANDLE;
		if (stdhandle) 
			SetStdHandle(stdhandle,NULL);
#endif

		// Get the size written to the log file
		int sizeLog = std::ftell(fileLog);

		std::fclose(fileLog);
		fileLog = NULL;

		// Delete the log file if it was empty
		if (!sizeLog) std::remove(filenameLog.c_str());
		filenameLog = std::string();
	}

}
Exemple #19
0
static DWORD RunChildProcessCmdl( const char *cmdl, LPPROCESS_INFORMATION pinfo, LPHANDLE readpipe )
{
    HANDLE              cp;
    HANDLE              parent_std_output;
    HANDLE              parent_std_error;
    HANDLE              pipe_input;
    HANDLE              pipe_output;
    SECURITY_ATTRIBUTES sa;
    DWORD               rc = 0;

    sa.nLength = sizeof( sa );
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    if( !CreatePipe( &pipe_input, &pipe_output, &sa, 0 ) ) {
        return( GetLastError() );
    }
    cp = GetCurrentProcess();
    DuplicateHandle( cp, GetStdHandle( STD_OUTPUT_HANDLE ), cp, &parent_std_output, 0, TRUE, DUPLICATE_SAME_ACCESS );
    DuplicateHandle( cp, GetStdHandle( STD_ERROR_HANDLE ), cp, &parent_std_error, 0, TRUE, DUPLICATE_SAME_ACCESS );
    SetStdHandle( STD_OUTPUT_HANDLE, pipe_output );
    SetStdHandle( STD_ERROR_HANDLE, pipe_output );
    if( !DuplicateHandle( cp, pipe_input, cp, readpipe, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
        rc = GetLastError();
    }
    CloseHandle( pipe_input );
    if( rc == 0 ) {
        STARTUPINFO     sinfo;
        memset( &sinfo, 0, sizeof( sinfo ) );
        sinfo.cb = sizeof( sinfo );
        if( !CreateProcess( NULL, (LPSTR)cmdl, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, pinfo ) ) {
            rc = GetLastError();
        }
    }
    CloseHandle( pipe_output );
    SetStdHandle( STD_OUTPUT_HANDLE, parent_std_output );
    SetStdHandle( STD_ERROR_HANDLE, parent_std_error );
    CloseHandle( parent_std_output );
    CloseHandle( parent_std_error );
    return( rc );
}
Exemple #20
0
int nt_dup2(int fdorig,int fdcopy) {

    HANDLE hdup;
    HANDLE horig =  __gOpenFiles[fdorig].handle;


    if (__gOpenFiles[fdcopy].handle != INVHL) {
        CloseHandle((HANDLE)__gOpenFiles[fdcopy].handle );
        __gOpenFiles[fdcopy].handle = INVHL;
        __gOpenFiles[fdcopy].flags = 0;
    }
    if (!DuplicateHandle(GetCurrentProcess(),
                         horig,
                         GetCurrentProcess(),
                         &hdup,
                         0,
                         fdcopy<3?TRUE:FALSE, DUPLICATE_SAME_ACCESS)) {
        errno = GetLastError();
        errno = EBADF;
        return -1;
    }
    __gOpenFiles[fdcopy].handle = hdup;
    __gOpenFiles[fdcopy].flags = __gOpenFiles[fdorig].flags;
    switch(fdcopy) {
    case 0:
        SetStdHandle(STD_INPUT_HANDLE,hdup);
        break;
    case 1:
        SetStdHandle(STD_OUTPUT_HANDLE,hdup);
        break;
    case 2:
        SetStdHandle(STD_ERROR_HANDLE,hdup);
        break;
    default:
        break;
    }

    return  0;
}
OutputLogger::OutputLogger(FILE *file, const std::string &filename) :
	fd(-1), fileOld(NULL), filenameLog(filename), fileLog(NULL), 	
	fdPipeRead(-1), pThread(NULL)
{
	// Get the underlying file descriptor for the FILE stream
	fd = _fileno(file);

	// Probably on windows and there is no stdout/stderr in Subsystem Windows
	if (fd < 0) {
		fileLog = freopen(filenameLog.c_str(),"w",file);
#ifdef WIN32
		DWORD stdhandle = 0;
		if (fileLog == stdout) 
			stdhandle = STD_OUTPUT_HANDLE;
		else if (fileLog == stderr) 
			stdhandle = STD_ERROR_HANDLE;
		if (stdhandle) 
			SetStdHandle(stdhandle,(HANDLE)_get_osfhandle(_fileno(fileLog)));
#endif
		return;
	}

	// Create the pipe
	int fdsPipe[2];
	if (_pipe(fdsPipe,256,_O_BINARY) != 0) {
		return;
	}
	fdPipeRead = fdsPipe[0];
	int fdPipeWrite = fdsPipe[1];

	// Make sure that buffering is turned off on the incoming file
	std::setvbuf(file,NULL,_IONBF,0);

	// Duplicate the fd and create new filestream for it
	fileOld = _fdopen(_dup(fd),"w");
	// If the file was stderr, make sure the new file doesn't have buffering
	if (fileOld && file == stderr) std::setvbuf(fileOld,NULL,_IONBF,0);

	// Create the output log file
	fileLog =  std::fopen(filenameLog.c_str(),"w");

	// Duplicate pipe write file descriptor and replace original
	_dup2(fdPipeWrite,fd);
	
	// Close the fd for the write end of the pipe
	_close(fdPipeWrite);
	fdPipeWrite = -1;

	// Create the thread
	pThread = SDL_CreateThread( (int (SDLCALL*)(void*)) &OutputLogger::sThreadMain,this);
}
Exemple #22
0
		bool DaemonWin32::start()
		{
			setlocale(LC_CTYPE, "");
			SetConsoleCP(1251);
			SetConsoleOutputCP(1251);
			setlocale(LC_ALL, "Russian");
#ifdef WIN32_APP
            if (!i2p::win32::StartWin32App ()) return false;

            // override log
            i2p::config::SetOption("log", std::string ("file"));
#endif
			bool ret = Daemon_Singleton::start();
			if (ret && i2p::log::Logger().GetLogType() == eLogFile)
			{
				// TODO: find out where this garbage to console comes from
				SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
				SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
			}
			bool insomnia; i2p::config::GetOption("insomnia", insomnia);
			if (insomnia)
				SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
			return ret;
		}
Exemple #23
0
static
int
_to_descriptor(HANDLE source, void* fd)
{
    intptr_t res = (intptr_t)fd;
    static const DWORD StdHandleTable[] = { STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE };

    if (res < 0 || !(res < 3)) {
        errno = EINVAL;
        return -1;
    }
    // FIXME: int cygwin_attach_handle_to_fd(char* name, int fd, HANDLE handle, mode_t bin, DWORD myaccess)

    assert(res < sizeof(StdHandleTable)/sizeof(StdHandleTable[0]) );
    return SetStdHandle(StdHandleTable[res], source)? 0 : -1;
}
Exemple #24
0
HANDLE GetFileHandle(char *pFilePath)
{
	printf("GetFileHandle(%s)", pFilePath);
	HANDLE hStdOutFile = GetStdHandle(STD_OUTPUT_HANDLE);
	if (INVALID_HANDLE_VALUE == hStdOutFile)return INVALID_HANDLE_VALUE;
	if (!pFilePath)return hStdOutFile;

	HANDLE	 hFile = CreateFile(pFilePath,GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
	if(INVALID_HANDLE_VALUE == hFile)return hStdOutFile;

	if (!SetStdHandle(STD_OUTPUT_HANDLE, hFile))
	{
		CloseHandle(hFile);
		return hStdOutFile;
	}
	return hFile;
}
Exemple #25
0
/// Try to set std HANDLE from FILE*
static void WINAPI_SetStdHandleFromFile(int type, FILE *file)
{

	int fd;
	HANDLE handle;

	fd = _fileno(file);

	if (fd < 0) {
		return;
	}

	handle = (HANDLE)_get_osfhandle(fd);

	if (! handle || handle == INVALID_HANDLE_VALUE) {
		return;
	}

	SetStdHandle(type, handle);

}
Exemple #26
0
static void app_init_logging() {
    BOOL outputToConsole = !!wcsstr(GetCommandLine(), L"--console");
    if (outputToConsole) {
        AllocConsole();
        freopen("CONOUT$", "wb", stdout);
        freopen("CONOUT$", "wb", stderr);
    } else {
        WCHAR buf[MAX_PATH];
        MultiByteToWideChar(CP_UTF8, 0, os_log_path, -1, buf, MAX_PATH);
        wcscat(buf, L"\\log.txt");
        _wfreopen(buf, L"w", stderr);
        HANDLE hLogFile = (HANDLE) _get_osfhandle(_fileno(stderr));
        //HANDLE hLogFile = CreateFile(buf, FILE_ALL_ACCESS, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
        //SetStdHandle(STD_OUTPUT_HANDLE, hLogFile);
        SetStdHandle(STD_ERROR_HANDLE, hLogFile);
    }
    time_t startup_time = time(NULL);
    struct tm *startup_tm = gmtime(&startup_time);
    fprintf(stderr, "%04d-%02d-%02d %02d:%02d:%02d LiveReload " LIVERELOAD_VERSION " launched\n", 1900 + startup_tm->tm_year,
        1 + startup_tm->tm_mon, startup_tm->tm_mday, startup_tm->tm_hour, startup_tm->tm_min, startup_tm->tm_sec);
    fflush(stderr);
}
VOID
IN_PROCESS_APPLICATION::SetCallbackHandles(
    _In_ PFN_REQUEST_HANDLER request_handler,
    _In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
    _In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
    _In_ VOID* pvRequstHandlerContext,
    _In_ VOID* pvShutdownHandlerContext
)
{
    m_RequestHandler = request_handler;
    m_RequestHandlerContext = pvRequstHandlerContext;
    m_ShutdownHandler = shutdown_handler;
    m_ShutdownHandlerContext = pvShutdownHandlerContext;
    m_AsyncCompletionHandler = async_completion_handler;

    CloseStdErrHandles();
    // Can't check the std err handle as it isn't a critical error
    SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
    // Initialization complete
    SetEvent(m_pInitalizeEvent);
    m_fInitialized = TRUE;
}
// Redirects stdout/stderr back to the original stdout/stderr.
// Note, this will not restore the original handle values returned by GetStdHandle,
// rather a duplicated number. This is because the original handle value is invalid
// due to dup2 closing the file originally in stdout/stderr
HRESULT
StdWrapper::StopRedirection() const
{
    // After setting the std handle, we need to set stdout/stderr to the current
    // output/error handle.
    FILE * file = _fdopen(m_previousFileDescriptor, "w");
    if (file == nullptr)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    RETURN_LAST_ERROR_IF(!SetStdHandle(m_stdHandleNumber, reinterpret_cast<HANDLE>(_get_osfhandle(m_previousFileDescriptor))));

    if (!m_enableNativeRedirection)
    {
        return S_OK;
    }

    // Set stdout/stderr to the newly created file output.
    const auto dup2Result = _dup2(_fileno(file), _fileno(m_stdStream));
    if (dup2Result != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    if (setvbuf(m_stdStream, nullptr, _IONBF, 0) != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    if (fclose(m_redirectedFile) != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    return S_OK;
}
/*static*/
IProcess* WinProcessImpl::Execute(wxEvtHandler *parent, const wxString& cmd, wxString &errMsg, IProcessCreateFlags flags, const wxString &workingDir, IProcessCallback* cb)
{
    SECURITY_ATTRIBUTES saAttr;
    BOOL                fSuccess;

    MyDirGuard dg;

    wxString wd(workingDir);
    if (workingDir.IsEmpty()) {
        wd = wxGetCwd();
    }
    wxSetWorkingDirectory( wd );

    // Set the bInheritHandle flag so pipe handles are inherited.
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    WinProcessImpl *prc = new WinProcessImpl(parent);
    prc->m_callback = cb;
    prc->m_flags = flags;

    // The steps for redirecting child process's STDOUT:
    //     1. Save current STDOUT, to be restored later.
    //     2. Create anonymous pipe to be STDOUT for child process.
    //     3. Set STDOUT of the parent process to be write handle to
    //        the pipe, so it is inherited by the child process.
    //     4. Create a noninheritable duplicate of the read handle and
    //        close the inheritable read handle.

    // Save the handle to the current STDOUT.
    prc->hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    // Create a pipe for the child process's STDOUT.
    if ( !CreatePipe( &prc->hChildStdoutRd, &prc->hChildStdoutWr, &saAttr, 0) ) {
        delete prc;
        return NULL;
    }

    // Set a write handle to the pipe to be STDOUT.
    if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hChildStdoutWr) ) {
        delete prc;
        return NULL;
    }

    // Create noninheritable read handle and close the inheritable read handle.
    fSuccess = DuplicateHandle( GetCurrentProcess(), prc->hChildStdoutRd,
                                GetCurrentProcess(),  &prc->hChildStdoutRdDup ,
                                0,  FALSE,
                                DUPLICATE_SAME_ACCESS );
    if ( !fSuccess ) {
        delete prc;
        return NULL;
    }
    CloseHandle( prc->hChildStdoutRd );

    // The steps for redirecting child process's STDERR:
    //     1. Save current STDERR, to be restored later.
    //     2. Create anonymous pipe to be STDERR for child process.
    //     3. Set STDERR of the parent process to be write handle to
    //        the pipe, so it is inherited by the child process.
    //     4. Create a noninheritable duplicate of the read handle and
    //        close the inheritable read handle.

    // Save the handle to the current STDERR.
    prc->hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);

    // Create a pipe for the child process's STDERR.
    if ( !CreatePipe( &prc->hChildStderrRd, &prc->hChildStderrWr, &saAttr, 0) ) {
        delete prc;
        return NULL;
    }

    // Set a write handle to the pipe to be STDERR.
    if ( !SetStdHandle(STD_ERROR_HANDLE, prc->hChildStderrWr) ) {
        delete prc;
        return NULL;
    }

    // Create noninheritable read handle and close the inheritable read handle.
    fSuccess = DuplicateHandle( GetCurrentProcess(), prc->hChildStderrRd,
                                GetCurrentProcess(),  &prc->hChildStderrRdDup ,
                                0,  FALSE,
                                DUPLICATE_SAME_ACCESS );
    if ( !fSuccess ) {
        delete prc;
        return NULL;
    }
    CloseHandle( prc->hChildStderrRd );

    // The steps for redirecting child process's STDIN:
    //     1.  Save current STDIN, to be restored later.
    //     2.  Create anonymous pipe to be STDIN for child process.
    //     3.  Set STDIN of the parent to be the read handle to the
    //         pipe, so it is inherited by the child process.
    //     4.  Create a noninheritable duplicate of the write handle,
    //         and close the inheritable write handle.

    // Save the handle to the current STDIN.
    prc->hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

    // Create a pipe for the child process's STDIN.
    if ( !CreatePipe(&prc->hChildStdinRd, &prc->hChildStdinWr, &saAttr, 0) ) {
        delete prc;
        return NULL;
    }
    // Set a read handle to the pipe to be STDIN.
    if ( !SetStdHandle(STD_INPUT_HANDLE, prc->hChildStdinRd) ) {
        delete prc;
        return NULL;
    }
    // Duplicate the write handle to the pipe so it is not inherited.
    fSuccess = DuplicateHandle(GetCurrentProcess(), prc->hChildStdinWr,
                               GetCurrentProcess(), &prc->hChildStdinWrDup,
                               0, FALSE,                  // not inherited
                               DUPLICATE_SAME_ACCESS );
    if ( !fSuccess ) {
        delete prc;
        return NULL;
    }
    CloseHandle(prc->hChildStdinWr);

    // Execute the child process
    STARTUPINFO siStartInfo;

    // Set up members of STARTUPINFO structure.
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
    siStartInfo.cb = sizeof(STARTUPINFO);

    siStartInfo.dwFlags    = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; ;
    siStartInfo.hStdInput  = prc->hChildStdinRd;
    siStartInfo.hStdOutput = prc->hChildStdoutWr;
    siStartInfo.hStdError  = prc->hChildStderrWr;

    // Set the window to hide
    siStartInfo.wShowWindow = flags & IProcessCreateConsole ? SW_SHOW : SW_HIDE;
    DWORD creationFlags     = flags & IProcessCreateConsole ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW;

    if(flags & IProcessCreateWithHiddenConsole) {
        siStartInfo.wShowWindow = SW_HIDE;
        creationFlags           = CREATE_NEW_CONSOLE|CREATE_NEW_PROCESS_GROUP;
    }

    BOOL ret = CreateProcess( NULL,
                              cmd.wchar_str(),   // shell line execution command
                              NULL,              // process security attributes
                              NULL,              // primary thread security attributes
                              TRUE,              // handles are inherited
                              creationFlags,     // creation flags
                              NULL,              // use parent's environment
                              NULL,              // CD to tmp dir
                              &siStartInfo,      // STARTUPINFO pointer
                              &prc->piProcInfo); // receives PROCESS_INFORMATION
    if ( ret ) {
        prc->dwProcessId = prc->piProcInfo.dwProcessId;
    } else {
        int err = GetLastError();
        wxUnusedVar(err);
        delete prc;
        return NULL;
    }

    // After process creation, restore the saved STDIN and STDOUT.
    if ( !SetStdHandle(STD_INPUT_HANDLE, prc->hSaveStdin) ) {

        delete prc;
        return NULL;
    }
    if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hSaveStdout) ) {

        delete prc;
        return NULL;
    }
    if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hSaveStderr) ) {

        delete prc;
        return NULL;
    }
    
    if ( prc->m_flags & IProcessCreateConsole || prc->m_flags & IProcessCreateWithHiddenConsole ) {
        ConsoleAttacher ca(prc->GetPid());
        if ( ca.isAttached ) {
            freopen("CONOUT$","wb", stdout);  // reopen stout handle as console window output
            freopen("CONOUT$","wb", stderr);  // reopen stderr handle as console window output
        }
    }
    
    prc->SetPid( prc->dwProcessId );
    prc->StartReaderThread();
    return prc;
}
Exemple #30
0
// Function name	: LaunchMPDProcess
// Description	    : 
// Return type		: void 
// Argument         : LaunchMPDProcessArg *pArg
void LaunchMPDProcess(LaunchMPDProcessArg *pArg)
{
	char pBuffer[4096];
	char pszEnv[1024] = "";
	char pszDir[MAX_PATH] = ".";
	char pszCmd[1024] = "";
	char pszArg[1024] = "";
	char pszCmdLine[4096] = "";
	char pszStdinHost[100] = "";
	char pszStdoutHost[100] = "";
	char pszStderrHost[100] = "";
	int nStdinPort = 0, nStdoutPort = 0, nStderrPort = 0;
	int nGroupID = -1, nGroupRank = -1;
	char *token;
	HANDLE hStdin, hStdout, hStderr;
	HANDLE hStdoutPipeW=NULL, hStderrPipeW = NULL, hStdinPipeR=NULL;
	HANDLE hStdoutPipeR=NULL,                      hStdinPipeW=NULL;
	HANDLE hTempPipe=NULL;
	STARTUPINFO saInfo;
	PROCESS_INFORMATION psInfo;
	void *pEnv=NULL;
	char pszSavedPath[MAX_PATH] = ".";
	bool bSuccess = false;
	int nError;
	unsigned long nSrcIP;
	int nSrcPort;
	LaunchNode *pLaunchNode;

	//printf("cmd before: %s\n", pArg->pszCommand);fflush(stdout);
	GetStringOpt(pArg->pszCommand, 'e', pszEnv);
	GetStringOpt(pArg->pszCommand, 'd', pszDir);
	GetStringOpt(pArg->pszCommand, 'c', pszCmd);
	GetStringOpt(pArg->pszCommand, 'a', pszArg);
	//printf("cmd after : %s\n", pArg->pszCommand);fflush(stdout);
	//printf("pszArg: %s\n", pszArg);fflush(stdout);

	if (GetStringOpt(pArg->pszCommand, '0', pBuffer) == 0)
	{
		token = strtok(pBuffer, ":");
		if (token != NULL)
		{
			strcpy(pszStdinHost, token);
			token = strtok(NULL, "");
			if (token != NULL)
			{
				nStdinPort = atoi(token);
			}
		}
	}

	if (GetStringOpt(pArg->pszCommand, '1', pBuffer) == 0)
	{
		token = strtok(pBuffer, ":");
		if (token != NULL)
		{
			strcpy(pszStdoutHost, token);
			token = strtok(NULL, "");
			if (token != NULL)
			{
				nStdoutPort = atoi(token);
			}
		}
	}

	if (GetStringOpt(pArg->pszCommand, '2', pBuffer) == 0)
	{
		token = strtok(pBuffer, ":");
		if (token != NULL)
		{
			strcpy(pszStderrHost, token);
			token = strtok(NULL, "");
			if (token != NULL)
			{
				nStderrPort = atoi(token);
			}
		}
	}

	if (GetStringOpt(pArg->pszCommand, 'g', pBuffer) == 0)
		nGroupID = atoi(pBuffer);

	if (GetStringOpt(pArg->pszCommand, 'r', pBuffer) == 0)
		nGroupRank = atoi(pBuffer);

	pLaunchNode = pArg->pNode;
	nSrcIP = pArg->nSrcIP;
	nSrcPort = pArg->nSrcPort;

	delete pArg->pszCommand;
	delete pArg;
	pArg = NULL;

	// Create the command line
	HMODULE hModule = GetModuleHandle(NULL);
	if (!GetModuleFileName(hModule, pszCmdLine, 4096))
		strcpy(pszCmdLine, "mpd.exe");
	if (pszCmd[0] == '\"')
	{
		if (strlen(pszArg))
			sprintf(pBuffer, " -cmd %s -args \"%s\"", pszCmd, pszArg);
		else
			sprintf(pBuffer, " -cmd %s", pszCmd);
	}
	else
	{
		if (strlen(pszArg))
			sprintf(pBuffer, " -cmd \"%s\" -args \"%s\"", pszCmd, pszArg);
		else
			sprintf(pBuffer, " -cmd \"%s\"", pszCmd);
	}
	strcat(pszCmdLine, pBuffer);
	if (strlen(pszEnv) > 0)
	{
		sprintf(pBuffer, " -env \"%s\"", pszEnv);
		strcat(pszCmdLine, pBuffer);
	}
	if (strlen(pszDir) > 0)
	{
		sprintf(pBuffer, " -dir \"%s\"", pszDir);
		strcat(pszCmdLine, pBuffer);
	}
	if (nStdinPort != 0)
	{
		sprintf(pBuffer, " -0 %s:%d", pszStdinHost, nStdinPort);
		strcat(pszCmdLine, pBuffer);
	}
	if (nStdoutPort != 0)
	{
		sprintf(pBuffer, " -1 %s:%d", pszStdoutHost, nStdoutPort);
		strcat(pszCmdLine, pBuffer);
	}
	if (nStderrPort != 0)
	{
		sprintf(pBuffer, " -2 %s:%d", pszStderrHost, nStderrPort);
		strcat(pszCmdLine, pBuffer);
	}
	if (nGroupID != -1)
	{
		sprintf(pBuffer, " -group %d", nGroupID);
		strcat(pszCmdLine, pBuffer);
	}
	if (nGroupRank != -1)
	{
		sprintf(pBuffer, " -rank %d", nGroupRank);
		strcat(pszCmdLine, pBuffer);
	}

	//printf("launching:\n'%s'\n", pszCmdLine); fflush(stdout);

	WaitForSingleObject(g_hLaunchMutex, INFINITE);

	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

	// Get and save the current standard handles
	hStdin = GetStdHandle(STD_INPUT_HANDLE);
	if (hStdin == INVALID_HANDLE_VALUE)
	{
		nError = GetLastError();
		printf("0 GetStdHandle failed for stdin, error %d\n", nError);fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
		return;
	}
	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hStdout == INVALID_HANDLE_VALUE)
	{
		nError = GetLastError();
		printf("0 GetStdHandle failed for stdout, error %d\n", nError);fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
		return;
	}
	hStderr = GetStdHandle(STD_ERROR_HANDLE);
	if (hStderr == INVALID_HANDLE_VALUE)
	{
		nError = GetLastError();
		printf("0 GetStdHandle failed for stderr, error %d\n", nError);fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
		return;
	}

	// Set the security attributes to allow handles to be inherited
	SECURITY_ATTRIBUTES saAttr;
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.lpSecurityDescriptor = NULL;
	saAttr.bInheritHandle = TRUE;

	// Create an event to be signalled to abort the mpd child process
	HANDLE hAbortEvent = CreateEvent(&saAttr, TRUE, FALSE, NULL);
	sprintf(pBuffer, " -hAbortEvent %u", (int)hAbortEvent);
	strcat(pszCmdLine, pBuffer);
	//printf("hAbortEvent: %d\n", (int)hAbortEvent);fflush(stdout);

	//printf("launching:\n'%s'\n", pszCmdLine); fflush(stdout);

	// Create pipes for stdin, stdout

	// Stdout
	if (!CreatePipe(&hTempPipe, &hStdoutPipeW, &saAttr, 0))
	{
		nError = GetLastError();
		goto CLEANUP;
	}
	// Make the read end of the stdout pipe not inheritable
	if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, 
		GetCurrentProcess(), &hStdoutPipeR, 
		0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
	{
		nError = GetLastError();
		goto CLEANUP;
	}

	// Stdin
	if (!CreatePipe(&hStdinPipeR, &hTempPipe, &saAttr, 0))
	{
		nError = GetLastError();
		goto CLEANUP;
	}
	// Make the write end of the stdin pipe not inheritable
	if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, 
		GetCurrentProcess(), &hStdinPipeW, 
		0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
	{
		nError = GetLastError();
		goto CLEANUP;
	}

	// Set stdin, stdout, and stderr to the ends of the pipe the created process will use
	if (!SetStdHandle(STD_INPUT_HANDLE, hStdinPipeR))
	{
		nError = GetLastError();
		goto CLEANUP;
	}
	if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdoutPipeW))
	{
		nError = GetLastError();
		goto RESTORE_CLEANUP;
	}
	if (!SetStdHandle(STD_ERROR_HANDLE, hStdoutPipeW))
	{
		nError = GetLastError();
		goto RESTORE_CLEANUP;
	}

	// Set up the STARTINFO structure
	memset(&saInfo, 0, sizeof(STARTUPINFO));
	saInfo.cb         = sizeof(STARTUPINFO);
	saInfo.hStdInput  = hStdinPipeR;
	saInfo.hStdOutput = hStdoutPipeW;
	saInfo.hStdError  = hStdoutPipeW;
	saInfo.dwFlags    = STARTF_USESTDHANDLES;

	if (CreateProcess(
		NULL,
		pszCmdLine,
		NULL, NULL, TRUE,
		//DETACHED_PROCESS | IDLE_PRIORITY_CLASS, 
		//CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS,
		CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP,
		//DETACHED_PROCESS | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP,
		//CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_SUSPENDED, 
		NULL, //pEnv,
		NULL,
		&saInfo, &psInfo))
	{
		CloseHandle(psInfo.hThread);
		bSuccess = true;
	}
	else
	{
		nError = GetLastError();
		printf("CreateProcess failed for '%s', error %d\n", pszCmdLine, nError);
	}

RESTORE_CLEANUP:
	// Restore stdin, stdout, stderr
	if (!SetStdHandle(STD_INPUT_HANDLE, hStdin))
	{
		nError = GetLastError();
		printf("SetStdHandle failed to restore stdin, error %d\n", nError);
	}
	if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdout))
	{
		nError = GetLastError();
		printf("SetStdHandle failed to restore stdout, error %d\n", nError);
	}
	if (!SetStdHandle(STD_ERROR_HANDLE, hStderr))
	{
		nError = GetLastError();
		printf("SetStdHandle failed to restore stderr, error %d\n", nError);
	}

CLEANUP:

	CloseHandle(hStdoutPipeW);
	CloseHandle(hStdinPipeR);

	if (bSuccess)
	{
		MPD_CMD_HANDLE hCmd;
		CommandData cmd;
		char *pBuf;

		ProcessNode *p = new ProcessNode;
		strcpy(p->pszCmdLine, pszCmdLine);
		p->nPid = psInfo.dwProcessId;
		//printf("%d\n", psInfo.dwProcessId);fflush(stdout);
		p->nGroupID = nGroupID;
		p->hAbortEvent = hAbortEvent;
		p->hProcess = psInfo.hProcess;
		p->pNext = g_pProcessList;
		g_pProcessList = p;

		cmd.nCommand = MPD_CMD_LAUNCH_RET;
		pBuf = cmd.pCommandBuffer;
		*((unsigned long *)pBuf) = nSrcIP;
		pBuf = pBuf + sizeof(unsigned long);
		*((int *)pBuf) = nSrcPort;
		pBuf = pBuf + sizeof(int);
		*((LaunchNode **)pBuf) = pLaunchNode;
		pBuf = pBuf + sizeof(LaunchNode *);
		*((DWORD*)pBuf) = psInfo.dwProcessId;
		cmd.hCmd.nBufferLength = sizeof(unsigned long) + sizeof(int) + sizeof(LaunchNode*) + sizeof(DWORD);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		ReleaseMutex(g_hLaunchMutex);

		// Tell everyone on the ring that the load on this node has increased by one process.
		cmd.nCommand = MPD_CMD_INCREMENT;
		cmd.hCmd.nBufferLength = 0;
		//printf("Inserting INCREMENT command.\n");fflush(stdout);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		TerminalClientThreadArg *pArg = new TerminalClientThreadArg;
		pArg->hInput = hStdoutPipeR;
		pArg->hOutput = hStdinPipeW;
		TerminalClientThread(pArg);
		// The process should already have exited causing the TerminalClientThread function to return.
		WaitForSingleObject(psInfo.hProcess, 1000);
		// Remove the process handle from the list by setting it to NULL
		WaitForSingleObject(g_hLaunchMutex, 10000);
		p = g_pProcessList;
		while (p != NULL)
		{
			if (p->hProcess == psInfo.hProcess)
			{
				p->hProcess = NULL;
				break;
			}
			p = p->pNext;
		}
		ReleaseMutex(g_hLaunchMutex);

		// Tell everyone on the ring that the load on this node has decreased by one process.
		cmd.nCommand = MPD_CMD_DECREMENT;
		cmd.hCmd.nBufferLength = 0;
		//printf("Inserting DECREMENT command.\n");fflush(stdout);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		// Send the exit code back
		cmd.nCommand = MPD_CMD_LAUNCH_EXITCODE;
		pBuf = cmd.pCommandBuffer;
		*((unsigned long *)pBuf) = nSrcIP;
		pBuf = pBuf + sizeof(unsigned long);
		*((int *)pBuf) = nSrcPort;
		pBuf = pBuf + sizeof(int);
		*((LaunchNode **)pBuf) = pLaunchNode;
		pBuf = pBuf + sizeof(LaunchNode *);
		GetExitCodeProcess(psInfo.hProcess, (DWORD*)pBuf);
		//printf("Process exiting, send exit code: %d\n", *(DWORD*)pBuf);fflush(stdout);
		pBuf = pBuf + sizeof(DWORD);
		*((int *)pBuf) = nGroupID;
		pBuf = pBuf + sizeof(int);
		*((int *)pBuf) = nGroupRank;
		cmd.hCmd.nBufferLength = sizeof(unsigned long) + sizeof(int) + sizeof(LaunchNode*) + sizeof(DWORD) + sizeof(int) + sizeof(int);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		CloseHandle(psInfo.hProcess);
	}
	else
	{
		//printf("0\n");fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
	}

	CloseHandle(hStdoutPipeR);
	CloseHandle(hStdinPipeW);
}