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)
20 /* FUNCTIONS ******************************************************************/
27 GetEnvironmentVariableA (
35 UNICODE_STRING VarNameU
;
36 UNICODE_STRING VarValueU
;
39 /* initialize unicode variable name string */
40 RtlInitAnsiString (&VarName
,
42 RtlAnsiStringToUnicodeString (&VarNameU
,
46 /* initialize ansi variable value string */
48 VarValue
.MaximumLength
= (USHORT
)nSize
;
49 VarValue
.Buffer
= lpBuffer
;
51 /* initialize unicode variable value string and allocate buffer */
55 VarValueU
.MaximumLength
= (USHORT
)(nSize
- 1) * sizeof(WCHAR
);
56 VarValueU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
58 nSize
* sizeof(WCHAR
));
59 if (VarValueU
.Buffer
!= NULL
)
61 /* NULL-terminate the buffer in any case! RtlQueryEnvironmentVariable_U
62 only terminates it if MaximumLength < Length! */
63 VarValueU
.Buffer
[nSize
- 1] = L
'\0';
68 VarValueU
.MaximumLength
= 0;
69 VarValueU
.Buffer
= NULL
;
72 if (VarValueU
.Buffer
!= NULL
|| nSize
== 0)
74 /* get unicode environment variable */
75 Status
= RtlQueryEnvironmentVariable_U (NULL
,
78 if (!NT_SUCCESS(Status
))
80 /* free unicode buffer */
81 RtlFreeHeap (RtlGetProcessHeap (),
85 /* free unicode variable name string */
86 RtlFreeUnicodeString (&VarNameU
);
88 BaseSetLastNTError (Status
);
89 if (Status
== STATUS_BUFFER_TOO_SMALL
)
91 return (VarValueU
.Length
/ sizeof(WCHAR
)) + 1;
99 /* convert unicode value string to ansi */
100 RtlUnicodeStringToAnsiString (&VarValue
,
104 if (VarValueU
.Buffer
!= NULL
)
106 /* free unicode buffer */
107 RtlFreeHeap (RtlGetProcessHeap (),
112 /* free unicode variable name string */
113 RtlFreeUnicodeString (&VarNameU
);
115 return (VarValueU
.Length
/ sizeof(WCHAR
));
119 SetLastError (ERROR_NOT_ENOUGH_MEMORY
);
130 GetEnvironmentVariableW (
136 UNICODE_STRING VarName
;
137 UNICODE_STRING VarValue
;
140 RtlInitUnicodeString (&VarName
,
144 VarValue
.MaximumLength
= (USHORT
) (nSize
? nSize
- 1 : 0) * sizeof(WCHAR
);
145 VarValue
.Buffer
= lpBuffer
;
147 Status
= RtlQueryEnvironmentVariable_U (NULL
,
150 if (!NT_SUCCESS(Status
))
152 if (Status
== STATUS_BUFFER_TOO_SMALL
)
154 return (VarValue
.Length
/ sizeof(WCHAR
)) + 1;
158 BaseSetLastNTError (Status
);
165 /* make sure the string is NULL-terminated! RtlQueryEnvironmentVariable_U
166 only terminates it if MaximumLength < Length */
167 lpBuffer
[VarValue
.Length
/ sizeof(WCHAR
)] = L
'\0';
170 return (VarValue
.Length
/ sizeof(WCHAR
));
179 SetEnvironmentVariableA (
185 ANSI_STRING VarValue
;
186 UNICODE_STRING VarNameU
;
187 UNICODE_STRING VarValueU
;
190 DPRINT("SetEnvironmentVariableA(Name '%s', Value '%s')\n", lpName
, lpValue
);
192 RtlInitAnsiString (&VarName
,
194 RtlAnsiStringToUnicodeString (&VarNameU
,
200 RtlInitAnsiString (&VarValue
,
202 RtlAnsiStringToUnicodeString (&VarValueU
,
206 Status
= RtlSetEnvironmentVariable (NULL
,
210 RtlFreeUnicodeString (&VarValueU
);
214 Status
= RtlSetEnvironmentVariable (NULL
,
218 RtlFreeUnicodeString (&VarNameU
);
220 if (!NT_SUCCESS(Status
))
222 BaseSetLastNTError (Status
);
235 SetEnvironmentVariableW (
240 UNICODE_STRING VarName
;
241 UNICODE_STRING VarValue
;
244 DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName
, lpValue
);
246 RtlInitUnicodeString (&VarName
,
249 RtlInitUnicodeString (&VarValue
,
252 Status
= RtlSetEnvironmentVariable (NULL
,
256 if (!NT_SUCCESS(Status
))
258 BaseSetLastNTError (Status
);
271 GetEnvironmentStringsA (
275 UNICODE_STRING UnicodeString
;
276 ANSI_STRING AnsiString
;
282 EnvU
= (PWCHAR
)(NtCurrentPeb ()->ProcessParameters
->Environment
);
290 /* get environment size */
298 Length
= (ULONG
)(PtrU
- EnvU
);
299 DPRINT("Length %lu\n", Length
);
301 /* allocate environment buffer */
302 EnvPtr
= RtlAllocateHeap (RtlGetProcessHeap (),
307 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
310 DPRINT("EnvPtr %p\n", EnvPtr
);
312 /* convert unicode environment to ansi */
313 UnicodeString
.MaximumLength
= (USHORT
)Length
* sizeof(WCHAR
) + sizeof(WCHAR
);
314 UnicodeString
.Buffer
= EnvU
;
316 AnsiString
.MaximumLength
= (USHORT
)Length
+ 1;
317 AnsiString
.Length
= 0;
318 AnsiString
.Buffer
= EnvPtr
;
320 DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString
.Buffer
);
322 while (*(UnicodeString
.Buffer
))
324 UnicodeString
.Length
= wcslen (UnicodeString
.Buffer
) * sizeof(WCHAR
);
325 UnicodeString
.MaximumLength
= UnicodeString
.Length
+ sizeof(WCHAR
);
326 if (UnicodeString
.Length
> 0)
328 AnsiString
.Length
= 0;
329 AnsiString
.MaximumLength
= (USHORT
)Length
+ 1 - (AnsiString
.Buffer
- EnvPtr
);
331 RtlUnicodeStringToAnsiString (&AnsiString
,
335 AnsiString
.Buffer
+= (AnsiString
.Length
+ 1);
336 UnicodeString
.Buffer
+= ((UnicodeString
.Length
/ sizeof(WCHAR
)) + 1);
339 *(AnsiString
.Buffer
) = 0;
350 GetEnvironmentStringsW (
354 return (LPWSTR
)(NtCurrentPeb ()->ProcessParameters
->Environment
);
363 FreeEnvironmentStringsA (
364 LPSTR EnvironmentStrings
367 if (EnvironmentStrings
== NULL
)
370 RtlFreeHeap (RtlGetProcessHeap (),
383 FreeEnvironmentStringsW (
384 LPWSTR EnvironmentStrings
396 ExpandEnvironmentStringsA (
403 ANSI_STRING Destination
;
404 UNICODE_STRING SourceU
;
405 UNICODE_STRING DestinationU
;
409 RtlInitAnsiString (&Source
,
411 Status
= RtlAnsiStringToUnicodeString (&SourceU
,
414 if (!NT_SUCCESS(Status
))
416 BaseSetLastNTError (Status
);
420 /* make sure we don't overflow the maximum ANSI_STRING size */
424 Destination
.Length
= 0;
425 Destination
.MaximumLength
= (USHORT
)nSize
;
426 Destination
.Buffer
= lpDst
;
428 DestinationU
.Length
= 0;
429 DestinationU
.MaximumLength
= (USHORT
)nSize
* sizeof(WCHAR
);
430 DestinationU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
432 DestinationU
.MaximumLength
);
433 if (DestinationU
.Buffer
== NULL
)
435 RtlFreeUnicodeString(&SourceU
);
436 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
440 Status
= RtlExpandEnvironmentStrings_U (NULL
,
445 RtlFreeUnicodeString (&SourceU
);
447 if (!NT_SUCCESS(Status
))
449 BaseSetLastNTError (Status
);
450 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
452 RtlFreeHeap (RtlGetProcessHeap (),
454 DestinationU
.Buffer
);
459 RtlUnicodeStringToAnsiString (&Destination
,
463 RtlFreeHeap (RtlGetProcessHeap (),
465 DestinationU
.Buffer
);
467 return (Length
/ sizeof(WCHAR
));
476 ExpandEnvironmentStringsW (
482 UNICODE_STRING Source
;
483 UNICODE_STRING Destination
;
487 RtlInitUnicodeString (&Source
,
490 /* make sure we don't overflow the maximum UNICODE_STRING size */
494 Destination
.Length
= 0;
495 Destination
.MaximumLength
= (USHORT
)nSize
* sizeof(WCHAR
);
496 Destination
.Buffer
= lpDst
;
498 Status
= RtlExpandEnvironmentStrings_U (NULL
,
502 if (!NT_SUCCESS(Status
))
504 BaseSetLastNTError (Status
);
505 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
509 return (Length
/ sizeof(WCHAR
));
517 SetEnvironmentStringsA(IN LPCH NewEnvironment
)
528 SetEnvironmentStringsW(IN LPWCH NewEnvironment
)