Example #1
0
void nt_execve_wrapped(char *prog, char**args, char**envir ) {

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    BOOL bRet;
    DWORD type=0;
    char *argv0;
    char **savedargs = args;
    unsigned int cmdsize,cmdlen;
    char *cmdstr ,*cmdend;
//	int rc=0; // unused variable
    int retries=0;
    int is_winnt;
    int hasdot=0;
    char myself[512];

    memset(&si,0,sizeof(si));

    /*
     * This memory is not freed because we are exec()ed and will
     * not be alive long.
     */

    /* This version avoids realloc in concat_args_and_quote, so it should be a little bit safer */
    /* cmdsize = 65500;
     * cmdstr= heap_alloc(cmdsize);
     */
    cmdsize = MAX_PATH << 2;
    cmdstr= heap_alloc(MAX_PATH<<2);

    is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS);

    /* replace /bin/sh with myself to be executed */
    if( strcmp(prog, "/bin/sh") == 0 ) {
        if (GetModuleFileName(GetModuleHandle(NULL),myself,512) <= 512) {
            prog = myself;
        }
    }

    cmdlen = copy_quote_and_fix_slashes(prog,cmdstr,&hasdot);

    cmdend = cmdstr + cmdlen;
    *cmdend = 0;

    if (!is_winnt) {
        argv0 = NULL;
        goto win95_directly_here;
    }
    else {
        argv0 = heap_alloc(MAX_PATH);
        wsprintf(argv0,"%s",prog);
    }

retry:

    bRet=GetBinaryType(argv0,&type);

    if (is_winnt && !bRet  ) {
        /* Don't append .EXE if it could be a script file */
        if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
            try_shell_ex(args,1);
            errno = ENOEXEC;
            return;
        }
        else if (retries) {
            /* If argv[0] got parsed as \\foo (stupid paths with '/' as one
             * of the components will do it,) and if argv[1] is not the same,
             * then this is not a real UNC name.
             * In other cases, argv[0] and argv[1] here must be the same
             * anyway. -amol 5/1/6/98
             */
            if (
                ( (*prog == '\\') ||(*prog == '/') ) &&
                ( (prog[1] == '\\') ||(prog[1] == '/') ) &&
                ((*args[0] == *prog) && (args[0][1] == prog[1])) &&
                (!args[1])
            )
                try_shell_ex(args,1);
            errno  = ENOENT;
        }
        if (retries > 2) {
            return;
        }
        if (retries == 0) {
            wsprintf(argv0,"%s.EXE",prog);
            retries++;
        }
        else if (prog[0] == '\\' && retries == 1) {
            char ptr[80];
            if(GetEnvironmentVariable("ZSHROOT",ptr,80)) {
                wsprintf(argv0,"%s%s",ptr,prog);
            }
            retries++;
        }
        else if (prog[0] == '\\' && retries == 2) {
            char ptr[80];
            if(GetEnvironmentVariable("ZSHROOT",ptr,80)) {
                wsprintf(argv0,"%s%s.EXE",ptr,prog);
            }
            retries++;
        }
        else
            retries += 2;
        goto retry;
    }
    else if (bRet && retries > 0) { //re-fix argv0
        cmdlen = copy_quote_and_fix_slashes(argv0,cmdstr,&hasdot);

        cmdend = cmdstr + cmdlen;
        *cmdend = 0;
    }

win95_directly_here:

    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdInput = (HANDLE)_get_osfhandle(0);
    si.hStdOutput = (HANDLE)_get_osfhandle(1);
    si.hStdError = (HANDLE)_get_osfhandle(2);

    *args++; // ignore argv[0];

    concat_args_and_quote(args,&cmdstr,&cmdlen,&cmdend,&cmdsize);
    *cmdend = 0;
    if (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS) {
        if (!SetConsoleCtrlHandler(NULL,FALSE)) {
            errno = ENOENT;
        }
    }
    fix_path_for_child();

    if (cmdlen < 1000)
        dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr);
    if (!CreateProcess(argv0,
                       cmdstr,
                       NULL,
                       NULL,
                       TRUE, // need this for redirecting std handles
                       0,
                       NULL,//envcrap,
                       NULL,
                       &si,
                       &pi) ) {

        if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
            try_shell_ex(savedargs,1);
            errno  = ENOEXEC;
        }
        else if (GetLastError() == ERROR_INVALID_PARAMETER) {
            /* exceeded command line */
            errno = ENAMETOOLONG;
        }
        else
            errno  = ENOENT;
    }
    else {
        errno= 0;
        //
        {
            DWORD exitcode=0;
            int gui_app = 0;
            if (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS) {
                SetConsoleCtrlHandler(NULL,TRUE);
            }
            if (isset(WINNTWAITFORGUIAPPS))
                gui_app = 0;
            else if (is_winnt)
                gui_app = is_gui(argv0);
            else
                gui_app = is_9x_gui(prog);

            if (!gui_app) {
                WaitForSingleObject(pi.hProcess,INFINITE);
            }
            (void)GetExitCodeProcess(pi.hProcess,&exitcode);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            ExitProcess(exitcode);
        }
    }
}
Example #2
0
void nt_execve(char *prog, char**args, char**envir ) {

	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	HANDLE htemp;
	BOOL bRet;
    DWORD type=0;
	DWORD dwCreationflags;
	unsigned int priority;
	char *argv0;
	char *cmdstr, *cmdend ;
	char *originalPtr;
	unsigned int cmdsize,cmdlen;
    char *p2;
	char **savedargs;
	int retries=0;
	int hasdot =0;
	int is_winnt ;

	memset(&si,0,sizeof(si));
	savedargs = args;

	/* 
	 * This memory is not freed because we are exec()ed and will
	 * not be alive long.
	 */
	originalPtr = cmdstr= heap_alloc(MAX_PATH<<2);

	is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS);


	cmdsize = MAX_PATH<<2;

	p2 = cmdstr;

	cmdlen = 0;
	cmdlen += copy_quote_and_fix_slashes(prog,cmdstr,&hasdot);

	p2 += cmdlen;

	/* If the command was not quoted ,
	  skip initial character we left for quote */
	if (*cmdstr != '"') {
		*cmdstr = 'A';
		cmdstr++; 
		cmdsize--;
	}
	*p2 = 0;
	cmdend = p2;


	if (!is_winnt){
		argv0 = NULL;
		goto win95_directly_here;
	}
	else {
		argv0 = heap_alloc(MAX_PATH); /* not freed */
		wsprintf(argv0,"%s",prog);
	}

