Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenenviron.c
Go to the documentation of this file.
00001 /* 00002 * environ.c 00003 * 00004 * ReactOS MSVCRT.DLL Compatibility Library 00005 */ 00006 00007 #include <precomp.h> 00008 #include <internal/wine/msvcrt.h> 00009 00010 unsigned int _osplatform = 0; 00011 unsigned int _osver = 0; 00012 unsigned int _winminor = 0; 00013 unsigned int _winmajor = 0; 00014 unsigned int _winver = 0; 00015 00016 unsigned int __setlc_active = 0; 00017 unsigned int __unguarded_readlc_active = 0; 00018 char *_acmdln = NULL; /* pointer to ascii command line */ 00019 wchar_t *_wcmdln = NULL; /* pointer to wide character command line */ 00020 #undef _environ 00021 #undef _wenviron 00022 char **_environ = NULL; /* pointer to environment block */ 00023 wchar_t **_wenviron = NULL; /* pointer to environment block */ 00024 char **__initenv = NULL; /* pointer to initial environment block */ 00025 wchar_t **__winitenv = NULL; /* pointer to initial environment block */ 00026 #undef _pgmptr 00027 char *_pgmptr = NULL; /* pointer to program name */ 00028 #undef _wpgmptr 00029 wchar_t *_wpgmptr = NULL; /* pointer to program name */ 00030 int __app_type = _UNKNOWN_APP; /* application type */ 00031 int _commode = _IOCOMMIT; 00032 00033 00034 int BlockEnvToEnvironA(void) 00035 { 00036 char *ptr, *environment_strings; 00037 char **envptr; 00038 int count = 1; 00039 size_t len; 00040 00041 TRACE("BlockEnvToEnvironA()\n"); 00042 00043 environment_strings = GetEnvironmentStringsA(); 00044 if (environment_strings == NULL) { 00045 return -1; 00046 } 00047 00048 for (ptr = environment_strings; *ptr; ptr += len) 00049 { 00050 len = strlen(ptr) + 1; 00051 /* Skip drive letter settings. */ 00052 if (*ptr != '=') 00053 count++; 00054 } 00055 00056 __initenv = _environ = malloc(count * sizeof(char*)); 00057 if (_environ) 00058 { 00059 for (ptr = environment_strings, envptr = _environ; count > 1; ptr += len) 00060 { 00061 len = strlen(ptr) + 1; 00062 /* Skip drive letter settings. */ 00063 if (*ptr != '=') 00064 { 00065 if ((*envptr = malloc(len)) == NULL) 00066 { 00067 for (envptr--; envptr >= _environ; envptr--); 00068 free(*envptr); 00069 FreeEnvironmentStringsA(environment_strings); 00070 free(_environ); 00071 __initenv = _environ = NULL; 00072 return -1; 00073 } 00074 memcpy(*envptr++, ptr, len); 00075 count--; 00076 } 00077 } 00078 /* Add terminating NULL entry. */ 00079 *envptr = NULL; 00080 } 00081 00082 FreeEnvironmentStringsA(environment_strings); 00083 return _environ ? 0 : -1; 00084 } 00085 00086 int BlockEnvToEnvironW(void) 00087 { 00088 wchar_t *ptr, *environment_strings; 00089 wchar_t **envptr; 00090 int count = 1; 00091 size_t len; 00092 00093 TRACE("BlockEnvToEnvironW()\n"); 00094 00095 environment_strings = GetEnvironmentStringsW(); 00096 if (environment_strings == NULL) { 00097 return -1; 00098 } 00099 00100 for (ptr = environment_strings; *ptr; ptr += len) 00101 { 00102 len = wcslen(ptr) + 1; 00103 /* Skip drive letter settings. */ 00104 if (*ptr != '=') 00105 count++; 00106 } 00107 00108 __winitenv = _wenviron = malloc(count * sizeof(wchar_t*)); 00109 if (_wenviron) 00110 { 00111 for (ptr = environment_strings, envptr = _wenviron; count > 1; ptr += len) 00112 { 00113 len = wcslen(ptr) + 1; 00114 /* Skip drive letter settings. */ 00115 if (*ptr != '=') 00116 { 00117 if ((*envptr = malloc(len * sizeof(wchar_t))) == NULL) 00118 { 00119 for (envptr--; envptr >= _wenviron; envptr--); 00120 free(*envptr); 00121 FreeEnvironmentStringsW(environment_strings); 00122 free(_wenviron); 00123 __winitenv = _wenviron = NULL; 00124 return -1; 00125 } 00126 memcpy(*envptr++, ptr, len * sizeof(wchar_t)); 00127 count--; 00128 } 00129 } 00130 /* Add terminating NULL entry. */ 00131 *envptr = NULL; 00132 } 00133 00134 FreeEnvironmentStringsW(environment_strings); 00135 return _wenviron ? 0 : -1; 00136 } 00137 00151 char **DuplicateEnvironment(char **original_environment, int wide) 00152 { 00153 int count = 1; 00154 char **envptr, **newenvptr, **newenv; 00155 00156 for (envptr = original_environment; *envptr != NULL; envptr++, count++) 00157 ; 00158 00159 newenvptr = newenv = malloc(count * sizeof(char*)); 00160 if (newenv == NULL) 00161 return original_environment; 00162 00163 for (envptr = original_environment; count > 1; newenvptr++, count--) 00164 { 00165 if (wide) 00166 *newenvptr = (char*)_wcsdup((wchar_t*)*envptr++); 00167 else 00168 *newenvptr = _strdup(*envptr++); 00169 if (*newenvptr == NULL) 00170 { 00171 for (newenvptr--; newenvptr >= newenv; newenvptr--); 00172 free(*newenvptr); 00173 free(newenv); 00174 return original_environment; 00175 } 00176 } 00177 *newenvptr = NULL; 00178 00179 return newenv; 00180 } 00181 00190 void FreeEnvironment(char **environment) 00191 { 00192 char **envptr; 00193 for (envptr = environment; *envptr != NULL; envptr++) 00194 free(*envptr); 00195 free(environment); 00196 } 00197 00210 int SetEnv(const wchar_t *option) 00211 { 00212 wchar_t *epos, *name; 00213 wchar_t **wenvptr; 00214 wchar_t *woption; 00215 char *mboption; 00216 int remove, index, count, size, result = 0, found = 0; 00217 00218 if (option == NULL || (epos = wcschr(option, L'=')) == NULL) 00219 return -1; 00220 remove = (epos[1] == 0); 00221 00222 /* Duplicate environment if needed. */ 00223 if (_environ == __initenv) 00224 { 00225 if ((_environ = DuplicateEnvironment(_environ, 0)) == __initenv) 00226 return -1; 00227 } 00228 if (_wenviron == __winitenv) 00229 { 00230 if ((_wenviron = (wchar_t**)DuplicateEnvironment((char**)_wenviron, 1)) == 00231 __winitenv) 00232 return -1; 00233 } 00234 00235 /* Create a copy of the option name. */ 00236 name = malloc((epos - option + 1) * sizeof(wchar_t)); 00237 if (name == NULL) 00238 return -1; 00239 memcpy(name, option, (epos - option) * sizeof(wchar_t)); 00240 name[epos - option] = 0; 00241 00242 /* Find the option we're trying to modify. */ 00243 for (index = 0, wenvptr = _wenviron; *wenvptr != NULL; wenvptr++, index++) 00244 { 00245 if (!_wcsnicmp(*wenvptr, option, epos - option)) 00246 { 00247 found = 1; 00248 break; 00249 } 00250 } 00251 00252 if (remove) 00253 { 00254 if (!found) 00255 { 00256 free(name); 00257 return 0; 00258 } 00259 00260 /* Remove the option from wide character environment. */ 00261 free(*wenvptr); 00262 for (count = index; *wenvptr != NULL; wenvptr++, count++) 00263 *wenvptr = *(wenvptr + 1); 00264 _wenviron = realloc(_wenviron, count * sizeof(wchar_t*)); 00265 00266 /* Remove the option from multibyte environment. We assume 00267 * the environments are in sync and the option is at the 00268 * same position. */ 00269 free(_environ[index]); 00270 memmove(&_environ[index], &_environ[index+1], (count - index) * sizeof(char*)); 00271 _environ = realloc(_environ, count * sizeof(char*)); 00272 00273 result = SetEnvironmentVariableW(name, NULL) ? 0 : -1; 00274 } 00275 else 00276 { 00277 /* Make a copy of the option that we will store in the environment block. */ 00278 woption = _wcsdup((wchar_t*)option); 00279 if (woption == NULL) 00280 { 00281 free(name); 00282 return -1; 00283 } 00284 00285 /* Create a multibyte copy of the option. */ 00286 size = WideCharToMultiByte(CP_ACP, 0, option, -1, NULL, 0, NULL, NULL); 00287 mboption = malloc(size); 00288 if (mboption == NULL) 00289 { 00290 free(name); 00291 free(woption); 00292 return -1; 00293 } 00294 WideCharToMultiByte(CP_ACP, 0, option, -1, mboption, size, NULL, NULL); 00295 00296 if (found) 00297 { 00298 /* Replace the current entry. */ 00299 free(*wenvptr); 00300 *wenvptr = woption; 00301 free(_environ[index]); 00302 _environ[index] = mboption; 00303 } 00304 else 00305 { 00306 wchar_t **wnewenv; 00307 char **mbnewenv; 00308 00309 /* Get the size of the original environment. */ 00310 for (count = index; *wenvptr != NULL; wenvptr++, count++) 00311 ; 00312 00313 /* Create a new entry. */ 00314 if ((wnewenv = realloc(_wenviron, (count + 2) * sizeof(wchar_t*))) == NULL) 00315 { 00316 free(name); 00317 free(mboption); 00318 free(woption); 00319 return -1; 00320 } 00321 _wenviron = wnewenv; 00322 if ((mbnewenv = realloc(_environ, (count + 2) * sizeof(char*))) == NULL) 00323 { 00324 free(name); 00325 free(mboption); 00326 free(woption); 00327 return -1; 00328 } 00329 _environ = mbnewenv; 00330 00331 /* Set the last entry to our option. */ 00332 _wenviron[count] = woption; 00333 _environ[count] = mboption; 00334 _wenviron[count + 1] = NULL; 00335 _environ[count + 1] = NULL; 00336 } 00337 00338 /* And finally update the OS environment. */ 00339 result = SetEnvironmentVariableW(name, epos + 1) ? 0 : -1; 00340 } 00341 free(name); 00342 00343 return result; 00344 } 00345 00346 /* 00347 * @implemented 00348 */ 00349 int *__p__commode(void) // not exported by NTDLL 00350 { 00351 return &_commode; 00352 } 00353 00354 /* 00355 * @implemented 00356 */ 00357 void __set_app_type(int app_type) 00358 { 00359 __app_type = app_type; 00360 } 00361 00362 /* 00363 * @implemented 00364 */ 00365 char **__p__acmdln(void) 00366 { 00367 return &_acmdln; 00368 } 00369 00370 /* 00371 * @implemented 00372 */ 00373 wchar_t **__p__wcmdln(void) 00374 { 00375 return &_wcmdln; 00376 } 00377 00378 /* 00379 * @implemented 00380 */ 00381 char ***__p__environ(void) 00382 { 00383 return &_environ; 00384 } 00385 00386 /* 00387 * @implemented 00388 */ 00389 wchar_t ***__p__wenviron(void) 00390 { 00391 return &_wenviron; 00392 } 00393 00394 /* 00395 * @implemented 00396 */ 00397 char ***__p___initenv(void) 00398 { 00399 return &__initenv; 00400 } 00401 00402 /* 00403 * @implemented 00404 */ 00405 wchar_t ***__p___winitenv(void) 00406 { 00407 return &__winitenv; 00408 } 00409 00410 /* 00411 * @implemented 00412 */ 00413 errno_t _get_osplatform(unsigned int *pValue) 00414 { 00415 if (!MSVCRT_CHECK_PMT(pValue != NULL)) { 00416 *_errno() = EINVAL; 00417 return EINVAL; 00418 } 00419 00420 *pValue = _osplatform; 00421 return 0; 00422 } 00423 00424 /* 00425 * @implemented 00426 */ 00427 int *__p___mb_cur_max(void) 00428 { 00429 return &__mb_cur_max; 00430 } 00431 00432 /* 00433 * @implemented 00434 */ 00435 unsigned int *__p__osver(void) 00436 { 00437 return &_osver; 00438 } 00439 00440 /* 00441 * @implemented 00442 */ 00443 char **__p__pgmptr(void) 00444 { 00445 return &_pgmptr; 00446 } 00447 00448 /* 00449 * @implemented 00450 */ 00451 int _get_pgmptr(char** p) 00452 { 00453 if (!MSVCRT_CHECK_PMT(p)) 00454 { 00455 *_errno() = EINVAL; 00456 return EINVAL; 00457 } 00458 00459 *p = _pgmptr; 00460 return 0; 00461 } 00462 00463 /* 00464 * @implemented 00465 */ 00466 wchar_t **__p__wpgmptr(void) 00467 { 00468 return &_wpgmptr; 00469 } 00470 00471 /* 00472 * @implemented 00473 */ 00474 int _get_wpgmptr(WCHAR** p) 00475 { 00476 if (!MSVCRT_CHECK_PMT(p)) 00477 { 00478 *_errno() = EINVAL; 00479 return EINVAL; 00480 } 00481 00482 *p = _wpgmptr; 00483 return 0; 00484 } 00485 00486 /* 00487 * @implemented 00488 */ 00489 unsigned int *__p__winmajor(void) 00490 { 00491 return &_winmajor; 00492 } 00493 00494 /* 00495 * @implemented 00496 */ 00497 unsigned int *__p__winminor(void) 00498 { 00499 return &_winminor; 00500 } 00501 00502 /* 00503 * @implemented 00504 */ 00505 unsigned int *__p__winver(void) 00506 { 00507 return &_winver; 00508 } 00509 00510 /* EOF */ Generated on Sun May 27 2012 04:24:25 for ReactOS by
1.7.6.1
|