示例#1
0
_CRTIMP int __cdecl __wgetmainargs (
        int *pargc,
        wchar_t ***pargv,
        wchar_t ***penvp,
        int dowildcard,
        _startupinfo * startinfo)
{
        int ret;

        /* set global new mode flag */
        _newmode = startinfo->newmode;

#if !defined(_CRT_APP) || defined(_KERNELX)
        if ( dowildcard )
            ret = __wsetargv(); /* do wildcard expansion after parsing args */
        else
#endif /* !defined(_CRT_APP) || defined(_KERNELX) */ 
            ret = _wsetargv();  /* NO wildcard expansion; just parse args */
        if (ret < 0)
#ifdef _SYSCRT
            ExitProcess(-1);      // Failed to parse the cmdline - bail
#else  /* _SYSCRT */
            return ret;
#endif  /* _SYSCRT */

        *pargc = __argc;
        *pargv = __wargv;

        /*
         * if wide environment does not already exist,
         * create it from multibyte environment
         */
#if !defined(_CRT_APP) || defined(_KERNELX)
        if (!_wenviron)
        {
            _wenvptr=__crtGetEnvironmentStringsW();

            if (_wsetenvp() < 0)
            {
                __mbtow_environ();
            }
        }

        *penvp = _wenviron;
#endif /* !defined(_CRT_APP) || defined(_KERNELX) */

        return ret;
}
示例#2
0
int __cdecl _cenvarg (
#endif
	const _TSCHAR * const *argv,
	const _TSCHAR * const *envp,
	_TSCHAR **argblk,
	_TSCHAR **envblk,
	const _TSCHAR *name
	)
{
	REG1 const _TSCHAR * const *vp;
	REG2 unsigned tmp;
	REG3 _TSCHAR *cptr;
	unsigned arg_len;
	int cfi_len;		/* counts the number of file handles in CFI */

	/*
	 * Null environment pointer "envp" means use global variable,
	 * "_environ"
	 */

	int cwd_start;
	int cwd_end;		/* length of "cwd" strings in environment */

	/*
	 * Allocate space for command line string
	 *  tmp counts the number of bytes in the command line string
	 *	including spaces between arguments
	 *  An empty string is special -- 2 bytes
	 */

	for (vp = argv, tmp = 2; *vp; tmp += _tcslen(*vp++) + 1)
		if( tmp > ENV_MAX )
			break;

	/*
	 * Make sure there are not already > 32 KB in strings
	 */

	if ((arg_len = tmp) >= ENV_MAX / sizeof(_TSCHAR)) {
		*envblk = NULL;
		errno = E2BIG;
		_doserrno = E_badenv;
		return(-1);
	}

	/*
	 * Allocate space for the command line plus 2 null bytes
	 */

	if ( (*argblk = _malloc_crt(tmp * sizeof(_TSCHAR))) == NULL)
        {
		*envblk = NULL;
		errno = ENOMEM;
		_doserrno = E_nomem;
		return(-1);
	}

	/*
	 * Allocate space for environment strings
	 *  tmp counts the number of bytes in the environment strings
	 *	including nulls between strings
	 *  Also add "_C_FILE_INFO=" string
	 */
	if (envp)
		for (vp = envp, tmp = 2; *vp; tmp += _tcslen(*vp++) + 1)
			if( tmp > ENV_MAX )
				break;
        /*
	 * The _osfile and _osfhnd arrays are passed as binary data in
	 * dospawn.c
	 */
	cfi_len = 0;	/* no _C_FILE_INFO */

	if (!envp)
                *envblk = NULL;
	else {
		/*
		 * Now that we've decided to pass our own environment block,
		 * compute the size of the "current directory" strings to
		 * propagate to the new environment.
		 */

#ifdef WPRFLAG
            /*
             * Make sure wide environment exists.
             */
            if (!_wenvptr)
            {
		    if ((_wenvptr = (wchar_t *)__crtGetEnvironmentStringsW()) == NULL)
                    return -1;
            }
#endif

            /*
		 * search for the first one
		 */
		for (cwd_start = 0;
		     _tenvptr[cwd_start] != _T('\0') &&
		       _tenvptr[cwd_start] != _T('=');
		     cwd_start += _tcslen(&_tenvptr[cwd_start]) + 1)
		{
		}

		/* find the total size of all contiguous ones */
		cwd_end = cwd_start;
		while (_tenvptr[cwd_end+0] == _T('=') &&
		       _tenvptr[cwd_end+1] != _T('\0') &&
		       _tenvptr[cwd_end+2] == _T(':') &&
		       _tenvptr[cwd_end+3] == _T('='))
		{
			cwd_end += 4 + _tcslen(&_tenvptr[cwd_end+4]) + 1;
		}
		tmp += cwd_end - cwd_start;

		/*
		 * Check for too many strings to be placed in the environment
		 * Increment tmp for final null byte after environment strings
		 * "tmp + arg_len + _tcslen(name) + 1" must also be < ENV_MAX
		 */
		if( (long) tmp + arg_len + _tcslen(name) > (ENV_MAX - 1) / sizeof(_TSCHAR) ) {
			_free_crt(*argblk);
			*argblk = NULL;
			errno = E2BIG;
			_doserrno = E_badenv;
			return(-1);
		}

		/*
		 * Allocate space for the environment strings plus extra null byte
		 */
		if( !(*envblk = _malloc_crt(tmp * sizeof(_TSCHAR))) )
            {
			_free_crt(*argblk);
			*argblk = NULL;
			errno = ENOMEM;
			_doserrno = E_nomem;
			return(-1);
		}

        }

	/*
	 * Build the command line by concatenating the argument strings
	 * with spaces between, and two null bytes at the end.
	 * NOTE: The argv[0] argument is followed by a null.
	 */

	cptr = *argblk;
	vp = argv;

	if (!*vp)	/* Empty argument list ? */
		++cptr; /* just two null bytes */
	else {		/* argv[0] must be followed by a null */
		_tcscpy(cptr, *vp);
		cptr += _tcslen(*vp++) + 1;
	}

	while( *vp ) {
		_tcscpy(cptr, *vp);
		cptr += _tcslen(*vp++);
		*cptr++ = ' ';
	}

	*cptr = cptr[ -1 ] = _T('\0'); /* remove extra blank, add double null */

	/*
	 * Build the environment block by concatenating the environment
	 * strings with nulls between and two null bytes at the end
	 */

	cptr = *envblk;

	if (envp != NULL) {
		/*
		 * Copy the "cwd" strings to the new environment.
		 */
		memcpy(cptr, &_tenvptr[cwd_start], (cwd_end - cwd_start) * sizeof(_TSCHAR));
		cptr += cwd_end - cwd_start;

		/*
		 * Copy the environment strings from "envp".
		 */
		vp = envp;
		while( *vp ) {
			_tcscpy(cptr, *vp);
			cptr += 1 + _tcslen(*vp++);
		}
	}

	if (cptr != NULL) {
		if (cptr == *envblk) {
			/*
			 * Empty environment block ... this requires two
			 * nulls.
			 */
			*cptr++ = _T('\0');
		}
		/*
		 * Extra null terminates the segment
		 */
		*cptr = _T('\0');
	}

	return(0);
}
示例#3
0
/***
*int _cenvarg(argv, envp, argblk, envblk, name) - set up cmd line/environ
*
*Purpose:
*       Set up the block forms of  the environment and the command line.
*       If "envp" is null, "_environ" is used instead.
*
*Entry:
*       _TSCHAR **argv   - argument vector
*       _TSCHAR **envp   - environment vector
*       _TSCHAR **argblk - pointer to pointer set to malloc'ed space for args
*       _TSCHAR **envblk - pointer to pointer set to malloc'ed space for env
*       _TSCHAR *name    - name of program being invoked
*
*Exit:
*       returns 0 if ok, -1 if fails
*       stores through argblk and envblk
*       (calls malloc)
*
*Exceptions:
*
*******************************************************************************/

