Code:
/ 4.0 / 4.0 / 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;i0) { // 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) { 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ColorBlend.cs
- OdbcRowUpdatingEvent.cs
- TdsRecordBufferSetter.cs
- UpdatePanelTrigger.cs
- TemplateControlCodeDomTreeGenerator.cs
- MSAAWinEventWrap.cs
- Assert.cs
- LightweightCodeGenerator.cs
- DataTableNewRowEvent.cs
- __ComObject.cs
- ModifierKeysConverter.cs
- ButtonColumn.cs
- MailAddress.cs
- Profiler.cs
- XmlUtil.cs
- ManagedCodeMarkers.cs
- Token.cs
- WindowsPrincipal.cs
- AppSettingsReader.cs
- EnumerationRangeValidationUtil.cs
- GridViewColumnCollectionChangedEventArgs.cs
- HttpCacheVary.cs
- CompositeCollectionView.cs
- CalendarDateChangedEventArgs.cs
- Subtree.cs
- EndPoint.cs
- DesigntimeLicenseContext.cs
- ConstNode.cs
- WithStatement.cs
- WebAdminConfigurationHelper.cs
- StrongNameUtility.cs
- PageThemeBuildProvider.cs
- WebBrowsableAttribute.cs
- VarRefManager.cs
- ElementHostAutomationPeer.cs
- SQLInt64.cs
- AssemblyBuilder.cs
- ConfigUtil.cs
- HtmlHead.cs
- LoginUtil.cs
- SudsWriter.cs
- ExeContext.cs
- Random.cs
- PrtCap_Public_Simple.cs
- FloaterBaseParaClient.cs
- OdbcReferenceCollection.cs
- SmiEventSink_DeferedProcessing.cs
- MimeWriter.cs
- ToolboxItemSnapLineBehavior.cs
- EventListenerClientSide.cs
- ListViewItemSelectionChangedEvent.cs
- ListBoxChrome.cs
- ReflectionUtil.cs
- PersonalizationDictionary.cs
- TypeLoadException.cs
- PropertyPushdownHelper.cs
- Int16KeyFrameCollection.cs
- CommandManager.cs
- SystemTcpConnection.cs
- Path.cs
- LoginName.cs
- UpdateManifestForBrowserApplication.cs
- FeedUtils.cs
- SoapReflectionImporter.cs
- ServiceDurableInstance.cs
- ActivityDefaults.cs
- ServiceDescriptionReflector.cs
- FileLevelControlBuilderAttribute.cs
- GeneralTransformGroup.cs
- XmlDictionaryReaderQuotas.cs
- NativeMethodsOther.cs
- figurelength.cs
- SrgsDocument.cs
- ECDiffieHellmanCng.cs
- LeftCellWrapper.cs
- SafeThemeHandle.cs
- SocketInformation.cs
- Win32Native.cs
- GridViewRowCollection.cs
- dbenumerator.cs
- WebPartCatalogAddVerb.cs
- SoapAttributeAttribute.cs
- FixedDSBuilder.cs
- ConfigXmlAttribute.cs
- ScriptReference.cs
- CachedPathData.cs
- RightsManagementPermission.cs
- SeekStoryboard.cs
- OSEnvironmentHelper.cs
- QueryAccessibilityHelpEvent.cs
- StaticContext.cs
- SHA384.cs
- MenuItemBinding.cs
- EventProvider.cs
- CompositeFontInfo.cs
- CheckableControlBaseAdapter.cs
- SwitchElementsCollection.cs
- IntSecurity.cs
- SmtpFailedRecipientsException.cs
- SchemaMapping.cs