Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 146723
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T08:39:15+00:00 2026-05-11T08:39:15+00:00

I am maintaining an application that uses SetupDiGetDeviceInterfaceDetail() to find out information on the

  • 0

I am maintaining an application that uses SetupDiGetDeviceInterfaceDetail() to find out information on the installed serial ports on the computer. I have noticed while testing this that there are some devices, such as my Lucent WinModem, that do not show up in that enumeration. It turns out that I am having a similar issue with a set of devices manufactured by my company that implement the serial port interface. My assumption is that there is something that is missing from the INF file for the device. Does anyone know what kinds of conditions can result in this kind of omission?

Edit: Here is a sample of the code that I am using to enumerate the serial ports. I have tried various combinations of flags but have not seen any significant difference in behaviour.

DEFINE_GUID(GUID_CLASS_COMPORT, 0x4d36e978, 0xe325, 0x11ce, 0xbf, 0xc1, \             0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18);   GUID *serial_port_guid = const_cast<GUID *>(&GUID_CLASS_COMPORT); HDEVINFO device_info = INVALID_HANDLE_VALUE; SP_DEVICE_INTERFACE_DETAIL_DATA *detail_data = 0;  device_info = SetupDiGetClassDevs(    serial_port_guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(device_info != INVALID_HANDLE_VALUE) {    uint4 const detail_data_size = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;    detail_data = reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA *>(new char[detail_data_size]);    SP_DEVICE_INTERFACE_DATA ifc_data;    bool more_interfaces = true;    int rcd;    memset(&ifc_data, 0, sizeof(ifc_data));     memset(detail_data, 0, detail_data_size);    ifc_data.cbSize = sizeof(ifc_data);    detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);    for(uint4 index = 0; more_interfaces; ++index)    {       rcd = SetupDiEnumDeviceInterfaces(device_info, 0, serial_port_guid, index, &ifc_data);       if(rcd)       {          // we need to get the details of this device          SP_DEVINFO_DATA device_data = { sizeof(SP_DEVINFO_DATA) };          rcd = SetupDiGetDeviceInterfaceDetail(             device_info, &ifc_data, detail_data, detail_data_size, 0, &device_data);          if(rcd)          {             StrAsc device_path(detail_data->DevicePath);             byte friendly_name[256];              rcd = SetupDiGetDeviceRegistryProperty(                device_info, &device_data, SPDRP_FRIENDLYNAME, 0, friendly_name, sizeof(friendly_name), 0);             if(rcd)             {                std::for_each(                   port_names.begin(),                   port_names.end(),                   update_friendly_name(                      reinterpret_cast<char const *>(friendly_name)));             }          }          else             more_interfaces = false;       }    } } 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-11T08:39:15+00:00Added an answer on May 11, 2026 at 8:39 am

    I decided to punt on this and to do away with the dependency on the SetupDi() functions. Instead, I have written code that traverses the subkeys in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum to find any drivers that support the serial port GUID. I have the feeling that this is what the device manager does. In case anyone is interested, my code fragment can be seen below:

    typedef std::string StrAsc; typedef std::pair<StrAsc, StrAsc> port_name_type; typedef std::list<port_name_type> friendly_names_type; void SerialPortBase::list_ports_friendly(friendly_names_type &port_names) {    // we will first get the list of names.  This will ensure that, at the very least, we get    // the same list of names as we would have otherwise obtained.     port_names_type simple_list;    list_ports(simple_list);    port_names.clear();    for(port_names_type::iterator pi = simple_list.begin(); pi != simple_list.end(); ++pi)       port_names.push_back(friendly_name_type(*pi, *pi));     // we will now need to enumerate the subkeys of the Enum registry key. We will need to    // consider many levels of the registry key structure in doing this so we will use a list    // of key handles as a stack.    HKEY enum_key ;    char const enum_key_name[] = 'SYSTEM\\CurrentControlSet\\Enum';    StrAsc const com_port_guid('{4d36e978-e325-11ce-bfc1-08002be10318}');    char const class_guid_name[] = 'ClassGUID';    char const friendly_name_name[] = 'FriendlyName';    char const device_parameters_name[] = 'Device Parameters';    char const port_name_name[] = 'PortName';    long rcd = ::RegOpenKeyEx(       HKEY_LOCAL_MACHINE, enum_key_name, 0, KEY_READ, &enum_key);    char value_buff[MAX_PATH];    StrAsc port_name, friendly_name;     if(!port_names.empty() && rcd == ERROR_SUCCESS)    {       std::list<HKEY> key_stack;       key_stack.push_back(enum_key);       while(!key_stack.empty())       {          // we need to determine whether this key has a 'ClassGUID' value          HKEY current = key_stack.front();          uint4 value_buff_len = sizeof(value_buff);          key_stack.pop_front();          rcd = ::RegQueryValueEx(             current,             class_guid_name,             0,             0,             reinterpret_cast<byte *>(value_buff),             &value_buff_len);          if(rcd == ERROR_SUCCESS)          {             // we will only consider devices that match the com port GUID             if(com_port_guid == value_buff)             {                // this key appears to identify a com port.  We will need to get the friendly name                // and try to get the 'PortName' from the 'Device Parameters' subkey.  Once we                // have those things, we can update the friendly name in our original list                value_buff_len = sizeof(value_buff);                rcd = ::RegQueryValueEx(                   current,                   friendly_name_name,                   0,                   0,                   reinterpret_cast<byte *>(value_buff),                   &value_buff_len);                if(rcd == ERROR_SUCCESS)                {                   HKEY device_parameters_key;                   rcd = ::RegOpenKeyEx(                      current,                      device_parameters_name,                      0,                      KEY_READ,                      &device_parameters_key);                   if(rcd == ERROR_SUCCESS)                   {                      friendly_name = value_buff;                      value_buff_len = sizeof(value_buff);                      rcd = ::RegQueryValueEx(                         device_parameters_key,                         port_name_name,                         0,                         0,                         reinterpret_cast<byte *>(value_buff),                         &value_buff_len);                      if(rcd == ERROR_SUCCESS)                      {                         friendly_names_type::iterator fi;                         port_name = value_buff;                         fi = std::find_if(                            port_names.begin(), port_names.end(), port_has_name(port_name));                         if(fi != port_names.end())                            fi->second = friendly_name;                      }                      ::RegCloseKey(device_parameters_key);                   }                }             }          }          else          {             // since this key did not have what we expected, we will need to check its             // children             uint4 index = 0;             rcd = ERROR_SUCCESS;             while(rcd == ERROR_SUCCESS)             {                value_buff_len = sizeof(value_buff);                rcd = ::RegEnumKeyEx(                   current, index, value_buff, &value_buff_len, 0, 0, 0, 0);                if(rcd == ERROR_SUCCESS)                {                   HKEY child;                   rcd = ::RegOpenKeyEx(current, value_buff, 0, KEY_READ, &child);                   if(rcd == ERROR_SUCCESS)                      key_stack.push_back(child);                }                ++index;             }          }          ::RegCloseKey(current);       }    } } // list_ports_friendly 
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've got a J2SE application that I am maintaining uses JNDI. (It uses JNDI
I'm maintaining an application that uses SQL Server Express 2005 as the back end.
I have a legacy Struts 1.2.8 application that I'm maintaining and porting from Oracle
I am maintaining an application that was written in Visual Basic 6.0 and makes
I'm maintaining a web application that utilizes the provider pattern as described below, for
I am looking at an asp.net 2 web application that I am maintaining (but
I am building a web application that uses the database for Users, Security/roles, and
I'm working on an ASP.NET web application that uses a lot of JavaScript on
I'm maintaining a rails 2.1 application that has some unfortunate choices for column names.
We're maintaining an old video game that uses a full-screen 256-color graphics mode with

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.