2 * msvcrt.dll environment functions
4 * Copyright 1996,1998 Marcus Meissner
5 * Copyright 1996 Jukka Iivonen
6 * Copyright 1997,2000 Uwe Bonnes
7 * Copyright 2000 Jon Griffiths
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt
);
28 /*********************************************************************
31 char * CDECL
getenv(const char *name
)
34 unsigned int length
=strlen(name
);
36 for (env
= MSVCRT__environ
; *env
; env
++)
39 char *pos
= strchr(str
,'=');
40 if (pos
&& ((pos
- str
) == length
) && !_strnicmp(str
,name
,length
))
42 TRACE("(%s): got %s\n", debugstr_a(name
), debugstr_a(pos
+ 1));
49 /*********************************************************************
52 wchar_t * CDECL
_wgetenv(const wchar_t *name
)
55 unsigned int length
=wcslen(name
);
57 /* Initialize the _wenviron array if it's not already created. */
58 if (!MSVCRT__wenviron
)
59 MSVCRT__wenviron
= msvcrt_SnapshotOfEnvironmentW(NULL
);
61 for (env
= MSVCRT__wenviron
; *env
; env
++)
64 wchar_t *pos
= wcschr(str
,'=');
65 if (pos
&& ((pos
- str
) == length
) && !_wcsnicmp(str
,name
,length
))
67 TRACE("(%s): got %s\n", debugstr_w(name
), debugstr_w(pos
+ 1));
74 /*********************************************************************
77 int CDECL
_putenv(const char *str
)
83 TRACE("%s\n", debugstr_a(str
));
88 name
= HeapAlloc(GetProcessHeap(), 0, strlen(str
) + 1);
92 while (*str
&& *str
!= '=')
105 ret
= SetEnvironmentVariableA(name
, value
[0] ? value
: NULL
) ? 0 : -1;
107 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
108 if ((ret
== -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND
)) ret
= 0;
110 MSVCRT__environ
= msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ
);
111 /* Update the __p__wenviron array only when already initialized */
112 if (MSVCRT__wenviron
)
113 MSVCRT__wenviron
= msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron
);
116 HeapFree(GetProcessHeap(), 0, name
);
120 /*********************************************************************
121 * _wputenv (MSVCRT.@)
123 int CDECL
_wputenv(const wchar_t *str
)
125 wchar_t *name
, *value
;
129 TRACE("%s\n", debugstr_w(str
));
133 name
= HeapAlloc(GetProcessHeap(), 0, (wcslen(str
) + 1) * sizeof(wchar_t));
137 while (*str
&& *str
!= '=')
150 ret
= SetEnvironmentVariableW(name
, value
[0] ? value
: NULL
) ? 0 : -1;
152 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
153 if ((ret
== -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND
)) ret
= 0;
155 MSVCRT__environ
= msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ
);
156 MSVCRT__wenviron
= msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron
);
159 HeapFree(GetProcessHeap(), 0, name
);
163 /*********************************************************************
164 * _putenv_s (MSVCRT.@)
166 int CDECL
_putenv_s(const char *name
, const char *value
)
170 TRACE("%s %s\n", debugstr_a(name
), debugstr_a(value
));
172 if (!MSVCRT_CHECK_PMT(name
!= NULL
)) return -1;
173 if (!MSVCRT_CHECK_PMT(value
!= NULL
)) return -1;
175 ret
= SetEnvironmentVariableA(name
, value
[0] ? value
: NULL
) ? 0 : -1;
177 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
178 if ((ret
== -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND
)) ret
= 0;
180 MSVCRT__environ
= msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ
);
181 MSVCRT__wenviron
= msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron
);
186 /*********************************************************************
187 * _wputenv_s (MSVCRT.@)
189 int CDECL
_wputenv_s(const wchar_t *name
, const wchar_t *value
)
193 TRACE("%s %s\n", debugstr_w(name
), debugstr_w(value
));
195 if (!MSVCRT_CHECK_PMT(name
!= NULL
)) return -1;
196 if (!MSVCRT_CHECK_PMT(value
!= NULL
)) return -1;
198 ret
= SetEnvironmentVariableW(name
, value
[0] ? value
: NULL
) ? 0 : -1;
200 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
201 if ((ret
== -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND
)) ret
= 0;
203 MSVCRT__environ
= msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ
);
204 MSVCRT__wenviron
= msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron
);
211 /******************************************************************
212 * _dupenv_s (MSVCR80.@)
214 int CDECL
_dupenv_s(char **buffer
, size_t *numberOfElements
, const char *varname
)
219 if (!MSVCRT_CHECK_PMT(buffer
!= NULL
)) return EINVAL
;
220 if (!MSVCRT_CHECK_PMT(varname
!= NULL
)) return EINVAL
;
222 if (!(e
= getenv(varname
))) return *_errno() = EINVAL
;
225 if (!(*buffer
= malloc(sz
)))
227 if (numberOfElements
) *numberOfElements
= 0;
228 return *_errno() = ENOMEM
;
231 if (numberOfElements
) *numberOfElements
= sz
;
235 /******************************************************************
236 * _wdupenv_s (MSVCR80.@)
238 int CDECL
_wdupenv_s(wchar_t **buffer
, size_t *numberOfElements
,
239 const wchar_t *varname
)
244 if (!MSVCRT_CHECK_PMT(buffer
!= NULL
)) return EINVAL
;
245 if (!MSVCRT_CHECK_PMT(varname
!= NULL
)) return EINVAL
;
247 if (!(e
= _wgetenv(varname
))) return *_errno() = EINVAL
;
250 if (!(*buffer
= malloc(sz
* sizeof(wchar_t))))
252 if (numberOfElements
) *numberOfElements
= 0;
253 return *_errno() = ENOMEM
;
256 if (numberOfElements
) *numberOfElements
= sz
;
260 #endif /* _MSVCR_VER>=80 */
262 /******************************************************************
263 * getenv_s (MSVCRT.@)
265 int CDECL
getenv_s(size_t *pReturnValue
, char* buffer
, size_t numberOfElements
, const char *varname
)
269 if (!MSVCRT_CHECK_PMT(pReturnValue
!= NULL
)) return EINVAL
;
270 if (!MSVCRT_CHECK_PMT(!(buffer
== NULL
&& numberOfElements
> 0))) return EINVAL
;
271 if (!MSVCRT_CHECK_PMT(varname
!= NULL
)) return EINVAL
;
273 if (!(e
= getenv(varname
)))
276 return *_errno() = EINVAL
;
278 *pReturnValue
= strlen(e
) + 1;
279 if (numberOfElements
< *pReturnValue
)
281 return *_errno() = ERANGE
;
287 /******************************************************************
288 * _wgetenv_s (MSVCRT.@)
290 int CDECL
_wgetenv_s(size_t *pReturnValue
, wchar_t *buffer
, size_t numberOfElements
,
291 const wchar_t *varname
)
295 if (!MSVCRT_CHECK_PMT(pReturnValue
!= NULL
)) return EINVAL
;
296 if (!MSVCRT_CHECK_PMT(!(buffer
== NULL
&& numberOfElements
> 0))) return EINVAL
;
297 if (!MSVCRT_CHECK_PMT(varname
!= NULL
)) return EINVAL
;
299 if (!(e
= _wgetenv(varname
)))
302 return *_errno() = EINVAL
;
304 *pReturnValue
= wcslen(e
) + 1;
305 if (numberOfElements
< *pReturnValue
)
307 return *_errno() = ERANGE
;
313 /*********************************************************************
314 * _get_environ (MSVCRT.@)
316 void CDECL
_get_environ(char ***ptr
)
318 *ptr
= MSVCRT__environ
;
321 /*********************************************************************
322 * _get_wenviron (MSVCRT.@)
324 void CDECL
_get_wenviron(wchar_t ***ptr
)
326 *ptr
= MSVCRT__wenviron
;