private static bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref Win32.SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref Win32.SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, int deviceInterfaceDetailSize) { var retval = Win32.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, ref deviceInterfaceDetailData, (uint)deviceInterfaceDetailSize, out uint reqSize, IntPtr.Zero); retval = Win32.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, ref deviceInterfaceDetailData, (uint)reqSize, out reqSize, IntPtr.Zero); if (!retval) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != 0) { throw Marshal.GetExceptionForHR(errorCode); } else { throw new Exception("SetupDiGetDeviceInterfaceDetail call failed but Win32 didn't catch an error."); } } return(retval); }
public static BatteryInformation GetBatteryInformation() { var deviceDataPointer = IntPtr.Zero; var queryInfoPointer = IntPtr.Zero; var batteryInfoPointer = IntPtr.Zero; var batteryWaitStatusPointer = IntPtr.Zero; var batteryStatusPointer = IntPtr.Zero; try { var deviceHandle = SetupDiGetClassDevs(Win32.GUID_DEVCLASS_BATTERY, Win32.DEVICE_GET_CLASS_FLAGS.DIGCF_PRESENT | Win32.DEVICE_GET_CLASS_FLAGS.DIGCF_DEVICEINTERFACE); var deviceInterfaceData = new Win32.SP_DEVICE_INTERFACE_DATA(); deviceInterfaceData.CbSize = Marshal.SizeOf(deviceInterfaceData); SetupDiEnumDeviceInterfaces(deviceHandle, Win32.GUID_DEVCLASS_BATTERY, 0, ref deviceInterfaceData); deviceDataPointer = Marshal.AllocHGlobal(Win32.DEVICE_INTERFACE_BUFFER_SIZE); var deviceDetailData = new Win32.SP_DEVICE_INTERFACE_DETAIL_DATA { CbSize = (IntPtr.Size == 8) ? 8 : 4 + Marshal.SystemDefaultCharSize }; SetupDiGetDeviceInterfaceDetail(deviceHandle, ref deviceInterfaceData, ref deviceDetailData, Win32.DEVICE_INTERFACE_BUFFER_SIZE); var batteryHandle = CreateFile(deviceDetailData.DevicePath, FileAccess.ReadWrite, FileShare.ReadWrite, FileMode.Open, Win32.FILE_ATTRIBUTES.Normal); var queryInformation = new Win32.BATTERY_QUERY_INFORMATION(); DeviceIoControl(batteryHandle, Win32.IOCTL_BATTERY_QUERY_TAG, ref queryInformation.BatteryTag); var batteryInformation = new Win32.BATTERY_INFORMATION(); queryInformation.InformationLevel = Win32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryInformation; var queryInfoSize = Marshal.SizeOf(queryInformation); var batteryInfoSize = Marshal.SizeOf(batteryInformation); queryInfoPointer = Marshal.AllocHGlobal(queryInfoSize); Marshal.StructureToPtr(queryInformation, queryInfoPointer, false); batteryInfoPointer = Marshal.AllocHGlobal(batteryInfoSize); Marshal.StructureToPtr(batteryInformation, batteryInfoPointer, false); DeviceIoControl(batteryHandle, Win32.IOCTL_BATTERY_QUERY_INFORMATION, queryInfoPointer, queryInfoSize, batteryInfoPointer, batteryInfoSize); var updatedBatteryInformation = (Win32.BATTERY_INFORMATION)Marshal.PtrToStructure(batteryInfoPointer, typeof(Win32.BATTERY_INFORMATION)); var batteryWaitStatus = new Win32.BATTERY_WAIT_STATUS { BatteryTag = queryInformation.BatteryTag }; var batteryStatus = new Win32.BATTERY_STATUS(); var waitStatusSize = Marshal.SizeOf(batteryWaitStatus); var batteryStatusSize = Marshal.SizeOf(batteryStatus); batteryWaitStatusPointer = Marshal.AllocHGlobal(waitStatusSize); Marshal.StructureToPtr(batteryWaitStatus, batteryWaitStatusPointer, false); batteryStatusPointer = Marshal.AllocHGlobal(batteryStatusSize); Marshal.StructureToPtr(batteryStatus, batteryStatusPointer, false); DeviceIoControl(batteryHandle, Win32.IOCTL_BATTERY_QUERY_STATUS, batteryWaitStatusPointer, waitStatusSize, batteryStatusPointer, batteryStatusSize); var updatedStatus = (Win32.BATTERY_STATUS)Marshal.PtrToStructure(batteryStatusPointer, typeof(Win32.BATTERY_STATUS)); Win32.SetupDiDestroyDeviceInfoList(deviceHandle); return(new BatteryInformation() { DesignedMaxCapacity = updatedBatteryInformation.DesignedCapacity, FullChargeCapacity = updatedBatteryInformation.FullChargedCapacity, CurrentCapacity = updatedStatus.Capacity, Voltage = updatedStatus.Voltage, DischargeRate = updatedStatus.Rate }); } finally { Marshal.FreeHGlobal(deviceDataPointer); Marshal.FreeHGlobal(queryInfoPointer); Marshal.FreeHGlobal(batteryInfoPointer); Marshal.FreeHGlobal(batteryStatusPointer); Marshal.FreeHGlobal(batteryWaitStatusPointer); } }
private static bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, Guid guid, int memberIndex, ref Win32.SP_DEVICE_INTERFACE_DATA deviceInterfaceData) { var retval = Win32.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref guid, (uint)memberIndex, ref deviceInterfaceData); if (!retval) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != 0) { if (errorCode == 259) { throw new Exception( "SetupDeviceInfoEnumerateDeviceInterfaces ran out of batteries to enumerate."); } throw Marshal.GetExceptionForHR(errorCode); } else { throw new Exception( "SetupDeviceInfoEnumerateDeviceInterfaces call failed but Win32 didn't catch an error."); } } return(retval); }