mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
b02427417c
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@5614 21ef857c-d57f-4fe0-8362-d861dc6d29cd
214 lines
5.9 KiB
C#
214 lines
5.9 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
|
|
{
|
|
private static readonly EnvironmentBlock _zero = new EnvironmentBlock(IntPtr.Zero);
|
|
|
|
public static EnvironmentBlock Zero
|
|
{
|
|
get { return _zero; }
|
|
}
|
|
|
|
public static EnvironmentBlock GetCurrent()
|
|
{
|
|
unsafe
|
|
{
|
|
return new EnvironmentBlock(ProcessHandle.GetCurrentProcessParameters()->Environment);
|
|
}
|
|
}
|
|
|
|
public static string GetCurrentVariable(string name)
|
|
{
|
|
return GetCurrent().GetVariable(name);
|
|
}
|
|
|
|
public static EnvironmentBlock SetCurrent(EnvironmentBlock environmentBlock)
|
|
{
|
|
NtStatus status;
|
|
IntPtr previousEnvironment;
|
|
|
|
if ((status = Win32.RtlSetCurrentEnvironment(
|
|
environmentBlock,
|
|
out previousEnvironment
|
|
)) >= NtStatus.Error)
|
|
Win32.Throw(status);
|
|
|
|
return new EnvironmentBlock(previousEnvironment);
|
|
}
|
|
|
|
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.Throw(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.Throw(status);
|
|
}
|
|
|
|
public EnvironmentBlock(TokenHandle tokenHandle)
|
|
{
|
|
if (!Win32.CreateEnvironmentBlock(out _environment, tokenHandle, false))
|
|
Win32.Throw();
|
|
}
|
|
|
|
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.ResizeNew(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.Throw(status);
|
|
|
|
return valueStr.Read();
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
nameStr.Dispose();
|
|
}
|
|
}
|
|
|
|
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.Throw(status);
|
|
}
|
|
finally
|
|
{
|
|
valueStr.Dispose();
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
nameStr.Dispose();
|
|
}
|
|
|
|
_environment = environment;
|
|
}
|
|
}
|
|
}
|