ReactOS 0.4.16-dev-334-g4d9f67c
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 /* Check if the size is too big to fit */
47 UniSize = UNICODE_STRING_MAX_CHARS - 2;
48 if (nSize <= UniSize)
49 {
50 /* It fits, but was there a string at all? */
51 if (nSize)
52 {
53 /* Keep the given size, minus a NULL-char */
54 UniSize = (USHORT)(nSize - 1);
55 }
56 else
57 {
58 /* No size */
59 UniSize = 0;
60 }
61 }
62 else
63 {
64 /* String is too big, so we need to return a NULL char as well */
65 UniSize--;
66 }
67
68 /* Allocate the value string buffer */
69 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize * sizeof(WCHAR));
70 if (!Buffer)
71 {
73 goto Quickie;
74 }
75
76 /* And initialize its string */
77 RtlInitEmptyUnicodeString(&VarValueU, Buffer, UniSize * sizeof(WCHAR));
78
79 /* Acquire the PEB lock since we'll be querying variables now */
81
82 /* Query the variable */
83 Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU);
85
86 /* Check if we didn't have enough space */
88 {
89 /* Fixup the length that the API returned */
90 VarValueU.MaximumLength = VarValueU.Length + sizeof(UNICODE_NULL);
91
92 /* Free old Unicode buffer */
93 RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer);
94
95 /* Allocate new one */
96 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VarValueU.MaximumLength);
97 if (Buffer)
98 {
99 /* Query the variable so we can know its size */
100 VarValueU.Buffer = Buffer;
101 Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU);
102 if (NT_SUCCESS(Status))
103 {
104 /* Get the ASCII length of the variable */
106 }
107 }
108 else
109 {
110 /* Set failure status */
112 VarValueU.Buffer = NULL;
113 }
114 }
115 else if (NT_SUCCESS(Status))
116 {
117 /* Check if the size is too big to fit */
118 UniSize = UNICODE_STRING_MAX_BYTES - 1;
119 if (nSize <= UniSize) UniSize = (USHORT)nSize;
120
121 /* Check the size */
123 if (Result <= UniSize)
124 {
125 /* Convert the string */
126 RtlInitEmptyAnsiString(&VarValue, lpBuffer, UniSize);
127 Status = RtlUnicodeStringToAnsiString(&VarValue, &VarValueU, FALSE);
128 if (NT_SUCCESS(Status))
129 {
130 /* NULL-terminate and set the final length */
131 lpBuffer[VarValue.Length] = ANSI_NULL;
132 Result = VarValue.Length;
133 }
134 }
135 }
136
137 /* Release the lock */
139
140Quickie:
141 /* Free the strings */
142 RtlFreeUnicodeString(&VarNameU);
143 if (VarValueU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer);
144
145 /* Check if we succeeded */
146 if (!NT_SUCCESS(Status))
147 {
148 /* We did not, clear the result and set the error code */
150 Result = 0;
151 }
152
153 /* Return the result */
154 return Result;
155}
156
157/*
158 * @implemented
159 */
160DWORD
161WINAPI
165 IN DWORD nSize)
166{
167 UNICODE_STRING VarName, VarValue;
169 USHORT UniSize;
170
171 if (nSize <= (UNICODE_STRING_MAX_CHARS - 1))
172 {
173 if (nSize)
174 {
175 UniSize = (USHORT)nSize * sizeof(WCHAR) - sizeof(UNICODE_NULL);
176 }
177 else
178 {
179 UniSize = 0;
180 }
181 }
182 else
183 {
184 UniSize = UNICODE_STRING_MAX_BYTES - sizeof(UNICODE_NULL);
185 }
186
188 if (!NT_SUCCESS(Status))
189 {
191 return 0;
192 }
193
194 RtlInitEmptyUnicodeString(&VarValue, lpBuffer, UniSize);
195
196 Status = RtlQueryEnvironmentVariable_U(NULL, &VarName, &VarValue);
197 if (!NT_SUCCESS(Status))
198 {
200 {
201 return (VarValue.Length / sizeof(WCHAR)) + sizeof(ANSI_NULL);
202 }
204 return 0;
205 }
206
207 lpBuffer[VarValue.Length / sizeof(WCHAR)] = UNICODE_NULL;
208
209 return (VarValue.Length / sizeof(WCHAR));
210}
211
212/*
213 * @implemented
214 */
215BOOL
216WINAPI
219 IN LPCSTR lpValue)
220{
221 ANSI_STRING VarName, VarValue;
222 UNICODE_STRING VarNameU, VarValueU;
224
225 RtlInitAnsiString(&VarName, (LPSTR)lpName);
226 Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE);
227 if (NT_SUCCESS(Status))
228 {
229 if (lpValue)
230 {
231 RtlInitAnsiString(&VarValue, (LPSTR)lpValue);
232 Status = RtlAnsiStringToUnicodeString(&VarValueU, &VarValue, TRUE);
233 if (NT_SUCCESS(Status))
234 {
235 Status = RtlSetEnvironmentVariable(NULL, &VarNameU, &VarValueU);
236 RtlFreeUnicodeString(&VarValueU);
237 }
238 }
239 else
240 {
242 }
243
244 RtlFreeUnicodeString(&VarNameU);
245
246 if (NT_SUCCESS(Status)) return TRUE;
247 }
248
250 return FALSE;
251}
252
253/*
254 * @implemented
255 */
256BOOL
257WINAPI
260 IN LPCWSTR lpValue)
261{
262 UNICODE_STRING VarName, VarValue;
264
266 if (NT_SUCCESS(Status))
267 {
268 if (lpValue)
269 {
270 Status = RtlInitUnicodeStringEx(&VarValue, lpValue);
271 if (NT_SUCCESS(Status))
272 {
273 Status = RtlSetEnvironmentVariable(NULL, &VarName, &VarValue);
274 }
275 }
276 else
277 {
279 }
280
281 if (NT_SUCCESS(Status)) return TRUE;
282 }
283
285 return FALSE;
286}
287
288/*
289 * @implemented
290 */
291LPSTR
292WINAPI
294{
298 PCHAR Buffer = NULL;
299
301 p = Environment = NtCurrentPeb()->ProcessParameters->Environment;
302
303 do
304 {
305 p += wcslen(p) + 1;
306 } while (*p);
307
308 Length = p - Environment + 1;
309
311 if (NT_SUCCESS(Status))
312 {
313 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
314 if (Buffer)
315 {
317 if (!NT_SUCCESS(Status))
318 {
319 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
320 Buffer = NULL;
321
323 }
324 }
325 else
326 {
328 }
329 }
330 else
331 {
333 }
334
336 return Buffer;
337}
338
339/*
340 * @implemented
341 */
342LPWSTR
343WINAPI
345{
348
350
351 p = Environment = NtCurrentPeb()->ProcessParameters->Environment;
352
353 do
354 {
355 p += wcslen(p) + 1;
356 } while (*p);
357
358 Length = p - Environment + 1;
359
360 p = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
361 if (p)
362 {
364 }
365 else
366 {
368 }
369
371 return p;
372}
373
374/*
375 * @implemented
376 */
377BOOL
378WINAPI
380{
381 return RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings);
382}
383
384/*
385 * @implemented
386 */
387BOOL
388WINAPI
390{
391 return RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings);
392}
393
394/*
395 * @implemented
396 */
397DWORD
398WINAPI
400 IN LPSTR lpDst,
401 IN DWORD nSize)
402{
403 ANSI_STRING Source, Dest;
404 UNICODE_STRING SourceU, DestU;
406 ULONG Result = 0, Length;
407 USHORT UniSize;
409
410 /* Check if the size is too big to fit */
411 UniSize = UNICODE_STRING_MAX_CHARS - 2;
412 if (nSize <= UniSize) UniSize = (USHORT)nSize;
413
414 /* Clear the input buffer */
415 if (lpDst) *lpDst = ANSI_NULL;
416
417 /* Initialize all the strings */
418 RtlInitAnsiString(&Source, lpSrc);
419 RtlInitUnicodeString(&SourceU, NULL);
420 RtlInitUnicodeString(&DestU, NULL);
422 if (!NT_SUCCESS(Status)) goto Quickie;
423
424 /* If the string fit in, make space for a NULL char */
425 if (UniSize)
426 {
427 UniSize--;
428 }
429 else
430 {
431 /* No input size, so no string size */
432 UniSize = 0;
433 }
434
435 /* Allocate the value string buffer */
436 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize * sizeof(WCHAR));
437 if (!Buffer)
438 {
440 goto Quickie;
441 }
442
443 /* And initialize its string */
444 RtlInitEmptyUnicodeString(&DestU, Buffer, UniSize * sizeof(WCHAR));
445
446 /* Query the variable */
447 Length = 0;
448 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length);
449
450 /* Check if we didn't have enough space */
452 {
453 /* Fixup the length that the API returned */
454 DestU.MaximumLength = (SHORT)Length;
455
456 /* Free old Unicode buffer */
457 RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer);
458
459 /* Allocate new one */
460 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
461 if (Buffer)
462 {
463 /* Query the variable so we can know its size */
464 DestU.Buffer = Buffer;
465 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length);
466 if (NT_SUCCESS(Status))
467 {
468 /* Get the ASCII length of the variable, add a byte for NULL */
469 Result = RtlUnicodeStringToAnsiSize(&DestU) + sizeof(ANSI_NULL);
470 }
471 }
472 else
473 {
474 /* Set failure status */
476 DestU.Buffer = NULL;
477 }
478 }
479 else if (NT_SUCCESS(Status))
480 {
481 /* Check if the size is too big to fit */
482 UniSize = UNICODE_STRING_MAX_BYTES - 1;
483 if (nSize <= UniSize) UniSize = (USHORT)nSize;
484
485 /* Check the size */
487 if (Result <= UniSize)
488 {
489 /* Convert the string */
490 RtlInitEmptyAnsiString(&Dest, lpDst, UniSize);
491 Status = RtlUnicodeStringToAnsiString(&Dest, &DestU, FALSE);
492
493 /* Write a NULL-char in case of failure only */
494 if (!NT_SUCCESS(Status)) *lpDst = ANSI_NULL;
495 }
496 }
497Quickie:
498 /* Free the strings */
499 RtlFreeUnicodeString(&SourceU);
500 if (DestU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer);
501
502 /* Check if we succeeded */
503 if (!NT_SUCCESS(Status))
504 {
505 /* We did not, clear the result and set the error code */
507 Result = 0;
508 }
509
510 /* Return the result */
511 return Result;
512}
513
514/*
515 * @implemented
516 */
517DWORD
518WINAPI
520 IN LPWSTR lpDst,
521 IN DWORD nSize)
522{
525 USHORT UniSize;
526
527 UniSize = min(nSize, UNICODE_STRING_MAX_CHARS - 2);
528
530 RtlInitEmptyUnicodeString(&Destination, lpDst, UniSize * sizeof(WCHAR));
531
533 &Source,
535 &nSize);
537 {
538 return nSize / sizeof(WCHAR);
539 }
540
542 return 0;
543}
544
545/*
546 * @implemented
547 */
548BOOL
549WINAPI
551{
552 STUB;
553 return FALSE;
554}
555
556/*
557 * @implemented
558 */
559BOOL
560WINAPI
562{
563 STUB;
564 return FALSE;
565}
566
567/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#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:561
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:399
BOOL WINAPI FreeEnvironmentStringsA(IN LPSTR EnvironmentStrings)
Definition: environ.c:379
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
BOOL WINAPI SetEnvironmentStringsA(IN LPCH NewEnvironment)
Definition: environ.c:550
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:218
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat p
Definition: glext.h:8902
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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 *)
#define STUB
Definition: kernel32.h:27
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)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3016
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
_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:263
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteSize(_Out_ PULONG MbSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:145
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:399
WCHAR * LPWCH
Definition: ntbasedef.h:418
#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 SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define DECLSPEC_HOTPATCH
Definition: config.h:9
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
#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:4533
_In_ LPCSTR lpName
Definition: winbase.h:2814
LPWSTR WINAPI GetEnvironmentStringsW(void)
Definition: environ.c:344
#define GetEnvironmentStringsA
Definition: winbase.h:3838
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2109
#define WINAPI
Definition: msvc.h:6
_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
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185