60a1addd42e6f54bc72b5ab777b0148112dfa09e
[reactos.git] / reactos / lib / kernel32 / misc / env.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/misc/env.c
5 * PURPOSE: Environment functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * Created 01/11/98
9 */
10
11 #include <windows.h>
12 #include <ddk/ntddk.h>
13 #include <wchar.h>
14 #include <string.h>
15
16 #include <kernel32/kernel32.h>
17
18 #define MAX_ENVIRONMENT_VARS 255
19 #define MAX_VALUE 1024
20
21 typedef struct _ENV_ELEMENT
22 {
23 UNICODE_STRING Name;
24 UNICODE_STRING Value;
25 WINBOOL Valid;
26 } ENV_ELEMENT;
27
28 ENV_ELEMENT Environment[MAX_ENVIRONMENT_VARS+1];
29 UINT nEnvVar = 0;
30
31 DWORD STDCALL GetEnvironmentVariableA(LPCSTR lpName,
32 LPSTR lpBuffer,
33 DWORD nSize)
34 {
35 WCHAR BufferW[MAX_VALUE];
36 WCHAR NameW[MAX_PATH];
37 DWORD RetValue;
38 int i=0;
39
40 while ((*lpName)!=0 && i < MAX_PATH)
41 {
42 NameW[i] = *lpName;
43 lpName++;
44 i++;
45 }
46 NameW[i] = 0;
47
48 RetValue = GetEnvironmentVariableW(NameW,BufferW,nSize);
49 for(i=0;i<nSize;i++)
50 lpBuffer[i] = (char)BufferW[i];
51 return RetValue;
52 }
53
54 DWORD
55 STDCALL
56 GetEnvironmentVariableW(
57 LPCWSTR lpName,
58 LPWSTR lpBuffer,
59 DWORD nSize
60 )
61 {
62 UINT NameLen;
63 UINT i;
64 NameLen = lstrlenW(lpName);
65 i = 0;
66
67 while (i < nEnvVar)
68 {
69 if ( _wcsnicmp(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length/sizeof(WCHAR))) != 0 ) {
70 lstrcpynW(lpBuffer,Environment[i].Value.Buffer,min(nSize,Environment[i].Value.Length/sizeof(WCHAR)));
71
72 return lstrlenW(Environment[i].Value.Buffer);
73
74 }
75 i++;
76 }
77 return 0;
78
79 }
80
81
82
83 WINBOOL
84 STDCALL
85 SetEnvironmentVariableA(
86 LPCSTR lpName,
87 LPCSTR lpValue
88 )
89 {
90 WCHAR NameW[MAX_PATH];
91 WCHAR ValueW[MAX_VALUE];
92
93 int i=0;
94 while ((*lpName)!=0 && i < MAX_PATH)
95 {
96 NameW[i] = *lpName;
97 lpName++;
98 i++;
99 }
100 NameW[i] = 0;
101
102 i = 0;
103
104 while ((*lpValue)!=0 && i < MAX_PATH)
105 {
106 ValueW[i] = *lpValue;
107 lpValue++;
108 i++;
109 }
110 ValueW[i] = 0;
111 return SetEnvironmentVariableW(NameW,ValueW);
112
113
114 }
115
116 WINBOOL
117 STDCALL
118 SetEnvironmentVariableW(
119 LPCWSTR lpName,
120 LPCWSTR lpValue
121 )
122 {
123 UINT NameLen, ValueLen;
124 UINT i;
125 WCHAR *NameBuffer;
126 WCHAR *ValueBuffer;
127 NameLen = lstrlenW(lpName);
128 ValueLen = lstrlenW(lpValue);
129 i = 0;
130
131 while (i < nEnvVar)
132 {
133 if ( _wcsnicmp(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length/sizeof(WCHAR))) != 0 ) {
134 if ( lpValue != NULL ) {
135 lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,Environment[i].Value.MaximumLength/sizeof(WCHAR)));
136 return TRUE;
137 }
138 else {
139 Environment[i].Valid = FALSE;
140 Environment[i].Value.Length = 0;
141 Environment[i].Name.Length = 0;
142 return FALSE;
143 }
144
145
146
147 }
148 i++;
149 }
150
151 if ( nEnvVar >= MAX_ENVIRONMENT_VARS )
152 return FALSE;
153
154 while (i < nEnvVar)
155 {
156 if ( Environment[i].Valid == FALSE )
157 break;
158 i++;
159 }
160 if ( i == nEnvVar ) {
161 NameBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,MAX_PATH*sizeof(WCHAR) );
162 ValueBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,MAX_VALUE*sizeof(WCHAR) );
163
164 Environment[i].Name.Buffer = NameBuffer;
165 Environment[i].Name.MaximumLength = MAX_PATH*sizeof(WCHAR);
166
167 Environment[i].Value.Buffer = ValueBuffer;
168 Environment[i].Value.MaximumLength = MAX_VALUE*sizeof(WCHAR);
169 nEnvVar++;
170 }
171 Environment[i].Valid = TRUE;
172
173 lstrcpynW(Environment[i].Name.Buffer,lpValue,min(NameLen,(Environment[i].Name.MaximumLength-sizeof(WCHAR))/sizeof(WCHAR)));
174 Environment[i].Name.Length = NameLen*sizeof(WCHAR);
175
176
177 lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,(Environment[i].Value.MaximumLength-sizeof(WCHAR)))/sizeof(WCHAR));
178 Environment[i].Value.Length = ValueLen*sizeof(WCHAR);
179
180
181
182 return TRUE;
183
184 }
185
186 DWORD
187 STDCALL
188 GetVersion(VOID)
189 {
190 DWORD Version = 0;
191 OSVERSIONINFO VersionInformation;
192 GetVersionExW(&VersionInformation);
193
194 Version |= ( VersionInformation.dwMajorVersion << 8 );
195 Version |= VersionInformation.dwMinorVersion;
196
197 Version |= ( VersionInformation.dwPlatformId << 16 );
198
199 return Version;
200
201 }
202
203
204
205 WINBOOL
206 STDCALL
207 GetVersionExW(
208 LPOSVERSIONINFO lpVersionInformation
209 )
210 {
211 lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
212 lpVersionInformation->dwMajorVersion = 4;
213 lpVersionInformation->dwMinorVersion = 0;
214 lpVersionInformation->dwBuildNumber = 12;
215 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
216 lstrcpyW((WCHAR *)lpVersionInformation->szCSDVersion,L"Ariadne was here...");
217 return TRUE;
218 }
219
220 WINBOOL
221 STDCALL
222 GetVersionExA(
223 LPOSVERSIONINFO lpVersionInformation
224 )
225 {
226 lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
227 lpVersionInformation->dwMajorVersion = 4;
228 lpVersionInformation->dwMinorVersion = 0;
229 lpVersionInformation->dwBuildNumber = 12;
230 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
231 lstrcpyA((char *)lpVersionInformation->szCSDVersion,"ReactOs Pre-Alpha");
232 return TRUE;
233 }
234
235
236
237
238
239 LPSTR STDCALL GetEnvironmentStringsA(VOID)
240 {
241 #if 0
242 WCHAR *EnvironmentStringsW;
243 char *EnvironmentStringsA;
244 int size = 0;
245 int i;
246 #endif
247
248 return(NULL);
249
250 /* FIXME: This doesn't work */
251 #if 0
252 EnvironmentStringsW = GetEnvironmentStringsW();
253 EnvironmentStringsA = (char *)EnvironmentStringsW;
254
255 for(i=0;i<nEnvVar;i++)
256 {
257 if ( Environment[i].Valid )
258 {
259 size += Environment[i].Name.Length;
260 size += sizeof(WCHAR); // =
261 size += Environment[i].Value.Length;
262 size += sizeof(WCHAR); // zero
263 }
264 }
265 size += sizeof(WCHAR);
266 size /= sizeof(WCHAR);
267 for(i=0;i<size;i++)
268 EnvironmentStringsA[i] = (char)EnvironmentStringsW[i];
269 return EnvironmentStringsA;
270 #endif
271 }
272
273
274 LPWSTR STDCALL GetEnvironmentStringsW(VOID)
275 {
276 #if 0
277 int size = 0;
278 int i;
279 WCHAR *EnvironmentString;
280 WCHAR *EnvironmentStringSave;
281 #endif
282
283 return(NULL);
284
285 /* FIXME: This doesn't work, why not? */
286 #if 0
287 for(i=0;i<nEnvVar;i++)
288 {
289 if ( Environment[i].Valid )
290 {
291 size += Environment[i].Name.Length;
292 size += sizeof(WCHAR); // =
293 size += Environment[i].Value.Length;
294 size += sizeof(WCHAR); // zero
295 }
296 }
297 size += sizeof(WCHAR); // extra zero
298 DPRINT("size %d\n",size);
299 EnvironmentString = (WCHAR *)HeapAlloc(GetProcessHeap(),
300 HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
301 size);
302 DPRINT("EnvironmentString %x\n",EnvironmentString);
303 EnvironmentStringSave = EnvironmentString;
304 for(i=0;i<nEnvVar;i++)
305 {
306 if ( Environment[i].Valid )
307 {
308 wcscpy(EnvironmentString,Environment[i].Name.Buffer);
309 wcscat(EnvironmentString,L"=");
310 wcscat(EnvironmentString,Environment[i].Value.Buffer);
311
312 size = Environment[i].Name.Length;
313 size += sizeof(WCHAR); // =
314 size += Environment[i].Value.Length;
315 size += sizeof(WCHAR); // zero
316 EnvironmentString += (size/sizeof(WCHAR));
317 }
318 }
319 *EnvironmentString = 0;
320 return EnvironmentStringSave;
321 #endif
322 }
323
324
325 WINBOOL
326 STDCALL
327 FreeEnvironmentStringsA(
328 LPSTR EnvironmentStrings
329 )
330 {
331 if ( EnvironmentStrings == NULL )
332 return FALSE;
333 HeapFree(GetProcessHeap(),0,EnvironmentStrings);
334 return TRUE;
335 }
336
337 WINBOOL
338 STDCALL
339 FreeEnvironmentStringsW(
340 LPWSTR EnvironmentStrings
341 )
342 {
343 if ( EnvironmentStrings == NULL )
344 return FALSE;
345 HeapFree(GetProcessHeap(),0,EnvironmentStrings);
346 return TRUE;
347 }
348
349
350 int ExpandVariableA(
351 LPCSTR lpSrc, LPSTR lpDst, DWORD nSize , DWORD *nWritten)
352 {
353 int nVar = 0;
354 LPSTR lpVar;
355 LPSTR lpEnd;
356
357 if ( nWritten == NULL )
358 return -1;
359
360 if ( *lpSrc != '%' ) {
361 return -1;
362 }
363
364
365 lpVar = (LPSTR)lpSrc;
366 lpVar++;
367
368
369 lpEnd = strchr( lpVar, '%' );
370 if ( lpEnd == NULL ) {
371 return -1;
372 }
373 else
374 *lpEnd = 0;
375
376 nWritten = GetEnvironmentVariableA(lpVar,lpDst,nSize);
377 *lpEnd = '%';
378
379 if ( nWritten == 0 )
380 return -1;
381
382 if ( nWritten > nSize )
383 return -1;
384
385 return (lpEnd - lpVar) -1;
386 }
387
388
389 DWORD STDCALL ExpandEnvironmentStringsA(
390 LPCSTR lpSrc, LPSTR lpDst, DWORD nSize
391 )
392 {
393 DWORD v;
394 DWORD bw;
395
396 while(*lpSrc != 0 && nSize > 0 )
397 {
398 if ( *lpSrc == '%' ) {
399 v = ExpandVariableA(lpSrc,lpDst,nSize , &bw);
400 if ( v == -1 ) {
401 *lpDst = *lpSrc;
402 lpDst++;
403 lpSrc++;
404 nSize--;
405 }
406 else {
407 lpSrc+=v;
408 lpDst+=bw;
409 nSize-=bw;
410 }
411 }
412 else {
413
414 *lpDst = *lpSrc;
415 lpDst++;
416 lpSrc++;
417 nSize--;
418
419 }
420
421 }
422
423 }
424
425 int ExpandVariableW(
426 LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize , DWORD *nWritten)
427 {
428 LPWSTR lpVar;
429 LPWSTR lpEnd;
430
431 if ( nWritten == NULL )
432 return -1;
433
434 if ( *lpSrc != L'%' ) {
435 return -1;
436 }
437
438
439 lpVar = (LPWSTR)lpSrc;
440 lpVar++;
441
442
443 lpEnd = wcschr( lpVar, L'%' );
444 if ( lpEnd == NULL ) {
445 return -1;
446 }
447 else
448 *lpEnd = 0;
449
450 nWritten = GetEnvironmentVariableW(lpVar,lpDst,nSize);
451 *lpEnd = L'%';
452
453 if ( nWritten == 0 )
454 return -1;
455
456 if ( nWritten > nSize )
457 return -1;
458
459 return ((lpEnd - lpVar)/2) -1;
460 }
461
462
463 DWORD STDCALL ExpandEnvironmentStringsW(
464 LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize
465 )
466 {
467 DWORD v;
468 DWORD bw;
469
470 while(*lpSrc != 0 && nSize > 0 )
471 {
472 if ( *lpSrc == L'%' ) {
473 v = ExpandVariableW(lpSrc,lpDst,nSize , &bw);
474 if ( v == -1 ) {
475 *lpDst = *lpSrc;
476 lpDst++;
477 lpSrc++;
478 nSize--;
479 }
480 else {
481 lpSrc+=v;
482 lpDst+=bw;
483 nSize-=bw;
484 }
485 }
486 else {
487
488 *lpDst = *lpSrc;
489 lpDst++;
490 lpSrc++;
491 nSize--;
492
493 }
494
495 }
496
497 }
498