示例#1
0
        }//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);
            }
        }
示例#2
0
            //****************************************
            //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);
            }
示例#3
0
        //********************************************
        //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()
示例#4
0
 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);
     }
 }
示例#5
0
        /// <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);
        }
示例#7
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);
            }
示例#8
0
        //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);
        }