Back to home page

Wine source

 
 

    


File indexing completed on 2023-03-03 23:04:43

1db20bfd3 Jon *0001 /*
                0002  * msvcrt.dll environment functions
                0003  *
                0004  * Copyright 1996,1998 Marcus Meissner
                0005  * Copyright 1996 Jukka Iivonen
                0006  * Copyright 1997,2000 Uwe Bonnes
                0007  * Copyright 2000 Jon Griffiths
0799c1a78 Alex*0008  *
                0009  * This library is free software; you can redistribute it and/or
                0010  * modify it under the terms of the GNU Lesser General Public
                0011  * License as published by the Free Software Foundation; either
                0012  * version 2.1 of the License, or (at your option) any later version.
                0013  *
                0014  * This library is distributed in the hope that it will be useful,
                0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                0017  * Lesser General Public License for more details.
                0018  *
                0019  * You should have received a copy of the GNU Lesser General Public
                0020  * License along with this library; if not, write to the Free Software
360a3f914 Jona*0021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
1db20bfd3 Jon *0022  */
                0023 #include "msvcrt.h"
bd1689ec0 Alex*0024 #include "wine/debug.h"
                0025 
                0026 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
1db20bfd3 Jon *0027 
b7a586771 Piot*0028 static char * getenv_helper(const char *name)
1db20bfd3 Jon *0029 {
eeada5682 Piot*0030     char **env;
86fb5c7ba Piot*0031     size_t len;
                0032 
b7a586771 Piot*0033     if (!name) return NULL;
86fb5c7ba Piot*0034     len = strlen(name);
1db20bfd3 Jon *0035 
eeada5682 Piot*0036     for (env = MSVCRT__environ; *env; env++)
b48d81243 Alex*0037     {
eeada5682 Piot*0038         char *str = *env;
b48d81243 Alex*0039         char *pos = strchr(str,'=');
86fb5c7ba Piot*0040         if (pos && ((pos - str) == len) && !_strnicmp(str, name, len))
b48d81243 Alex*0041         {
                0042             TRACE("(%s): got %s\n", debugstr_a(name), debugstr_a(pos + 1));
                0043             return pos + 1;
                0044         }
                0045     }
                0046     return NULL;
1db20bfd3 Jon *0047 }
                0048 
b7a586771 Piot*0049 /*********************************************************************
                0050  *              getenv (MSVCRT.@)
                0051  */
                0052 char * CDECL getenv(const char *name)
                0053 {
                0054     if (!MSVCRT_CHECK_PMT(name != NULL)) return NULL;
                0055 
                0056     return getenv_helper(name);
                0057 }
                0058 
667d889d3 Piot*0059 static wchar_t * wgetenv_helper(const wchar_t *name)
1db20bfd3 Jon *0060 {
eeada5682 Piot*0061     wchar_t **env;
d812af3f1 Piot*0062     size_t len;
                0063 
667d889d3 Piot*0064     if (!name) return NULL;
d812af3f1 Piot*0065     len = wcslen(name);
1db20bfd3 Jon *0066 
eb0947287 Andr*0067     /* Initialize the _wenviron array if it's not already created. */
                0068     if (!MSVCRT__wenviron)
                0069         MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(NULL);
                0070 
eeada5682 Piot*0071     for (env = MSVCRT__wenviron; *env; env++)
b48d81243 Alex*0072     {
eeada5682 Piot*0073         wchar_t *str = *env;
6ad42ee7f Piot*0074         wchar_t *pos = wcschr(str,'=');
d812af3f1 Piot*0075         if (pos && ((pos - str) == len) && !_wcsnicmp(str, name, len))
b48d81243 Alex*0076         {
                0077             TRACE("(%s): got %s\n", debugstr_w(name), debugstr_w(pos + 1));
                0078             return pos + 1;
                0079         }
                0080     }
                0081     return NULL;
1db20bfd3 Jon *0082 }
34c786b2d Jon *0083 
667d889d3 Piot*0084 /*********************************************************************
                0085  *              _wgetenv (MSVCRT.@)
                0086  */
                0087 wchar_t * CDECL _wgetenv(const wchar_t *name)
                0088 {
                0089     if (!MSVCRT_CHECK_PMT(name != NULL)) return NULL;
                0090 
                0091     return wgetenv_helper(name);
                0092 }
                0093 
