Пример #1
0
bool Q3Process::start( QStringList *env )
{
#if defined(QT_Q3PROCESS_DEBUG)
    qDebug( "Q3Process::start()" );
#endif
    reset();

    if ( _arguments.isEmpty() )
	return false;

    // Open the pipes.  Make non-inheritable copies of input write and output
    // read handles to avoid non-closable handles (this is done by the
    // DuplicateHandle() call).
    SECURITY_ATTRIBUTES secAtt = { sizeof( SECURITY_ATTRIBUTES ), NULL, TRUE };
#ifndef Q_OS_WINCE
    // I guess there is no stdin stdout and stderr on Q_OS_WINCE to dup
    // CreatePipe and DupilcateHandle aren't available for Q_OS_WINCE
    HANDLE tmpStdin, tmpStdout, tmpStderr;
    if ( comms & Stdin ) {
	if ( !CreatePipe( &d->pipeStdin[0], &tmpStdin, &secAtt, 0 ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !DuplicateHandle( GetCurrentProcess(), tmpStdin, GetCurrentProcess(), &d->pipeStdin[1], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !CloseHandle( tmpStdin ) ) {
	    d->closeHandles();
	    return false;
	}
    }
    if ( comms & Stdout ) {
	if ( !CreatePipe( &tmpStdout, &d->pipeStdout[1], &secAtt, 0 ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !DuplicateHandle( GetCurrentProcess(), tmpStdout, GetCurrentProcess(), &d->pipeStdout[0], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !CloseHandle( tmpStdout ) ) {
	    d->closeHandles();
	    return false;
	}
    }
    if ( comms & Stderr ) {
	if ( !CreatePipe( &tmpStderr, &d->pipeStderr[1], &secAtt, 0 ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !DuplicateHandle( GetCurrentProcess(), tmpStderr, GetCurrentProcess(), &d->pipeStderr[0], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !CloseHandle( tmpStderr ) ) {
	    d->closeHandles();
	    return false;
	}
    }
    if ( comms & DupStderr ) {
	CloseHandle( d->pipeStderr[1] );
	d->pipeStderr[1] = d->pipeStdout[1];
    }
#endif

    // construct the arguments for CreateProcess()
    QString args;
    QString appName;
    QStringList::Iterator it = _arguments.begin();
    args = *it;
    ++it;
    if ( args.endsWith( QLatin1String(".bat") ) && args.contains( QLatin1Char(' ') ) ) {
	// CreateProcess() seems to have a strange semantics (see also
	// http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_11138647.html):
	// If you start a batch file with spaces in the filename, the first
	// argument to CreateProcess() must be the name of the batchfile
	// without quotes, but the second argument must start with the same
	// argument with quotes included. But if the same approach is used for
	// .exe files, it doesn't work.
	appName = args;
	args = QLatin1Char('"') + args + QLatin1Char('"');
    }
    for ( ; it != _arguments.end(); ++it ) {
	QString tmp = *it;
	// escape a single " because the arguments will be parsed
	tmp.replace( QLatin1Char('\"'), QLatin1String("\\\"") );
	if ( tmp.isEmpty() || tmp.contains( QLatin1Char(' ') ) || tmp.contains( QLatin1Char('\t') ) ) {
	    // The argument must not end with a \ since this would be interpreted
	    // as escaping the quote -- rather put the \ behind the quote: e.g.
	    // rather use "foo"\ than "foo\"
	    QString endQuote( QLatin1String("\"") );
	    int i = tmp.length();
	    while ( i>0 && tmp.at( i-1 ) == QLatin1Char('\\') ) {
		--i;
		endQuote += QLatin1Char('\\');
	    }
        args += QLatin1String(" \"") + tmp.left( i ) + endQuote;
	} else {
	    args += QLatin1Char(' ') + tmp;
	}
    }
#if defined(QT_Q3PROCESS_DEBUG)
    qDebug( "Q3Process::start(): args [%s]", args.latin1() );
#endif

    // CreateProcess()
    bool success;
    d->newPid();

    STARTUPINFOW startupInfo = {
        sizeof( STARTUPINFO ), 0, 0, 0,
        (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
        0, 0, 0,
        STARTF_USESTDHANDLES,
        0, 0, 0,
        d->pipeStdin[0], d->pipeStdout[1], d->pipeStderr[1]
    };
    wchar_t *applicationName;
    if ( appName.isNull() )
        applicationName = 0;
    else
        applicationName = _wcsdup( (wchar_t*)appName.utf16() );
    wchar_t *commandLine = _wcsdup( (wchar_t*)args.utf16() );
    QByteArray envlist;
    if ( env != 0 ) {
        int pos = 0;
        // add PATH if necessary (for DLL loading)
        QByteArray path = qgetenv( "PATH" );
        if ( env->grep( QRegExp(QLatin1String("^PATH="),FALSE) ).empty() && !path.isNull() ) {
            QString tmp = QString::fromLatin1("PATH=%1").arg(QLatin1String(path.constData()));
            uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
            envlist.resize( envlist.size() + tmpSize );
            memcpy( envlist.data() + pos, tmp.utf16(), tmpSize );
            pos += tmpSize;
        }
        // add the user environment
        for ( QStringList::Iterator it = env->begin(); it != env->end(); it++ ) {
            QString tmp = *it;
            uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
            envlist.resize( envlist.size() + tmpSize );
            memcpy( envlist.data() + pos, tmp.utf16(), tmpSize );
            pos += tmpSize;
        }
        // add the 2 terminating 0 (actually 4, just to be on the safe side)
        envlist.resize( envlist.size()+4 );
        envlist[pos++] = 0;
        envlist[pos++] = 0;
        envlist[pos++] = 0;
        envlist[pos++] = 0;
    }
    success = CreateProcess( applicationName, commandLine,
                            0, 0, TRUE, ( comms == 0 ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW )
#ifndef Q_OS_WINCE
                            | CREATE_UNICODE_ENVIRONMENT
#endif
                            , env == 0 ? 0 : envlist.data(),
                            (wchar_t*)QDir::toNativeSeparators(workingDir.absPath()).utf16(),
                            &startupInfo, d->pid );

    free( applicationName );
    free( commandLine );

    if  ( !success ) {
	d->deletePid();
	return false;
    }

#ifndef Q_OS_WINCE
    if ( comms & Stdin )
	CloseHandle( d->pipeStdin[0] );
    if ( comms & Stdout )
        CloseHandle( d->pipeStdout[1] );
    if ( (comms & Stderr) && !(comms & DupStderr) )
	CloseHandle( d->pipeStderr[1] );
#endif

    if ( ioRedirection || notifyOnExit ) {
	d->lookup->start( 100 );
    }

    // cleanup and return
    return true;
}
Пример #2
0
int get_exec_output (struct extensible *ex)
{
#ifndef USING_UTILITIES_EXECUTE_MODULE
    ex->result = -1;
    NETSNMP_LOGONCE ((LOG_WARNING, "support for run_exec_command not available\n"));
#else
#if HAVE_EXECV
    char cachefile[STRMAX];

    char cache[NETSNMP_MAXCACHESIZE];

    int cachebytes;

    int cfd;

#ifdef NETSNMP_EXCACHETIME
    long curtime;

    static char lastcmd[STRMAX];

    static int lastresult;
#endif

    DEBUGMSGTL (("exec:get_exec_output", "calling %s\n", ex->command));

    sprintf (cachefile, "%s/%s", get_persistent_directory (), NETSNMP_CACHEFILE);
#ifdef NETSNMP_EXCACHETIME
    curtime = time (NULL);
    if (curtime > (cachetime + NETSNMP_EXCACHETIME) || strcmp (ex->command, lastcmd) != 0)
    {
        strcpy (lastcmd, ex->command);
        cachetime = curtime;
#endif

        cachebytes = NETSNMP_MAXCACHESIZE;
        ex->result = run_exec_command (ex->command, NULL, cache, &cachebytes);

        unlink (cachefile);
        /*
         * XXX  Use SNMP_FILEMODE_CLOSED instead of 644? 
         */
        if ((cfd = open (cachefile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0)
        {
            snmp_log (LOG_ERR, "can not create cache file\n");
            setPerrorstatus (cachefile);
#ifdef NETSNMP_EXCACHETIME
            cachetime = 0;
#endif
            return -1;
        }
        if (cachebytes > 0)
            write (cfd, (void *) cache, cachebytes);
        close (cfd);
#ifdef NETSNMP_EXCACHETIME
        lastresult = ex->result;
    }
    else
    {
        ex->result = lastresult;
    }
#endif
    DEBUGMSGTL (("exec:get_exec_output", "using cached value\n"));
    if ((cfd = open (cachefile, O_RDONLY)) < 0)
    {
        snmp_log (LOG_ERR, "can not open cache file\n");
        setPerrorstatus (cachefile);
        return -1;
    }
    return (cfd);
#else                            /* !HAVE_EXECV */
#if defined(WIN32) && !defined(HAVE_EXECV)

/* MSVC and MinGW.  Cygwin already works as it has execv and fork */
    int fd;

    /* Reference:  MS tech note: 190351 */
    HANDLE hOutputReadTmp, hOutputRead, hOutputWrite = NULL;

    HANDLE hErrorWrite;

    SECURITY_ATTRIBUTES sa;

    PROCESS_INFORMATION pi;

    STARTUPINFO si;

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

    DEBUGMSGTL (("exec:get_exec_output", "calling %s\n", ex->command));

    /* Child temporary output pipe with Inheritance on (sa.bInheritHandle is true) */
    if (!CreatePipe (&hOutputReadTmp, &hOutputWrite, &sa, 0))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CreatePipe ChildOut: %lu\n", GetLastError ()));
        return -1;
    }

    /* Copy the stdout handle to the stderr handle in case the child closes one of 
     * its stdout handles. */
    if (!DuplicateHandle (GetCurrentProcess (), hOutputWrite, GetCurrentProcess (),
                          &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output DuplicateHandle: %lu\n", GetLastError ()));
        return -1;
    }

    /* Create new copies of the input and output handles but set bInheritHandle to 
     * FALSE so the new handle can not be inherited.  Otherwise the handles can not
     * be closed.  */
    if (!DuplicateHandle (GetCurrentProcess (), hOutputReadTmp, GetCurrentProcess (),
                          &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output DupliateHandle ChildOut: %lu\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        return -1;
    }

    /* Close the temporary output and input handles */
    if (!CloseHandle (hOutputReadTmp))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle (hOutputReadTmp): %lu\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        return -1;
    }

    /* Associates a C run-time file descriptor with an existing operating-system file handle. */
    fd = _open_osfhandle ((long) hOutputRead, 0);

    /* Set up STARTUPINFO for CreateProcess with the handles and have it hide the window
     * for the new process. */
    ZeroMemory (&si, sizeof (STARTUPINFO));
    si.cb = sizeof (STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdOutput = hOutputWrite;
    si.hStdError = hErrorWrite;
    si.wShowWindow = SW_HIDE;

    /* Launch the process that you want to redirect.  Example snmpd.conf pass_persist:
     * pass_persist    .1.3.6.1.4.1.2021.255  c:/perl/bin/perl c:/temp/pass_persisttest
     */
    if (!CreateProcess (NULL, ex->command, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CreateProcess:'%s' %lu\n", ex->command, GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        return -1;
    }

    /* Set global child process handle */
    ex->pid = pi.hProcess;
    ex->tid = pi.hThread;

    /* Close pipe handles 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 any calls to ReadFile 
     * will hang.
     */

    if (!CloseHandle (hOutputWrite))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle hOutputWrite: %lu\n", GetLastError ()));
        return -1;
    }
    if (!CloseHandle (hErrorWrite))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle hErrorWrite: %lu\n", GetLastError ()));
        return -1;
    }
    return fd;
#endif                            /* WIN32 */
#endif
#endif                            /* !defined(USING_UTILITIES_EXECUTE_MODULE) */
    return -1;
}
Пример #3
0
int launch_server(int server_port)
{
#ifdef HAVE_WIN32_PROC
    /* we need to start the server in the background                    */
    /* we create a PIPE that will be used to wait for the server's "OK" */
    /* message since the pipe handles must be inheritable, we use a     */
    /* security attribute                                               */
    HANDLE                pipe_read, pipe_write;
    SECURITY_ATTRIBUTES   sa;
    STARTUPINFO           startup;
    PROCESS_INFORMATION   pinfo;
    char                  program_path[ MAX_PATH ];
    int                   ret;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /* create pipe, and ensure its read handle isn't inheritable */
    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
    if (!ret) {
        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
        return -1;
    }

    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );

    ZeroMemory( &startup, sizeof(startup) );
    startup.cb = sizeof(startup);
    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
    startup.hStdOutput = pipe_write;
    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
    startup.dwFlags    = STARTF_USESTDHANDLES;

    ZeroMemory( &pinfo, sizeof(pinfo) );

    /* get path of current program */
    GetModuleFileName( NULL, program_path, sizeof(program_path) );

    ret = CreateProcess(
            program_path,                              /* program path  */
            "adb fork-server server",
                                    /* the fork-server argument will set the
                                       debug = 2 in the child           */
            NULL,                   /* process handle is not inheritable */
            NULL,                    /* thread handle is not inheritable */
            TRUE,                          /* yes, inherit some handles */
            DETACHED_PROCESS, /* the new process doesn't have a console */
            NULL,                     /* use parent's environment block */
            NULL,                    /* use parent's starting directory */
            &startup,                 /* startup info, i.e. std handles */
            &pinfo );

    CloseHandle( pipe_write );

    if (!ret) {
        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
        CloseHandle( pipe_read );
        return -1;
    }

    CloseHandle( pinfo.hProcess );
    CloseHandle( pinfo.hThread );

    /* wait for the "OK\n" message */
    {
        char  temp[3];
        DWORD  count;

        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
        CloseHandle( pipe_read );
        if ( !ret ) {
            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
            return -1;
        }
        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }
    }
#elif defined(HAVE_FORKEXEC)
    char    path[PATH_MAX];
    int     fd[2];

    // set up a pipe so the child can tell us when it is ready.
    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
    if (pipe(fd)) {
        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
        return -1;
    }
    get_my_path(path, PATH_MAX);
    pid_t pid = fork();
    if(pid < 0) return -1;

    if (pid == 0) {
        // child side of the fork

        // redirect stderr to the pipe
        // we use stderr instead of stdout due to stdout's buffering behavior.
        adb_close(fd[0]);
        dup2(fd[1], STDERR_FILENO);
        adb_close(fd[1]);

        // child process
        int result = execl(path, "adb", "fork-server", "server", NULL);
        // this should not return
        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
    } else  {
        // parent side of the fork

        char  temp[3];

        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
        // wait for the "OK\n" message
        adb_close(fd[1]);
        int ret = adb_read(fd[0], temp, 3);
        int saved_errno = errno;
        adb_close(fd[0]);
        if (ret < 0) {
            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
            return -1;
        }
        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }

        setsid();
    }
#else
#error "cannot implement background server start on this platform"
#endif
    return 0;
}
Пример #4
0
Файл: nmakehlp.c Проект: das/tcl
int
CheckForLinkerFeature(
    const char *option)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    char cmdline[100];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
     */

    CreatePipe(&Err.pipe, &h, &sa, 0);
    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Base command line.
     */

    lstrcpy(cmdline, "link.exe -nologo ");

    /*
     * Append our option for testing.
     */

    lstrcat(cmdline, option);

    ok = CreateProcess(
	    NULL,	    /* Module name. */
	    cmdline,	    /* Command line. */
	    NULL,	    /* Process handle not inheritable. */
	    NULL,	    /* Thread handle not inheritable. */
	    TRUE,	    /* yes, inherit handles. */
	    DETACHED_PROCESS, /* No console for you. */
	    NULL,	    /* Use parent's environment block. */
	    NULL,	    /* Use parent's starting directory. */
	    &si,	    /* Pointer to STARTUPINFO structure. */
	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

    CloseHandle(si.hStdOutput);
    CloseHandle(si.hStdError);

    WaitForInputIdle(pi.hProcess, 5000);
    CloseHandle(pi.hThread);

    /*
     * Start the pipe reader threads.
     */

    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);

    /*
     * Block waiting for the process to end.
     */

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);

    /*
     * Wait for our pipe to get done reading, should it be a little slow.
     */

    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
    CloseHandle(pipeThreads[0]);
    CloseHandle(pipeThreads[1]);

    /*
     * Look for the commandline warning code in the stderr stream.
     */

    return !(strstr(Out.buffer, "LNK1117") != NULL ||
	    strstr(Err.buffer, "LNK1117") != NULL ||
	    strstr(Out.buffer, "LNK4044") != NULL ||
	    strstr(Err.buffer, "LNK4044") != NULL);
}
Пример #5
0
int ProcessUtil::ForkCmd( const string &path, const string &cmd, const vector<string> &opts )
{

#ifdef WIN32


    SECURITY_ATTRIBUTES saAttr;

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

    if ( !CreatePipe( &m_StdoutPipe[PIPE_READ], &m_StdoutPipe[PIPE_WRITE], &saAttr, 0 ) )
    {
        printf( "Error StdoutRd CreatePipe\n" );
        exit( 0 );
    }

    if ( !SetHandleInformation( m_StdoutPipe[PIPE_READ], HANDLE_FLAG_INHERIT, 0 ) )
    {
        printf( "Stdout SetHandleInformation\n" );
        exit( 0 );
    }

    string command = QuoteString( path + string("\\") + cmd );
    for( int i = 0; i < opts.size(); i++ )
    {
        command += string(" ") + QuoteString( opts[i] );
    }

    char *cmdstr = (char*) malloc( (command.size()+1) * sizeof(char) );
    strcpy( cmdstr, command.c_str() );

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    si.hStdError = m_StdoutPipe[PIPE_WRITE];
    si.hStdOutput = m_StdoutPipe[PIPE_WRITE];
    si.dwFlags |= STARTF_USESTDHANDLES;

    ZeroMemory( &pi, sizeof(pi) );

    if( !CreateProcess( NULL,    // No module name (use command line).
                        TEXT( cmdstr ),          // Command line.
                        NULL,                    // Process handle not inheritable.
                        NULL,                    // Thread handle not inheritable.
                        TRUE,                    // Set handle inheritance to FALSE.
                        0,                       // No creation flags.
                        NULL,                    // Use parent's environment block.
                        NULL,                    // Use parent's starting directory.
                        &si,                     // Pointer to STARTUPINFO structure.
                        &pi )                    // Pointer to PROCESS_INFORMATION structure.
      )
    {
        printf( "CreateProcess failed (%d).\n", GetLastError() );
        return 0;
    }

    CloseHandle( m_StdoutPipe[PIPE_WRITE] );
    m_StdoutPipe[PIPE_WRITE] = NULL;

    free( cmdstr );

#else

    if( pipe( m_StdoutPipe ) < 0 )
    {
        printf( "Error allocating pipe for child output redirect");
        return -1;
    }

    fcntl( m_StdoutPipe[PIPE_WRITE] , F_SETFL, O_NONBLOCK );
    fcntl( m_StdoutPipe[PIPE_READ] , F_SETFL, O_NONBLOCK );

    if ( ( childPid = fork() ) == 0 )
    {

        if( dup2( m_StdoutPipe[PIPE_WRITE], STDOUT_FILENO ) == -1 ||
                dup2( m_StdoutPipe[PIPE_WRITE], STDERR_FILENO ) == -1 )
        {
            printf( "Error redirecting child stdout" );
            exit( 0 );
        }

        close( m_StdoutPipe[PIPE_READ] );
        close( m_StdoutPipe[PIPE_WRITE] );

        string command = path + string("/") + cmd;
        if( cppexecv( command, opts ) < 0 ) {
            printf( "execv error\n" );
        }
    }
    else if (childPid < 0)
    {
        close( m_StdoutPipe[PIPE_READ] );
        close( m_StdoutPipe[PIPE_WRITE] );

        printf( "Fork failed (%d).\n", childPid );
        return 0;
    }

    close( m_StdoutPipe[PIPE_WRITE] );

#endif

    return 0;
}
Пример #6
0
int launch_server(int server_port)
{
#if defined(_WIN32)
    /* we need to start the server in the background                    */
    /* we create a PIPE that will be used to wait for the server's "OK" */
    /* message since the pipe handles must be inheritable, we use a     */
    /* security attribute                                               */
    HANDLE                nul_read, nul_write;
    HANDLE                pipe_read, pipe_write;
    HANDLE                stdout_handle, stderr_handle;
    SECURITY_ATTRIBUTES   sa;
    STARTUPINFOW          startup;
    PROCESS_INFORMATION   pinfo;
    WCHAR                 program_path[ MAX_PATH ];
    int                   ret;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /* Redirect stdin and stderr to Windows /dev/null. If we instead pass our
     * stdin/stderr handles and they are console handles, when the adb server
     * starts up, the C Runtime will see console handles for a process that
     * isn't connected to a console and it will configure stderr to be closed.
     * At that point, freopen() could be used to reopen stderr, but it would
     * take more massaging to fixup the file descriptor number that freopen()
     * uses. It's simplest to avoid all of this complexity by just redirecting
     * stdin/stderr to `nul' and then the C Runtime acts as expected.
     */
    nul_read = CreateFileW(L"nul", GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (nul_read == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "CreateFileW(nul, GENERIC_READ) failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }

    nul_write = CreateFileW(L"nul", GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (nul_write == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "CreateFileW(nul, GENERIC_WRITE) failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        CloseHandle(nul_read);
        return -1;
    }

    /* create pipe, and ensure its read handle isn't inheritable */
    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
    if (!ret) {
        fprintf(stderr, "CreatePipe() failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        CloseHandle(nul_read);
        CloseHandle(nul_write);
        return -1;
    }

    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );

    /* Some programs want to launch an adb command and collect its output by
     * calling CreateProcess with inheritable stdout/stderr handles, then
     * using read() to get its output. When this happens, the stdout/stderr
     * handles passed to the adb client process will also be inheritable.
     * When starting the adb server here, care must be taken to reset them
     * to non-inheritable.
     * Otherwise, something bad happens: even if the adb command completes,
     * the calling process is stuck while read()-ing from the stdout/stderr
     * descriptors, because they're connected to corresponding handles in the
     * adb server process (even if the latter never uses/writes to them).
     */
    stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
    stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
    if (stdout_handle != INVALID_HANDLE_VALUE) {
        SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
    }
    if (stderr_handle != INVALID_HANDLE_VALUE) {
        SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
    }

    ZeroMemory( &startup, sizeof(startup) );
    startup.cb = sizeof(startup);
    startup.hStdInput  = nul_read;
    startup.hStdOutput = nul_write;
    startup.hStdError  = nul_write;
    startup.dwFlags    = STARTF_USESTDHANDLES;

    ZeroMemory( &pinfo, sizeof(pinfo) );

    /* get path of current program */
    DWORD module_result = GetModuleFileNameW(NULL, program_path,
                                             arraysize(program_path));
    if ((module_result == arraysize(program_path)) || (module_result == 0)) {
        // String truncation or some other error.
        fprintf(stderr, "GetModuleFileNameW() failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }

    // Verify that the pipe_write handle value can be passed on the command line
    // as %d and that the rest of adb code can pass it around in an int.
    const int pipe_write_as_int = cast_handle_to_int(pipe_write);
    if (cast_int_to_handle(pipe_write_as_int) != pipe_write) {
        // If this fires, either handle values are larger than 32-bits or else
        // there is a bug in our casting.
        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
        fprintf(stderr, "CreatePipe handle value too large: 0x%p\n",
                pipe_write);
        return -1;
    }

    WCHAR args[64];
    snwprintf(args, arraysize(args),
              L"adb -P %d fork-server server --reply-fd %d", server_port,
              pipe_write_as_int);
    ret = CreateProcessW(
            program_path,                              /* program path  */
            args,
                                    /* the fork-server argument will set the
                                       debug = 2 in the child           */
            NULL,                   /* process handle is not inheritable */
            NULL,                    /* thread handle is not inheritable */
            TRUE,                          /* yes, inherit some handles */
            DETACHED_PROCESS, /* the new process doesn't have a console */
            NULL,                     /* use parent's environment block */
            NULL,                    /* use parent's starting directory */
            &startup,                 /* startup info, i.e. std handles */
            &pinfo );

    CloseHandle( nul_read );
    CloseHandle( nul_write );
    CloseHandle( pipe_write );

    if (!ret) {
        fprintf(stderr, "CreateProcess failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        CloseHandle( pipe_read );
        return -1;
    }

    CloseHandle( pinfo.hProcess );
    CloseHandle( pinfo.hThread );

    /* wait for the "OK\n" message */
    {
        char  temp[3];
        DWORD  count;

        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
        CloseHandle( pipe_read );
        if ( !ret ) {
            fprintf(stderr, "could not read ok from ADB Server, error: %s\n",
                    SystemErrorCodeToString(GetLastError()).c_str());
            return -1;
        }
        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }
    }
#else /* !defined(_WIN32) */
    char    path[PATH_MAX];
    int     fd[2];

    // set up a pipe so the child can tell us when it is ready.
    // fd[0] will be parent's end, and the child will write on fd[1]
    if (pipe(fd)) {
        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
        return -1;
    }
    get_my_path(path, PATH_MAX);
    pid_t pid = fork();
    if(pid < 0) return -1;

    if (pid == 0) {
        // child side of the fork

        adb_close(fd[0]);

        char str_port[30];
        snprintf(str_port, sizeof(str_port), "%d", server_port);
        char reply_fd[30];
        snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
        // child process
        int result = execl(path, "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL);
        // this should not return
        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
    } else  {
        // parent side of the fork

        char  temp[3];

        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
        // wait for the "OK\n" message
        adb_close(fd[1]);
        int ret = adb_read(fd[0], temp, 3);
        int saved_errno = errno;
        adb_close(fd[0]);
        if (ret < 0) {
            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
            return -1;
        }
        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }

        setsid();
    }
#endif /* !defined(_WIN32) */
    return 0;
}
Пример #7
0
static PSESSION_DATA
CreateSession(
    VOID
    )
{
    PSESSION_DATA Session = NULL;
    BOOL Result;
    SECURITY_ATTRIBUTES SecurityAttributes;
    HANDLE ShellStdinPipe = NULL;
    HANDLE ShellStdoutPipe = NULL;

    //
    // Allocate space for the session data
    //
    Session = (PSESSION_DATA) malloc(sizeof(SESSION_DATA));
    if (Session == NULL) {
        return(NULL);
    }

    //
    // Reset fields in preparation for failure
    //
    Session->ReadPipeHandle  = NULL;
    Session->WritePipeHandle = NULL;


    //
    // Create the I/O pipes for the shell
    //
    SecurityAttributes.nLength = sizeof(SecurityAttributes);
    SecurityAttributes.lpSecurityDescriptor = NULL; // Use default ACL
    SecurityAttributes.bInheritHandle = TRUE; // Shell will inherit handles

    Result = CreatePipe(&Session->ReadPipeHandle, &ShellStdoutPipe,
                          &SecurityAttributes, 0);
    if (!Result) {
        holler("Failed to create shell stdout pipe, error = %s",
			itoa(GetLastError(), smbuff, 10), NULL, NULL, NULL, NULL, NULL);
        goto Failure;
    }
    Result = CreatePipe(&ShellStdinPipe, &Session->WritePipeHandle,
                        &SecurityAttributes, 0);

    if (!Result) {
        holler("Failed to create shell stdin pipe, error = %s",  
			itoa(GetLastError(), smbuff, 10), NULL, NULL, NULL, NULL, NULL);
        goto Failure;
    }
    //
    // Start the shell
    //
    Session->ProcessHandle = StartShell(ShellStdinPipe, ShellStdoutPipe);

    //
    // We're finished with our copy of the shell pipe handles
    // Closing the runtime handles will close the pipe handles for us.
    //
    CloseHandle(ShellStdinPipe);
    CloseHandle(ShellStdoutPipe);

    //
    // Check result of shell start
    //
    if (Session->ProcessHandle == NULL) {
        holler("Failed to execute shell", NULL,
			 NULL, NULL, NULL, NULL, NULL);
			
        goto Failure;
    }

    //
    // The session is not connected, initialize variables to indicate that
    //
    Session->ClientSocket = INVALID_SOCKET;

    //
    // Success, return the session pointer as a handle
    //
    return(Session);

Failure:

    //
    // We get here for any failure case.
    // Free up any resources and exit
    //

    if (ShellStdinPipe != NULL) 
        CloseHandle(ShellStdinPipe);
    if (ShellStdoutPipe != NULL) 
        CloseHandle(ShellStdoutPipe);
    if (Session->ReadPipeHandle != NULL) 
        CloseHandle(Session->ReadPipeHandle);
    if (Session->WritePipeHandle != NULL) 
        CloseHandle(Session->WritePipeHandle);

    free(Session);

    return(NULL);
}
Пример #8
0
//Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx.
Process::id_type Process::open(const string_type &command, const string_type &path) {
  if(open_stdin)
    stdin_fd=std::unique_ptr<fd_type>(new fd_type(NULL));
  if(read_stdout)
    stdout_fd=std::unique_ptr<fd_type>(new fd_type(NULL));
  if(read_stderr)
    stderr_fd=std::unique_ptr<fd_type>(new fd_type(NULL));

  Handle stdin_rd_p;
  Handle stdin_wr_p;
  Handle stdout_rd_p;
  Handle stdout_wr_p;
  Handle stderr_rd_p;
  Handle stderr_wr_p;

  SECURITY_ATTRIBUTES security_attributes;

  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  security_attributes.bInheritHandle = TRUE;
  security_attributes.lpSecurityDescriptor = nullptr;

  std::lock_guard<std::mutex> lock(create_process_mutex);
  if(stdin_fd) {
    if (!CreatePipe(&stdin_rd_p, &stdin_wr_p, &security_attributes, 0) ||
        !SetHandleInformation(stdin_wr_p, HANDLE_FLAG_INHERIT, 0))
      return 0;
  }
  if(stdout_fd) {
    if (!CreatePipe(&stdout_rd_p, &stdout_wr_p, &security_attributes, 0) ||
        !SetHandleInformation(stdout_rd_p, HANDLE_FLAG_INHERIT, 0)) {
      return 0;
    }
  }
  if(stderr_fd) {
    if (!CreatePipe(&stderr_rd_p, &stderr_wr_p, &security_attributes, 0) ||
        !SetHandleInformation(stderr_rd_p, HANDLE_FLAG_INHERIT, 0)) {
      return 0;
    }
  }

  PROCESS_INFORMATION process_info;
  STARTUPINFO startup_info;

  ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION));

  ZeroMemory(&startup_info, sizeof(STARTUPINFO));
  startup_info.cb = sizeof(STARTUPINFO);
  startup_info.hStdInput = stdin_rd_p;
  startup_info.hStdOutput = stdout_wr_p;
  startup_info.hStdError = stderr_wr_p;
  if(stdin_fd || stdout_fd || stderr_fd)
    startup_info.dwFlags |= STARTF_USESTDHANDLES;

  string_type process_command=command;
#ifdef MSYS_PROCESS_USE_SH
  size_t pos=0;
  while((pos=process_command.find('\\', pos))!=string_type::npos) {
    process_command.replace(pos, 1, "\\\\\\\\");
    pos+=4;
  }
  pos=0;
  while((pos=process_command.find('\"', pos))!=string_type::npos) {
    process_command.replace(pos, 1, "\\\"");
    pos+=2;
  }
  process_command.insert(0, "sh -c \"");
  process_command+="\"";
#endif

  BOOL bSuccess = CreateProcess(nullptr, process_command.empty()?nullptr:&process_command[0], nullptr, nullptr, TRUE, 0,
                                nullptr, path.empty()?nullptr:path.c_str(), &startup_info, &process_info);

  if(!bSuccess) {
    CloseHandle(process_info.hProcess);
    CloseHandle(process_info.hThread);
    return 0;
  }
  else {
    CloseHandle(process_info.hThread);
  }

  if(stdin_fd) *stdin_fd=stdin_wr_p.detach();
  if(stdout_fd) *stdout_fd=stdout_rd_p.detach();
  if(stderr_fd) *stderr_fd=stderr_rd_p.detach();

  closed=false;
  data.id=process_info.dwProcessId;
  data.handle=process_info.hProcess;
  return process_info.dwProcessId;
}
deBool deProcess_start (deProcess* process, const char* commandLine, const char* workingDirectory)
{
	SECURITY_ATTRIBUTES	securityAttr;
	STARTUPINFO			startInfo;

	/* Pipes. */
	HANDLE		stdInRead	= DE_NULL;
	HANDLE		stdInWrite	= DE_NULL;
	HANDLE		stdOutRead	= DE_NULL;
	HANDLE		stdOutWrite	= DE_NULL;
	HANDLE		stdErrRead	= DE_NULL;
	HANDLE		stdErrWrite	= DE_NULL;

	if (process->state == PROCESSSTATE_RUNNING)
	{
		deProcess_setError(process, "Process already running");
		return DE_FALSE;
	}
	else if (process->state == PROCESSSTATE_FINISHED)
	{
		/* Process finished, clean up old cruft. */
		deProcess_cleanupHandles(process);
		process->state = PROCESSSTATE_NOT_STARTED;
	}

	deMemset(&startInfo, 0, sizeof(startInfo));
	deMemset(&securityAttr, 0, sizeof(securityAttr));

	/* Security attributes for inheriting handle. */
	securityAttr.nLength				= sizeof(SECURITY_ATTRIBUTES);
	securityAttr.bInheritHandle			= TRUE;
	securityAttr.lpSecurityDescriptor	= DE_NULL;

	/* Create pipes. \todo [2011-10-03 pyry] Clean up handles on error! */
	if (!CreatePipe(&stdInRead, &stdInWrite, &securityAttr, 0) ||
		!SetHandleInformation(stdInWrite, HANDLE_FLAG_INHERIT, 0))
	{
		deProcess_setErrorFromWin32(process, "CreatePipe() failed");
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		return DE_FALSE;
	}

	if (!CreatePipe(&stdOutRead, &stdOutWrite, &securityAttr, 0) ||
		!SetHandleInformation(stdOutRead, HANDLE_FLAG_INHERIT, 0))
	{
		deProcess_setErrorFromWin32(process, "CreatePipe() failed");
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		CloseHandle(stdOutRead);
		CloseHandle(stdOutWrite);
		return DE_FALSE;
	}

	if (!CreatePipe(&stdErrRead, &stdErrWrite, &securityAttr, 0) ||
		!SetHandleInformation(stdErrRead, HANDLE_FLAG_INHERIT, 0))
	{
		deProcess_setErrorFromWin32(process, "CreatePipe() failed");
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		CloseHandle(stdOutRead);
		CloseHandle(stdOutWrite);
		CloseHandle(stdErrRead);
		CloseHandle(stdErrWrite);
		return DE_FALSE;
	}

	/* Setup startup info. */
	startInfo.cb = sizeof(startInfo);
	startInfo.hStdError		 = stdErrWrite;
	startInfo.hStdOutput	 = stdOutWrite;
	startInfo.hStdInput		 = stdInRead;
	startInfo.dwFlags		|= STARTF_USESTDHANDLES;

	if (!CreateProcess(DE_NULL, (LPTSTR)commandLine, DE_NULL, DE_NULL, TRUE /* inherit handles */, 0, DE_NULL, workingDirectory, &startInfo, &process->procInfo))
	{
		/* Store error info. */
		deProcess_setErrorFromWin32(process, "CreateProcess() failed");

		/* Close all handles. */
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		CloseHandle(stdOutRead);
		CloseHandle(stdOutWrite);
		CloseHandle(stdErrRead);
		CloseHandle(stdErrWrite);

		return DE_FALSE;
	}

	process->state = PROCESSSTATE_RUNNING;

	/* Close our ends of handles.*/
	CloseHandle(stdErrWrite);
	CloseHandle(stdOutWrite);
	CloseHandle(stdInRead);

	/* Construct stdio file objects \note May fail, not detected. */
	process->standardIn		= deFile_createFromHandle((deUintptr)stdInWrite);
	process->standardOut	= deFile_createFromHandle((deUintptr)stdOutRead);
	process->standardErr	= deFile_createFromHandle((deUintptr)stdErrRead);

	return DE_TRUE;
}
Пример #10
0
/*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->LinkCallback( 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;
}
Пример #11
0
Файл: win.c Проект: 0xe/win-sshd
/*
  Execute a command as a "user". The command is run as cmd.exe /c <command>
  The command is executed from the user's HOME (as determined by the user profile)
  Input, Output & Err streams are redirected. 
*/
void *win_execute_command(wchar_t *shell, wchar_t *command, wchar_t *user, wchar_t *password, wchar_t *domain, wchar_t *root, int pty_mode) {
    SECURITY_ATTRIBUTES sa;
    STARTUPINFOW si;
    HANDLE out_rd_tmp, in_wr_tmp, out_wr, in_rd, in_wr, err_wr;
    exec_ctx *ctx;
    HANDLE ttok, ntok;
	int ret;

    ZeroMemory(&sa, sizeof(sa));
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;

    ctx = malloc(sizeof(*ctx));
    ZeroMemory(ctx, sizeof(*ctx));
    ctx->pty_mode = pty_mode;
 
    /* setup the parent child plumbing */
    if (!CreatePipe(&in_rd, &in_wr_tmp, &sa, 0)) {
        printf("Couldn't set up in pipe to child %s", get_error_msg(GetLastError()));
        free(ctx);
        return NULL;
    }

    if (!CreatePipe(&out_rd_tmp, &out_wr, &sa, 0)) {
        printf("Couldn't set up stdout pipe to child %s", get_error_msg(GetLastError()));
		free(ctx);
        return NULL;
    }

    if (!DuplicateHandle(GetCurrentProcess(), out_wr, GetCurrentProcess(), &err_wr, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
		printf("Couldn't set up stderr pipe to child %s", get_error_msg(GetLastError()));
		free(ctx);
		return NULL;
    }

    if (!DuplicateHandle(GetCurrentProcess(), out_rd_tmp, GetCurrentProcess(), &ctx->out_rd, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
		return NULL;
    }
    if (!DuplicateHandle(GetCurrentProcess(), in_wr_tmp, GetCurrentProcess(), &in_wr, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
		return NULL;
    }
    CloseHandle(out_rd_tmp);
    CloseHandle(in_wr_tmp);

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput = in_rd;
    si.hStdOutput = out_wr; 
    si.hStdError = err_wr;
/*
    if (!CreateProcessWithLogonW(user, domain, password, LOGON_WITH_PROFILE, shell, command, 0, NULL, root, &si, &ctx->pi)) {
	*/
	ret = LogonUserW(user, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &ttok);
	if (!ret) {
		CloseHandle(ttok);
		INFO(GetLastError(), "Login failed for user");
		return NULL;
	}
	ret = DuplicateTokenEx(ttok, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &ntok);
	if (!ret) {
		CloseHandle(ttok);
		INFO(GetLastError(), "Can't impersonate user");
		return NULL;
	}
	CloseHandle(ttok);
	if (!CreateProcessAsUserW(ntok, shell, command, NULL, NULL, TRUE, 0, NULL, root, &si, &ctx->pi)) {
		int ecode = GetLastError();
		INFO(GetLastError(), "CreateProcess failed");
        free(ctx);
		CloseHandle(ntok);
        return NULL;
    }
	CloseHandle(ntok);
    CloseHandle(out_wr);
    CloseHandle(err_wr);
    CloseHandle(in_rd);
    return ctx;
}
Пример #12
0
Файл: exec.c Проект: GisKook/Gis
/*
 * The runtime library's popen() on win32 does not work when being
 * called from a service when running on windows <= 2000, because
 * there is no stdin/stdout/stderr.
 *
 * Executing a command in a pipe and reading the first line from it
 * is all we need.
 */
static char *
pipe_read_line(char *cmd, char *line, int maxsize)
{
#ifndef WIN32
	FILE	   *pgver;

	/* flush output buffers in case popen does not... */
	fflush(stdout);
	fflush(stderr);

	if ((pgver = popen(cmd, "r")) == NULL)
		return NULL;

	if (fgets(line, maxsize, pgver) == NULL)
	{
		perror("fgets failure");
		pclose(pgver);			/* no error checking */
		return NULL;
	}

	if (pclose_check(pgver))
		return NULL;

	return line;
#else							/* WIN32 */

	SECURITY_ATTRIBUTES sattr;
	HANDLE		childstdoutrd,
				childstdoutwr,
				childstdoutrddup;
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	char	   *retval = NULL;

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

	if (!CreatePipe(&childstdoutrd, &childstdoutwr, &sattr, 0))
		return NULL;

	if (!DuplicateHandle(GetCurrentProcess(),
						 childstdoutrd,
						 GetCurrentProcess(),
						 &childstdoutrddup,
						 0,
						 FALSE,
						 DUPLICATE_SAME_ACCESS))
	{
		CloseHandle(childstdoutrd);
		CloseHandle(childstdoutwr);
		return NULL;
	}

	CloseHandle(childstdoutrd);

	ZeroMemory(&pi, sizeof(pi));
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdError = childstdoutwr;
	si.hStdOutput = childstdoutwr;
	si.hStdInput = INVALID_HANDLE_VALUE;

	if (CreateProcess(NULL,
					  cmd,
					  NULL,
					  NULL,
					  TRUE,
					  0,
					  NULL,
					  NULL,
					  &si,
					  &pi))
	{
		/* Successfully started the process */
		char	   *lineptr;

		ZeroMemory(line, maxsize);

		/* Try to read at least one line from the pipe */
		/* This may require more than one wait/read attempt */
		for (lineptr = line; lineptr < line + maxsize - 1;)
		{
			DWORD		bytesread = 0;

			/* Let's see if we can read */
			if (WaitForSingleObject(childstdoutrddup, 10000) != WAIT_OBJECT_0)
				break;			/* Timeout, but perhaps we got a line already */

			if (!ReadFile(childstdoutrddup, lineptr, maxsize - (lineptr - line),
						  &bytesread, NULL))
				break;			/* Error, but perhaps we got a line already */

			lineptr += strlen(lineptr);

			if (!bytesread)
				break;			/* EOF */

			if (strchr(line, '\n'))
				break;			/* One or more lines read */
		}

		if (lineptr != line)
		{
			/* OK, we read some data */
			int			len;

			/* If we got more than one line, cut off after the first \n */
			lineptr = strchr(line, '\n');
			if (lineptr)
				*(lineptr + 1) = '\0';

			len = strlen(line);

			/*
			 * If EOL is \r\n, convert to just \n. Because stdout is a
			 * text-mode stream, the \n output by the child process is
			 * received as \r\n, so we convert it to \n.  The server main.c
			 * sets setvbuf(stdout, NULL, _IONBF, 0) which has the effect of
			 * disabling \n to \r\n expansion for stdout.
			 */
			if (len >= 2 && line[len - 2] == '\r' && line[len - 1] == '\n')
			{
				line[len - 2] = '\n';
				line[len - 1] = '\0';
				len--;
			}

			/*
			 * We emulate fgets() behaviour. So if there is no newline at the
			 * end, we add one...
			 */
			if (len == 0 || line[len - 1] != '\n')
				strcat(line, "\n");

			retval = line;
		}

		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	}

	CloseHandle(childstdoutwr);
	CloseHandle(childstdoutrddup);

	return retval;
#endif   /* WIN32 */
}
Пример #13
0
int startCcd(const char* titleId)
{
    STARTUPINFO si;
    wchar_t *ccd_dir = NULL;
    std::wstring progPathStr, appDataPathStr, commandLineStr;
    SECURITY_ATTRIBUTES saAttr; 
    int rv = 0;

    rv = checkRunningCcd();
    if (rv != 0) {
        LOG_ERROR("An active CCD detected. Please kill the CCD first"); 
        return -1;
    }

    ccd_dir = _wgetenv(L"DX_CCD_EXE_PATH");
    if (ccd_dir != NULL) {
        progPathStr.assign(ccd_dir);
    } else {
        progPathStr.assign(L".");
    }
    progPathStr.append(L"\\ccd.exe");

    // DEFAULT_CCD_APP_DATA_PATH
    rv = _getCcdAppDataWPath(appDataPathStr);
    if (rv != 0) {
        LOG_ERROR("Fail to get ccd app data path: rv %d", rv);
        return rv;
    }

    if (testInstanceNum) {
        std::wostringstream instanceSuffix;
        instanceSuffix << L"_" << testInstanceNum;
        appDataPathStr += instanceSuffix.str();
    }

    std::wstring w_titleId;
    if (titleId) {
        std::string titleIdIdString(titleId);
        w_titleId.assign(titleIdIdString.begin(), titleIdIdString.end());
    }

    wprintf(L"CCD Executable Path: %s\n", progPathStr.c_str());
    wprintf(L"AppData Path: %s\n", appDataPathStr.c_str());

    commandLineStr = progPathStr + L" \"" + appDataPathStr + L"\"" + L" \"\"" + L" \"\"" + L" \"\"" + L" \"\"" + L" \"" + w_titleId + L"\"";

    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)) {
        LOG_ERROR("Fail StdoutRd CreatePipe"); 
    }
    if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
        LOG_ERROR("Fail Stdout SetHandleInformation");
    }
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.hStdOutput = g_hChildStd_OUT_Wr;
    si.hStdError = g_hChildStd_OUT_Wr;
    si.dwFlags |= STARTF_USESTDHANDLES;
    ZeroMemory(&pi, sizeof(pi));

    // Issue 1: It is important to detach CCD from the current console window, otherwise it will be
    // terminated when the console window is closed.
    // Issue 2: An unfortunate consequence of DETACHED_PROCESS is that certain types of crashes cause
    // the process to immediately close instead of popping up the "just-in-time debugger" dialog.
    // Using CREATE_NEW_PROCESS_GROUP doesn't help with issue 1.
    // Using CREATE_NO_WINDOW doesn't help with issue 2.
    // Using CREATE_NEW_CONSOLE might be good enough for developers, so allow setting it via the
    // environment variable, DX_CREATE_NEW_CONSOLE.
    DWORD processCreationFlags;
    if (_wgetenv(L"DX_CREATE_NEW_CONSOLE") != NULL) {
        processCreationFlags = CREATE_NEW_CONSOLE;
    } else {
        processCreationFlags = DETACHED_PROCESS;
    }

    wprintf(L"CreateProcess(%s)\n", commandLineStr.c_str());
    if (!CreateProcess(NULL,
                       (LPTSTR) commandLineStr.c_str(),
                       NULL,
                       NULL,
                       FALSE,
                       processCreationFlags,
                       NULL,
                       NULL,
                       &si,
                       &pi))
    {
        LOG_ERROR("CreateProcess for CCD failed (%d).", GetLastError());
        LOG_ERROR("Please make sure CCD.exe is in current folder or set");
        LOG_ERROR("DX_CCD_EXE_PATH to the directory that contains CCD.exe");
        return -1;
    }

    return 0;
}
Пример #14
0
Socket platform_new_connection(SockAddr addr, char *hostname,
			       int port, int privport,
			       int oobinline, int nodelay, int keepalive,
			       Plug plug, Conf *conf)
{
    char *cmd;
    HANDLE us_to_cmd, us_from_cmd, cmd_to_us, cmd_from_us;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
	return NULL;

    cmd = format_telnet_command(addr, port, conf);

    /* We are responsible for this and don't need it any more */
    sk_addr_free(addr);

    {
	char *msg = dupprintf("Starting local proxy command: %s", cmd);
	/* We're allowed to pass NULL here, because we're part of the Windows
	 * front end so we know logevent doesn't expect any data. */
	logevent(NULL, msg);
	sfree(msg);
    }

    /*
     * Create the pipes to the proxy command, and spawn the proxy
     * command process.
     */
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;    /* default */
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
	Socket ret =
            new_error_socket("Unable to create pipes for proxy command", plug);
        sfree(cmd);
	return ret;
    }

    if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
	Socket ret =
            new_error_socket("Unable to create pipes for proxy command", plug);
        sfree(cmd);
	CloseHandle(us_from_cmd);
	CloseHandle(cmd_to_us);
	return ret;
    }

    SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);

    si.cb = sizeof(si);
    si.lpReserved = NULL;
    si.lpDesktop = NULL;
    si.lpTitle = NULL;
    si.dwFlags = STARTF_USESTDHANDLES;
    si.cbReserved2 = 0;
    si.lpReserved2 = NULL;
    si.hStdInput = cmd_from_us;
    si.hStdOutput = cmd_to_us;
    si.hStdError = NULL;
    CreateProcess(NULL, cmd, NULL, NULL, TRUE,
		  CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
		  NULL, NULL, &si, &pi);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    sfree(cmd);

    CloseHandle(cmd_from_us);
    CloseHandle(cmd_to_us);

    return make_handle_socket(us_to_cmd, us_from_cmd, plug, FALSE);
}
Пример #15
0
/*--------------------------------------------------------------------------
 Launches NetShell, waits for Netshell and all of NetShell's launched
   processes to die and then relaunches NetShell if nothing exited with
   non-zero exit status.
--------------------------------------------------------------------------*/
int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE hinstExePrev, LPSTR lpszCmdLine, int nCmdShow)
{
	int firsttime = 1;
	char cmd[2*MAX_PATH];
	char args[MAX_PATH];
	char cwd[MAX_PATH];
	char strhandle[MAX_HSTR];
	DWORD nhandles = 0;
	DWORD exitCode = 0;
	DWORD dwThreadId, iSignal;
	HANDLE hpipeRead, hpipeWrite, hSelf;
	HANDLE *hArray, *hStartArr;
	SECURITY_ATTRIBUTES saAttr;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

#ifdef DEBUG
#ifndef PRINT_STDOUT
	{	char logfile[MAX_PATH];
		sprintf(logfile, "%x", time(NULL));
		strcat(logfile, ".log");
		flog = fopen(logfile, "w");
	}
#endif
#endif
	/* Pick random session id for benefit of serial and modem drivers */
	sprintf(strhandle, "%x", GetTickCount());
	if (!SetEnvironmentVariable(DPSTUBID, strhandle)) {
		DPRINT(("stub: set environment variable error %x.\n", GetLastError()));
		exit(1);
	}
	hArray = (HANDLE *)malloc(MAXIMUM_WAIT_OBJECTS * sizeof(HANDLE));
	hStartArr = hArray;
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.bInheritHandle = TRUE;
	saAttr.lpSecurityDescriptor = NULL;
	if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &hSelf,  0, TRUE, DUPLICATE_SAME_ACCESS)) {
		DPRINT(("stub: error duplicating own handle\n"));
		exit(1);
	}
	sprintf(strhandle, "%x", hSelf);
	if (!SetEnvironmentVariable(DPSTUB, strhandle)) {
		DPRINT(("stub: set environment variable error %x.\n", GetLastError()));
		exit(1);
	}
//	DPRINT(("stub: current process handle is %s\n", strhandle));

	/* create event so read thread can signal when it's read a new process */
	if (!(hreadEvent = CreateEvent(NULL, FALSE, FALSE, "ReadEvent"))) {
		DPRINT(("stub: create read event error %x.\n", GetLastError()));
		exit(1);
	}
	*hArray++ = hreadEvent;
	nhandles++;
//	DPRINT(("stub: read event handle is %x\n", *(hArray - 1)));

	/* create event so read thread knows main thread has finished processing
	   hSpawn and can continue to get new processes */
	if (!(hcontEvent = CreateEvent(NULL, FALSE, FALSE, "ContinueReadEvent"))) {
		DPRINT(("stub: create continue read event error %x.\n", GetLastError()));
		exit(1);
	}
//	DPRINT(("stub: continue read event handle is %x\n", hcontEvent));

	/* create a pipe with read end uninheritable and write end inheritable*/
	if(!CreatePipe(&hpipeRead, &hpipeWrite, &saAttr, sizeof(HANDLE))) {
		DPRINT(("stub: create pipe error %x.\n", GetLastError()));
		exit(1);
	}
	sprintf(strhandle, "%x", hpipeWrite);
	if (!SetEnvironmentVariable(DPSTUBWPIPE, strhandle)) {
		DPRINT(("stub: set environment variable error %x.\n", GetLastError()));
		exit(1);
	}
	if (!DuplicateHandle(GetCurrentProcess(), hpipeRead, GetCurrentProcess(), &hpipeReadDup,  0, FALSE, DUPLICATE_SAME_ACCESS)) {
		DPRINT(("stub: error duplicating uninheritable handle\n"));
		exit(1);
	}
	CloseHandle(hpipeRead);
//	DPRINT(("stub: uninheritable pipe handle is %x.\n", hpipeReadDup));

	/* create a thread to read from pipe about new processes*/
	if (CreateThread(NULL, 0, readThread, 0, 0, &dwThreadId) < 0) {
		DPRINT(("stub: create thread error %x.\n", GetLastError()));
		exit(1);
	}

	/* set command and current working directory for CreateProcess() */
	{	char *buf;
		char path[2*MAX_PATH];
		char cmdline[1024];
		if (getinfo(path, args, cwd) != 0) {
			CHAR title[TITLELEN];
			CHAR msg[MSGLEN];
			LoadString(NULL, IDS_NO_JRE_TITLE, title, TITLELEN);
			LoadString(NULL, IDS_NO_JRE_MSG, msg, MSGLEN);
			MessageBox(NULL, msg, title,
				MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
			exit(1);
		}
		strcat(cmd, "\"");
		strcat(cmd, path);
		strcat(cmd, "\" ");
		strcat(cmd, args);

		buf = GetCommandLine();
		if (!buf) {
			DPRINT(("stub: error getting commandline args; quitting\n"));
			exit(1);
		}
		strcpy(cmdline, buf);
#ifdef DEFAULTARGS
		/* If no switches given, append default args */
		if (!strstr(cmdline, " -")) {
			strcat(cmdline, " ");
			strcat(cmdline, DEFAULTARGS);
		}
#endif
		buf = cmdline;
		DPRINT(("args: %s\n", buf));
		{
			OSVERSIONINFO VersionInfo;
			VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
			if (!GetVersionEx(&VersionInfo)) {
				DPRINT(("stub: cannot determine OS; quitting\n"));
				exit(1); 
			}
			if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT || VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
				while (' ' == *buf || '\t' == *buf) buf++;
				if (*buf == '\"') {
					buf++;
					if (!(buf = strchr(buf, '\"'))) {
						DPRINT(("stub: cannot get commandline args; quitting\n"));
						exit(1);
					}
					buf++;
				} else {
					if (buf = strchr(buf, ' ')) {
						buf++;
					} else {
						buf = "\0";
					}
				}
			} else {
				CHAR title[TITLELEN];
				CHAR msg[MSGLEN];
				LoadString(NULL, IDS_UNSP_OS_TITLE, title, TITLELEN);
				LoadString(NULL, IDS_UNSP_OS_MSG, msg, MSGLEN);
				MessageBox(NULL, msg, title,
					MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
				DPRINT(("OS not supported; quitting\n"));
				exit(1);
			}
			while (' ' == *buf || '\t' == *buf) buf++;
			if (2 * MAX_PATH < strlen(cmd) + strlen(buf) + 2) {
				DPRINT(("stub: cmd buffer not large enough to hold args; quitting\n"));
				exit(1);
			}
			strcat(cmd, " ");
			strcat(cmd, buf);
		}
	}
	DPRINT(("cmd: %s\n", cmd));

	/* launch NetShell then wait for NetShell and all its launched processes
	   to die, then if all exit status are zero, relaunch NetShell */
	do {
		memset(&pi, 0, sizeof(pi));
		memset(&si, 0, sizeof(si));
		si.cb = sizeof(si);
		/* launch NetShell */
    	DPRINT(("stub: Launching %s from %s.\n", cmd, cwd));
		if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, cwd, &si, &pi)) {
			DPRINT(("stub: Error launching %s from %s; quitting\n", cmd, cwd));
			DPRINT(("stub: GetLastError returns %x", GetLastError()));
			exit(1);
		}
		if (firsttime) {
			char *buf = " -r";
			if (2 * MAX_PATH < strlen(cmd) + strlen(buf) + 1) {
				DPRINT(("stub: cmd buffer not large enough to hold args\n"));
				exit(1);
			}
			strcat(cmd, buf);
			firsttime = 0;
		}
		CloseHandle(pi.hThread);
		*hArray++ = pi.hProcess;
		nhandles++;
		DPRINT(("stub: Launch complete; shell handle %x.\n", *(hArray-1)));

		/* Wait for NetShell and all its launched processes to exit */
		do {
			iSignal = WaitForMultipleObjects(nhandles, hStartArr, FALSE, INFINITE);
			if (WAIT_FAILED == iSignal) {
				DPRINT(("stub: wait error %x.\n", GetLastError()));
				exit(1);
			}
			iSignal -= WAIT_OBJECT_0;
			if (iSignal >= 0 && iSignal < nhandles) {
				if (*(hStartArr + iSignal) != hreadEvent) {
					if (!GetExitCodeProcess(*(hStartArr + iSignal), &exitCode)) {
						DPRINT(("stub: Error reading spawned process\n"));
						exit(1);
					}
					DPRINT(("stub: deleting handle %x, exit code %d.\n", *(hStartArr + iSignal), exitCode));
					if (exitCode) break;
					CloseHandle(*(hStartArr + iSignal));
					if (nhandles && iSignal < nhandles - 1) {
						*(hStartArr + iSignal) = *(hStartArr + nhandles - 1);
					}
					nhandles--;
					hArray = hStartArr + nhandles;
				} else {
					// DPRINT(("stub: got new handle %x\n", hSpawn));
					if (hSpawn != 0) {
						if (hSpawn < 0) {
							DPRINT(("stub: Error reading spawned process; hSpawn %x\n", hSpawn));
							exit(1);
						}
						DPRINT(("stub: adding handle %x.\n", hSpawn));
						*hArray++ = hSpawn;
						nhandles++;
						hSpawn = 0;
					} else if (hSerial != 0) {
						char *pstrhandle;
						if (hSerial < 0 && hSerial != INVALID_HANDLE_VALUE) {
							DPRINT(("stub: Error reading serial handle; hSerial %x\n", hSerial));
							exit(1);
						}
						if (hSerial == INVALID_HANDLE_VALUE) {
							if (GetEnvironmentVariable(DPSTUBMODEM, strhandle, 256)) {
								HANDLE baseadr;
								sscanf(strhandle, "%x", &baseadr);
								CloseHandle(baseadr);
								DPRINT(("stub: deleted serial h:%x\n",baseadr));
								pstrhandle = NULL;
							}
						} else {
							DPRINT(("stub: setting serial h:%x.\n", hSerial));
							sprintf(strhandle, "%x", hSerial);
							pstrhandle = strhandle;
						}
						if (!SetEnvironmentVariable(DPSTUBMODEM, pstrhandle)) {
							DPRINT(("stub: set environment variable error %x.\n", GetLastError()));
							exit(1);
						}
						hSerial = 0;
					} else {
						DPRINT(("stub: Error no handle set\n"));
						exit(1);
					}
					if (!SetEvent(hcontEvent)) {
						DPRINT(("stub: set continue read event error %x.\n", GetLastError()));
						exit(1);
					}
				}
			} else {
				DPRINT(("stub: error wait returned invalid handle %d\n", iSignal));
				exit(1);
			}
//			DPRINT(("stub: nhandles = %d\n", nhandles));
		} while (nhandles > 1);
//		DPRINT(("stub: exited inside loop\n"));
#ifdef NOLOOP		
		break;
#endif
	} while (!exitCode);
	return 0;
}
Пример #16
0
int __cdecl main(int argc, char *argv[])
{

    const   int MAPPINGSIZE = 2048;
    HANDLE  hFileMapping;
    LPVOID  lpMapViewAddress;
    HANDLE  hReadPipe   = NULL;
    HANDLE  hWritePipe  = NULL;
    BOOL    bRetVal;

    SECURITY_ATTRIBUTES lpPipeAttributes;

    /* Initialize the PAL environment.
     */
    if(0 != PAL_Initialize(argc, argv))
    {
        return FAIL;
    }


    /* Attempt to create a MapViewOfFile with a NULL handle.
     */
    hFileMapping = NULL;
    
    lpMapViewAddress = MapViewOfFile(
                            hFileMapping,
                            FILE_MAP_WRITE, /* access code */
                            0,              /* high order offset */
                            0,              /* low order offset */
                            MAPPINGSIZE);   /* number of bytes for map */

    if((NULL != lpMapViewAddress) && 
       (GetLastError() != ERROR_INVALID_HANDLE))
    {
        Trace("ERROR:%u: Able to create a MapViewOfFile with "
              "hFileMapping=0x%lx.\n",
              GetLastError());
        UnmapViewOfFile(lpMapViewAddress);
        Fail("");
    }

    /* Attempt to create a MapViewOfFile with an invalid handle.
     */
    hFileMapping = INVALID_HANDLE_VALUE;
    
    lpMapViewAddress = MapViewOfFile(
                            hFileMapping,
                            FILE_MAP_WRITE, /* access code */
                            0,              /* high order offset */
                            0,              /* low order offset */
                            MAPPINGSIZE);   /* number of bytes for map */

    if((NULL != lpMapViewAddress) && 
       (GetLastError() != ERROR_INVALID_HANDLE))
    {
        Trace("ERROR:%u: Able to create a MapViewOfFile with "
              "hFileMapping=0x%lx.\n",
              GetLastError());
        UnmapViewOfFile(lpMapViewAddress);
        Fail("");
    }

    /* Setup SECURITY_ATTRIBUTES structure for CreatePipe.
     */
    lpPipeAttributes.nLength              = sizeof(lpPipeAttributes); 
    lpPipeAttributes.lpSecurityDescriptor = NULL; 
    lpPipeAttributes.bInheritHandle       = TRUE; 

    /* Create a Pipe.
     */
    bRetVal = CreatePipe(&hReadPipe,       /* read handle*/
                         &hWritePipe,      /* write handle */
                         &lpPipeAttributes,/* security attributes*/
                         0);               /* pipe size*/
    if (bRetVal == FALSE)
    {
        Fail("ERROR: %ld :Unable to create pipe\n", 
             GetLastError());
    }

    /* Attempt creating a MapViewOfFile with a Pipe Handle.
     */
    lpMapViewAddress = MapViewOfFile(
                            hReadPipe,
                            FILE_MAP_WRITE, /* access code */
                            0,              /* high order offset */
                            0,              /* low order offset */
                            MAPPINGSIZE);   /* number of bytes for map */

    if((NULL != lpMapViewAddress) && 
       (GetLastError() != ERROR_INVALID_HANDLE))
    {
        Trace("ERROR:%u: Able to create a MapViewOfFile with "
              "hFileMapping=0x%lx.\n",
              GetLastError());
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        UnmapViewOfFile(lpMapViewAddress);
        Fail("");
    }

    /* Clean-up and Terminate the PAL.
    */
    CloseHandle(hReadPipe);
    CloseHandle(hWritePipe);
    PAL_Terminate();
    return PASS;
}
Пример #17
0
DWORD WINAPI ThreadProc(LPVOID p) // thread that will start & monitor makensis
{
  TCHAR buf[1024];
  char iobuf[1024];           //i/o buffer
  STARTUPINFO si={sizeof(si),};
  SECURITY_ATTRIBUTES sa={sizeof(sa),};
  SECURITY_DESCRIPTOR sd={0,};               //security information for pipes
  PROCESS_INFORMATION pi={0,};
  HANDLE newstdout=0,read_stdout=0;         //pipe handles

  OSVERSIONINFO osv={sizeof(osv)};
  GetVersionEx(&osv);
  if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)        //initialize security descriptor (Windows NT)
  {
    InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, true, NULL, false);
    sa.lpSecurityDescriptor = &sd;
  }
  else sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = true;         //allow inheritable handles

  if (!CreatePipe(&read_stdout,&newstdout,&sa,0))  //create stdout pipe
  {
    ErrorMessage(_T("CreatePipe"));
    PostMessage(g_hwnd,WM_USER+1203,0,1);
    return 1;
  }

  GetStartupInfo(&si);      //set startupinfo for the spawned process
  /*
    The dwFlags member tells CreateProcess how to make the process.
    STARTF_USESTDHANDLES validates the hStd* members. STARTF_USESHOWWINDOW
    validates the wShowWindow member.
  */
  si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.wShowWindow = SW_HIDE;
  si.hStdOutput = newstdout;
  si.hStdError = newstdout;     //set the new handles for the child process

  // *******************************************************************
  // If there is a command line in the config file, use it for create process

  //spawn the child process
  if (!CreateProcess(NULL,g_cmdline,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,
      NULL,tempzip_path,&si,&pi))
  {
    ErrorMessage(_T("CreateProcess"));
    wnd_printf(_T("\r\nPlease make sure the path to makensis.exe is correct."));
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    PostMessage(g_hwnd,WM_USER+1203,0,1);
    return 1;
  }
  CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE
  DWORD dwLeft = 0, dwRead = 0;
  while (ReadFile(read_stdout, iobuf+dwLeft, sizeof(iobuf)-dwLeft-1, &dwRead, NULL)) //wait for buffer, or fails with ERROR_BROKEN_PIPE when subprocess exits
  {
    dwRead += dwLeft;
    iobuf[dwRead] = '\0';
#ifdef _UNICODE
    // this tweak is to prevent LogMessage from cutting in the middle of an UTF-8 sequence
    // we print only up to the latest \n of the buffer, and keep the remaining for the next loop
    char* lastLF = strrchr(iobuf,'\n');
    if (lastLF == NULL) lastLF = iobuf+dwRead-1;
    char ch = *++lastLF;
    *lastLF = '\0';
    MultiByteToWideChar(CP_UTF8,0,iobuf,lastLF+1-iobuf,buf,COUNTOF(buf));
    wnd_printf(buf);
    *lastLF = ch;
    dwLeft = iobuf+dwRead-lastLF;
    memmove(iobuf, lastLF, dwLeft);
#else
    wnd_printf(iobuf);
#endif
  }
