Beispiel #1
0
            //****************************************
            //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);
        }