## EnumSerialPorts v1.16

Welcome to EnumSerialPorts, A simple set of MFC/ATL functions to enumerate the serial ports installed on your machine.

Features
Usage
Copyright
History
API Reference
Contacting the Author

## Features

- Simple C++ class interface.
- The code works on both Windows 95/98, NT, 2000, XP, 2003 and Vista.
- The code is fully Unicode compliant and include Unicode built options in the workspace file.
- Can be compiled with or without MFC support. If you do not want MFC support, then the code falls back to using the ATL CSimpleArray classes. Please note that this non MFC mode requires a recentish copy of Visual Studio and will not support Visual C++ 6.0 as the code makes use of the ATL CString class.

## Usage

- To use the functions in your code simply include enumser.cpp in your project and #include enumser.h in which ever of your modules needs to make calls to the function.
- You will need an up to date Platform SDK installed to compile the code if you are using an older compiler such as Visual C++ 6 (February 2003 was the last version which was compatible with VC 6). For further information on this, please see my blog entry from April 14 2007 titled "Common problems compiling my code" at http://naughter.spaces.live.com/blog/. Also note that on this older compiler you will only be able to use the MFC mode of the class.
- Your code will need to include MFC either statically or dynamically.
- To see the class in action, have a look at the main function in the module "main.cpp".

## Copyright

- You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) when your product is released in binary form.
- You are allowed to modify the source code in any way you want except you cannot modify the copyright details at the top of each module.
- If you want to distribute source code with your application, then you are only allowed to distribute versions released by the author. This is to maintain a single distribution point for the source code.

## History

v1.0 (3 November 1998)

- Initial public release.

v1.01 (23 February 1999)

- Code now uses QueryDosDevice if running on NT to determine which serial ports are available. This avoids having to open the ports at all. It should operate a lot faster in addition.

v1.02 (12 December 1999)

- Fixed a problem in the Win9x code path when trying to detect deactivated IRDA-ports. When trying to open those, you will get the error-code ERROR_GEN_FAILURE.

v1.03 (17 May 2000)

- Code now uses GetDefaultCommConfig in all cases to detect the ports.

v1.04 (29 March 2001)

- Reverted code to use CreateFile or QueryDosDevice as it is much faster than using the GetDefaultCommConfig method.
- Updated copyright message.

v1.05 (25 June 2001)

- Guess what, You now have the choice of using the GetDefaultCommConfig thro the use of three versions of the function. You take your pick.
- Fixed problem where port fails to be reported thro the CreateFile mechanism when the error code is ERROR_SHARING_VIOLATION i.e. someone has the port already open.

v1.06 (11 August 2001)

- Made code path which uses QueryDosDevice more robust by checking to make sure the device name is of the form "COMxyz.." where xyz are numeric.

v1.07 (13 August 2001)

- Made the code in IsNumeric more robust when sent an empty string
- Optimized the code in EnumerateSerialPorts2 somewhat. Thanks to Dennis Lim for these suggestions.

v1.08 (22 May 2003)

- Updated copyright details.
- Addition of a EnumerateSerialPorts4 which uses Device Manager API

v1.09 (20 September 2003)

- Addition of a "EnumerateSerialPorts5" method. This method (hopefully the last method!) uses EnumPorts and was provided by Andi Martin.

v1.10 (12 December 2003)

- Updated the sample app to VC 6.
- Addition of a "EnumerateSerialPorts6" (See Note 4 below) which uses WMI.
- You can now optionally exclude each function using preprocessor defines of the form "NO_ENUMSERIAL_USING_XYX".
- Made the functions members of a C++ class and renamed them to using more meaningful names

v1.11 (13 May 2004)

- Extended CEnumerateSerial::UsingSetupAPI to now also return the friendly name of the port. Thanks to Jay C. Howard for prompting this update.

v1.12 (9 July 2006)

- Updated copyright details.
- Addition of a CENUMERATESERIAL_EXT_CLASS macro to allow the code to be easily added to an extension dll
- Code now uses newer C++ style casts instead of C style casts.
- Updated the code to clean compile on VC 2005.
- Updated the documentation to use the same style as the web site.

v1.13 (8 November 2006)

- Extended CEnumerateSerial::UsingWMI to now also return the friendly name of the port. Thanks to Giovanni Bajo for providing this update.
- Fixed a bug where CEnumerateSerial::UsingSetupAPI forget to empty out the Friendly name array on start.
- VariantInit is now called for the 2 VARIANT structs used in the UsingWMI method code.

v1.14 (29 January 2007)

- Updated copyright details.
- UsingSetupAPI code now uses the GUID_DEVINTERFACE_COMPORT guid to enumerate COM ports. Thanks to David McMinn for reporting this nice addition.
- Detection code which uses CreateFile call, now treats the error code of ERROR_SEM_TIMEOUT as indication that a port is present.

v1.15 (9 June 2007)

- Following feedback from John Miles, it looks like my previous change of the 29 January 2007 to use GUID_DEVINTERFACE_COMPORT in the UsingSetupAPI method had the unintended consequence of causing this method not to work on any versions of Windows prior to Windows 2000. What I have now done is reinstate the old mechanism using the name UsingSetupAPI2 so that you can continue to use this approach if you need to support NT 4 and Windows 9x. The new approach of using GUID_DEVINTERFACE_COMPORT has been renamed to UsingSetupAPI1.

