internal AtaStorage(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, string id, int index, IEnumerable <SmartAttribute> smartAttributes, ISettings settings) : base(storageInfo, name, firmwareRevision, id, index, settings) { Smart = smart; if (smart.IsValid) { smart.EnableSmart(); } _smartAttributes = new List <SmartAttribute>(smartAttributes); CreateSensors(); }
internal NVMeSmart(StorageInfo storageInfo) { _driveNumber = storageInfo.Index; NVMeDrive = null; // Test samsung protocol. // Exclude Samsung 980 Pro, this SSD uses the NVMeWindows generic protocol. // Samsung 980 Pro can accessed via IdentifyDevice and IdentifyController but not by HealthInfoLog. if (NVMeDrive == null && storageInfo.Name.IndexOf("Samsung", StringComparison.OrdinalIgnoreCase) > -1 && storageInfo.Name.IndexOf("980 Pro", StringComparison.OrdinalIgnoreCase) == -1) { _handle = NVMeSamsung.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeSamsung(); } } // Test Intel protocol. if (NVMeDrive == null && storageInfo.Name.IndexOf("Intel", StringComparison.OrdinalIgnoreCase) > -1) { _handle = NVMeIntel.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeIntel(); } } // Test Intel raid protocol. if (NVMeDrive == null && storageInfo.Name.IndexOf("Intel", StringComparison.OrdinalIgnoreCase) > -1) { _handle = NVMeIntelRst.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeIntelRst(); } } // Test Windows generic driver protocol. if (NVMeDrive == null) { _handle = NVMeWindows.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeWindows(); } } }
internal NVMeSmart(StorageInfo storageInfo) { _driveNumber = storageInfo.Index; NVMeDrive = null; string name = storageInfo.Name; // Test Samsung protocol. if (NVMeDrive == null && name.IndexOf("Samsung", StringComparison.OrdinalIgnoreCase) > -1) { _handle = NVMeSamsung.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeSamsung(); } } // Test Intel protocol. if (NVMeDrive == null && name.IndexOf("Intel", StringComparison.OrdinalIgnoreCase) > -1) { _handle = NVMeIntel.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeIntel(); } } // Test Intel raid protocol. if (NVMeDrive == null && name.IndexOf("Intel", StringComparison.OrdinalIgnoreCase) > -1) { _handle = NVMeIntelRst.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeIntelRst(); } } // Test Windows generic driver protocol. if (NVMeDrive == null) { _handle = NVMeWindows.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeWindows(); } } }
public static SafeHandle IdentifyDevice(StorageInfo storageInfo) { SafeHandle handle = Kernel32.OpenDevice(storageInfo.Scsi); if (handle == null || handle.IsInvalid) { return(null); } Kernel32.NVME_PASS_THROUGH_IOCTL passThrough = Kernel32.CreateStruct <Kernel32.NVME_PASS_THROUGH_IOCTL>(); passThrough.srb.HeaderLenght = (uint)Marshal.SizeOf <Kernel32.SRB_IO_CONTROL>(); passThrough.srb.Signature = Encoding.ASCII.GetBytes(Kernel32.IntelNVMeMiniPortSignature1); passThrough.srb.Timeout = 10; passThrough.srb.ControlCode = Kernel32.NVME_PASS_THROUGH_SRB_IO_CODE; passThrough.srb.ReturnCode = 0; passThrough.srb.Length = (uint)Marshal.SizeOf <Kernel32.NVME_PASS_THROUGH_IOCTL>() - (uint)Marshal.SizeOf <Kernel32.SRB_IO_CONTROL>(); passThrough.NVMeCmd = new uint[16]; passThrough.NVMeCmd[0] = 6; //identify passThrough.NVMeCmd[10] = 1; //return to host passThrough.Direction = Kernel32.NVME_DIRECTION.NVME_FROM_DEV_TO_HOST; passThrough.QueueId = 0; passThrough.DataBufferLen = (uint)passThrough.DataBuffer.Length; passThrough.MetaDataLen = 0; passThrough.ReturnBufferLen = (uint)Marshal.SizeOf <Kernel32.NVME_PASS_THROUGH_IOCTL>(); int length = Marshal.SizeOf <Kernel32.NVME_PASS_THROUGH_IOCTL>(); IntPtr buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(passThrough, buffer, false); bool validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); Marshal.FreeHGlobal(buffer); if (validTransfer) { } else { handle.Close(); handle = null; } return(handle); }
internal NVMeSmart(StorageInfo storageInfo) { _driveNumber = storageInfo.Index; NVMeDrive = null; //test samsung protocol if (NVMeDrive == null && storageInfo.Name.ToLower().Contains("samsung")) { _handle = NVMeSamsung.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeSamsung(); } } //test intel protocol if (NVMeDrive == null && storageInfo.Name.ToLower().Contains("intel")) { _handle = NVMeIntel.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeIntel(); } } //test intel raid protocol if (NVMeDrive == null && storageInfo.Name.ToLower().Contains("intel")) { _handle = NVMeIntelRst.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeIntelRst(); } } //test windows generic driver protocol if (NVMeDrive == null) { _handle = NVMeWindows.IdentifyDevice(storageInfo); if (_handle != null) { NVMeDrive = new NVMeWindows(); } } }
public static SafeHandle IdentifyDevice(StorageInfo storageInfo) { SafeHandle handle = Kernel32.OpenDevice(storageInfo.DeviceId); if (handle == null || handle.IsInvalid) { return(null); } Kernel32.STORAGE_QUERY_BUFFER nptwb = Kernel32.CreateStruct <Kernel32.STORAGE_QUERY_BUFFER>(); nptwb.ProtocolSpecific.ProtocolType = Kernel32.STORAGE_PROTOCOL_TYPE.ProtocolTypeNvme; nptwb.ProtocolSpecific.DataType = (uint)Kernel32.STORAGE_PROTOCOL_NVME_DATA_TYPE.NVMeDataTypeIdentify; nptwb.ProtocolSpecific.ProtocolDataRequestValue = (uint)Kernel32.STORAGE_PROTOCOL_NVME_PROTOCOL_DATA_REQUEST_VALUE.NVMeIdentifyCnsController; nptwb.ProtocolSpecific.ProtocolDataOffset = (uint)Marshal.SizeOf <Kernel32.STORAGE_PROTOCOL_SPECIFIC_DATA>(); nptwb.ProtocolSpecific.ProtocolDataLength = (uint)nptwb.Buffer.Length; nptwb.PropertyId = Kernel32.STORAGE_PROPERTY_ID.StorageAdapterProtocolSpecificProperty; nptwb.QueryType = Kernel32.STORAGE_QUERY_TYPE.PropertyStandardQuery; int length = Marshal.SizeOf <Kernel32.STORAGE_QUERY_BUFFER>(); IntPtr buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(nptwb, buffer, false); bool validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { Marshal.FreeHGlobal(buffer); } else { Marshal.FreeHGlobal(buffer); handle.Close(); handle = null; } return(handle); }
public SsdMicron(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings) : base(storageInfo, smart, name, firmwareRevision, "ssd", index, _smartAttributes, settings) { _temperature = new Sensor("Temperature", 0, false, SensorType.Temperature, this, new[] { new ParameterDescription("Offset [°C]", "Temperature offset of the thermal sensor.\n" + "Temperature = Value + Offset.", 0) }, settings); _writeAmplification = new Sensor("Write Amplification", 0, SensorType.Factor, this, settings); }
public static AbstractStorage CreateInstance(string deviceId, uint driveNumber, ulong diskSize, int scsiPort, ISettings settings) { StorageInfo info = WindowsStorage.GetStorageInfo(deviceId, driveNumber); if (info == null) { return(null); } info.DiskSize = diskSize; info.DeviceId = deviceId; info.Scsi = $@"\\.\SCSI{scsiPort}:"; if (info.Removable || info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeVirtual || info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeFileBackedVirtual) { return(null); } //fallback, when it is not possible to read out with the nvme implementation, //try it with the sata smart implementation if (info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeNvme) { AbstractStorage x = NVMeGeneric.CreateInstance(info, settings); if (x != null) { return(x); } } if (info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeAta || info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeSata || info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeNvme) { return(AtaStorage.CreateInstance(info, settings)); } return(StorageGeneric.CreateInstance(info, settings)); }
//windows generic driver nvme access public SafeHandle Identify(StorageInfo storageInfo) { return(IdentifyDevice(storageInfo)); }
private static NVMeInfo GetDeviceInfo(StorageInfo storageInfo) { var smart = new NVMeSmart(storageInfo); return(smart.GetInfo()); }
public static SafeHandle IdentifyDevice(StorageInfo storageInfo) { SafeHandle handle = Kernel32.OpenDevice(storageInfo.DeviceId); if (handle == null || handle.IsInvalid) { return(null); } Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS buffers = Kernel32.CreateStruct <Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS>(); buffers.Spt.Length = (ushort)Marshal.SizeOf <Kernel32.SCSI_PASS_THROUGH>(); buffers.Spt.PathId = 0; buffers.Spt.TargetId = 0; buffers.Spt.Lun = 0; buffers.Spt.SenseInfoLength = 24; buffers.Spt.DataTransferLength = (uint)buffers.DataBuf.Length; buffers.Spt.TimeOutValue = 2; buffers.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); buffers.Spt.SenseInfoOffset = (uint)Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); buffers.Spt.CdbLength = 16; buffers.Spt.Cdb[0] = 0xB5; // SECURITY PROTOCOL IN buffers.Spt.Cdb[1] = 0xFE; // Samsung Protocol buffers.Spt.Cdb[3] = 5; // Identify buffers.Spt.Cdb[8] = 0; // Transfer Length buffers.Spt.Cdb[9] = 0x40; buffers.Spt.DataIn = (byte)Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_OUT; buffers.DataBuf[0] = 1; int length = Marshal.SizeOf <Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS>(); IntPtr buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(buffers, buffer, false); bool validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); Marshal.FreeHGlobal(buffer); if (validTransfer) { //read data from samsung SSD buffers = Kernel32.CreateStruct <Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS>(); buffers.Spt.Length = (ushort)Marshal.SizeOf <Kernel32.SCSI_PASS_THROUGH>(); buffers.Spt.PathId = 0; buffers.Spt.TargetId = 0; buffers.Spt.Lun = 0; buffers.Spt.SenseInfoLength = 24; buffers.Spt.DataTransferLength = (uint)buffers.DataBuf.Length; buffers.Spt.TimeOutValue = 2; buffers.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); buffers.Spt.SenseInfoOffset = (uint)Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); buffers.Spt.CdbLength = 16; buffers.Spt.Cdb[0] = 0xA2; // SECURITY PROTOCOL IN buffers.Spt.Cdb[1] = 0xFE; // Samsung Protocol buffers.Spt.Cdb[3] = 5; // Identify buffers.Spt.Cdb[8] = 2; // Transfer Length buffers.Spt.Cdb[9] = 0; buffers.Spt.DataIn = (byte)Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_IN; length = Marshal.SizeOf <Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS>(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(buffers, buffer, false); validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { var result = Marshal.PtrToStructure <Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS>(buffer); if (result.DataBuf.Sum(x => (long)x) == 0) { handle.Close(); handle = null; } } else { handle.Close(); handle = null; } Marshal.FreeHGlobal(buffer); } return(handle); }
public SsdSandforce(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings) : base(storageInfo, smart, name, firmwareRevision, "ssd", index, _smartAttributes, settings) { _writeAmplification = new Sensor("Write Amplification", 1, SensorType.Factor, this, settings); }
internal static AbstractStorage CreateInstance(StorageInfo info, ISettings settings) { ISmart smart = new WindowsSmart(info.Index); string name = null; string firmwareRevision = null; Kernel32.SMART_ATTRIBUTE[] values = { }; if (smart.IsValid) { bool nameValid = smart.ReadNameAndFirmwareRevision(out name, out firmwareRevision); bool smartEnabled = smart.EnableSmart(); if (smartEnabled) { values = smart.ReadSmartData(); } if (!nameValid) { name = null; firmwareRevision = null; } } else { string[] logicalDrives = WindowsStorage.GetLogicalDrives(info.Index); if (logicalDrives == null || logicalDrives.Length == 0) { smart.Close(); return(null); } bool hasNonZeroSizeDrive = false; foreach (string logicalDrive in logicalDrives) { try { var di = new DriveInfo(logicalDrive); if (di.TotalSize > 0) { hasNonZeroSizeDrive = true; break; } } catch (ArgumentException) { } catch (IOException) { } catch (UnauthorizedAccessException) { } } if (!hasNonZeroSizeDrive) { smart.Close(); return(null); } } if (string.IsNullOrEmpty(name)) { name = string.IsNullOrEmpty(info.Name) ? "Generic Hard Disk" : info.Name; } if (string.IsNullOrEmpty(firmwareRevision)) { firmwareRevision = string.IsNullOrEmpty(info.Revision) ? "Unknown" : info.Revision; } foreach (Type type in HddTypes) { // get the array of name prefixes for the current type var namePrefixes = type.GetCustomAttributes(typeof(NamePrefixAttribute), true) as NamePrefixAttribute[]; // get the array of the required SMART attributes for the current type var requiredAttributes = type.GetCustomAttributes(typeof(RequireSmartAttribute), true) as RequireSmartAttribute[]; // check if all required attributes are present bool allRequiredAttributesFound = true; if (requiredAttributes != null) { foreach (var requireAttribute in requiredAttributes) { bool attributeFound = false; foreach (Kernel32.SMART_ATTRIBUTE value in values) { if (value.Id == requireAttribute.AttributeId) { attributeFound = true; break; } } if (!attributeFound) { allRequiredAttributesFound = false; break; } } } // if an attribute is missing, then try the next type if (!allRequiredAttributesFound) { continue; } // check if there is a matching name prefix for this type if (namePrefixes != null) { foreach (NamePrefixAttribute prefix in namePrefixes) { if (name.StartsWith(prefix.Prefix, StringComparison.InvariantCulture)) { var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; return(Activator.CreateInstance(type, flags, null, new object[] { info, smart, name, firmwareRevision, info.Index, settings }, null) as AtaStorage); } } } } // no matching type has been found smart.Close(); return(null); }
internal GenericHardDisk(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings) : base(storageInfo, smart, name, firmwareRevision, "hdd", index, _smartAttributes.AsIReadOnlyList(), settings) { }
//intel nvme access public SafeHandle Identify(StorageInfo storageInfo) { return(NVMeWindows.IdentifyDevice(storageInfo)); }
public SsdPlextor(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings) : base(storageInfo, smart, name, firmwareRevision, "ssd", index, _smartAttributes, settings) { }
internal static AbstractStorage CreateInstance(StorageInfo storageInfo, ISettings settings) { NVMeInfo nvmeInfo = GetDeviceInfo(storageInfo); return(nvmeInfo == null ? null : new NVMeGeneric(storageInfo, nvmeInfo, storageInfo.Index, settings)); }
private StorageGeneric(StorageInfo storageInfo, string name, string firmwareRevision, int index, ISettings settings) : base(storageInfo, name, firmwareRevision, "hdd", index, settings) { CreateSensors(); }