Skip to content

Commit

Permalink
Finished work on #403
Browse files Browse the repository at this point in the history
  • Loading branch information
dahall committed Jun 9, 2023
1 parent 91490dc commit 71b857b
Show file tree
Hide file tree
Showing 5 changed files with 6,401 additions and 6,207 deletions.
16 changes: 11 additions & 5 deletions PInvoke/Kernel32/IoApiSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -612,15 +612,18 @@ public static uint CTL_CODE(ushort deviceType, ushort function, byte method, byt
/// <param name="outVal">
/// The data returned by the operation. The format of this data depends on the value of the dwIoControlCode parameter.
/// </param>
/// <param name="outSz">
/// The amount of memory to allocate for <paramref name="outVal"/> retrieval. If this value is <c>0</c>, then initialize the default structure.
/// </param>
/// <returns><c>true</c> if successful.</returns>
[PInvokeData("Winbase.h", MSDNShortId = "aa363216")]
public static bool DeviceIoControl<TIn, TOut>(HFILE hDev, uint ioControlCode, TIn inVal, out TOut outVal) where TIn : struct where TOut : struct
public static bool DeviceIoControl<TIn, TOut>(HFILE hDev, uint ioControlCode, TIn inVal, out TOut outVal, SizeT outSz = default) where TIn : struct where TOut : struct
{
using SafeHGlobalHandle ptrIn = SafeHGlobalHandle.CreateFromStructure(inVal), ptrOut = SafeHGlobalHandle.CreateFromStructure<TOut>();
using SafeHGlobalHandle ptrIn = SafeHGlobalHandle.CreateFromStructure(inVal), ptrOut = outSz == 0 ? SafeHGlobalHandle.CreateFromStructure<TOut>() : new(outSz);
var ret = DeviceIoControl(hDev, ioControlCode, ptrIn, ptrIn.Size, ptrOut, ptrOut.Size, out var bRet, IntPtr.Zero);
if (!ret && Win32Error.GetLastError() == Win32Error.ERROR_INSUFFICIENT_BUFFER)
{
ptrOut.Size = bRet;
ptrOut.Size = bRet == 0 ? ptrOut.Size * 16 : bRet;
ret = DeviceIoControl(hDev, ioControlCode, ptrIn, ptrIn.Size, ptrOut, ptrOut.Size, out bRet, IntPtr.Zero);
}
outVal = ret ? ptrOut.ToStructure<TOut>() : default;
Expand All @@ -642,11 +645,14 @@ public static uint CTL_CODE(ushort deviceType, ushort function, byte method, byt
/// <param name="outVal">
/// The data returned by the operation. The format of this data depends on the value of the dwIoControlCode parameter.
/// </param>
/// <param name="outSz">
/// The amount of memory to allocate for <paramref name="outVal"/> retrieval. If this value is <c>0</c>, then initialize the default structure.
/// </param>
/// <returns><c>true</c> if successful.</returns>
[PInvokeData("Winbase.h", MSDNShortId = "aa363216")]
public static bool DeviceIoControl<TOut>(HFILE hDev, uint ioControlCode, out TOut outVal) where TOut : struct
public static bool DeviceIoControl<TOut>(HFILE hDev, uint ioControlCode, out TOut outVal, SizeT outSz = default) where TOut : struct
{
using var ptrOut = SafeHGlobalHandle.CreateFromStructure<TOut>();
using var ptrOut = outSz == 0 ? SafeHGlobalHandle.CreateFromStructure<TOut>() : new(outSz);
var ret = DeviceIoControl(hDev, ioControlCode, IntPtr.Zero, 0, ptrOut, ptrOut.Size, out var bRet, IntPtr.Zero);
var err = Win32Error.GetLastError();
if (!ret && err == Win32Error.ERROR_INSUFFICIENT_BUFFER)
Expand Down
4 changes: 2 additions & 2 deletions PInvoke/Kernel32/WinIOCtl.Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2120,7 +2120,7 @@ public enum STORAGE_PORT_CODE_SET
public enum STORAGE_PROPERTY_ID
{
/// <summary>Indicates that the caller is querying for the device descriptor, STORAGE_DEVICE_DESCRIPTOR.</summary>
[CorrespondingType(typeof(STORAGE_DEVICE_DESCRIPTOR))]
[CorrespondingType(typeof(STORAGE_DEVICE_DESCRIPTOR_MGD))]
StorageDeviceProperty = 0,

/// <summary>Indicates that the caller is querying for the adapter descriptor, STORAGE_ADAPTER_DESCRIPTOR.</summary>
Expand All @@ -2139,7 +2139,7 @@ public enum STORAGE_PROPERTY_ID
/// the STORAGE_DEVICE_UNIQUE_IDENTIFIER structure (see the storduid.h header in the DDK). Windows Server 2003 and Windows XP:
/// This value is not supported before Windows Vista and Windows Server 2008.
/// </summary>
[CorrespondingType(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER))]
[CorrespondingType(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER_MGD))]
StorageDeviceUniqueIdProperty,

/// <summary>
Expand Down
97 changes: 82 additions & 15 deletions PInvoke/Kernel32/WinIOCtl.STORAGE_DEVICE_MANAGEMENT_STATUS.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System.Runtime.InteropServices;
using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;

namespace Vanara.PInvoke;

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public static partial class Kernel32
{
private const int STORAGE_ADAPTER_SERIAL_NUMBER_V1_MAX_LENGTH = 128;
Expand Down Expand Up @@ -84,6 +85,40 @@ public struct STORAGE_ADAPTER_SERIAL_NUMBER
public string SerialNumber;
}

/// <summary>The STORAGE_DEVICE_LAYOUT_SIGNATURE structure defines a device layout structure.</summary>
[PInvokeData("storduid.h", MSDNShortId = "NS:storduid._STORAGE_DEVICE_LAYOUT_SIGNATURE")]
[StructLayout(LayoutKind.Sequential)]
public struct STORAGE_DEVICE_LAYOUT_SIGNATURE
{
/// <summary>The version of the DUID.</summary>
public uint Version;

/// <summary>The size, in bytes, of this STORAGE_DEVICE_LAYOUT_SIGNATURE structure.</summary>
public uint Size;

/// <summary>
/// A Boolean value that indicates whether the partition table of the disk is formatted with a master boot record (MBR). If TRUE, the
/// partition table of the disk is formatted with a master boot record (MBR). If FALSE, the disk has a GUID partition table (GPT).
/// </summary>
public bool Mbr;

/// <summary>The device specific info.</summary>
public DEVICESPECIFIC DeviceSpecific;

/// <summary>The device specific info.</summary>
[StructLayout(LayoutKind.Explicit)]
public struct DEVICESPECIFIC
{
/// <summary>The signature value, which uniquely identifies the disk.</summary>
[FieldOffset(0)]
public uint MbrSignature;

/// <summary>The GUID that uniquely identifies the disk.</summary>
[FieldOffset(0)]
public Guid GptDiskId;
}
}

/// <summary>Structure for STORAGE_PROPERTY_ID.StorageDeviceManagementStatus</summary>
[PInvokeData("winioctl.h")]
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<STORAGE_DEVICE_MANAGEMENT_STATUS>), nameof(NumberOfAdditionalReasons))]
Expand Down Expand Up @@ -125,29 +160,27 @@ public struct STORAGE_DEVICE_MANAGEMENT_STATUS
// _STORAGE_DEVICE_UNIQUE_IDENTIFIER { ULONG Version; ULONG Size; ULONG StorageDeviceIdOffset; ULONG StorageDeviceOffset; ULONG
// DriveLayoutSignatureOffset; } STORAGE_DEVICE_UNIQUE_IDENTIFIER, *PSTORAGE_DEVICE_UNIQUE_IDENTIFIER;
[PInvokeData("storduid.h", MSDNShortId = "NS:storduid._STORAGE_DEVICE_UNIQUE_IDENTIFIER")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STORAGE_DEVICE_UNIQUE_IDENTIFIER
[VanaraMarshaler(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER_Marshaler))]
[StructLayout(LayoutKind.Sequential)]
public struct STORAGE_DEVICE_UNIQUE_IDENTIFIER_MGD
{
/// <summary>The version of the DUID.</summary>
public uint Version;

/// <summary>The size, in bytes, of the identifier header and the identifiers (IDs) that follow the header.</summary>
public uint Size;

/// <summary>
/// The offset, in bytes, from the beginning of the header to the device ID descriptor (STORAGE_DEVICE_ID_DESCRIPTOR). The device ID
/// descriptor contains the IDs that are extracted from page 0x83 of the device's vital product data (VPD).
/// The offset, in bytes, from the beginning of the header to the device ID descriptor ( <see cref="STORAGE_DEVICE_ID_DESCRIPTOR"/>).
/// The device ID descriptor contains the IDs that are extracted from page 0x83 of the device's vital product data (VPD).
/// </summary>
public uint StorageDeviceIdOffset;
public STORAGE_DEVICE_ID_DESCRIPTOR StorageDeviceId;

/// <summary>
/// The offset, in bytes, from the beginning of the header to the device descriptor (STORAGE_DEVICE_DESCRIPTOR). The device
/// descriptor contains IDs that are extracted from non-VPD inquiry data.
/// The offset, in bytes, from the beginning of the header to the device descriptor ( <see cref="STORAGE_DEVICE_DESCRIPTOR"/>). The
/// device descriptor contains IDs that are extracted from non-VPD inquiry data.
/// </summary>
public uint StorageDeviceOffset;
public STORAGE_DEVICE_DESCRIPTOR_MGD StorageDevice;

/// <summary>The offset, in bytes, to the drive layout signature (STORAGE_DEVICE_LAYOUT_SIGNATURE).</summary>
public uint DriveLayoutSignatureOffset;
/// <summary>The offset, in bytes, to the drive layout signature ( <see cref="STORAGE_DEVICE_LAYOUT_SIGNATURE"/>).</summary>
public STORAGE_DEVICE_LAYOUT_SIGNATURE DriveLayoutSignature;
}

/// <summary>Additional reasons.</summary>
Expand Down Expand Up @@ -201,4 +234,38 @@ public struct RawBytesUnion
public uint AsUlong;
}
}

[StructLayout(LayoutKind.Sequential)]
private struct STORAGE_DEVICE_UNIQUE_IDENTIFIER
{
public uint Version;

public uint Size;

public uint StorageDeviceIdOffset;

public uint StorageDeviceOffset;

public uint DriveLayoutSignatureOffset;
}

private class STORAGE_DEVICE_UNIQUE_IDENTIFIER_Marshaler : IVanaraMarshaler
{
SizeT IVanaraMarshaler.GetNativeSize() => Marshal.SizeOf(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER));

SafeAllocatedMemoryHandle IVanaraMarshaler.MarshalManagedToNative(object managedObject) => new SafeCoTaskMemHandle(1024);

object IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocatedBytes)
{
if (pNativeData == IntPtr.Zero) return null;
STORAGE_DEVICE_UNIQUE_IDENTIFIER sdd = (STORAGE_DEVICE_UNIQUE_IDENTIFIER)Marshal.PtrToStructure(pNativeData, typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER))!;
return new STORAGE_DEVICE_UNIQUE_IDENTIFIER_MGD
{
Version = sdd.Version,
StorageDeviceId = sdd.StorageDeviceIdOffset == 0 ? default : pNativeData.ToStructure<STORAGE_DEVICE_ID_DESCRIPTOR>(allocatedBytes, (int)sdd.StorageDeviceIdOffset),
StorageDevice = sdd.StorageDeviceOffset == 0 ? default : pNativeData.ToStructure<STORAGE_DEVICE_DESCRIPTOR_MGD>(allocatedBytes, (int)sdd.StorageDeviceOffset),
DriveLayoutSignature = sdd.DriveLayoutSignatureOffset == 0 ? default : pNativeData.ToStructure<STORAGE_DEVICE_LAYOUT_SIGNATURE>(allocatedBytes, (int)sdd.DriveLayoutSignatureOffset),
};
}
}
}

0 comments on commit 71b857b

Please sign in to comment.