namespace Microsoft.VSDesigner.WMI {
using System;
using System.ComponentModel;
//using System.Core;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Management;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Net;
using System.Resources;
internal class WmiHelper
{
const UInt16 DMTF_DATETIME_STR_LENGTH = 25;
const UInt16 DMTF_DATETIME_INTERVAL_STR_LENGTH = 25;
public static bool UseFriendlyNames = true;
private static SortedList classesWithIcons = new SortedList(100);
public readonly static Image defaultClassIcon = (Image)new Bitmap(typeof(WMIClassesNode), "class.bmp");
public readonly static Image defaultInstanceIcon = (Image)new Bitmap(typeof(WMIClassesNode), "inst.bmp");
///
/// Property is not writeable only if "read" qualifier is present and its value is "true"
/// Also, for dynamic classes, absence of "write" qualifier means that the property is read-only.
///
///
///
static public bool IsPropertyWriteable(ManagementObject obj, Property prop)
{
//collect all the info:
bool isDynamic = CheckObjectBoolQualifier(obj, "dynamic");
bool hasWrite = CheckPropertyQualifierExistence(prop, "write");
bool writeValue = CheckPropertyBoolQualifier (prop, "write");
bool hasRead = CheckPropertyQualifierExistence(prop, "read");
bool readValue = CheckPropertyBoolQualifier (prop, "read");
if ((!isDynamic && !hasWrite && !hasRead)||
(!isDynamic && hasWrite && writeValue)||
(isDynamic && hasWrite && writeValue))
{
return true;
}
return false;
}
///
/// Converts DMTF datetime property value to System.DateTime
///
///
static public DateTime ToDateTime (String dmtf)
{
try
{
//set the defaults:
Int32 year = DateTime.Now.Year;
Int32 month = 1;
Int32 day = 1;
Int32 hour = 0;
Int32 minute = 0;
Int32 second = 0;
Int32 millisec = 0;
String str = dmtf;
if (str == String.Empty ||
str.Length != DMTF_DATETIME_STR_LENGTH )
//|| str.IndexOf("*") >= 0 )
{
return DateTime.MinValue;
}
string strYear = str.Substring(0, 4);
if (strYear != "****")
{
year = Int32.Parse (strYear);
}
string strMonth = str.Substring(4, 2);
if (strMonth != "**")
{
month = Int32.Parse(strMonth);
}
string strDay = str.Substring(6, 2);
if (strDay != "**")
{
day = Int32.Parse(strDay);
}
string strHour = str.Substring(8, 2);
if (strHour != "**")
{
hour = Int32.Parse(strHour);
}
string strMinute = str.Substring(10, 2);
if (strMinute != "**")
{
minute = Int32.Parse(strMinute);
}
string strSecond = str.Substring(12, 2);
if (strSecond != "**")
{
second = Int32.Parse(strSecond);
}
//note: approximation here: DMTF actually stores microseconds
string strMillisec = str.Substring(15, 3);
if (strMillisec != "***")
{
millisec = Int32.Parse(strMillisec);
}
DateTime ret = new DateTime(year, month, day, hour, minute, second, millisec);
return ret;
}
catch(Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
throw (e);
}
}
static public String ToDMTFTime (DateTime wfcTime)
{
String dmtf = string.Empty;
dmtf += wfcTime.Year.ToString();
dmtf += wfcTime.Month.ToString().PadLeft(2, '0');
dmtf += wfcTime.Day.ToString().PadLeft(2, '0');
dmtf += wfcTime.Hour.ToString().PadLeft(2, '0');
dmtf += wfcTime.Minute.ToString().PadLeft(2, '0');
dmtf += wfcTime.Second.ToString().PadLeft(2, '0');
dmtf += ".";
dmtf += wfcTime.Millisecond.ToString().PadLeft(3, '0');
dmtf += "000"; //this is to compensate for lack of microseconds in DateTime
TimeZone curZone = TimeZone.CurrentTimeZone;
long tickOffset = curZone.GetUTCOffset(wfcTime);
if (tickOffset >= 0)
{
dmtf += "+";
dmtf += (tickOffset/60000).ToString();
}
else
{
dmtf += "-";
dmtf += (tickOffset/60000).ToString().Substring(1, 3);
}
return dmtf;
}
static public bool IsValueMap (Property prop)
{
try
{
QualifierCollection.QualifierEnumerator enumQuals = prop.Qualifiers.GetEnumerator();
while (enumQuals.MoveNext())
{
Qualifier qual = enumQuals.Current;
if (qual.Name == "Values")
{
return true;
}
}
return false;
}
catch (Exception )
{
return false;
}
}
static public String GetPropertyDescription (String propName,
ManagementObject curObj,
string connectAs,
string pw)
{
try
{
if (curObj == null)
{
throw new ArgumentNullException("curObj");
}
Property verboseProp = null;
if (!curObj.Path.IsClass)
{
ManagementObject classObj = WmiHelper.GetClassObject(curObj, connectAs, pw);
verboseProp = classObj.Properties[propName];
}
else
{
verboseProp = curObj.Properties[propName];
}
string descr = string.Empty;
Qualifier descrQual = verboseProp.Qualifiers["Description"];
descr = descrQual.Value.ToString();
return descr;
}
catch (Exception )
{
return "";
}
}
static public String GetClassDescription (ManagementObject obj,
string connectAs,
string pw)
{
try
{
ManagementObject verboseObj = obj;
if (!obj.Path.IsClass)
{
verboseObj = WmiHelper.GetClassObject(obj, connectAs, pw);
}
Qualifier descrQual = verboseObj.Qualifiers["Description"];
return (descrQual.Value.ToString());
}
catch (Exception )
{
return "";
}
}
static public String GetMethodDescription (String methName,
ManagementObject curObj,
string connectAs,
string pw)
{
try
{
Qualifier descrQual = null;
Method verboseMeth = null;
if (!curObj.Path.IsClass)
{
ManagementClass classObj = WmiHelper.GetClassObject(curObj, connectAs, pw);
verboseMeth = classObj.Methods[methName];
}
else
{
verboseMeth = ((ManagementClass)curObj).Methods[methName];
}
descrQual = verboseMeth.Qualifiers["Description"];
return (descrQual.Value.ToString());
}
catch (Exception)
{
//2880: removed message here
return "";
}
}
public static ManagementClass GetClassObject (ManagementObject objIn,
string user,
string pw)
{
if (objIn == null)
{
throw new ArgumentException();
}
try
{
ManagementPath path = objIn.Path;
if (path.IsClass)
{
return (ManagementClass)objIn;
}
ManagementPath classPath = new ManagementPath(path.NamespacePath + ":" + path.ClassName);
ObjectGetOptions options = new ObjectGetOptions(null, true);
ConnectionOptions connectOpts = new ConnectionOptions(
"", //locale
user, //username
pw, //password
"", //authority
ImpersonationLevel.Impersonate,
AuthenticationLevel.Connect,
true, //enablePrivileges
null //context
);
ManagementScope scope = (path.Server == WmiHelper.DNS2UNC(Dns.GetHostName())) ?
new ManagementScope(path.NamespacePath) :
new ManagementScope(path.NamespacePath, connectOpts);
ManagementClass classObj = new ManagementClass(scope,
classPath,
options);
return classObj;
}
catch (Exception)
{
return null;
}
}
public static ManagementObject GetClassObject (string server,
string ns,
string className,
string user,
string pw)
{
if (ns == string.Empty || className == string.Empty)
{
throw new ArgumentException();
}
try
{
ManagementPath classPath = new ManagementPath(WmiHelper.MakeClassPath(server, ns, className));
ObjectGetOptions options = new ObjectGetOptions(null, true);
ConnectionOptions connectOpts = new ConnectionOptions(
"", //locale
user, //username
pw, //password
"", //authority
ImpersonationLevel.Impersonate,
AuthenticationLevel.Connect,
true, //enablePrivileges
null //context
);
ManagementScope scope = (server == WmiHelper.DNS2UNC(Dns.GetHostName())) ?
new ManagementScope(WmiHelper.MakeNSPath(server, ns)) :
new ManagementScope(WmiHelper.MakeNSPath(server, ns), connectOpts);
ManagementObject classObj = new ManagementObject(scope,
classPath,
options);
return classObj;
}
catch (Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
return null;
}
}
///
/// IsStaticMethod
///
///
static public bool IsStaticMethod (Method meth)
{
return CheckMethodBoolQualifier(meth, "Static");
}
///
/// IsImplementedMethod
///
///
static public bool IsImplementedMethod (Method meth)
{
return CheckMethodBoolQualifier(meth, "Implemented");
}
///
/// IsKeyProperty
///
///
static public bool IsKeyProperty (Property prop)
{
return CheckPropertyBoolQualifier(prop, "Key");
}
///
/// CheckMethodBoolQualifier
///
///
///
static private bool CheckMethodBoolQualifier(Method meth, String qualName)
{
try
{
QualifierCollection qualSet = meth.Qualifiers;
Qualifier qual = qualSet[qualName];
return (Convert.ToBoolean(qual.Value));
}
catch(Exception)
{
//NOTE that if the qualifier is not present, "Not found" will be returned
//Return false in this case
return false;
}
}
///
/// CheckPropertyBoolQualifier
///
///
///
static private bool CheckPropertyBoolQualifier(Property prop, String qualName)
{
try
{
QualifierCollection qualSet = prop.Qualifiers;
Qualifier qual = (Qualifier)qualSet[qualName];
return (Convert.ToBoolean(qual.Value));
}
catch(Exception)
{
//NOTE that if the qualifier is not present, "Not found" will be returned
//Return false in this case
return false;
}
}
///
/// CheckPropertyQualifierExistence
///
///
///
static private bool CheckPropertyQualifierExistence(Property prop, String qualName)
{
QualifierCollection qualSet = prop.Qualifiers;
try
{
Qualifier qual = qualSet[qualName];
return true; //previous statement didn't throw, so qualifier must be present
}
catch(Exception )
{
return false;
}
}
///
/// CheckObjectBoolQualifier
///
///
///
static private bool CheckObjectBoolQualifier(ManagementObject obj, String qualName)
{
try
{
QualifierCollection qualSet = obj.Qualifiers;
Qualifier qual = qualSet[qualName];
return (Convert.ToBoolean(qual.Value));
}
catch(Exception)
{
//NOTE that if the qualifier is not present, "Not found" will be returned
//Return false in this case
return false;
}
}
///
/// IsAbstract
///
///
static public bool IsAbstract (ManagementObject obj)
{
try
{
return CheckObjectBoolQualifier(obj, "abstract");
}
catch (Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
return false;
}
}
///
/// IsAssociation
///
///
static public bool IsAssociation (ManagementObject obj)
{
try
{
return CheckObjectBoolQualifier(obj, "association");
}
catch (Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
return false;
}
}
///
/// IsSystem
///
///
static public bool IsSystem (ManagementObject obj)
{
try
{
String NameOut = obj.Path.RelativePath;
if (NameOut.Length < 2)
{
return false;
}
return (NameOut.Substring(0, 2) == "__");
}
catch (Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
return false;
}
}
///
/// IsEvent
///
///
static public bool IsEvent (ManagementObject obj)
{
try
{
//handle __ExtrinsicEvent class separately, since it is not its own parent
if (obj.Path.RelativePath.ToString() == "__ExtrinsicEvent")
{
return true;
}
Object[] arParents = (Object[])obj.SystemProperties["__DERIVATION"].Value;
for (int i =0; i < arParents.Length; i++)
{
if (arParents[i].ToString() == "__ExtrinsicEvent")
{
return true;
}
}
return false;
}
catch (Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
return false;
}
}
///
/// Given an instance of an association object and a path to one of its
/// endpoints (the "source"), this method returns "path" to the other endpoint
/// (the "target").
///
///
///
static public String GetAssocTargetNamespacePath (ManagementObject assocInstance,
ManagementPath sourcePath)
{
try
{
PropertyCollection.PropertyEnumerator enumAssocProps = assocInstance.Properties.GetEnumerator();
while(enumAssocProps.MoveNext())
{
Property curProp = enumAssocProps.Current;
if (curProp.Type != CimType.Reference)
{
continue;
}
else
{
//get CimType property qualifier value
String refValue = curProp.Qualifiers["CimType"].Value.ToString();
//get rid of "ref:" prefix:
refValue = refValue.Substring(4);
//confirm that this is not the source
if ((String.Compare(refValue, sourcePath.ClassName, true) != 0) &&
(String.Compare(refValue, sourcePath.Path, true) != 0))
{
return refValue;
}
}
}
return String.Empty;
}
catch (Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
return String.Empty;
}
}
///
/// Given an instance of an association object and a path to one of its
/// endpoints (the "source"), this method returns the role of the other endpoint
/// (the "target") in this association.
///
///
///
static public String GetAssocTargetRole (ManagementObject assocInstance,
ManagementPath sourcePath)
{
try
{
PropertyCollection.PropertyEnumerator enumAssocProps = assocInstance.Properties.GetEnumerator();
while(enumAssocProps.MoveNext())
{
Property curProp = enumAssocProps.Current;
if (curProp.Type != CimType.Reference)
{
continue;
}
else
{
//confirm that this is not the source
if ((String.Compare(curProp.Value.ToString(),
sourcePath.Path, true )) != 0)
{
return curProp.Name;
}
}
}
return String.Empty;
}
catch (Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
return String.Empty;
}
}
public static Object GetTypedObjectFromString(CimType CimType, String strValue)
{
switch (CimType)
{
case (CimType.Boolean):
{
Boolean bValue = Boolean.Parse(strValue);
return bValue;
}
case (CimType.Char16):
{
Char charValue = Char.Parse(strValue);
return charValue;
}
case (CimType.DateTime):
{
return strValue;
}
case (CimType.Object):
{
//VT_UNKNOWN
//what's the format of strValue?
//thios wouldn't work until there is a way to invoke custom type converters and editors
return null;
}
case (CimType.Real32):
{
Single retValue = Single.Parse(strValue);
return retValue;
}
case (CimType.Real64):
{
Double retValue = Double.Parse(strValue);
return retValue;
}
case (CimType.Reference):
{
return strValue;
}
case (CimType.SInt16):
{
Int16 retValue = Int16.Parse(strValue);
return retValue;
}
case (CimType.SInt32):
{
Int32 retValue = Int32.Parse(strValue);
return retValue;
}
case (CimType.SInt64):
{
return strValue;
}
case (CimType.SInt8):
{
//NOTE that SInt8 get expanded to VT_I2 in automation layer
Int16 retValue = Int16.Parse(strValue);
return retValue;
}
case (CimType.String):
{
return strValue;
}
case (CimType.UInt16):
{
//NOTE that UInt16 gets expanded to VT_I4 in automation layer
Int32 retValue = Int32.Parse(strValue);
return retValue;
}
case (CimType.UInt32):
{
Int32 retValue = Int32.Parse(strValue);
return retValue;
}
case (CimType.UInt64):
{
return strValue;
}
case (CimType.UInt8):
{
Byte retVal = Byte.Parse(strValue);
return retVal;
}
default:
return strValue;
}
}
public static String GetDisplayName(ManagementObject obj,
string connectAs,
string pw)
{
try
{
ManagementObject verboseObj = obj;
if (!obj.Path.IsClass)
{
verboseObj = WmiHelper.GetClassObject(obj, connectAs, pw);
}
Qualifier dispName = verboseObj.Qualifiers["DisplayName"];
return (dispName.Value.ToString());
}
catch (Exception )
{
return String.Empty;
}
}
///
/// Converts DMTF datetime interval property value to System.TimeSpan
///
///
static public TimeSpan ToTimeSpan (string dmtf)
{
try
{
//set the defaults:
Int32 days = 0;
Int32 hours = 0;
Int32 minutes = 0;
Int32 seconds = 0;
Int32 millisecs = 0;
String str = dmtf;
if (str == String.Empty ||
str.Length != DMTF_DATETIME_INTERVAL_STR_LENGTH )
{
return TimeSpan.Zero;
}
string strDay = str.Substring(0, 8);
days = Int32.Parse(strDay);
string strHour = str.Substring(8, 2);
hours = Int32.Parse(strHour);
string strMinute = str.Substring(10, 2);
minutes = Int32.Parse(strMinute);
string strSecond = str.Substring(12, 2);
seconds = Int32.Parse(strSecond);
//dot in the 14th position
if (str.Substring(14, 1) != ".")
{
return TimeSpan.Zero;
}
//note: approximation here: DMTF actually stores microseconds
string strMillisec = str.Substring(15, 3);
if (strMillisec != "***")
{
millisecs = Int32.Parse(strMillisec);
}
TimeSpan ret = new TimeSpan(days, hours, minutes, seconds, millisecs);
return ret;
}
catch(Exception e)
{
MessageBox.Show(WMISys.GetString("WMISE_Exception", e.Message, e.StackTrace));
throw (e);
}
}
///
///
///
///
static public String ToDMTFInterval (TimeSpan wfcTimeSpan)
{
String dmtf = string.Empty;
dmtf += wfcTimeSpan.Days.ToString().PadLeft(8, '0');
dmtf += wfcTimeSpan.Hours.ToString().PadLeft(2, '0');
dmtf += wfcTimeSpan.Minutes.ToString().PadLeft(2, '0');
dmtf += wfcTimeSpan.Seconds.ToString().PadLeft(2, '0');
dmtf += ".";
dmtf += wfcTimeSpan.Milliseconds.ToString().PadLeft(3, '0');
dmtf += "000"; //this is to compensate for lack of microseconds in TimeSpan
dmtf +=":000";
return dmtf;
}
static public bool IsInterval (Property prop)
{
if (prop.Type != CimType.DateTime)
{
throw new ArgumentException();
}
try
{
string subtype = string.Empty;
Qualifier subtypeQual = prop.Qualifiers["Subtype"];
subtype = subtypeQual.Value.ToString();
if (subtype.ToUpper() == "INTERVAL")
{
return true;
}
return false;
}
catch (Exception )
{
return false;
}
}
///
/// Converts Dns name to UNC machine name, where
/// UNC Name - eg: zinap1.
/// Dns Name - eg: zinap1.ntdev.microsoft.com
///
static public string DNS2UNC (string Dns)
{
try
{
char[] separator = new char[] {'.'};
string [] parts = Dns.Split(separator);
return parts[0];
}
catch (Exception)
{
return string.Empty;
}
}
///
/// Returns true if classObj has non-abstract subclasses (with deep enumeration)
///
///
static public bool HasNonAbstractChildren (ManagementClass classObj)
{
GetSubclassesOptions opts = new GetSubclassesOptions(null, //context
TimeSpan.MaxValue, //timeout
50, //block size
false, //rewindable
true, //return immediately
false, //amended
true); //deep
ManagementObjectCollection subClasses = classObj.GetSubclasses(opts);
ManagementObjectCollection.ManagementObjectEnumerator childEnum = subClasses.GetEnumerator();
while (childEnum.MoveNext())
{
ManagementClass curChild = (ManagementClass)childEnum.Current;
if (!WmiHelper.IsAbstract(curChild))
{
return true;
}
}
return false;
}
public static string MakeClassPath (string server, string ns, string className)
{
if (ns == string.Empty)
{
throw new ArgumentException("ns");
}
if (className == string.Empty)
{
throw new ArgumentException("className");
}
if (server == string.Empty)
{
server = ".";
}
return "\\\\" + server + "\\" + ns + ":" + className;
}
public static string MakeNSPath (string server, string ns)
{
if (ns == string.Empty)
{
throw new ArgumentException("ns");
}
if (server == string.Empty)
{
server = ".";
}
return "\\\\" + server + "\\" + ns;
}
///
/// Given a class path, this returns the icon from the resource file
///
/// WMI Class path (with or without the server part, which would be ignored anyway)
/// True if requesting a class icon, false if requesting an instance icon
/// Class-specific icon (or default if anything goes wrong)
///
public static Image GetClassIconFromResource(string classPath, bool isClass, Type loadingType)
{
try
{
string underscoredPath = classPath;
//remove SERVER part, if any
int rootIndex = underscoredPath.ToLower().IndexOf("root");
if (rootIndex < 0)
{
throw new Exception();
}
underscoredPath = underscoredPath.Substring(rootIndex);
//replace all colons and backslashes by underscores
underscoredPath = underscoredPath.Replace("\\", "_");
underscoredPath = underscoredPath.Replace(":", "_");
underscoredPath +=".ico";
underscoredPath = underscoredPath.ToLower();
underscoredPath = underscoredPath;
if (classesWithIcons.Contains(underscoredPath))
{
return (Image)classesWithIcons[underscoredPath];
}
else
{
Image retIcon = (new Icon(loadingType, underscoredPath)).ToBitmap();
//Image retIcon = Bitmap.FromResource( ??? //TODO: try to eliminate conversion to bitmap: bug 3145
if (retIcon != null)
{
classesWithIcons.Add(underscoredPath, retIcon);
return retIcon;
}
else
throw new Exception();
}
}
catch (Exception )
{
//if anything goes wrong, return the default
if (isClass)
{
return defaultClassIcon;
}
else //an instance
{
return defaultInstanceIcon;
}
}
}
public static string[] GetOperators(CimType CimType)
{
ArrayList retArray = new ArrayList(10);
switch(CimType)
{
case(CimType.Boolean) :
{
retArray.Add ("=");
retArray.Add ("<>");
break;
}
case (CimType.Char16) :
case (CimType.DateTime) :
case (CimType.Real32) :
case (CimType.Real64) :
case (CimType.SInt16) :
case (CimType.SInt32 ):
case (CimType.SInt64) :
case (CimType.SInt8) :
case (CimType.UInt16 ):
case (CimType.UInt32) :
case (CimType.UInt64) :
case (CimType.UInt8 ) :
case (CimType.Reference) :
case (CimType.String) :
{
retArray.Add ("=");
retArray.Add ("<>");
retArray.Add (">");
retArray.Add ("<");
retArray.Add (">=");
retArray.Add ("<=");
break;
}
case (CimType.Object) :
{
retArray.Add("ISA");
break;
}
default:
break;
}
return (string[])retArray.ToArray(typeof(string));
}
}
}