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