mirror of
https://github.com/AssetRipper/Capstone.NET.git
synced 2026-11-13 20:05:44 -10:00
58 lines
2.9 KiB
C#
58 lines
2.9 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Gee.External.Capstone {
|
|
/// <summary>
|
|
/// Safe Handle Extension.
|
|
/// </summary>
|
|
internal static class SafeHandleExtension {
|
|
/// <summary>
|
|
/// Add a Reference to and Get a Handle.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// Convenient method to add a reference to a handle before retrieving its wrapped pointer. If a
|
|
/// reference cannot be added to the handle, an exception is thrown. This follows Microsoft's
|
|
/// recommended best practice to add a reference to the handle before retrieving its wrapped pointer
|
|
/// to minimize the risk of handle recycle attacks. You, however, are responsible for releasing the
|
|
/// reference to the handle after you are done with it, using <c>SafeHandle.DangerousRelease()</c>,
|
|
/// otherwise you risk a memory leak.
|
|
/// </para>
|
|
/// <para>
|
|
/// This method is the equivalent to calling both <c>SafeHandle.DangerousAddRef()</c> and
|
|
/// <c>SafeHandle.DangerousGetHandle()</c>, except an exception is thrown if the operation fails. This
|
|
/// is for convenience if, and only if, you want to treat the failure of this operation as
|
|
/// exceptional! If you do not want to treat the failure of this operation as exceptional and you
|
|
/// instead have a non-exceptional back-off routine, do not call this method and perform your back-off
|
|
/// routine in an exception handler! You're better off simply calling both
|
|
/// <c>SafeHandle.DangerousAddRef()</c> and <c>SafeHandle.DangerousGetHandle()</c> yourself.
|
|
/// </para>
|
|
/// </remarks>
|
|
/// <param name="this">
|
|
/// A handle.
|
|
/// </param>
|
|
/// <returns>
|
|
/// The handle's wrapped pointer.
|
|
/// </returns>
|
|
/// <exception cref="System.ArgumentException">
|
|
/// Thrown if the handle is closed, or if the handle is invalid.
|
|
/// </exception>
|
|
/// <exception cref="System.ArgumentNullException">
|
|
/// Thrown if the handle is a null reference.
|
|
/// </exception>
|
|
/// <exception cref="System.InvalidOperationException">
|
|
/// Thrown if a reference to the handle could not be added.
|
|
/// </exception>
|
|
internal static IntPtr DangerousAddRefAndGetHandle(this SafeHandle @this) {
|
|
var isReferenceAdded = false;
|
|
@this.DangerousAddRef(ref isReferenceAdded);
|
|
if (!isReferenceAdded) {
|
|
const string detailMessage = "Unable to add a reference to a handle.";
|
|
throw new InvalidOperationException(detailMessage);
|
|
}
|
|
|
|
var pHandle = @this.DangerousGetHandle();
|
|
return pHandle;
|
|
}
|
|
}
|
|
} |