EventSource.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 / EventSource.cs / 1305376 / EventSource.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
namespace System.Management.Instrumentation
{ 
    using System; 
    using System.Runtime.InteropServices;
    using System.Collections; 
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Security;
    using System.Globalization; 
    using System.Runtime.Versioning;
 
    class ComThreadingInfo 
    {
        public enum APTTYPE 
        {
            APTTYPE_CURRENT = -1,
            APTTYPE_STA = 0,
            APTTYPE_MTA = 1, 
            APTTYPE_NA  = 2,
            APTTYPE_MAINSTA = 3 
        } 

        public enum THDTYPE 
        {
            THDTYPE_BLOCKMESSAGES   = 0,
            THDTYPE_PROCESSMESSAGES = 1
        } 

        [ComImport] 
        [Guid("000001ce-0000-0000-C000-000000000046")] 
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IComThreadingInfo 
        {
            APTTYPE GetCurrentApartmentType();
            THDTYPE GetCurrentThreadType();
            Guid GetCurrentLogicalThreadId(); 
            void SetCurrentLogicalThreadId([In] Guid rguid);
        } 
 
        Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
 
        ComThreadingInfo()
        {
            IComThreadingInfo info = (IComThreadingInfo)CoGetObjectContext(ref IID_IUnknown);
 
            apartmentType  = info.GetCurrentApartmentType();
            threadType = info.GetCurrentThreadType(); 
            logicalThreadId = info.GetCurrentLogicalThreadId(); 
        }
 
        public static ComThreadingInfo Current
        {
            get
            { 
                return new ComThreadingInfo();
            } 
        } 

        public override string ToString() 
        {
            return String.Format("{{{0}}} - {1} - {2}", LogicalThreadId, ApartmentType, ThreadType);
        }
 
        APTTYPE apartmentType;
        THDTYPE threadType; 
        Guid logicalThreadId; 

        public APTTYPE ApartmentType { get { return apartmentType; } 
        }
        public THDTYPE ThreadType { get { return threadType; }
        }
        public Guid LogicalThreadId { get { return logicalThreadId; } 
        }
 
        [ResourceExposure( ResourceScope.None),DllImport("ole32.dll", PreserveSig = false)] 
        [return:MarshalAs(UnmanagedType.IUnknown)]
        static extern object CoGetObjectContext([In] ref Guid riid); 
    }

    sealed class EventSource : IWbemProviderInit, IWbemEventProvider, IWbemEventProviderQuerySink, IWbemEventProviderSecurity, IWbemServices_Old
    { 
        IWbemDecoupledRegistrar registrar = (IWbemDecoupledRegistrar)new WbemDecoupledRegistrar();
 
        static ArrayList eventSources = new ArrayList(); 

        InstrumentedAssembly instrumentedAssembly; 

        public EventSource(string namespaceName, string appName, InstrumentedAssembly instrumentedAssembly)
        {
            lock(eventSources) 
            {
                // This is a pathalogical case where the process is shutting down, but 
                // someone wants us to register us as a provider.  In this case, we ignore 
                // the request.  This would be problematic if the eventSources list has already
                // been enumerated and all other eventSources unregistered.  If we were allowed 
                // to register a new event source, it would never be unregistered
                if(shutdownInProgress != 0)
                    return;
 
                this.instrumentedAssembly = instrumentedAssembly;
             int hr = registrar.Register_(0, null, null, null, namespaceName, appName, this); 
 
                if(hr != 0)
                    Marshal.ThrowExceptionForHR(hr); 

                // If we've gotten here, we were successful with the Register call
                eventSources.Add(this);
            } 
        }
 
#if OldShutdown 
        ~EventSource()
        { 
            // Kill worker thread
            if(lengthFromSTA != -1)
            {
                alive = false; 
                SetEvent(hDoIndicate);
//                doIndicate.Set(); 
            } 

            registrar.UnRegister_(); 
        }
#endif

        ~EventSource() 
        {
            // 
 

 



 

 
            UnRegister(); 
        }
 
        void UnRegister()
        {
            lock(this)
            { 
                // Only unregister one time
                if(registrar == null) 
                    return; 

                // Kill worker thread 
                if(workerThreadInitialized == true)
                {
                    alive = false;
                    doIndicate.Set(); // SetEvent(hDoIndicate); 
                    GC.KeepAlive(this);
                    workerThreadInitialized = false; 
                } 
                registrar.UnRegister_();
                registrar = null; 
            }
        }

