SchemaMapping.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Wmi / managed / System / Management / Instrumentation / SchemaMapping.cs / 1305376 / SchemaMapping.cs

                            //------------------------------------------------------------------------------ 
// 
//    Copyright (c) Microsoft Corporation. All Rights Reserved.
//    Information Contained Herein is Proprietary and Confidential.
//  
//-----------------------------------------------------------------------------
 
namespace System.Management.Instrumentation 
{
 	using System; 
	using System.Reflection;
	using System.Management;
	using System.Collections;
 
 	class SchemaMapping
	{ 
 		Type classType; 
 		ManagementClass newClass;
		string className; 
 		string classPath;
		string codeClassName;
		CodeWriter code = new CodeWriter();
 
		public Type ClassType { get { return classType; } }
 		public ManagementClass NewClass { get { return newClass; } } 
		public string ClassName { get { return className; } } 
 		public string ClassPath { get { return classPath; } }
 		public CodeWriter Code { get { return code; } } 
		public string CodeClassName { get {return codeClassName; } }

 		InstrumentationType instrumentationType;
		public InstrumentationType InstrumentationType { get { return instrumentationType; } } 

		static public void ThrowUnsupportedMember(MemberInfo mi) 
		{ 
 			ThrowUnsupportedMember(mi, null);
		} 
 		static public void ThrowUnsupportedMember(MemberInfo mi, Exception innerException)
 		{
			throw new ArgumentException(String.Format(RC.GetString("UNSUPPORTEDMEMBER_EXCEPT"), mi.Name), mi.Name, innerException);
 		} 
		public SchemaMapping(Type type, SchemaNaming naming, Hashtable mapTypeToConverterClassName)
		{ 
			codeClassName = (string)mapTypeToConverterClassName[type]; 
 			classType = type;
 
			bool hasGenericEmbeddedObject = false;

 			string baseClassName = ManagedNameAttribute.GetBaseClassName(type);
 			className = ManagedNameAttribute.GetMemberName(type); 
			instrumentationType = InstrumentationClassAttribute.GetAttribute(type).InstrumentationType;
 
 			classPath = naming.NamespaceName + ":" + className; 

			if(null == baseClassName) 
			{
				newClass = new ManagementClass(naming.NamespaceName, "", null);
 				newClass.SystemProperties ["__CLASS"].Value = className;
			} 
 			else
 			{ 
				ManagementClass baseClass = new ManagementClass(naming.NamespaceName + ":" + baseClassName); 
 				if(instrumentationType == InstrumentationType.Instance)
				{ 
					bool baseAbstract = false;
					try
 					{
						QualifierData o = baseClass.Qualifiers["abstract"]; 
 						if(o.Value is bool)
 							baseAbstract = (bool)o.Value; 
					} 
 					catch(ManagementException e)
					{ 
						if(e.ErrorCode != ManagementStatus.NotFound)
							throw;
 					}
					if(!baseAbstract) 
 						throw new Exception(RC.GetString("CLASSINST_EXCEPT"));
 
 				} 

				newClass = baseClass.Derive(className); 
 			}


			// Create the converter class 
			CodeWriter codeClass = code.AddChild("public class "+codeClassName+" : IWmiConverter");
 
			// Create code block for one line Members 
 			CodeWriter codeOneLineMembers = codeClass.AddChild(new CodeWriter());
			codeOneLineMembers.Line("static ManagementClass managementClass = new ManagementClass(@\"" + classPath + "\");"); 
 			codeOneLineMembers.Line("static IntPtr classWbemObjectIP;");
 			codeOneLineMembers.Line("static Guid iidIWbemObjectAccess = new Guid(\"49353C9A-516B-11D1-AEA6-00C04FB68820\");");
			codeOneLineMembers.Line("internal ManagementObject instance = managementClass.CreateInstance();");
 			codeOneLineMembers.Line("object reflectionInfoTempObj = null ; "); 
			codeOneLineMembers.Line("FieldInfo reflectionIWbemClassObjectField = null ; ");
			codeOneLineMembers.Line("IntPtr emptyWbemObject = IntPtr.Zero ; "); 
			codeOneLineMembers.Line("IntPtr originalObject = IntPtr.Zero ; "); 
 			codeOneLineMembers.Line("bool toWmiCalled = false ; ");
			 
 			//
 			// Reuters VSQFE#: 750	[marioh] see comments above
			// Used as a temporary pointer to the newly created instance that we create to avoid re-using the same
 			// object causing unbound memory usage in IWbemClassObject implementation. 
			codeOneLineMembers.Line("IntPtr theClone = IntPtr.Zero;");
			codeOneLineMembers.Line("public static ManagementObject emptyInstance = managementClass.CreateInstance();"); 
 
			//
 			codeOneLineMembers.Line("public IntPtr instWbemObjectAccessIP;"); 

			// Create static constructor to initialize handles
 			CodeWriter codeCCTOR = codeClass.AddChild("static "+codeClassName+"()");
 			codeCCTOR.Line("classWbemObjectIP = (IntPtr)managementClass;"); 
			codeCCTOR.Line("IntPtr wbemObjectAccessIP;");
 			codeCCTOR.Line("Marshal.QueryInterface(classWbemObjectIP, ref iidIWbemObjectAccess, out wbemObjectAccessIP);"); 
			codeCCTOR.Line("int cimType;"); 

			// Create constructor 
			CodeWriter codeCTOR = codeClass.AddChild("public "+codeClassName+"()");
 			codeCTOR.Line("IntPtr wbemObjectIP = (IntPtr)instance;");
       	       codeCTOR.Line("originalObject = (IntPtr)instance;");
			codeCTOR.Line("Marshal.QueryInterface(wbemObjectIP, ref iidIWbemObjectAccess, out instWbemObjectAccessIP);"); 

 			// 
 			// Reuters VSQFE#: 750	[marioh] 
			// In the CCTOR we set things up only once:
 			//  1. We get the IWbemClassObjectFreeThreaded object '_wbemObject' from the ManagementObject instance 
			//  2. We then get the actual IntPtr to the underlying WMI object
			//  3. Finally, the simple cast to IntPtr from the ManagementObject instance
			// These fields will be used later during the ToWMI call.
 			codeCTOR.Line ("FieldInfo tempField = instance.GetType().GetField ( \"_wbemObject\", BindingFlags.Instance | BindingFlags.NonPublic );" ); 
			codeCTOR.Line("if ( tempField == null )");
 			codeCTOR.Line("{"); 
 			codeCTOR.Line("   tempField = instance.GetType().GetField ( \"wbemObject\", BindingFlags.Instance | BindingFlags.NonPublic ) ;"); 
			codeCTOR.Line("}");
 
 			codeCTOR.Line ("reflectionInfoTempObj = tempField.GetValue (instance) ;");
			codeCTOR.Line("reflectionIWbemClassObjectField = reflectionInfoTempObj.GetType().GetField (\"pWbemClassObject\", BindingFlags.Instance | BindingFlags.NonPublic );");
			codeCTOR.Line("emptyWbemObject = (IntPtr) emptyInstance;");
 
			// Create destructor that will be called at process cleanup
 			CodeWriter codeDTOR = codeClass.AddChild("~"+codeClassName+"()"); 
			codeDTOR.AddChild("if(instWbemObjectAccessIP != IntPtr.Zero)").Line("Marshal.Release(instWbemObjectAccessIP);"); 
 			// [marioh] Make sure we release the initial instance so that we dont leak
 			codeDTOR.Line("if ( toWmiCalled == true )"); 
			codeDTOR.Line("{");
 			codeDTOR.Line("	Marshal.Release (originalObject);");
			codeDTOR.Line("}");
			 

			// Create method to convert from managed code to WMI 
 			CodeWriter codeToWMI = codeClass.AddChild("public void ToWMI(object obj)"); 

			// 
 			// Reuters VSQFE#: 750	[marioh] see comments above
 			// Ensure the release of the WbemObjectAccess interface pointer.
			codeToWMI.Line( "toWmiCalled = true ;" ) ;
 			codeToWMI.Line( "if(instWbemObjectAccessIP != IntPtr.Zero)" ) ; 
			codeToWMI.Line( "{" ) ;
			codeToWMI.Line("    Marshal.Release(instWbemObjectAccessIP);" ) ; 
			codeToWMI.Line("    instWbemObjectAccessIP = IntPtr.Zero;" ) ; 
 			codeToWMI.Line( "}" ) ;
 
			codeToWMI.Line( "if(theClone != IntPtr.Zero)" ) ;
 			codeToWMI.Line( "{" ) ;
 			codeToWMI.Line("    Marshal.Release(theClone);" ) ;
			codeToWMI.Line("    theClone = IntPtr.Zero;" ) ; 
 			codeToWMI.Line( "}" ) ;
 
			codeToWMI.Line( "IWOA.Clone_f(12, emptyWbemObject, out theClone) ;" ) ; 
			codeToWMI.Line( "Marshal.QueryInterface(theClone, ref iidIWbemObjectAccess, out instWbemObjectAccessIP) ;" ) ;
			codeToWMI.Line( "reflectionIWbemClassObjectField.SetValue ( reflectionInfoTempObj, theClone ) ;" ) ; 

 			codeToWMI.Line(String.Format("{0} instNET = ({0})obj;", type.FullName.Replace('+', '.'))); // bug#92918 - watch for nested classes

			// Explicit cast to IntPtr 
 			CodeWriter codeIntPtrCast = codeClass.AddChild("public static explicit operator IntPtr("+codeClassName+" obj)");
 			codeIntPtrCast.Line("return obj.instWbemObjectAccessIP;"); 
 
			// Add GetInstance
 			codeOneLineMembers.Line("public ManagementObject GetInstance() {return instance;}"); 

			PropertyDataCollection props = newClass.Properties;

			// type specific info 
			switch(instrumentationType)
 			{ 
				case InstrumentationType.Event: 
 					break;
 				case InstrumentationType.Instance: 
					props.Add("ProcessId", CimType.String, false);
 					props.Add("InstanceId", CimType.String, false);
					props["ProcessId"].Qualifiers.Add("key", true);
					props["InstanceId"].Qualifiers.Add("key", true); 
					newClass.Qualifiers.Add("dynamic", true, false, false, false, true);
 					newClass.Qualifiers.Add("provider", naming.DecoupledProviderInstanceName, false, false, false, true); 
					break; 
 				case InstrumentationType.Abstract:
 					newClass.Qualifiers.Add("abstract", true, false, false, false, true); 
					break;
 				default:
					break;
			} 
			
 			int propCount = 0; 
			bool needsNullObj = false; 
 			foreach(MemberInfo field in type.GetMembers())
 			{ 
				if(!(field is FieldInfo || field is PropertyInfo))
 					continue;

				if(field.GetCustomAttributes(typeof(IgnoreMemberAttribute), false).Length > 0) 
					continue;
 
				if(field is FieldInfo) 
 				{
					FieldInfo fi = field as FieldInfo; 

 					// We ignore statics
 					if(fi.IsStatic)
						ThrowUnsupportedMember(field); 
 				}
				else if (field is PropertyInfo) 
				{ 
					PropertyInfo pi = field as PropertyInfo;
 					// We must have a 'get' property accessor 
					if(!pi.CanRead)
 						ThrowUnsupportedMember(field);

 					// We ignore static properties 
					MethodInfo mi = pi.GetGetMethod();
 					if(null == mi || mi.IsStatic) 
						ThrowUnsupportedMember(field); 

					// We don't support parameters on properties 
					if(mi.GetParameters().Length > 0)
 						ThrowUnsupportedMember(field);
				}
 
 				String propName = ManagedNameAttribute.GetMemberName(field);
 
 
#if SUPPORTS_ALTERNATE_WMI_PROPERTY_TYPE
                Type t2 = ManagedTypeAttribute.GetManagedType(field); 
#else
 				Type t2;
				if(field is FieldInfo)
 					t2 = (field as FieldInfo).FieldType; 
				else
					t2 = (field as PropertyInfo).PropertyType; 
#endif 
				bool isArray = false;
 				if(t2.IsArray) 
				{
 					// We only support one dimensional arrays in this version
 					if(t2.GetArrayRank() != 1)
						ThrowUnsupportedMember(field); 

 					isArray = true; 
					t2 = t2.GetElementType(); 
				}
 
				string embeddedTypeName = null;
 				string embeddedConverterName = null;
				if(mapTypeToConverterClassName.Contains(t2))
 				{ 
 					embeddedConverterName = (string)mapTypeToConverterClassName[t2];
					embeddedTypeName = ManagedNameAttribute.GetMemberName(t2); 
 				} 

				bool isGenericEmbeddedObject = false; 
				if(t2 == typeof(object))
				{
 					isGenericEmbeddedObject = true;
					if(hasGenericEmbeddedObject == false) 
 					{
 						hasGenericEmbeddedObject = true; 
						// Add map 
 						codeOneLineMembers.Line("static Hashtable mapTypeToConverter = new Hashtable();");
						foreach(DictionaryEntry entry in mapTypeToConverterClassName) 
						{
							codeCCTOR.Line(String.Format("mapTypeToConverter[typeof({0})] = typeof({1});", ((Type)entry.Key).FullName.Replace('+', '.'), (string)entry.Value)); // bug#92918 - watch for nested classes
 						}
					} 

 				} 
 
 				string propFieldName = "prop_" + (propCount);
				string handleFieldName = "handle_" + (propCount++); 

 				// Add handle for field, which is static accross all instances
				codeOneLineMembers.Line("static int " + handleFieldName + ";");
				codeCCTOR.Line(String.Format("IWOA.GetPropertyHandle_f27(27, wbemObjectAccessIP, \"{0}\", out cimType, out {1});", propName, handleFieldName)); 

				// Add PropertyData for field, which is specific to each instance 
 				codeOneLineMembers.Line("PropertyData " + propFieldName + ";"); 
				codeCTOR.Line(String.Format("{0} = instance.Properties[\"{1}\"];", propFieldName, propName));
 				 
 				if(isGenericEmbeddedObject)
				{
 					CodeWriter codeNotNull = codeToWMI.AddChild(String.Format("if(instNET.{0} != null)", field.Name));
					CodeWriter codeElse = codeToWMI.AddChild("else"); 
					codeElse.Line(String.Format("{0}.Value = null;", propFieldName));
					if(isArray) 
 					{ 
						codeNotNull.Line(String.Format("int len = instNET.{0}.Length;", field.Name));
 						codeNotNull.Line("ManagementObject[] embeddedObjects = new ManagementObject[len];"); 
 						codeNotNull.Line("IWmiConverter[] embeddedConverters = new IWmiConverter[len];");

						CodeWriter codeForLoop = codeNotNull.AddChild("for(int i=0;i

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK