mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 20:56:02 +00:00
This commit uses psl-monad branch source-depot 7209cb9 And corresponds to [SD:688741]
431 lines
13 KiB
C#
431 lines
13 KiB
C#
/********************************************************************++
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
--********************************************************************/
|
|
/*
|
|
* The registry wrapper provides a common interface to both the transacted
|
|
* and non-transacted registry APIs. It is used exclusively by the registry provider
|
|
* to perform registry operations. In most cases, the wrapper simply forwards the
|
|
* call to the appropriate registry API.
|
|
*/
|
|
|
|
using System;
|
|
using System.Globalization;
|
|
using Microsoft.Win32;
|
|
using System.Security.AccessControl;
|
|
using System.Management.Automation.Provider;
|
|
using Microsoft.PowerShell.Commands.Internal;
|
|
|
|
|
|
namespace Microsoft.PowerShell.Commands
|
|
{
|
|
internal interface IRegistryWrapper
|
|
{
|
|
void SetValue(string name, object value);
|
|
void SetValue(string name, object value, RegistryValueKind valueKind);
|
|
string[] GetValueNames();
|
|
void DeleteValue(string name);
|
|
string[] GetSubKeyNames();
|
|
IRegistryWrapper CreateSubKey(string subkey);
|
|
IRegistryWrapper OpenSubKey(string name, bool writable);
|
|
void DeleteSubKeyTree(string subkey);
|
|
object GetValue(string name);
|
|
object GetValue(string name, object defaultValue, RegistryValueOptions options);
|
|
RegistryValueKind GetValueKind(string name);
|
|
object RegistryKey { get; }
|
|
void SetAccessControl(ObjectSecurity securityDescriptor);
|
|
ObjectSecurity GetAccessControl(AccessControlSections includeSections);
|
|
void Close();
|
|
string Name { get;}
|
|
int SubKeyCount { get;}
|
|
}
|
|
|
|
internal static class RegistryWrapperUtils
|
|
{
|
|
public static object ConvertValueToUIntFromRegistryIfNeeded(string name, object value, RegistryValueKind kind)
|
|
{
|
|
try
|
|
{
|
|
// Workaround for CLR bug that doesn't support full range of DWORD or QWORD
|
|
if (kind == RegistryValueKind.DWord)
|
|
{
|
|
value = (int)value;
|
|
if ((int)value < 0)
|
|
{
|
|
value = BitConverter.ToUInt32(BitConverter.GetBytes((int)value), 0);
|
|
}
|
|
}
|
|
else if (kind == RegistryValueKind.QWord)
|
|
{
|
|
value = (long)value;
|
|
if ((long)value < 0)
|
|
{
|
|
value = BitConverter.ToUInt64(BitConverter.GetBytes((long)value), 0);
|
|
}
|
|
}
|
|
}
|
|
catch (System.IO.IOException)
|
|
{
|
|
// This is expected if the value does not exist.
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
public static object ConvertUIntToValueForRegistryIfNeeded(object value, RegistryValueKind kind)
|
|
{
|
|
// Workaround for CLR bug that doesn't support full range of DWORD or QWORD
|
|
if (kind == RegistryValueKind.DWord)
|
|
{
|
|
UInt32 intValue = 0;
|
|
|
|
// See if it's already a positive number
|
|
try
|
|
{
|
|
intValue = Convert.ToUInt32(value, CultureInfo.InvariantCulture);
|
|
value = BitConverter.ToInt32(BitConverter.GetBytes(intValue), 0);
|
|
}
|
|
catch (OverflowException)
|
|
{
|
|
// It must be a negative Int32, and therefore need no more conversion
|
|
}
|
|
}
|
|
else if (kind == RegistryValueKind.QWord)
|
|
{
|
|
UInt64 intValue = 0;
|
|
|
|
// See if it's already a positive number
|
|
try
|
|
{
|
|
intValue = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
|
|
value = BitConverter.ToInt64(BitConverter.GetBytes(intValue), 0);
|
|
}
|
|
catch (OverflowException)
|
|
{
|
|
// It must be a negative Int64, and therefore need no more conversion
|
|
}
|
|
}
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
internal class RegistryWrapper : IRegistryWrapper
|
|
{
|
|
RegistryKey regKey;
|
|
|
|
internal RegistryWrapper(RegistryKey regKey)
|
|
{
|
|
this.regKey = regKey;
|
|
}
|
|
|
|
#region IRegistryWrapper Members
|
|
|
|
public void SetValue(string name, object value)
|
|
{
|
|
regKey.SetValue(name, value);
|
|
}
|
|
|
|
public void SetValue(string name, object value, RegistryValueKind valueKind)
|
|
{
|
|
value = System.Management.Automation.PSObject.Base(value);
|
|
value = RegistryWrapperUtils.ConvertUIntToValueForRegistryIfNeeded(value, valueKind);
|
|
|
|
regKey.SetValue(name, value, valueKind);
|
|
}
|
|
|
|
public string[] GetValueNames()
|
|
{
|
|
return regKey.GetValueNames();
|
|
}
|
|
|
|
public void DeleteValue(string name)
|
|
{
|
|
regKey.DeleteValue(name);
|
|
}
|
|
|
|
public string[] GetSubKeyNames()
|
|
{
|
|
return regKey.GetSubKeyNames();
|
|
}
|
|
|
|
public IRegistryWrapper CreateSubKey(string subkey)
|
|
{
|
|
RegistryKey newKey = regKey.CreateSubKey(subkey);
|
|
if (newKey == null)
|
|
return null;
|
|
else
|
|
return new RegistryWrapper(newKey);
|
|
}
|
|
|
|
public IRegistryWrapper OpenSubKey(string name, bool writable)
|
|
{
|
|
RegistryKey newKey = regKey.OpenSubKey(name, writable);
|
|
if (newKey == null)
|
|
return null;
|
|
else
|
|
return new RegistryWrapper(newKey);
|
|
}
|
|
|
|
public void DeleteSubKeyTree(string subkey)
|
|
{
|
|
regKey.DeleteSubKeyTree(subkey);
|
|
}
|
|
|
|
public object GetValue(string name)
|
|
{
|
|
object value = regKey.GetValue(name);
|
|
|
|
try
|
|
{
|
|
value = RegistryWrapperUtils.ConvertValueToUIntFromRegistryIfNeeded(name, value, GetValueKind(name));
|
|
}
|
|
catch (System.IO.IOException)
|
|
{
|
|
// This is expected if the value does not exist.
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
public object GetValue(string name, object defaultValue, RegistryValueOptions options)
|
|
{
|
|
object value = regKey.GetValue(name, defaultValue, options);
|
|
|
|
try
|
|
{
|
|
value = RegistryWrapperUtils.ConvertValueToUIntFromRegistryIfNeeded(name, value, GetValueKind(name));
|
|
}
|
|
catch (System.IO.IOException)
|
|
{
|
|
// This is expected if the value does not exist.
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
public RegistryValueKind GetValueKind(string name)
|
|
{
|
|
return regKey.GetValueKind(name);
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
regKey.Dispose();
|
|
}
|
|
|
|
public string Name
|
|
{
|
|
get { return regKey.Name; }
|
|
}
|
|
|
|
public int SubKeyCount
|
|
{
|
|
get { return regKey.SubKeyCount; }
|
|
}
|
|
|
|
public object RegistryKey
|
|
{
|
|
get { return regKey; }
|
|
}
|
|
|
|
public void SetAccessControl(ObjectSecurity securityDescriptor)
|
|
{
|
|
regKey.SetAccessControl((RegistrySecurity)securityDescriptor);
|
|
}
|
|
|
|
public ObjectSecurity GetAccessControl(AccessControlSections includeSections)
|
|
{
|
|
return regKey.GetAccessControl(includeSections);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
internal class TransactedRegistryWrapper : IRegistryWrapper
|
|
{
|
|
TransactedRegistryKey txRegKey;
|
|
CmdletProvider provider;
|
|
|
|
internal TransactedRegistryWrapper(TransactedRegistryKey txRegKey, CmdletProvider provider)
|
|
{
|
|
this.txRegKey = txRegKey;
|
|
this.provider = provider;
|
|
}
|
|
|
|
#region IRegistryWrapper Members
|
|
|
|
public void SetValue(string name, object value)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
txRegKey.SetValue(name, value);
|
|
}
|
|
}
|
|
|
|
public void SetValue(string name, object value, RegistryValueKind valueKind)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
value = System.Management.Automation.PSObject.Base(value);
|
|
value = RegistryWrapperUtils.ConvertUIntToValueForRegistryIfNeeded(value, valueKind);
|
|
|
|
txRegKey.SetValue(name, value, valueKind);
|
|
}
|
|
}
|
|
|
|
public string[] GetValueNames()
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
return txRegKey.GetValueNames();
|
|
}
|
|
}
|
|
|
|
public void DeleteValue(string name)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
txRegKey.DeleteValue(name);
|
|
}
|
|
}
|
|
|
|
public string[] GetSubKeyNames()
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
return txRegKey.GetSubKeyNames();
|
|
}
|
|
}
|
|
|
|
public IRegistryWrapper CreateSubKey(string subkey)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
TransactedRegistryKey newKey = txRegKey.CreateSubKey(subkey);
|
|
if (newKey == null)
|
|
return null;
|
|
else
|
|
return new TransactedRegistryWrapper(newKey, provider);
|
|
}
|
|
}
|
|
|
|
public IRegistryWrapper OpenSubKey(string name, bool writable)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
TransactedRegistryKey newKey = txRegKey.OpenSubKey(name, writable);
|
|
if (newKey == null)
|
|
return null;
|
|
else
|
|
return new TransactedRegistryWrapper(newKey, provider);
|
|
}
|
|
}
|
|
|
|
public void DeleteSubKeyTree(string subkey)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
txRegKey.DeleteSubKeyTree(subkey);
|
|
}
|
|
}
|
|
|
|
public object GetValue(string name)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
object value = txRegKey.GetValue(name);
|
|
|
|
try
|
|
{
|
|
value = RegistryWrapperUtils.ConvertValueToUIntFromRegistryIfNeeded(name, value, GetValueKind(name));
|
|
}
|
|
catch (System.IO.IOException)
|
|
{
|
|
// This is expected if the value does not exist.
|
|
}
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
public object GetValue(string name, object defaultValue, RegistryValueOptions options)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
object value = txRegKey.GetValue(name, defaultValue, options);
|
|
|
|
try
|
|
{
|
|
value = RegistryWrapperUtils.ConvertValueToUIntFromRegistryIfNeeded(name, value, GetValueKind(name));
|
|
}
|
|
catch (System.IO.IOException)
|
|
{
|
|
// This is expected if the value does not exist.
|
|
}
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
public RegistryValueKind GetValueKind(string name)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
return txRegKey.GetValueKind(name);
|
|
}
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
txRegKey.Close();
|
|
}
|
|
}
|
|
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
return txRegKey.Name;
|
|
}
|
|
}
|
|
}
|
|
|
|
public int SubKeyCount
|
|
{
|
|
get
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
return txRegKey.SubKeyCount;
|
|
}
|
|
}
|
|
}
|
|
|
|
public object RegistryKey
|
|
{
|
|
get { return txRegKey; }
|
|
}
|
|
|
|
public void SetAccessControl(ObjectSecurity securityDescriptor)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
txRegKey.SetAccessControl((TransactedRegistrySecurity)securityDescriptor);
|
|
}
|
|
}
|
|
|
|
public ObjectSecurity GetAccessControl(AccessControlSections includeSections)
|
|
{
|
|
using (provider.CurrentPSTransaction)
|
|
{
|
|
return txRegKey.GetAccessControl(includeSections);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |