// 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())); } }
// 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()); } }
/* * 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); }
private DoesntExistOrMarkedAsDeletedState DoesntExistOrMarkedAsDeleted(KeyIdentity existingBase, KeyIdentity identity, IntPtr allocatedpData, IntPtr allocatedpcbData) { string[] subkeys = identity.SplitPath(); int existingLevels, nonRemovableLevels; CalcNonRemovableLevels(existingBase, identity, out existingLevels, out nonRemovableLevels); if (subkeys.Length <= nonRemovableLevels) { return(DoesntExistOrMarkedAsDeletedState.Exists); } for (int level = existingLevels; level < subkeys.Length; level++) { KeyIdentity curLevelIdentity = KeyIdentity.Build(identity.BaseKey, subkeys, level); KeyImplHolder holder; lock (this) { IKeyImpl keyImpl = null; if (level <= nonRemovableLevels) { keyImpl = cacheForDeletedMarks_.TryGet(curLevelIdentity, KeyDisposition.DIFF_HIVE, cacheSecurity_); } if (keyImpl != null) { holder = new NotOwningKeyImplHolder(keyImpl); } else { OffregLib.OffregKey key; OffregLib.Win32Result result; if (!hive_.Root.TryOpenSubKey(OffRegKey.GetMainOffRegPath(curLevelIdentity), out key, out result)) { return(DoesntExistOrMarkedAsDeletedState.DoesntExist); } holder = new KeyImplHolder(new OffRegKey(this, key, curLevelIdentity)); if (level <= nonRemovableLevels) { // Adding to cache only the lowest, non removable level holder = cacheForDeletedMarks_.Add( curLevelIdentity, KeyDisposition.DIFF_HIVE, holder); } } } using (holder) { Marshal.WriteInt32(allocatedpcbData, Marshal.SizeOf(typeof(int))); if (holder.GetKeyImpl().TryQueryValue( DELETED_PREFIX + subkeys[level], IntPtr.Zero, IntPtr.Zero, allocatedpData, allocatedpcbData)) { if (Marshal.ReadInt32(allocatedpcbData) == Marshal.SizeOf(typeof(int)) && Marshal.ReadInt32(allocatedpData) != 0) { // There is a special value marking key as deleted return(DoesntExistOrMarkedAsDeletedState.MarkedAsDeleted); } } } } return(DoesntExistOrMarkedAsDeletedState.Exists); }
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); }