Skip to content

Commit

Permalink
Add project files.
Browse files Browse the repository at this point in the history
  • Loading branch information
lkruger009 authored and lkruger009 committed Jun 19, 2017
1 parent 6272a1c commit e2f19e8
Show file tree
Hide file tree
Showing 14 changed files with 865 additions and 0 deletions.
28 changes: 28 additions & 0 deletions Smart.Net.sln
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
6 changes: 6 additions & 0 deletions Smart.Net/App.config
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>
39 changes: 39 additions & 0 deletions Smart.Net/Helper.cs
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;
}
}
}
83 changes: 83 additions & 0 deletions Smart.Net/Objects.cs
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>
{

}
}
175 changes: 175 additions & 0 deletions Smart.Net/Program.cs
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();

// print
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);
}
}
}
}
36 changes: 36 additions & 0 deletions Smart.Net/Properties/AssemblyInfo.cs
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")]
Loading

0 comments on commit e2f19e8

Please sign in to comment.