示例#1
0
        public override CollectedData OnAcquire()
        {
            bool            success = true;
            List <HardDisk> disks   = new List <HardDisk>();
            CollectedData   cd      = new CollectedData(Context, success);

            OnAcquireDelegate(
                dict =>
            {
                string serial_num = string.Empty;
                if (dict.TryGetValue("SerialNumber", out object o))
                {
                    serial_num = o.ToString().Trim();
                }

                if (string.IsNullOrEmpty(serial_num) == false)
                {
                    HardDisk d = new HardDisk()
                    {
                        DeviceID      = dict["DeviceID"]?.ToString().Trim(),
                        Model         = dict["Model"]?.ToString().Trim(),
                        PnpDeviceID   = dict["PNPDeviceID"]?.ToString().Trim(),
                        InterfaceType = dict["InterfaceType"]?.ToString().Trim(),
                        SerialNum     = serial_num
                    };
                    disks.Add(d);
                }
            });

            if (disks.Count > 0)
            {
                ListData <HardDisk> disks2 = new ListData <HardDisk>(Context);
                foreach (HardDisk disk in disks)
                {
                    try
                    {
                        // Figure out which drive letters are on this hard disk
                        ManagementScope scope     = WmiContext.GetManagementScope();
                        string          drive_pnp = disk.PnpDeviceID.Replace("\\", "\\\\");
                        string          queryStr  = string.Format("ASSOCIATORS OF {{Win32_DiskDrive.DeviceID='{0}'}} WHERE AssocClass = Win32_DiskDriveToDiskPartition", disk.DeviceID);
                        //Console.WriteLine(queryStr);
                        foreach (ManagementBaseObject partition in new ManagementObjectSearcher(scope, new ObjectQuery(queryStr)).Get())
                        {
                            queryStr = string.Format("ASSOCIATORS OF {{Win32_DiskPartition.DeviceID='{0}'}} WHERE AssocClass = Win32_LogicalDiskToPartition", partition["DeviceID"]);
                            //Console.WriteLine(queryStr);
                            foreach (ManagementBaseObject o in new ManagementObjectSearcher(scope, new ObjectQuery(queryStr)).Get())
                            {
                                string drive_letter = o["Name"].ToString().Trim().ToUpper();
                                if (disk.DriveLetters.Contains(drive_letter) == false)
                                {
                                    disk.DriveLetters.Add(drive_letter);
                                }
                            }
                        }

                        // See if the drive is predicting failure
                        scope    = WmiContext.GetManagementScope("WMI");
                        queryStr = string.Format("SELECT * FROM MSStorageDriver_FailurePredictStatus WHERE InstanceName LIKE \"%{0}%\"", drive_pnp);
                        //Console.WriteLine(queryStr);
                        foreach (ManagementBaseObject m in new ManagementObjectSearcher(scope, new ObjectQuery(queryStr)).Get())
                        {
                            object failure = m["PredictFailure"];
                            //Console.WriteLine("PredictFailure: " + failure.ToString() + "\n");
                            disk.FailureIsPredicted = (bool)failure;

                            //SMARTFailureRequest req = new SMARTFailureRequest("SMARTCollector");
                            //RequestBus.Instance.MakeRequest(req);
                            //if (req.IsHandled)
                            //    disk.FailureIsPredicted = req.FailureIsPredicted;
                        }

                        // Now get the SMART attributes
                        queryStr = string.Format("SELECT * FROM MSStorageDriver_FailurePredictData WHERE InstanceName LIKE \"%{0}%\"", drive_pnp);
                        //Console.WriteLine(queryStr);
                        foreach (ManagementBaseObject m in new ManagementObjectSearcher(scope, new ObjectQuery(queryStr)).Get())
                        {
                            Byte[] attributes = (Byte[])m.Properties["VendorSpecific"].Value;

                            //Console.WriteLine("Attributes length [A]: {0}", attributes.Length);

                            int num_attributes = attributes.Length / (int)ESmartField.NumSmartFields;
                            for (int i = 0; i < num_attributes; ++i)
                            {
                                try
                                {
                                    byte[] field = new byte[(int)ESmartField.NumSmartFields];
                                    Array.Copy(attributes, i * (int)ESmartField.NumSmartFields, field, 0, (int)ESmartField.NumSmartFields);

                                    ESmartAttribute attr = (ESmartAttribute)field[(int)ESmartField.Attribute];
                                    if (attr == ESmartAttribute.Invalid)
                                    {
                                        continue;
                                    }

                                    //int flags = bytes[i * 12 + 4]; // least significant status byte, +3 most significant byte, but not used so ignored.
                                    //                               //bool advisory = (flags & 0x1) == 0x0;
                                    //bool failureImminent = (flags & 0x1) == 0x1;
                                    //bool onlineDataCollection = (flags & 0x2) == 0x2;

                                    int value = field[(int)ESmartField.Value];
                                    //int worst = field[(int)ESmartField.Worst];
                                    //int vendordata = BitConverter.ToInt32(field, (int)ESmartField.VendorData1);

                                    SmartAttribute resource = new SmartAttribute(attr)
                                    {
                                        Value = value
                                    };
                                    disk.SmartAttributes.Add(resource);
                                }
                                catch (Exception ex)
                                {
                                    // given key does not exist in attribute collection (attribute not in the dictionary of attributes)
                                    Console.WriteLine(ex.Message);
                                }
                            }
                        }

                        disks2.Data.Add(disk);
                    }
                    catch (Exception ex)
                    {
                        cd.SetMessage(ex);
                        success = false;
                    }
                }

                cd.D.Add(disks2);
            }
            else
            {
                success = false;
            }

            cd.DataIsCollected = success;
            return(cd);
        }
