}//Get() //******************************************** //Get() asynchronous //******************************************** /// <summary> /// <para>Invokes the WMI query, asynchronously, and binds to a watcher to deliver the results.</para> /// </summary> /// <param name='watcher'>The watcher that raises events triggered by the operation. </param> public void Get(ManagementOperationObserver watcher) { if (null == watcher) { throw new ArgumentNullException("watcher"); } Initialize(); IWbemServices wbemServices = scope.GetIWbemServices(); EnumerationOptions enumOptions = (EnumerationOptions)options.Clone(); // Ensure we switch off ReturnImmediately as this is invalid for async calls enumOptions.ReturnImmediately = false; // If someone has registered for progress, make sure we flag it if (watcher.HaveListenersForProgress) { enumOptions.SendStatus = true; } WmiEventSink sink = watcher.GetNewSink(scope, enumOptions.Context); SecurityHandler securityHandler = scope.GetSecurityHandler(); int status = (int)ManagementStatus.NoError; try { //If this is a simple SelectQuery (className only), and the enumerateDeep is set, we have //to find out whether this is a class enumeration or instance enumeration and call CreateInstanceEnum/ //CreateClassEnum appropriately, because with ExecQuery we can't do a deep enumeration. if ((query.GetType() == typeof(SelectQuery)) && (((SelectQuery)query).Condition == null) && (((SelectQuery)query).SelectedProperties == null) && (options.EnumerateDeep == true)) { //Need to make sure that we're not passing invalid flags to enumeration APIs. //The only flags not valid for enumerations are EnsureLocatable & PrototypeOnly. enumOptions.EnsureLocatable = false; enumOptions.PrototypeOnly = false; if (((SelectQuery)query).IsSchemaQuery == false) //deep instance enumeration { status = scope.GetSecuredIWbemServicesHandler(wbemServices).CreateInstanceEnumAsync_(((SelectQuery)query).ClassName, enumOptions.Flags, enumOptions.GetContext(), sink.Stub); } else { status = scope.GetSecuredIWbemServicesHandler(wbemServices).CreateClassEnumAsync_(((SelectQuery)query).ClassName, enumOptions.Flags, enumOptions.GetContext(), sink.Stub); } } else //we can use ExecQuery { //Make sure the EnumerateDeep flag bit is turned off because it's invalid for queries enumOptions.EnumerateDeep = true; status = scope.GetSecuredIWbemServicesHandler(wbemServices).ExecQueryAsync_( query.QueryLanguage, query.QueryString, enumOptions.Flags, enumOptions.GetContext(), sink.Stub); } } catch (COMException e) { // watcher.RemoveSink(sink); ManagementException.ThrowWithExtendedInfo(e); } finally { securityHandler.Reset(); } if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else if ((status & 0x80000000) != 0) { Marshal.ThrowExceptionForHR(status); } }
//**************************************** //MoveNext //**************************************** /// <summary> /// Indicates whether the enumerator has moved to /// the next object in the enumeration. /// </summary> /// <returns> /// <para><see langword='true'/>, if the enumerator was /// successfully advanced to the next element; <see langword='false'/> if the enumerator has /// passed the end of the collection.</para> /// </returns> public bool MoveNext() { if (isDisposed) { throw new ObjectDisposedException(name); } //If there are no more objects in the collection return false if (atEndOfCollection) { return(false); } //Look for the next object cacheIndex++; if ((cachedCount - cacheIndex) == 0) //cache is empty - need to get more objects { //If the timeout is set to infinite, need to use the WMI infinite constant int timeout = (collectionObject.options.Timeout.Ticks == Int64.MaxValue) ? (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)collectionObject.options.Timeout.TotalMilliseconds; //Get the next [BLockSize] objects within the specified timeout // SecurityHandler securityHandler = collectionObject.scope.GetSecurityHandler(); //Because Interop doesn't support custom marshalling for arrays, we have to use //the "DoNotMarshal" objects in the interop and then convert to the "FreeThreaded" //counterparts afterwards. IWbemClassObject_DoNotMarshal[] tempArray = new IWbemClassObject_DoNotMarshal[collectionObject.options.BlockSize]; int status = collectionObject.scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem).Next_(timeout, (uint)collectionObject.options.BlockSize, tempArray, ref cachedCount); securityHandler.Reset(); if (status >= 0) { //Convert results and put them in cache. for (int i = 0; i < cachedCount; i++) { cachedObjects[i] = new IWbemClassObjectFreeThreaded ( Marshal.GetIUnknownForObject(tempArray[i]) ); } } if (status < 0) { if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else { Marshal.ThrowExceptionForHR(status); } } else { //If there was a timeout and no object can be returned we throw a timeout exception... // - if ((status == (int)tag_WBEMSTATUS.WBEM_S_TIMEDOUT) && (cachedCount == 0)) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } //If not timeout and no objects were returned - we're at the end of the collection if ((status == (int)tag_WBEMSTATUS.WBEM_S_FALSE) && (cachedCount == 0)) { atEndOfCollection = true; cacheIndex--; //back to last object /* This call to Dispose is being removed as per discussion with URT people and the newly supported * Dispose() call in the foreach implementation itself. * * //Release the COM object (so that the user doesn't have to) * Dispose(); */ return(false); } } cacheIndex = 0; } return(true); }
//******************************************** //Get() //******************************************** /// <overload> /// Invokes the specified WMI query and returns the resulting collection. /// </overload> /// <summary> /// <para>Invokes the specified WMI query and returns the /// resulting collection.</para> /// </summary> /// <returns> /// <para>A <see cref='System.Management.ManagementObjectCollection'/> containing the objects that match the /// specified query.</para> /// </returns> public ManagementObjectCollection Get() { Initialize(); IEnumWbemClassObject ew = null; SecurityHandler securityHandler = scope.GetSecurityHandler(); EnumerationOptions enumOptions = (EnumerationOptions)options.Clone(); int status = (int)ManagementStatus.NoError; try { //If this is a simple SelectQuery (className only), and the enumerateDeep is set, we have //to find out whether this is a class enumeration or instance enumeration and call CreateInstanceEnum/ //CreateClassEnum appropriately, because with ExecQuery we can't do a deep enumeration. if ((query.GetType() == typeof(SelectQuery)) && (((SelectQuery)query).Condition == null) && (((SelectQuery)query).SelectedProperties == null) && (options.EnumerateDeep == true)) { //Need to make sure that we're not passing invalid flags to enumeration APIs. //The only flags not valid for enumerations are EnsureLocatable & PrototypeOnly. enumOptions.EnsureLocatable = false; enumOptions.PrototypeOnly = false; if (((SelectQuery)query).IsSchemaQuery == false) //deep instance enumeration { status = scope.GetSecuredIWbemServicesHandler(scope.GetIWbemServices()).CreateInstanceEnum_( ((SelectQuery)query).ClassName, enumOptions.Flags, enumOptions.GetContext(), ref ew); } else //deep class enumeration { status = scope.GetSecuredIWbemServicesHandler(scope.GetIWbemServices()).CreateClassEnum_(((SelectQuery)query).ClassName, enumOptions.Flags, enumOptions.GetContext(), ref ew); } } else //we can use ExecQuery { //Make sure the EnumerateDeep flag bit is turned off because it's invalid for queries enumOptions.EnumerateDeep = true; status = scope.GetSecuredIWbemServicesHandler(scope.GetIWbemServices()).ExecQuery_( query.QueryLanguage, query.QueryString, enumOptions.Flags, enumOptions.GetContext(), ref ew); } } catch (COMException e) { // ManagementException.ThrowWithExtendedInfo(e); } finally { securityHandler.Reset(); } if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else if ((status & 0x80000000) != 0) { Marshal.ThrowExceptionForHR(status); } //Create a new collection object for the results return(new ManagementObjectCollection(scope, options, ew)); }//Get()
public ManagementBaseObject WaitForNextEvent() { unsafe { int totalMilliseconds; ManagementBaseObject managementBaseObject = null; this.Initialize(); lock (this) { SecurityHandler securityHandler = this.Scope.GetSecurityHandler(); int num = 0; try { if (this.enumWbem == null) { num = this.scope.GetSecuredIWbemServicesHandler(this.Scope.GetIWbemServices()).ExecNotificationQuery_(this.query.QueryLanguage, this.query.QueryString, this.options.Flags, this.options.GetContext(), ref this.enumWbem); } if (num >= 0) { if (this.cachedCount - this.cacheIndex == 0) { IWbemClassObject_DoNotMarshal[] wbemClassObjectDoNotMarshalArray = new IWbemClassObject_DoNotMarshal[this.options.BlockSize]; if (ManagementOptions.InfiniteTimeout == this.options.Timeout) { totalMilliseconds = -1; } else { TimeSpan timeout = this.options.Timeout; totalMilliseconds = (int)timeout.TotalMilliseconds; } int num1 = totalMilliseconds; num = this.scope.GetSecuredIEnumWbemClassObjectHandler(this.enumWbem).Next_(num1, this.options.BlockSize, wbemClassObjectDoNotMarshalArray, ref this.cachedCount); this.cacheIndex = 0; if (num >= 0) { if (this.cachedCount == 0) { ManagementException.ThrowWithExtendedInfo(ManagementStatus.Timedout); } for (int i = 0; (long)i < (long)this.cachedCount; i++) { this.cachedObjects[i] = new IWbemClassObjectFreeThreaded(Marshal.GetIUnknownForObject(wbemClassObjectDoNotMarshalArray[i].NativeObject)); } } } if (num >= 0) { ManagementEventWatcher managementEventWatcher = this; managementEventWatcher.cacheIndex = managementEventWatcher.cacheIndex + 1; } } } finally { securityHandler.Reset(); } if (num < 0) { if (((long)num & (long)-4096) != (long)-2147217408) { Marshal.ThrowExceptionForHR(num); } else { ManagementException.ThrowWithExtendedInfo((ManagementStatus)num); } } } return(managementBaseObject); } }
/// <summary> /// <para>Waits for the next event that matches the specified query to arrive, and /// then returns it.</para> /// </summary> /// <returns> /// <para>A <see cref='System.Management.ManagementBaseObject'/> representing the /// newly arrived event.</para> /// </returns> /// <remarks> /// <para>If the event watcher object contains options with /// a specified timeout, the API will wait for the next event only for the specified /// amount of time; otherwise, the API will be blocked until the next event occurs.</para> /// </remarks> public ManagementBaseObject WaitForNextEvent() { ManagementBaseObject obj = null; Initialize(); #pragma warning disable CA2002 lock (this) #pragma warning restore CA2002 { SecurityHandler securityHandler = Scope.GetSecurityHandler(); int status = (int)ManagementStatus.NoError; try { if (null == enumWbem) //don't have an enumerator yet - get it { //Execute the query status = scope.GetSecuredIWbemServicesHandler(Scope.GetIWbemServices()).ExecNotificationQuery_( query.QueryLanguage, query.QueryString, options.Flags, options.GetContext(), ref enumWbem); } if (status >= 0) { if ((cachedCount - cacheIndex) == 0) //cache is empty - need to get more objects { //Because Interop doesn't support custom marshalling for arrays, we have to use //the "DoNotMarshal" objects in the interop and then convert to the "FreeThreaded" //counterparts afterwards. IWbemClassObject_DoNotMarshal[] tempArray = new IWbemClassObject_DoNotMarshal[options.BlockSize]; int timeout = (ManagementOptions.InfiniteTimeout == options.Timeout) ? (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)options.Timeout.TotalMilliseconds; status = scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem).Next_(timeout, (uint)options.BlockSize, tempArray, ref cachedCount); cacheIndex = 0; if (status >= 0) { //Convert results and put them in cache. Note that we may have timed out //in which case we might not have all the objects. If no object can be returned //we throw a timeout exception. if (cachedCount == 0) { ManagementException.ThrowWithExtendedInfo(ManagementStatus.Timedout); } for (int i = 0; i < cachedCount; i++) { cachedObjects[i] = new IWbemClassObjectFreeThreaded(Marshal.GetIUnknownForObject(tempArray[i])); } } } if (status >= 0) { obj = new ManagementBaseObject(cachedObjects[cacheIndex]); cacheIndex++; } } } finally { securityHandler.Reset(); } if (status < 0) { if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else { Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f()); } } } return(obj); }
/// <summary> /// <para>Waits for the next event that matches the specified query to arrive, and /// then returns it.</para> /// </summary> /// <returns> /// <para>A <see cref='System.Management.ManagementBaseObject'/> representing the /// newly arrived event.</para> /// </returns> /// <remarks> /// <para>If the event watcher object contains options with /// a specified timeout, the API will wait for the next event only for the specified /// amount of time; otherwise, the API will be blocked until the next event occurs.</para> /// </remarks> public ManagementBaseObject WaitForNextEvent() { ManagementBaseObject obj = null; Initialize(); lock (this) { SecurityHandler securityHandler = Scope.GetSecurityHandler(); int status = (int)ManagementStatus.NoError; try { if (null == enumWbem) //don't have an enumerator yet - get it { //Execute the query status = Scope.GetIWbemServices().ExecNotificationQuery_( query.QueryLanguage, query.QueryString, options.Flags, options.GetContext(), out enumWbem); //Set security on enumerator if (status >= 0) { securityHandler.Secure(enumWbem); } } if (status >= 0) { if ((cachedCount - cacheIndex) == 0) //cache is empty - need to get more objects { #if true //Because Interop doesn't support custom marshalling for arrays, we have to use //the "DoNotMarshal" objects in the interop and then convert to the "FreeThreaded" //counterparts afterwards. IWbemClassObject_DoNotMarshal[] tempArray = new IWbemClassObject_DoNotMarshal[options.BlockSize]; int timeout = (ManagementOptions.InfiniteTimeout == options.Timeout) ? (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)options.Timeout.TotalMilliseconds; status = enumWbem.Next_(timeout, (uint)options.BlockSize, tempArray, out cachedCount); cacheIndex = 0; if (status >= 0) { //Convert results and put them in cache. Note that we may have timed out //in which case we might not have all the objects. If no object can be returned //we throw a timeout exception... - TODO: what should happen if there was a timeout //but at least some objects were returned ?? if (cachedCount == 0) { ManagementException.ThrowWithExtendedInfo(ManagementStatus.Timedout); } for (int i = 0; i < cachedCount; i++) { cachedObjects[i] = new IWbemClassObjectFreeThreaded(Marshal.GetIUnknownForObject(tempArray[i])); } } #else //This was workaround when using TLBIMP we couldn't pass in arrays... IWbemClassObjectFreeThreaded cachedObject = cachedObjects[0]; int timeout = (ManagementOptions.InfiniteTimeout == options.Timeout) ? (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)options.Timeout.TotalMilliseconds; status = enumWbem.Next_(timeout, 1, out cachedObjects, out cachedCount); cacheIndex = 0; if (status >= 0) { //Create ManagementObject for result. Note that we may have timed out //in which case we won't have an object if (null == cachedObject) { ManagementException.ThrowWithExtendedInfo(ManagementStatus.Timedout); } cachedObjects[0] = cachedObject; } #endif } if (status >= 0) { obj = new ManagementBaseObject(cachedObjects[cacheIndex]); cacheIndex++; } } } finally { securityHandler.Reset(); } if (status < 0) { if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else { Marshal.ThrowExceptionForHR(status); } } } return(obj); }
//**************************************** //MoveNext //**************************************** /// <summary> /// Moves to the next object in the enumeration /// </summary> public bool MoveNext() { if (isDisposed) { throw new ObjectDisposedException("ManagementObjectEnumerator"); } //If there are no more objects in the collection return false if (atEndOfCollection) { return(false); } //Look for the next object cacheIndex++; if ((cachedCount - cacheIndex) == 0) //cache is empty - need to get more objects { //If the timeout is set to infinite, need to use the WMI infinite constant int timeout = (collectionObject.options.Timeout.Ticks == Int64.MaxValue) ? (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)collectionObject.options.Timeout.TotalMilliseconds; //Get the next [BLockSize] objects within the specified timeout // TODO - cannot use arrays of IWbemClassObject with a TLBIMP // generated wrapper SecurityHandler securityHandler = collectionObject.scope.GetSecurityHandler(); int status = (int)ManagementStatus.NoError; #if false status = enumWbem.Next(timeout, collectionObject.options.BlockSize, out cachedObjects, out cachedCount); #else IWbemClassObjectFreeThreaded obj = null; try { status = enumWbem.Next_(timeout, 1, out obj, out cachedCount); } catch (Exception e) { ManagementException.ThrowWithExtendedInfo(e); } if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else if ((status & 0x80000000) != 0) { Marshal.ThrowExceptionForHR(status); } cachedObjects[0] = obj; #endif // BUGBUG : Review this //Check the return code - might be failure, timeout or WBEM_S_FALSE... if (status != 0) //not success { //If it's anything but WBEM_S_FALSE (which means end of collection) - we need to throw if (status != (int)tag_WBEMSTATUS.WBEM_S_FALSE) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } //if we got less objects than we wanted, need to check why... if (cachedCount < collectionObject.options.BlockSize) { //If no objects were returned we're at the very end if (cachedCount == 0) { atEndOfCollection = true; cacheIndex--; //back to last object //Release the COM object (so that the user doesn't have to) Dispose(); return(false); } } } cacheIndex = 0; securityHandler.Reset(); } else { //Advance the index to the next cacheIndex++; } return(true); }
//int statusFromMTA; void InitializeGuts(object o) { ManagementScope threadParam = (ManagementScope)o; IWbemLocator loc = (IWbemLocator) new WbemLocator(); if (null == options) { threadParam.Options = new ConnectionOptions(); } string nsPath = threadParam.prvpath.GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY); // If no namespace specified, fill in the default one if ((null == nsPath) || (0 == nsPath.Length)) { // NB: we use a special method to set the namespace // path here as we do NOT want to trigger an // IdentifierChanged event as a result of this set bool bUnused; nsPath = threadParam.prvpath.SetNamespacePath(ManagementPath.DefaultPath.Path, out bUnused); } // If we have privileges to enable, now is the time SecurityHandler securityHandler = GetSecurityHandler(); int status = (int)ManagementStatus.NoError; //If we're on XP or higher, always use the "max_wait" flag to avoid hanging if ((Environment.OSVersion.Platform == PlatformID.Win32NT) && (Environment.OSVersion.Version.Major >= 5) && (Environment.OSVersion.Version.Minor >= 1)) { threadParam.options.Flags |= (int)tag_WBEM_CONNECT_OPTIONS.WBEM_FLAG_CONNECT_USE_MAX_WAIT; } try { status = loc.ConnectServer_( nsPath, threadParam.options.Username, threadParam.options.GetPassword(), threadParam.options.Locale, threadParam.options.Flags, threadParam.options.Authority, threadParam.options.GetContext(), out threadParam.wbemServices); //Set security on services pointer GetSecurityHandler().Secure(threadParam.wbemServices); // // RAID: 127453 [marioh] // Make sure we enable RPC garbage collection to avoid tons // of useless idle connections not being recycled. This only // has impact on Win2k and below since XP has this enabled by // default. // if (rpcGarbageCollectionEnabled == false) { RpcMgmtEnableIdleCleanup( ); rpcGarbageCollectionEnabled = true; } Marshal.ReleaseComObject(loc); loc = null; } catch (Exception e) { // BUGBUG : securityHandler.Reset()? ManagementException.ThrowWithExtendedInfo(e); } finally { securityHandler.Reset(); } //statusFromMTA = status; if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else if ((status & 0x80000000) != 0) { Marshal.ThrowExceptionForHR(status); } }
internal void Initialize() { //If the path is not set yet we can't do it if (null == path) { throw new InvalidOperationException(); } /* * If we're not connected yet, this is the time to do it... We lock * the state to prevent 2 threads simultaneously doing the same * connection. To avoid taking the lock unnecessarily we examine * isConnected first */ if (!IsConnected) { lock (this) { if (!IsConnected) { IWbemLocator loc = (IWbemLocator) new WbemLocator(); if (null == options) { Options = new ConnectionOptions(); } string nsPath = path.NamespacePath; // If no namespace specified, fill in the default one if ((null == nsPath) || (0 == nsPath.Length)) { // NB: we use a special method to set the namespace // path here as we do NOT want to trigger an // IdentifierChanged event as a result of this set path.SetNamespacePath(ManagementPath.DefaultPath.Path); } // If we have privileges to enable, now is the time SecurityHandler securityHandler = GetSecurityHandler(); int status = (int)ManagementStatus.NoError; try { status = loc.ConnectServer_( path.NamespacePath, options.Username, options.GetPassword(), options.Locale, options.Flags, options.Authority, options.GetContext(), out wbemServices); //Set security on services pointer Secure(wbemServices); } catch (Exception e) { // BUGBUG : securityHandler.Reset()? ManagementException.ThrowWithExtendedInfo(e); } finally { securityHandler.Reset(); } if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else if ((status & 0x80000000) != 0) { Marshal.ThrowExceptionForHR(status); } } } } }
/// <summary> /// <para>Waits until the next event that matches the specified query arrives, /// and returns it</para> /// </summary> /// <remarks> /// If the event watcher object contains /// options with a specified timeout, this API will wait for the next event only for /// the specified time. If not, the API will block until the next event occurs. /// </remarks> public ManagementBaseObject WaitForNextEvent() { Trace.WriteLine("Entering WaitForNextEvent..."); ManagementBaseObject obj = null; Initialize(); lock (this) { SecurityHandler securityHandler = Scope.GetSecurityHandler(); int status = (int)ManagementStatus.NoError; try { if (null == enumWbem) //don't have an enumerator yet - get it { //Execute the query status = Scope.GetIWbemServices().ExecNotificationQuery_( query.QueryLanguage, query.QueryString, options.Flags, options.GetContext(), out enumWbem); //Set security on enumerator if ((status & 0x80000000) == 0) { securityHandler.Secure(enumWbem); } } if ((status & 0x80000000) == 0) { if ((cachedCount - cacheIndex) == 0) //cache is empty - need to get more objects { // TODO - due to TLBIMP restrictions IEnumWBemClassObject.Next will // not work with arrays - have to set count to 1 #if false enumWbem.Next((int)options.Timeout.TotalMilliseconds, (uint)options.BlockCount, out cachedObjects, out cachedCount); #else IWbemClassObjectFreeThreaded cachedObject = cachedObjects[0]; int timeout = (ManagementOptions.InfiniteTimeout == options.Timeout) ? (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)options.Timeout.TotalMilliseconds; status = enumWbem.Next_(timeout, 1, out cachedObject, out cachedCount); cacheIndex = 0; if ((status & 0x80000000) == 0) { //Create ManagementObject for result. Note that we may have timed out //in which case we won't have an object if (null == cachedObject) { ManagementException.ThrowWithExtendedInfo(ManagementStatus.Timedout); } cachedObjects[0] = cachedObject; } #endif } if ((status & 0x80000000) == 0) { obj = new ManagementBaseObject(cachedObjects[cacheIndex]); cacheIndex++; } } } catch (Exception e) { // BUGBUG : securityHandler.Reset()? if (e is ManagementException) { throw; //just let it propagate } ManagementException.ThrowWithExtendedInfo(e); } finally { securityHandler.Reset(); Trace.WriteLine("Returning from WaitForNextEvent..."); } if ((status & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); } else if ((status & 0x80000000) != 0) { Marshal.ThrowExceptionForHR(status); } } return(obj); }