Skip to content

Commit

Permalink
Improve performance of RegistryKey.GetValue (#66918)
Browse files Browse the repository at this point in the history
Reduces typical number of syscalls as well as avoids allocation (or uses the ArrayPool otherwise).

Also updates Corelib's copy of RegistryKey to match (with things like perf key support removed).
  • Loading branch information
stephentoub authored Jul 23, 2022
1 parent 02ee890 commit cbfc549
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 412 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,12 @@ internal static partial int RegQueryValueEx(
ref int lpcbData);

[LibraryImport(Libraries.Advapi32, EntryPoint = "RegQueryValueExW", StringMarshalling = StringMarshalling.Utf16)]
internal static partial int RegQueryValueEx(
SafeRegistryHandle hKey,
string? lpValueName,
int[]? lpReserved,
ref int lpType,
ref int lpData,
ref int lpcbData);

[LibraryImport(Libraries.Advapi32, EntryPoint = "RegQueryValueExW", StringMarshalling = StringMarshalling.Utf16)]
internal static partial int RegQueryValueEx(
SafeRegistryHandle hKey,
string? lpValueName,
int[]? lpReserved,
ref int lpType,
ref long lpData,
ref int lpcbData);

[LibraryImport(Libraries.Advapi32, EntryPoint = "RegQueryValueExW", StringMarshalling = StringMarshalling.Utf16)]
internal static partial int RegQueryValueEx(
internal static unsafe partial int RegQueryValueEx(
SafeRegistryHandle hKey,
string? lpValueName,
int[]? lpReserved,
ref int lpType,
[Out] char[]? lpData,
ref int lpcbData);
int* lpReserved,
int* lpType,
byte* lpData,
uint* lpcbData);
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<root>
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
Expand Down Expand Up @@ -84,8 +85,8 @@
<data name="Arg_RegBadKeyKind" xml:space="preserve">
<value>The specified RegistryValueKind is an invalid value.</value>
</data>
<data name="Arg_RegGetOverflowBug" xml:space="preserve">
<value>RegistryKey.GetValue does not allow a String that has a length greater than Int32.MaxValue.</value>
<data name="Arg_RegValueTooLarge" xml:space="preserve">
<value>RegistryKey.GetValue does not support values with more than Int32.MaxValue bytes.</value>
</data>
<data name="Arg_RegSetMismatchedKind" xml:space="preserve">
<value>The type of the value object did not match the specified RegistryValueKind or the object could not be properly converted.</value>
Expand Down Expand Up @@ -135,4 +136,4 @@
<data name="UnauthorizedAccess_RegistryNoWrite" xml:space="preserve">
<value>Cannot write to the registry key.</value>
</data>
</root>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ public void ReadRegMultiSzLackingFinalNullTerminatorCorrectly()
}

[Theory]
[InlineData(RegistryValueKind.String, new byte[] { 6, 5, 6 })]
[InlineData(RegistryValueKind.ExpandString, new byte[] { 6, 5, 6 })]
[InlineData(RegistryValueKind.MultiString, new byte[] { 6, 5, 6, 0, 0 })]
public void RegSzOddByteLength(RegistryValueKind kind, byte[] contents)
[InlineData(RegistryValueKind.String, new byte[] { 6, 5, 6 }, "\u0506")]
[InlineData(RegistryValueKind.ExpandString, new byte[] { 6, 5, 6 }, "\u0506")]
[InlineData(RegistryValueKind.MultiString, new byte[] { 6, 5, 6 }, "\u0506")]
[InlineData(RegistryValueKind.String, new byte[] { 6, 5, 6, 0, 0 }, "\u0506\u0006")]
[InlineData(RegistryValueKind.ExpandString, new byte[] { 6, 5, 6, 0, 0 }, "\u0506\u0006")]
[InlineData(RegistryValueKind.MultiString, new byte[] { 6, 5, 6, 0, 0 }, "\u0506\u0006")]
public void RegSzOddByteLength(RegistryValueKind kind, byte[] contents, string expected)
{
const string TestValueName = "CorruptData2";

Expand All @@ -73,9 +76,7 @@ public void RegSzOddByteLength(RegistryValueKind kind, byte[] contents)
s = (string)o;
}

Assert.Equal(2, s.Length);
Assert.Equal(0x506, s[0]);
Assert.Equal(0x6, s[1]);
Assert.Equal(expected, s);
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,12 @@ public void GetStringArrayTest()
Assert.Equal(expected, (string[])TestRegistryKey.GetValue(valueName));
TestRegistryKey.DeleteValue(valueName);
}

[Fact]
public void GetPerformanceKeyValue()
{
string[] counterNames = (string[])Registry.PerformanceData.GetValue("Counter");
Assert.NotEmpty(counterNames);
}
}
}
Loading

0 comments on commit cbfc549

Please sign in to comment.