/// <summary>
        /// Reads the guids from the enumerator.
        /// </summary>
        private List <Guid> ReadClasses(OpcRcw.Comn.IOPCEnumGUID enumerator)
        {
            List <Guid> guids = new List <Guid>();

            int fetched = 0;

            Guid[] buffer = new Guid[10];

            do
            {
                try
                {
                    IntPtr pGuids = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(Guid)) * buffer.Length);

                    try
                    {
                        enumerator.Next(buffer.Length, pGuids, out fetched);

                        if (fetched > 0)
                        {
                            IntPtr pos = pGuids;

                            for (int ii = 0; ii < fetched; ii++)
                            {
                                buffer[ii] = (Guid)Marshal.PtrToStructure(pos, typeof(Guid));
                                pos        = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(Guid)));
                                guids.Add(buffer[ii]);
                            }
                        }
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(pGuids);
                    }
                }
                catch
                {
                    break;
                }
            }while (fetched > 0);

            return(guids);
        }
        /// <summary>
        /// Returns a list of servers that support the specified specification.
        /// </summary>
        public ServerDescription[] GetAvailableServers(params Guid[] catids)
        {
            // enumerate servers on specified machine.
            try
            {
                // get list of servers in the specified specification.
                OpcRcw.Comn.IOPCEnumGUID enumerator = null;

                m_server.EnumClassesOfCategories(
                    catids.Length,
                    catids,
                    0,
                    null,
                    out enumerator);

                // read clsids.
                List <Guid> clsids = ReadClasses(enumerator);

                // release enumerator object.
                Utils.ReleaseServer(enumerator);
                enumerator = null;

                // fetch class descriptions.
                ServerDescription[] servers = new ServerDescription[clsids.Count];

                for (int ii = 0; ii < servers.Length; ii++)
                {
                    servers[ii] = ReadServerDetails(clsids[ii]);
                }

                return(servers);
            }
            catch (Exception e)
            {
                throw Utils.CreateComException(e, ResultIds.E_FAIL, "Could not enumerate COM servers.");
            }
        }