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