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 <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.cbSize)).ToInt32()); Assert.Equal(4, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.InfDate)).ToInt32()); Assert.Equal(0xc, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsOffset)).ToInt32()); Assert.Equal(0x10, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsLength)).ToInt32()); Assert.Equal(0x18, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.Reserved)).ToInt32()); Assert.Equal(0x20, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.SectionName)).ToInt32()); Assert.Equal(0x220, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.InfFileName)).ToInt32()); Assert.Equal(0x428, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.DrvDescription)).ToInt32()); Assert.Equal(0x628, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.HardwareID)).ToInt32()); Assert.Equal(0x630, SP_DRVINFO_DETAIL_DATA.Create().cbSize); } else { Assert.Equal(0, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.cbSize)).ToInt32()); Assert.Equal(4, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.InfDate)).ToInt32()); Assert.Equal(0xc, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsOffset)).ToInt32()); Assert.Equal(0x10, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.CompatIDsLength)).ToInt32()); Assert.Equal(0x14, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.Reserved)).ToInt32()); Assert.Equal(0x18, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.SectionName)).ToInt32()); Assert.Equal(0x218, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.InfFileName)).ToInt32()); Assert.Equal(0x420, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.DrvDescription)).ToInt32()); Assert.Equal(0x620, Marshal.OffsetOf <SP_DRVINFO_DETAIL_DATA>(nameof(SP_DRVINFO_DETAIL_DATA.HardwareID)).ToInt32()); Assert.Equal(0x622, SP_DRVINFO_DETAIL_DATA.Create().cbSize); } }
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 <SP_DRVINFO_DATA> driverInfos = new Collection <SP_DRVINFO_DATA>(); while (SetupDiEnumDriverInfo(deviceInfoSet, null, DriverType.SPDIT_CLASSDRIVER, i++, ref driverInfoData)) { driverInfos.Add(driverInfoData); } // We should have enumerated at least one driver Assert.NotEmpty(driverInfos); var loopbackDrivers = driverInfos .Where(d => new string(d.Description).IndexOf("loopback", StringComparison.OrdinalIgnoreCase) >= 0).ToArray(); 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(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)); } }
private static string GetDriverInf(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfo) { // Get Currently Installed Driver. SP_DEVINSTALL_PARAMS deviceInstallParams = new SP_DEVINSTALL_PARAMS { cbSize = Marshal.SizeOf(typeof(SP_DEVINSTALL_PARAMS)), FlagsEx = DI_FLAGS.ALLOWEXCLUDEDDRVS | DI_FLAGS.INSTALLEDDRIVER }; if (!NativeMethods.SetupDiSetDeviceInstallParams(deviceInfoSet, ref deviceInfo, ref deviceInstallParams)) { throw new Win32Exception(); } if (!NativeMethods.SetupDiBuildDriverInfoList(deviceInfoSet, ref deviceInfo, SPDIT.COMPATDRIVER)) { throw new Win32Exception(); } try { if (Environment.Is64BitProcess) { SP_DRVINFO_DATA drvInfo = new SP_DRVINFO_DATA { cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA)) }; if (NativeMethods.SetupDiEnumDriverInfo(deviceInfoSet, ref deviceInfo, SPDIT.COMPATDRIVER, 0, ref drvInfo)) { SP_DRVINFO_DETAIL_DATA driverInfoDetailData = new SP_DRVINFO_DETAIL_DATA { cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DETAIL_DATA)) }; if (NativeMethods.SetupDiGetDriverInfoDetail(deviceInfoSet, ref deviceInfo, ref drvInfo, ref driverInfoDetailData, Marshal.SizeOf(driverInfoDetailData), out _) || Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER) { return(driverInfoDetailData.InfFileName); } else { throw new Win32Exception(); } } else if (Marshal.GetLastWin32Error() != ERROR_NO_MORE_ITEMS) { throw new Win32Exception(); } } else { SP_DRVINFO_DATA32 drvInfo = new SP_DRVINFO_DATA32 { cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA32)) }; if (NativeMethods.SetupDiEnumDriverInfo32(deviceInfoSet, ref deviceInfo, SPDIT.COMPATDRIVER, 0, ref drvInfo)) { SP_DRVINFO_DETAIL_DATA32 driverInfoDetailData = new SP_DRVINFO_DETAIL_DATA32 { cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DETAIL_DATA32)) }; if (NativeMethods.SetupDiGetDriverInfoDetail32(deviceInfoSet, ref deviceInfo, ref drvInfo, ref driverInfoDetailData, Marshal.SizeOf(driverInfoDetailData), out _) || Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER) { return(driverInfoDetailData.InfFileName); } else { throw new Win32Exception(); } } else if (Marshal.GetLastWin32Error() != ERROR_NO_MORE_ITEMS) { throw new Win32Exception(); } } } finally { NativeMethods.SetupDiDestroyDriverInfoList(deviceInfoSet, ref deviceInfo, SPDIT.COMPATDRIVER); } return(null); }