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); }
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); }