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 (),
293 DPRINT("EnvPtr %p\n", EnvPtr
);
295 /* convert unicode environment to ansi */
296 UnicodeString
.MaximumLength
= Length
* sizeof(WCHAR
) + sizeof(WCHAR
);
297 UnicodeString
.Buffer
= EnvU
;
299 AnsiString
.MaximumLength
= Length
+ 1;
300 AnsiString
.Length
= 0;
301 AnsiString
.Buffer
= EnvPtr
;
303 DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString
.Buffer
);
305 while (*(UnicodeString
.Buffer
))
307 UnicodeString
.Length
= wcslen (UnicodeString
.Buffer
) * sizeof(WCHAR
);
308 UnicodeString
.MaximumLength
= UnicodeString
.Length
+ sizeof(WCHAR
);
309 if (UnicodeString
.Length
> 0)
311 AnsiString
.Length
= 0;
312 AnsiString
.MaximumLength
= Length
+ 1 - (AnsiString
.Buffer
- EnvPtr
);
314 RtlUnicodeStringToAnsiString (&AnsiString
,
318 AnsiString
.Buffer
+= (AnsiString
.Length
+ 1);
319 UnicodeString
.Buffer
+= ((UnicodeString
.Length
/ sizeof(WCHAR
)) + 1);
322 *(AnsiString
.Buffer
) = 0;
333 GetEnvironmentStringsW (
337 return (LPWSTR
)(NtCurrentPeb ()->ProcessParameters
->Environment
);
346 FreeEnvironmentStringsA (
347 LPSTR EnvironmentStrings
350 if (EnvironmentStrings
== NULL
)
353 RtlFreeHeap (RtlGetProcessHeap (),
366 FreeEnvironmentStringsW (
367 LPWSTR EnvironmentStrings
370 (void)EnvironmentStrings
;
380 ExpandEnvironmentStringsA (
387 ANSI_STRING Destination
;
388 UNICODE_STRING SourceU
;
389 UNICODE_STRING DestinationU
;
393 RtlInitAnsiString (&Source
,
395 RtlAnsiStringToUnicodeString (&SourceU
,
399 Destination
.Length
= 0;
400 Destination
.MaximumLength
= nSize
;
401 Destination
.Buffer
= lpDst
;
403 DestinationU
.Length
= 0;
404 DestinationU
.MaximumLength
= nSize
* sizeof(WCHAR
);
405 DestinationU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
407 DestinationU
.MaximumLength
);
409 Status
= RtlExpandEnvironmentStrings_U (NULL
,
414 RtlFreeUnicodeString (&SourceU
);
416 if (!NT_SUCCESS(Status
))
418 SetLastErrorByStatus (Status
);
419 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
421 RtlFreeHeap (RtlGetProcessHeap (),
423 DestinationU
.Buffer
);
428 RtlUnicodeStringToAnsiString (&Destination
,
432 RtlFreeHeap (RtlGetProcessHeap (),
434 DestinationU
.Buffer
);
436 return (Length
/ sizeof(WCHAR
));
445 ExpandEnvironmentStringsW (
451 UNICODE_STRING Source
;
452 UNICODE_STRING Destination
;
456 RtlInitUnicodeString (&Source
,
459 Destination
.Length
= 0;
460 Destination
.MaximumLength
= nSize
* sizeof(WCHAR
);
461 Destination
.Buffer
= lpDst
;
463 Status
= RtlExpandEnvironmentStrings_U (NULL
,
467 if (!NT_SUCCESS(Status
))
469 SetLastErrorByStatus (Status
);
470 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
474 return (Length
/ sizeof(WCHAR
));