_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; }
/*** *char *getenv(option) - search environment for a string * *Purpose: * searches the environment for a string of the form "option=value", * if found, return value, otherwise NULL. * *Entry: * const char *option - variable to search for in environment * *Exit: * returns the value part of the environment string if found, * otherwise NULL * *Exceptions: * *******************************************************************************/ #ifdef _MT #ifdef WPRFLAG wchar_t * __cdecl _wgetenv ( #else /* WPRFLAG */ char * __cdecl getenv ( #endif /* WPRFLAG */ const _TSCHAR *option ) { _TSCHAR *retval; _mlock(_ENV_LOCK); #ifdef WPRFLAG retval = _wgetenv_lk(option); #else /* WPRFLAG */ retval = _getenv_lk(option); #endif /* WPRFLAG */ _munlock(_ENV_LOCK); return(retval); } #ifdef WPRFLAG wchar_t * __cdecl _wgetenv_lk ( #else /* WPRFLAG */ char * __cdecl _getenv_lk ( #endif /* WPRFLAG */ const _TSCHAR *option ) #else /* _MT */ #ifdef WPRFLAG wchar_t * __cdecl _wgetenv ( #else /* WPRFLAG */ char * __cdecl getenv ( #endif /* WPRFLAG */ const _TSCHAR *option ) #endif /* _MT */ { _TSCHAR **search = _tenviron; unsigned int length; #ifndef CRTDLL /* * Make sure the environment is initialized. */ if ( !__env_initialized ) return NULL; #endif /* CRTDLL */ /* * At startup, we obtain the 'native' flavor of environment strings * from the OS. So a "main" program has _environ and a "wmain" has * _wenviron loaded at startup. Only when the user gets or puts the * 'other' flavor do we convert it. */ #ifdef WPRFLAG if (!search && _environ) { /* don't have requested type, but other exists, so convert it */ if (__mbtow_environ() != 0) return NULL; /* now requested type exists */ search = _wenviron; } #else /* WPRFLAG */ if (!search && _wenviron) { /* don't have requested type, but other exists, so convert it */ if (__wtomb_environ() != 0) return NULL; /* now requested type exists */ search = _environ; } #endif /* WPRFLAG */ if (search && option) { length = _tcslen(option); /* ** Make sure `*search' is long enough to be a candidate ** (We must NOT index past the '\0' at the end of `*search'!) ** and that it has an equal sign (`=') in the correct spot. ** If both of these requirements are met, compare the strings. */ while (*search) { if (_tcslen(*search) > length && (*(*search + length) == _T('=')) && (_tcsnicoll(*search, option, length) == 0)) { return(*search + length + 1); } search++; } } return(NULL); }
int __cdecl __crtsetenv ( #endif const _TSCHAR *option, const int primary ) { int ix; int remove; /* 1 if variable is to be removed */ _TSCHAR **env; _TSCHAR *name, *value; const _TSCHAR *equal; /* * check that the option string is valid, find the equal sign * and verify '=' is not the first character in string. */ if ( (option == NULL) || ((equal = _tcschr(option, _T('='))) == NULL) || option == equal) return(-1); /* if the character following '=' is null, we are removing the * the environment variable. Otherwise, we are adding or updating * an environment variable. */ remove = (*(equal + 1) == _T('\0')); /* * the first time _[w]putenv() is called, copy the environment * block that was passed to [w]main to avoid making a * dangling pointer if the block is re-alloced. */ #ifdef WPRFLAG if (_wenviron == __winitenv) _wenviron = copy_environ(_wenviron); #else if (_environ == __initenv) _environ = copy_environ(_environ); #endif /* see if requested environment array exists */ if (_tenviron == NULL) { /* * The requested type of environment does not exist. * See if other type exists, if so convert it to requested type. * The functions that convert the enviroment (__mbtow_environ and * __wtomb_environ) will call this function (__crt[w]setenv) once * for each of the pre-existing environment variables. To avoid * an infinite loop, test the primary flag. */ #ifdef WPRFLAG if (primary && _environ) { if (__mbtow_environ() != 0) return -1; } #else if (primary && _wenviron) { if (__wtomb_environ() != 0) return -1; } #endif else { /* nothing to remove, return */ if ( remove ) return 0; else { /* create ones that do not exist */ if (_environ == NULL) { if ( (_environ = _malloc_crt(sizeof(char *))) == NULL) return -1; *_environ = NULL; } if (_wenviron == NULL) { if ( (_wenviron = _malloc_crt(sizeof(wchar_t *))) == NULL) return -1; *_wenviron = NULL; } } } } /* * At this point, the two types of environments are in sync (as much * as they can be anyway). The only way they can get out of sync * (besides users directly modifiying the environment) is if there * are conversion problems: If the user sets two Unicode EVs, * "foo1" and "foo2" and converting then to multibyte yields "foo?" * and "foo?", then the environment blocks will differ. */ /* init env pointers */ env = _tenviron; /* See if the string is already in the environment */ #ifdef WPRFLAG ix = wfindenv(option, equal - option); #else ix = findenv(option, equal - option); #endif if ((ix >= 0) && (*env != NULL)) { /* String is already in the environment - overwrite/remove it */ if (remove) { /* free the string being removed */ _free_crt(env[ix]); /* removing -- move all the later strings up */ for ( ; env[ix] != NULL; ++ix) { env[ix] = env[ix+1]; } /* shrink the environment memory block (ix now has number of strings, including NULL) -- this realloc probably can't fail, since we're shrinking a mem block, but we're careful anyway. */ if (env = (_TSCHAR **) _realloc_crt(env, ix * sizeof(_TSCHAR *))) _tenviron = env; } else { /* replace the option */ env[ix] = (_TSCHAR *) option; } } else { /* * String is NOT in the environment */ if ( !remove ) { /* * Append the string to the environ table. Note that * table must be grown to do this. */ if (ix < 0) ix = -ix; /* ix = length of environ table */ if ( (env = (_TSCHAR **)_realloc_crt(env, sizeof(_TSCHAR *) * (ix + 2))) == NULL ) return -1; env[ix] = (_TSCHAR *)option; env[ix + 1] = NULL; _tenviron = env; } else /* * We are asked to remove an environment var that * isn't there...just return success */ return 0; } /* * Update the OS environment. Don't give an error if this fails * since the failure will not affect the user unless he/she is making * direct API calls. Only need to do this for one type, OS converts * to other type automatically. */ if ( primary && (name = (_TSCHAR *)_malloc_crt((_tcslen(option) + 2) * sizeof(_TSCHAR))) != NULL ) { _tcscpy(name, option); value = name + (equal - option); *value++ = _T('\0'); SetEnvironmentVariable(name, remove ? NULL : value); _free_crt(name); } return 0; }