        static int shutdownInProgress = 0; 
        static ReaderWriterLock preventShutdownLock = new ReaderWriterLock();
        static void ProcessExit(object o, EventArgs args) 
        { 
            // We can be called multiple times, but only one time will we
            // try to unregister all the event sources 
            if(shutdownInProgress != 0)
                return;

            // Notify anyone interested that a shutdown as been initiated 
            Interlocked.Increment(ref shutdownInProgress);
 
            try 
            {
                // Wait for anyone currently in a DCOM callback to finish 
                preventShutdownLock.AcquireWriterLock(-1);

                // Unregister all existing event sources
                lock(eventSources) 
                {
                    foreach(EventSource eventSource in eventSources) 
                        eventSource.UnRegister(); 
                }
            } 
            finally
            {
                // Let any straglers call start their calls
                preventShutdownLock.ReleaseWriterLock(); 
                Thread.Sleep(50);
 
                // Wait for any stragler that started 
                preventShutdownLock.AcquireWriterLock(-1);
                preventShutdownLock.ReleaseWriterLock(); 
            }
        }
        static EventSource()
        { 
            // We'll register for both ProcessExit and DomainUnload.  It is OK
            // if both are called, but bad if neither are called.  See comments 
            // in ~EventSource(); 
            AppDomain.CurrentDomain.ProcessExit += new EventHandler(ProcessExit);
            AppDomain.CurrentDomain.DomainUnload += new EventHandler(ProcessExit); 
        }

        IWbemServices pNamespaceNA = null;
        IWbemObjectSink pSinkNA = null; 
        IWbemServices pNamespaceMTA = null;
        IWbemObjectSink pSinkMTA = null; 
 
        private class MTARequest
        { 
            public AutoResetEvent doneIndicate = new AutoResetEvent(false);
            public Exception exception = null;
            public int lengthFromSTA = -1;
            public IntPtr[] objectsFromSTA; 
            public MTARequest(int length, IntPtr[] objects)
            { 
                this.lengthFromSTA = length; 
                this.objectsFromSTA = objects;
            } 
        }

        ArrayList reqList = new ArrayList(3);
        object critSec = new object(); 

        AutoResetEvent doIndicate = new AutoResetEvent(false); 
 

        bool workerThreadInitialized = false; 
        /*
        [DllImport("kernel32")] static extern IntPtr CreateEvent(IntPtr pSecurity, int manual, int initial, IntPtr name);
        [SuppressUnmanagedCodeSecurity, DllImport("kernel32")] static extern int SetEvent(IntPtr handle);
        [SuppressUnmanagedCodeSecurity, DllImport("kernel32")] static extern int WaitForSingleObject(IntPtr handle, int timeout); 
        IntPtr hDoIndicate = CreateEvent(IntPtr.Zero, 0, 0, IntPtr.Zero);
        IntPtr hDoneIndicate = CreateEvent(IntPtr.Zero, 0, 0, IntPtr.Zero); 
        */ 

        // Worker thread for each EventSource 



        // 
        // Ensure we are able to trap exceptions from worker thread.
        // Called from IndicateEvents which in turn is protected from 
        // concurrent access. 
        //
 

        public void MTAWorkerThread2()
        {
            while(true) 
            {
                doIndicate.WaitOne(); //WaitForSingleObject(hDoIndicate, -1); 
                if(alive == false) 
                {
                    break; 
                }
                 // get requests from the request queue. Since two Set within short time on evtGo can wake this thread only once
                // workerthread should check until we empty all the results. Even if we consume the request that is not set,
                // workerthread will wake up one more time unnecessarily and do nothing 
                while(true)
                { 
                    MTARequest reqToProcess = null; 
                    lock (critSec)
                    { 
                        if (reqList.Count > 0)
                        {
                            reqToProcess = (MTARequest)reqList[0];
                            reqList.RemoveAt(0); 
                        }
                        else 
                        { 
                            break;  // break the inner while true
                        } 
                    }
                    try
                    {
                        if (pSinkMTA != null) 
                        {
                            int hresult = pSinkMTA.Indicate_(reqToProcess.lengthFromSTA, reqToProcess.objectsFromSTA); 
                            if (hresult < 0) 
                            {
                                if ((hresult & 0xfffff000) == 0x80041000) 
                                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult);
                                else
                                    Marshal.ThrowExceptionForHR(hresult);
                            } 
                        }
                    } 
                    catch(Exception e) 
                    {
                        reqToProcess.exception = e; 
                    }
                    finally
                    {
                        reqToProcess.doneIndicate.Set(); //SetEvent(hDoneIndicate); 
                        GC.KeepAlive(this);
                    } 
                } 
            }
        } 