34c786b2d Jon *0094 /*********************************************************************
                0095  *      _putenv (MSVCRT.@)
                0096  */
24beabfd4 Alex*0097 int CDECL _putenv(const char *str)
34c786b2d Jon *0098 {
35a9398ff qing*0099  char *name, *value;
                0100  char *dst;
2f61c4a1b Uwe *0101  int ret;
34c786b2d Jon *0102 
330978ec9 qing*0103  TRACE("%s\n", debugstr_a(str));
34c786b2d Jon *0104 
                0105  if (!str)
                0106    return -1;
35a9398ff qing*0107    
                0108  name = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
                0109  if (!name)
                0110    return -1;
                0111  dst = name;
34c786b2d Jon *0112  while (*str && *str != '=')
                0113   *dst++ = *str++;
                0114  if (!*str++)
35a9398ff qing*0115  {
                0116    ret = -1;
                0117    goto finish;
                0118  }
                0119  *dst++ = '\0';
                0120  value = dst;
34c786b2d Jon *0121  while (*str)
                0122   *dst++ = *str++;
                0123  *dst = '\0';
                0124 
ad4a00d35 Mike*0125  ret = SetEnvironmentVariableA(name, value[0] ? value : NULL) ? 0 : -1;
                0126 
4d801b66e Fran*0127  /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
ad4a00d35 Mike*0128  if ((ret == -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0;
                0129 
285e6d249 Andr*0130  MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
                0131  /* Update the __p__wenviron array only when already initialized */
7c15ae127 Alex*0132  if (MSVCRT__wenviron)
                0133    MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
35a9398ff qing*0134    
                0135 finish:
                0136  HeapFree(GetProcessHeap(), 0, name);
2f61c4a1b Uwe *0137  return ret;
34c786b2d Jon *0138 }
                0139 
                0140 /*********************************************************************
                0141  *      _wputenv (MSVCRT.@)
                0142  */
c302397c7 Piot*0143 int CDECL _wputenv(const wchar_t *str)
34c786b2d Jon *0144 {
c302397c7 Piot*0145  wchar_t *name, *value;
                0146  wchar_t *dst;
2f61c4a1b Uwe *0147  int ret;
34c786b2d Jon *0148 
                0149  TRACE("%s\n", debugstr_w(str));
                0150 
                0151  if (!str)
                0152    return -1;
6ad42ee7f Piot*0153  name = HeapAlloc(GetProcessHeap(), 0, (wcslen(str) + 1) * sizeof(wchar_t));
35a9398ff qing*0154  if (!name)
                0155    return -1;
                0156  dst = name;
5f31b3294 Alex*0157  while (*str && *str != '=')
34c786b2d Jon *0158   *dst++ = *str++;
                0159  if (!*str++)
35a9398ff qing*0160  {
                0161    ret = -1;
                0162    goto finish;
                0163  }
                0164  *dst++ = 0;
                0165  value = dst;
34c786b2d Jon *0166  while (*str)
                0167   *dst++ = *str++;
5f31b3294 Alex*0168  *dst = 0;
34c786b2d Jon *0169 
ad4a00d35 Mike*0170  ret = SetEnvironmentVariableW(name, value[0] ? value : NULL) ? 0 : -1;
                0171 
4d801b66e Fran*0172  /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
ad4a00d35 Mike*0173  if ((ret == -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0;
                0174 
285e6d249 Andr*0175  MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
                0176  MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
35a9398ff qing*0177 
                0178 finish:
                0179  HeapFree(GetProcessHeap(), 0, name);
2f61c4a1b Uwe *0180  return ret;
34c786b2d Jon *0181 }
356b2d2bc Eric*0182 
                0183 /*********************************************************************
                0184  *      _putenv_s (MSVCRT.@)
                0185  */
1f657729e Alex*0186 errno_t CDECL _putenv_s(const char *name, const char *value)
356b2d2bc Eric*0187 {
53acb6e73 Piot*0188     errno_t ret = 0;
356b2d2bc Eric*0189 
                0190     TRACE("%s %s\n", debugstr_a(name), debugstr_a(value));
                0191 
53acb6e73 Piot*0192     if (!MSVCRT_CHECK_PMT(name != NULL)) return EINVAL;
                0193     if (!MSVCRT_CHECK_PMT(value != NULL)) return EINVAL;
356b2d2bc Eric*0194 
53acb6e73 Piot*0195     if (!SetEnvironmentVariableA(name, value[0] ? value : NULL))
                0196     {
                0197         /* _putenv returns success on deletion of nonexistent variable */
                0198         if (GetLastError() != ERROR_ENVVAR_NOT_FOUND)
                0199         {
                0200             msvcrt_set_errno(GetLastError());
                0201             ret = *_errno();
                0202         }
                0203     }
356b2d2bc Eric*0204 
                0205     MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
                0206     MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
                0207 
                0208     return ret;
                0209 }
                0210 
                0211 /*********************************************************************
                0212  *      _wputenv_s (MSVCRT.@)
                0213  */
f0e6447b7 Piot*0214 errno_t CDECL _wputenv_s(const wchar_t *name, const wchar_t *value)
356b2d2bc Eric*0215 {
f0e6447b7 Piot*0216     errno_t ret = 0;
356b2d2bc Eric*0217 
                0218     TRACE("%s %s\n", debugstr_w(name), debugstr_w(value));
                0219 
f943d4497 Piot*0220     if (!MSVCRT_CHECK_PMT(name != NULL)) return EINVAL;
                0221     if (!MSVCRT_CHECK_PMT(value != NULL)) return EINVAL;
356b2d2bc Eric*0222 
f0e6447b7 Piot*0223     if (!SetEnvironmentVariableW(name, value[0] ? value : NULL))
                0224     {
                0225         /* _putenv returns success on deletion of nonexistent variable */
                0226         if (GetLastError() != ERROR_ENVVAR_NOT_FOUND)
                0227         {
                0228             msvcrt_set_errno(GetLastError());
                0229             ret = *_errno();
                0230         }
                0231     }
356b2d2bc Eric*0232 
                0233     MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
                0234     MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
                0235 
                0236     return ret;
                0237 }
fc186c3bd Eric*0238 
00fe56a73 Alex*0239 #if _MSVCR_VER>=80
                0240 
fc186c3bd Eric*0241 /******************************************************************
00fe56a73 Alex*0242  *      _dupenv_s (MSVCR80.@)
fc186c3bd Eric*0243  */
fa272adae Piot*0244 int CDECL _dupenv_s(char **buffer, size_t *numberOfElements, const char *varname)
fc186c3bd Eric*0245 {
fa272adae Piot*0246     char *e;
                0247     size_t sz;
fc186c3bd Eric*0248 
1317b935e Piot*0249     if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
                0250     if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
06989a048 Alex*0251 
5a08eab30 Rémi*0252     if (!(e = getenv(varname)))
                0253     {
                0254         *buffer = NULL;
                0255         if (numberOfElements) *numberOfElements = 0;
                0256         return 0;
                0257     }
06989a048 Alex*0258 
fc186c3bd Eric*0259     sz = strlen(e) + 1;
d784dbb89 Piot*0260     if (!(*buffer = malloc(sz)))
fc186c3bd Eric*0261     {
                0262         if (numberOfElements) *numberOfElements = 0;
eeada5682 Piot*0263         return *_errno() = ENOMEM;
fc186c3bd Eric*0264     }
                0265     strcpy(*buffer, e);
                0266     if (numberOfElements) *numberOfElements = sz;
                0267     return 0;
                0268 }
                0269 
                0270 /******************************************************************
00fe56a73 Alex*0271  *      _wdupenv_s (MSVCR80.@)
fc186c3bd Eric*0272  */
fa272adae Piot*0273 int CDECL _wdupenv_s(wchar_t **buffer, size_t *numberOfElements,
c302397c7 Piot*0274                      const wchar_t *varname)
fc186c3bd Eric*0275 {
fa272adae Piot*0276     wchar_t *e;
                0277     size_t sz;
fc186c3bd Eric*0278 
1317b935e Piot*0279     if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
                0280     if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
06989a048 Alex*0281 
aafef01cc Rémi*0282     if (!(e = _wgetenv(varname)))
                0283     {
                0284         *buffer = NULL;
                0285         if (numberOfElements) *numberOfElements = 0;
                0286         return 0;
                0287     }
06989a048 Alex*0288 
6ad42ee7f Piot*0289     sz = wcslen(e) + 1;
d784dbb89 Piot*0290     if (!(*buffer = malloc(sz * sizeof(wchar_t))))
fc186c3bd Eric*0291     {
                0292         if (numberOfElements) *numberOfElements = 0;
eeada5682 Piot*0293         return *_errno() = ENOMEM;
fc186c3bd Eric*0294     }
6ad42ee7f Piot*0295     wcscpy(*buffer, e);
fc186c3bd Eric*0296     if (numberOfElements) *numberOfElements = sz;
                0297     return 0;
                0298 }
b0c3dc35a Eric*0299 
00fe56a73 Alex*0300 #endif /* _MSVCR_VER>=80 */
                0301 
b0c3dc35a Eric*0302 /******************************************************************
                0303  *      getenv_s (MSVCRT.@)
                0304  */
b7a586771 Piot*0305 int CDECL getenv_s(size_t *ret_len, char* buffer, size_t len, const char *varname)
b0c3dc35a Eric*0306 {
fa272adae Piot*0307     char *e;
b0c3dc35a Eric*0308 
b7a586771 Piot*0309     if (!MSVCRT_CHECK_PMT(ret_len != NULL)) return EINVAL;
                0310     *ret_len = 0;
                0311     if (!MSVCRT_CHECK_PMT((buffer && len > 0) || (!buffer && !len))) return EINVAL;
                0312     if (buffer) buffer[0] = 0;
                0313 
                0314     if (!(e = getenv_helper(varname))) return 0;
                0315     *ret_len = strlen(e) + 1;
                0316     if (!len) return 0;
                0317     if (len < *ret_len) return ERANGE;
06989a048 Alex*0318 
b0c3dc35a Eric*0319     strcpy(buffer, e);
                0320     return 0;
                0321 }
                0322 
                0323 /******************************************************************
                0324  *      _wgetenv_s (MSVCRT.@)
                0325  */
667d889d3 Piot*0326 int CDECL _wgetenv_s(size_t *ret_len, wchar_t *buffer, size_t len,
c302397c7 Piot*0327                      const wchar_t *varname)
b0c3dc35a Eric*0328 {
fa272adae Piot*0329     wchar_t *e;
b0c3dc35a Eric*0330 
667d889d3 Piot*0331     if (!MSVCRT_CHECK_PMT(ret_len != NULL)) return EINVAL;
                0332     *ret_len = 0;
                0333     if (!MSVCRT_CHECK_PMT((buffer && len > 0) || (!buffer && !len))) return EINVAL;
                0334     if (buffer) buffer[0] = 0;
                0335 
                0336     if (!(e = wgetenv_helper(varname))) return 0;
                0337     *ret_len = wcslen(e) + 1;
                0338     if (!len) return 0;
                0339     if (len < *ret_len) return ERANGE;
06989a048 Alex*0340 
6ad42ee7f Piot*0341     wcscpy(buffer, e);
b0c3dc35a Eric*0342     return 0;
                0343 }
f20be3b00 Mart*0344 
                0345 /*********************************************************************
                0346  *      _get_environ (MSVCRT.@)
                0347  */
9011b0b7c Piot*0348 void CDECL _get_environ(char ***ptr)
f20be3b00 Mart*0349 {
                0350     *ptr = MSVCRT__environ;
                0351 }
                0352 
                0353 /*********************************************************************
                0354  *      _get_wenviron (MSVCRT.@)
                0355  */
9011b0b7c Piot*0356 void CDECL _get_wenviron(wchar_t ***ptr)
f20be3b00 Mart*0357 {
                0358     *ptr = MSVCRT__wenviron;
                0359 }