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;
 }
Пример #2
0
        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);
 }
Пример #4
0
        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);
        }