        bool alive = true;
 
        public void IndicateEvents(int length, IntPtr[] objects)
        { 
            if (pSinkMTA == null) 
                return;
            // 
            // Checking for MTA is not enough.  We need to make sure we are not in a COM+ Context
            //
            if (MTAHelper.IsNoContextMTA())
            { 
                // Sink lives in MTA
                int hresult = pSinkMTA.Indicate_(length, objects); 
                if (hresult < 0) 
                {
                    if ((hresult & 0xfffff000) == 0x80041000) 
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult);
                    else
                        Marshal.ThrowExceptionForHR(hresult);
                } 
            }
            else 
            { 
                MTARequest myReq = new MTARequest(length,objects);
                int ndx; 
                lock(critSec)
                {
                    // Do it from worker thread
                    if (workerThreadInitialized == false) 
                    {
                        // We've never created worker thread 
                        Thread thread = new Thread(new ThreadStart(MTAWorkerThread2)); 
                        thread.IsBackground = true;
                        thread.SetApartmentState(ApartmentState.MTA); 
                        thread.Start();
                        workerThreadInitialized = true;
                    }
                    ndx = reqList.Add(myReq); 
                    if( doIndicate.Set() == false ) //SetEvent(hDoIndicate);
                    { 
                        reqList.RemoveAt(ndx); 
                        throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
                    } 
                }
                myReq.doneIndicate.WaitOne(); //WaitForSingleObject(hDoneIndicate, -1);
                if (myReq.exception != null)
                { 
                    throw myReq.exception;
                } 
            } 
            GC.KeepAlive(this);
        } 

        void RelocateSinkRCWToMTA()
        {
            ThreadDispatch disp = new ThreadDispatch(new ThreadDispatch.ThreadWorkerMethodWithParam(RelocateSinkRCWToMTA_ThreadFuncion)); 
            disp.Parameter = this;
            disp.Start(); 
        } 

        void RelocateSinkRCWToMTA_ThreadFuncion( object param ) 
        {
            EventSource threadParam = (EventSource) param;
            threadParam.pSinkMTA = (IWbemObjectSink)RelocateRCWToCurrentApartment(threadParam.pSinkNA);
            threadParam.pSinkNA = null; 
        }
 
        void RelocateNamespaceRCWToMTA() 
        {
            ThreadDispatch disp = new ThreadDispatch(new ThreadDispatch.ThreadWorkerMethodWithParam(RelocateNamespaceRCWToMTA_ThreadFuncion)); 
            disp.Parameter = this;
            disp.Start();
        }
 
        void RelocateNamespaceRCWToMTA_ThreadFuncion(object param)
        { 
            EventSource threadParam = (EventSource) param ; 
            threadParam.pNamespaceMTA = (IWbemServices)RelocateRCWToCurrentApartment(threadParam.pNamespaceNA);
            threadParam.pNamespaceNA = null; 
        }

        static object RelocateRCWToCurrentApartment(object comObject)
        { 
            if(null == comObject)
                return null; 
 
            IntPtr pUnk = Marshal.GetIUnknownForObject(comObject);
            int references = Marshal.ReleaseComObject(comObject); 
            if (references != 0)
                throw new Exception();

            comObject = Marshal.GetObjectForIUnknown(pUnk); 
            Marshal.Release(pUnk);
            return comObject; 
        } 

        public bool Any() 
        {
            return (null == pSinkMTA) || (mapQueryIdToQuery.Count == 0);
        }
 
        Hashtable mapQueryIdToQuery = new Hashtable();
 
        // IWbemProviderInit 

        int IWbemProviderInit.Initialize_( 
            [In][MarshalAs(UnmanagedType.LPWStr)]  string   wszUser,
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.LPWStr)]  string   wszNamespace,
            [In][MarshalAs(UnmanagedType.LPWStr)]  string   wszLocale, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemServices   pNamespace,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemProviderInitSink   pInitSink) 
        {
            this.pNamespaceNA = pNamespace; 
            RelocateNamespaceRCWToMTA();

            this.pSinkNA = null;
            this.pSinkMTA = null; 

            lock(mapQueryIdToQuery) 
            { 
                mapQueryIdToQuery.Clear();
            } 

            pInitSink.SetStatus_((int)tag_WBEM_EXTRA_RETURN_CODES.WBEM_S_INITIALIZED, 0);
            Marshal.ReleaseComObject(pInitSink);
 
            return 0;
        } 
 
        // IWbemEventProvider
        int IWbemEventProvider.ProvideEvents_( 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pSink,
            [In] Int32 lFlags)
        {
            this.pSinkNA = pSink; 
            RelocateSinkRCWToMTA();
 
            // 

            return 0; 
        }

        // IWbemEventProviderQuerySink
 
        int IWbemEventProviderQuerySink.NewQuery_(
            [In] UInt32 dwId, 
            [In][MarshalAs(UnmanagedType.LPWStr)]  string   wszQueryLanguage, 
            [In][MarshalAs(UnmanagedType.LPWStr)]  string   wszQuery)
        { 
            lock(mapQueryIdToQuery)
            {
                // HACK: for bug where CancelQuery is not called correctly
                // and we get a NewQuery where dwId is already in our hashtable 
                if(mapQueryIdToQuery.ContainsKey(dwId))
                    mapQueryIdToQuery.Remove(dwId); 
                mapQueryIdToQuery.Add(dwId, wszQuery); 
            }
            return 0; 
        }

        int IWbemEventProviderQuerySink.CancelQuery_([In] UInt32 dwId)
        { 
            lock(mapQueryIdToQuery)
            { 
                mapQueryIdToQuery.Remove(dwId); 
            }
            return 0; 
        }

        // IWbemEventProviderSecurity
        int IWbemEventProviderSecurity.AccessCheck_( 
            [In][MarshalAs(UnmanagedType.LPWStr)]  string   wszQueryLanguage,
            [In][MarshalAs(UnmanagedType.LPWStr)]  string   wszQuery, 
            [In] Int32 lSidLength, 
            [In] ref Byte pSid)
        { 
            return 0;
        }

        // IWbemServices 
        int IWbemServices_Old.OpenNamespace_([In][MarshalAs(UnmanagedType.BStr)]  string   strNamespace,
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [In][Out][MarshalAs(UnmanagedType.Interface)]  ref IWbemServices   ppWorkingNamespace,
            [In] IntPtr ppCallResult) 
        {
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        }
 
        int IWbemServices_Old.CancelAsyncCall_([In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pSink)
        { 
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED); 
        }
 
        int IWbemServices_Old.QueryObjectSink_([In] Int32 lFlags,
            [Out][MarshalAs(UnmanagedType.Interface)]  out IWbemObjectSink   ppResponseHandler)
        {
            ppResponseHandler = null; 
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        } 
 
        int IWbemServices_Old.GetObject_([In][MarshalAs(UnmanagedType.BStr)]  string   strObjectPath,
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [In][Out][MarshalAs(UnmanagedType.Interface)]  ref IWbemClassObject_DoNotMarshal   ppObject,
            [In] IntPtr ppCallResult)
        { 
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        } 
 
        int IWbemServices_Old.GetObjectAsync_([In][MarshalAs(UnmanagedType.BStr)]  string   strObjectPath,
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pResponseHandler)
        {
//            pResponseHandler.SetStatus(0, (int)tag_WBEMSTATUS.WBEM_E_NOT_FOUND, null, null); 
//            Marshal.ReleaseComObject(pResponseHandler);
//            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_FOUND); 
 
            Match match = Regex.Match(strObjectPath.ToLower(CultureInfo.InvariantCulture), "(.*?)\\.instanceid=\"(.*?)\",processid=\"(.*?)\"");
            if(match.Success==false) 
            {
                pResponseHandler.SetStatus_(0, (int)tag_WBEMSTATUS.WBEM_E_NOT_FOUND, null, IntPtr.Zero);
                Marshal.ReleaseComObject(pResponseHandler);
                return (int)(tag_WBEMSTATUS.WBEM_E_NOT_FOUND); 
            }
 
            string className = match.Groups[1].Value; 
            string instanceId = match.Groups[2].Value;
            string processId = match.Groups[3].Value; 


            if(Instrumentation.ProcessIdentity != processId)
            { 
                pResponseHandler.SetStatus_(0, (int)tag_WBEMSTATUS.WBEM_E_NOT_FOUND, null, IntPtr.Zero);
                Marshal.ReleaseComObject(pResponseHandler); 
                return (int)(tag_WBEMSTATUS.WBEM_E_NOT_FOUND); 
            }
 
            int id = ((IConvertible)instanceId).ToInt32((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int32)));
            Object theObject = null;

            try 
            {
                InstrumentedAssembly.readerWriterLock.AcquireReaderLock(-1); 
                theObject = InstrumentedAssembly.mapIDToPublishedObject[id.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int32)))]; 
            }
            finally 
            {
                InstrumentedAssembly.readerWriterLock.ReleaseReaderLock();
            }
 
            if(theObject != null)
            { 
                Type converterType = (Type)instrumentedAssembly.mapTypeToConverter[theObject.GetType()]; 
                if(converterType != null)
                { 
                    Object converter = Activator.CreateInstance(converterType);
                    ConvertToWMI func = (ConvertToWMI)Delegate.CreateDelegate(typeof(ConvertToWMI), converter, "ToWMI");

            // 
            // Regression: Reuters VSQFE#: 750, PS#141144    [marioh]
            // GetObjectAsync was missed. Again, here we have to call ToWMI before retrieving the pointer to the object 
            // since we clone a new one during the ToWMI call. The code below was simply moved from a location further down 
            //
            lock(theObject) 
                func(theObject);
            //
            // END: Regression: Reuters VSQFE#: 750, PS#141144    [marioh]
 

                    IntPtr[] objs = new IntPtr[] {(IntPtr)converter.GetType().GetField("instWbemObjectAccessIP").GetValue(converter)}; 
                    Marshal.AddRef(objs[0]); 
                    IWbemClassObjectFreeThreaded inst = new IWbemClassObjectFreeThreaded(objs[0]);
 
                    Object o = id;
                    inst.Put_("InstanceId", 0, ref o, 0);
                    o = Instrumentation.ProcessIdentity;
                    inst.Put_("ProcessId", 0, ref o, 0); 
                    //               ConvertFuncToWMI func = (ConvertFuncToWMI)InstrumentedAssembly.mapTypeToToWMIFunc[h.Target.GetType()];
            // 
            // Reuters VSQFE#: 750, PS#141144    [marioh] 
            // The commented out code was moved up before accessing the object pointer in order to get the
            // newly cloned one. 
            //
//                    lock(theObject)
//                        func(theObject);
                    pResponseHandler.Indicate_(1, objs); 

                    pResponseHandler.SetStatus_(0, 0, null, IntPtr.Zero); 
                    Marshal.ReleaseComObject(pResponseHandler); 
                    return 0;
                } 
            }
            pResponseHandler.SetStatus_(0, (int)tag_WBEMSTATUS.WBEM_E_NOT_FOUND, null, IntPtr.Zero);
            Marshal.ReleaseComObject(pResponseHandler);
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_FOUND); 
#if xxx
            IWbemClassObject classObj = null; 
            IWbemCallResult result = null; 
            pNamespace.GetObject("TestInstance", 0, pCtx, ref classObj, ref result);
            IWbemClassObject inst; 
            classObj.SpawnInstance(0, out inst);

            TestInstance testInstance = (TestInstance)mapNameToTestInstance[match.Groups[1].Value];
 
            Object o = (object)testInstance.name;
            inst.Put("name", 0, ref o, 0); 
            o = (object)testInstance.value; 
            inst.Put("value", 0, ref o, 0);
 
            pResponseHandler.Indicate(1, new IWbemClassObject[] {inst});
            pResponseHandler.SetStatus_(0, 0, IntPtr.Zero, IntPtr.Zero);
            Marshal.ReleaseComObject(pResponseHandler);
