public NVMeHealthInfoImpl(NVMeHealthInfoLog log, byte[] rawData) { CriticalWarning = (NVMeCriticalWarning)log.CriticalWarning; Temperature = KelvinToCelsius(log.CompositeTemperature); AvailableSpare = log.AvailableSpare; AvailableSpareThreshold = log.AvailableSpareThreshold; PercentageUsed = log.PercentageUsed; DataUnitRead = BitConverter.ToUInt64(log.DataUnitRead, 0); DataUnitWritten = BitConverter.ToUInt64(log.DataUnitWritten, 0); HostReadCommands = BitConverter.ToUInt64(log.HostReadCommands, 0); HostWriteCommands = BitConverter.ToUInt64(log.HostWriteCommands, 0); ControllerBusyTime = BitConverter.ToUInt64(log.ControllerBusyTime, 0); PowerCycle = BitConverter.ToUInt64(log.PowerCycle, 0); PowerOnHours = BitConverter.ToUInt64(log.PowerOnHours, 0); UnsafeShutdowns = BitConverter.ToUInt64(log.UnsafeShutdowns, 0); MediaErrors = BitConverter.ToUInt64(log.MediaErrors, 0); ErrorInfoLogEntryCount = BitConverter.ToUInt64(log.ErrorInfoLogEntryCount, 0); WarningCompositeTemperatureTime = log.WarningCompositeTemperatureTime; CriticalCompositeTemperatureTime = log.CriticalCompositeTemperatureTime; TemperatureSensors = new short[log.TemperatureSensors.Length]; for (int i = 0; i < TemperatureSensors.Length; i++) { TemperatureSensors[i] = KelvinToCelsius(log.TemperatureSensors[i]); } RawData = rawData; }
public NVMeHealthInfo GetHealthInfo() { if (handle.IsClosed) { throw new ObjectDisposedException("WindowsNVMeSmart"); } if (!_requiresAlternateHealthInfo) { try { uint size = (uint)Marshal.SizeOf(typeof(NVMeHealthInfoLog)); uint cdw10 = 0x000000002 | (((size / 4) - 1) << 16); byte[] rawData; NVMeHealthInfoLog data = ReadPassThrough <NVMeHealthInfoLog>(NVMePassThroughOpcode.AdminGetLogPage, 0xffffffff, cdw10, out rawData); return(new NVMeHealthInfoImpl(data, rawData)); } catch (Win32Exception x) { Logging.LogError(x, "Unable to query NVMe Health Information, trying alternate API"); } } try { NVMeHealthInfoLog data2; if (GetHealthInfoAlternate(out data2)) { // If this succeeds (and the above fails), always go directly here _requiresAlternateHealthInfo = true; return(new NVMeHealthInfoImpl(data2, null)); } } catch (Win32Exception x) { Logging.LogError(x, "Alternate API doesn't work, either."); } return(null); }
public NVMeHealthInfo GetHealthInfo() { if (handle.IsClosed) { throw new ObjectDisposedException("WindowsNVMeSmart"); } try { uint size = (uint)Marshal.SizeOf(typeof(NVMeHealthInfoLog)); uint cdw10 = 0x000000002 | (((size / 4) - 1) << 16); byte[] rawData; NVMeHealthInfoLog data = ReadPassThrough <NVMeHealthInfoLog>(NVMePassThroughOpcode.AdminGetLogPage, 0xffffffff, cdw10, out rawData); return(new NVMeHealthInfoImpl(data, rawData)); } catch (Win32Exception) { } return(null); }
private bool GetHealthInfoAlternate(out NVMeHealthInfoLog data) { data = NativeMethods.CreateStruct <NVMeHealthInfoLog>(); if (handle == null || handle.IsInvalid) { return(false); } bool result = false; NativeMethods.STORAGE_QUERY_BUFFER nptwb = NativeMethods.CreateStruct <NativeMethods.STORAGE_QUERY_BUFFER>(); nptwb.ProtocolSpecific.ProtocolType = NativeMethods.STORAGE_PROTOCOL_TYPE.ProtocolTypeNvme; nptwb.ProtocolSpecific.DataType = (uint)NativeMethods.STORAGE_PROTOCOL_NVME_DATA_TYPE.NVMeDataTypeLogPage; nptwb.ProtocolSpecific.ProtocolDataRequestValue = (uint)NativeMethods.NVME_LOG_PAGES.NVME_LOG_PAGE_HEALTH_INFO; nptwb.ProtocolSpecific.ProtocolDataOffset = (uint)Marshal.SizeOf <NativeMethods.STORAGE_PROTOCOL_SPECIFIC_DATA>(); nptwb.ProtocolSpecific.ProtocolDataLength = (uint)nptwb.Buffer.Length; nptwb.PropertyId = NativeMethods.STORAGE_PROPERTY_ID.StorageAdapterProtocolSpecificProperty; nptwb.QueryType = NativeMethods.STORAGE_QUERY_TYPE.PropertyStandardQuery; int length = Marshal.SizeOf <NativeMethods.STORAGE_QUERY_BUFFER>(); IntPtr buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(nptwb, buffer, false); bool validTransfer = NativeMethods.DeviceIoControl(handle, Command.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { //map NVME_HEALTH_INFO_LOG to nptwb.Buffer IntPtr offset = Marshal.OffsetOf <NativeMethods.STORAGE_QUERY_BUFFER>(nameof(NativeMethods.STORAGE_QUERY_BUFFER.Buffer)); var newPtr = IntPtr.Add(buffer, offset.ToInt32()); NVMeHealthInfoLog item = Marshal.PtrToStructure <NVMeHealthInfoLog>(newPtr); data = item; Marshal.FreeHGlobal(buffer); result = true; } else { Marshal.FreeHGlobal(buffer); } return(result); }