3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/env.c
6 * PURPOSE: Environment functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
15 #include "../include/debug.h"
18 /* FUNCTIONS ******************************************************************/
25 GetEnvironmentVariableA (
33 UNICODE_STRING VarNameU
;
34 UNICODE_STRING VarValueU
;
37 /* initialize unicode variable name string */
38 RtlInitAnsiString (&VarName
,
40 RtlAnsiStringToUnicodeString (&VarNameU
,
44 /* initialize ansi variable value string */
46 VarValue
.MaximumLength
= nSize
;
47 VarValue
.Buffer
= lpBuffer
;
49 /* initialize unicode variable value string and allocate buffer */
53 VarValueU
.MaximumLength
= (nSize
- 1) * sizeof(WCHAR
);
54 VarValueU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
56 nSize
* sizeof(WCHAR
));
57 if (VarValueU
.Buffer
!= NULL
)
59 /* NULL-terminate the buffer in any case! RtlQueryEnvironmentVariable_U
60 only terminates it if MaximumLength < Length! */
61 VarValueU
.Buffer
[nSize
- 1] = L
'\0';
66 VarValueU
.MaximumLength
= 0;
67 VarValueU
.Buffer
= NULL
;
70 if (VarValueU
.Buffer
!= NULL
|| nSize
== 0)
72 /* get unicode environment variable */
73 Status
= RtlQueryEnvironmentVariable_U (NULL
,
76 if (!NT_SUCCESS(Status
))
78 /* free unicode buffer */
79 RtlFreeHeap (RtlGetProcessHeap (),
83 /* free unicode variable name string */
84 RtlFreeUnicodeString (&VarNameU
);
86 SetLastErrorByStatus (Status
);
87 if (Status
== STATUS_BUFFER_TOO_SMALL
)
89 return (VarValueU
.Length
/ sizeof(WCHAR
)) + 1;
97 /* convert unicode value string to ansi */
98 RtlUnicodeStringToAnsiString (&VarValue
,
102 if (VarValueU
.Buffer
!= NULL
)
104 /* free unicode buffer */
105 RtlFreeHeap (RtlGetProcessHeap (),
110 /* free unicode variable name string */
111 RtlFreeUnicodeString (&VarNameU
);
113 return (VarValueU
.Length
/ sizeof(WCHAR
));
117 SetLastError (ERROR_NOT_ENOUGH_MEMORY
);
128 GetEnvironmentVariableW (
134 UNICODE_STRING VarName
;
135 UNICODE_STRING VarValue
;
138 RtlInitUnicodeString (&VarName
,
142 VarValue
.MaximumLength
= (nSize
!= 0 ? (nSize
- 1) * sizeof(WCHAR
) : 0);
143 VarValue
.Buffer
= lpBuffer
;
145 Status
= RtlQueryEnvironmentVariable_U (NULL
,
148 if (!NT_SUCCESS(Status
))
150 SetLastErrorByStatus (Status
);
151 if (Status
== STATUS_BUFFER_TOO_SMALL
)
153 return (VarValue
.Length
/ sizeof(WCHAR
)) + 1;
163 /* make sure the string is NULL-terminated! RtlQueryEnvironmentVariable_U
164 only terminates it if MaximumLength < Length */
165 VarValue
.Buffer
[VarValue
.Length
/ sizeof(WCHAR
)] = L
'\0';
168 return (VarValue
.Length
/ sizeof(WCHAR
));
177 SetEnvironmentVariableA (
183 ANSI_STRING VarValue
;
184 UNICODE_STRING VarNameU
;
185 UNICODE_STRING VarValueU
;
188 DPRINT("SetEnvironmentVariableA(Name '%s', Value '%s')\n", lpName
, lpValue
);
190 RtlInitAnsiString (&VarName
,
192 RtlAnsiStringToUnicodeString (&VarNameU
,
196 RtlInitAnsiString (&VarValue
,
198 RtlAnsiStringToUnicodeString (&VarValueU
,
202 Status
= RtlSetEnvironmentVariable (NULL
,
206 RtlFreeUnicodeString (&VarNameU
);
207 RtlFreeUnicodeString (&VarValueU
);
209 if (!NT_SUCCESS(Status
))
211 SetLastErrorByStatus (Status
);
224 SetEnvironmentVariableW (
229 UNICODE_STRING VarName
;
230 UNICODE_STRING VarValue
;
233 DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName
, lpValue
);
235 RtlInitUnicodeString (&VarName
,
238 RtlInitUnicodeString (&VarValue
,
241 Status
= RtlSetEnvironmentVariable (NULL
,
244 if (!NT_SUCCESS(Status
))
246 SetLastErrorByStatus (Status
);
259 GetEnvironmentStringsA (
263 UNICODE_STRING UnicodeString
;
264 ANSI_STRING AnsiString
;
270 EnvU
= (PWCHAR
)(NtCurrentPeb ()->ProcessParameters
->Environment
);
278 /* get environment size */
286 Length
= (ULONG
)(PtrU
- EnvU
);
287 DPRINT("Length %lu\n", Length
);
289 /* allocate environment buffer */
290 EnvPtr
= RtlAllocateHeap (RtlGetProcessHeap (),
295 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
298 DPRINT("EnvPtr %p\n", EnvPtr
);
300 /* convert unicode environment to ansi */
301 UnicodeString
.MaximumLength
= Length
* sizeof(WCHAR
) + sizeof(WCHAR
);
302 UnicodeString
.Buffer
= EnvU
;
304 AnsiString
.MaximumLength
= Length
+ 1;
305 AnsiString
.Length
= 0;
306 AnsiString
.Buffer
= EnvPtr
;
308 DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString
.Buffer
);
310 while (*(UnicodeString
.Buffer
))
312 UnicodeString
.Length
= wcslen (UnicodeString
.Buffer
) * sizeof(WCHAR
);
313 UnicodeString
.MaximumLength
= UnicodeString
.Length
+ sizeof(WCHAR
);
314 if (UnicodeString
.Length
> 0)
316 AnsiString
.Length
= 0;
317 AnsiString
.MaximumLength
= Length
+ 1 - (AnsiString
.Buffer
- EnvPtr
);
319 RtlUnicodeStringToAnsiString (&AnsiString
,
323 AnsiString
.Buffer
+= (AnsiString
.Length
+ 1);
324 UnicodeString
.Buffer
+= ((UnicodeString
.Length
/ sizeof(WCHAR
)) + 1);
327 *(AnsiString
.Buffer
) = 0;
338 GetEnvironmentStringsW (
342 return (LPWSTR
)(NtCurrentPeb ()->ProcessParameters
->Environment
);
351 FreeEnvironmentStringsA (
352 LPSTR EnvironmentStrings
355 if (EnvironmentStrings
== NULL
)
358 RtlFreeHeap (RtlGetProcessHeap (),
371 FreeEnvironmentStringsW (
372 LPWSTR EnvironmentStrings
375 (void)EnvironmentStrings
;
385 ExpandEnvironmentStringsA (
392 ANSI_STRING Destination
;
393 UNICODE_STRING SourceU
;
394 UNICODE_STRING DestinationU
;
398 RtlInitAnsiString (&Source
,
400 Status
= RtlAnsiStringToUnicodeString (&SourceU
,
403 if (!NT_SUCCESS(Status
))
405 SetLastErrorByStatus (Status
);
409 Destination
.Length
= 0;
410 Destination
.MaximumLength
= nSize
;
411 Destination
.Buffer
= lpDst
;
413 DestinationU
.Length
= 0;
414 DestinationU
.MaximumLength
= nSize
* sizeof(WCHAR
);
415 DestinationU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
417 DestinationU
.MaximumLength
);
418 if (DestinationU
.Buffer
== NULL
)
420 RtlFreeUnicodeString(&SourceU
);
421 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
425 Status
= RtlExpandEnvironmentStrings_U (NULL
,
430 RtlFreeUnicodeString (&SourceU
);
432 if (!NT_SUCCESS(Status
))
434 SetLastErrorByStatus (Status
);
435 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
437 RtlFreeHeap (RtlGetProcessHeap (),
439 DestinationU
.Buffer
);
444 RtlUnicodeStringToAnsiString (&Destination
,
448 RtlFreeHeap (RtlGetProcessHeap (),
450 DestinationU
.Buffer
);
452 return (Length
/ sizeof(WCHAR
));
461 ExpandEnvironmentStringsW (
467 UNICODE_STRING Source
;
468 UNICODE_STRING Destination
;
472 RtlInitUnicodeString (&Source
,
475 Destination
.Length
= 0;
476 Destination
.MaximumLength
= nSize
* sizeof(WCHAR
);
477 Destination
.Buffer
= lpDst
;
479 Status
= RtlExpandEnvironmentStrings_U (NULL
,
483 if (!NT_SUCCESS(Status
))
485 SetLastErrorByStatus (Status
);
486 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
490 return (Length
/ sizeof(WCHAR
));