Skip to content

Commit ba40434

Browse files
author
dahall
committed
Completed autogen handle work
1 parent f189b79 commit ba40434

File tree

13 files changed

+154
-20
lines changed

13 files changed

+154
-20
lines changed

CodeGen/HandleModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public string GetSafeHandleCode(string summaryText = "")
3030
templateText = ReplaceMarker(templateText, "#2#", HandleName);
3131
templateText = ReplaceMarker(templateText, "#3#", InheritedHandleName);
3232
templateText = ReplaceMarker(templateText, "#4#", CloseCode);
33+
templateText = ReplaceMarker(templateText, "#5#", string.IsNullOrEmpty(HandleName) ? "IntPtr" : "");
3334
var closeCode = string.IsNullOrEmpty(CloseCode) ? "" : (CloseCode!.Trim().StartsWith("{") ? CloseCode : $"=> {CloseCode};");
3435
var baseClassName = BaseClassName + (InterfaceName is "IHandle" or "Vanara.PInvoke.IHandle" or "" ? "" : $", {InterfaceName}");
3536
return Util.ReplaceWholeWords(templateText, new Dictionary<string, string>()

CodeGen/SafeHandleTemplate.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#1#public static partial class ParentClassName
44
{
55
#1# SummaryText
6-
/// <seealso cref="BaseClassName"/>
76
public partial class ClassName : BaseClassName
87
{
98
/// <summary>Initializes a new instance of the <see cref="ClassName"/> class and assigns an existing handle.</summary>
@@ -16,7 +15,12 @@ public ClassName(IntPtr preexistingHandle = default, bool ownsHandle = true) : b
1615
public static new ClassName Null => new(IntPtr.Zero, false);
1716
#pragma warning restore CS0109 // Member does not hide an inherited member
1817

19-
#2# /// <summary>Initializes a new instance of the <see cref="ClassName"/> class and assigns an existing handle.</summary>
18+
#5# /// <summary>Performs an implicit conversion from <see cref="ClassName"/> to <see cref="IntPtr"/>.</summary>
19+
/// <param name="h">The safe handle instance.</param>
20+
/// <returns>The result of the conversion.</returns>
21+
public static implicit operator IntPtr(ClassName h) => h.handle;
22+
23+
#5##2# /// <summary>Initializes a new instance of the <see cref="ClassName"/> class and assigns an existing handle.</summary>
2024
/// <param name="preexistingHandle">An <see cref="HandleName"/> object that represents the pre-existing handle to use.</param>
2125
/// <param name="ownsHandle"><see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).</param>
2226
public ClassName(HandleName preexistingHandle = default, bool ownsHandle = true) : base((IntPtr)preexistingHandle, ownsHandle) { }

Net/DnsService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public async Task RegisterAsync(bool unicastEnabled = false, NetworkInterface? a
175175
{
176176
Version = DNS_QUERY_REQUEST_VERSION1,
177177
InterfaceIndex = (uint)(adapter?.GetIPProperties().GetIPv4Properties().Index ?? 0),
178-
pServiceInstance = pSvcInst,
178+
pServiceInstance = (IntPtr)pSvcInst,
179179
pQueryContext = ctx,
180180
pRegisterCompletionCallback = RegCallback,
181181
unicastEnabled = unicastEnabled

PInvoke/ActiveDS/IADs.Interface4.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2785,8 +2785,21 @@ public partial struct ADS_SEARCH_HANDLE { }
27852785
/// <summary>
27862786
/// Provides a <see cref="SafeHandle"/> for <see cref="ADS_SEARCH_HANDLE"/> that is disposed using <see cref="IDirectorySearch.CloseSearchHandle"/>.
27872787
/// </summary>
2788-
[AutoSafeHandle("{ try { ids?.CloseSearchHandle(handle); return true; } catch { return false; } }", typeof(ADS_SEARCH_HANDLE))]
2789-
public partial class SafeADS_SEARCH_HANDLE { }
2788+
public class SafeADS_SEARCH_HANDLE : SafeHANDLE
2789+
{
2790+
private readonly IDirectorySearch? ids;
2791+
2792+
/// <summary>Initializes a new instance of the <see cref="SafeADS_SEARCH_HANDLE"/> class.</summary>
2793+
internal SafeADS_SEARCH_HANDLE(IDirectorySearch? ids = null, ADS_SEARCH_HANDLE h = default) : base((IntPtr)h, true) => this.ids = ids;
2794+
2795+
/// <summary>Performs an implicit conversion from <see cref="SafeADS_SEARCH_HANDLE"/> to <see cref="ADS_SEARCH_HANDLE"/>.</summary>
2796+
/// <param name="h">The safe handle instance.</param>
2797+
/// <returns>The result of the conversion.</returns>
2798+
public static implicit operator ADS_SEARCH_HANDLE(SafeADS_SEARCH_HANDLE h) => h.handle;
2799+
2800+
/// <inheritdoc/>
2801+
protected override bool InternalReleaseHandle() { try { ids?.CloseSearchHandle(handle); return true; } catch { return false; } }
2802+
}
27902803

27912804
/*internal class VariantMarshaler<T> : ICustomMarshaler
27922805
{

PInvoke/DnsApi/WinDns.Funcs.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,8 +1712,8 @@ protected override bool InternalReleaseHandle()
17121712
public partial class SafeDnsRecordList : IEnumerable<DNS_RECORD>
17131713
{
17141714
/// <summary>Returns an enumerator that iterates through the collection.</summary>
1715-
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.</returns>
1716-
/// <exception cref="NotImplementedException"></exception>
1715+
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.</returns>
1716+
/// <exception cref="NotImplementedException"></exception>
17171717
public IEnumerator<DNS_RECORD> GetEnumerator() => handle.LinkedListToIEnum<DNS_RECORD>(r => r.pNext).GetEnumerator();
17181718

17191719
/// <summary>Gets a sequence of pointers to each of the records.</summary>

PInvoke/Lz32/LzExpand.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,50 @@ public enum LZERROR : int
763763
public static extern int LZSeek(HLZFILE hFile, int lOffset, SeekOrigin iOrigin);
764764

765765
/// <summary>Provides a handle to a compressed file.</summary>
766-
[AutoHandle]
767-
public partial struct HLZFILE { }
766+
[StructLayout(LayoutKind.Sequential)]
767+
public readonly struct HLZFILE : IHandle
768+
{
769+
private readonly int handle;
770+
771+
/// <summary>Initializes a new instance of the <see cref="HLZFILE"/> struct.</summary>
772+
/// <param name="preexistingHandle">An <see cref="int"/> object that represents the pre-existing handle to use.</param>
773+
public HLZFILE(int preexistingHandle) => handle = preexistingHandle;
774+
775+
/// <summary>Returns an invalid handle by instantiating a <see cref="HLZFILE"/> object with <c>0</c>.</summary>
776+
public static HLZFILE NULL => new(0);
777+
778+
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
779+
public bool IsNull => handle == 0;
780+
781+
/// <summary>Performs an explicit conversion from <see cref="HLZFILE"/> to <see cref="int"/>.</summary>
782+
/// <param name="h">The handle.</param>
783+
/// <returns>The result of the conversion.</returns>
784+
public static explicit operator int(HLZFILE h) => h.handle;
785+
786+
/// <summary>Performs an implicit conversion from <see cref="int"/> to <see cref="HLZFILE"/>.</summary>
787+
/// <param name="h">The pointer to a handle.</param>
788+
/// <returns>The result of the conversion.</returns>
789+
public static implicit operator HLZFILE(int h) => new(h);
790+
791+
/// <summary>Implements the operator !=.</summary>
792+
/// <param name="h1">The first handle.</param>
793+
/// <param name="h2">The second handle.</param>
794+
/// <returns>The result of the operator.</returns>
795+
public static bool operator !=(HLZFILE h1, HLZFILE h2) => !(h1 == h2);
796+
797+
/// <summary>Implements the operator ==.</summary>
798+
/// <param name="h1">The first handle.</param>
799+
/// <param name="h2">The second handle.</param>
800+
/// <returns>The result of the operator.</returns>
801+
public static bool operator ==(HLZFILE h1, HLZFILE h2) => h1.Equals(h2);
802+
803+
/// <inheritdoc/>
804+
public override bool Equals(object? obj) => obj is HLZFILE h && handle == h.handle;
805+
806+
/// <inheritdoc/>
807+
public override int GetHashCode() => handle.GetHashCode();
808+
809+
/// <inheritdoc/>
810+
public IntPtr DangerousGetHandle() => (IntPtr)handle;
811+
}
768812
}

PInvoke/Msi/Msi.cs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,14 +789,50 @@ public struct MSIFILEHASHINFO
789789
}
790790

791791
/// <summary>Provides a handle to a MSI instance.</summary>
792+
/// <remarks>Initializes a new instance of the <see cref="MSIHANDLE"/> struct.</remarks>
793+
/// <param name="preexistingHandle">An <see cref="ulong"/> object that represents the pre-existing handle to use.</param>
792794
[PInvokeData("msi.h")]
793-
[AutoHandle]
794-
public partial struct MSIHANDLE
795+
[StructLayout(LayoutKind.Sequential)]
796+
public readonly struct MSIHANDLE(ulong preexistingHandle) : IHandle
795797
{
798+
private readonly ulong handle = preexistingHandle;
799+
800+
/// <summary>Returns an invalid handle by instantiating a <see cref="MSIHANDLE"/> object with zero.</summary>
801+
public static MSIHANDLE NULL => new(0UL);
802+
803+
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
804+
public bool IsNull => handle == 0UL;
805+
796806
/// <summary>Performs an explicit conversion from <see cref="MSIHANDLE"/> to <see cref="ulong"/>.</summary>
797807
/// <param name="h">The handle.</param>
798808
/// <returns>The result of the conversion.</returns>
799809
public static explicit operator ulong(MSIHANDLE h) => h.handle;
810+
811+
/// <summary>Performs an implicit conversion from <see cref="ulong"/> to <see cref="MSIHANDLE"/>.</summary>
812+
/// <param name="h">The pointer to a handle.</param>
813+
/// <returns>The result of the conversion.</returns>
814+
public static implicit operator MSIHANDLE(ulong h) => new(h);
815+
816+
/// <summary>Implements the operator !=.</summary>
817+
/// <param name="h1">The first handle.</param>
818+
/// <param name="h2">The second handle.</param>
819+
/// <returns>The result of the operator.</returns>
820+
public static bool operator !=(MSIHANDLE h1, MSIHANDLE h2) => !(h1 == h2);
821+
822+
/// <summary>Implements the operator ==.</summary>
823+
/// <param name="h1">The first handle.</param>
824+
/// <param name="h2">The second handle.</param>
825+
/// <returns>The result of the operator.</returns>
826+
public static bool operator ==(MSIHANDLE h1, MSIHANDLE h2) => h1.Equals(h2);
827+
828+
/// <inheritdoc/>
829+
public override bool Equals(object? obj) => obj is MSIHANDLE h && handle == h.handle;
830+
831+
/// <inheritdoc/>
832+
public override int GetHashCode() => handle.GetHashCode();
833+
834+
/// <inheritdoc/>
835+
public IntPtr DangerousGetHandle() => new(unchecked((long)handle));
800836
}
801837

802838
/// <summary>

PInvoke/NTDSApi/NTDSAPI.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5174,7 +5174,11 @@ public partial struct SpnArrayHandle
51745174

51755175
/// <summary>Provides a <see cref="SafeHandle"/> to an authentication identity that releases its handle at disposal using DsFreePasswordCredentials.</summary>
51765176
[AutoSafeHandle("{ DsFreePasswordCredentials(handle); return true; }")]
5177-
public partial class SafeAuthIdentityHandle { }
5177+
public partial class SafeAuthIdentityHandle
5178+
{
5179+
/// <summary>Gets a value that marshals as NULL so that the local thread's identity is used.</summary>
5180+
public static readonly SafeAuthIdentityHandle LocalThreadIdentity = new();
5181+
}
51785182

51795183
/// <summary>Provides a safe handle to an array of DS_REPSYNCALL_ERRINFO structures returned from <see cref="DsReplicaSyncAll"/>.</summary>
51805184
/// <seealso cref="Vanara.InteropServices.GenericSafeHandle"/>

PInvoke/Odbc32/Sql.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6042,24 +6042,24 @@ public readonly struct SQLHSTMT(IntPtr preexistingHandle) : ISQLHANDLE
60426042
/// <summary>
60436043
/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHDBC"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
60446044
/// </summary>
6045-
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_DBC, handle).SQL_SUCCEEDED()")]
6045+
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_DBC, handle).SQL_SUCCEEDED()", typeof(SQLHDBC))]
60466046
public partial class SafeSQLHDBC : ISQLHANDLE { }
60476047

60486048
/// <summary>
60496049
/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHDESC"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
60506050
/// </summary>
6051-
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_DESC, handle).SQL_SUCCEEDED()")]
6051+
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_DESC, handle).SQL_SUCCEEDED()", typeof(SQLHDESC))]
60526052
public partial class SafeSQLHDESC : ISQLHANDLE { }
60536053

60546054
/// <summary>
60556055
/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHENV"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
60566056
/// </summary>
6057-
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_ENV, handle).SQL_SUCCEEDED()")]
6057+
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_ENV, handle).SQL_SUCCEEDED()", typeof(SQLHENV))]
60586058
public partial class SafeSQLHENV : ISQLHANDLE { }
60596059

60606060
/// <summary>
60616061
/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHSTMT"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
60626062
/// </summary>
6063-
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_STMT, handle).SQL_SUCCEEDED()")]
6063+
[AutoSafeHandle("SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_STMT, handle).SQL_SUCCEEDED()", typeof(SQLHSTMT))]
60646064
public partial class SafeSQLHSTMT : ISQLHANDLE { }
60656065
}

PInvoke/WinSCard/WinSCard.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4958,4 +4958,12 @@ public struct SCARD_READERSTATE
49584958
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
49594959
public byte[] rgbAtr;
49604960
}
4961+
4962+
public partial struct SCARDHANDLE
4963+
{
4964+
/// <summary>Performs an explicit conversion from <see cref="SCARDHANDLE"/> to <see cref="IntPtr"/>.</summary>
4965+
/// <param name="h">The handle.</param>
4966+
/// <returns>The result of the conversion.</returns>
4967+
public static implicit operator UIntPtr(SCARDHANDLE h) => h.handle.ToUIntPtr();
4968+
}
49614969
}

0 commit comments

Comments
 (0)