v1.16 (5 July 2007)

- Updated the code to work if the code does not include MFC. In this case, CUIntArray parameters becomes the ATL class CSimpleArray<UINT> and CStringArray parameters become the ATL class CSimpleArray<CString>. Please note that this support requires a recentish copy of Visual Studio and will not support Visual C++ 6.0 as the code makes use of the ATL CString class. Thanks to Michael Venus for prompting this update.
- CEnumerateSerial::UsingWMI method now uses ATL smart pointers to improve robustness of the code.

API Reference

CEnumerateSerial::UsingCreateFile

BOOL CEnumerateSerial::UsingCreateFile(CUIntArray& ports);

Parameters

ports Upon return this array will contain the port numbers of all the serial ports installed on the computer

Remarks

This function uses the CreateFile method of detecting serial ports. This will work on all Win32 OS'es, but requires actually opening the port. If you compile the code without MFC support, then the CUIntArray parameter becomes the ATL class CSimpleArray<UINT>.

CEnumerateSerial::UsingQueryDosDevice

BOOL CEnumerateSerial::UsingQueryDosDevice(CUIntArray& ports);

Parameters

ports Upon return this array will contain the port numbers of all the serial ports installed on the computer

Remarks

This function uses the QueryDosDevice method of detect serial ports. Please note that this only works correctly on NT, Windows 2000, XP or 2003. If you compile the code without MFC support, then the CUIntArray parameter becomes the ATL class CSimpleArray<UINT>.

CEnumerateSerial::UsingGetDefaultCommConfig

BOOL CEnumerateSerial::UsingGetDefaultCommConfig(CUIntArray& ports);

Parameters

ports Upon return this array will contain the port numbers of all the serial ports installed on the computer

Remarks

This function uses the GetDefaultCommConfig method of detect serial ports. Please note that this is the most compatible way of detecting serial ports and will work on all Win32 OS'es from Windows 95 onwards but also happens to be the slowest. If you compile the code without MFC support, then the CUIntArray parameter becomes the ATL class CSimpleArray<UINT>.

CEnumerateSerial::UsingSetupAPI1

BOOL CEnumerateSerial::UsingSetupAPI1(CUIntArray& ports, CStringArray& sFriendlyNames);

Parameters

ports Upon return this array will contain the port numbers of all the serial ports installed on the computer

sFriendlyNames Upon return this array will contain the Friendly names as appears in the Device Manager corresponding to the serial ports returned in "ports".

Remarks

This function uses the Device Manager "SetupDi.." APIs and the value GUID_DEVINTERFACE_COMPORT device interface class to detect serial ports. Please note that this will only work on Windows 2000 or later. If you compile the code without MFC support, then the CUIntArray parameter becomes the ATL class CSimpleArray<UINT> and the CStringArray parameter becomes the ATL class CSimpleArray<CString>.

CEnumerateSerial::UsingSetupAPI2

BOOL CEnumerateSerial::UsingSetupAPI2(CUIntArray& ports, CStringArray& sFriendlyNames);

Parameters

ports Upon return this array will contain the port numbers of all the serial ports installed on the computer

sFriendlyNames Upon return this array will contain the Friendly names as appears in the Device Manager corresponding to the serial ports returned in "ports".

Remarks

This function uses the Device Manager "SetupDi.." APIs and the "Ports" device information set to detect serial ports. The code of course implements logic to exclude parallel ports from the returned array as they are included in the "Ports" device information set in addition to serial ports. This approach will work on all Win32 OS'es from Windows 95 onwards. If you compile the code without MFC support, then the CUIntArray parameter becomes the ATL class CSimpleArray<UINT> and the CStringArray parameter becomes the ATL class CSimpleArray<CString>.

CEnumerateSerial::UsingEnumPorts

BOOL CEnumerateSerial::UsingEnumPorts(CUIntArray& ports);

Parameters

ports Upon return this array will contain the port numbers of all the serial ports installed on the computer

Remarks

This function uses the Win32 SDK call "EnumPorts" APIs to detect serial ports. This will work on all Win32 OS'es from Windows 95 onwards. If you compile the code without MFC support, then the CUIntArray parameter becomes the ATL class CSimpleArray<UINT>.

CEnumerateSerial::UsingWMI

BOOL CEnumerateSerial::UsingWMI(CUIntArray& ports, CStringArray& sFriendlyNames);

Parameters

ports Upon return this array will contain the port numbers of all the serial ports installed on the computer

sFriendlyNames Upon return this array will contain the Friendly names as reported using WMI corresponding to the serial ports returned in "ports".

Remarks

This function uses the WMI COM interfaces to detect serial ports. This will only work on Windows NT 4 SP4, Windows 2000, XP or 2003 (i.e versions of Windows on which WMI is available). If you compile the code without MFC support, then the CUIntArray parameter becomes the ATL class CSimpleArray<UINT> and the CStringArray parameter becomes the ATL class CSimpleArray<CString>.

## Contacting the Author

PJ Naughter
Email: pjna@naughter.com
Web: http://www.naughter.com
5 July 2007