示例#2
0
        private static int ReadAndDumpSmart(string path)
        {
            var error      = 0;
            var returnCode = SUCCESS;
            var ioctlFlag  = false;

            var smartAttributes    = new byte[516];
            var smartAttributesPtr = IntPtr.Zero;

            unsafe
            {
                fixed(byte *p = smartAttributes)
                smartAttributesPtr = (IntPtr)p;
            }

            Logger.Info("Trying to open \"{0}\" at disk layer...", path);
            var diskHandle =
                CreateFile(
                    path,
                    FileAccess.Read,
                    FileShare.ReadWrite,
                    IntPtr.Zero,
                    FileMode.Open,
                    0,
                    IntPtr.Zero
                    );

            error = Marshal.GetLastWin32Error();
            if (error != 0)
            {
                Logger.Error("Failed to open disk to read S.M.A.R.T. values: Error {0}", error);
                returnCode = ERROR;
                goto exit;
            }

            Logger.Info("Trying to read S.M.A.R.T. attributes...");
            ioctlFlag =
                DeviceIoControl(
                    diskHandle,
                    IOCTL_STORAGE_PREDICT_FAILURE,
                    IntPtr.Zero,
                    0,
                    smartAttributesPtr,
                    (uint)smartAttributes.Length,
                    out var dummy1,
                    IntPtr.Zero
                    );

            error = Marshal.GetLastWin32Error();
            if (error != 0)
            {
                Logger.Error("Failed to read S.M.A.R.T. values: Error {0}", error);
                returnCode = ERROR;
                goto exit;
            }

            diskHandle.Close();
            diskHandle.Dispose();
            diskHandle = null;

            Logger.Info("");

            var predictFailure = (BitConverter.ToInt32(smartAttributes, 0) != 0);

            if (predictFailure)
            {
                Logger.Warn("****************************************************");
                Logger.Warn("****************************************************");
                Logger.Warn("***                                              ***");
                Logger.Warn("***      IMMINENT  FAILURE  PREDICTED:  YES      ***");
                Logger.Warn("***                                              ***");
                Logger.Warn("****************************************************");
                Logger.Warn("****************************************************");
            }
            else
            {
                Logger.Info("Imminent failure predicted: No");
            }

            Logger.Info("");

            Logger.Info(" {1,-4}{0}{2,-40}{0}{3,-5}{0}{4,-5}{0}{5,-15}",
                        " | ", "ID", "Name", "Value", "Worst", "Data");
            Logger.Info("={1,-4}{0}{2,-40}{0}{3,-5}{0}{4,-5}{0}{5,-15}",
                        "===",
                        new string('=', 4), new string('=', 40), new string('=', 5),
                        new string('=', 5), new string('=', 15));

            for (int i = 0; i < 30; i++)
            {
                var offset = i * 12 + 6;

                var attributeId = smartAttributes[offset + 0];

                var attribute = SmartAttribute.GetAttribute(attributeId, HardDiskType.HDD);
                if (attribute == null)
                {
                    continue;
                }

                var value = smartAttributes[offset + 3];
                var worst = smartAttributes[offset + 4];

                var raw = new byte[8];
                Array.Copy(smartAttributes, offset + 5, raw, 0, 7);
                var data = BitConverter.ToInt64(raw, 0);

                Logger.Info(" 0x{1,-2:X2}{0}{2,-40}{0}{3,-5}{0}{4,-5}{0}0x{5,-15:X12}",
                            " | ", attributeId, attribute.Name, value, worst, data);
            }

exit:
            WaitForUserExit();
            return(returnCode);
        }