📄 win32keyprovider.cs
字号:
/* * Win32KeyProvider.cs - Implementation of the * "Microsoft.Win32.Win32KeyProvider" class. * * Copyright (C) 2003 Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */namespace Microsoft.Win32{#if CONFIG_WIN32_SPECIFICSusing System;using System.Text;using System.Collections;using System.Runtime.InteropServices;using System.Runtime.CompilerServices;// This class implements registry functionality for Win32 systems.internal sealed class Win32KeyProvider : IRegistryKeyProvider{ // Internal state. private String name; private IntPtr hKey; // Constructors. public Win32KeyProvider(String name, IntPtr hKey) { this.name = name; this.hKey = hKey; } // Destructor. ~Win32KeyProvider() { Close(false); } // Determine if we should use the Win32 registry. public static bool IsWin32() { return (Environment.OSVersion.Platform != PlatformID.Unix); } // Close a reference to this key and flush any modifications to disk. public void Close(bool writable) { lock(this) { if(hKey != IntPtr.Zero) { long key = hKey.ToInt64(); if(key < (long)(int)(RegistryHive.ClassesRoot) || key > (long)(int)(RegistryHive.DynData)) { RegCloseKey(hKey); } hKey = IntPtr.Zero; } } } // Create a subkey underneath this particular registry key. public IRegistryKeyProvider CreateSubKey(String subkey) { lock(this) { if(hKey != IntPtr.Zero) { IntPtr newKey; if(RegCreateKey(hKey, subkey, out newKey) == 0) { return new Win32KeyProvider (name + "\\" + subkey, newKey); } } } throw new ArgumentException(_("IO_RegistryKeyNotExist")); } // Returns true if we should delete subkeys from their parents. public bool DeleteFromParents { get { // Use "DeleteSubKey" and "DeleteSubKeyTree". return true; } } // Delete a subkey of this key entry. Returns false if not present. public bool DeleteSubKey(String name) { lock(this) { if(hKey != IntPtr.Zero) { // Make sure that we don't have any subkeys. // This is to work around an API discontinuity: // Win95 deletes subtrees, but WinNT doesn't. uint numSubKeys, numValues; RegQueryInfoKey(hKey, null, IntPtr.Zero, IntPtr.Zero, out numSubKeys, IntPtr.Zero, IntPtr.Zero, out numValues, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if(numSubKeys != 0) { throw new InvalidOperationException (_("IO_RegistryHasSubKeys")); } return (RegDeleteKey(hKey, name) == 0); } else { return false; } } } // Delete this key entry. public void Delete() { // This version is not used under Win32. } // Internal recursive version of "DeleteSubKeyTree". private static bool DeleteSubKeyTree(IntPtr hKey, String name) { IntPtr subTree; // Open the subkey tree. if(RegOpenKeyEx(hKey, name, 0, KEY_ALL_ACCESS, out subTree) != 0) { return false; } // Collect up the names of all subkeys under "subTree". uint numSubKeys, numValues; RegQueryInfoKey(subTree, null, IntPtr.Zero, IntPtr.Zero, out numSubKeys, IntPtr.Zero, IntPtr.Zero, out numValues, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); String[] names = new String [numSubKeys]; uint index = 0; char[] nameBuf = new char [1024]; uint nameLen; long writeTime; while(index < numSubKeys) { nameBuf.Initialize(); nameLen = (uint)(name.Length); if(RegEnumKeyEx(subTree, index, nameBuf, ref nameLen, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out writeTime) != 0) { break; } names[(int)(index++)] = ArrayToString(nameBuf); } // Recursively delete the subtrees. foreach(String n in names) { DeleteSubKeyTree(subTree, n); } // Close the subtree. RegCloseKey(subTree); // Delete the subkey that corresponds to the subtree. return (RegDeleteKey(hKey, name) == 0); } // Delete a subkey entry and all of its descendents. // Returns false if not present. public bool DeleteSubKeyTree(String name) { lock(this) { if(hKey != IntPtr.Zero) { return DeleteSubKeyTree(hKey, name); } else { return false; } } } // Delete this key entry and all of its descendents. public void DeleteTree() { // This version is not used under Win32. } // Delete a particular value underneath this registry key. // Returns false if the value is missing. public bool DeleteValue(String name) { lock(this) { if(hKey != IntPtr.Zero) { if(RegDeleteValue(hKey, name) == 0) { return true; } } return false; } } // Flush all modifications to this registry key. public void Flush() { lock(this) { if(hKey != IntPtr.Zero) { RegFlushKey(hKey); } } } // Convert a null-terminated "char[]" array into a "String". private static String ArrayToString(char[] array) { int index = 0; while(index < array.Length && array[index] != '\0') { ++index; } return new String(array, 0, index); } // Convert a null-terminated "byte[]" array into a "String", // where the array contains 16-bit character values. private static String ArrayToString(byte[] array, ref int index) { int len = 0; while((index + len + 1) < array.Length && (array[index + len] != 0 || array[index + len + 1] != 0)) { len += 2; } StringBuilder builder = new StringBuilder(len / 2); len = 0; while((index + len + 1) < array.Length && (array[index + len] != 0 || array[index + len + 1] != 0)) { builder.Append((char)(((int)array[index + len]) | (((int)array[index + len + 1]) << 8))); len += 2; } index += len + 2; return builder.ToString(); } private static String ArrayToString(byte[] array) { int index = 0; return ArrayToString(array, ref index); } // Convert a "byte[]" array into an array of "String" values. private static String[] ArrayToStringArray(byte[] array) { ArrayList list = new ArrayList(); String value; int index = 0; for(;;) { value = ArrayToString(array, ref index); if(value.Length == 0) { break; } list.Add(value); } return (String[])(list.ToArray(typeof(String))); } // Convert a "String" into a "byte[]" array. private static byte[] StringToArray(String value) { byte[] data = new byte [value.Length * 2]; int index; for(index = 0; index < value.Length; ++index) { data[index * 2] = (byte)(value[index]); data[index * 2 + 1] = (byte)(value[index] >> 8); } return data; } // Convert a "String[]" array into a "byte[]" array. private static byte[] StringArrayToArray(String[] value) { // Determine the total length of the "byte[]" array. int len = 0; int index, posn; String str; for(index = 0; index < value.Length; ++index) { str = value[index]; if(str != null) { len += str.Length * 2 + 2; } else { len += 2; } } len += 2; // Create the "byte[]" array. byte[] data = new byte [len]; // Write the strings into the "byte[]" array. len = 0; for(index = 0; index < value.Length; ++index) { str = value[index]; if(str != null) { for(posn = 0; posn < str.Length; ++posn) { data[len++] = (byte)(str[posn]); data[len++] = (byte)(str[posn] >> 8); } len += 2; } else { len += 2; } } // Return the final encoded array to the caller. return data; } // Get the names of all subkeys underneath this registry key. public String[] GetSubKeyNames() { lock(this) { if(hKey != IntPtr.Zero) { // Get the number of subkey names under the key. uint numSubKeys, numValues; RegQueryInfoKey(hKey, null, IntPtr.Zero, IntPtr.Zero, out numSubKeys, IntPtr.Zero, IntPtr.Zero, out numValues, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); // Create an array to hold the names. String[] names = new String [numSubKeys]; // Enumerate the names into the array. uint index = 0; char[] name = new char [1024]; uint nameLen; long writeTime; while(index < numSubKeys) { name.Initialize(); nameLen = (uint)(name.Length); if(RegEnumKeyEx(hKey, index, name, ref nameLen, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out writeTime) != 0) { break; } names[(int)(index++)] = ArrayToString(name); } // Return the final name array to the caller. return names; } return new String [0]; } } // Get a value from underneath this registry key. public Object GetValue(String name, Object defaultValue) { uint type = REG_NONE; byte[] data = null; uint dataLen; // Query the value from the registry. lock(this) { if(hKey != IntPtr.Zero) { // Determine how big the buffer needs to be first. dataLen = 0; if(RegQueryValueEx(hKey, name, IntPtr.Zero, out type, IntPtr.Zero, ref dataLen) != 0) { return defaultValue; } // Allocate a buffer to hold the data. data = new byte [dataLen]; // Now query the actual value. if(RegQueryValueEx(hKey, name, IntPtr.Zero, out type, data, ref dataLen) != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -