diff --git a/PInvoke/SetupAPI/SetupAPI.cs b/PInvoke/SetupAPI/SetupAPI.cs
index 2b8dd3b5..91036407 100644
--- a/PInvoke/SetupAPI/SetupAPI.cs
+++ b/PInvoke/SetupAPI/SetupAPI.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
@@ -3490,6 +3491,107 @@ namespace Vanara.PInvoke
public string HardwareID;
}
+ /// An SP_DRVINFO_DETAIL_DATA structure contains detailed information about a particular driver information structure.
+ ///
+ /// The hardware ID and compatible IDs for a device are specified in the INF Models section in the following order:
+ ///
+ /// -
+ /// The first ID (if specified) is the hardware ID for the device.
+ ///
+ /// -
+ /// The remaining IDs (if specified) are compatible IDs for the device.
+ ///
+ ///
+ ///
+ /// When you parse the HardwareID buffer, you must ensure that you correctly determine the end of the data in the buffer. Be
+ /// aware that the buffer is not necessarily double NULL terminated.
+ ///
+ ///
+ /// For example, depending on how the list of hardware ID and compatible IDs are specified in the INF Models section, the
+ /// HardwareID buffer can resemble any of the following:
+ ///
+ ///
+ /// -
+ /// \0
+ ///
+ /// -
+ /// <HWID>\0
+ ///
+ /// -
+ /// <HWID>\0<COMPATID_1>\0...<COMPATID_N>\0\0
+ ///
+ /// -
+ /// \0<COMPATID_1>\0...<COMPATID_N>\0\0
+ ///
+ ///
+ ///
+ /// An algorithm to correctly parse this buffer must use the CompatIDsOffset and CompatIDsLength fields to extract the
+ /// hardware ID and compatible IDs, as shown in the following code example:
+ ///
+ ///
+ /// // parse the hardware ID, if it exists if (CompatIDsOffset > 1) { // Parse for hardware ID from index 0. // This is a single NULL-terminated string } // Parse the compatible IDs, if they exist if (CompatIDsLength > 0) { // Parse for list of compatible IDs from CompatIDsOffset. // This is a double NULL-terminated list of strings (i.e. MULTI-SZ) }
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/setupapi/ns-setupapi-sp_drvinfo_detail_data_a typedef struct
+ // _SP_DRVINFO_DETAIL_DATA_A { DWORD cbSize; FILETIME InfDate; DWORD CompatIDsOffset; DWORD CompatIDsLength; ULONG_PTR Reserved;
+ // CHAR SectionName[LINE_LEN]; CHAR InfFileName[MAX_PATH]; CHAR DrvDescription[LINE_LEN]; CHAR HardwareID[ANYSIZE_ARRAY]; }
+ // SP_DRVINFO_DETAIL_DATA_A, *PSP_DRVINFO_DETAIL_DATA_A;
+ [PInvokeData("setupapi.h", MSDNShortId = "NS:setupapi._SP_DRVINFO_DETAIL_DATA_A")]
+ public class SP_DRVINFO_DETAIL_DATA_MGD
+ {
+ private SP_DRVINFO_DETAIL_DATA_MGD() { }
+
+ private SP_DRVINFO_DETAIL_DATA_MGD(DateTime infDate, string sectionName, string infFileName, string drvDescription)
+ {
+ InfDate = infDate;
+ SectionName = sectionName;
+ InfFileName = infFileName;
+ DrvDescription = drvDescription;
+ }
+
+ /// Date of the INF file for this driver.
+ public DateTime InfDate { get; }
+
+ ///
+ /// A string that contains the name of the INF DDInstall section for this driver. This must be the basic
+ /// DDInstall section name, such as InstallSec, without any OS/architecture-specific extensions.
+ ///
+ public string SectionName { get; }
+
+ /// A string that contains the full-qualified name of the INF file for this driver.
+ public string InfFileName { get; }
+
+ /// A string that describes the driver.
+ public string DrvDescription { get; }
+
+ /// The hardware ID that corresponds to the ID in the INF Models section. This value may be an empty string.
+ public string HardwareID { get; private set; }
+
+ /// Contains a list of compatible IDs. These IDs correspond to the compatible IDs in the INF Models section.
+ public string[] CompatIDs { get; private set; }
+
+ /// Creates an instance of from allocated memory.
+ /// A pointer to the memory containing .
+ /// The number of allocated bytes behind .
+ /// An instance of with the extracted data.
+ public static SP_DRVINFO_DETAIL_DATA_MGD Create(IntPtr self, SizeT allocatedBytes) => Create(new(self, false, allocatedBytes));
+
+ /// Creates an instance of from allocated memory.
+ /// The memory containing .
+ /// An instance of with the extracted data.
+ public static SP_DRVINFO_DETAIL_DATA_MGD Create(SafeCoTaskMemStruct dataMem)
+ {
+ SP_DRVINFO_DETAIL_DATA d = dataMem.Value;
+ SP_DRVINFO_DETAIL_DATA_MGD ret = new(d.InfDate.ToDateTime(), d.SectionName, d.InfFileName, d.DrvDescription);
+ IntPtr idPtr = dataMem.GetFieldAddress(nameof(HardwareID));
+ long idoffset = idPtr.ToInt64() - dataMem.DangerousGetHandle().ToInt64();
+ string[] ids = idPtr.ToStringEnum(allocatedBytes: dataMem.Size - idoffset).ToArray();
+ ret.HardwareID = d.CompatIDsOffset <= 1 || ids.Length == 0 ? string.Empty : ids[0];
+ ret.CompatIDs = d.CompatIDsOffset == 0 || ids.Length == 0 ? new string[0] : ids.Skip(d.CompatIDsOffset == 0 ? 0 : 1).ToArray();
+ return ret;
+ }
+ }
+
///
/// An SP_DRVINSTALL_PARAMS structure contains driver installation parameters associated with a particular driver information element.
///