#endif 
        }
 
        int IWbemServices_Old.PutClass_([In][MarshalAs(UnmanagedType.Interface)]  IWbemClassObject_DoNotMarshal   pObject, 
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [In] IntPtr ppCallResult)
        {
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        } 

        int IWbemServices_Old.PutClassAsync_([In][MarshalAs(UnmanagedType.Interface)]  IWbemClassObject_DoNotMarshal   pObject, 
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pResponseHandler) 
        {
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        }
 
        int IWbemServices_Old.DeleteClass_([In][MarshalAs(UnmanagedType.BStr)]  string   strClass,
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [In] IntPtr ppCallResult)
        { 
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        }

        int IWbemServices_Old.DeleteClassAsync_([In][MarshalAs(UnmanagedType.BStr)]  string   strClass, 
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pResponseHandler) 
        {
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED); 
        }

        int IWbemServices_Old.CreateClassEnum_([In][MarshalAs(UnmanagedType.BStr)]  string   strSuperclass,
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [Out][MarshalAs(UnmanagedType.Interface)]  out IEnumWbemClassObject   ppEnum) 
        { 
            ppEnum = null;
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED); 
        }

        int IWbemServices_Old.CreateClassEnumAsync_([In][MarshalAs(UnmanagedType.BStr)]  string   strSuperclass,
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pResponseHandler) 
        { 
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        } 

        int IWbemServices_Old.PutInstance_([In][MarshalAs(UnmanagedType.Interface)]  IWbemClassObject_DoNotMarshal   pInst,
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [In] IntPtr ppCallResult)
        { 
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED); 
        }
 
        int IWbemServices_Old.PutInstanceAsync_([In][MarshalAs(UnmanagedType.Interface)]  IWbemClassObject_DoNotMarshal   pInst,
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pResponseHandler) 
        {
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED); 
        } 

        int IWbemServices_Old.DeleteInstance_([In][MarshalAs(UnmanagedType.BStr)]  string   strObjectPath, 
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [In] IntPtr ppCallResult)
        { 
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED);
        } 
 
        int IWbemServices_Old.DeleteInstanceAsync_([In][MarshalAs(UnmanagedType.BStr)]  string   strObjectPath,
            [In] Int32 lFlags, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pResponseHandler)
        {
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED); 
        }
 
        int IWbemServices_Old.CreateInstanceEnum_([In][MarshalAs(UnmanagedType.BStr)]  string   strFilter, 
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [Out][MarshalAs(UnmanagedType.Interface)]  out IEnumWbemClassObject   ppEnum)
        {
            ppEnum = null;
            return (int)(tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED); 
        }
 
        int IWbemServices_Old.CreateInstanceEnumAsync_([In][MarshalAs(UnmanagedType.BStr)]  string   strFilter, 
            [In] Int32 lFlags,
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext   pCtx, 
            [In][MarshalAs(UnmanagedType.Interface)]  IWbemObjectSink   pResponseHandler)
        {
            try
            { 
                // Make sure we do not let a shutdown kill this thread
                preventShutdownLock.AcquireReaderLock(-1); 
 
                // If we are already shutting down, don't do anything
                if(shutdownInProgress != 0) 
                    return 0;

                // If batching takes longer than 1/10 of a second, we want to stop
                // and flush the batch 
                uint timeLimitForBatchFlush = (uint)Environment.TickCount + 100;
 
                // Find the managed type that is being requested by this call 
                Type managedType = null;
                foreach(Type type in instrumentedAssembly.mapTypeToConverter.Keys) 
                {
                    if(0==String.Compare(ManagedNameAttribute.GetMemberName(type), strFilter, StringComparison.Ordinal))
                    {
                        managedType = type; 
                        break;
                    } 
                } 

                // If we do not support the requested type, just exit 
                if(null == managedType)
                    return 0;

                // size for batching 
                int batchSize = 64;
 
                // Array of IWbemClassObject IntPtrs for batching 
                IntPtr[] objs = new IntPtr[batchSize];
                IntPtr[] objsClone = new IntPtr[batchSize]; 

                // Array of converter methods for batching
                ConvertToWMI[] funcs = new ConvertToWMI[batchSize];
 
                // Array of IWbemClassObjectFreeThreaded instances for batching
                IWbemClassObjectFreeThreaded[] insts = new IWbemClassObjectFreeThreaded[batchSize]; 
 
                // IWbemObjectAccess handle for 'InstanceId'
                int handleInstanceId = 0; 

                // Current number of objects in batch
                int count = 0;
 
                // The process identity string
                Object processIdentity = Instrumentation.ProcessIdentity; 
 
                // Walk all published instances
                try 
                {
                    // Don't let anyone add entries to the dictionary while we are enumerating it.
                    // Other people can read from the dictionary
                    InstrumentedAssembly.readerWriterLock.AcquireReaderLock(-1); 
                    foreach(DictionaryEntry entry in InstrumentedAssembly.mapIDToPublishedObject)
                    { 
                        // If the process is going away, stop indicating more instances 
                        if(shutdownInProgress != 0)
                            return 0; 

                        // Is this object the type requested by this query?
                        if(managedType != entry.Value.GetType())
                            continue; 

                        // Initialize this batch entry if necessary.  Each element of the batch arrays 
                        // are initialized 'just in time'.  If we have less than batchSize entries total 
                        // (or it takes too long to batch), we do not unnecessarily allocate the batch entry
                        if(funcs[count] == null) 
                        {
                            Object converter = Activator.CreateInstance((Type)instrumentedAssembly.mapTypeToConverter[managedType]);
                            funcs[count] = (ConvertToWMI)Delegate.CreateDelegate(typeof(ConvertToWMI), converter, "ToWMI");
 
                            //
                            // Reuters VSQFE#: 750    [marioh] 
                            // In order for the instance data batching logic to work properly, we HAVE TO convert the .NET 
                            // objects to WMI objects before we update the batching pointers since the ToWMI method in the generated
                            // code will Spawn new instances. 
                            //
                            lock(entry.Value)
                                funcs[count](entry.Value);
 
                            objs[count] = (IntPtr)converter.GetType().GetField("instWbemObjectAccessIP").GetValue(converter);
                            Marshal.AddRef(objs[count]); 
                            insts[count] = new IWbemClassObjectFreeThreaded(objs[count]); 
                            insts[count].Put_("ProcessId", 0, ref processIdentity, 0);
 
                            int cimType;
                            if(count==0)
                                WmiNetUtilsHelper.GetPropertyHandle_f27(27, insts[count], "InstanceId", out cimType, out handleInstanceId);
                        } 
                        else
                        { 
                            // 
                            // Reuters VSQFE#: 750    [marioh]
                            // If we end up re-using an existing delegate from the batch array, we still have to convert 
                            // the .NET to WMI objects and update the instance pointers.
                            //

                            // Copy the managed instance information into the IWbemClassObject' 
                            // We're using a batch, therefore we have to convert them.
                            lock(entry.Value) 
                                funcs[count](entry.Value); 

                            objs[count] = (IntPtr) funcs[count].Target.GetType().GetField("instWbemObjectAccessIP").GetValue(funcs[count].Target); 

                            //
                            // We have to AddRef the interface pointer due to the IWbemClassObjectFreeThreaded not addreffing
                            // but releasing in the destructor. Great huh? 
                            //
                            Marshal.AddRef(objs[count]); 
                            insts[count] = new IWbemClassObjectFreeThreaded(objs[count]); 
                            insts[count].Put_("ProcessId", 0, ref processIdentity, 0);
 
                            int cimType;
                            if(count==0)
                                WmiNetUtilsHelper.GetPropertyHandle_f27(27, insts[count], "InstanceId", out cimType, out handleInstanceId);
                        } 

                        // We have an instance to publish.  Store the instance ID in 'InstanceId' 
                        string instanceId = (string)entry.Key; 
                        WmiNetUtilsHelper.WritePropertyValue_f28(28, insts[count], handleInstanceId, (instanceId.Length+1)*2, instanceId);
 
                        //                        // Copy the managed instance information into the IWbemClassObject'
                        //                        lock(entry.Value)
                        //                            funcs[count](entry.Value);
 
                        // Increment the batch counter
                        count++; 
 
                        // If we've reached batchSize, or if we've gone longer than 1/10th second since
                        // an Indicate, flush the batch 
                        if(count == batchSize || ((uint)Environment.TickCount) >= timeLimitForBatchFlush)
                        {
                            // Do the Indicate to WMI
                            // NOTE: On WinXP, we cannot control whether the implementation of 
                            // Indicate will immediately send the objects to WMI, or if it will
                            // batch them.  If it batches them, we cannot reuse them in a future 
                            // call to Indicate, or change them in any way after the call to 
                            // Indicate.  Because of this, we will always 'Clone' the objects
                            // just before calling Indicate.  The performance is negligable, even 
                            // on Windows 2000, which can handle about 200,000 Clones per second
                            // on a 1 GHz machine.
                            for(int i=0;i 0)
                { 
                    // NOTE: On WinXP, we cannot control whether the implementation of
                    // Indicate will immediately send the objects to WMI, or if it will
                    // batch them.  If it batches them, we cannot reuse them in a future
                    // call to Indicate, or change them in any way after the call to 
                    // Indicate.  Because of this, we will always 'Clone' the objects
                    // just before calling Indicate.  The performance is negligable, even 
                    // on Windows 2000, which can handle about 200,000 Clones per second 
                    // on a 1 GHz machine.
                    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