#ifdef _UNICODE
  // because of UTF-8 tweak, in rare case there can be some data remaining
  dwRead += dwLeft;
  iobuf[dwRead] = 0;
  MultiByteToWideChar(CP_UTF8,0,iobuf,dwRead+1,buf,COUNTOF(buf));
  wnd_printf(buf);
#endif
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(read_stdout);


  wsprintf(buf,_T("(source ZIP size was %d bytes)\r\n"),g_zipfile_size);
  wnd_printf(buf);

  PostMessage(g_hwnd,WM_USER+1203,0,0);
  return 0;
}
Пример #18
0
Socket platform_new_connection(SockAddr addr, char *hostname,
			       int port, int privport,
			       int oobinline, int nodelay, int keepalive,
			       Plug plug, const Config *cfg)
{
    char *cmd;

    static const struct socket_function_table socket_fn_table = {
	sk_localproxy_plug,
	sk_localproxy_close,
	sk_localproxy_write,
	sk_localproxy_write_oob,
	sk_localproxy_flush,
	sk_localproxy_set_private_ptr,
	sk_localproxy_get_private_ptr,
	sk_localproxy_set_frozen,
	sk_localproxy_socket_error
    };

    Local_Proxy_Socket ret;
    HANDLE us_to_cmd, us_from_cmd, cmd_to_us, cmd_from_us;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    if (cfg->proxy_type != PROXY_CMD)
	return NULL;

    cmd = format_telnet_command(addr, port, cfg);

    {
	char *msg = dupprintf("Starting local proxy command: %s", cmd);
	/* We're allowed to pass NULL here, because we're part of the Windows
	 * front end so we know logevent doesn't expect any data. */
	logevent(NULL, msg);
	sfree(msg);
    }

    ret = snew(struct Socket_localproxy_tag);
    ret->fn = &socket_fn_table;
    ret->plug = plug;
    ret->error = NULL;

    /*
     * Create the pipes to the proxy command, and spawn the proxy
     * command process.
     */
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;    /* default */
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
	ret->error = dupprintf("Unable to create pipes for proxy command");
	return (Socket)ret;
    }

    if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
	CloseHandle(us_from_cmd);
	CloseHandle(cmd_to_us);
	ret->error = dupprintf("Unable to create pipes for proxy command");
	return (Socket)ret;
    }

    SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);

    si.cb = sizeof(si);
    si.lpReserved = NULL;
    si.lpDesktop = NULL;
    si.lpTitle = NULL;
    si.dwFlags = STARTF_USESTDHANDLES;
    si.cbReserved2 = 0;
    si.lpReserved2 = NULL;
    si.hStdInput = cmd_from_us;
    si.hStdOutput = cmd_to_us;
    si.hStdError = NULL;
    CreateProcess(NULL, cmd, NULL, NULL, TRUE,
		  CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
		  NULL, NULL, &si, &pi);

    sfree(cmd);

    CloseHandle(cmd_from_us);
    CloseHandle(cmd_to_us);

    ret->to_cmd_H = us_to_cmd;
    ret->from_cmd_H = us_from_cmd;

    ret->from_cmd_h = handle_input_new(ret->from_cmd_H, localproxy_gotdata,
				       ret, 0);
    ret->to_cmd_h = handle_output_new(ret->to_cmd_H, localproxy_sentdata,
				      ret, 0);

    /* We are responsible for this and don't need it any more */
    sk_addr_free(addr);

    return (Socket) ret;
}
Пример #19
0
/* 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;

    setup_environment(&info->fdn);

    /* 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;
}
Пример #20
0
int Helium::Execute( const tstring& command, tstring& output, bool showWindow )
{
    HANDLE hReadPipe;
    HANDLE hWritePipe;
    SECURITY_ATTRIBUTES sa;
    sa.nLength              = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle       = TRUE;
    if( !CreatePipe( &hReadPipe, &hWritePipe, &sa, 0 ) )
    {
        return -1;
    }

    STARTUPINFO          si;
    memset( &si, 0, sizeof(si) );
    si.cb          = sizeof(si);
    si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = static_cast<int>( showWindow );
    si.hStdOutput  = hWritePipe;
    si.hStdError   = hWritePipe;      

    PROCESS_INFORMATION  pi;
    memset( &pi, 0, sizeof( pi ) );

    if( !CreateProcess(
        NULL,                                                 // filename
        (tchar*) command.c_str(),                               // command line for child
        NULL,                                                 // process security descriptor
        NULL,                                                 // thread security descriptor
        TRUE,                                                 // inherit handles?
        showWindow ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW,   // creation flags
        NULL,                                                 // inherited environment address
        NULL,                                                 // startup dir; NULL = start in current
        &si,                                                  // pointer to startup info (input)
        &pi ) )                                               // pointer to process info (output)
    {
        ::CloseHandle( hReadPipe );
        ::CloseHandle( hWritePipe );
        return -1;
    }

    // close the write end of the pipe so the child will terminate it with EOF
    ::CloseHandle( hWritePipe );

    // read from the pipe until EOF condition reached
    tchar buffer[80];
    unsigned long count;
    tstringstream stream;
    BOOL success = TRUE;
    do
    {
        while ( success = ReadFile( hReadPipe, buffer, sizeof(buffer), &count, NULL ) )
        {
            if( success )
            {
                stream.write( buffer, count );
            }
            else
            {
                if ( ::GetLastError() == ERROR_BROKEN_PIPE )
                {
                    break;
                }
                else
                {
                    return -1;
                }
            }
        }
    } while( success && count );

    // done reading, close our read pipe
    ::CloseHandle( hReadPipe );

    // copy output string
    output = stream.str();

    // get exit code
    DWORD result = 0;
    BOOL codeResult = ::GetExitCodeProcess( pi.hProcess, &result );
    HELIUM_ASSERT( codeResult );

    // close the process handle
    ::CloseHandle( pi.hProcess );
    ::CloseHandle( pi.hThread );

    return result;
}
Пример #21
0
/*
** CreateAsc( ) --- Create an association.
**
** Inputs:
**	asipc	ASSOC_IPC for association
**	name	name of server creating association.
** Output:
**	returns TRUE if succeeds.
**
** GClisten( ) calls CreateAsc( ) when a server wishes to create
** a new association. CrateAsc( ) allocates the resources required by 
** the association, and exposes shared information available to other processes.
** The only requirements are that it create four handles in the ASSOC_IPC:
** standard send, standard receive, expedited send, and expeditied receive.
** These handles are the only members created here used by gcacl. In 
** this implementation handles to anonymous pipes are used.
**
** If there are no existing connections to the server spicified in the 
** name parameter, CreateAsc( ) creates the server specific resources and
** adds the server to the internally maintained list of servers. A memory mapped
** mapped file is created for passing information between the client and 
** server. This file contains a temporary area for passing process id and
** handles which the client needs to copy to its own ASSOC_IPC. It also 
** contains and array of assoc_info structures. These structures contain
** information that must be shared per connection for the duration of each 
** association. A mutex is created to protect access to the temporary area.
** The temporary area is only used when a connectionis first established
** to copy handles to the pipes and other information to the requester's
** ASSOC_IPC.
**
** Two events are also created to arbitrate the connection process. When
** a server is ready for a connection, it signals a "listening event". 
** and waits for a client to set a requesting event. Before connecting 
** a client waits on the listening event before trying to connect. When
** the client tries to connect it sets a requesting event to tell the server
** that a client has connected.
**
** The names for the memory mapped file, the mutex, and the events are
** based on the server name.
**
** History:
**      10-Dec-98 (lunbr01) Bug 94183
**          Eliminate use of *Ct fields (using PeekNamedPipe instead).
*/
BOOL 	 
CreateAsc(ASSOC_IPC * asipc, char *name )
{
	HANDLE 		hMapping; /* for memory mapped file */
	static HANDLE	hMutex;	  /* for memory mapped file */
	ASSOC_IPC	*asipc_temp;
	ASSOC_INFO	*assoc_info;
	struct _Asc_ipc_area	*svr_ipc_area;
	SERVER_ENTRY	*server;
	short		i;
															
	SECURITY_ATTRIBUTES	sa;
	
	/* Set up security attributes */		
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;
	
	/* If there are no existing connections to this server. Open the
	** memory mapped file, events, and mutex for this server. 
	*/
	if( NULL == ( server = LookUpServer( name ) ) )	
	{
		char ReqEventName[MAXPNAME + 4 ];
		char LstEventName[MAXPNAME + 4 ];
		
		if ((hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
				&sa,
				PAGE_READWRITE,
				0,
				sizeof( struct _Asc_ipc_area ),  
				name )) == NULL)
		{
			DWORD err = GetLastError( );
			return FALSE ;
		}
		
		if (NULL == (svr_ipc_area=
			(struct _Asc_ipc_area *)MapViewOfFile(hMapping,
						FILE_MAP_ALL_ACCESS,
						0,
						0,
						0 ) ) )
		{
			return FALSE;
		}
		
		/* Create an event that will be signaled when an 
		** association is requested.
		*/
		wsprintf( ReqEventName, "%s-%s", name, "req" );
		wsprintf( LstEventName, "%s-%s", name, "lst" );
		
		/* Create SERVER_ENTRY */
		server = AddServer( name,  svr_ipc_area, hMapping, 
					CreateEvent( &sa, FALSE, FALSE, 
					ReqEventName ), 
					CreateEvent( &sa, FALSE, FALSE, 
					LstEventName ) );
		
		/* Create a mutex to coordinate access to asipc_temp */
		hMutex = CreateMutex( &sa, FALSE, name );
		
		/* Create a proces handle so other processes can 
		   use DuplicateHandle */
		svr_ipc_area->nProcId =  GetCurrentProcessId( );
	}
	
	/* Get a pointer to the Memory mapped file for this server. */
	svr_ipc_area = server->lpMapping;
	
	if ( server->nConnections == MAX_ASSOCS ) /* no more assocs allowed */
		return FALSE ;
		
	asipc_temp = &( svr_ipc_area->asipc );
	assoc_info = (ASSOC_INFO *)&( svr_ipc_area->assoc_info );

	/* Make sure that it is safe to change temporary connection info.  
	** Copy the connection information the local ASSOC_IPC. 
	*/
	WaitForSingleObject( hMutex, INFINITE );	
	
	/* Find a valid id and set up the assoc_info. */
	for( i = 0; i < MAX_ASSOCS; i++ )
	{
		if ( assoc_info[i].refs == 0 )
			break;
	}
	asipc->IpcInternal.hMapping 	= hMapping; /* for save and restore */
	asipc->IpcInternal.AssocInfo	= &assoc_info[i];
	asipc_temp->IpcInternal.AscID	= asipc->IpcInternal.AscID = i;
	assoc_info[i].bPipesClosed = FALSE;
	assoc_info[i].refs++;

	/* Set the AssocInfo */

	assoc_info[i].out_buffer_size = Pipe_buffer_size;
	assoc_info[i].in_buffer_size = Pipe_buffer_size;

	if(!CreatePipe( &asipc->RcvStdChan, &asipc_temp->SndStdChan, &sa, 
				Pipe_buffer_size ) ||
	   !CreatePipe( &asipc_temp->RcvStdChan, &asipc->SndStdChan, &sa, 
				Pipe_buffer_size ) ||
	   !CreatePipe( &asipc->RcvExpChan, &asipc_temp->SndExpChan, &sa, 
				Pipe_buffer_size ) ||
	   !CreatePipe( &asipc_temp->RcvExpChan, &asipc->SndExpChan, &sa, 
				Pipe_buffer_size ) ) 
	{
		CloseAsc( asipc );
		CloseAsc( asipc_temp );
		return FALSE ;
	}

        /* We need to duplicate the client side of standard read handle
           asipc_temp->RcvStdChan for PeekNamedPipe() because it gets closed
           by the DUPLICATE_CLOSE_SOURCE option of DuplicateHandle() after a
           front end client connects to the server and duplicates it into
           their address space. */
        if (!DuplicateHandle(
                       GetCurrentProcess(),
                       asipc_temp->RcvStdChan,
                       GetCurrentProcess(),
                       &asipc->ClientReadHandle,
                       GENERIC_READ,
                       TRUE,
                       DUPLICATE_SAME_ACCESS
                       ) )
        {
                        CloseAsc( asipc );
                        CloseAsc( asipc_temp );
                        return FALSE ;
        }

        /* We need to duplicate the server side of standard read handle
           asipc->RcvStdChan for PeekNamedPipe() in the client because it
           gets closed by the DUPLICATE_CLOSE_SOURCE option of
           DuplicateHandle() after a front end client connects to the server
           and duplicates it into their address space. */
        if (!DuplicateHandle(
                       GetCurrentProcess(),
                       asipc->RcvStdChan,
                       GetCurrentProcess(),
                       &asipc_temp->ClientReadHandle,
                       GENERIC_READ,
                       TRUE,
                       DUPLICATE_SAME_ACCESS
                       ) )
        {
                        CloseAsc( asipc );
                        CloseAsc( asipc_temp );
                        return FALSE ;
        }

	ReleaseMutex( hMutex );

	/* 
	** Set up pointer to server and increment the number of connections.	
	*/
	asipc->IpcInternal.server = server;
	asipc->IpcInternal.server->nConnections++;
		
	return TRUE;
}
Пример #22
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;
}
Пример #23
0
int TestPipeCreatePipe(int argc, char* argv[])
{
	BOOL status;
	DWORD dwRead;
	DWORD dwWrite;
	HANDLE hReadPipe;
	HANDLE hWritePipe;
	BYTE readBuffer[BUFFER_SIZE];
	BYTE writeBuffer[BUFFER_SIZE];

	status = CreatePipe(&hReadPipe, &hWritePipe, NULL, BUFFER_SIZE * 2);

	if (!status)
	{
		_tprintf(_T("CreatePipe failed\n"));
		return -1;
	}

	FillMemory(writeBuffer, sizeof(writeBuffer), 0xAA);
	status = WriteFile(hWritePipe, &writeBuffer, sizeof(writeBuffer), &dwWrite, NULL);

	if (!status)
	{
		_tprintf(_T("WriteFile failed\n"));
		return -1;
	}

	if (dwWrite != sizeof(writeBuffer))
	{
		_tprintf(_T("WriteFile: unexpected number of bytes written: Actual: %ld, Expected: %ld\n"),
			dwWrite, (long int)sizeof(writeBuffer));
		return -1;
	}

	ZeroMemory(readBuffer, sizeof(readBuffer));
	status = ReadFile(hReadPipe, &readBuffer, sizeof(readBuffer), &dwRead, NULL);

	if (!status)
	{
		_tprintf(_T("ReadFile failed\n"));
		return -1;
	}

	if (dwRead != sizeof(readBuffer))
	{
		_tprintf(_T("ReadFile: unexpected number of bytes read: Actual: %ld, Expected: %ld\n"),
			dwWrite, (long int)sizeof(readBuffer));
		return -1;
	}

	if (memcmp(readBuffer, writeBuffer, BUFFER_SIZE) != 0)
	{
		_tprintf(_T("ReadFile: read buffer is different from write buffer\n"));
		return -1;
	}

	CloseHandle(hReadPipe);
	CloseHandle(hWritePipe);

	return 0;
}
Пример #24
0
static NBBOOL session_attach_process(sessions_t *sessions, session_t *session, char *process)
{
#ifdef WIN32
	STARTUPINFOA         startupInfo;
	PROCESS_INFORMATION  processInformation;
	SECURITY_ATTRIBUTES  sa;
	session_group_t *session_group = (session_group_t*) safe_malloc(sizeof(session_group_t));
	session_group->session  = session;
	session_group->sessions = sessions;

	/* Create a security attributes structure. This is required to inherit handles. */
	ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
	sa.nLength              = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle       = TRUE;

	/* Create the anonymous pipes. */
	if(!CreatePipe(&session->exec_stdin[PIPE_READ], &session->exec_stdin[PIPE_WRITE], &sa, 0))
		nbdie("exec: Couldn't create pipe for stdin");
	if(!CreatePipe(&session->exec_stdout[PIPE_READ], &session->exec_stdout[PIPE_WRITE], &sa, 0))
		nbdie("exec: Couldn't create pipe for stdout");

	fprintf(stderr, "Attempting to load the program: %s\n", process);

	/* Initialize the STARTUPINFO structure. */
	ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
	startupInfo.cb         = sizeof(STARTUPINFO);
	startupInfo.dwFlags    = STARTF_USESTDHANDLES;
	startupInfo.hStdInput  = session->exec_stdin[PIPE_READ];
	startupInfo.hStdOutput = session->exec_stdout[PIPE_WRITE];
	if(!sessions->exec_no_stderr)
		startupInfo.hStdError = session->exec_stdout[PIPE_WRITE];

	/* Initialize the PROCESS_INFORMATION structure. */
	ZeroMemory(&processInformation, sizeof(PROCESS_INFORMATION));

	/* Create the actual process with an overly-complicated CreateProcess function. */
	if(!CreateProcessA(NULL, process, 0, &sa, TRUE, CREATE_NO_WINDOW, 0, NULL, &startupInfo, &processInformation))
	{
		fprintf(stderr, "Failed to create the process");
		exit(1);
	}

	/* Save the process id and the handle. */
	session->pid = processInformation.dwProcessId;
	session->exec_handle = processInformation.hProcess;
	session->socket_id = --sessions->current_socket_id;

	/* Close the duplicate pipes we created -- this lets us detect the proicess termination. */
	CloseHandle(session->exec_stdin[PIPE_READ]);
	CloseHandle(session->exec_stdout[PIPE_WRITE]);
	if(!sessions->exec_no_stderr)
		CloseHandle(session->exec_stdout[PIPE_WRITE]);

	fprintf(stderr, "Successfully created the process!\n\n");

	/* On Windows, add the sub-process's stdout as a pipe. */
	select_group_add_pipe(sessions->select_group, session->socket_id, session->exec_stdout[PIPE_READ], session_group);
	select_set_recv(sessions->select_group, session->socket_id, exec_callback);
	select_set_closed(sessions->select_group, session->socket_id, exec_closed_callback);
#else
	session_group_t *session_group = (session_group_t*) safe_malloc(sizeof(session_group_t));
	session_group->session  = session;
	session_group->sessions = sessions;

	fprintf(stderr, "Attempting to start process '%s' for session %s\n", process, session->name);

	/* Create communication channels. */
	if(pipe(session->exec_stdin) == -1)
		nbdie("exec: couldn't create pipe for STDIN");

	if(pipe(session->exec_stdout) == -1)
		nbdie("exec: couldn't create pipe for STDOUT");

	session->pid = fork();

	if(session->pid == -1)
		nbdie("exec: couldn't create process");

	if(session->pid == 0)
	{
		/* Copy the pipes. */
		if(dup2(session->exec_stdin[PIPE_READ], STDIN_FILENO) == -1)
			nbdie("exec: couldn't duplicate STDIN handle");
		if(dup2(session->exec_stdout[PIPE_WRITE], STDOUT_FILENO) == -1)
			nbdie("exec: couldn't duplicate STDOUT handle");
		if(sessions->exec_no_stderr)
		{
			session->exec_stdout[PIPE_WRITE] = 0;
		}
		else
		{
			if(dup2(session->exec_stdout[PIPE_WRITE], STDERR_FILENO) == -1)
				nbdie("exec: couldn't duplicate STDERR handle");
		}

		/* Execute the new process. */
		execlp("/bin/sh", "sh", "-c", process, (char*) NULL);

		/* If execlp returns, bad stuff happened. */
		fprintf(stderr, "exec: execlp failed");
		return FALSE;
	}

	fprintf(stderr, "Started: %s (pid: %d)\n", process, session->pid);
	close(session->exec_stdin[PIPE_READ]);
	close(session->exec_stdout[PIPE_WRITE]);

	/* On Linux, add the sub-process's stdout as a socket. */
	select_group_add_socket(sessions->select_group, session->exec_stdout[PIPE_READ], SOCKET_TYPE_STREAM, session_group);
	select_set_recv(sessions->select_group, session->exec_stdout[PIPE_READ], exec_callback);
	select_set_closed(sessions->select_group, session->exec_stdout[PIPE_READ], exec_closed_callback);
#endif

	return TRUE;
}
Пример #25
0
static int rar_open(char *rarname, mode_t m, stream_t *stream)
{
	stream_0day_priv_t *p;
	char RarTag[7], method, *pp, type = 0;
	WORD w, n, flag;

	int h = open(rarname, m);
	if (h < 0) return h;

	read(h, RarTag, 7);						/* Read Rar!... Tag */
	if (strncmp(RarTag, "Rar!", 4)) {
		lseek(h, 0, SEEK_SET);				/* Not a RAR */
		return h;
	}

	p = (stream_0day_priv_t*)malloc(sizeof(stream_0day_priv_t));
	memset(p, 0, sizeof(stream_0day_priv_t));
	p->headSize = 7;
	while (type != 0x74) {
		lseek(h, 2, SEEK_CUR);				/* CRC */
		read(h, &type, 1);					/* Type */
		read(h, (char*)&flag, 2);			/* Flag */
		read(h, (char*)&w, 2);				/* Size */
		p->headSize += w;
		if (type == 0x73) { /* main header */
			p->naming = flag & 0x10;
		} else
		if (type == 0x74) {	/* file header */
			read(h, (char*)&(p->packSize), 4);
			read(h, (char*)&(p->fileSize), 4);
			lseek(h, 10, SEEK_CUR);			/* Skip OS/CRC/Time/Ver */
			read(h, &method, 1);			/* Compression Method */
			read(h, (char*)&n, 2);			/* Size of rarname */
			if (w == n + 0x2D) {
				/* fileSize is 64bit */
				lseek(h, 8, SEEK_CUR);
				read(h, ((char*)&(p->fileSize))+4, 4);
			} else {
				lseek(h, 4, SEEK_CUR);		/* Attr */
			}
			p->filename = (char *)malloc(n + 1);
			read(h, p->filename, n);		/* filename */
			p->filename[n] = 0;
		} else
		if (type == 0x7A) {	/* comment header */
			read(h, (char*)&w, 2);			/* Size of comment */
			p->headSize += w;
		}
		lseek(h, p->headSize, SEEK_SET);	/* Seek to next header */
	}
	mp_msg(MSGT_STREAM,MSGL_INFO, "File Flags=%04x\tCompression Method=%x\n", flag, method);

	if (!(flag & 0x04) && (method == 0x30)) {	/* 0day stream */
		n = strlen(rarname);
		p->basename = strdup(rarname);
		if (p->naming) {
			p->naming = rarname + n - strrchr(rarname, 't') - 5;
			n -= (p->naming + 4);
		} else {
			n -= 3;
		}
		p->basename[n] = 0;

		close(h);
		h = open_0day_volume(p, 0);
		if (h < 0) {
			free(p->filename);
			free(p->basename);
			free(p);
		} else {
			/* reget packSize, avoid got the last volume's packSize */
			type = 0;
			n = 7;
			lseek(h, 7, SEEK_SET);
			while (type != 0x74) {
				lseek(h, 2, SEEK_CUR);				/* CRC */
				read(h, &type, 1);					/* Type */
				read(h, (char*)&flag, 2);			/* Flag */
				read(h, (char*)&w, 2);				/* Size */
				n += w;
				if (type == 0x74) {	/* file header */
					read(h, (char*)&(p->packSize), 4);
				} else
				if (type == 0x7A) {	/* comment header */
					read(h, (char*)&w, 2);			/* Size of comment */
					n += w;
				}
				lseek(h, n, SEEK_SET);	/* Seek to next header */
			}

			stream->priv = (void*)p;
			stream->close = close_0day;
			stream->seek = seek_0day;
			stream->fill_buffer = fill_buffer_0day;
			stream->end_pos = p->fileSize;
			stream->type = STREAMTYPE_FILE;
		}
		return h;
	}

	free(p);

	if (unrardll) {								/* rar stream */
		struct RAROpenArchiveDataEx OpenArchiveData;
		struct RARHeaderDataEx HeaderData;
		HANDLE hPipeRead, hPipeWrite;
		int hArcData;

		memset(&OpenArchiveData,0,sizeof(OpenArchiveData));
		OpenArchiveData.ArcName=rarname;
		OpenArchiveData.OpenMode=RAR_OM_EXTRACT;

		hArcData=(*RAROpenArchiveEx)(&OpenArchiveData);
		if (!OpenArchiveData.OpenResult) {
			HeaderData.CmtBuf=NULL;
			if (!(*RARReadHeaderEx)(hArcData,&HeaderData)) {
				if (HeaderData.Flags & 0x04) {
					/* Request password */
					if (DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_PASSWORD),
						GetForegroundWindow(), unrar_pw_dlgproc) == IDOK) {
						(*RARSetPassword)(hArcData, pw);
					} else {
						close(h);
						h = -2;
						goto rar_open_break;
					}
				}
				if (CreatePipe(&hPipeRead, &hPipeWrite, 0, 0x10000)) {
					stream_rar_priv_t *p;

					(*RARSetCallback)(hArcData, unrar_callback, (int)hPipeWrite);
					p = (stream_rar_priv_t*)malloc(sizeof(stream_rar_priv_t));
					p->filename = strdup(HeaderData.FileName);
					p->hArcData = hArcData;
					p->hPipeWrite = hPipeWrite;
					if (_beginthread((void (*)())unrar_thread, 0, (void*)p) != -1) {
						stream->priv = (void*)p;
						stream->close = close_rar;
						close(h);
						return (int)hPipeRead;
					}
					else {
						free(p->filename);
						free(p);
						CloseHandle(hPipeRead);
						CloseHandle(hPipeWrite);
					}
				}
			}

rar_open_break:
			(*RARCloseArchive)(hArcData);
		}
	}

	return h;
}
Пример #26
0
//
// Invoke()
//
// invoke the GIB program and return the recommended play
//
int CGIB::Invoke(CPlayer* pPlayer, CHandHoldings* pHand, CHandHoldings* pDummyHand, CPlayerStatusDialog* pStatusDlg)
{
	SECURITY_ATTRIBUTES saAttr; 
	
	//
	// create the GIB monitor dialog
	//
	CGIBDialog	gibDialog(pMAINFRAME);
	int nProcessingTime = theApp.GetValue(tnGIBAnalysisTime);
	gibDialog.m_nProcessTime = nProcessingTime;
//	gibDialog.m_hEventCancel = m_hEventCancel;

	
	// Set the bInheritHandle flag so pipe handles are inherited. 
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL; 
	
	//
	// create input and output pipes for the child process
	//

	// Create a pipe for the child process's STDOUT. 
	if (!CreatePipe(&m_hChildStdoutRd,	// returns the pipe's input handle
				    &m_hChildStdoutWr, 	// returns the pipe's output handle
					&saAttr, 
					0)) 
	{
		CString strError = "Stdout pipe creation failed\n"; 
		TRACE(strError); 
		pMAINFRAME->SetGIBMonitorText(strError);
		return ExitGracefully(-5);
	}
	// then create a pipe for the child process's STDIN. 
	if (!CreatePipe(&m_hChildStdinRd, 
					&m_hChildStdinWr, 
					&saAttr, 
					0)) 
	{
		CString strError = "Stdin pipe creation failed\n"; 
		TRACE(strError); 
		pMAINFRAME->SetGIBMonitorText(strError);
		return ExitGracefully(-5);
	}

	//
	// Now create the child process (GIB)
	//
	PROCESS_INFORMATION piProcInfo; 
	if (!LaunchProgram(piProcInfo)) 
	{
		TRACE("Create process failed"); 
		return ExitGracefully(-1);
	}
	HANDLE hGIBProcess = piProcInfo.hProcess;
	DWORD nGIBProcessID = piProcInfo.dwProcessId;

	// now close the readable handle to the child's stdin
	SafeCloseHandle(m_hChildStdinRd);
	// and the writable handle to the child's stdout
	SafeCloseHandle(m_hChildStdoutWr);

	//
	//------------------------------------------------------------------
	//
	// create the GIB input file
	//
	CFile file;
	CFileException fileException;
	CString strTempFile, strTempPath;
	GetTempPath(1024, strTempPath.GetBuffer(1024));
	strTempPath.ReleaseBuffer();
	GetTempFileName(strTempPath, "ezb", 0, strTempFile.GetBuffer(2048));
	strTempFile.ReleaseBuffer();
//	strTempFile.Format("%s\\%s", theApp.GetValueString(tszProgramDirectory), tszGIBTempFilename);
/*
	LPTSTR szBuffer = strTempFile.GetBuffer(MAX_PATH);
	GetTempFileName(theApp.GetValueString(tszProgramDirectory), "ezb", 0, szBuffer);
	strTempFile.ReleaseBuffer();
*/
//	CString strInput;
//	strInput.Format("-T %d %s\n",theApp.GetValue(tnGIBAnalysisTime),strTempFile);
	int nCode = file.Open(strTempFile, 
			  			  CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite, 
						  &fileException);
	if (nCode == 0) 
	{
		CString strError = "Error opening temporary input file for GIB"; 
		TRACE(strError); 
		pMAINFRAME->SetGIBMonitorText(strError);
		return ExitGracefully(-2);
	}
	//
	CString strFileContents;
	CreateGIBInputFile(file, pPlayer, pHand, pDummyHand, strFileContents);
	file.Close();

	// then send the parameters line
	CString strParameters, strShortParameters;
	strParameters.Format("-T %d %s\n",nProcessingTime,strTempFile);
	strShortParameters.Format("-T %d",nProcessingTime);
	DWORD dwWritten;
	int nErrCode;
	if (!WriteFile(m_hChildStdinWr, (LPCTSTR)strParameters, strParameters.GetLength(), &dwWritten, NULL)) 
	{
		CString strError = "Error providing parameters to GIB"; 
		TRACE(strError); 
		pMAINFRAME->SetGIBMonitorText(strError);
		nErrCode = GetLastError();
		return ExitGracefully(-3);
	}

	//
	// update the GIB monitor window
	//
	CString strGIBText = "========================================\n";
	strGIBText += FormString("Launching %s %s\n",
							 theApp.GetValueString(tszGIBPath),
							 strShortParameters);
//	strGIBText += FormString("Input file contents:\n%s", strFileContents);
	strGIBText += "Awaiting Responses...\n";
	strGIBText += "----------------------------------------\n";
//	pMAINFRAME->SetGIBMonitorText(strGIBText);
	pMAINFRAME->AppendGIBMonitorText(strGIBText);
	

	//
	//------------------------------------------------------------
	//
	// now set up the wait loop and the cancel dialog,
	// then sit and wait for the process to run or for a cancel message
	//

/*
	//
	// create the "Cancel GIB" dialog thread
	// (this is a user interface thread)
	//
	CGIBMonitorThread* pMonitorThread = new CGIBMonitorThread(m_hEventFinished, m_hEventCancel, nProcessingTime);
	pMonitorThread->CreateThread(CREATE_SUSPENDED);
	pMonitorThread->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
	pMonitorThread->ResumeThread();

	// wait for the monitor thread to initialize
	DWORD nCode0 = WaitForSingleObject(m_hEventFinished,
									   INFINITE);		
*/

	//
	// create the wait thread
	// (this is a worker thread)
	//
	GIBStruct gibData;
	gibData.hReadHandle = m_hChildStdoutRd;
	gibData.pGIBDialog = &gibDialog;
	CWinThread* pWaitThread = AfxBeginThread(CGIB::ReadGIBOutput, &gibData, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

	// copy its handle se that we can check its exit code later
  	HANDLE hWaitThread;
	BOOL bCode = ::DuplicateHandle(GetCurrentProcess(), pWaitThread->m_hThread, 
								   GetCurrentProcess(), &hWaitThread, 
								   0, FALSE, DUPLICATE_SAME_ACCESS);
	// and launch the threads
//	MonitorThread->ResumeThread();
	pWaitThread->ResumeThread();


	//
	// Show the Wait/Cancel dialog
	//
	m_bGIBPending = TRUE;		// mark dialog as active
	bCode = gibDialog.DoModal();

	// see if the user cancelled
	if (!bCode) 
	{
/*
		// lock out the wait thread and cancel operations
		if (ClearGIBPending())
		{
*/
		//
		pMAINFRAME->SetStatusText("GIB cancelled.");
		//
		TerminateProcess(hGIBProcess, 0);
		TerminateThread(hWaitThread, 0);
		// wait for the read thread to end
		WaitForSingleObject(hWaitThread, INFINITE);
		// close the wait thread handle
		CloseHandle(hWaitThread);
		CloseHandle(hGIBProcess);
		// and delete the thread object
		delete pWaitThread;
		// close pipe handles 
		SafeCloseHandle(m_hChildStdinWr);
		SafeCloseHandle(m_hChildStdoutRd);
		// and throw an exception
		throw CGIBException();
//		}
	}

/*
	// set up events
	HANDLE eventArray[2];
	eventArray[0] = m_hEventCancel;
	eventArray[1] = pWaitThread->m_hThread;

	//
	// then sit back and wait for the thread(s)
	//
	for(;;)
	{
		// wait for the cancelled or finished messages
		DWORD nCode = WaitForMultipleObjects(2,				// 2 events to wait for
											 eventArray,	// events array
											 FALSE,			// not all at once
											 INFINITE);		// wait 4-ever
		//
		if (nCode == WAIT_FAILED)
		{
			ASSERT(FALSE);
			break;
		}
		else if (nCode == WAIT_OBJECT_0) 
		{
			// got the cancel message, so kill GIB & the wait thread
			// the following is very dangersous --
			// so kids, don't try this at home
			TerminateThread(pWaitThread, 0);
			TerminateProcess(hGIBProcess, 0);
			return GIB_CANCEL;
		}
		else if (nCode == WAIT_OBJECT_0 + 1)
		{
			// GIB finished message
			// signal the GIB monitor that GIB has finished
			SetEvent(m_hEventFinished);
			break;
		}
	}

*/

	//
	//------------------------------------------------------------
	//
	// presumably, GIB has finished running
	//

	// wait for the GIB thread to exit, then get the card code
	DWORD nCardPlayed, nErrorCode;
	bCode = WaitForSingleObject(hWaitThread, INFINITE);
	bCode = GetExitCodeThread(hWaitThread, &nCardPlayed);
	if (!bCode)
		nErrorCode = GetLastError();

	// close the wait thread handle
	CloseHandle(hWaitThread);

	// delete the temporary file
	DeleteFile(strTempFile);
 
	// and kill the child process
	// first send a Ctrl-C to the app 
	// (this doesn't seem to do anything)
	CString strInput = "\03";	// Ctrl-C
	if (!WriteFile(m_hChildStdinWr, (LPCTSTR)strInput, strInput.GetLength(), &dwWritten, NULL)) 
	{
		CString strError = "Error stopping GIB"; 
		TRACE(strError); 
		pMAINFRAME->SetGIBMonitorText(strError);
		nErrCode = GetLastError();
		return ExitGracefully(-4);
	}

	// close the writable handle to the child's stdin
	SafeCloseHandle(m_hChildStdinWr);

	// then call terminateProcess
	TerminateProcess(hGIBProcess, 0);
	CloseHandle(hGIBProcess);

	// then close the readable handle to the child's stdout
	SafeCloseHandle(m_hChildStdoutRd);

	//
	// done
	//
	return nCardPlayed; 
} 
Пример #27
0
int get_exec_pipes (char *cmd, int *fdIn, int *fdOut, netsnmp_pid_t * pid)
{

/*     Alexander Prömel, [email protected] 08/24/2006
    The following code, is tested on picotux rev. 1.01.
    I think, it will be better to put the named pipes, into /var/run or make it selectable via CONFIG file.
    If the pipe file already exist, the creation will fail.
    I put the pipes into /flash, the pipepath has to change in ucd-snmp/pass_persist.c too, if you change it here.
*/
#if HAVE_EXECV
#ifdef __uClinux__                /* HAVE uClinux */
    int in, out;

    char fifo_in_path[256];

    char fifo_out_path[256];

    pid_t tpid;

    if ((tpid = vfork ()) == 0)
    {                            /*temp child */
        execve (cmd, NULL, NULL);
        perror (cmd);
        exit (1);
    }
    else
    {
        if (tpid > 0)
        {
            /*initialize workspace */
            snprintf (fifo_in_path, 256, "/flash/cp_%d", tpid);
            snprintf (fifo_out_path, 256, "/flash/pc_%d", tpid);

            in = mkfifo (fifo_in_path, S_IRWXU);    /*Create Input Pipe, 700 */
            if (in)
            {
                perror ("parent: inpipe");
                exit (0);
            }
            out = mkfifo (fifo_out_path, S_IRWXU);    /*Create Output Pipe, 700 */
            if (out)
            {
                perror ("parent: outpipe");
                exit (0);
            }

            in = open (fifo_in_path, O_RDONLY);    /*open the Input Pipe read Only */
            if (in < 0)
            {
                perror ("parent: input");
                exit (0);
            }
            out = open (fifo_out_path, O_WRONLY);    /*open the Output Pipe write Only */
            if (out < 0)
            {
                perror ("parent: output");
                exit (0);
            }

            *fdIn = in;            /*read */
            *fdOut = out;        /*write */
            *pid = tpid;
            return (1);            /* We are returning 0 for error... */
        }
        else
        {                        /*pid < 0 */
            setPerrorstatus ("vfork");
            return 0;
        }

    }
#else                            /*HAVE x86 */
    int fd[2][2], i, cnt;

    char ctmp[STRMAX], *cptr1, *cptr2, argvs[STRMAX], **argv, **aptr;

    /*
     * Setup our pipes 
     */
    if (pipe (fd[0]) || pipe (fd[1]))
    {
        setPerrorstatus ("pipe");
        return 0;
    }
    if ((*pid = fork ()) == 0)
    {                            /* First handle for the child */
        close (0);
        if (dup (fd[0][0]) != 0)
        {
            setPerrorstatus ("dup 0");
            return 0;
        }
        close (1);
        if (dup (fd[1][1]) != 1)
        {
            setPerrorstatus ("dup 1");
            return 0;
        }

        /*
         * write standard output and standard error to pipe. 
         */
        /*
         * close all non-standard open file descriptors 
         */
        for (cnt = getdtablesize () - 1; cnt >= 2; --cnt)
            (void) close (cnt);
        (void) dup (1);            /* stderr */

        for (cnt = 1, cptr1 = cmd, cptr2 = argvs; *cptr1 != 0; cptr2++, cptr1++)
        {
            *cptr2 = *cptr1;
            if (*cptr1 == ' ')
            {
                *(cptr2++) = 0;
                if ((cptr1 = skip_white (cptr1)) == NULL)
                    break;
                *cptr2 = *cptr1;
                if (*cptr1 != 0)
                    cnt++;
            }
        }
        *cptr2 = 0;
        *(cptr2 + 1) = 0;
        argv = (char **) malloc ((cnt + 2) * sizeof (char *));
        if (argv == NULL)
            return 0;            /* memory alloc error */
        aptr = argv;
        *(aptr++) = argvs;
        for (cptr2 = argvs, i = 1; i != cnt; cptr2++)
            if (*cptr2 == 0)
            {
                *(aptr++) = cptr2 + 1;
                i++;
            }
        while (*cptr2 != 0)
            cptr2++;
        *(aptr++) = NULL;
        copy_nword (cmd, ctmp, sizeof (ctmp));
        execv (ctmp, argv);
        perror (ctmp);
        exit (1);
    }
    else
    {
        close (fd[0][0]);
        close (fd[1][1]);
        if (*pid < 0)
        {
            close (fd[0][1]);
            close (fd[1][0]);
            setPerrorstatus ("fork");
            return 0;
        }
        *fdIn = fd[1][0];
        *fdOut = fd[0][1];
        return (1);                /* We are returning 0 for error... */
    }
#endif                            /* uClinux or x86 */
#endif                            /* !HAVE_EXECV */
#if defined(WIN32) && !defined (mingw32) && !defined(HAVE_EXECV)

/* MSVC (MinGW not working but should use this code).  Cygwin already works as it has execv and fork */
    /* Reference:  MS tech note: 190351 */
    HANDLE hInputWriteTmp, hInputRead, hInputWrite = NULL;

    HANDLE hOutputReadTmp, hOutputRead, hOutputWrite = NULL;

    HANDLE hErrorWrite;

    SECURITY_ATTRIBUTES sa;

    PROCESS_INFORMATION pi;

    STARTUPINFO si;

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

    /* Child temporary output pipe with Inheritance on (sa.bInheritHandle is true) */
    if (!CreatePipe (&hOutputReadTmp, &hOutputWrite, &sa, 0))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CreatePipe ChildOut: %d\n", GetLastError ()));
        return 0;
    }
    /* Child temporary input pipe with Inheritance on (sa.bInheritHandle is true) */
    if (!CreatePipe (&hInputRead, &hInputWriteTmp, &sa, 0))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CreatePipe ChildIn: %d\n", GetLastError ()));
        return 0;
    }

    /* Copy the stdout handle to the stderr handle in case the child closes one of 
     * its stdout handles. */
    if (!DuplicateHandle (GetCurrentProcess (), hOutputWrite, GetCurrentProcess (),
                          &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes DuplicateHandle: %d\n", GetLastError ()));
        return 0;
    }

    /* Create new copies of the input and output handles but set bInheritHandle to 
     * FALSE so the new handle can not be inherited.  Otherwise the handles can not
     * be closed.  */
    if (!DuplicateHandle (GetCurrentProcess (), hOutputReadTmp, GetCurrentProcess (),
                          &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes DupliateHandle ChildOut: %d\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        return 0;
    }
    if (!DuplicateHandle (GetCurrentProcess (), hInputWriteTmp,
                          GetCurrentProcess (), &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes DupliateHandle ChildIn: %d\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        return 0;
    }

    /* Close the temporary output and input handles */
    if (!CloseHandle (hOutputReadTmp))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CloseHandle (hOutputReadTmp): %d\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        CloseHandle (hInputWrite);
        return 0;
    }
    if (!CloseHandle (hInputWriteTmp))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CloseHandle (hInputWriteTmp): %d\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        CloseHandle (hInputWrite);
        return 0;
    }

    /* Associates a C run-time file descriptor with an existing operating-system file handle. */
    *fdIn = _open_osfhandle ((long) hOutputRead, 0);
    *fdOut = _open_osfhandle ((long) hInputWrite, 0);

    /* Set up STARTUPINFO for CreateProcess with the handles and have it hide the window
     * for the new process. */
    ZeroMemory (&si, sizeof (STARTUPINFO));
    si.cb = sizeof (STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdOutput = hOutputWrite;
    si.hStdInput = hInputRead;
    si.hStdError = hErrorWrite;
    si.wShowWindow = SW_HIDE;

    /* Launch the process that you want to redirect.  Example snmpd.conf pass_persist:
     * pass_persist    .1.3.6.1.4.1.2021.255  c:/perl/bin/perl c:/temp/pass_persisttest
     */
    if (!CreateProcess (NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CreateProcess:'%s' %d\n", cmd, GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        CloseHandle (hInputWrite);
        return 0;
    }

    DEBUGMSGTL (("util_funcs", "child hProcess (stored in pid): %d\n", (int) pi.hProcess));
    DEBUGMSGTL (("util_funcs", "child dwProcessId (task manager): %d\n", (int) pi.dwProcessId));

    /* Set global child process handle */
    *pid = pi.hProcess;

    /* Cleanup */
    if (!CloseHandle (pi.hThread))
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CloseHandle pi.hThread: %d\n", cmd));

    /* Close pipe handles 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 any calls to ReadFile 
     * will hang.
     */

    if (!CloseHandle (hOutputWrite))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CloseHandle hOutputWrite: %d\n", cmd, GetLastError ()));
        return 0;
    }
    if (!CloseHandle (hInputRead))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CloseHandle hInputRead: %d\n", cmd, GetLastError ()));
        return 0;
    }
    if (!CloseHandle (hErrorWrite))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CloseHandle hErrorWrite: %d\n", cmd, GetLastError ()));
        return 0;
    }
    return 1;
