:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / kernel32 / misc / env.c
1 /* $Id$
2  *
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)
8  * UPDATE HISTORY:
9  *                  Created 01/11/98
10  */
11
12 #include <ddk/ntddk.h>
13 #include <ntdll/rtl.h>
14 #include <windows.h>
15 #include <wchar.h>
16 #include <string.h>
17
18 #define NDEBUG
19 #include <kernel32/kernel32.h>
20 #include <kernel32/error.h>
21
22
23 /* FUNCTIONS ******************************************************************/
24
25 DWORD
26 STDCALL
27 GetEnvironmentVariableA (
28         LPCSTR  lpName,
29         LPSTR   lpBuffer,
30         DWORD   nSize
31         )
32 {
33         ANSI_STRING VarName;
34         ANSI_STRING VarValue;
35         UNICODE_STRING VarNameU;
36         UNICODE_STRING VarValueU;
37         NTSTATUS Status;
38
39         /* initialize unicode variable name string */
40         RtlInitAnsiString (&VarName,
41                            (LPSTR)lpName);
42         RtlAnsiStringToUnicodeString (&VarNameU,
43                                       &VarName,
44                                       TRUE);
45
46         /* initialize ansi variable value string */
47         VarValue.Length = 0;
48         VarValue.MaximumLength = nSize;
49         VarValue.Buffer = lpBuffer;
50
51         /* initialize unicode variable value string and allocate buffer */
52         VarValueU.Length = 0;
53         VarValueU.MaximumLength = nSize * sizeof(WCHAR);
54         VarValueU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
55                                             0,
56                                             VarValueU.MaximumLength);
57
58         /* get unicode environment variable */
59         Status = RtlQueryEnvironmentVariable_U (NULL,
60                                                 &VarNameU,
61                                                 &VarValueU);
62         if (!NT_SUCCESS(Status))
63         {
64                 /* free unicode buffer */
65                 RtlFreeHeap (RtlGetProcessHeap (),
66                              0,
67                              VarValueU.Buffer);
68
69                 /* free unicode variable name string */
70                 RtlFreeUnicodeString (&VarNameU);
71
72                 SetLastErrorByStatus (Status);
73                 if (Status == STATUS_BUFFER_TOO_SMALL)
74                 {
75                         return VarValueU.Length / sizeof(WCHAR) + 1;
76                 }
77                 else
78                 {
79                         return 0;
80                 }
81         }
82
83         /* convert unicode value string to ansi */
84         RtlUnicodeStringToAnsiString (&VarValue,
85                                       &VarValueU,
86                                       FALSE);
87
88         /* free unicode buffer */
89         RtlFreeHeap (RtlGetProcessHeap (),
90                      0,
91                      VarValueU.Buffer);
92
93         /* free unicode variable name string */
94         RtlFreeUnicodeString (&VarNameU);
95
96         return (VarValueU.Length / sizeof(WCHAR));
97 }
98
99
100 DWORD
101 STDCALL
102 GetEnvironmentVariableW (
103         LPCWSTR lpName,
104         LPWSTR  lpBuffer,
105         DWORD   nSize
106         )
107 {
108         UNICODE_STRING VarName;
109         UNICODE_STRING VarValue;
110         NTSTATUS Status;
111
112         RtlInitUnicodeString (&VarName,
113                               lpName);
114
115         VarValue.Length = 0;
116         VarValue.MaximumLength = nSize * sizeof(WCHAR);
117         VarValue.Buffer = lpBuffer;
118
119         Status = RtlQueryEnvironmentVariable_U (NULL,
120                                                 &VarName,
121                                                 &VarValue);
122         if (!NT_SUCCESS(Status))
123         {
124                 SetLastErrorByStatus (Status);
125                 if (Status == STATUS_BUFFER_TOO_SMALL)
126                 {
127                         return (VarValue.Length / sizeof(WCHAR)) + 1;
128                 }
129                 else
130                 {
131                         return 0;
132                 }
133         }
134
135         return (VarValue.Length / sizeof(WCHAR));
136 }
137
138
139 WINBOOL
140 STDCALL
141 SetEnvironmentVariableA (
142         LPCSTR  lpName,
143         LPCSTR  lpValue
144         )
145 {
146         ANSI_STRING VarName;
147         ANSI_STRING VarValue;
148         UNICODE_STRING VarNameU;
149         UNICODE_STRING VarValueU;
150         NTSTATUS Status;
151
152         DPRINT("SetEnvironmentVariableA(Name '%s', Value '%s')\n", lpName, lpValue);
153
154         RtlInitAnsiString (&VarName,
155                            (LPSTR)lpName);
156         RtlAnsiStringToUnicodeString (&VarNameU,
157                                       &VarName,
158                                       TRUE);
159
160         RtlInitAnsiString (&VarValue,
161                            (LPSTR)lpValue);
162         RtlAnsiStringToUnicodeString (&VarValueU,
163                                       &VarValue,
164                                       TRUE);
165
166         Status = RtlSetEnvironmentVariable (NULL,
167                                             &VarNameU,
168                                             &VarValueU);
169
170         RtlFreeUnicodeString (&VarNameU);
171         RtlFreeUnicodeString (&VarValueU);
172
173         if (!NT_SUCCESS(Status))
174         {
175                 SetLastErrorByStatus (Status);
176                 return FALSE;
177         }
178
179         return TRUE;
180 }
181
182
183 WINBOOL
184 STDCALL
185 SetEnvironmentVariableW (
186         LPCWSTR lpName,
187         LPCWSTR lpValue
188         )
189 {
190         UNICODE_STRING VarName;
191         UNICODE_STRING VarValue;
192         NTSTATUS Status;
193
194         DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName, lpValue);
195
196         RtlInitUnicodeString (&VarName,
197                               lpName);
198
199         RtlInitUnicodeString (&VarValue,
200                               lpValue);
201
202         Status = RtlSetEnvironmentVariable (NULL,
203                                             &VarName,
204                                             &VarValue);
205         if (!NT_SUCCESS(Status))
206         {
207                 SetLastErrorByStatus (Status);
208                 return FALSE;
209         }
210
211         return TRUE;
212 }
213
214
215 DWORD
216 STDCALL
217 GetVersion(VOID)
218 {
219         DWORD Version = 0;
220         OSVERSIONINFO VersionInformation;
221         GetVersionExW(&VersionInformation);
222
223         Version |= ( VersionInformation.dwMajorVersion << 8 );
224         Version |= VersionInformation.dwMinorVersion;
225
226         Version |= ( VersionInformation.dwPlatformId << 16 );
227
228         return Version;
229 }
230
231
232 WINBOOL
233 STDCALL
234 GetVersionExW(
235     LPOSVERSIONINFO lpVersionInformation
236     )
237 {
238         lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
239         lpVersionInformation->dwMajorVersion = 4;
240         lpVersionInformation->dwMinorVersion = 0;
241         lpVersionInformation->dwBuildNumber = 12;
242         lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
243         lstrcpyW((WCHAR *)lpVersionInformation->szCSDVersion,L"Ariadne was here...");
244         return TRUE;
245 }
246
247
248 WINBOOL
249 STDCALL
250 GetVersionExA(
251     LPOSVERSIONINFO lpVersionInformation
252     )
253 {
254         lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
255         lpVersionInformation->dwMajorVersion = 4;
256         lpVersionInformation->dwMinorVersion = 0;
257         lpVersionInformation->dwBuildNumber = 12;
258         lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
259         lstrcpyA((char *)lpVersionInformation->szCSDVersion,"ReactOs Pre-Alpha");
260         return TRUE;
261 }
262
263
264 LPSTR
265 STDCALL
266 GetEnvironmentStringsA (
267         VOID
268         )
269 {
270         UNICODE_STRING UnicodeString;
271         ANSI_STRING AnsiString;
272         PWCHAR EnvU;
273         PWCHAR PtrU;
274         ULONG  Length;
275         PCHAR EnvPtr = NULL;
276
277         EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment);
278
279         if (EnvU == NULL)
280                 return NULL;
281
282         if (*EnvU == 0)
283                 return NULL;
284
285         /* get environment size */
286         PtrU = EnvU;
287         while (*PtrU)
288         {
289                 while (*PtrU)
290                         PtrU++;
291                 PtrU++;
292         }
293         Length = (ULONG)(PtrU - EnvU);
294         DPRINT("Length %lu\n", Length);
295
296         /* allocate environment buffer */
297         EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (),
298                                   0,
299                                   Length + 1);
300         DPRINT("EnvPtr %p\n", EnvPtr);
301
302         /* convert unicode environment to ansi */
303         UnicodeString.MaximumLength = Length * sizeof(WCHAR) + sizeof(WCHAR);
304         UnicodeString.Buffer = EnvU;
305
306         AnsiString.MaximumLength = Length + 1;
307         AnsiString.Length = 0;
308         AnsiString.Buffer = EnvPtr;
309
310         DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer);
311
312         while (*(UnicodeString.Buffer))
313         {
314                 UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR);
315                 UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR);
316                 if (UnicodeString.Length > 0)
317                 {
318                         AnsiString.Length = 0;
319                         AnsiString.MaximumLength = Length + 1 - (AnsiString.Buffer - EnvPtr);
320
321                         RtlUnicodeStringToAnsiString (&AnsiString,
322                                                       &UnicodeString,
323                                                       FALSE);
324
325                         AnsiString.Buffer += (AnsiString.Length + 1);
326                         UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1);
327                 }
328         }
329         *(AnsiString.Buffer) = 0;
330
331         return EnvPtr;
332 }
333
334
335 LPWSTR
336 STDCALL
337 GetEnvironmentStringsW (
338         VOID
339         )
340 {
341         return (LPWSTR)(NtCurrentPeb ()->ProcessParameters->Environment);
342 }
343
344
345 WINBOOL
346 STDCALL
347 FreeEnvironmentStringsA (
348         LPSTR   EnvironmentStrings
349         )
350 {
351         if (EnvironmentStrings == NULL)
352                 return FALSE;
353
354         RtlFreeHeap (RtlGetProcessHeap (),
355                      0,
356                      EnvironmentStrings);
357
358         return TRUE;
359 }
360
361
362 WINBOOL
363 STDCALL
364 FreeEnvironmentStringsW (
365         LPWSTR  EnvironmentStrings
366         )
367 {
368         return TRUE;
369 }
370
371
372 DWORD
373 STDCALL
374 ExpandEnvironmentStringsA (
375         LPCSTR  lpSrc,
376         LPSTR   lpDst,
377         DWORD   nSize
378         )
379 {
380         ANSI_STRING Source;
381         ANSI_STRING Destination;
382         UNICODE_STRING SourceU;
383         UNICODE_STRING DestinationU;
384         NTSTATUS Status;
385         ULONG Length = 0;
386
387         RtlInitAnsiString (&Source,
388                            (LPSTR)lpSrc);
389         RtlAnsiStringToUnicodeString (&SourceU,
390                                       &Source,
391                                       TRUE);
392
393         Destination.Length = 0;
394         Destination.MaximumLength = nSize;
395         Destination.Buffer = lpDst,
396
397         DestinationU.Length = 0;
398         DestinationU.MaximumLength = nSize * sizeof(WCHAR);
399         DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
400                                                0,
401                                                DestinationU.MaximumLength);
402
403         Status = RtlExpandEnvironmentStrings_U (NULL,
404                                                 &SourceU,
405                                                 &DestinationU,
406                                                 &Length);
407
408         RtlFreeUnicodeString (&SourceU);
409
410         if (!NT_SUCCESS(Status))
411         {
412                 RtlFreeHeap (RtlGetProcessHeap (),
413                              0,
414                              DestinationU.Buffer);
415                 SetLastErrorByStatus (Status);
416                 return 0;
417         }
418
419         RtlUnicodeStringToAnsiString (&Destination,
420                                       &DestinationU,
421                                       FALSE);
422
423         RtlFreeHeap (RtlGetProcessHeap (),
424                      0,
425                      DestinationU.Buffer);
426
427         return (Length / sizeof(WCHAR));
428 }
429
430
431 DWORD
432 STDCALL
433 ExpandEnvironmentStringsW (
434         LPCWSTR lpSrc,
435         LPWSTR  lpDst,
436         DWORD   nSize
437         )
438 {
439         UNICODE_STRING Source;
440         UNICODE_STRING Destination;
441         NTSTATUS Status;
442         ULONG Length = 0;
443
444         RtlInitUnicodeString (&Source,
445                               (LPWSTR)lpSrc);
446
447         Destination.Length = 0;
448         Destination.MaximumLength = nSize * sizeof(WCHAR);
449         Destination.Buffer = lpDst;
450
451         Status = RtlExpandEnvironmentStrings_U (NULL,
452                                                 &Source,
453                                                 &Destination,
454                                                 &Length);
455         if (!NT_SUCCESS(Status))
456         {
457                 SetLastErrorByStatus (Status);
458                 return 0;
459         }
460
461         return (Length / sizeof(WCHAR));
462 }
463
464 /* EOF */