retry:

	bRet=GetBinaryType(argv0,&type);
	dprintf("binary type for %s is %d\n",argv0,bRet);
	//
	// For NT, append .EXE and retry
	//
	if (is_winnt && !bRet ) {
        /* Don't append .EXE if it could be a script file */
		if (GetLastError() == ERROR_BAD_EXE_FORMAT){
			errno = ENOEXEC;
			if (!__nt_only_start_exes)
				try_shell_ex(args,1,FALSE); //can't throw on error
			return;
		}
		else if ( retries ){
			if (
				( (argv0[0] == '\\') ||(argv0[0] == '/') ) &&
				( (argv0[1] == '\\') ||(argv0[1] == '/') ) &&
				(!args[1])
			   )
				if (!__nt_only_start_exes)
					try_shell_ex(args,1,FALSE);
			errno  = ENOENT;
		}
		if (retries > 1){
			return;
		}
		// Try uppercase once and then lower case
		//
		if (!retries)
			wsprintf(argv0,"%s.exe",prog);
		else 
			wsprintf(argv0,"%s.EXE",prog); /* fix for clearcase */
		retries++;
		goto retry;
	}

win95_directly_here:

	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESTDHANDLES;
	htemp= (HANDLE)_get_osfhandle(0);
	DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
						&si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS);
	htemp= (HANDLE)_get_osfhandle(1);
	DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
						&si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS);
	htemp= (HANDLE)_get_osfhandle(2);
	DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
						&si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS);



	*args++; // the first arg is the command


	dprintf("nt_execve calling c_a_a_q");
	if(!concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend,
				&cmdsize))
	{
        dprintf("concat_args_and_quote failed\n");
		heap_free(originalPtr);
		errno = ENOMEM;
		goto fail_return;
	}

	*cmdend = 0;

	dwCreationflags = GetPriorityClass(GetCurrentProcess());
	if (__nt_child_nohupped) {
		dwCreationflags |= DETACHED_PROCESS;
	}
	priority = GetThreadPriority(GetCurrentThread());

	(void)fix_path_for_child();

	if (is_winnt)
		dwCreationflags |= CREATE_SUSPENDED;


re_cp:
	dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr);
	bRet = CreateProcessA(argv0, cmdstr,
			NULL, NULL,
			TRUE, // need this for redirecting std handles
			dwCreationflags,
			NULL, NULL,
			&si,
			&pi);
	if (!bRet){
		if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
			if (!__nt_only_start_exes)
				try_shell_ex(savedargs,1,FALSE);
			errno  = ENOEXEC;
		}
		else if (GetLastError() == ERROR_INVALID_PARAMETER) {
			/* can't get invalid parameter, so this must be
			 *  the case when we exceed the command length limit.
			 */
			errno = ENAMETOOLONG;
		}
		else {
			errno  = ENOENT;
		}
		if (!is_winnt && !hasdot) { //append '.' to the end if needed
			lstrcat(cmdstr,".");
			hasdot=1;
			goto re_cp;
		}
	}
	else{
		int gui_app ;
		char guivar[50];

		if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50))
			gui_app=0;
		else {
			if (is_winnt || hasdot)
				gui_app= is_gui(argv0);
			else
				gui_app = is_9x_gui(prog);
		}

		if (is_winnt && !SetThreadPriority(pi.hThread,priority) ) {
			priority =GetLastError();
		}
		if (is_winnt)
			ResumeThread(pi.hThread);
		errno= 0;
		
		if (__nt_really_exec||__nt_child_nohupped || gui_app){
			ExitProcess(0);
		}
		else {
			DWORD exitcode=0;
			WaitForSingleObject(pi.hProcess,INFINITE);
			(void)GetExitCodeProcess(pi.hProcess,&exitcode);
			CloseHandle(pi.hProcess);
			CloseHandle(pi.hThread);
			/*
			 * If output was redirected to /dev/clipboard,
			 * we need to close the pipe handles
			 */
			if (is_dev_clipboard_active) {
				CloseHandle((HANDLE)_get_osfhandle(0));
				CloseHandle((HANDLE)_get_osfhandle(1));
				CloseHandle((HANDLE)_get_osfhandle(2));
				CloseHandle(si.hStdInput);
				CloseHandle(si.hStdOutput);
				CloseHandle(si.hStdError);
				WaitForSingleObject(ghdevclipthread,60*1000);
			}
			ExitProcess(exitcode);
		}
	}
fail_return:
    CloseHandle(si.hStdInput);
    CloseHandle(si.hStdOutput);
    CloseHandle(si.hStdError);
    return;
}