Beispiel #1
0
int nt_texec(char *prog, char**args ) {

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

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

	/* MUST FREE !! */
	originalPtr = cmdstr= heap_alloc(MAX_PATH<<2);
	cmdsize = MAX_PATH<<2;

	is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS);


	p2 = cmdstr;

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

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

	if (!is_winnt) {
		argv0 = NULL;
	}
	else {
		argv0= heap_alloc(MAX_PATH);
		(void)StringCbPrintf(argv0,MAX_PATH,"%s",prog);
	}

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


	/* 
	   quotespace hack needed since execv() would have separated args, but
	   createproces doesnt
	   -amol 9/14/96
	 */

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

	dprintf("nt_texec calling c_a_a_q");
	if(concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend,&cmdsize) == NULL)
	{
		retval = 1;
		errno  = ENOMEM;
		heap_free(originalPtr);
		goto free_mem;
	}

	*cmdend = 0;

	dwCreationflags = GetPriorityClass(GetCurrentProcess());
	priority = GetThreadPriority(GetCurrentThread());

	if (is_winnt) {
		retries = 0;
		// For NT, try ShellExecuteEx first
		do {
			if (GetBinaryType(argv0,&type)) 
				break;
			if (GetLastError() == ERROR_BAD_EXE_FORMAT){
				errno = ENOEXEC;
				if (!__nt_only_start_exes)
					try_shell_ex(savedargs,0,FALSE);
				if (errno) {
					retval = 1; 
					goto free_mem;
				}
				else {
					retval = 0;
					goto free_mem;
				}
			}
			// only try shellex again after appending ".exe fails
			else if ( retries > 1 ){
				if (
						( (argv0[0] == '\\') ||(argv0[0] == '/') ) &&
						( (argv0[1] == '\\') ||(argv0[1] == '/') ) &&
						(!args[1])
				   )
					if (!__nt_only_start_exes)
						try_shell_ex(savedargs,0,FALSE);
				errno  = ENOENT;
			}
			if (retries == 0)
				(void)StringCbPrintf(argv0,MAX_PATH,"%s.exe",prog);
			else if (retries == 1) {
				(void)StringCbPrintf(argv0,MAX_PATH,"%s.EXE",prog);
			}
			retries++;
		}while(retries < 3);
	}
	savepath = fix_path_for_child();
re_cp:
	dprintf("nt_texec cmdstr %s\n",cmdstr);


	if (!CreateProcess(argv0,
				cmdstr,
				NULL,
				NULL,
				TRUE, // need this for redirecting std handles
				dwCreationflags,
				NULL,//envcrap,
				NULL,
				&si,
				&pi) ){

		if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
			errno  = ENOEXEC;
		}
		else if (GetLastError() == ERROR_INVALID_PARAMETER) {
			errno = ENAMETOOLONG;
		}else {
			errno  = ENOENT;
		}
		if (!is_winnt && !hasdot) { //append '.' to the end if needed
			StringCbCat(cmdstr,cmdsize,".");
			hasdot=1;
			goto re_cp;
		}
		retval = 1;
	}
	else{
		int gui_app ;
		DWORD exitcode;
		char guivar[50];


		if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50))
			gui_app=0;
		else
			gui_app= is_gui(argv0);

		if(!gui_app) {
			WaitForSingleObject(pi.hProcess,INFINITE);
			(void)GetExitCodeProcess(pi.hProcess,&exitcode);
			setv(STRstatus, putn(exitcode), VAR_READWRITE);/*FIXRESET*/
		}
		retval = 0;
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	}
free_mem:
	CloseHandle(si.hStdInput);
	CloseHandle(si.hStdOutput);
	CloseHandle(si.hStdError);

	if(savepath)
		restore_path(savepath);

	heap_free(originalPtr);
	if (argv0)
		heap_free(argv0);
	return retval;
}
Beispiel #2
0
void try_shell_ex(char **argv,int exitsuccess, BOOL throw_ok) {/*FIXRESET*/

	char *prog;
	char *cmdstr, *p2, *cmdend;
	char *originalPtr = NULL;
	unsigned int cmdsize,cmdlen;
	char err2[256];
	char *ptr;
	SHELLEXECUTEINFO shinfo;
	unsigned long  mask = SEE_MASK_FLAG_NO_UI;
	BOOL rc;
	char *extension;

	prog=*argv;

	dprintf("trying shellex for prog %s\n",prog);
	ptr = prog;
	if (!is_url(prog)) {

		while(*ptr) {
			if (*ptr == '/')
				*ptr = '\\';
			ptr++;
		}

		extension = ptr;

		// search back for "."
		while(extension != prog) {
			if (*extension == '.') {
				extension++;
				break;
			}
			else
				extension--;
		}
		/* check if this matches a member in the no_assoc array.
		 */
		if (extension != prog)  {
			if (find_no_assoc(extension))
				return;
		}

	}
	originalPtr = cmdstr= heap_alloc(MAX_PATH<<2);

	cmdsize = MAX_PATH<<2;

	p2 = cmdstr;

	cmdlen = 0;
	cmdend = p2;

	argv++; // the first arg is the command


	dprintf("try_shell_ex calling c_a_a_q");
	if(!concat_args_and_quote(argv,&originalPtr,&cmdstr,&cmdlen,&cmdend,&cmdsize))
	{
		errno = ENOMEM;
		heap_free(originalPtr);
		return;
	}

	*cmdend = 0;


	memset(&shinfo,0,sizeof(shinfo));
	shinfo.cbSize = sizeof(shinfo);
	shinfo.fMask = SEE_MASK_FLAG_DDEWAIT | mask;
	shinfo.hwnd = NULL;
	shinfo.lpVerb = NULL;
	shinfo.lpFile = prog;
	shinfo.lpParameters = &cmdstr[0];
	shinfo.lpDirectory = 0;
	shinfo.nShow = SW_SHOWDEFAULT;


	ptr = fix_path_for_child();

	rc = pShellExecuteEx(&shinfo);
	if (rc ) {
		if (exitsuccess) 
			ExitProcess(0);
		errno = 0;

		heap_free(originalPtr);
		return;
	}
	if (throw_ok) { 
		// if we got here, ShellExecuteEx failed, so reset() via stderror()
		// this may cause the caller to leak, but the assumption is that
		// only a child process sets exitsuccess, so it will be dead soon
		// anyway

		restore_path(ptr);

		make_err_str(GetLastError(),cmdstr,512);//don't need the full size
		(void)StringCbPrintf(err2,sizeof(err2),"%s",prog);
		stderror(ERR_SYSTEM,err2,cmdstr);/*FIXRESET*/
	}

	heap_free(originalPtr);
	restore_path(ptr);

	errno = ENOEXEC;

}
Beispiel #3
0
int nt_feed_to_cmd(char *file,char **argv) {

	char *ptr, *orig;
	char cmdbuf[128];
	HANDLE htemp;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	if (!file)
		return 1;

	ptr = strrchr(file,'.');

	if(!ptr)
		return 1;

	if (lstrlen(ptr) <4)
		return 1;

	if ( _stricmp(ptr,".bat") &&  _stricmp(ptr,".cmd") )
		return 1;


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

	si.cb = sizeof(si);
	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);


	ptr =file;
	while(*ptr) {
		if (*ptr == '/')
			*ptr = '\\';
		ptr++;
	}
	if (gdwPlatform == VER_PLATFORM_WIN32_WINDOWS){
		(void)StringCbPrintf(cmdbuf,sizeof(cmdbuf),
							 "command.com /c %s",file);
	}
	else
		(void)StringCbPrintf(cmdbuf,sizeof(cmdbuf),
							 "cmd /c %s",file);

	argv++;
	ptr = &cmdbuf[0] ;
	orig = ptr;
	while(*argv) {
		StringCbCat(ptr,sizeof(cmdbuf) - (orig - ptr), " ");
		StringCbCat(ptr,sizeof(cmdbuf) - (orig - ptr),*argv);
		argv++;
	}

	ptr = fix_path_for_child();

	if (!CreateProcess(NULL,
				cmdbuf,
				NULL,
				NULL,
				TRUE,
				0,//CREATE_NEW_CONSOLE |CREATE_NEW_PROCESS_GROUP,
				NULL,
				NULL,
				&si,
				&pi) ){
		restore_path(ptr);
	}
	else {

		restore_path(ptr);
		CloseHandle(pi.hThread);
		WaitForSingleObject(pi.hProcess,INFINITE);
		CloseHandle(pi.hProcess);
		ExitProcess(0);
	}

	return 1; /*NOTREACHED*/
}
Beispiel #4
0
void dostart(Char ** vc, struct command *c) {

	char *cmdstr,*cmdend,*ptr;
	char argv0[256];/*FIXBUF*/
	DWORD cmdsize;
	char *currdir=NULL;
	char *savepath;
	char **v = NULL;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	DWORD dwCreationFlags=CREATE_NEW_CONSOLE;
	DWORD k,cmdlen,j,jj,ret;


	UNREFERENCED_PARAMETER(c);
	vc++;

	cmdsize = 512;
	cmdstr = heap_alloc(cmdsize);
	cmdend = cmdstr;
	cmdlen = 0;

	memset(&si,0,sizeof(si));
	si.cb = sizeof(si);

	vc = glob_all_or_error(vc);
	v = short2blk(vc);
	if(v == NULL) {
		stderror(ERR_NOMEM);
		return;
	}
	blkfree(vc);
	for (k = 0; v[k] != NULL ; k++){

		if ( v[k][0] == '-' ) {
			/* various options */
			if( (v[k][1] == 'T') || (v[k][1] == 't'))
				si.lpTitle =&( v[k][2]);
			else if ( (v[k][1] == 'D') || (v[k][1] == 'd'))
				currdir =&( v[k][2]);
			else if (!_stricmp(&v[k][1],"MIN") )
				si.wShowWindow = SW_SHOWMINIMIZED;
			else if (!_stricmp(&v[k][1],"MAX") )
				si.wShowWindow = SW_SHOWMAXIMIZED;
			else if (!_stricmp(&v[k][1],"SEPARATE") )
				dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
			else if (!_stricmp(&v[k][1],"SHARED") )
				dwCreationFlags |= CREATE_SHARED_WOW_VDM;
			else if (!_stricmp(&v[k][1],"LOW") )
				dwCreationFlags |= IDLE_PRIORITY_CLASS;
			else if (!_stricmp(&v[k][1],"NORMAL") )
				dwCreationFlags |= NORMAL_PRIORITY_CLASS;
			else if (!_stricmp(&v[k][1],"HIGH") )
				dwCreationFlags |= HIGH_PRIORITY_CLASS;
			else if (!_stricmp(&v[k][1],"REALTIME") )
				dwCreationFlags |= REALTIME_PRIORITY_CLASS;
			else{
				blkfree((Char **)v);
				stderror(ERR_SYSTEM,start_usage,"See CMD.EXE for more info");/*FIXRESET*/
			}
		}
		else{ // non-option arg
			break;
		}
	}
	/* 
	 * Stop the insanity of requiring start "tcsh -l"
	 * Option processing now stops at first non-option arg
	 * -amol 5/30/96
	 */
	for (jj=k;v[jj] != NULL; jj++) {
		j=(lstrlen(v[jj]) + 2);
		if (j + cmdlen > cmdsize) {
			ptr = cmdstr;
			cmdstr = heap_realloc(cmdstr, max(cmdsize << 1, j+cmdlen) );
			if(!cmdstr)
			{
				heap_free(ptr);
				stderror(ERR_NOMEM,"start");/*FIXRESET*/
			}
			cmdend =  cmdstr + (cmdend - ptr);
			cmdsize <<= 1;
		}
		ptr = v[jj];
		while (*ptr) {
			*cmdend++ = *ptr++;
			cmdlen++;
		}
		*cmdend++ = ' ';
		cmdlen++;
	}
	if (jj == k) {
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,start_usage,"See CMD.EXE for more info");/*FIXRESET*/
		return;
	}
	*cmdend = 0;
	StringCbCopy(argv0,sizeof(argv0),v[k]);


	/* 
	 * strictly speaking, it should do no harm to set the path
	 * back to '\'-delimited even in the parent, but in the
	 * interest of consistency, we save the old value and restore it
	 * later
	 */

	savepath = fix_path_for_child();

	if (! CreateProcess(NULL,
				cmdstr,
				NULL,
				NULL,
				FALSE,
				dwCreationFlags,
				NULL,
				currdir,
				&si,
				&pi) ) {

		restore_path(savepath);

		ret = GetLastError();
		if (ret == ERROR_BAD_EXE_FORMAT || ret == ERROR_ACCESS_DENIED ||
				(ret == ERROR_FILE_NOT_FOUND && 
				 (is_url(v[k]) || is_directory(v[k]))
				) 
		   ) {

			char erbuf[MAX_PATH];

			errno = ENOEXEC;

			try_shell_ex(&v[k],0,FALSE);

			heap_free(cmdstr); /* free !! */

			if (errno) {
				strerror_s(erbuf,sizeof(erbuf),errno);
				stderror(ERR_ARCH,argv0,erbuf);/*FIXRESET*/
			}
		}
		else if (ret == ERROR_INVALID_PARAMETER) {

			errno = ENAMETOOLONG;

			heap_free(cmdstr); /* free !! */

			stderror(ERR_TOOLARGE,argv0);/*FIXRESET*/

		}
		else {
			errno = ENOENT;
			if (
					( (v[k][0] == '\\') ||(v[k][0] == '/') ) &&
					( (v[k][1] == '\\') ||(v[k][1] == '/') ) &&
					(!v[k+1])
			   )
				try_shell_ex(&v[k],0,FALSE);

			heap_free(cmdstr); /* free !! */
			if (errno) {
				stderror(ERR_NOTFOUND,argv0);/*FIXRESET*/
			}
		}
	}
	else {
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);

		heap_free(cmdstr);
		restore_path(savepath);
	}
	blkfree((Char **)v);
	return;
}
Beispiel #5
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);
        }
    }
}
Beispiel #6
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;
}