Click here to Skip to main content
15,884,298 members
Articles / Mobile Apps
Article

Another serial port enumerator

Rate me:
Please Sign up or sign in to vote.
4.35/5 (22 votes)
8 Sep 20054 min read 235.8K   9.8K   78   29
A library for enumeration of serial ports that works on 9x, NT 4.0 and 2000, XP and CE platforms

Introduction

ListPorts is a function that lists all serial ports available on the system, along with some descriptive text suitable to be shown to the user in place of the somewhat terse "COM1", "COM2", etc. You can see an example of this on the "Port" combobox at the system Modem properties dialog box.

PJ Naughter has already wrote some code with this very purpose (see EnumSerialPorts at CodeProject, or click here for the latest version of his library). ListPorts has, IMHO, some advantages with respect to PJ Naughter's approach:

  • it does not depend on MFC,
  • it seems to handle non-standard ports (virtual, infrared) somewhat better,
  • descriptive text is provided for each port,
  • works for Windows CE.

Anyway, we wouldn't like to be blamed for proselytism: please compare both approaches and make your own choice.

Usage

listports.h header provides the following C language definitions:

typedef struct
{
  LPCTSTR lpPortName;
  LPCTSTR lpFriendlyName;
  LPCTSTR lpTechnology;
}LISTPORTS_PORTINFO;

typedef BOOL (CALLBACK* LISTPORTS_CALLBACK)(LPVOID lpCallbackValue,
                                            LISTPORTS_PORTINFO* lpPortInfo);

BOOL ListPorts(LISTPORTS_CALLBACK lpCallback,LPVOID lpCallbackValue);

LISTPORTS_PORTINFO holds information about a particular serial port: lpPortName holds the typical "COMn" string with which one can get a handle to the port via CreateFile(), whereas lpFriendlyName holds a fuller description of the port (vg., "Infrared Communications Port (COM4)"). On those systems where it is supported, lpTechnology names the technology upon which the serial port operates: typical values are "BIOS", "INFRARED", "USB", etc.

LISTPORTS_CALLBACK defines a user-supplied callback routine that is provided the information on each serial port available on the system on successive calls from ListPorts. Do in your callback whatever that suits your needs: dump the information on to the console, plug it into a listbox or store it for later use. Please note, however, that the strings stored on the LISTPORTS_PORTINFO are not to be referenced after the callbacks returns: so, if you plan on storing the values you should make private copies of them instead.

If your callback returns FALSE, the enumeration is aborted.

ListPorts accepts an additional parameter named lpCallbackValue. This is treated opaquely by the library and passed to your callback, so that you can use it for your particular purposes (telling between different invocations to ListPorts or storing a pointer to some object responsible of using the results, for instance). This is a standard technique used in many callback-based APIs, anyway.

Please see the demo project for a particularly simple example of the use of the library.

Cross-platform issues

ListPorts works on the following OSs:

  • Windows 95, 98, ME
  • Windows NT 4.0
  • Windows 2000, XP
  • Windows CE

But there are several shortcomings depending on the operating system. On NT 4.0, we haven't been able to locate the description text for the serial ports (actually we suspect NT 4.0 does not have these): instead, the bare "COMn" strings are supplied. The lpTecnhlogy field is not available for NT 4.0 and Windows CE platforms.

Windows CE devices have vendor-specific customizations of the operating system low-level layers which may not adjust to the algorithm used by ListPorts: our practical tests have shown, however, that the probability of ListPorts missing to locate some ports in Windows CE is very low.

Unicode

The code compiles and works just fine in Unicode, with macros UNICODE and _UNICODE defined.

Technical

If you don't have curiosity about the internals of the library, skip this section.

ListPorts finds the information on the serial ports available on the system by scanning the registry. On Windows 9x platforms, information on installed devices is stored under the HKEY_LOCAL_MACHINE\Enum key. The enumeration tree has three levels, and devices are described at the deepest one. For instance, a standard UART serial port built into the motherboard and recognized by the BIOS could be stored like this:

HKLM\ENUM
  |-BIOS
    |-*PNP0501
      |-0D (or any other value, this is not important for us)
        · CLASS=        "Ports"
        · PORTNAME=     "COM1"
        · FRIENDLYNAME= "Communications Port (COM1)"

The value CLASS identifies the type of device and is used by ListPorts to pinpoint the communications ports.

On Windows 2000/XP, the situation is very similar, except that the enumeration tree is located at HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum, and CLASS is deprecated in favor of a CLASSGUID identifier based on COM unique identifiers.

Windows NT 4.0 lacks a fully developed device enumeration tree. Information on serial ports can be found at HKEY_LOCAL_MACHINE\Hardware\DEVICEMAP\SERIALCOMM, but no FRIENDLYNAME is provided here.

Windows CE stores serial port entries along with other communications ports under HKLM\Drivers\BuiltIn.

The method used by the library is discussed in greater detail at the comments of the code in listports.c file.

New in version 2.0 (August 2005)

  • New lpTecnhlogy field.
  • Support for Windows CE platforms.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Spain Spain
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWill this work with Vista? Pin
PlusPlus6-Sep-07 18:49
PlusPlus6-Sep-07 18:49 
AnswerRe: Will this work with Vista? Pin
Joaquín M López Muñoz8-Sep-07 12:10
Joaquín M López Muñoz8-Sep-07 12:10 
AnswerRe: Will this work with Vista? Pin
NigelQ12-Sep-07 8:18
NigelQ12-Sep-07 8:18 
GeneralGoto Pin
bradley.jarvis9-Dec-06 20:47
bradley.jarvis9-Dec-06 20:47 
GeneralRe: Goto Pin
Joaquín M López Muñoz17-Dec-06 11:37
Joaquín M López Muñoz17-Dec-06 11:37 
GeneralBug in QueryStringValue() Pin
slkirtbzqmlyuk12-Dec-05 8:09
slkirtbzqmlyuk12-Dec-05 8:09 
GeneralRe: Bug in QueryStringValue() Pin
Joaquín M López Muñoz13-Dec-05 2:53
Joaquín M López Muñoz13-Dec-05 2:53 
GeneralEnumerating registry Pin
Vladimir Afanasyev9-Sep-05 1:50
Vladimir Afanasyev9-Sep-05 1:50 
GeneralRe: Enumerating registry Pin
Tony Kmoch9-Sep-05 2:01
Tony Kmoch9-Sep-05 2:01 
GeneralThanks, Pin
Jon Lynes7-Feb-05 4:24
Jon Lynes7-Feb-05 4:24 
GeneralRe: Thanks, Pin
Joaquín M López Muñoz7-Feb-05 9:26
Joaquín M López Muñoz7-Feb-05 9:26 
Generaldialog based applicaton interaction Pin
moto muzphee5-Jun-04 23:40
moto muzphee5-Jun-04 23:40 
GeneralClaim/release Serial port Pin
orfeas2912-Apr-04 23:55
orfeas2912-Apr-04 23:55 
GeneralRe: Claim/release Serial port Pin
Anonymous3-Oct-05 16:52
Anonymous3-Oct-05 16:52 
GeneralRunning on a laptop Pin
rrjimlad4-Dec-03 6:39
rrjimlad4-Dec-03 6:39 
GeneralUsing registry works much better Pin
conrad Braam20-Oct-03 1:50
conrad Braam20-Oct-03 1:50 
GeneralRe: Using registry works much better Pin
Joaquín M López Muñoz20-Oct-03 2:34
Joaquín M López Muñoz20-Oct-03 2:34 
GeneralRe: Using registry works much better Pin
conrad Braam20-Oct-03 2:49
conrad Braam20-Oct-03 2:49 
GeneralRe: Using registry works much better Pin
David Crow13-Feb-09 2:57
David Crow13-Feb-09 2:57 
GeneralDetecting devices Pin
joelparker17-Jun-03 7:07
joelparker17-Jun-03 7:07 
GeneralRe: Detecting devices Pin
Joaquín M López Muñoz17-Jun-03 7:14
Joaquín M López Muñoz17-Jun-03 7:14 
GeneralGreat! Pin
Hofver7-Apr-03 5:18
Hofver7-Apr-03 5:18 
Generalit work on XP, but... Pin
20-Jun-02 4:50
suss20-Jun-02 4:50 
Generalit work on XP, but... Pin
20-Jun-02 4:49
suss20-Jun-02 4:49 
GeneralNot so good... Pin
Christian B25-Jul-01 1:21
Christian B25-Jul-01 1:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.