Beispiel #1
0
        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();
        }
Beispiel #2
0
        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();
                }
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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();
                }
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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());
        }
Beispiel #11
0
        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);
 }
Beispiel #13
0
        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);
        }
Beispiel #14
0
 internal GenericHardDisk(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings)
     : base(storageInfo, smart, name, firmwareRevision, "hdd", index, _smartAttributes.AsIReadOnlyList(), settings)
 {
 }
Beispiel #15
0
        //intel nvme access

        public SafeHandle Identify(StorageInfo storageInfo)
        {
            return(NVMeWindows.IdentifyDevice(storageInfo));
        }
Beispiel #16
0
 public SsdPlextor(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings)
     : base(storageInfo, smart, name, firmwareRevision, "ssd", index, _smartAttributes, settings)
 {
 }
Beispiel #17
0
        internal static AbstractStorage CreateInstance(StorageInfo storageInfo, ISettings settings)
        {
            NVMeInfo nvmeInfo = GetDeviceInfo(storageInfo);

            return(nvmeInfo == null ? null : new NVMeGeneric(storageInfo, nvmeInfo, storageInfo.Index, settings));
        }
Beispiel #18
0
 private StorageGeneric(StorageInfo storageInfo, string name, string firmwareRevision, int index, ISettings settings)
     : base(storageInfo, name, firmwareRevision, "hdd", index, settings)
 {
     CreateSensors();
 }