-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
lkruger009
authored and
lkruger009
committed
Jun 19, 2017
1 parent
6272a1c
commit e2f19e8
Showing
14 changed files
with
865 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 14 | ||
VisualStudioVersion = 14.0.25123.0 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Smart.Net", "Smart.Net\Smart.Net.csproj", "{6BD2604A-5FC9-4ED0-8C9A-563892FA2C9C}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Smart.Tests\Demo.csproj", "{E10C3C1E-0B13-4DA0-A398-4EEFA00A9834}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{6BD2604A-5FC9-4ED0-8C9A-563892FA2C9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{6BD2604A-5FC9-4ED0-8C9A-563892FA2C9C}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{6BD2604A-5FC9-4ED0-8C9A-563892FA2C9C}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{6BD2604A-5FC9-4ED0-8C9A-563892FA2C9C}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{E10C3C1E-0B13-4DA0-A398-4EEFA00A9834}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{E10C3C1E-0B13-4DA0-A398-4EEFA00A9834}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{E10C3C1E-0B13-4DA0-A398-4EEFA00A9834}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{E10C3C1E-0B13-4DA0-A398-4EEFA00A9834}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<configuration> | ||
<startup> | ||
|
||
<supportedRuntime version="v2.0.50727"/></startup> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace Smart.Net | ||
{ | ||
public sealed class Helper | ||
{ | ||
public static int ConvertStringHexToInt(string hex0x0) | ||
{ | ||
try | ||
{ | ||
int value = (int) new System.ComponentModel.Int32Converter().ConvertFromString(hex0x0); | ||
return value; | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new Exception($"Error converting hex value {hex0x0} to integer.", ex); | ||
} | ||
} | ||
|
||
public static SmartAttributeCollection GetSmartRegisters(string textRegisters) | ||
{ | ||
var collection = new SmartAttributeCollection(); | ||
|
||
var splitOnCRLF = Resource.SmartAttributes.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); | ||
foreach (var line in splitOnCRLF) | ||
{ | ||
var splitLineOnComma = line.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries); | ||
string register = splitLineOnComma[0].Trim(); | ||
string attributeName = splitLineOnComma[1].Trim(); | ||
|
||
collection.Add(new SmartAttribute (Helper.ConvertStringHexToInt(register), attributeName)); | ||
} | ||
|
||
return collection; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace Smart.Net | ||
{ | ||
|
||
#region Smart | ||
public sealed class SmartAttribute | ||
{ | ||
public SmartAttribute(int register, string attributeName) | ||
{ | ||
this.Register = register; | ||
this.Name = attributeName; | ||
} | ||
|
||
public int Register { get; set; } | ||
public string Name { get; set; } | ||
|
||
public int Current { get; set; } | ||
public int Worst { get; set; } | ||
public int Threshold { get; set; } | ||
public int Data { get; set; } | ||
public bool IsOK { get; set; } | ||
|
||
public bool HasData | ||
{ | ||
get | ||
{ | ||
if (Current == 0 && Worst == 0 && Threshold == 0 && Data == 0) | ||
return false; | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
public class SmartAttributeCollection :List<SmartAttribute> | ||
{ | ||
|
||
public SmartAttributeCollection() | ||
{ | ||
|
||
} | ||
|
||
public SmartAttribute GetAttribute(int registerID) | ||
{ | ||
foreach (var item in this) | ||
{ | ||
if (item.Register == registerID) | ||
return item; | ||
} | ||
|
||
return null; | ||
} | ||
} | ||
#endregion | ||
|
||
public class Drive | ||
{ | ||
public Drive() | ||
{ | ||
SmartAttributeAttributes = new SmartAttributeCollection(); | ||
DriveLetters = new List<string>(); | ||
} | ||
|
||
public int Index { get; set; } | ||
|
||
public string DeviceID { get; set; } | ||
public string PnpDeviceID { get; set; } | ||
|
||
public List<string> DriveLetters { get; set; } | ||
public bool IsOK { get; set; } | ||
public string Model { get; set; } | ||
public string Type { get; set; } | ||
public string Serial { get; set; } | ||
public SmartAttributeCollection SmartAttributeAttributes { get; set; } | ||
} | ||
|
||
public class DriveCollection : List<Drive> | ||
{ | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/* | ||
Copyright (c) 2017, Llewellyn Kruger | ||
All rights reserved. | ||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | ||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | ||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | ||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Management; | ||
|
||
namespace Smart.Net | ||
{ | ||
/// <summary> | ||
/// Tested against Crystal Disk Info 5.3.1 and HD Tune Pro 3.5 on 15 Feb 2013. | ||
/// Findings; I do not trust the individual smart register "OK" status reported back frm the drives. | ||
/// I have tested faulty drives and they return an OK status on nearly all applications except HD Tune. | ||
/// After further research I see HD Tune is checking specific attribute values against their thresholds | ||
/// and and making a determination of their own (which is good) for whether the disk is in good condition or not. | ||
/// I recommend whoever uses this code to do the same. For example --> | ||
/// "Reallocated sector count" - the general threshold is 36, but even if 1 sector is reallocated I want to know about it and it should be flagged. | ||
/// </summary> | ||
public class Program | ||
{ | ||
public static void Main() | ||
{ | ||
try | ||
{ | ||
//DriveCollection drives = new DriveCollection(); | ||
|
||
////foreach (ManagementObject device in new ManagementObjectSearcher(@"SELECT * FROM Win32_DiskDrive WHERE InterfaceType LIKE 'USB%'").Get()) | ||
//foreach (var device in new ManagementObjectSearcher(@"SELECT * FROM Win32_DiskDrive").Get()) | ||
//{ | ||
// #region Drive Info | ||
// Drive drive = new Drive | ||
// { | ||
// DeviceID = device.GetPropertyValue("DeviceID").ToString(), | ||
// PnpDeviceID = device.GetPropertyValue("PNPDeviceID").ToString(), | ||
// Model = device["Model"]?.ToString().Trim(), | ||
// Type = device["InterfaceType"]?.ToString().Trim(), | ||
// Serial = device["SerialNumber"]?.ToString().Trim() | ||
|
||
// }; | ||
// #endregion | ||
|
||
// #region Get drive letters | ||
// foreach (var partition in new ManagementObjectSearcher( | ||
// "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + device.Properties["DeviceID"].Value | ||
// + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get()) | ||
// { | ||
|
||
// foreach (var disk in new ManagementObjectSearcher( | ||
// "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" | ||
// + partition["DeviceID"] | ||
// + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get()) | ||
// { | ||
// drive.DriveLetters.Add(disk["Name"].ToString()); | ||
// } | ||
|
||
// } | ||
// #endregion | ||
|
||
// #region Overall Smart Status | ||
|
||
// ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\WMI"); | ||
// ObjectQuery query = new ObjectQuery(@"SELECT * FROM MSStorageDriver_FailurePredictStatus Where InstanceName like ""%" | ||
// + drive.PnpDeviceID.Replace("\\", "\\\\") + @"%"""); | ||
// ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); | ||
// ManagementObjectCollection queryCollection = searcher.Get(); | ||
// foreach (ManagementObject m in queryCollection) | ||
// { | ||
// drive.IsOK = (bool)m.Properties["PredictFailure"].Value == false; | ||
// } | ||
// #endregion | ||
|
||
// #region Smart Registers | ||
// drive.SmartAttributeAttributes.AddRange(Helper.GetSmartRegisters(Resource.SmartAttributes)); | ||
|
||
// searcher.Query = new ObjectQuery(@"Select * from MSStorageDriver_FailurePredictData Where InstanceName like ""%" | ||
// + drive.PnpDeviceID.Replace("\\", "\\\\") + @"%"""); | ||
// foreach (ManagementObject data in searcher.Get()) | ||
// { | ||
// Byte[] bytes = (Byte[]) data.Properties["VendorSpecific"].Value; | ||
// foreach (var attribute in drive.SmartAttributeAttributes) | ||
// { | ||
// try | ||
// { | ||
// int id = bytes[attribute.Register * 12 + 2]; | ||
|
||
// int flags = bytes[attribute.Register * 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 = bytes[attribute.Register * 12 + 5]; | ||
// int worst = bytes[attribute.Register * 12 + 6]; | ||
// int vendordata = BitConverter.ToInt32(bytes, attribute.Register * 12 + 7); | ||
// if (id == 0) continue; | ||
|
||
// attribute.Current = value; | ||
// attribute.Worst = worst; | ||
// attribute.Data = vendordata; | ||
// attribute.IsOK = failureImminent == false; | ||
|
||
// //Console.WriteLine("{0}\t {1}\t {2}\t {3}\t " + attribute.Data + " " + ((attribute.IsOK) ? "OK" : ""), attribute.Name, attribute.Current, attribute.Worst, attribute.Threshold); | ||
// } | ||
// catch (Exception ex) | ||
// { | ||
// Debug.WriteLine($"Error resolving attribute data [{attribute.Name}]."); | ||
// } | ||
// } | ||
// } | ||
|
||
// searcher.Query = new ObjectQuery(@"Select * from MSStorageDriver_FailurePredictThresholds Where InstanceName like ""%" | ||
// + drive.PnpDeviceID.Replace("\\", "\\\\") + @"%"""); | ||
// foreach (ManagementObject data in searcher.Get()) | ||
// { | ||
// Byte[] bytes = (Byte[])data.Properties["VendorSpecific"].Value; | ||
// for (int i = 0; i < 30; ++i) | ||
// { | ||
// try | ||
// { | ||
// int id = bytes[i * 12 + 2]; | ||
// int thresh = bytes[i * 12 + 3]; | ||
// if (id == 0) continue; | ||
|
||
// var attr = drive.SmartAttributeAttributes.GetAttribute(id); | ||
// attr.Threshold = thresh; | ||
|
||
// //Console.WriteLine("{0}\t {1}\t {2}\t {3}\t " + attr.Data + " " + ((attr.IsOK) ? "OK" : ""), attr.Name, attr.Current, attr.Worst, attr.Threshold); | ||
// } | ||
// catch | ||
// { | ||
// // given key does not exist in attribute collection (attribute not in the dictionary of attributes) | ||
// } | ||
// } | ||
// } | ||
// #endregion | ||
|
||
// drives.Add(drive); | ||
//} | ||
|
||
var drives = Smart.GetDrives(); | ||
|
||
foreach (var drive in drives) | ||
{ | ||
Console.WriteLine("-----------------------------------------------------"); | ||
Console.WriteLine(" DRIVE ({0}): " + drive.Serial + " - " + drive.Model + " - " + drive.Type, ((drive.IsOK) ? "OK" : "BAD")); | ||
Console.WriteLine("-----------------------------------------------------"); | ||
Console.WriteLine(""); | ||
|
||
Console.WriteLine("ID Current Worst Threshold Data Status"); | ||
foreach (var attr in drive.SmartAttributeAttributes) | ||
{ | ||
if (attr.HasData) | ||
Console.WriteLine("{0}\t {1}\t {2}\t {3}\t " + attr.Data + " " + ((attr.IsOK) ? "OK" : "BAD"), attr.Name, attr.Current, attr.Worst, attr.Threshold); | ||
} | ||
Console.WriteLine(); | ||
Console.WriteLine(); | ||
Console.WriteLine(); | ||
} | ||
|
||
Console.ReadLine(); | ||
} | ||
catch (ManagementException e) | ||
{ | ||
Console.WriteLine("An error occurred while querying for WMI data: " + e.Message); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
// General Information about an assembly is controlled through the following | ||
// set of attributes. Change these attribute values to modify the information | ||
// associated with an assembly. | ||
[assembly: AssemblyTitle("Smart.Net")] | ||
[assembly: AssemblyDescription("")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("KrugerTech")] | ||
[assembly: AssemblyProduct("Smart.Net")] | ||
[assembly: AssemblyCopyright("Copyright © KrugerTech 2017")] | ||
[assembly: AssemblyTrademark("")] | ||
[assembly: AssemblyCulture("")] | ||
|
||
// Setting ComVisible to false makes the types in this assembly not visible | ||
// to COM components. If you need to access a type in this assembly from | ||
// COM, set the ComVisible attribute to true on that type. | ||
[assembly: ComVisible(false)] | ||
|
||
// The following GUID is for the ID of the typelib if this project is exposed to COM | ||
[assembly: Guid("6bd2604a-5fc9-4ed0-8c9a-563892fa2c9c")] | ||
|
||
// Version information for an assembly consists of the following four values: | ||
// | ||
// Major Version | ||
// Minor Version | ||
// Build Number | ||
// Revision | ||
// | ||
// You can specify all the values or you can default the Build and Revision Numbers | ||
// by using the '*' as shown below: | ||
// [assembly: AssemblyVersion("1.0.*")] | ||
[assembly: AssemblyVersion("1.0.0.0")] | ||
[assembly: AssemblyFileVersion("1.0.0.0")] |
Oops, something went wrong.