#ifdef WPRFLAG
int __cdecl _wcenvarg (
#else  /* WPRFLAG */
int __cdecl _cenvarg (
#endif  /* WPRFLAG */
        const _TSCHAR * const *argv,
        const _TSCHAR * const *envp,
        _TSCHAR **argblk,
        _TSCHAR **envblk,
        const _TSCHAR *name
        )
{
        REG1 const _TSCHAR * const *vp;
        REG2 unsigned tmp;
        REG3 _TSCHAR *cptr;
        unsigned arg_len;
        unsigned env_len;
        int cfi_len;            /* counts the number of file handles in CFI */
        int retval = 0;

        /*
         * Null environment pointer "envp" means use global variable,
         * "_environ"
         */

        int cwd_start;
        int cwd_end;            /* length of "cwd" strings in environment */

        _TSCHAR envpfx[] = _T("SystemRoot");
        _TSCHAR *envbuf = NULL;
        int envsize = 0;
        int defined = 0;

        /*
         * Allocate space for command line string
         *  tmp counts the number of bytes in the command line string
         *      including spaces between arguments
         *  An empty string is special -- 2 bytes
         */

        for (vp = argv, tmp = 2; *vp; tmp += (unsigned int)_tcslen(*vp++) + 1) ;

        arg_len = tmp;

        /*
         * Allocate space for the command line plus 2 null bytes
         */

        if ( (*argblk = _calloc_crt(tmp, sizeof(_TSCHAR))) == NULL)
        {
                *envblk = NULL;
                errno = ENOMEM;
                _doserrno = E_nomem;
                return(-1);
        }

        if (_ERRCHECK_EINVAL(_tdupenv_s_crt(&envbuf, NULL, envpfx)) != 0)
        {
                retval = -1;
                goto error;
        }

        envsize = (int)_tcslen(envpfx) + 2;
        if (envbuf != NULL)
        {
            envsize += (int)_tcslen(envbuf);
        }

        /*
         * Allocate space for environment strings
         *  tmp counts the number of bytes in the environment strings
         *      including nulls between strings
         *  Also add "_C_FILE_INFO=" string
         */
        if (envp)
                for (vp = envp, tmp = 2; *vp; tmp += (unsigned int)_tcslen(*vp++) + 1) ;

        /*
         * The _osfile and _osfhnd arrays are passed as binary data in
         * dospawn.c
         */
        cfi_len = 0;    /* no _C_FILE_INFO */

        if (!envp)
                *envblk = NULL;
        else {
                /*
                 * Now that we've decided to pass our own environment block,
                 * compute the size of the "current directory" strings to
                 * propagate to the new environment.
                 */

#ifdef WPRFLAG
                /*
                 * Make sure wide environment exists.
                 */
                if (!_wenvptr)
                {
                        if ((_wenvptr = (wchar_t *)__crtGetEnvironmentStringsW()) == NULL)
                        {
                                retval = -1;
                                goto error;
                        }
                }
#else  /* WPRFLAG */
                if (!_aenvptr)
                {
                        if ((_aenvptr = (char *)__crtGetEnvironmentStringsA()) == NULL)
                        {
                                retval = -1;
                                goto error;
                        }
                }
#endif  /* WPRFLAG */

                /*
                 * search for the first one
                 */
                for (cwd_start = 0;
                     _tenvptr[cwd_start] != _T('\0') &&
                       _tenvptr[cwd_start] != _T('=');
                     cwd_start += (int)_tcslen(&_tenvptr[cwd_start]) + 1)
                {
                }

                /* find the total size of all contiguous ones */
                cwd_end = cwd_start;
                while (_tenvptr[cwd_end+0] == _T('=') &&
                       _tenvptr[cwd_end+1] != _T('\0') &&
                       _tenvptr[cwd_end+2] == _T(':') &&
                       _tenvptr[cwd_end+3] == _T('='))
                {
                        cwd_end += 4 + (int)_tcslen(&_tenvptr[cwd_end+4]) + 1;
                }
                tmp += cwd_end - cwd_start;

                /*
                 * Allocate space for the environment strings plus extra null byte
                 */
                env_len = tmp;

                /*
                 * Check if SystemRoot is already defined in environment provided
                 */
                for (vp = envp; *vp; vp++) {
                        if (_tcsncicmp(*vp, envpfx, _tcslen(envpfx)) == 0) {
                                defined = 1;
                                break;
                        }
                }

                if (!defined)
                        tmp += envsize;

                if( !(*envblk = _calloc_crt(tmp, sizeof(_TSCHAR))) )
                {
                        _free_crt(*argblk);
                        *argblk = NULL;
                        errno = ENOMEM;
                        _doserrno = E_nomem;
                        retval = -1;
                        goto done;
                }
        }

        /*
         * Build the command line by concatenating the argument strings
         * with spaces between, and two null bytes at the end.
         * NOTE: The argv[0] argument is followed by a null.
         */

        cptr = *argblk;
        vp = argv;

        if (!*vp)       /* Empty argument list ? */
                ++cptr; /* just two null bytes */
        else {          /* argv[0] must be followed by a null */
                _ERRCHECK(_tcscpy_s(cptr, arg_len - (cptr - *argblk), *vp));
                cptr += (int)_tcslen(*vp++) + 1;
        }

        while( *vp ) {
                _ERRCHECK(_tcscpy_s(cptr, arg_len - (cptr - *argblk), *vp));
                cptr += (int)_tcslen(*vp++);
                *cptr++ = ' ';
        }

        *cptr = cptr[ -1 ] = _T('\0'); /* remove extra blank, add double null */

        /*
         * Build the environment block by concatenating the environment
         * strings with nulls between and two null bytes at the end
         */

        cptr = *envblk;

        if (envp != NULL) {
                /*
                 * Copy the "cwd" strings to the new environment.
                 */
                memcpy(cptr, &_tenvptr[cwd_start], (cwd_end - cwd_start) * sizeof(_TSCHAR));
                cptr += cwd_end - cwd_start;

                /*
                 * Copy the environment strings from "envp".
                 */
                vp = envp;
                while( *vp ) {
                        _ERRCHECK(_tcscpy_s(cptr, env_len - (cptr - *envblk), *vp));
                        cptr += 1 + (int)_tcslen(*vp++);
                }

                if (!defined) {
                        /*
                         * Copy SystemRoot to the new environment.
                         */
                        _ERRCHECK(_tcscpy_s(cptr, envsize, envpfx));
                        _ERRCHECK(_tcscat_s(cptr, envsize, _T("=")));
                        if (envbuf != NULL)
                        {
                            _ERRCHECK(_tcscat_s(cptr, envsize, envbuf));
                        }
                        cptr += envsize;
                }
        }

        if (cptr != NULL) {
                if (cptr == *envblk) {
                        /*
                         * Empty environment block ... this requires two
                         * nulls.
                         */
                        *cptr++ = _T('\0');
                }
                /*
                 * Extra null terminates the segment
                 */
                *cptr = _T('\0');
        }

        goto done;

error:
        _free_crt(*argblk);
        *argblk = NULL;
        *envblk = NULL;

done:

#ifdef WPRFLAG
        if (_wenvptr)
                _free_crt(_wenvptr);
        _wenvptr = NULL;
#else  /* WPRFLAG */
        if (_aenvptr)
                _free_crt(_aenvptr);
        _aenvptr = NULL;
#endif  /* WPRFLAG */
        if (envbuf)
                _free_crt(envbuf);

        return retval;
}