Skip to content

Commit

Permalink
Use RegDeleteTree in RegistryKey.DeleteSubKeyTree
Browse files Browse the repository at this point in the history
  • Loading branch information
huoyaoyuan committed Feb 28, 2023
1 parent 18e20d8 commit 1404726
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if REGISTRY_ASSEMBLY
using Microsoft.Win32.SafeHandles;
#else
using Internal.Win32.SafeHandles;
#endif
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Advapi32
{
[LibraryImport(Libraries.Advapi32, EntryPoint = "RegDeleteTreeW", StringMarshalling = StringMarshalling.Utf16)]
internal static partial int RegDeleteTree(
SafeRegistryHandle hKey,
string lpSubKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
Link="Common\Interop\Windows\Interop.RegCreateKeyEx.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegDeleteKeyEx.cs"
Link="Common\Interop\Windows\Interop.RegDeleteKeyEx.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegDeleteTree.cs"
Link="Common\Interop\Windows\Interop.RegDeleteTree.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegDeleteValue.cs"
Link="Common\Interop\Windows\Interop.RegDeleteValue.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegEnumKeyEx.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,63 +334,16 @@ public void DeleteSubKeyTree(string subkey, bool throwOnMissingSubKey)

subkey = FixupName(subkey); // Fixup multiple slashes to a single slash

RegistryKey? key = InternalOpenSubKeyWithoutSecurityChecks(subkey, true);
if (key != null)
{
using (key)
{
if (key.SubKeyCount > 0)
{
string[] keys = key.GetSubKeyNames();

for (int i = 0; i < keys.Length; i++)
{
key.DeleteSubKeyTreeInternal(keys[i]);
}
}
}
int ret = Interop.Advapi32.RegDeleteTree(_hkey, subkey);

DeleteSubKeyTreeCore(subkey);
}
else if (throwOnMissingSubKey)
{
throw new ArgumentException(SR.Arg_RegSubKeyAbsent);
}
}

/// <summary>
/// An internal version which does no security checks or argument checking. Skipping the
/// security checks should give us a slight perf gain on large trees.
/// </summary>
private void DeleteSubKeyTreeInternal(string subkey)
{
RegistryKey? key = InternalOpenSubKeyWithoutSecurityChecks(subkey, true);
if (key != null)
if (ret == Interop.Errors.ERROR_FILE_NOT_FOUND)
{
using (key)
if (throwOnMissingSubKey)
{
if (key.SubKeyCount > 0)
{
string[] keys = key.GetSubKeyNames();
for (int i = 0; i < keys.Length; i++)
{
key.DeleteSubKeyTreeInternal(keys[i]);
}
}
throw new ArgumentException(SR.Arg_RegSubKeyAbsent);
}

DeleteSubKeyTreeCore(subkey);
}
else
{
throw new ArgumentException(SR.Arg_RegSubKeyAbsent);
}
}

private void DeleteSubKeyTreeCore(string subkey)
{
int ret = Interop.Advapi32.RegDeleteKeyEx(_hkey, subkey, (int)_regView, 0);
if (ret != 0)
else if (ret != 0)
{
Win32Error(ret, null);
}
Expand Down

0 comments on commit 1404726

Please sign in to comment.