kernel32: Move environment functions to kernelbase.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a311140f93
commit
3e6b961f00
|
@ -93,314 +93,6 @@ LPWSTR WINAPI GetCommandLineW(void)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentStringsA (KERNEL32.@)
|
||||
* GetEnvironmentStrings (KERNEL32.@)
|
||||
*/
|
||||
LPSTR WINAPI GetEnvironmentStringsA(void)
|
||||
{
|
||||
LPWSTR ptrW;
|
||||
unsigned len, slen;
|
||||
LPSTR ret, ptrA;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
|
||||
len = 1;
|
||||
|
||||
ptrW = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
||||
while (*ptrW)
|
||||
{
|
||||
slen = strlenW(ptrW) + 1;
|
||||
len += WideCharToMultiByte( CP_ACP, 0, ptrW, slen, NULL, 0, NULL, NULL );
|
||||
ptrW += slen;
|
||||
}
|
||||
|
||||
if ((ret = HeapAlloc( GetProcessHeap(), 0, len )) != NULL)
|
||||
{
|
||||
ptrW = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
||||
ptrA = ret;
|
||||
while (*ptrW)
|
||||
{
|
||||
slen = strlenW(ptrW) + 1;
|
||||
WideCharToMultiByte( CP_ACP, 0, ptrW, slen, ptrA, len, NULL, NULL );
|
||||
ptrW += slen;
|
||||
ptrA += strlen(ptrA) + 1;
|
||||
}
|
||||
*ptrA = 0;
|
||||
}
|
||||
|
||||
RtlReleasePebLock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentStringsW (KERNEL32.@)
|
||||
*/
|
||||
LPWSTR WINAPI GetEnvironmentStringsW(void)
|
||||
{
|
||||
LPWSTR ret, ptrW;
|
||||
unsigned len;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
|
||||
ptrW = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
||||
while (*ptrW) ptrW += strlenW(ptrW) + 1;
|
||||
ptrW++;
|
||||
|
||||
len = (ptrW - NtCurrentTeb()->Peb->ProcessParameters->Environment) * sizeof(WCHAR);
|
||||
ret = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (ret) memcpy(ret, NtCurrentTeb()->Peb->ProcessParameters->Environment, len);
|
||||
|
||||
RtlReleasePebLock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* FreeEnvironmentStringsA (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI FreeEnvironmentStringsA( LPSTR ptr )
|
||||
{
|
||||
return HeapFree( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* FreeEnvironmentStringsW (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI FreeEnvironmentStringsW( LPWSTR ptr )
|
||||
{
|
||||
return HeapFree( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentVariableA (KERNEL32.@)
|
||||
*/
|
||||
DWORD WINAPI GetEnvironmentVariableA( LPCSTR name, LPSTR value, DWORD size )
|
||||
{
|
||||
UNICODE_STRING us_name;
|
||||
PWSTR valueW;
|
||||
DWORD ret;
|
||||
|
||||
if (!name || !*name)
|
||||
{
|
||||
SetLastError(ERROR_ENVVAR_NOT_FOUND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* limit the size to sane values */
|
||||
size = min(size, 32767);
|
||||
if (!(valueW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR))))
|
||||
return 0;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_name, name );
|
||||
SetLastError(0);
|
||||
ret = GetEnvironmentVariableW( us_name.Buffer, valueW, size);
|
||||
if (ret && ret < size)
|
||||
{
|
||||
WideCharToMultiByte( CP_ACP, 0, valueW, ret + 1, value, size, NULL, NULL );
|
||||
}
|
||||
/* this is needed to tell, with 0 as a return value, the difference between:
|
||||
* - an error (GetLastError() != 0)
|
||||
* - returning an empty string (in this case, we need to update the buffer)
|
||||
*/
|
||||
if (ret == 0 && size && GetLastError() == 0)
|
||||
value[0] = '\0';
|
||||
|
||||
RtlFreeUnicodeString( &us_name );
|
||||
HeapFree(GetProcessHeap(), 0, valueW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentVariableW (KERNEL32.@)
|
||||
*/
|
||||
DWORD WINAPI GetEnvironmentVariableW( LPCWSTR name, LPWSTR val, DWORD size )
|
||||
{
|
||||
UNICODE_STRING us_name;
|
||||
UNICODE_STRING us_value;
|
||||
NTSTATUS status;
|
||||
unsigned len;
|
||||
|
||||
TRACE("(%s %p %u)\n", debugstr_w(name), val, size);
|
||||
|
||||
if (!name || !*name)
|
||||
{
|
||||
SetLastError(ERROR_ENVVAR_NOT_FOUND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&us_name, name);
|
||||
us_value.Length = 0;
|
||||
us_value.MaximumLength = (size ? size - 1 : 0) * sizeof(WCHAR);
|
||||
us_value.Buffer = val;
|
||||
|
||||
status = RtlQueryEnvironmentVariable_U(NULL, &us_name, &us_value);
|
||||
len = us_value.Length / sizeof(WCHAR);
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return (status == STATUS_BUFFER_TOO_SMALL) ? len + 1 : 0;
|
||||
}
|
||||
if (size) val[len] = '\0';
|
||||
|
||||
return us_value.Length / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetEnvironmentVariableA (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI SetEnvironmentVariableA( LPCSTR name, LPCSTR value )
|
||||
{
|
||||
UNICODE_STRING us_name;
|
||||
BOOL ret;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
SetLastError(ERROR_ENVVAR_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_name, name );
|
||||
if (value)
|
||||
{
|
||||
UNICODE_STRING us_value;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_value, value );
|
||||
ret = SetEnvironmentVariableW( us_name.Buffer, us_value.Buffer );
|
||||
RtlFreeUnicodeString( &us_value );
|
||||
}
|
||||
else ret = SetEnvironmentVariableW( us_name.Buffer, NULL );
|
||||
|
||||
RtlFreeUnicodeString( &us_name );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetEnvironmentVariableW (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI SetEnvironmentVariableW( LPCWSTR name, LPCWSTR value )
|
||||
{
|
||||
UNICODE_STRING us_name;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("(%s %s)\n", debugstr_w(name), debugstr_w(value));
|
||||
|
||||
if (!name)
|
||||
{
|
||||
SetLastError(ERROR_ENVVAR_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&us_name, name);
|
||||
if (value)
|
||||
{
|
||||
UNICODE_STRING us_value;
|
||||
|
||||
RtlInitUnicodeString(&us_value, value);
|
||||
status = RtlSetEnvironmentVariable(NULL, &us_name, &us_value);
|
||||
}
|
||||
else status = RtlSetEnvironmentVariable(NULL, &us_name, NULL);
|
||||
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ExpandEnvironmentStringsA (KERNEL32.@)
|
||||
*
|
||||
* See ExpandEnvironmentStringsW.
|
||||
*
|
||||
* Note: overlapping buffers are not supported; this is how it should be.
|
||||
* FIXME: return value is wrong for MBCS
|
||||
*/
|
||||
DWORD WINAPI ExpandEnvironmentStringsA( LPCSTR src, LPSTR dst, DWORD count )
|
||||
{
|
||||
UNICODE_STRING us_src;
|
||||
PWSTR dstW = NULL;
|
||||
DWORD ret;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_src, src );
|
||||
if (count)
|
||||
{
|
||||
if (!(dstW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
|
||||
return 0;
|
||||
ret = ExpandEnvironmentStringsW( us_src.Buffer, dstW, count);
|
||||
if (ret)
|
||||
WideCharToMultiByte( CP_ACP, 0, dstW, ret, dst, count, NULL, NULL );
|
||||
}
|
||||
else ret = ExpandEnvironmentStringsW( us_src.Buffer, NULL, 0);
|
||||
|
||||
RtlFreeUnicodeString( &us_src );
|
||||
HeapFree(GetProcessHeap(), 0, dstW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ExpandEnvironmentStringsW (KERNEL32.@)
|
||||
*
|
||||
* Replaces references to environment variables of the form '%EnvVar%'
|
||||
* by their value. If the environment variable does not exist, then the
|
||||
* reference is left as is.
|
||||
*
|
||||
* PARAMS
|
||||
* src [I] The string to be expanded.
|
||||
* dst [O] The buffer in which to put the expanded string.
|
||||
* len [I] The buffer size, in characters.
|
||||
*
|
||||
* RETURNS
|
||||
* The number of characters copied into the buffer. If the buffer is
|
||||
* too small, then the required buffer size, in characters including the
|
||||
* trailing '\0', is returned.
|
||||
* If the function fails for some other reason, then it returns 0.
|
||||
*/
|
||||
DWORD WINAPI ExpandEnvironmentStringsW( LPCWSTR src, LPWSTR dst, DWORD len )
|
||||
{
|
||||
UNICODE_STRING us_src;
|
||||
UNICODE_STRING us_dst;
|
||||
NTSTATUS status;
|
||||
DWORD res;
|
||||
|
||||
TRACE("(%s %p %u)\n", debugstr_w(src), dst, len);
|
||||
|
||||
RtlInitUnicodeString(&us_src, src);
|
||||
|
||||
/* make sure we don't overflow the maximum UNICODE_STRING size */
|
||||
if (len > UNICODE_STRING_MAX_CHARS)
|
||||
len = UNICODE_STRING_MAX_CHARS;
|
||||
|
||||
us_dst.Length = 0;
|
||||
us_dst.MaximumLength = len * sizeof(WCHAR);
|
||||
us_dst.Buffer = dst;
|
||||
|
||||
res = 0;
|
||||
status = RtlExpandEnvironmentStrings_U(NULL, &us_src, &us_dst, &res);
|
||||
res /= sizeof(WCHAR);
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
if (status != STATUS_BUFFER_TOO_SMALL) return 0;
|
||||
if (len && dst) dst[len - 1] = '\0';
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetStdHandle (KERNEL32.@)
|
||||
*/
|
||||
|
|
|
@ -439,8 +439,8 @@
|
|||
@ stdcall ExitProcess(long)
|
||||
@ stdcall ExitThread(long) ntdll.RtlExitUserThread
|
||||
@ stub ExitVDM
|
||||
@ stdcall ExpandEnvironmentStringsA(str ptr long)
|
||||
@ stdcall ExpandEnvironmentStringsW(wstr ptr long)
|
||||
@ stdcall -import ExpandEnvironmentStringsA(str ptr long)
|
||||
@ stdcall -import ExpandEnvironmentStringsW(wstr ptr long)
|
||||
@ stdcall ExpungeConsoleCommandHistoryA(str)
|
||||
@ stdcall ExpungeConsoleCommandHistoryW(wstr)
|
||||
@ stub ExtendVirtualBuffer
|
||||
|
@ -525,8 +525,8 @@
|
|||
@ stdcall FormatMessageA(long ptr long long ptr long ptr)
|
||||
@ stdcall FormatMessageW(long ptr long long ptr long ptr)
|
||||
@ stdcall FreeConsole()
|
||||
@ stdcall FreeEnvironmentStringsA(ptr)
|
||||
@ stdcall FreeEnvironmentStringsW(ptr)
|
||||
@ stdcall -import FreeEnvironmentStringsA(ptr)
|
||||
@ stdcall -import FreeEnvironmentStringsW(ptr)
|
||||
@ stub -i386 FreeLSCallback
|
||||
@ stdcall FreeLibrary(long)
|
||||
@ stdcall FreeLibraryAndExitThread(long long)
|
||||
|
@ -658,11 +658,11 @@
|
|||
@ stdcall GetDynamicTimeZoneInformation(ptr)
|
||||
@ stdcall GetDynamicTimeZoneInformationEffectiveYears(ptr ptr ptr)
|
||||
@ stdcall -ret64 -arch=i386,x86_64 GetEnabledXStateFeatures()
|
||||
@ stdcall GetEnvironmentStrings() GetEnvironmentStringsA
|
||||
@ stdcall GetEnvironmentStringsA()
|
||||
@ stdcall GetEnvironmentStringsW()
|
||||
@ stdcall GetEnvironmentVariableA(str ptr long)
|
||||
@ stdcall GetEnvironmentVariableW(wstr ptr long)
|
||||
@ stdcall -import GetEnvironmentStrings()
|
||||
@ stdcall -import GetEnvironmentStringsA()
|
||||
@ stdcall -import GetEnvironmentStringsW()
|
||||
@ stdcall -import GetEnvironmentVariableA(str ptr long)
|
||||
@ stdcall -import GetEnvironmentVariableW(wstr ptr long)
|
||||
# @ stub GetEraNameCountedString
|
||||
@ stdcall -import GetErrorMode()
|
||||
@ stdcall GetExitCodeProcess(long ptr)
|
||||
|
@ -1386,8 +1386,8 @@
|
|||
@ stdcall -import SetEndOfFile(long)
|
||||
# @ stub SetEnvironmentStringsA
|
||||
# @ stub SetEnvironmentStringsW
|
||||
@ stdcall SetEnvironmentVariableA(str str)
|
||||
@ stdcall SetEnvironmentVariableW(wstr wstr)
|
||||
@ stdcall -import SetEnvironmentVariableA(str str)
|
||||
@ stdcall -import SetEnvironmentVariableW(wstr wstr)
|
||||
@ stdcall -import SetErrorMode(long)
|
||||
@ stdcall -import SetEvent(long)
|
||||
@ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion
|
||||
|
|
|
@ -339,8 +339,8 @@
|
|||
@ stdcall EventWriteTransfer(int64 ptr ptr ptr long ptr) ntdll.EtwEventWriteTransfer
|
||||
@ stdcall ExitProcess(long) ntdll.RtlExitUserProcess
|
||||
@ stdcall ExitThread(long) ntdll.RtlExitUserThread
|
||||
@ stdcall ExpandEnvironmentStringsA(str ptr long) kernel32.ExpandEnvironmentStringsA
|
||||
@ stdcall ExpandEnvironmentStringsW(wstr ptr long) kernel32.ExpandEnvironmentStringsW
|
||||
@ stdcall ExpandEnvironmentStringsA(str ptr long)
|
||||
@ stdcall ExpandEnvironmentStringsW(wstr ptr long)
|
||||
@ stdcall FatalAppExitA(long str)
|
||||
@ stdcall FatalAppExitW(long wstr)
|
||||
@ stdcall FileTimeToLocalFileTime(ptr ptr) kernel32.FileTimeToLocalFileTime
|
||||
|
@ -390,8 +390,8 @@
|
|||
@ stdcall FormatMessageA(long ptr long long ptr long ptr) kernel32.FormatMessageA
|
||||
@ stdcall FormatMessageW(long ptr long long ptr long ptr) kernel32.FormatMessageW
|
||||
@ stdcall FreeConsole() kernel32.FreeConsole
|
||||
@ stdcall FreeEnvironmentStringsA(ptr) kernel32.FreeEnvironmentStringsA
|
||||
@ stdcall FreeEnvironmentStringsW(ptr) kernel32.FreeEnvironmentStringsW
|
||||
@ stdcall FreeEnvironmentStringsA(ptr) FreeEnvironmentStringsW
|
||||
@ stdcall FreeEnvironmentStringsW(ptr)
|
||||
# @ stub FreeGPOListInternalA
|
||||
# @ stub FreeGPOListInternalW
|
||||
@ stdcall FreeLibrary(long) kernel32.FreeLibrary
|
||||
|
@ -492,11 +492,11 @@
|
|||
# @ stub GetEightBitStringToUnicodeSizeRoutine
|
||||
# @ stub GetEightBitStringToUnicodeStringRoutine
|
||||
@ stdcall -ret64 -arch=i386,x86_64 GetEnabledXStateFeatures() kernel32.GetEnabledXStateFeatures
|
||||
@ stdcall GetEnvironmentStrings() kernel32.GetEnvironmentStrings
|
||||
@ stdcall GetEnvironmentStringsA() kernel32.GetEnvironmentStringsA
|
||||
@ stdcall GetEnvironmentStringsW() kernel32.GetEnvironmentStringsW
|
||||
@ stdcall GetEnvironmentVariableA(str ptr long) kernel32.GetEnvironmentVariableA
|
||||
@ stdcall GetEnvironmentVariableW(wstr ptr long) kernel32.GetEnvironmentVariableW
|
||||
@ stdcall GetEnvironmentStrings() GetEnvironmentStringsA
|
||||
@ stdcall GetEnvironmentStringsA()
|
||||
@ stdcall GetEnvironmentStringsW()
|
||||
@ stdcall GetEnvironmentVariableA(str ptr long)
|
||||
@ stdcall GetEnvironmentVariableW(wstr ptr long)
|
||||
@ stub GetEraNameCountedString
|
||||
@ stdcall GetErrorMode()
|
||||
@ stdcall GetExitCodeProcess(long ptr)
|
||||
|
@ -1352,8 +1352,8 @@
|
|||
@ stdcall RevertToSelf()
|
||||
# @ stub RsopLoggingEnabledInternal
|
||||
# @ stub SHCoCreateInstance
|
||||
@ stdcall SHExpandEnvironmentStringsA(str ptr long) kernel32.ExpandEnvironmentStringsA
|
||||
@ stdcall SHExpandEnvironmentStringsW(wstr ptr long) kernel32.ExpandEnvironmentStringsW
|
||||
@ stdcall SHExpandEnvironmentStringsA(str ptr long) ExpandEnvironmentStringsA
|
||||
@ stdcall SHExpandEnvironmentStringsW(wstr ptr long) ExpandEnvironmentStringsW
|
||||
@ stdcall SHLoadIndirectString(wstr ptr long ptr)
|
||||
# @ stub SHLoadIndirectStringInternal
|
||||
@ stdcall SHRegCloseUSKey(ptr)
|
||||
|
@ -1424,8 +1424,8 @@
|
|||
# @ stub SetDynamicTimeZoneInformation
|
||||
@ stdcall SetEndOfFile(long)
|
||||
@ stub SetEnvironmentStringsW
|
||||
@ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA
|
||||
@ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW
|
||||
@ stdcall SetEnvironmentVariableA(str str)
|
||||
@ stdcall SetEnvironmentVariableW(wstr wstr)
|
||||
@ stdcall SetErrorMode(long)
|
||||
@ stdcall SetEvent(long)
|
||||
@ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define NONAMELESSUNION
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "kernelbase.h"
|
||||
|
@ -345,6 +346,230 @@ BOOL WINAPI DECLSPEC_HOTPATCH TerminateProcess( HANDLE handle, DWORD exit_code )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Process environment
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
static inline SIZE_T get_env_length( const WCHAR *env )
|
||||
{
|
||||
const WCHAR *end = env;
|
||||
while (*end) end += lstrlenW(end) + 1;
|
||||
return end + 1 - env;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ExpandEnvironmentStringsA (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH ExpandEnvironmentStringsA( LPCSTR src, LPSTR dst, DWORD count )
|
||||
{
|
||||
UNICODE_STRING us_src;
|
||||
PWSTR dstW = NULL;
|
||||
DWORD ret;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_src, src );
|
||||
if (count)
|
||||
{
|
||||
if (!(dstW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)))) return 0;
|
||||
ret = ExpandEnvironmentStringsW( us_src.Buffer, dstW, count);
|
||||
if (ret) WideCharToMultiByte( CP_ACP, 0, dstW, ret, dst, count, NULL, NULL );
|
||||
}
|
||||
else ret = ExpandEnvironmentStringsW( us_src.Buffer, NULL, 0 );
|
||||
|
||||
RtlFreeUnicodeString( &us_src );
|
||||
HeapFree( GetProcessHeap(), 0, dstW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ExpandEnvironmentStringsW (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH ExpandEnvironmentStringsW( LPCWSTR src, LPWSTR dst, DWORD len )
|
||||
{
|
||||
UNICODE_STRING us_src, us_dst;
|
||||
NTSTATUS status;
|
||||
DWORD res;
|
||||
|
||||
TRACE( "(%s %p %u)\n", debugstr_w(src), dst, len );
|
||||
|
||||
RtlInitUnicodeString( &us_src, src );
|
||||
|
||||
/* make sure we don't overflow the maximum UNICODE_STRING size */
|
||||
len = min( len, UNICODE_STRING_MAX_CHARS );
|
||||
|
||||
us_dst.Length = 0;
|
||||
us_dst.MaximumLength = len * sizeof(WCHAR);
|
||||
us_dst.Buffer = dst;
|
||||
|
||||
res = 0;
|
||||
status = RtlExpandEnvironmentStrings_U( NULL, &us_src, &us_dst, &res );
|
||||
res /= sizeof(WCHAR);
|
||||
if (!set_ntstatus( status ))
|
||||
{
|
||||
if (status != STATUS_BUFFER_TOO_SMALL) return 0;
|
||||
if (len && dst) dst[len - 1] = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentStrings (kernelbase.@)
|
||||
* GetEnvironmentStringsA (kernelbase.@)
|
||||
*/
|
||||
LPSTR WINAPI DECLSPEC_HOTPATCH GetEnvironmentStringsA(void)
|
||||
{
|
||||
LPWSTR env;
|
||||
LPSTR ret;
|
||||
SIZE_T lenA, lenW;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
||||
lenW = get_env_length( env );
|
||||
lenA = WideCharToMultiByte( CP_ACP, 0, env, lenW, NULL, 0, NULL, NULL );
|
||||
if ((ret = HeapAlloc( GetProcessHeap(), 0, lenA )))
|
||||
WideCharToMultiByte( CP_ACP, 0, env, lenW, ret, lenA, NULL, NULL );
|
||||
RtlReleasePebLock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentStringsW (kernelbase.@)
|
||||
*/
|
||||
LPWSTR WINAPI DECLSPEC_HOTPATCH GetEnvironmentStringsW(void)
|
||||
{
|
||||
LPWSTR ret;
|
||||
SIZE_T len;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
len = get_env_length( NtCurrentTeb()->Peb->ProcessParameters->Environment ) * sizeof(WCHAR);
|
||||
if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
|
||||
memcpy( ret, NtCurrentTeb()->Peb->ProcessParameters->Environment, len );
|
||||
RtlReleasePebLock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentVariableA (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH GetEnvironmentVariableA( LPCSTR name, LPSTR value, DWORD size )
|
||||
{
|
||||
UNICODE_STRING us_name;
|
||||
PWSTR valueW;
|
||||
DWORD ret;
|
||||
|
||||
/* limit the size to sane values */
|
||||
size = min( size, 32767 );
|
||||
if (!(valueW = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return 0;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_name, name );
|
||||
SetLastError( 0 );
|
||||
ret = GetEnvironmentVariableW( us_name.Buffer, valueW, size);
|
||||
if (ret && ret < size) WideCharToMultiByte( CP_ACP, 0, valueW, ret + 1, value, size, NULL, NULL );
|
||||
|
||||
/* this is needed to tell, with 0 as a return value, the difference between:
|
||||
* - an error (GetLastError() != 0)
|
||||
* - returning an empty string (in this case, we need to update the buffer)
|
||||
*/
|
||||
if (ret == 0 && size && GetLastError() == 0) value[0] = 0;
|
||||
RtlFreeUnicodeString( &us_name );
|
||||
HeapFree( GetProcessHeap(), 0, valueW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetEnvironmentVariableW (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH GetEnvironmentVariableW( LPCWSTR name, LPWSTR val, DWORD size )
|
||||
{
|
||||
UNICODE_STRING us_name, us_value;
|
||||
NTSTATUS status;
|
||||
DWORD len;
|
||||
|
||||
TRACE( "(%s %p %u)\n", debugstr_w(name), val, size );
|
||||
|
||||
RtlInitUnicodeString( &us_name, name );
|
||||
us_value.Length = 0;
|
||||
us_value.MaximumLength = (size ? size - 1 : 0) * sizeof(WCHAR);
|
||||
us_value.Buffer = val;
|
||||
|
||||
status = RtlQueryEnvironmentVariable_U( NULL, &us_name, &us_value );
|
||||
len = us_value.Length / sizeof(WCHAR);
|
||||
if (!set_ntstatus( status )) return (status == STATUS_BUFFER_TOO_SMALL) ? len + 1 : 0;
|
||||
if (size) val[len] = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* FreeEnvironmentStringsA (kernelbase.@)
|
||||
* FreeEnvironmentStringsW (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH FreeEnvironmentStringsW( LPWSTR ptr )
|
||||
{
|
||||
return HeapFree( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetEnvironmentVariableA (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA( LPCSTR name, LPCSTR value )
|
||||
{
|
||||
UNICODE_STRING us_name, us_value;
|
||||
BOOL ret;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
SetLastError( ERROR_ENVVAR_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_name, name );
|
||||
if (value)
|
||||
{
|
||||
RtlCreateUnicodeStringFromAsciiz( &us_value, value );
|
||||
ret = SetEnvironmentVariableW( us_name.Buffer, us_value.Buffer );
|
||||
RtlFreeUnicodeString( &us_value );
|
||||
}
|
||||
else ret = SetEnvironmentVariableW( us_name.Buffer, NULL );
|
||||
RtlFreeUnicodeString( &us_name );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetEnvironmentVariableW (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW( LPCWSTR name, LPCWSTR value )
|
||||
{
|
||||
UNICODE_STRING us_name, us_value;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE( "(%s %s)\n", debugstr_w(name), debugstr_w(value) );
|
||||
|
||||
if (!name)
|
||||
{
|
||||
SetLastError( ERROR_ENVVAR_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString( &us_name, name );
|
||||
if (value)
|
||||
{
|
||||
RtlInitUnicodeString( &us_value, value );
|
||||
status = RtlSetEnvironmentVariable( NULL, &us_name, &us_value );
|
||||
}
|
||||
else status = RtlSetEnvironmentVariable( NULL, &us_name, NULL );
|
||||
|
||||
return set_ntstatus( status );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Process/thread attribute lists
|
||||
***********************************************************************/
|
||||
|
|
Loading…
Reference in New Issue