ReactOS 0.4.17-dev-243-g1369312
environ.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/environ.c
5 * PURPOSE: Environment functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * Emanuele Aliberti
8 * Thomas Weidenmueller
9 * UPDATE HISTORY:
10 * Created 01/11/98
11 */
12
13/* INCLUDES *******************************************************************/
14
15#include <k32.h>
16
17#define NDEBUG
18#include <debug.h>
19
20/* FUNCTIONS ******************************************************************/
21
22/*
23 * @implemented
24 */
31{
32 ANSI_STRING VarName, VarValue;
33 UNICODE_STRING VarNameU, VarValueU;
35 ULONG Result = 0;
36 USHORT UniSize;
38
39 /* Initialize all the strings */
40 RtlInitAnsiString(&VarName, lpName);
41 RtlInitUnicodeString(&VarNameU, NULL);
42 RtlInitUnicodeString(&VarValueU, NULL);
43 Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE);
44 if (!NT_SUCCESS(Status)) goto Quickie;
45
46 /* Set maximum size for unicode string (in chars, including ANSI_NULL) */
48
49 /* Allocate the value string buffer */
50 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize * sizeof(WCHAR));
51 if (!Buffer)
52 {
54 goto Quickie;
55 }
56
57 /* And initialize its string */
58 RtlInitEmptyUnicodeString(&VarValueU, Buffer, UniSize * sizeof(WCHAR));
59
60 /* Acquire the PEB lock since we'll be querying variables now */
62
63 /* Query the variable */
64 Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU);
65 if ((NT_SUCCESS(Status)) && !(nSize))
67
68 /* Check if we didn't have enough space */
70 {
71 /* Fixup the length that the API returned */
72 VarValueU.MaximumLength = VarValueU.Length + sizeof(UNICODE_NULL);
73
74 /* Free old Unicode buffer */
75 RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer);
76
77 /* Allocate new one */
78 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VarValueU.MaximumLength);
79 if (Buffer)
80 {
81 /* Query the variable so we can know its size */
82 VarValueU.Buffer = Buffer;
83 Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU);
84 if (NT_SUCCESS(Status))
85 {
86 /* Get the ASCII length of the variable */
88 }
89 }
90 else
91 {
92 /* Set failure status */
94 VarValueU.Buffer = NULL;
95 }
96 }
97 else if (NT_SUCCESS(Status))
98 {
99 /* Check the size */
101 if (Result <= UniSize)
102 {
103 /* Convert the string */
104 RtlInitEmptyAnsiString(&VarValue, lpBuffer, UniSize);
105 Status = RtlUnicodeStringToAnsiString(&VarValue, &VarValueU, FALSE);
106 if (NT_SUCCESS(Status))
107 {
108 /* NULL-terminate and set the final length */
109 ASSERT(VarValue.Length < UniSize);
110 lpBuffer[VarValue.Length] = ANSI_NULL;
111 Result = VarValue.Length;
112 }
113 }
114 }
115
116 /* Release the lock */
118
119Quickie:
120 /* Free the strings */
121 RtlFreeUnicodeString(&VarNameU);
122 if (VarValueU.Buffer)
123 RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer);
124
125 /* Check if we succeeded */
126 if (!NT_SUCCESS(Status))
127 {
128 /* We did not, clear the result and set the error code */
130 Result = 0;
131 }
132
133 /* Return the result */
134 return Result;
135}
136
137/*
138 * @implemented
139 */
140DWORD
141WINAPI
145 IN DWORD nSize)
146{
147 UNICODE_STRING VarName, VarValue;
149 USHORT UniSize;
150
151 if (lpBuffer == NULL)
152 {
153 nSize = 0;
154 }
155
156 /* Set maximum size for unicode string (in chars, including UNICODE_NULL) */
158
160 if (!NT_SUCCESS(Status))
161 {
163 return 0;
164 }
165
166 RtlInitEmptyUnicodeString(&VarValue, lpBuffer, UniSize * sizeof(WCHAR));
167
168 Status = RtlQueryEnvironmentVariable_U(NULL, &VarName, &VarValue);
169 if (!NT_SUCCESS(Status))
170 {
172 {
173 return (VarValue.Length / sizeof(WCHAR)) + sizeof(ANSI_NULL);
174 }
176 return 0;
177 }
178
179 if (lpBuffer)
180 lpBuffer[VarValue.Length / sizeof(WCHAR)] = UNICODE_NULL;
181
182 return (VarValue.Length / sizeof(WCHAR));
183}
184
185/*
186 * @implemented
187 */
188BOOL
189WINAPI
192 IN LPCSTR lpValue)
193{
194 ANSI_STRING VarName, VarValue;
195 UNICODE_STRING VarNameU, VarValueU;
197
198 RtlInitAnsiString(&VarName, (LPSTR)lpName);
199 Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE);
200 if (NT_SUCCESS(Status))
201 {
202 if (lpValue)
203 {
204 RtlInitAnsiString(&VarValue, (LPSTR)lpValue);
205 Status = RtlAnsiStringToUnicodeString(&VarValueU, &VarValue, TRUE);
206 if (NT_SUCCESS(Status))
207 {
208 Status = RtlSetEnvironmentVariable(NULL, &VarNameU, &VarValueU);
209 RtlFreeUnicodeString(&VarValueU);
210 }
211 }
212 else
213 {
215 }
216
217 RtlFreeUnicodeString(&VarNameU);
218
219 if (NT_SUCCESS(Status)) return TRUE;
220 }
221
223 return FALSE;
224}
225
226/*
227 * @implemented
228 */
229BOOL
230WINAPI
233 IN LPCWSTR lpValue)
234{
235 UNICODE_STRING VarName, VarValue;
237
239 if (NT_SUCCESS(Status))
240 {
241 if (lpValue)
242 {
243 Status = RtlInitUnicodeStringEx(&VarValue, lpValue);
244 if (NT_SUCCESS(Status))
245 {
246 Status = RtlSetEnvironmentVariable(NULL, &VarName, &VarValue);
247 }
248 }
249 else
250 {
252 }
253
254 if (NT_SUCCESS(Status)) return TRUE;
255 }
256
258 return FALSE;
259}
260
261/*
262 * @implemented
263 */
264LPSTR
265WINAPI
267{
271 PCHAR Buffer = NULL;
272
274 p = Environment = NtCurrentPeb()->ProcessParameters->Environment;
275
276 do
277 {
278 p += wcslen(p) + 1;
279 } while (*p);
280
281 Length = p - Environment + 1;
282
284 if (NT_SUCCESS(Status))
285 {
286 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
287 if (Buffer)
288 {
290 if (!NT_SUCCESS(Status))
291 {
292 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
293 Buffer = NULL;
294
296 }
297 }
298 else
299 {
301 }
302 }
303 else
304 {
306 }
307
309 return Buffer;
310}
311
312/*
313 * @implemented
314 */
315LPWSTR
316WINAPI
318{
321
323
324 p = Environment = NtCurrentPeb()->ProcessParameters->Environment;
325
326 do
327 {
328 p += wcslen(p) + 1;
329 } while (*p);
330
331 Length = p - Environment + 1;
332
333 p = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
334 if (p)
335 {
337 }
338 else
339 {
341 }
342
344 return p;
345}
346
347/*
348 * @implemented
349 */
350BOOL
351WINAPI
353{
354 return RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings);
355}
356
357/*
358 * @implemented
359 */
360BOOL
361WINAPI
363{
364 return RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings);
365}
366
367/*
368 * @implemented
369 */
370DWORD
371WINAPI
373 IN LPSTR lpDst,
374 IN DWORD nSize)
375{
376 ANSI_STRING Source, Dest;
377 UNICODE_STRING SourceU, DestU;
379 ULONG Result = 0, Length;
380 USHORT UniSize;
382
383 /* Check if the size is too big to fit */
384 UniSize = UNICODE_STRING_MAX_CHARS - 2;
385 if (nSize <= UniSize) UniSize = (USHORT)nSize;
386
387 /* Clear the input buffer */
388 if (lpDst) *lpDst = ANSI_NULL;
389
390 /* Initialize all the strings */
391 RtlInitAnsiString(&Source, lpSrc);
392 RtlInitUnicodeString(&SourceU, NULL);
393 RtlInitUnicodeString(&DestU, NULL);
395 if (!NT_SUCCESS(Status)) goto Quickie;
396
397 /* If the string fit in, make space for a NULL char */
398 if (UniSize)
399 {
400 UniSize--;
401 }
402 else
403 {
404 /* No input size, so no string size */
405 UniSize = 0;
406 }
407
408 /* Allocate the value string buffer */
409 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize * sizeof(WCHAR));
410 if (!Buffer)
411 {
413 goto Quickie;
414 }
415
416 /* And initialize its string */
417 RtlInitEmptyUnicodeString(&DestU, Buffer, UniSize * sizeof(WCHAR));
418
419 /* Query the variable */
420 Length = 0;
421 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length);
422
423 /* Check if we didn't have enough space */
425 {
426 /* Fixup the length that the API returned */
427 DestU.MaximumLength = (SHORT)Length;
428
429 /* Free old Unicode buffer */
430 RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer);
431
432 /* Allocate new one */
433 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
434 if (Buffer)
435 {
436 /* Query the variable so we can know its size */
437 DestU.Buffer = Buffer;
438 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length);
439 if (NT_SUCCESS(Status))
440 {
441 /* Get the ASCII length of the variable, add a byte for NULL */
442 Result = RtlUnicodeStringToAnsiSize(&DestU) + sizeof(ANSI_NULL);
443 }
444 }
445 else
446 {
447 /* Set failure status */
449 DestU.Buffer = NULL;
450 }
451 }
452 else if (NT_SUCCESS(Status))
453 {
454 /* Check if the size is too big to fit */
455 UniSize = UNICODE_STRING_MAX_BYTES - 1;
456 if (nSize <= UniSize) UniSize = (USHORT)nSize;
457
458 /* Check the size */
460 if (Result <= UniSize)
461 {
462 /* Convert the string */
463 RtlInitEmptyAnsiString(&Dest, lpDst, UniSize);
464 Status = RtlUnicodeStringToAnsiString(&Dest, &DestU, FALSE);
465
466 /* Write a NULL-char in case of failure only */
467 if (!NT_SUCCESS(Status)) *lpDst = ANSI_NULL;
468 }
469 }
470Quickie:
471 /* Free the strings */
472 RtlFreeUnicodeString(&SourceU);
473 if (DestU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer);
474
475 /* Check if we succeeded */
476 if (!NT_SUCCESS(Status))
477 {
478 /* We did not, clear the result and set the error code */
480 Result = 0;
481 }
482
483 /* Return the result */
484 return Result;
485}
486
487/*
488 * @implemented
489 */
490DWORD
491WINAPI
493 IN LPWSTR lpDst,
494 IN DWORD nSize)
495{
498 USHORT UniSize;
499
500 UniSize = min(nSize, UNICODE_STRING_MAX_CHARS - 2);
501
503 RtlInitEmptyUnicodeString(&Destination, lpDst, UniSize * sizeof(WCHAR));
504
506 &Source,
508 &nSize);
510 {
511 return nSize / sizeof(WCHAR);
512 }
513
515 return 0;
516}
517
518/*
519 * @implemented
520 */
521BOOL
522WINAPI
524{
525 STUB;
526 return FALSE;
527}
528
529/*
530 * @implemented
531 */
532BOOL
533WINAPI
535{
536 STUB;
537 return FALSE;
538}
539
540/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
Definition: bufpool.h:45
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:754
BOOL WINAPI SetEnvironmentStringsW(IN LPWCH NewEnvironment)
Definition: environ.c:534
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:372
BOOL WINAPI FreeEnvironmentStringsA(IN LPSTR EnvironmentStrings)
Definition: environ.c:352
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:362
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:232
BOOL WINAPI SetEnvironmentStringsA(IN LPCH NewEnvironment)
Definition: environ.c:523
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:492
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:191
LPWSTR WINAPI DECLSPEC_HOTPATCH GetEnvironmentStringsW(void)
Definition: process.c:1538
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:24
GLfloat GLfloat p
Definition: glext.h:8902
#define STUB
Definition: kernel32.h:27
#define ASSERT(a)
Definition: mode.c:44
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
NTSYSAPI NTSTATUS NTAPI RtlSetEnvironmentVariable(_In_z_ PWSTR *Environment, _In_ PUNICODE_STRING Name, _In_ PUNICODE_STRING Value)
Definition: env.c:338
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3051
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
Definition: env.c:659
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToOemN(_Out_ PCHAR OemString, _In_ ULONG OemSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:264
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteSize(_Out_ PULONG MbSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:146
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
CHAR * LPCH
Definition: ntbasedef.h:403
WCHAR * LPWCH
Definition: ntbasedef.h:422
#define UNICODE_NULL
#define UNICODE_STRING_MAX_CHARS
#define UNICODE_STRING_MAX_BYTES
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
short WCHAR
Definition: pedump.c:58
short SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ LPCSTR lpName
Definition: winbase.h:2543
#define GetEnvironmentStringsA
Definition: winbase.h:3562
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:1834
#define WINAPI
Definition: msvc.h:6
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:84
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:74
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
NTSYSAPI NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PCWSTR, const UNICODE_STRING *, UNICODE_STRING *, ULONG *)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define RtlUnicodeStringToAnsiSize(String)
Definition: rtlfuncs.h:1022