ReactOS 0.4.16-dev-2207-geb15453
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 if (lpBuffer)
208 lpBuffer[VarValue.Length / sizeof(WCHAR)] = UNICODE_NULL;
209
210 return (VarValue.Length / sizeof(WCHAR));
211}
212
213/*
214 * @implemented
215 */
216BOOL
217WINAPI
220 IN LPCSTR lpValue)
221{
222 ANSI_STRING VarName, VarValue;
223 UNICODE_STRING VarNameU, VarValueU;
225
226 RtlInitAnsiString(&VarName, (LPSTR)lpName);
227 Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE);
228 if (NT_SUCCESS(Status))
229 {
230 if (lpValue)
231 {
232 RtlInitAnsiString(&VarValue, (LPSTR)lpValue);
233 Status = RtlAnsiStringToUnicodeString(&VarValueU, &VarValue, TRUE);
234 if (NT_SUCCESS(Status))
235 {
236 Status = RtlSetEnvironmentVariable(NULL, &VarNameU, &VarValueU);
237 RtlFreeUnicodeString(&VarValueU);
238 }
239 }
240 else
241 {
243 }
244
245 RtlFreeUnicodeString(&VarNameU);
246
247 if (NT_SUCCESS(Status)) return TRUE;
248 }
249
251 return FALSE;
252}
253
254/*
255 * @implemented
256 */
257BOOL
258WINAPI
261 IN LPCWSTR lpValue)
262{
263 UNICODE_STRING VarName, VarValue;
265
267 if (NT_SUCCESS(Status))
268 {
269 if (lpValue)
270 {
271 Status = RtlInitUnicodeStringEx(&VarValue, lpValue);
272 if (NT_SUCCESS(Status))
273 {
274 Status = RtlSetEnvironmentVariable(NULL, &VarName, &VarValue);
275 }
276 }
277 else
278 {
280 }
281
282 if (NT_SUCCESS(Status)) return TRUE;
283 }
284
286 return FALSE;
287}
288
289/*
290 * @implemented
291 */
292LPSTR
293WINAPI
295{
299 PCHAR Buffer = NULL;
300
302 p = Environment = NtCurrentPeb()->ProcessParameters->Environment;
303
304 do
305 {
306 p += wcslen(p) + 1;
307 } while (*p);
308
309 Length = p - Environment + 1;
310
312 if (NT_SUCCESS(Status))
313 {
314 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
315 if (Buffer)
316 {
318 if (!NT_SUCCESS(Status))
319 {
320 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
321 Buffer = NULL;
322
324 }
325 }
326 else
327 {
329 }
330 }
331 else
332 {
334 }
335
337 return Buffer;
338}
339
340/*
341 * @implemented
342 */
343LPWSTR
344WINAPI
346{
349
351
352 p = Environment = NtCurrentPeb()->ProcessParameters->Environment;
353
354 do
355 {
356 p += wcslen(p) + 1;
357 } while (*p);
358
359 Length = p - Environment + 1;
360
361 p = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
362 if (p)
363 {
365 }
366 else
367 {
369 }
370
372 return p;
373}
374
375/*
376 * @implemented
377 */
378BOOL
379WINAPI
381{
382 return RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings);
383}
384
385/*
386 * @implemented
387 */
388BOOL
389WINAPI
391{
392 return RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings);
393}
394
395/*
396 * @implemented
397 */
398DWORD
399WINAPI
401 IN LPSTR lpDst,
402 IN DWORD nSize)
403{
404 ANSI_STRING Source, Dest;
405 UNICODE_STRING SourceU, DestU;
407 ULONG Result = 0, Length;
408 USHORT UniSize;
410
411 /* Check if the size is too big to fit */
412 UniSize = UNICODE_STRING_MAX_CHARS - 2;
413 if (nSize <= UniSize) UniSize = (USHORT)nSize;
414
415 /* Clear the input buffer */
416 if (lpDst) *lpDst = ANSI_NULL;
417
418 /* Initialize all the strings */
419 RtlInitAnsiString(&Source, lpSrc);
420 RtlInitUnicodeString(&SourceU, NULL);
421 RtlInitUnicodeString(&DestU, NULL);
423 if (!NT_SUCCESS(Status)) goto Quickie;
424
425 /* If the string fit in, make space for a NULL char */
426 if (UniSize)
427 {
428 UniSize--;
429 }
430 else
431 {
432 /* No input size, so no string size */
433 UniSize = 0;
434 }
435
436 /* Allocate the value string buffer */
437 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize * sizeof(WCHAR));
438 if (!Buffer)
439 {
441 goto Quickie;
442 }
443
444 /* And initialize its string */
445 RtlInitEmptyUnicodeString(&DestU, Buffer, UniSize * sizeof(WCHAR));
446
447 /* Query the variable */
448 Length = 0;
449 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length);
450
451 /* Check if we didn't have enough space */
453 {
454 /* Fixup the length that the API returned */
455 DestU.MaximumLength = (SHORT)Length;
456
457 /* Free old Unicode buffer */
458 RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer);
459
460 /* Allocate new one */
461 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
462 if (Buffer)
463 {
464 /* Query the variable so we can know its size */
465 DestU.Buffer = Buffer;
466 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length);
467 if (NT_SUCCESS(Status))
468 {
469 /* Get the ASCII length of the variable, add a byte for NULL */
470 Result = RtlUnicodeStringToAnsiSize(&DestU) + sizeof(ANSI_NULL);
471 }
472 }
473 else
474 {
475 /* Set failure status */
477 DestU.Buffer = NULL;
478 }
479 }
480 else if (NT_SUCCESS(Status))
481 {
482 /* Check if the size is too big to fit */
483 UniSize = UNICODE_STRING_MAX_BYTES - 1;
484 if (nSize <= UniSize) UniSize = (USHORT)nSize;
485
486 /* Check the size */
488 if (Result <= UniSize)
489 {
490 /* Convert the string */
491 RtlInitEmptyAnsiString(&Dest, lpDst, UniSize);
492 Status = RtlUnicodeStringToAnsiString(&Dest, &DestU, FALSE);
493
494 /* Write a NULL-char in case of failure only */
495 if (!NT_SUCCESS(Status)) *lpDst = ANSI_NULL;
496 }
497 }
498Quickie:
499 /* Free the strings */
500 RtlFreeUnicodeString(&SourceU);
501 if (DestU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer);
502
503 /* Check if we succeeded */
504 if (!NT_SUCCESS(Status))
505 {
506 /* We did not, clear the result and set the error code */
508 Result = 0;
509 }
510
511 /* Return the result */
512 return Result;
513}
514
515/*
516 * @implemented
517 */
518DWORD
519WINAPI
521 IN LPWSTR lpDst,
522 IN DWORD nSize)
523{
526 USHORT UniSize;
527
528 UniSize = min(nSize, UNICODE_STRING_MAX_CHARS - 2);
529
531 RtlInitEmptyUnicodeString(&Destination, lpDst, UniSize * sizeof(WCHAR));
532
534 &Source,
536 &nSize);
538 {
539 return nSize / sizeof(WCHAR);
540 }
541
543 return 0;
544}
545
546/*
547 * @implemented
548 */
549BOOL
550WINAPI
552{
553 STUB;
554 return FALSE;
555}
556
557/*
558 * @implemented
559 */
560BOOL
561WINAPI
563{
564 STUB;
565 return FALSE;
566}
567
568/* 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:562
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:400
BOOL WINAPI FreeEnvironmentStringsA(IN LPSTR EnvironmentStrings)
Definition: environ.c:380
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:390
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:260
BOOL WINAPI SetEnvironmentStringsA(IN LPCH NewEnvironment)
Definition: environ.c:551
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:520
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:219
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:25
GLfloat GLfloat p
Definition: glext.h:8902
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:3051
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
_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: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: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 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
#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
_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
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182