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)
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
= (USHORT
)nSize
;
47 VarValue
.Buffer
= lpBuffer
;
49 /* initialize unicode variable value string and allocate buffer */
53 VarValueU
.MaximumLength
= (USHORT
)(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
= (USHORT
) (nSize
? nSize
- 1 : 0) * sizeof(WCHAR
);
143 VarValue
.Buffer
= lpBuffer
;
145 Status
= RtlQueryEnvironmentVariable_U (NULL
,
148 if (!NT_SUCCESS(Status
))
150 if (Status
== STATUS_BUFFER_TOO_SMALL
)
152 return (VarValue
.Length
/ sizeof(WCHAR
)) + 1;
156 SetLastErrorByStatus (Status
);
163 /* make sure the string is NULL-terminated! RtlQueryEnvironmentVariable_U
164 only terminates it if MaximumLength < Length */
165 lpBuffer
[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
,
198 RtlInitAnsiString (&VarValue
,
200 RtlAnsiStringToUnicodeString (&VarValueU
,
204 Status
= RtlSetEnvironmentVariable (NULL
,
208 RtlFreeUnicodeString (&VarValueU
);
212 Status
= RtlSetEnvironmentVariable (NULL
,
216 RtlFreeUnicodeString (&VarNameU
);
218 if (!NT_SUCCESS(Status
))
220 SetLastErrorByStatus (Status
);
233 SetEnvironmentVariableW (
238 UNICODE_STRING VarName
;
239 UNICODE_STRING VarValue
;
242 DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName
, lpValue
);
244 RtlInitUnicodeString (&VarName
,
247 RtlInitUnicodeString (&VarValue
,
250 Status
= RtlSetEnvironmentVariable (NULL
,
254 if (!NT_SUCCESS(Status
))
256 SetLastErrorByStatus (Status
);
269 GetEnvironmentStringsA (
273 UNICODE_STRING UnicodeString
;
274 ANSI_STRING AnsiString
;
280 EnvU
= (PWCHAR
)(NtCurrentPeb ()->ProcessParameters
->Environment
);
288 /* get environment size */
296 Length
= (ULONG
)(PtrU
- EnvU
);
297 DPRINT("Length %lu\n", Length
);
299 /* allocate environment buffer */
300 EnvPtr
= RtlAllocateHeap (RtlGetProcessHeap (),
305 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
308 DPRINT("EnvPtr %p\n", EnvPtr
);
310 /* convert unicode environment to ansi */
311 UnicodeString
.MaximumLength
= (USHORT
)Length
* sizeof(WCHAR
) + sizeof(WCHAR
);
312 UnicodeString
.Buffer
= EnvU
;
314 AnsiString
.MaximumLength
= (USHORT
)Length
+ 1;
315 AnsiString
.Length
= 0;
316 AnsiString
.Buffer
= EnvPtr
;
318 DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString
.Buffer
);
320 while (*(UnicodeString
.Buffer
))
322 UnicodeString
.Length
= wcslen (UnicodeString
.Buffer
) * sizeof(WCHAR
);
323 UnicodeString
.MaximumLength
= UnicodeString
.Length
+ sizeof(WCHAR
);
324 if (UnicodeString
.Length
> 0)
326 AnsiString
.Length
= 0;
327 AnsiString
.MaximumLength
= (USHORT
)Length
+ 1 - (AnsiString
.Buffer
- EnvPtr
);
329 RtlUnicodeStringToAnsiString (&AnsiString
,
333 AnsiString
.Buffer
+= (AnsiString
.Length
+ 1);
334 UnicodeString
.Buffer
+= ((UnicodeString
.Length
/ sizeof(WCHAR
)) + 1);
337 *(AnsiString
.Buffer
) = 0;
348 GetEnvironmentStringsW (
352 return (LPWSTR
)(NtCurrentPeb ()->ProcessParameters
->Environment
);
361 FreeEnvironmentStringsA (
362 LPSTR EnvironmentStrings
365 if (EnvironmentStrings
== NULL
)
368 RtlFreeHeap (RtlGetProcessHeap (),
381 FreeEnvironmentStringsW (
382 LPWSTR EnvironmentStrings
394 ExpandEnvironmentStringsA (
401 ANSI_STRING Destination
;
402 UNICODE_STRING SourceU
;
403 UNICODE_STRING DestinationU
;
407 RtlInitAnsiString (&Source
,
409 Status
= RtlAnsiStringToUnicodeString (&SourceU
,
412 if (!NT_SUCCESS(Status
))
414 SetLastErrorByStatus (Status
);
418 /* make sure we don't overflow the maximum ANSI_STRING size */
422 Destination
.Length
= 0;
423 Destination
.MaximumLength
= (USHORT
)nSize
;
424 Destination
.Buffer
= lpDst
;
426 DestinationU
.Length
= 0;
427 DestinationU
.MaximumLength
= (USHORT
)nSize
* sizeof(WCHAR
);
428 DestinationU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
430 DestinationU
.MaximumLength
);
431 if (DestinationU
.Buffer
== NULL
)
433 RtlFreeUnicodeString(&SourceU
);
434 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
438 Status
= RtlExpandEnvironmentStrings_U (NULL
,
443 RtlFreeUnicodeString (&SourceU
);
445 if (!NT_SUCCESS(Status
))
447 SetLastErrorByStatus (Status
);
448 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
450 RtlFreeHeap (RtlGetProcessHeap (),
452 DestinationU
.Buffer
);
457 RtlUnicodeStringToAnsiString (&Destination
,
461 RtlFreeHeap (RtlGetProcessHeap (),
463 DestinationU
.Buffer
);
465 return (Length
/ sizeof(WCHAR
));
474 ExpandEnvironmentStringsW (
480 UNICODE_STRING Source
;
481 UNICODE_STRING Destination
;
485 RtlInitUnicodeString (&Source
,
488 /* make sure we don't overflow the maximum UNICODE_STRING size */
492 Destination
.Length
= 0;
493 Destination
.MaximumLength
= (USHORT
)nSize
* sizeof(WCHAR
);
494 Destination
.Buffer
= lpDst
;
496 Status
= RtlExpandEnvironmentStrings_U (NULL
,
500 if (!NT_SUCCESS(Status
))
502 SetLastErrorByStatus (Status
);
503 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
507 return (Length
/ sizeof(WCHAR
));