示例#1
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);
            }
        }
示例#2
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);
        }
示例#3
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 == long.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, WmiNetUtilsHelper.GetErrorInfo_f());
                        }
                    }
                    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);
            }
示例#4
0
        //
        //IEnumerable methods
        //

        //****************************************
        //GetEnumerator
        //****************************************
        /// <summary>
        ///    <para>Returns the enumerator for the collection. If the collection was retrieved from an operation that
        /// specified the EnumerationOptions.Rewindable = false only one iteration through this enumerator is allowed.
        /// Note that this applies to using the Count property of the collection as well since an iteration over the collection
        /// is required. Due to this, code using the Count property should never specify EnumerationOptions.Rewindable = false.
        /// </para>
        /// </summary>
        /// <returns>
        ///    An <see cref='System.Collections.IEnumerator'/>that can be used to iterate through the
        ///    collection.
        /// </returns>
        public ManagementObjectEnumerator GetEnumerator()
        {
            if (isDisposed)
            {
                throw new ObjectDisposedException(name);
            }


            //
            // We do not clone the enumerator if its the first enumerator.
            // If it is the first enumerator we pass the reference
            // to the enumerator implementation rather than a clone. If the enumerator is used
            // from within a foreach statement in the client code, the foreach statement will
            // dec the ref count on the reference which also happens to be the reference to the
            // original enumerator causing subsequent uses of the collection to fail.
            // To prevent this we always clone the enumerator (assuming its a rewindable enumerator)
            // to avoid invalidating the collection.
            //
            // If its a forward only enumerator we simply pass back the original enumerator (i.e.
            // not cloned) and if it gets disposed we end up throwing the next time its used. Essentially,
            // the enumerator becomes the collection.
            //

            // Unless this is the first enumerator, we have
            // to clone. This may throw if we are non-rewindable.
            if (this.options.Rewindable == true)
            {
                IEnumWbemClassObject enumWbemClone = null;
                int status = (int)ManagementStatus.NoError;

                try
                {
                    status = scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem).Clone_(ref enumWbemClone);

                    if ((status & 0x80000000) == 0)
                    {
                        //since the original enumerator might not be reset, we need
                        //to reset the new one.
                        status = scope.GetSecuredIEnumWbemClassObjectHandler(enumWbemClone).Reset_();
                    }
                }
                catch (COMException e)
                {
                    ManagementException.ThrowWithExtendedInfo(e);
                }

                if ((status & 0xfffff000) == 0x80041000)
                {
                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                }
                else if ((status & 0x80000000) != 0)
                {
                    Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
                }
                return(new ManagementObjectEnumerator(this, enumWbemClone));
            }
            else
            {
                //
                // Notice that we use the original enumerator and hence enum position is retained.
                // For example, if the client code manually walked half the collection and then
                // used a foreach statement, the foreach statement would continue from where the
                // manual walk ended.
                //
                return(new ManagementObjectEnumerator(this, enumWbem));
            }
        }
        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);
                        }
                    }
                }
            }
        }
示例#6
0
        internal string SetNamespacePath(string nsPath, out bool bChange)
        {
            int       status     = (int)ManagementStatus.NoError;
            string    nsOrg      = null;
            string    nsNew      = null;
            IWbemPath wmiPathTmp = null;

            bChange = false;

            Debug.Assert(nsPath != null);

            //Do some validation on the path to make sure it is a valid namespace path (at least syntactically)
            if (!IsValidNamespaceSyntax(nsPath))
            {
                ManagementException.ThrowWithExtendedInfo((ManagementStatus)tag_WBEMSTATUS.WBEM_E_INVALID_NAMESPACE);
            }

            wmiPathTmp = CreateWbemPath(nsPath);
            if (wmiPath == null)
            {
                wmiPath = this.CreateWbemPath("");
            }
            else if (isWbemPathShared)
            {
                // Check if this IWbemPath is shared among multiple managed objects.
                // With this write, it will have to maintain its own copy.
                wmiPath          = CreateWbemPath(this.GetWbemPath());
                isWbemPathShared = false;
            }

            nsOrg = GetNamespacePath(wmiPath,
                                     (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY);
            nsNew = GetNamespacePath(wmiPathTmp,
                                     (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY);

            if (!string.Equals(nsOrg, nsNew, StringComparison.OrdinalIgnoreCase))
            {
                wmiPath.RemoveAllNamespaces_();                                 // Out with the old... Ignore status code.

                // Add the new ones in
                bChange = true;                                                 // Now dirty from above.
                uint nCount = 0;
                status = wmiPathTmp.GetNamespaceCount_(out nCount);

                if (status >= 0)
                {
                    for (uint i = 0; i < nCount; i++)
                    {
                        uint uLen = 0;
                        status = wmiPathTmp.GetNamespaceAt_(i, ref uLen, null);

                        if (status >= 0)
                        {
                            char[] space = new char[(int)uLen];
                            status = wmiPathTmp.GetNamespaceAt_(i, ref uLen, space);
                            if (status >= 0)
                            {
                                status = wmiPath.SetNamespaceAt_(i, space);

                                if (status < 0)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                ;
            }           // Continue on. Could have different server name, same ns specified.

            //
            // Update Server property if specified in the namespace.
            // eg: "\\MyServer\root\cimv2".
            //
            if (status >= 0 && nsPath.Length > 1 &&
                (nsPath[0] == '\\' && nsPath[1] == '\\' ||
                 nsPath[0] == '/' && nsPath[1] == '/'))
            {
                uint uLen = 0;
                status = wmiPathTmp.GetServer_(ref uLen, null);

                if (status >= 0 && uLen > 0)
                {
                    char[] newServerChars = new char[(int)uLen];
                    status = wmiPathTmp.GetServer_(ref uLen, newServerChars);
                    string serverNew = new string(newServerChars, 0, Array.IndexOf(newServerChars, '\0'));

                    if (status >= 0)
                    {
                        // Compare server name on this object, if specified, to the caller's.
                        //     Update this object if different or unspecified.
                        uLen   = 0;
                        status = wmiPath.GetServer_(ref uLen, null);            // NB: Cannot use property get since it may throw.

                        if (status >= 0)
                        {
                            char[] orgServerChars = new char[(int)uLen];
                            status = wmiPath.GetServer_(ref uLen, orgServerChars);
                            string serverOrg = new string(orgServerChars, 0, Array.IndexOf(orgServerChars, '\0'));

                            if (status >= 0 && !string.Equals(serverOrg, serverNew, StringComparison.OrdinalIgnoreCase))
                            {
                                status = wmiPath.SetServer_(serverNew);
                            }
                        }
                        else if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE)
                        {
                            status = wmiPath.SetServer_(serverNew);
                            if (status >= 0)
                            {
                                bChange = true;
                            }
                        }
                    }
                }
                else if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE)    // No caller-supplied server name;
                {
                    status = (int)ManagementStatus.NoError;                     // Ignore error.
                }
            }

            if (status < 0)
            {
                if ((status & 0xfffff000) == 0x80041000)
                {
                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                }
                else
                {
                    Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
                }
            }

            return(nsNew);
        }
        /// <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);
        }