public static BatteryInformation GetBatteryInformation()
            {
                IntPtr deviceDataPointer        = IntPtr.Zero;
                IntPtr queryInfoPointer         = IntPtr.Zero;
                IntPtr batteryInfoPointer       = IntPtr.Zero;
                IntPtr batteryWaitStatusPointer = IntPtr.Zero;
                IntPtr batteryStatusPointer     = IntPtr.Zero;

                try
                {
                    IntPtr deviceHandle = SetupDiGetClassDevs(
                        Win32.GUID_DEVCLASS_BATTERY, Win32.DEVICE_GET_CLASS_FLAGS.DIGCF_PRESENT | Win32.DEVICE_GET_CLASS_FLAGS.DIGCF_DEVICEINTERFACE);

                    Win32.SP_DEVICE_INTERFACE_DATA 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);
                    //Win32.SP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData =
                    //    (Win32.SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(deviceDataPointer, typeof(Win32.SP_DEVICE_INTERFACE_DETAIL_DATA));

                    //toggle these two and see if naything changes... ^^^^^^^^^^^^
                    Win32.SP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData = new Win32.SP_DEVICE_INTERFACE_DETAIL_DATA();
                    deviceDetailData.CbSize = (IntPtr.Size == 8) ? 8 : 4 + Marshal.SystemDefaultCharSize;

                    SetupDiGetDeviceInterfaceDetail(deviceHandle, ref deviceInterfaceData, ref deviceDetailData, Win32.DEVICE_INTERFACE_BUFFER_SIZE);

                    IntPtr batteryHandle = CreateFile(deviceDetailData.DevicePath, FileAccess.ReadWrite, FileShare.ReadWrite, FileMode.Open, Win32.FILE_ATTRIBUTES.Normal);

                    Win32.BATTERY_QUERY_INFORMATION queryInformation = new Win32.BATTERY_QUERY_INFORMATION();

                    DeviceIoControl(batteryHandle, Win32.IOCTL_BATTERY_QUERY_TAG, ref queryInformation.BatteryTag);

                    Win32.BATTERY_INFORMATION batteryInformation = new Win32.BATTERY_INFORMATION();
                    queryInformation.InformationLevel = Win32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryInformation;

                    int queryInfoSize   = Marshal.SizeOf(queryInformation);
                    int 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);

                    Win32.BATTERY_INFORMATION updatedBatteryInformation =
                        (Win32.BATTERY_INFORMATION)Marshal.PtrToStructure(batteryInfoPointer, typeof(Win32.BATTERY_INFORMATION));

                    Win32.BATTERY_WAIT_STATUS batteryWaitStatus = new Win32.BATTERY_WAIT_STATUS();
                    batteryWaitStatus.BatteryTag = queryInformation.BatteryTag;

                    Win32.BATTERY_STATUS batteryStatus = new Win32.BATTERY_STATUS();

                    int waitStatusSize    = Marshal.SizeOf(batteryWaitStatus);
                    int 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);

                    Win32.BATTERY_STATUS 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 SetupDiGetDeviceInterfaceDetail(
                IntPtr deviceInfoSet, ref Win32.SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref Win32.SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, int deviceInterfaceDetailSize)
            {
                //int tmpSize = Marshal.SizeOf(deviceInterfaceDetailData);
                uint reqSize;
                bool retval = Win32.SetupDiGetDeviceInterfaceDetail(
                    deviceInfoSet, ref deviceInterfaceData, ref deviceInterfaceDetailData, (uint)deviceInterfaceDetailSize, 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);
            }