Skip to content

Commit

Permalink
Add ComScope disposal test
Browse files Browse the repository at this point in the history
Add a test to ensure ComScope is "null" after disposal.
  • Loading branch information
JeremyKuhne committed Oct 2, 2023
1 parent 58dde21 commit b18bf3c
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 14 deletions.
25 changes: 11 additions & 14 deletions src/thirtytwo/Win32/System/Registry/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,21 @@ public static string QueryKeyName(HKEY key)
}

using BufferScope<char> buffer = new(stackalloc char[256]);
while (true)
while (true) fixed (char* b = buffer)
{
fixed (char* b = buffer)
{
uint length;
NTSTATUS status = Wdk.Interop.NtQueryKey(key, KEY_INFORMATION_CLASS.KeyNameInformation, b, (uint)buffer.Length, &length);
uint length;
NTSTATUS status = Wdk.Interop.NtQueryKey(key, KEY_INFORMATION_CLASS.KeyNameInformation, b, (uint)buffer.Length, &length);

if (status == NTSTATUS.STATUS_BUFFER_TOO_SMALL || status == NTSTATUS.STATUS_BUFFER_OVERFLOW)
{
buffer.EnsureCapacity((int)length);
continue;
}
if (status == NTSTATUS.STATUS_BUFFER_TOO_SMALL || status == NTSTATUS.STATUS_BUFFER_OVERFLOW)
{
buffer.EnsureCapacity((int)length);
continue;
}

status.ThrowIfFailed();
status.ThrowIfFailed();

KEY_NAME_INFORMATION* nameInfo = (KEY_NAME_INFORMATION*)b;
return new ReadOnlySpan<char>(nameInfo->Name.Value, (int)nameInfo->NameLength / sizeof(char)).ToString();
}
KEY_NAME_INFORMATION* nameInfo = (KEY_NAME_INFORMATION*)b;
return new ReadOnlySpan<char>(nameInfo->Name.Value, (int)nameInfo->NameLength / sizeof(char)).ToString();
}
}

Expand Down
62 changes: 62 additions & 0 deletions src/thirtytwo_tests/Win32/System/Com/ComScopeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) Jeremy W. Kuhne. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Windows.Win32.Foundation;

namespace Windows.Win32.System.Com;

public unsafe class ComScopeTests
{
[StaFact]
public void ComScope_NullAfterDispose()
{
ComScope<ITestObject> scope = new(ComHelpers.GetComPointer<ITestObject>(new TestObject()));
scope.IsNull.Should().BeFalse();
scope.Dispose();
scope.IsNull.Should().BeTrue();
}

public class TestObject : ITestObject.Interface, IManagedWrapper<ITestObject>
{
}

public readonly unsafe struct ITestObject : IComIID, IVTable<ITestObject, ITestObject.Vtbl>
{
private readonly void** _vtbl;

public struct Vtbl
{
internal delegate* unmanaged[Stdcall]<ITestObject*, Guid*, void**, HRESULT> QueryInterface_1;
internal delegate* unmanaged[Stdcall]<ITestObject*, uint> AddRef_2;
internal delegate* unmanaged[Stdcall]<ITestObject*, uint> Release_3;
}

[ComImport]
[Guid("630A7370-733D-43E9-8141-685DAE2BDB44")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface Interface
{
}

static ref readonly Guid IComIID.Guid
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ReadOnlySpan<byte> data = new byte[]
{
// "3BE9EE32-26FB-4E7A-B8A8-25795A7EFB53"
0x70, 0x73, 0x0A, 0x63, 0x3D, 0x73, 0xE9, 0x43, 0x81, 0x41, 0x68, 0x5D, 0xAE, 0x2B, 0xDB, 0x44
};

return ref Unsafe.As<byte, Guid>(ref MemoryMarshal.GetReference(data));
}
}

static void IVTable<ITestObject, Vtbl>.PopulateVTable(Vtbl* vtable)
{
}
}
}

0 comments on commit b18bf3c

Please sign in to comment.