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