Skip to content

Commit 1404726

Browse files
committed
Use RegDeleteTree in RegistryKey.DeleteSubKeyTree
1 parent 18e20d8 commit 1404726

File tree

3 files changed

+27
-52
lines changed

3 files changed

+27
-52
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
#if REGISTRY_ASSEMBLY
5+
using Microsoft.Win32.SafeHandles;
6+
#else
7+
using Internal.Win32.SafeHandles;
8+
#endif
9+
using System.Runtime.InteropServices;
10+
11+
internal static partial class Interop
12+
{
13+
internal static partial class Advapi32
14+
{
15+
[LibraryImport(Libraries.Advapi32, EntryPoint = "RegDeleteTreeW", StringMarshalling = StringMarshalling.Utf16)]
16+
internal static partial int RegDeleteTree(
17+
SafeRegistryHandle hKey,
18+
string lpSubKey);
19+
}
20+
}

src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
Link="Common\Interop\Windows\Interop.RegCreateKeyEx.cs" />
2828
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegDeleteKeyEx.cs"
2929
Link="Common\Interop\Windows\Interop.RegDeleteKeyEx.cs" />
30+
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegDeleteTree.cs"
31+
Link="Common\Interop\Windows\Interop.RegDeleteTree.cs" />
3032
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegDeleteValue.cs"
3133
Link="Common\Interop\Windows\Interop.RegDeleteValue.cs" />
3234
<Compile Include="$(CommonPath)Interop\Windows\Advapi32\Interop.RegEnumKeyEx.cs"

src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -334,63 +334,16 @@ public void DeleteSubKeyTree(string subkey, bool throwOnMissingSubKey)
334334

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

337-
RegistryKey? key = InternalOpenSubKeyWithoutSecurityChecks(subkey, true);
338-
if (key != null)
339-
{
340-
using (key)
341-
{
342-
if (key.SubKeyCount > 0)
343-
{
344-
string[] keys = key.GetSubKeyNames();
345-
346-
for (int i = 0; i < keys.Length; i++)
347-
{
348-
key.DeleteSubKeyTreeInternal(keys[i]);
349-
}
350-
}
351-
}
337+
int ret = Interop.Advapi32.RegDeleteTree(_hkey, subkey);
352338

353-
DeleteSubKeyTreeCore(subkey);
354-
}
355-
else if (throwOnMissingSubKey)
356-
{
357-
throw new ArgumentException(SR.Arg_RegSubKeyAbsent);
358-
}
359-
}
360-
361-
/// <summary>
362-
/// An internal version which does no security checks or argument checking. Skipping the
363-
/// security checks should give us a slight perf gain on large trees.
364-
/// </summary>
365-
private void DeleteSubKeyTreeInternal(string subkey)
366-
{
367-
RegistryKey? key = InternalOpenSubKeyWithoutSecurityChecks(subkey, true);
368-
if (key != null)
339+
if (ret == Interop.Errors.ERROR_FILE_NOT_FOUND)
369340
{
370-
using (key)
341+
if (throwOnMissingSubKey)
371342
{
372-
if (key.SubKeyCount > 0)
373-
{
374-
string[] keys = key.GetSubKeyNames();
375-
for (int i = 0; i < keys.Length; i++)
376-
{
377-
key.DeleteSubKeyTreeInternal(keys[i]);
378-
}
379-
}
343+
throw new ArgumentException(SR.Arg_RegSubKeyAbsent);
380344
}
381-
382-
DeleteSubKeyTreeCore(subkey);
383-
}
384-
else
385-
{
386-
throw new ArgumentException(SR.Arg_RegSubKeyAbsent);
387345
}
388-
}
389-
390-
private void DeleteSubKeyTreeCore(string subkey)
391-
{
392-
int ret = Interop.Advapi32.RegDeleteKeyEx(_hkey, subkey, (int)_regView, 0);
393-
if (ret != 0)
346+
else if (ret != 0)
394347
{
395348
Win32Error(ret, null);
396349
}

0 commit comments

Comments
 (0)