// existingBase is passed for performance optimization // TODO: encapsulate existingBase in a class and extract methods // with it a first argument there private bool TryOpenImpl(KeyIdentity existingBase, KeyDisposition disposition, KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl) { openedImpl = null; if (disposition != KeyDisposition.DIFF_HIVE) { if (diffHive_.IsMarkedAsDeleted(existingBase, identity)) { return(false); } } IKeyImplOpenFactory factory = null; switch (disposition) { case KeyDisposition.WINDOWS_REG: factory = windowsKeyFactory_; break; case KeyDisposition.BASE_HIVE: factory = baseHive_; break; case KeyDisposition.DIFF_HIVE: factory = diffHive_; break; } if (factory == null) { // In case if specified hive is not used (currently used // only for null baseHive_) return(false); } return(factory.TryOpen(identity, samDesired, out openedImpl)); }
private static extern Win32Result CreateKey64( IntPtr hKey, string lpSubKey, string lpClass, RegOption dwOptions, /*ref SECURITY_DESCRIPTOR*/ IntPtr lpSecurityDescriptor, /*ref IntPtr*/ out IntPtr phkResult, out KeyDisposition lpdwDisposition);
public static extern NtStatus NtCreateKey( out SafeKernelObjectHandle KeyHandle, KeyAccessRights DesiredAccess, [In] ObjectAttributes ObjectAttributes, int TitleIndex, UnicodeString Class, KeyCreateOptions CreateOptions, out KeyDisposition Disposition );
internal static extern int RegCreateKeyEx( uint hKey, string lpSubKey, int lpReserved, string lpClass, int dwOptions, int samDesired, IntPtr lpSecurityAttributes, ref uint phkResult, ref KeyDisposition lpdwDisposition);
/// <summary> /// Creates a new subkey or opens an existing subkey. /// The string subKey is not case-sensitive. /// <para><b>New in v1.3</b></para> /// </summary> /// <param name="subkey">Name or path of subkey to create or open.</param> /// <param name="createVolatile">If true creates a volatile key (Requires Windows CE 5.0).</param> /// <returns>Returns the subkey, or null if the operation failed.</returns> /// <exception cref="System.ArgumentNullException">The specified subkey is null.</exception> /// <exception cref="System.ArgumentException">The length of the specified subkey is longer than the maximum length allowed (255 characters).</exception> /// <exception cref="System.ObjectDisposedException">The RegistryKey on which this method is being invoked is closed (closed keys cannot be accessed).</exception> public RegistryKey CreateSubKey(string subkey, bool createVolatile) { //check handle is valid if (CheckHKey()) { //check subkey is not null if (subkey != null) { //check subkey length if (subkey.Length < 256) { //handle to new registry key uint newhandle = 0; //key disposition - did this create a new key or open an existing key KeyDisposition kdisp = 0; //options RegOptions options = 0; if (createVolatile) { options = RegOptions.Volatile; } //create new key int result = RegCreateKeyEx(m_handle, subkey, 0, null, options, 0, IntPtr.Zero, ref newhandle, ref kdisp); if (result == 0) { //success return the new key return(new RegistryKey(newhandle, m_name + "\\" + subkey, true, false)); } else { throw new ExternalException("An error occured creating the registry key."); } } else { //name is more than 255 chars throw new ArgumentException("The length of the specified subkey is longer than the maximum length allowed (255 characters)."); } } else { throw new ArgumentNullException("The specified subkey is null."); } } else { //registry key is closed throw new ObjectDisposedException("The RegistryKey on which this method is being invoked is closed (closed keys cannot be accessed)."); } }
internal IKeyImpl Open(KeyDisposition disposition, KeyIdentity identity, KeySecurity samDesired) { IKeyImpl result; if (!TryOpen(null, disposition, identity, samDesired, out result)) { throw new FileNotFoundException(); } return(result); }
private static void CheckReadOnlyHivesAccess(KeyDisposition disposition, KeySecurity samDesired) { if (disposition != KeyDisposition.DIFF_HIVE) { Debug.Assert(samDesired.IsOnlyForRead()); if (!samDesired.IsOnlyForRead()) { throw new AccessDeniedException(); } } }
// returns false if the key does not exist in the given disposition, // on other errors throws exception. private bool TryOpen(KeyIdentity existingBase, KeyDisposition disposition, KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl) { if (!TryOpenImpl(existingBase, disposition, identity, samDesired, out openedImpl)) { return(false); } baseKeyManager_.BaseKeyCopied(identity.BaseKey); openedImpl = new KeyImplDecoratorHookingClose(openedImpl, () => baseKeyManager_.BaseKeyClosed(identity.BaseKey)); return(true); }
private bool TryOpenKey(KeyIdentity existingBase, KeyDisposition disposition, KeyIdentity identity, KeySecurity samDesired, out VirtualKey key) { KeyImplHolder holder; key = null; if (!TryOpenHolder(existingBase, disposition, identity, samDesired, out holder)) { return(false); } key = new VirtualKey(this, identity, holder.ReleaseKeyImpl(), alterer_); return(true); }
/// <summary> /// Create a new subkey (or open an existing one) under another key. /// See http://msdn.microsoft.com/en-us/library/ee210761(v=vs.85).aspx /// </summary> /// <param name="hKey">Handle to an open key.</param> /// <param name="lpSubKey">Name of the new subkey.</param> /// <param name="lpClass">Name of the type of the new subkey.</param> /// <param name="dwOptions">Options for the creation.</param> /// <param name="lpSecurityDescriptor">Security descripter, may be NULL.</param> /// <param name="phkResult">The handle to the newly created key.</param> /// <param name="lpdwDisposition">The reuslting disposition.</param> /// <returns> /// <see cref="Win32Result" /> of the result. Win32Result.ERROR_SUCCESS indicates success. /// </returns> public static Win32Result CreateKey(IntPtr hKey, string lpSubKey, string lpClass, RegOption dwOptions, /*ref SECURITY_DESCRIPTOR*/ IntPtr lpSecurityDescriptor, /*ref IntPtr*/ out IntPtr phkResult, out KeyDisposition lpdwDisposition) { return(Is64BitProcess ? CreateKey64(hKey, lpSubKey, lpClass, dwOptions, lpSecurityDescriptor, out phkResult, out lpdwDisposition) : CreateKey32(hKey, lpSubKey, lpClass, dwOptions, lpSecurityDescriptor, out phkResult, out lpdwDisposition)); }
// If the keyImpl is added, returns NotOwningKeyImplHolder, // otherwise returns original KeyImplHolder public KeyImplHolder Add(KeyIdentity identity, KeyDisposition disposition, KeyImplHolder keyHolder) { lock (this) { CacheKey cacheKey = new CacheKey { Identity = identity, Disposition = disposition }; if (cachedKeyImpls_.ContainsKey(cacheKey)) { return(keyHolder); } cachedKeyImpls_.Add(cacheKey, keyHolder); return(new NotOwningKeyImplHolder(keyHolder.GetKeyImpl())); } }
private static bool CheckSystemKeyAccess(KeyDisposition disposition, KeyIdentity identity, KeySecurity samDesired) { // This way we redirect system registry locations into windows registry // and make it fail for write operations if (disposition != KeyDisposition.WINDOWS_REG && identity.IsSystemKey()) { if (samDesired.IsOnlyForRead()) { // So that it retries to read from system registry return(false); } // So that user gets appropriate error code throw new AccessDeniedException(); } return(true); }
internal OffRegHive(KeyDisposition disposition, string regHivePath, bool readOnly = true) { disposition_ = disposition; path_ = regHivePath; readOnly_ = readOnly; // We need to lock the specified path so that nobody can open it // until we close it, otherwise there might be conflicts in // save operations fileLock_ = new FileLock(regHivePath + ".lock"); try { OpenOrCreateHive(regHivePath, !readOnly); } catch (Exception) { fileLock_.Dispose(); throw; } }
// Returns keyImpl owned by cache, thus KeyHolder is not used public IKeyImpl TryGet(KeyIdentity identity, KeyDisposition disposition, KeySecurity samDesired) { lock (this) { CacheKey cacheKey = new CacheKey { Identity = identity, Disposition = disposition }; if (!cachedKeyImpls_.ContainsKey(cacheKey)) { return(null); } KeyImplHolder cached = cachedKeyImpls_[cacheKey]; if (!samDesired.IsSubSetOf(cached.GetKeyImpl().GetAccessMode())) { return(null); } return(cached.GetKeyImpl()); } }
private bool TryGetSubKey(KeyDisposition disposition, string lpSubKey, KeySecurity samDesired, Win32Api.RegWow64Options wowOptions, out KeyImplHolder subKeyHolder) { KeyIdentity subKeyIdentity = new KeyIdentity(identity_, wowOptions, lpSubKey); IKeyImpl keyImpl = cachedKeyImpls_.TryGet(subKeyIdentity, disposition, samDesired); if (keyImpl != null) { subKeyHolder = new NotOwningKeyImplHolder(keyImpl); return(true); } KeyImplHolder newOne; if (!opener_.TryOpenHolder(identity_, disposition, subKeyIdentity, samDesired, out newOne)) { subKeyHolder = null; return(false); } subKeyHolder = cachedKeyImpls_.Add(subKeyIdentity, disposition, newOne); return(true); }
private bool KeyExists(KeyDisposition disposition, KeyIdentity identity) { try { // TODO: perhaps use MAX_ALLOWED access here instead of READ IKeyImpl windowsKey; if (!TryOpen(null, disposition, identity, new KeySecurity(Win32Api.KeySecurity.STANDARD_RIGHTS_READ), out windowsKey)) { // Key does not exist return(false); } windowsKey.Close(); return(true); } catch (Win32Exception) { // Other error return(false); } }
// returns false in case of FileNotFound error, otherwise throws exception internal bool TryApplyOperation(KeyDisposition disposition, string subKeyName, KeySecurity samDesired, KeyImplOperation operation, Win32Api.RegWow64Options wowOptions = Win32Api.RegWow64Options.None) { // None is passed from Get/Set/Enum operations which does not allow user to pass wow options // in such case we take it from the current identity if (wowOptions == Win32Api.RegWow64Options.None) { wowOptions = identity_.GetWow64Mode(); } KeyImplHolder subKey; if (!TryGetSubKey(disposition, subKeyName, samDesired, wowOptions, out subKey)) { return(false); } using (subKey) { // TODO: almost always the operation needs subKey name, at least for logging // so it is constructed second time there. // Better to pass it from here. try { if (!operation(subKey.GetKeyImpl())) { return(false); } } catch (FileNotFoundException) { // TODO: make all operations return false in case of FileNotFoundException // so that this catch can be removed. return(false); } } return(true); }
/* * public KeyImplHolder OpenHolder(KeyDisposition disposition, * KeyIdentity identity, KeySecurity samDesired) * { * KeyImplHolder result; * if (!TryOpenHolder(disposition, identity, samDesired, out result)) * throw new FileNotFoundException(); * return result; * } */ public bool TryOpenHolder(KeyIdentity existingBase, KeyDisposition disposition, KeyIdentity identity, KeySecurity samDesired, out KeyImplHolder openedHolder) { openedHolder = null; // ATTENTION: it is not clear if this function works fine if // lpSubKey == null is given for a predefined key, may be it will fail // trying to close the predefined key or something. Check later. // This way we redirect system registry locations into windows registry // and make it fail for write operations if (!CheckSystemKeyAccess(disposition, identity, samDesired)) { return(false); } CheckReadOnlyHivesAccess(disposition, samDesired); IKeyImpl registryKey; if (disposition != KeyDisposition.DIFF_HIVE) { if (!TryOpen(existingBase, disposition, identity, samDesired, out registryKey)) { return(false); } } else { if (!TryOpenOrCreateDiffKey(existingBase, identity, samDesired, out registryKey)) { return(false); } } openedHolder = new KeyImplHolder(registryKey); return(true); }
/// <summary> /// Create a new subkey (or open an existing one) under another key. /// See http://msdn.microsoft.com/en-us/library/ee210761(v=vs.85).aspx /// </summary> /// <param name="hKey">Handle to an open key.</param> /// <param name="lpSubKey">Name of the new subkey.</param> /// <param name="lpClass">Name of the type of the new subkey.</param> /// <param name="dwOptions">Options for the creation.</param> /// <param name="lpSecurityDescriptor">Security descripter, may be NULL.</param> /// <param name="phkResult">The handle to the newly created key.</param> /// <param name="lpdwDisposition">The reuslting disposition.</param> /// <returns> /// <see cref="Win32Result" /> of the result. Win32Result.ERROR_SUCCESS indicates success. /// </returns> public static Win32Result CreateKey(IntPtr hKey, string lpSubKey, string lpClass, RegOption dwOptions, /*ref SECURITY_DESCRIPTOR*/ IntPtr lpSecurityDescriptor, /*ref IntPtr*/ out IntPtr phkResult, out KeyDisposition lpdwDisposition) { return Is64BitProcess ? CreateKey64(hKey, lpSubKey, lpClass, dwOptions, lpSecurityDescriptor, out phkResult, out lpdwDisposition) : CreateKey32(hKey, lpSubKey, lpClass, dwOptions, lpSecurityDescriptor, out phkResult, out lpdwDisposition); }
internal static extern int RegCreateKeyEx(uint hKey, string lpSubKey, int lpReserved, string lpClass, int dwOptions, int samDesired, IntPtr lpSecurityAttributes, ref uint phkResult, ref KeyDisposition lpdwDisposition);
internal NtKey(SafeKernelObjectHandle handle, KeyDisposition disposition) : base(handle) { Disposition = disposition; }