コード例 #1
0
        /// <summary>
        /// HACK: Microsoft CDC driver (usbser.sys) does not register properly as a serial port
        /// It needs serenum.sys upper port filter which causes problems of its own...
        ///
        /// </summary>
        /// <param name="ports"></param>
        private static void PatchInZModemSerials(List <SerialPortInfo> ports)
        {
            /* SiLabs licensed USB to serial driver PID/VID */
            const string SILABS_VID_PID = @"USB\VID_10C4&PID_81E8";
            /* Zephyr VID (not specific on PID) */
            const string ZEPHYR_VID = @"USB\VID_22F3";
            string       pnpDevId;
            int          startIndex;
            int          length;

            System.Management.ManagementScope            scope;
            System.Management.ObjectQuery                query;
            System.Management.ManagementObjectSearcher   searcher;
            System.Management.ManagementObjectCollection returnCollection;
            System.Management.EnumerationOptions         opt = new System.Management.EnumerationOptions();


            try
            {
                /* get the data NOW, don't put off the query until it is required (30sec timeout) */
                opt.ReturnImmediately = false;
                opt.Timeout           = new TimeSpan(0, 0, 30);

                /* define scope, in this case, this machine */
                scope = new System.Management.ManagementScope(@"root\CIMV2");
                /* set the query, get all information on the serial ports on the system */
                query = new System.Management.ObjectQuery("SELECT * from Win32_SerialPort");

                /* stick two together into a search */
                searcher = new System.Management.ManagementObjectSearcher(scope, query, opt);

                /* Run the query */
                returnCollection = searcher.Get();

                foreach (var oReturn in returnCollection)
                {
                    pnpDevId = oReturn["PNPDeviceID"] as string;
                    pnpDevId = pnpDevId.ToUpper();  // Vista / Win7 seem to use upper case PID/VID/GUID


                    /* Checks to see if the candidate mySerialPort is a zephyr Serial Port */
                    if ((pnpDevId.LastIndexOf(SILABS_VID_PID) > -1) || (pnpDevId.LastIndexOf(ZEPHYR_VID) > -1))
                    {
                        /* Extract the serial number from the PnP mySerialPort ID */
                        startIndex = pnpDevId.LastIndexOf(@"\") + 1;
                        length     = pnpDevId.LastIndexOf(@"_") - startIndex;
                        if (length < 0)
                        {
                            length = pnpDevId.Length - startIndex;
                        }

                        /* If port not already known, add to list */
                        string serial   = pnpDevId.Substring(startIndex, length);
                        string portName = oReturn["DeviceID"] as string;
                        string caption  = oReturn["Caption"] as string;
                        var    search   = ports.FirstOrDefault(item => item.Name == portName);
                        if (search == null)
                        {
                            System.Diagnostics.Debug.WriteLine("Found: " + oReturn["DeviceID"] + " " + oReturn["Caption"]);
                            SerialPortInfo spi = new SerialPortInfo();
                            spi.SerialName   = serial;
                            spi.Name         = portName;
                            spi.FriendlyName = caption;
                            spi.Description  = caption;
                            spi.Manufacturer = "Zephyr";
                            spi.Driver       = "usbser.sys";
                            ports.Add(spi);
                        }
                    }
                }
            }
            catch
            {
            }
        }
コード例 #2
0
        /// <summary>
        /// Return the list of all available COM port into the system
        /// </summary>
        /// <returns></returns>
        public static ReadOnlyCollection <SerialPortInfo> GetAvailablePorts()
        {
            IntPtr hdevInfo = SetupDi.SetupDiGetClassDevs(
                ref GUID_DEVINTERFACE_COMPORT,
                null,
                IntPtr.Zero,
                SetupDIGetClassDevsFlags.DIGCF_PRESENT | SetupDIGetClassDevsFlags.DIGCF_DEVICEINTERFACE);

            if (hdevInfo == INVALID_HANDLE_VALUE)
            {
                throw new Exception("can't access to serial port communication information.");
            }

            List <SerialPortInfo> ports = new List <SerialPortInfo>();

            uint            index          = 0;
            SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();

            while (SetupDi.SetupDiEnumDeviceInfo(hdevInfo, index++, deviceInfoData) == true)
            {
                IntPtr hKey = SetupDi.SetupDiOpenDevRegKey(
                    hdevInfo,
                    deviceInfoData,
                    SetupDiOpenDevRegKeyScopeFlags.DICS_FLAG_GLOBAL,
                    0,
                    SetupDiOpenDevRegKeyKeyTypeFlags.DIREG_DEV,
                    REGSAM.KEY_QUERY_VALUE);

                if (hKey != IntPtr.Zero)
                {
                    SerialPortInfo portInfo = new SerialPortInfo();

                    UInt32 resultLength = 1024;
                    IntPtr registryName = Marshal.AllocHGlobal(1024);

                    var retValue = Registry.NtQueryKey(hKey, 3, registryName, 1024, ref resultLength);
                    if (retValue == 0)
                    {
                        string registryNameStr = Marshal.PtrToStringAuto((IntPtr)(registryName.ToInt32() + 4), Marshal.ReadInt32(registryName) / 2);
                        Marshal.FreeHGlobal(registryName);

                        var registryPath = registryNameStr.Split('\\');

                        if (registryPath != null && registryPath.Length > 3)
                        {
                            var sNumber = registryPath[registryPath.Length - 2];
                            if (sNumber != null && sNumber.Contains('_'))
                            {
                                portInfo.SerialName = sNumber.Remove(sNumber.IndexOf('_'));
                            }
                            else
                            {
                                portInfo.SerialName = sNumber;
                            }

                            var deviceVidPid = registryPath[registryPath.Length - 3].ToUpperInvariant();
                            if (deviceVidPid != null && deviceVidPid.Length > 0 && deviceVidPid.Contains("pid_") && deviceVidPid.Contains("vid_"))
                            {
                                try
                                {
                                    char separator = '&';
                                    if (deviceVidPid.Contains('&'))
                                    {
                                        separator = '&';
                                    }
                                    else if (deviceVidPid.Contains('+'))
                                    {
                                        separator = '+';
                                    }

                                    var position = deviceVidPid.IndexOf("vid_") + 4;
                                    var vid      = deviceVidPid.Substring(position, deviceVidPid.IndexOf(separator) - position);

                                    position = deviceVidPid.IndexOf("pid_") + 4;
                                    var pid = deviceVidPid.Substring(position, deviceVidPid.Length - position);
                                    if (pid.Contains(separator))
                                    {
                                        pid = pid.Remove(pid.IndexOf(separator));
                                    }

                                    portInfo.DevicePid = int.Parse(pid, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                                    portInfo.DeviceVid = int.Parse(vid, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                                }
                                catch
                                {
                                }
                            }
                        }
                    }

                    RegistryType  type = RegistryType.REG_NONE;
                    UInt32        capacity;
                    StringBuilder data = new StringBuilder(256);
                    capacity = (UInt32)data.Capacity;
                    int result = Registry.RegQueryValueEx(hKey, "PortName", 0, ref type, data, ref capacity);

                    if ((result == Registry.ERROR_SUCCESS) & (type == RegistryType.REG_SZ))
                    {
                        portInfo.Name = data.ToString();

                        string property = GetDeviceRegistryProperty(hdevInfo, deviceInfoData, DeviceRegistryProperty.SPDRP_DEVICEDESC);
                        if (property != null)
                        {
                            portInfo.Description = property;
                        }

                        property = GetDeviceRegistryProperty(hdevInfo, deviceInfoData, DeviceRegistryProperty.SPDRP_MFG);
                        if (property != null)
                        {
                            portInfo.Manufacturer = property;
                        }

                        property = GetDeviceRegistryProperty(hdevInfo, deviceInfoData, DeviceRegistryProperty.SPDRP_FRIENDLYNAME);
                        if (property != null)
                        {
                            portInfo.FriendlyName = property;
                        }

                        property = GetDeviceRegistryProperty(hdevInfo, deviceInfoData, DeviceRegistryProperty.SPDRP_LOCATION_INFORMATION);
                        if (property != null)
                        {
                            portInfo.LocalInformation = property;
                        }

                        property = GetDeviceRegistryProperty(hdevInfo, deviceInfoData, DeviceRegistryProperty.SPDRP_SERVICE);
                        if (property != null)
                        {
                            portInfo.Service = property;
                        }
                    }

                    ports.Add(portInfo);

                    Registry.RegCloseKey(hKey);
                }
            }

            SetupDi.SetupDiDestroyDeviceInfoList(hdevInfo);
            //PatchInZModemSerials(ports);
            return(new ReadOnlyCollection <SerialPortInfo>(ports));
        }