示例#1
0
 internal void MarkKeyAsDeleted(KeyIdentity identity)
 {
     try
     {
         string[] subkeys = identity.SplitPath();
         int      existingLevels, nonRemovableLevels;
         CalcNonRemovableLevels(null, identity, out existingLevels, out nonRemovableLevels);
         if (subkeys.Length <= nonRemovableLevels)
         {
             // We can't mark root keys as deleted
             return;
         }
         using (HGlobalPtr pData = new HGlobalPtr(Marshal.SizeOf(typeof(int))))
         {
             Marshal.WriteInt32(pData.Ptr, 1);
             // Conciously suppressing errors
             OffRegKey key = null;
             try
             {
                 key = new OffRegKey(this, hive_,
                                     KeyIdentity.Build(identity.BaseKey, subkeys, subkeys.Length - 1), null,
                                     Win32Api.RegOption.REG_OPTION_NON_VOLATILE, IntPtr.Zero,
                                     IntPtr.Zero);
                 key.SetValue(DELETED_PREFIX + subkeys[subkeys.Length - 1],
                              Win32Api.RegValueType.REG_DWORD,
                              pData.Ptr, Marshal.SizeOf(typeof(int)));
             }
             catch (Win32Exception)
             {
                 // Suppressing errors because there might be access issues
                 // or may be other stuff
                 if (key != null)
                 {
                     key.Close();
                 }
             }
         }
     }
     catch (FileNotFoundException)
     {
         // We don't know anything about the key, so we can't mark it as deleted
         return;
     }
 }
示例#2
0
        internal static void CalcNonRemovableLevels(KeyIdentity existingBase, KeyIdentity identity,
                                                    out int existing, out int nonRemovable)
        {
            existing = 0;
            if (existingBase != null && existingBase.BaseKey == identity.BaseKey)
            {
                existing = existingBase.SplitPath().Length;
            }
            if (!nonRemovableLevelsPerBaseKey_.ContainsKey((long)identity.BaseKey))
            {
                throw new FileNotFoundException();
            }
            List <KeyValuePair <string, int> > nonRemovableLevelsPerPrefix = nonRemovableLevelsPerBaseKey_[(long)identity.BaseKey];

            foreach (KeyValuePair <string, int> keyValue in nonRemovableLevelsPerPrefix)
            {
                if (keyValue.Key == null)
                {
                    nonRemovable = keyValue.Value;
                    existing     = Math.Max(existing, nonRemovable);
                    return;
                }
                if (identity.NtPath == null)
                {
                    continue;
                }
                // Optimized checking if NtPath begins with keyValue.Key
                if (identity.NtPath.StartsWith(keyValue.Key, StringComparison.CurrentCultureIgnoreCase) &&
                    (identity.NtPath.Length == keyValue.Key.Length || identity.NtPath[keyValue.Key.Length] == '\\'))
                {
                    nonRemovable = keyValue.Value;
                    existing     = Math.Max(existing, nonRemovable);
                    return;
                }
            }
            nonRemovable = 0;
            return;
        }
示例#3
0
        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);
        }