diff --git a/src/CfgMgr32/CfgMgr32+CM_NOTIFY_EVENT_DATA.cs b/src/CfgMgr32/CfgMgr32+CM_NOTIFY_EVENT_DATA.cs
index 9f7bc97c..e40c4b2c 100644
--- a/src/CfgMgr32/CfgMgr32+CM_NOTIFY_EVENT_DATA.cs
+++ b/src/CfgMgr32/CfgMgr32+CM_NOTIFY_EVENT_DATA.cs
@@ -44,8 +44,8 @@ public unsafe ref struct CM_NOTIFY_EVENT_DATA
///
/// A pointer to a null-terminated symbolic link path of the device interface to which the notification event data pertains.
- /// Convert this to a string using new string(eventData->SymbolicLink).
///
+ /// Convert this to a string by passing its value to .
[FieldOffset(24)]
public fixed char SymbolicLink[1];
@@ -79,8 +79,8 @@ public unsafe ref struct CM_NOTIFY_EVENT_DATA
///
/// A pointer to a null-terminated device instance ID of the device to which the notification event data pertains.
- /// Convert this to a string using new string(eventData->InstanceId).
///
+ /// Convert this to a string by passing its value to .
[FieldOffset(8)]
public fixed char InstanceId[1];
}
diff --git a/src/SetupApi.Tests/SP_DRVINFO_DETAIL_DATAFacts.cs b/src/SetupApi.Tests/SP_DRVINFO_DETAIL_DATAFacts.cs
new file mode 100644
index 00000000..06e957ac
--- /dev/null
+++ b/src/SetupApi.Tests/SP_DRVINFO_DETAIL_DATAFacts.cs
@@ -0,0 +1,45 @@
+// Copyright © .NET Foundation and Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Runtime.InteropServices;
+using Xunit;
+using static PInvoke.SetupApi;
+
+public class SP_DRVINFO_DETAIL_DATAFacts
+{
+ [Fact]
+ public void Layout_Test()
+ {
+ // These values listed below have been obtained by determining the size of the struct and the offset of its
+ // fields using a C program which calls sizeof() and offsetof().
+ if (Environment.Is64BitProcess)
+ {
+ Assert.Equal(0, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.cbSize)).ToInt32());
+ Assert.Equal(4, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.InfDate)).ToInt32());
+ Assert.Equal(0xc, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsOffset)).ToInt32());
+ Assert.Equal(0x10, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsLength)).ToInt32());
+ Assert.Equal(0x18, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.Reserved)).ToInt32());
+ Assert.Equal(0x20, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.SectionName)).ToInt32());
+ Assert.Equal(0x220, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.InfFileName)).ToInt32());
+ Assert.Equal(0x428, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.DrvDescription)).ToInt32());
+ Assert.Equal(0x628, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.HardwareID)).ToInt32());
+
+ Assert.Equal(0x630, SP_DRVINFO_DETAIL_DATA.Create().cbSize);
+ }
+ else
+ {
+ Assert.Equal(0, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.cbSize)).ToInt32());
+ Assert.Equal(4, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.InfDate)).ToInt32());
+ Assert.Equal(0xc, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsOffset)).ToInt32());
+ Assert.Equal(0x10, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsLength)).ToInt32());
+ Assert.Equal(0x14, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.Reserved)).ToInt32());
+ Assert.Equal(0x18, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.SectionName)).ToInt32());
+ Assert.Equal(0x218, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.InfFileName)).ToInt32());
+ Assert.Equal(0x420, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.DrvDescription)).ToInt32());
+ Assert.Equal(0x620, Marshal.OffsetOf(nameof(SP_DRVINFO_DETAIL_DATA.HardwareID)).ToInt32());
+
+ Assert.Equal(0x622, SP_DRVINFO_DETAIL_DATA.Create().cbSize);
+ }
+ }
+}
diff --git a/src/SetupApi.Tests/SetupApiFacts.cs b/src/SetupApi.Tests/SetupApiFacts.cs
index 18fbd33a..fee4c54f 100644
--- a/src/SetupApi.Tests/SetupApiFacts.cs
+++ b/src/SetupApi.Tests/SetupApiFacts.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
-using System.Runtime.InteropServices;
using PInvoke;
using Xunit;
using static PInvoke.SetupApi;
@@ -14,149 +13,188 @@ public unsafe class SetupApiFacts
[Fact]
public void SetupDiCreateDeviceInfoListWithoutGuidTest()
{
- using (var handle = SetupApi.SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero))
- {
- Assert.False(handle.IsInvalid);
- }
+ using var handle = SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero);
+ Assert.False(handle.IsInvalid);
}
[Fact]
public void SetupDiCreateDeviceInfoWithGuidListTest()
{
- Guid processorId = SetupApi.DeviceSetupClass.Processor;
- using (var handle = SetupApi.SetupDiCreateDeviceInfoList(&processorId, IntPtr.Zero))
- {
- Assert.False(handle.IsInvalid);
- }
+ Guid processorId = DeviceSetupClass.Processor;
+ using var handle = SetupDiCreateDeviceInfoList(&processorId, IntPtr.Zero);
+ Assert.False(handle.IsInvalid);
}
[Fact]
public void SetupDiOpenDeviceInfoTest()
{
- using (var deviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero))
- {
- SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
+ using var deviceInfoSet = SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero);
- // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
- // to the supplied device information set, if one does not already exist, for the root device in the device tree.
- string deviceId = null;
- Assert.True(SetupApi.SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData));
- }
+ SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
+
+ // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
+ // to the supplied device information set, if one does not already exist, for the root device in the device tree.
+ string deviceId = null;
+ Assert.True(SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData));
}
[Fact]
public void SetupDiSetSelectedDeviceTest()
{
- using (var deviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero))
- {
- SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
+ using var deviceInfoSet = SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero);
- // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
- // to the supplied device information set, if one does not already exist, for the root device in the device tree.
- string deviceId = null;
- Assert.True(SetupApi.SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData));
+ SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
- Assert.True(SetupApi.SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData));
+ // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
+ // to the supplied device information set, if one does not already exist, for the root device in the device tree.
+ string deviceId = null;
+ Assert.True(SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData));
- deviceInfoData = SP_DEVINFO_DATA.Create();
- Assert.False(SetupApi.SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData));
- }
+ Assert.True(SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData));
+
+ deviceInfoData = SP_DEVINFO_DATA.Create();
+ Assert.False(SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData));
}
[Fact]
public void SetupDiGetDeviceInstallParamsTest()
{
- using (var deviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero))
- {
- SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
+ using var deviceInfoSet = SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero);
- // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
- // to the supplied device information set, if one does not already exist, for the root device in the device tree.
- string deviceId = null;
- if (!SetupApi.SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData))
- {
- throw new Win32Exception();
- }
+ SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
- SP_DEVINSTALL_PARAMS deviceInstallParams = SP_DEVINSTALL_PARAMS.Create();
+ // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
+ // to the supplied device information set, if one does not already exist, for the root device in the device tree.
+ string deviceId = null;
+ if (!SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData))
+ {
+ throw new Win32Exception();
+ }
- if (!SetupApi.SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData, ref deviceInstallParams))
- {
- throw new Win32Exception();
- }
+ SP_DEVINSTALL_PARAMS deviceInstallParams = SP_DEVINSTALL_PARAMS.Create();
- deviceInfoData = SP_DEVINFO_DATA.Create();
- Assert.False(SetupApi.SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData, ref deviceInstallParams));
+ if (!SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData, ref deviceInstallParams))
+ {
+ throw new Win32Exception();
}
+
+ deviceInfoData = SP_DEVINFO_DATA.Create();
+ Assert.False(SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData, ref deviceInstallParams));
}
[Fact]
public void SetupDiGetSetDeviceInstallParamsTest()
{
- using (var deviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero))
- {
- SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
+ using var deviceInfoSet = SetupDiCreateDeviceInfoList((Guid*)null, IntPtr.Zero);
- // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
- // to the supplied device information set, if one does not already exist, for the root device in the device tree.
- string deviceId = null;
- Assert.True(SetupApi.SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData));
+ SP_DEVINFO_DATA deviceInfoData = SP_DEVINFO_DATA.Create();
- SP_DEVINSTALL_PARAMS deviceInstallParams = SP_DEVINSTALL_PARAMS.Create();
+ // If DeviceInstanceId is NULL or references a zero-length string, SetupDiOpenDeviceInfo adds a device information element
+ // to the supplied device information set, if one does not already exist, for the root device in the device tree.
+ string deviceId = null;
+ Assert.True(SetupDiOpenDeviceInfo(deviceInfoSet, deviceId, IntPtr.Zero, SetupDiOpenDeviceInfoFlags.None, ref deviceInfoData));
- Assert.True(SetupApi.SetupDiSetDeviceInstallParams(deviceInfoSet, deviceInfoData, deviceInstallParams));
+ SP_DEVINSTALL_PARAMS deviceInstallParams = SP_DEVINSTALL_PARAMS.Create();
- deviceInfoData = SP_DEVINFO_DATA.Create();
- Assert.False(SetupApi.SetupDiSetDeviceInstallParams(deviceInfoSet, deviceInfoData, deviceInstallParams));
- }
+ Assert.True(SetupDiSetDeviceInstallParams(deviceInfoSet, deviceInfoData, deviceInstallParams));
+
+ deviceInfoData = SP_DEVINFO_DATA.Create();
+ Assert.False(SetupDiSetDeviceInstallParams(deviceInfoSet, deviceInfoData, deviceInstallParams));
}
[Fact]
public void SetupDiBuildDriverInfoListTest()
{
- Guid usbDeviceId = SetupApi.DeviceSetupClass.UsbDevice;
+ Guid usbDeviceId = DeviceSetupClass.UsbDevice;
- using (var deviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList(&usbDeviceId, IntPtr.Zero))
- {
- Assert.True(SetupApi.SetupDiBuildDriverInfoList(deviceInfoSet, (SP_DEVINFO_DATA*)null, DriverType.SPDIT_CLASSDRIVER));
- }
+ using var deviceInfoSet = SetupDiCreateDeviceInfoList(&usbDeviceId, IntPtr.Zero);
+ Assert.True(SetupDiBuildDriverInfoList(deviceInfoSet, (SP_DEVINFO_DATA*)null, DriverType.SPDIT_CLASSDRIVER));
}
[Fact]
public void SetupDiEnumDriverInfoListTest()
{
- Guid usbDeviceId = SetupApi.DeviceSetupClass.Net;
+ Guid usbDeviceId = DeviceSetupClass.Net;
- using (var deviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList(&usbDeviceId, IntPtr.Zero))
+ using var deviceInfoSet = SetupDiCreateDeviceInfoList(&usbDeviceId, IntPtr.Zero);
+
+ Assert.True(SetupDiBuildDriverInfoList(deviceInfoSet, (SP_DEVINFO_DATA*)null, DriverType.SPDIT_CLASSDRIVER));
+
+ uint i = 0;
+ SP_DRVINFO_DATA driverInfoData = SP_DRVINFO_DATA.Create();
+ Collection driverInfos = new Collection();
+ while (SetupDiEnumDriverInfo(deviceInfoSet, null, DriverType.SPDIT_CLASSDRIVER, i++, ref driverInfoData))
{
- Assert.True(SetupApi.SetupDiBuildDriverInfoList(deviceInfoSet, (SP_DEVINFO_DATA*)null, DriverType.SPDIT_CLASSDRIVER));
+ driverInfos.Add(driverInfoData);
+ }
- uint i = 0;
+ // We should have enumerated at least one driver
+ Assert.NotEmpty(driverInfos);
- SP_DRVINFO_DATA driverInfoData = SP_DRVINFO_DATA.Create();
+ var loopbackDrivers =
+ driverInfos
+ .Where(d => new string(d.Description).IndexOf("loopback", StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
- Collection driverInfos = new Collection();
+ var loopbackDriver = Assert.Single(loopbackDrivers);
- while (SetupApi.SetupDiEnumDriverInfo(deviceInfoSet, null, DriverType.SPDIT_CLASSDRIVER, i, ref driverInfoData))
- {
- driverInfos.Add(driverInfoData);
- i += 1;
- }
+ Assert.Equal("Microsoft KM-TEST Loopback Adapter", new string(loopbackDriver.Description));
+ Assert.Equal(DriverType.SPDIT_CLASSDRIVER, loopbackDriver.DriverType);
+ Assert.NotEqual(0u, loopbackDriver.DriverVersion);
+ Assert.Equal("Microsoft", new string(loopbackDriver.MfgName));
+ Assert.Equal("Microsoft", new string(loopbackDriver.ProviderName));
+ }
+
+ [Fact]
+ public unsafe void SetupDiGetDriverInfoDetailTest()
+ {
+ Guid usbDeviceId = DeviceSetupClass.Net;
+
+ using var deviceInfoSet = SetupDiCreateDeviceInfoList(&usbDeviceId, IntPtr.Zero);
+
+ Assert.True(SetupDiBuildDriverInfoList(deviceInfoSet, (SP_DEVINFO_DATA*)null, DriverType.SPDIT_CLASSDRIVER));
+
+ uint i = 0;
+ SP_DRVINFO_DATA driverInfoData = SP_DRVINFO_DATA.Create();
+ Collection driverInfos = new Collection();
+ while (SetupDiEnumDriverInfo(deviceInfoSet, null, DriverType.SPDIT_CLASSDRIVER, i++, ref driverInfoData))
+ {
+ driverInfos.Add(driverInfoData);
+ }
- // We should have enumerated at least one driver
- Assert.NotEmpty(driverInfos);
+ // We should have enumerated at least one driver
+ Assert.NotEmpty(driverInfos);
- var loopbackDrivers =
- driverInfos
- .Where(d => d.DescriptionString.IndexOf("loopback", StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
+ var loopbackDrivers =
+ driverInfos
+ .Where(d => new string(d.Description).IndexOf("loopback", StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
- var loopbackDriver = Assert.Single(loopbackDrivers);
+ var loopbackDriver = Assert.Single(loopbackDrivers);
+
+ byte[] buffer = new byte[0x1000];
+ fixed (byte* ptr = buffer)
+ {
+ var drvInfoDetailData = (SP_DRVINFO_DETAIL_DATA*)ptr;
+ *drvInfoDetailData = SP_DRVINFO_DETAIL_DATA.Create();
+
+ if (!SetupDiGetDriverInfoDetail(
+ deviceInfoSet,
+ null,
+ &loopbackDriver,
+ ptr,
+ buffer.Length,
+ out int requiredSize))
+ {
+ throw new Win32Exception();
+ }
- Assert.Equal("Microsoft KM-TEST Loopback Adapter", loopbackDriver.DescriptionString);
- Assert.Equal(DriverType.SPDIT_CLASSDRIVER, loopbackDriver.DriverType);
- Assert.NotEqual(0u, loopbackDriver.DriverVersion);
- Assert.Equal("Microsoft", loopbackDriver.MfgNameString);
- Assert.Equal("Microsoft", loopbackDriver.ProviderNameString);
+ Assert.Equal(0, (int)drvInfoDetailData->CompatIDsLength);
+ Assert.Equal(0x8, drvInfoDetailData->CompatIDsOffset);
+ Assert.Equal("Microsoft KM-TEST Loopback Adapter", new string(drvInfoDetailData->DrvDescription));
+ Assert.NotEqual(0, drvInfoDetailData->InfDate.dwHighDateTime);
+ Assert.NotEqual(0, drvInfoDetailData->InfDate.dwLowDateTime);
+ Assert.Equal(@"C:\WINDOWS\INF\netloop.inf", new string(drvInfoDetailData->InfFileName), ignoreCase: true);
+ Assert.Equal("kmloop.ndi", new string(drvInfoDetailData->SectionName), ignoreCase: true);
+ Assert.Equal("*msloop", new string(drvInfoDetailData->HardwareID));
}
}
}
diff --git a/src/SetupApi/PublicAPI.Unshipped.txt b/src/SetupApi/PublicAPI.Unshipped.txt
index f67c02a2..2e6d5579 100644
--- a/src/SetupApi/PublicAPI.Unshipped.txt
+++ b/src/SetupApi/PublicAPI.Unshipped.txt
@@ -65,24 +65,31 @@ PInvoke.SetupApi.SP_DEVINSTALL_PARAMS.cbSize -> int
PInvoke.SetupApi.SP_DEVINSTALL_PARAMS.hwndParent -> System.IntPtr
PInvoke.SetupApi.SP_DRVINFO_DATA
PInvoke.SetupApi.SP_DRVINFO_DATA.Description -> char*
-PInvoke.SetupApi.SP_DRVINFO_DATA.DescriptionString.get -> string
PInvoke.SetupApi.SP_DRVINFO_DATA.DriverDate -> System.Runtime.InteropServices.ComTypes.FILETIME
PInvoke.SetupApi.SP_DRVINFO_DATA.DriverType -> PInvoke.SetupApi.DriverType
PInvoke.SetupApi.SP_DRVINFO_DATA.DriverVersion -> ulong
PInvoke.SetupApi.SP_DRVINFO_DATA.MfgName -> char*
-PInvoke.SetupApi.SP_DRVINFO_DATA.MfgNameString.get -> string
PInvoke.SetupApi.SP_DRVINFO_DATA.ProviderName -> char*
-PInvoke.SetupApi.SP_DRVINFO_DATA.ProviderNameString.get -> string
PInvoke.SetupApi.SP_DRVINFO_DATA.Reserved -> System.UIntPtr
PInvoke.SetupApi.SP_DRVINFO_DATA.SP_DRVINFO_DATA() -> void
PInvoke.SetupApi.SP_DRVINFO_DATA.cbSize -> int
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.CompatIDsLength -> int
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.CompatIDsOffset -> int
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.DrvDescription -> char*
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.HardwareID -> char*
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.InfDate -> PInvoke.Kernel32.FILETIME
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.InfFileName -> char*
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.Reserved -> System.UIntPtr
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.SP_DRVINFO_DETAIL_DATA() -> void
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.SectionName -> char*
+PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.cbSize -> int
PInvoke.SetupApi.SetupDiGetDevicePropertyFlags
PInvoke.SetupApi.SetupDiGetDevicePropertyFlags.None = 0 -> PInvoke.SetupApi.SetupDiGetDevicePropertyFlags
PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags
PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags.DIOD_CANCEL_REMOVE = 4 -> PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags
PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags.DIOD_INHERIT_CLASSDRVS = 2 -> PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags
PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags.None = 0 -> PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags
-override PInvoke.SetupApi.SP_DRVINFO_DATA.ToString() -> string
static PInvoke.SetupApi.DeviceSetupClass.Avc.get -> System.Guid
static PInvoke.SetupApi.DeviceSetupClass.Battery.get -> System.Guid
static PInvoke.SetupApi.DeviceSetupClass.Biometric.get -> System.Guid
@@ -135,6 +142,7 @@ static PInvoke.SetupApi.DeviceSetupClass.WCEUSBS.get -> System.Guid
static PInvoke.SetupApi.DeviceSetupClass.Wpd.get -> System.Guid
static PInvoke.SetupApi.SP_DEVINSTALL_PARAMS.Create() -> PInvoke.SetupApi.SP_DEVINSTALL_PARAMS
static PInvoke.SetupApi.SP_DRVINFO_DATA.Create() -> PInvoke.SetupApi.SP_DRVINFO_DATA
+static PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA.Create() -> PInvoke.SetupApi.SP_DRVINFO_DETAIL_DATA
static PInvoke.SetupApi.SetupDiBuildDriverInfoList(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA? deviceInfoData, PInvoke.SetupApi.DriverType driverType) -> bool
static PInvoke.SetupApi.SetupDiBuildDriverInfoList(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, System.IntPtr deviceInfoData, PInvoke.SetupApi.DriverType driverType) -> bool
static PInvoke.SetupApi.SetupDiCreateDeviceInfoList(System.Guid? classGuid, System.IntPtr hwndParent) -> PInvoke.SetupApi.SafeDeviceInfoSetHandle
@@ -147,6 +155,8 @@ static PInvoke.SetupApi.SetupDiGetDeviceInstallParams(PInvoke.SetupApi.SafeDevic
static PInvoke.SetupApi.SetupDiGetDeviceProperty(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData, PInvoke.SetupApi.DEVPROPKEY* propertyKey, uint* propertyType, byte[] propertyBuffer, uint propertyBufferSize, uint* requiredSize, PInvoke.SetupApi.SetupDiGetDevicePropertyFlags flags) -> bool
static PInvoke.SetupApi.SetupDiGetDeviceProperty(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, System.IntPtr deviceInfoData, System.IntPtr propertyKey, System.IntPtr propertyType, System.IntPtr propertyBuffer, uint propertyBufferSize, System.IntPtr requiredSize, PInvoke.SetupApi.SetupDiGetDevicePropertyFlags flags) -> bool
static PInvoke.SetupApi.SetupDiGetDeviceProperty(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, System.IntPtr deviceInfoData, System.IntPtr propertyKey, System.IntPtr propertyType, byte[] propertyBuffer, uint propertyBufferSize, System.IntPtr requiredSize, PInvoke.SetupApi.SetupDiGetDevicePropertyFlags flags) -> bool
+static PInvoke.SetupApi.SetupDiGetDriverInfoDetail(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA? deviceInfoData, PInvoke.SetupApi.SP_DRVINFO_DATA? driverInfoData, ref byte driverInfoDetailData, int driverInfoDetailDataSize, out int requiredSize) -> bool
+static PInvoke.SetupApi.SetupDiGetDriverInfoDetail(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, System.IntPtr deviceInfoData, System.IntPtr driverInfoData, System.IntPtr driverInfoDetailData, int driverInfoDetailDataSize, out int requiredSize) -> bool
static PInvoke.SetupApi.SetupDiOpenDeviceInfo(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, string deviceInstanceId, System.IntPtr parent, PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags openFlags, System.IntPtr deviceInfoData) -> bool
static PInvoke.SetupApi.SetupDiOpenDeviceInfo(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, string deviceInstanceId, System.IntPtr parent, PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags openFlags, ref PInvoke.SetupApi.SP_DEVINFO_DATA deviceInfoData) -> bool
static PInvoke.SetupApi.SetupDiSetDeviceInstallParams(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA? deviceInfoData, PInvoke.SetupApi.SP_DEVINSTALL_PARAMS deviceInstallParams) -> bool
@@ -160,6 +170,7 @@ static extern PInvoke.SetupApi.SetupDiCreateDeviceInfoList(System.Guid* classGui
static extern PInvoke.SetupApi.SetupDiEnumDriverInfo(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData, PInvoke.SetupApi.DriverType driverType, uint memberIndex, PInvoke.SetupApi.SP_DRVINFO_DATA* driverInfoData) -> bool
static extern PInvoke.SetupApi.SetupDiGetDeviceInstallParams(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData, PInvoke.SetupApi.SP_DEVINSTALL_PARAMS* deviceInstallParams) -> bool
static extern PInvoke.SetupApi.SetupDiGetDeviceProperty(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData, PInvoke.SetupApi.DEVPROPKEY* propertyKey, uint* propertyType, byte* propertyBuffer, uint propertyBufferSize, uint* requiredSize, PInvoke.SetupApi.SetupDiGetDevicePropertyFlags flags) -> bool
+static extern PInvoke.SetupApi.SetupDiGetDriverInfoDetail(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData, PInvoke.SetupApi.SP_DRVINFO_DATA* driverInfoData, byte* driverInfoDetailData, int driverInfoDetailDataSize, out int requiredSize) -> bool
static extern PInvoke.SetupApi.SetupDiOpenDeviceInfo(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, string deviceInstanceId, System.IntPtr parent, PInvoke.SetupApi.SetupDiOpenDeviceInfoFlags openFlags, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData) -> bool
static extern PInvoke.SetupApi.SetupDiSetDeviceInstallParams(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData, PInvoke.SetupApi.SP_DEVINSTALL_PARAMS* deviceInstallParams) -> bool
static extern PInvoke.SetupApi.SetupDiSetSelectedDevice(PInvoke.SetupApi.SafeDeviceInfoSetHandle deviceInfoSet, PInvoke.SetupApi.SP_DEVINFO_DATA* deviceInfoData) -> bool
diff --git a/src/SetupApi/SetupApi+SP_DRVINFO_DATA.cs b/src/SetupApi/SetupApi+SP_DRVINFO_DATA.cs
index f26427fb..a9eb036f 100644
--- a/src/SetupApi/SetupApi+SP_DRVINFO_DATA.cs
+++ b/src/SetupApi/SetupApi+SP_DRVINFO_DATA.cs
@@ -40,18 +40,19 @@ public unsafe struct SP_DRVINFO_DATA
///
/// A that describes the device supported by this driver.
///
- public fixed char Description[LINE_LEN];
+ public fixed char Description[SetupApi.LINE_LEN];
///
/// A that contains the name of the manufacturer of the device supported by this driver.
///
- public fixed char MfgName[LINE_LEN];
+ public fixed char MfgName[SetupApi.LINE_LEN];
///
/// A giving the provider of this driver. This is typically the name of the organization that
/// creates the driver or INF file. can be an empty string.
///
- public fixed char ProviderName[LINE_LEN];
+ /// Convert this to a string by passing its value to .
+ public fixed char ProviderName[SetupApi.LINE_LEN];
///
/// Date of the driver. From the DriverVer entry in the INF file.
@@ -63,72 +64,12 @@ public unsafe struct SP_DRVINFO_DATA
///
public ulong DriverVersion;
- ///
- /// The length of the strings that are part of this structure.
- ///
- private const int LINE_LEN = 256;
-
- ///
- /// Gets a that describes the device supported by this driver.
- ///
- public string DescriptionString
- {
- get
- {
- fixed (char* description = this.Description)
- {
- return new string(description);
- }
- }
- }
-
- ///
- /// Gets a that contains the name of the manufacturer of the device supported by this driver.
- ///
- public string MfgNameString
- {
- get
- {
- fixed (char* description = this.MfgName)
- {
- return new string(description);
- }
- }
- }
-
- ///
- /// Gets a giving the provider of this driver. This is typically the name of the organization that
- /// creates the driver or INF file. can be an empty string.
- ///
- public string ProviderNameString
- {
- get
- {
- fixed (char* description = this.ProviderName)
- {
- return new string(description);
- }
- }
- }
-
///
/// Initializes a new instance of the struct
/// with set to the correct value.
///
/// An instance of .
- public static SP_DRVINFO_DATA Create()
- {
- return new SP_DRVINFO_DATA
- {
- cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA)),
- };
- }
-
- ///
- public override string ToString()
- {
- return this.DescriptionString;
- }
+ public static SP_DRVINFO_DATA Create() => new SP_DRVINFO_DATA { cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA)) };
}
}
}
diff --git a/src/SetupApi/SetupApi+SP_DRVINFO_DETAIL_DATA.cs b/src/SetupApi/SetupApi+SP_DRVINFO_DETAIL_DATA.cs
new file mode 100644
index 00000000..e057ae1a
--- /dev/null
+++ b/src/SetupApi/SetupApi+SP_DRVINFO_DETAIL_DATA.cs
@@ -0,0 +1,98 @@
+// Copyright © .NET Foundation and Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace PInvoke
+{
+ using System;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+ using System.Runtime.InteropServices.ComTypes;
+
+ ///
+ /// Contains the nested type.
+ ///
+ public partial class SetupApi
+ {
+ ///
+ /// Contains detailed information about a particular driver information structure.
+ ///
+ ///
+ public unsafe struct SP_DRVINFO_DETAIL_DATA
+ {
+ ///
+ /// The size, in bytes, of the structure.
+ ///
+ public int cbSize;
+
+ ///
+ /// Date of the INF file for this driver.
+ ///
+ public Kernel32.FILETIME InfDate;
+
+ ///
+ /// The offset, in characters, from the beginning of the buffer where the CompatIDs list begins.
+ ///
+ ///
+ /// This value can also be used to determine whether there is a hardware ID that precedes the CompatIDs list.
+ /// If this value is greater than 1, the first string in the HardwareID buffer is the hardware ID.
+ /// If this value is less than or equal to 1, there is no hardware ID.
+ ///
+ public int CompatIDsOffset;
+
+ ///
+ /// The length, in characters, of the CompatIDs list starting at offset from the beginning of the buffer.
+ ///
+ ///
+ /// If is nonzero, the CompatIDs list contains one or more -terminated strings with an additional
+ /// character at the end of the list.
+ /// If is zero, the CompatIDs list is empty. In that case, there is no additional character at the end of the list.
+ ///
+ public int CompatIDsLength;
+
+ ///
+ /// Reserved. For internal use only.
+ ///
+ public UIntPtr Reserved;
+
+ ///
+ /// A -terminated 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 fixed char SectionName[SetupApi.LINE_LEN];
+
+ ///
+ /// A -terminated string that contains the full-qualified name of the INF file for this driver.
+ ///
+ public fixed char InfFileName[Kernel32.MAX_PATH];
+
+ ///
+ /// A -terminated string that describes the driver.
+ ///
+ public fixed char DrvDescription[SetupApi.LINE_LEN];
+
+ ///
+ /// A buffer that contains a list of IDs (a single hardware ID followed by a list of compatible IDs).
+ /// These IDs correspond to the hardware ID and compatible IDs in the INF Models section.
+ ///
+ ///
+ /// Each ID in the list is a -terminated string.
+ /// If the hardware ID exists (that is, if is greater than one), this single -terminated
+ /// string is found at the beginning of the buffer.
+ /// If the CompatIDs list is not empty (that is, if is not zero), the CompatIDs list starts at offset
+ /// from the beginning of this buffer, and is terminated with an additional
+ /// character at the end of the list.
+ ///
+ public fixed char HardwareID[1];
+
+ ///
+ /// Initializes a new instance of the struct
+ /// with set to the correct value.
+ ///
+ /// An instance of .
+ ///
+ /// The numbers are hard-coded because due to alignment issues, .NET reports 2 bytes more than the Win32 API is expecting and it won't accept a struct that is too large.
+ ///
+ public static SP_DRVINFO_DETAIL_DATA Create() => new SP_DRVINFO_DETAIL_DATA { cbSize = IntPtr.Size == 4 ? 0x622 : 0x630 };
+ }
+ }
+}
diff --git a/src/SetupApi/SetupApi.cs b/src/SetupApi/SetupApi.cs
index 70e5d3a7..d13e38dd 100644
--- a/src/SetupApi/SetupApi.cs
+++ b/src/SetupApi/SetupApi.cs
@@ -17,6 +17,11 @@ namespace PInvoke
[OfferFriendlyOverloads]
public static partial class SetupApi
{
+ ///
+ /// The line length of the strings that are used by .
+ ///
+ private const int LINE_LEN = 256;
+
///
/// The SetupDiGetClassDevs function returns a handle to a device information set
/// that contains requested device information elements for a local computer.
@@ -485,6 +490,55 @@ public static unsafe extern bool SetupDiSetSelectedDriver(
[Friendly(FriendlyFlags.In | FriendlyFlags.Optional)] SP_DEVINFO_DATA* deviceInfoData,
[Friendly(FriendlyFlags.Bidirectional | FriendlyFlags.Optional)] SP_DRVINFO_DATA* driverInfoData);
+ ///
+ /// Retrieves driver information detail for a device information set or a particular device information element in the device information set.
+ ///
+ ///
+ /// A handle to a device information set that contains a driver information element for which to retrieve driver information.
+ ///
+ ///
+ /// A pointer to an structure that specifies a device information element that represents the device
+ /// for which to retrieve driver information. This parameter is optional and can be .
+ /// If this parameter is specified, retrieves information about a driver in a driver list
+ /// for the specified device.
+ /// If this parameter is , SetupDiGetDriverInfoDetail retrieves information about a driver that is a member of
+ /// the global class driver list for .
+ ///
+ ///
+ /// A pointer to an structure that specifies the driver information element that represents the driver
+ /// for which to retrieve details. If DeviceInfoData is specified, the driver must be a member of the driver list for the device that
+ /// is specified by . Otherwise, the driver must be a member of the global class driver list for
+ /// .
+ ///
+ ///
+ /// A pointer to an structure that receives detailed information about the specified driver.
+ /// If this parameter is not specified, must be zero.
+ /// If this parameter is specified, must be set to the value of sizeof(SP_DRVINFO_DETAIL_DATA)
+ /// before it calls SetupDiGetDriverInfoDetail.
+ ///
+ ///
+ /// The size, in bytes, of the buffer.
+ ///
+ ///
+ /// A pointer to a variable that receives the number of bytes required to store the detailed driver information.
+ /// This value includes both the size of the structure and the additional bytes required for the variable-length character buffer at the
+ /// end that holds the hardware ID list and the compatible ID list. The lists are in REG_MULTI_SZ format.
+ ///
+ ///
+ /// The function returns if it is successful.
+ /// Otherwise, it returns and the logged error can be retrieved by making a call to .
+ ///
+ ///
+ [DllImport(nameof(SetupApi), SetLastError = true, CharSet = CharSet.Unicode)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static unsafe extern bool SetupDiGetDriverInfoDetail(
+ SafeDeviceInfoSetHandle deviceInfoSet,
+ [Friendly(FriendlyFlags.In | FriendlyFlags.Optional)] SP_DEVINFO_DATA* deviceInfoData,
+ [Friendly(FriendlyFlags.In | FriendlyFlags.Optional)] SP_DRVINFO_DATA* driverInfoData,
+ [Friendly(FriendlyFlags.Bidirectional)] byte* driverInfoDetailData,
+ int driverInfoDetailDataSize,
+ out int requiredSize);
+
///
/// Deletes a device information set and frees all associated memory.
///
diff --git a/src/WinUsb/WinUsb+WINUSB_PIPE_INFORMATION.cs b/src/WinUsb/WinUsb+WINUSB_PIPE_INFORMATION.cs
index 4a6092c3..5a456581 100644
--- a/src/WinUsb/WinUsb+WINUSB_PIPE_INFORMATION.cs
+++ b/src/WinUsb/WinUsb+WINUSB_PIPE_INFORMATION.cs
@@ -11,7 +11,7 @@ namespace PInvoke
public static partial class WinUsb
{
///
- /// Contains pipe information that the routine retrieves.
+ /// Contains pipe information that the routine retrieves.
///
///
public struct WINUSB_PIPE_INFORMATION