Files
wj32 7bd28e4357 moved branches, tags, trunk to 1.x branch
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@2304 21ef857c-d57f-4fe0-8362-d861dc6d29cd
2009-10-25 02:22:46 +00:00

201 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using ProcessHacker.Common.Objects;
using ProcessHacker.Native.Api;
using System.Runtime.InteropServices;
namespace ProcessHacker.Native.Objects
{
public struct EnvironmentBlock
{
public static EnvironmentBlock GetCurrent()
{
unsafe
{
return new EnvironmentBlock(ProcessHandle.GetCurrentProcessParameters()->Environment);
}
}
public static string GetCurrentVariable(string name)
{
return GetCurrent().GetVariable(name);
}
public static void SetCurrentVariable(string name, string value)
{
NtStatus status;
UnicodeString nameStr;
UnicodeString valueStr;
nameStr = new UnicodeString(name);
try
{
valueStr = new UnicodeString(value);
try
{
if ((status = Win32.RtlSetEnvironmentVariable(
IntPtr.Zero,
ref nameStr,
ref valueStr
)) >= NtStatus.Error)
Win32.ThrowLastError(status);
}
finally
{
valueStr.Dispose();
}
}
finally
{
nameStr.Dispose();
}
}
public static implicit operator IntPtr(EnvironmentBlock environmentBlock)
{
return environmentBlock.Memory;
}
private IntPtr _environment;
public EnvironmentBlock(bool cloneCurrent)
{
NtStatus status;
if ((status = Win32.RtlCreateEnvironment(
cloneCurrent,
out _environment
)) >= NtStatus.Error)
Win32.ThrowLastError(status);
}
public EnvironmentBlock(IntPtr environment)
{
_environment = environment;
}
public IntPtr Memory
{
get { return _environment; }
}
public void Destroy()
{
Win32.RtlDestroyEnvironment(this);
}
public unsafe int GetLength()
{
short* ptr = (short*)_environment;
while (*ptr != 0)
while (*ptr++ != 0)
;
ptr++;
return (new IntPtr(ptr)).Decrement(_environment).ToInt32();
}
public string GetVariable(string name)
{
NtStatus status;
UnicodeString nameStr;
UnicodeString valueStr;
nameStr = new UnicodeString(name);
try
{
using (var data = new MemoryAlloc(100))
{
valueStr = new UnicodeString();
valueStr.Buffer = data;
valueStr.MaximumLength = (ushort)data.Size;
status = Win32.RtlQueryEnvironmentVariable_U(
this,
ref nameStr,
ref valueStr
);
if (status == NtStatus.BufferTooSmall)
{
// Resize and try again (+2 for the null terminator).
data.Resize(valueStr.Length + 2);
valueStr.Buffer = data;
valueStr.MaximumLength = (ushort)(valueStr.Length + 2);
status = Win32.RtlQueryEnvironmentVariable_U(
this,
ref nameStr,
ref valueStr
);
}
if (status >= NtStatus.Error)
Win32.ThrowLastError(status);
return valueStr.Read();
}
}
finally
{
nameStr.Dispose();
}
}
public EnvironmentBlock SetCurrent()
{
NtStatus status;
IntPtr previousEnvironment;
if ((status = Win32.RtlSetCurrentEnvironment(
this,
out previousEnvironment
)) >= NtStatus.Error)
Win32.ThrowLastError(status);
return new EnvironmentBlock(previousEnvironment);
}
public void SetVariable(string name, string value)
{
NtStatus status;
IntPtr environment = _environment;
UnicodeString nameStr;
UnicodeString valueStr;
nameStr = new UnicodeString(name);
try
{
valueStr = new UnicodeString(value);
try
{
if ((status = Win32.RtlSetEnvironmentVariable(
ref environment,
ref nameStr,
ref valueStr
)) >= NtStatus.Error)
Win32.ThrowLastError(status);
}
finally
{
valueStr.Dispose();
}
}
finally
{
nameStr.Dispose();
}
_environment = environment;
}
}
}