Skip to content

Commit 1f1dc4f

Browse files
committed
refactor: add more native definitions, supporting Types
Some are platform-specific, hence the 32/64 suffixes. Although PEB32 and PEB64 are done, plain ol' PEB isn't done yet. I exploited FieldOffsetAttribute quite bit in these platform-specific definitions. Additionally, some of the less important, platform specific type definitions were skipped to save time.
1 parent 41b4c5a commit 1f1dc4f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2021
-103
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Runtime.InteropServices;
2+
3+
namespace deadlock_dotnet_sdk.Domain;
4+
5+
public class SafeBuffer<T> : SafeBuffer
6+
{
7+
public SafeBuffer(bool ownsHandle) : base(ownsHandle)
8+
{
9+
}
10+
11+
protected override bool ReleaseHandle()
12+
{
13+
Marshal.FreeHGlobal(handle);
14+
return true;
15+
}
16+
}

deadlock-dotnet-sdk/NativeMethods.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,10 @@ PUBLIC_OBJECT_TYPE_INFORMATION
6666
//VirtualQuery
6767

6868
GENERIC_MAPPING
69+
LDR_DATA_TABLE_ENTRY
70+
PEB32
71+
PEB64
72+
ProcessCommandLineInformation
73+
NtWow64ReadVirtualMemory64
74+
LARGE_INTEGER
75+
RTL_CRITICAL_SECTION
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The "32" and "64" suffixes indicate the bitness of the pointers (`UIntPtr32<T>`, `UIntPtr64<T>`¹) and the bitness of the pointers' owner process.
2+
3+
4+
¹ The generic Type `T` indicates the pointer type is a pointer to an object of type `T`. This is intended to mimic conventional pointer types' syntax. `UIntPtr32<int>` is intended to be equivalent to a 32-bit process's `int*`.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace Windows.Win32.Foundation;
2+
3+
internal struct HANDLE32
4+
{
5+
internal readonly UIntPtr32 Value { get; init; }
6+
7+
public static explicit operator HANDLE32(UIntPtr32 v) => new() { Value = v };
8+
public static implicit operator UIntPtr32(HANDLE32 v) => v.Value;
9+
}
10+
11+
internal struct HANDLE32<T> where T : unmanaged
12+
{
13+
internal readonly UIntPtr32<T> Value { get; init; }
14+
15+
public static explicit operator HANDLE32<T>(UIntPtr32<T> v) => new() { Value = v };
16+
public static implicit operator UIntPtr32<T>(HANDLE32<T> v) => v.Value;
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace Windows.Win32.Foundation;
2+
3+
internal struct HANDLE64
4+
{
5+
internal readonly UIntPtr64 Value { get; init; }
6+
7+
public static explicit operator HANDLE64(UIntPtr64 v) => new() { Value = v };
8+
public static implicit operator UIntPtr64(HANDLE64 v) => v.Value;
9+
}
10+
11+
internal struct HANDLE64<T> where T : unmanaged
12+
{
13+
internal readonly UIntPtr64<T> Value { get; init; }
14+
15+
public static explicit operator HANDLE64<T>(UIntPtr64<T> v) => new() { Value = v };
16+
public static implicit operator UIntPtr64<T>(HANDLE64<T> v) => v.Value;
17+
}

deadlock-dotnet-sdk/Windows.Win32/Foundation/NTSTATUS.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
using PInvoke;
2+
/// <summary>
13
/// This file supplements code generated by CsWin32
2-
using NTStatusException = PInvoke.NTStatusException;
3-
4+
/// </summary>
45
namespace Windows.Win32.Foundation;
56

67
readonly partial struct NTSTATUS
78
{
8-
public bool IsSuccessful => SeverityCode == Severity.Success;
9+
public bool IsSuccessful => SeverityCode is Severity.Success;
10+
11+
/// <inheritdoc cref="Kernel32Extensions.ThrowOnError(PInvoke.NTSTATUS)"/>
12+
public void ThrowOnError()
13+
{
14+
if (SeverityCode == Severity.Error)
15+
throw new NTStatusException(this);
16+
}
917

10-
public NTStatusException GetNTStatusException() => new(this);
18+
/// <inheritdoc cref="Kernel32Extensions.GetMessage(global::PInvoke.NTSTATUS)"/>
19+
public string GetMessage() => ((global::PInvoke.NTSTATUS)this).GetMessage();
1120

1221
public static implicit operator global::PInvoke.NTSTATUS(NTSTATUS v) => new(v.Value);
1322
public static implicit operator NTSTATUS(global::PInvoke.NTSTATUS v) => new(v.AsInt32);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/// This file supplements code generated by CsWin32
2+
using System.Runtime.InteropServices;
3+
4+
namespace Windows.Win32.Foundation;
5+
6+
unsafe readonly partial struct PCWSTR : IDisposable
7+
{
8+
/// <summary>
9+
/// Free the PWSTR's memory with Marshal.FreeHGlobal(IntPtr)
10+
/// </summary>
11+
public void Dispose() => Marshal.FreeHGlobal((IntPtr)Value);
12+
13+
public static explicit operator PCWSTR(IntPtr v) => new((char*)v);
14+
}

deadlock-dotnet-sdk/Windows.Win32/Foundation/UNICODE_STRING.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,43 @@
33

44
namespace Windows.Win32.Foundation;
55

6+
/// <summary>
7+
/// The UNICODE_STRING structure is used to define Unicode strings.
8+
/// </summary>
9+
/// <remarks>
10+
/// <para>The UNICODE_STRING structure is used to pass Unicode strings. Use RtlUnicodeStringInit or RtlUnicodeStringInitEx to initialize a UNICODE_STRING structure.</para>
11+
/// <para>If the string is null-terminated, Length does not include the trailing null character.</para>
12+
/// <para>The MaximumLength is used to indicate the length of Buffer so that if the string is passed to a conversion routine such as RtlAnsiStringToUnicodeString the returned string does not exceed the buffer size.</para>
13+
/// <para>
14+
/// - Length -- the length of the string in bytes.
15+
/// - MaximumLength -- the length of Buffer in bytes.
16+
/// - Buffer -- the address of the string.
17+
/// </para>
18+
/// </remarks>
619
partial struct UNICODE_STRING : IDisposable
720
{
21+
public UNICODE_STRING(ushort maximumLength, PWSTR buffer)
22+
{
23+
Length = (ushort)buffer.Length;
24+
MaximumLength = maximumLength;
25+
Buffer = buffer;
26+
}
27+
public UNICODE_STRING(ushort maximumLength)
28+
{
29+
Length = 0;
30+
MaximumLength = maximumLength;
31+
Buffer = Marshal.AllocHGlobal(maximumLength);
32+
}
33+
34+
public uint CharCount => (uint)ToStringLength().Length;
35+
836
public void Dispose()
937
{
1038
Buffer.Dispose();
1139
}
1240

1341
/// <summary>
14-
/// Allocates a managed string and copies a specified number of characters from an unmanaged Unicode string into it.
42+
/// Allocates a managed string and copies `(Length / 2)` number of characters from an unmanaged Unicode string into it.
1543
/// </summary>
1644
public unsafe string ToStringLength() => Marshal.PtrToStringUni((IntPtr)Buffer.Value, Length / 2);
1745
public string? ToStringZ() => Buffer.ToString();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Runtime.InteropServices;
2+
3+
namespace Windows.Win32.Foundation;
4+
5+
/// <summary>
6+
/// The UNICODE_STRING structure is used to define Unicode strings.
7+
/// </summary>
8+
/// <remarks>
9+
/// <para>The UNICODE_STRING structure is used to pass Unicode strings. Use RtlUnicodeStringInit or RtlUnicodeStringInitEx to initialize a UNICODE_STRING structure.</para>
10+
/// <para>If the string is null-terminated, Length does not include the trailing null character.</para>
11+
/// <para>The MaximumLength is used to indicate the length of Buffer so that if the string is passed to a conversion routine such as RtlAnsiStringToUnicodeString the returned string does not exceed the buffer size.</para>
12+
/// </remarks>
13+
[StructLayout(LayoutKind.Sequential, Size = 0x08)]
14+
internal struct UNICODE_STRING32
15+
{
16+
public ushort Length;
17+
public ushort MaximumLength;
18+
public UIntPtr32<char> Buffer;
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Runtime.InteropServices;
2+
3+
namespace Windows.Win32.Foundation;
4+
5+
[StructLayout(LayoutKind.Sequential, Size = 0x10)]
6+
internal struct UNICODE_STRING64
7+
{
8+
public ushort Length;
9+
public ushort MaximumLength;
10+
public UIntPtr64<char> Buffer;
11+
}

0 commit comments

Comments
 (0)