1998-12-04 18:28:13 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS system libraries
|
|
|
|
* FILE: lib/kernel32/misc/env.c
|
|
|
|
* PURPOSE: Environment functions
|
|
|
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 01/11/98
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
#include <ddk/ntddk.h>
|
1999-03-19 05:55:55 +00:00
|
|
|
#include <wchar.h>
|
1998-12-04 18:28:13 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
#include <kernel32/kernel32.h>
|
|
|
|
|
1998-12-04 18:28:13 +00:00
|
|
|
#define MAX_ENVIRONMENT_VARS 255
|
1999-01-16 02:11:45 +00:00
|
|
|
#define MAX_VALUE 1024
|
1998-12-04 18:28:13 +00:00
|
|
|
|
|
|
|
typedef struct _ENV_ELEMENT
|
|
|
|
{
|
|
|
|
UNICODE_STRING Name;
|
|
|
|
UNICODE_STRING Value;
|
1999-01-16 02:11:45 +00:00
|
|
|
WINBOOL Valid;
|
1998-12-04 18:28:13 +00:00
|
|
|
} ENV_ELEMENT;
|
|
|
|
|
|
|
|
ENV_ELEMENT Environment[MAX_ENVIRONMENT_VARS+1];
|
|
|
|
UINT nEnvVar = 0;
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
DWORD STDCALL GetEnvironmentVariableA(LPCSTR lpName,
|
|
|
|
LPSTR lpBuffer,
|
|
|
|
DWORD nSize)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
1999-05-29 00:15:17 +00:00
|
|
|
WCHAR BufferW[MAX_VALUE];
|
|
|
|
WCHAR NameW[MAX_PATH];
|
|
|
|
DWORD RetValue;
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
while ((*lpName)!=0 && i < MAX_PATH)
|
|
|
|
{
|
|
|
|
NameW[i] = *lpName;
|
|
|
|
lpName++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
NameW[i] = 0;
|
|
|
|
|
|
|
|
RetValue = GetEnvironmentVariableW(NameW,BufferW,nSize);
|
|
|
|
for(i=0;i<nSize;i++)
|
|
|
|
lpBuffer[i] = (char)BufferW[i];
|
|
|
|
return RetValue;
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
|
|
|
DWORD
|
|
|
|
STDCALL
|
|
|
|
GetEnvironmentVariableW(
|
|
|
|
LPCWSTR lpName,
|
|
|
|
LPWSTR lpBuffer,
|
|
|
|
DWORD nSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT NameLen;
|
|
|
|
UINT i;
|
|
|
|
NameLen = lstrlenW(lpName);
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
while (i < nEnvVar)
|
|
|
|
{
|
1999-07-29 21:25:04 +00:00
|
|
|
if ( _wcsnicmp(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length/sizeof(WCHAR))) != 0 ) {
|
1999-01-16 02:11:45 +00:00
|
|
|
lstrcpynW(lpBuffer,Environment[i].Value.Buffer,min(nSize,Environment[i].Value.Length/sizeof(WCHAR)));
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-01-16 02:11:45 +00:00
|
|
|
return lstrlenW(Environment[i].Value.Buffer);
|
1998-12-04 18:28:13 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-01-16 02:11:45 +00:00
|
|
|
|
|
|
|
WINBOOL
|
|
|
|
STDCALL
|
|
|
|
SetEnvironmentVariableA(
|
|
|
|
LPCSTR lpName,
|
|
|
|
LPCSTR lpValue
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-01-16 02:11:45 +00:00
|
|
|
WCHAR NameW[MAX_PATH];
|
|
|
|
WCHAR ValueW[MAX_VALUE];
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-01-16 02:11:45 +00:00
|
|
|
int i=0;
|
|
|
|
while ((*lpName)!=0 && i < MAX_PATH)
|
|
|
|
{
|
|
|
|
NameW[i] = *lpName;
|
|
|
|
lpName++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
NameW[i] = 0;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
while ((*lpValue)!=0 && i < MAX_PATH)
|
|
|
|
{
|
|
|
|
ValueW[i] = *lpValue;
|
|
|
|
lpValue++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
ValueW[i] = 0;
|
|
|
|
return SetEnvironmentVariableW(NameW,ValueW);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
|
|
|
WINBOOL
|
|
|
|
STDCALL
|
|
|
|
SetEnvironmentVariableW(
|
|
|
|
LPCWSTR lpName,
|
|
|
|
LPCWSTR lpValue
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT NameLen, ValueLen;
|
|
|
|
UINT i;
|
|
|
|
WCHAR *NameBuffer;
|
|
|
|
WCHAR *ValueBuffer;
|
|
|
|
NameLen = lstrlenW(lpName);
|
|
|
|
ValueLen = lstrlenW(lpValue);
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
while (i < nEnvVar)
|
|
|
|
{
|
1999-07-29 21:25:04 +00:00
|
|
|
if ( _wcsnicmp(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length/sizeof(WCHAR))) != 0 ) {
|
1999-01-16 02:11:45 +00:00
|
|
|
if ( lpValue != NULL ) {
|
|
|
|
lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,Environment[i].Value.MaximumLength/sizeof(WCHAR)));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Environment[i].Valid = FALSE;
|
|
|
|
Environment[i].Value.Length = 0;
|
|
|
|
Environment[i].Name.Length = 0;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-12-04 18:28:13 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
1999-01-16 02:11:45 +00:00
|
|
|
if ( nEnvVar >= MAX_ENVIRONMENT_VARS )
|
1998-12-04 18:28:13 +00:00
|
|
|
return FALSE;
|
1999-01-16 02:11:45 +00:00
|
|
|
|
|
|
|
while (i < nEnvVar)
|
|
|
|
{
|
|
|
|
if ( Environment[i].Valid == FALSE )
|
|
|
|
break;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if ( i == nEnvVar ) {
|
|
|
|
NameBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,MAX_PATH*sizeof(WCHAR) );
|
|
|
|
ValueBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,MAX_VALUE*sizeof(WCHAR) );
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-01-16 02:11:45 +00:00
|
|
|
Environment[i].Name.Buffer = NameBuffer;
|
|
|
|
Environment[i].Name.MaximumLength = MAX_PATH*sizeof(WCHAR);
|
|
|
|
|
|
|
|
Environment[i].Value.Buffer = ValueBuffer;
|
|
|
|
Environment[i].Value.MaximumLength = MAX_VALUE*sizeof(WCHAR);
|
|
|
|
nEnvVar++;
|
|
|
|
}
|
|
|
|
Environment[i].Valid = TRUE;
|
|
|
|
|
|
|
|
lstrcpynW(Environment[i].Name.Buffer,lpValue,min(NameLen,(Environment[i].Name.MaximumLength-sizeof(WCHAR))/sizeof(WCHAR)));
|
|
|
|
Environment[i].Name.Length = NameLen*sizeof(WCHAR);
|
|
|
|
|
|
|
|
|
|
|
|
lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,(Environment[i].Value.MaximumLength-sizeof(WCHAR)))/sizeof(WCHAR));
|
|
|
|
Environment[i].Value.Length = ValueLen*sizeof(WCHAR);
|
1998-12-04 18:28:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
|
|
STDCALL
|
|
|
|
GetVersion(VOID)
|
|
|
|
{
|
|
|
|
DWORD Version = 0;
|
|
|
|
OSVERSIONINFO VersionInformation;
|
|
|
|
GetVersionExW(&VersionInformation);
|
|
|
|
|
|
|
|
Version |= ( VersionInformation.dwMajorVersion << 8 );
|
|
|
|
Version |= VersionInformation.dwMinorVersion;
|
|
|
|
|
|
|
|
Version |= ( VersionInformation.dwPlatformId << 16 );
|
|
|
|
|
|
|
|
return Version;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WINBOOL
|
|
|
|
STDCALL
|
|
|
|
GetVersionExW(
|
|
|
|
LPOSVERSIONINFO lpVersionInformation
|
|
|
|
)
|
|
|
|
{
|
|
|
|
lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
lpVersionInformation->dwMajorVersion = 4;
|
|
|
|
lpVersionInformation->dwMinorVersion = 0;
|
|
|
|
lpVersionInformation->dwBuildNumber = 12;
|
|
|
|
lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
|
1999-01-16 02:11:45 +00:00
|
|
|
lstrcpyW((WCHAR *)lpVersionInformation->szCSDVersion,L"Ariadne was here...");
|
1998-12-04 18:28:13 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
WINBOOL
|
|
|
|
STDCALL
|
|
|
|
GetVersionExA(
|
|
|
|
LPOSVERSIONINFO lpVersionInformation
|
|
|
|
)
|
|
|
|
{
|
|
|
|
lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
lpVersionInformation->dwMajorVersion = 4;
|
|
|
|
lpVersionInformation->dwMinorVersion = 0;
|
|
|
|
lpVersionInformation->dwBuildNumber = 12;
|
|
|
|
lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
|
1999-01-16 02:11:45 +00:00
|
|
|
lstrcpyA((char *)lpVersionInformation->szCSDVersion,"ReactOs Pre-Alpha");
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
LPSTR STDCALL GetEnvironmentStringsA(VOID)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
1999-05-29 00:15:17 +00:00
|
|
|
#if 0
|
1999-04-14 00:52:19 +00:00
|
|
|
WCHAR *EnvironmentStringsW;
|
|
|
|
char *EnvironmentStringsA;
|
|
|
|
int size = 0;
|
|
|
|
int i;
|
1999-05-29 00:15:17 +00:00
|
|
|
#endif
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
return(NULL);
|
|
|
|
|
|
|
|
/* FIXME: This doesn't work */
|
|
|
|
#if 0
|
|
|
|
EnvironmentStringsW = GetEnvironmentStringsW();
|
|
|
|
EnvironmentStringsA = (char *)EnvironmentStringsW;
|
|
|
|
|
|
|
|
for(i=0;i<nEnvVar;i++)
|
|
|
|
{
|
|
|
|
if ( Environment[i].Valid )
|
|
|
|
{
|
|
|
|
size += Environment[i].Name.Length;
|
|
|
|
size += sizeof(WCHAR); // =
|
|
|
|
size += Environment[i].Value.Length;
|
|
|
|
size += sizeof(WCHAR); // zero
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += sizeof(WCHAR);
|
|
|
|
size /= sizeof(WCHAR);
|
|
|
|
for(i=0;i<size;i++)
|
|
|
|
EnvironmentStringsA[i] = (char)EnvironmentStringsW[i];
|
|
|
|
return EnvironmentStringsA;
|
|
|
|
#endif
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
LPWSTR STDCALL GetEnvironmentStringsW(VOID)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
1999-05-29 00:15:17 +00:00
|
|
|
#if 0
|
1999-04-14 00:52:19 +00:00
|
|
|
int size = 0;
|
|
|
|
int i;
|
|
|
|
WCHAR *EnvironmentString;
|
|
|
|
WCHAR *EnvironmentStringSave;
|
1999-05-29 00:15:17 +00:00
|
|
|
#endif
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
return(NULL);
|
|
|
|
|
|
|
|
/* FIXME: This doesn't work, why not? */
|
|
|
|
#if 0
|
|
|
|
for(i=0;i<nEnvVar;i++)
|
|
|
|
{
|
|
|
|
if ( Environment[i].Valid )
|
|
|
|
{
|
|
|
|
size += Environment[i].Name.Length;
|
|
|
|
size += sizeof(WCHAR); // =
|
|
|
|
size += Environment[i].Value.Length;
|
|
|
|
size += sizeof(WCHAR); // zero
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += sizeof(WCHAR); // extra zero
|
|
|
|
DPRINT("size %d\n",size);
|
|
|
|
EnvironmentString = (WCHAR *)HeapAlloc(GetProcessHeap(),
|
|
|
|
HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
|
|
|
|
size);
|
|
|
|
DPRINT("EnvironmentString %x\n",EnvironmentString);
|
|
|
|
EnvironmentStringSave = EnvironmentString;
|
|
|
|
for(i=0;i<nEnvVar;i++)
|
|
|
|
{
|
|
|
|
if ( Environment[i].Valid )
|
|
|
|
{
|
|
|
|
wcscpy(EnvironmentString,Environment[i].Name.Buffer);
|
|
|
|
wcscat(EnvironmentString,L"=");
|
|
|
|
wcscat(EnvironmentString,Environment[i].Value.Buffer);
|
|
|
|
|
|
|
|
size = Environment[i].Name.Length;
|
|
|
|
size += sizeof(WCHAR); // =
|
|
|
|
size += Environment[i].Value.Length;
|
|
|
|
size += sizeof(WCHAR); // zero
|
|
|
|
EnvironmentString += (size/sizeof(WCHAR));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*EnvironmentString = 0;
|
|
|
|
return EnvironmentStringSave;
|
|
|
|
#endif
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
WINBOOL
|
|
|
|
STDCALL
|
|
|
|
FreeEnvironmentStringsA(
|
|
|
|
LPSTR EnvironmentStrings
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if ( EnvironmentStrings == NULL )
|
|
|
|
return FALSE;
|
|
|
|
HeapFree(GetProcessHeap(),0,EnvironmentStrings);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
WINBOOL
|
|
|
|
STDCALL
|
|
|
|
FreeEnvironmentStringsW(
|
|
|
|
LPWSTR EnvironmentStrings
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if ( EnvironmentStrings == NULL )
|
|
|
|
return FALSE;
|
|
|
|
HeapFree(GetProcessHeap(),0,EnvironmentStrings);
|
1998-12-04 18:28:13 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1999-10-02 20:20:44 +00:00
|
|
|
|
|
|
|
int ExpandVariableA(
|
|
|
|
LPCSTR lpSrc, LPSTR lpDst, DWORD nSize , DWORD *nWritten)
|
|
|
|
{
|
|
|
|
int nVar = 0;
|
|
|
|
LPSTR lpVar;
|
|
|
|
LPSTR lpEnd;
|
|
|
|
|
|
|
|
if ( nWritten == NULL )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ( *lpSrc != '%' ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lpVar = (LPSTR)lpSrc;
|
|
|
|
lpVar++;
|
|
|
|
|
|
|
|
|
|
|
|
lpEnd = strchr( lpVar, '%' );
|
|
|
|
if ( lpEnd == NULL ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*lpEnd = 0;
|
|
|
|
|
|
|
|
nWritten = GetEnvironmentVariableA(lpVar,lpDst,nSize);
|
|
|
|
*lpEnd = '%';
|
|
|
|
|
|
|
|
if ( nWritten == 0 )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ( nWritten > nSize )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return (lpEnd - lpVar) -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD STDCALL ExpandEnvironmentStringsA(
|
|
|
|
LPCSTR lpSrc, LPSTR lpDst, DWORD nSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DWORD v;
|
|
|
|
DWORD bw;
|
|
|
|
|
|
|
|
while(*lpSrc != 0 && nSize > 0 )
|
|
|
|
{
|
|
|
|
if ( *lpSrc == '%' ) {
|
|
|
|
v = ExpandVariableA(lpSrc,lpDst,nSize , &bw);
|
|
|
|
if ( v == -1 ) {
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst++;
|
|
|
|
lpSrc++;
|
|
|
|
nSize--;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
lpSrc+=v;
|
|
|
|
lpDst+=bw;
|
|
|
|
nSize-=bw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst++;
|
|
|
|
lpSrc++;
|
|
|
|
nSize--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int ExpandVariableW(
|
|
|
|
LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize , DWORD *nWritten)
|
|
|
|
{
|
|
|
|
LPWSTR lpVar;
|
|
|
|
LPWSTR lpEnd;
|
|
|
|
|
|
|
|
if ( nWritten == NULL )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ( *lpSrc != L'%' ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lpVar = (LPWSTR)lpSrc;
|
|
|
|
lpVar++;
|
|
|
|
|
|
|
|
|
|
|
|
lpEnd = wcschr( lpVar, L'%' );
|
|
|
|
if ( lpEnd == NULL ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*lpEnd = 0;
|
|
|
|
|
|
|
|
nWritten = GetEnvironmentVariableW(lpVar,lpDst,nSize);
|
|
|
|
*lpEnd = L'%';
|
|
|
|
|
|
|
|
if ( nWritten == 0 )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ( nWritten > nSize )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return ((lpEnd - lpVar)/2) -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD STDCALL ExpandEnvironmentStringsW(
|
|
|
|
LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DWORD v;
|
|
|
|
DWORD bw;
|
|
|
|
|
|
|
|
while(*lpSrc != 0 && nSize > 0 )
|
|
|
|
{
|
|
|
|
if ( *lpSrc == L'%' ) {
|
|
|
|
v = ExpandVariableW(lpSrc,lpDst,nSize , &bw);
|
|
|
|
if ( v == -1 ) {
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst++;
|
|
|
|
lpSrc++;
|
|
|
|
nSize--;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
lpSrc+=v;
|
|
|
|
lpDst+=bw;
|
|
|
|
nSize-=bw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst++;
|
|
|
|
lpSrc++;
|
|
|
|
nSize--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|