#endif                            /* WIN32 */
    return 0;
}
int main(VOID)
{
 HANDLE ReadHandle, WriteHandle;
 STARTUPINFO si;
 PROCESS_INFORMATION pi;
 char message[BUFFER_SIZE] = "Greetings";
 DWORD written;
 
 /* set up security attributes so that pipe handles are inherited */
 SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL,TRUE};

 /* allocate memory */
 ZeroMemory(&pi, sizeof(pi));
 
  /* create the pipe */
 if ( !CreatePipe(&ReadHandle, &WriteHandle, &sa, 0)) {
    fprintf(stderr,"Create Pipe Failed\n");
    return 1;
 }
  
 /* establish the START_INFO structure for the child process */
 GetStartupInfo(&si);
 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 
 /* redirect the standard input to the read end of the pipe */
 si.hStdInput = ReadHandle;
 si.dwFlags = STARTF_USESTDHANDLES;
 
 /* we do not want the child to inherit the write end of the pipe */
 SetHandleInformation( WriteHandle, HANDLE_FLAG_INHERIT, 0); 
 
 /* create the child process */
 if (!CreateProcess(NULL, 
                     ".\\child.exe",
                     NULL,
                     NULL,
                     TRUE, /* inherit handles */
                     0,
                     NULL,
                     NULL,
                     &si,
                     &pi))
  {
     fprintf(stderr, "Process Creation Failed\n");
     return -1;
  }
               
 /* close the unused end of the pipe */
 CloseHandle(ReadHandle);
       
 /* the parent now wants to write to the pipe */
 if (!WriteFile (WriteHandle, message, BUFFER_SIZE, &written, NULL))
    fprintf(stderr, "Error writing to pipe\n");
    
 /* close the write end of the pipe */
 CloseHandle(WriteHandle);

 /* wait for the child to exit */
 WaitForSingleObject(pi.hProcess, INFINITE);  

 /* close all handles */
 CloseHandle(pi.hProcess);
 CloseHandle(pi.hThread);                 
}
Пример #29
0
/* Start child program with redirected standard input and output */
int 
ijs_exec_server(const char *server_cmd, int *pfd_to, int *pfd_from, 
    int *pchild_pid)
{
    SECURITY_ATTRIBUTES saAttr;
    STARTUPINFO siStartInfo;
    LPVOID env;
    HANDLE hPipeTemp;
    HANDLE hChildStdinRd = INVALID_HANDLE_VALUE;
    HANDLE hChildStdinWr = INVALID_HANDLE_VALUE;
    HANDLE hChildStdoutRd = INVALID_HANDLE_VALUE;
    HANDLE hChildStdoutWr = INVALID_HANDLE_VALUE;
    PROCESS_INFORMATION piProcInfo;
    BOOL flag;
    int fd_stdin_wr = -1;
    int fd_stdout_rd = -1;

    /* Set the bInheritHandle flag so pipe handles are inherited. */
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    /* Create anonymous inheritable pipes for STDIN and STDOUT
     * for child. For each pipe, create a noninheritable duplicate handle
     * of our end of the pipe, then close the inheritable handle.
     * Do not redirect STDERR.
     */
    flag = CreatePipe(&hChildStdinRd, &hPipeTemp, &saAttr, 0);
    if (flag) {
        flag = DuplicateHandle(GetCurrentProcess(), hPipeTemp,
            GetCurrentProcess(), &hChildStdinWr, 0,
            FALSE,       /* not inherited */
            DUPLICATE_SAME_ACCESS);
	CloseHandle(hPipeTemp);
    }
    if (flag)
	flag = CreatePipe(&hPipeTemp, &hChildStdoutWr, &saAttr, 0);
    if (flag) {
        flag = DuplicateHandle(GetCurrentProcess(), hPipeTemp,
            GetCurrentProcess(), &hChildStdoutRd, 0,
            FALSE,       /* not inherited */
            DUPLICATE_SAME_ACCESS);
        CloseHandle(hPipeTemp);
    }
    if (flag)
	flag = (fd_stdin_wr = _open_osfhandle((LONG)hChildStdinWr, 0)) != -1;
    if (flag)
	flag = (fd_stdout_rd = _open_osfhandle((LONG)hChildStdoutRd, 0)) != -1;

    /* Now create the child process. */
    if (flag) {
	/* Set up members of STARTUPINFO structure. */
	siStartInfo.cb = sizeof(STARTUPINFO);
	siStartInfo.lpReserved = NULL;
	siStartInfo.lpDesktop = NULL;
	siStartInfo.lpTitle = NULL;  /* use executable name as title */
	siStartInfo.dwX = siStartInfo.dwY = CW_USEDEFAULT;	/* ignored */
	siStartInfo.dwXSize = siStartInfo.dwYSize = CW_USEDEFAULT;/* ignored */
	siStartInfo.dwXCountChars = 80;
	siStartInfo.dwYCountChars = 25;
	siStartInfo.dwFillAttribute = 0;			/* ignored */
	siStartInfo.dwFlags = STARTF_USESTDHANDLES;
#ifdef VERBOSE
	siStartInfo.wShowWindow = SW_SHOWNORMAL;
	siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
#else
	siStartInfo.wShowWindow = SW_HIDE;
#endif
	siStartInfo.cbReserved2 = 0;
	siStartInfo.lpReserved2 = NULL;
	siStartInfo.hStdInput  = hChildStdinRd;
	siStartInfo.hStdOutput = hChildStdoutWr;
	siStartInfo.hStdError  = GetStdHandle(STD_ERROR_HANDLE);

	env = NULL;

	/* Create the child process. */

	flag = CreateProcess(server_cmd,
	    NULL,  	   /* command line                       */
	    NULL,          /* process security attributes        */
	    NULL,          /* primary thread security attributes */
	    TRUE,          /* handles are inherited              */
	    0,             /* creation flags                     */
	    env,           /* environment                        */
	    NULL,          /* use parent's current directory     */
	    &siStartInfo,  /* STARTUPINFO pointer                */
	    &piProcInfo);  /* receives PROCESS_INFORMATION  */
	if (flag) {
	    CloseHandle(piProcInfo.hProcess);
	    CloseHandle(piProcInfo.hThread);
	}
    }

    if (hChildStdinRd != INVALID_HANDLE_VALUE)
        CloseHandle(hChildStdinRd);
    if (hChildStdoutWr != INVALID_HANDLE_VALUE)
	CloseHandle(hChildStdoutWr);

    if (flag) {
	*pfd_to = fd_stdin_wr;
	*pfd_from = fd_stdout_rd;
	*pchild_pid = (int)piProcInfo.dwProcessId;
    }
    else {
	if (fd_stdin_wr != -1)
	    close(fd_stdin_wr);
	else if (hChildStdinWr != INVALID_HANDLE_VALUE)
	    CloseHandle(hChildStdinWr);
	if (fd_stdout_rd != -1)
	    close(fd_stdout_rd);
	else if (hChildStdoutRd != INVALID_HANDLE_VALUE)
	    CloseHandle(hChildStdoutRd);
	return -1;
    }
    return flag ? 0 : -1;
}
Пример #30
0
bool PipeWindows::init(const string &enginePath) {
    initialized = false;

    SECURITY_ATTRIBUTES saAttr;

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = true;
    saAttr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) {
        fatal("StdoutRd CreatePipe");
        return initialized;
    }

    if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
        fatal("Stdout SetHandleInformation");
        return initialized;
    }

    if (!CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr, 0)) {
        fatal("StdoutRd err CreatePipe");
        return initialized;
    }

    if (!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) {
        fatal("Stderr SetHandleInformation");
        return initialized;
    }

    if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) {
        fatal("Stdin CreatePipe");
        return initialized;
    }

    if (!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) {
        fatal("Stdin SetHandleInformation");
        return initialized;
    }
    ///////////
    TCHAR szCmdline[1024];
    strcpy(szCmdline, enginePath.c_str());
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo;
    bool bSuccess = false;

    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));


    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.hStdError = g_hChildStd_ERR_Wr;
    siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
    siStartInfo.hStdInput = g_hChildStd_IN_Rd;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    bSuccess = CreateProcess(NULL, szCmdline,     // 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 (bSuccess) {
        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);
    }
    initialized = true;
    return initialized;

}