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