From 140472600c9a68301c7c0154636bd68929f9960f Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Tue, 28 Feb 2023 17:26:57 +0800 Subject: [PATCH] Use RegDeleteTree in RegistryKey.DeleteSubKeyTree --- .../Windows/Advapi32/Interop.RegDeleteTree.cs | 20 +++++++ .../src/Microsoft.Win32.Registry.csproj | 2 + .../src/Microsoft/Win32/RegistryKey.cs | 57 ++----------------- 3 files changed, 27 insertions(+), 52 deletions(-) create mode 100644 src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteTree.cs diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteTree.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteTree.cs new file mode 100644 index 00000000000000..52289627bc243d --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteTree.cs @@ -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); + } +} diff --git a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj index 5920905308d2fc..438a4d0caf5926 100644 --- a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj +++ b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj @@ -27,6 +27,8 @@ Link="Common\Interop\Windows\Interop.RegCreateKeyEx.cs" /> + 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); - } - } - - /// - /// 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. - /// - 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); }