【问题标题】:How come GetDefaultCommConfig fails on windows 10为什么 GetDefaultCommConfig 在 Windows 10 上失败
【发布时间】:2015-07-17 18:25:59
【问题描述】:

我使用以下代码来验证计算机上的串口名称是否有效:

typedef std::pair<StrAsc const, bool> port_pair_type;
typedef std::list<port_pair_type> port_pairs_type;
port_pairs_type pairs;
StrBin config_buffer;
 config_buffer.fill(0,sizeof(COMMCONFIG));
while(!pairs.empty())
{
   port_pair_type pair(pairs.front());
   pairs.pop_front();
   if(!pair.second)
   {
      // we need to get the default configuration for the port.  This may
      // require some fudging on the buffer size.  That is why two calls
      // are being made.
      uint4 config_size = config_buffer.length();
      StrUni temp(pair.first);
      COMMCONFIG *config(reinterpret_cast<COMMCONFIG *>(config_buffer.getContents_writable()));
      config->dwSize = sizeof(COMMCONFIG);
      rcd = GetDefaultCommConfigW(
         temp.c_str(), config, &config_size);
      if(!rcd && config_buffer.length() < config_size)
      {
         config_buffer.fill(0, config_size);
         config = reinterpret_cast<COMMCONFIG *>(config_buffer.getContents_writable());
         config->dwSize = sizeof(COMMCONFIG);
         rcd = GetDefaultCommConfigW(
            temp.c_str(),
            reinterpret_cast<COMMCONFIG *>(config_buffer.getContents_writable()),
                 &config_size);
      }

      // if the call succeeded, we can go ahead and look at the
      // configuration structure.
      if(rcd)
      {
         COMMCONFIG const *config = reinterpret_cast<COMMCONFIG const *>(
         config_buffer.getContents());
         if(config->dwProviderSubType == PST_RS232)
            port_names.push_back(pair.first);
      }
      else
      {
         OsException error("GetDefaultCommConfig Failed");
         trace("\"%s\"", error.what());
      }
   }
   else
      port_names.push_back(pair.first);
}

在 Windows 10 上,当尝试确认使用 usbser.sys 的串行端口时,对 GetDefaultCommConfig() 的调用失败,GetLastError() 返回的错误代码为 87(无效参数)。据我所知,usbser.sys 驱动程序已在 Windows 10 上重写,我怀疑这是该驱动程序的问题。有没有其他人知道可能出了什么问题?

【问题讨论】:

  • 每次使用reinterpret_cast 都会引发危险信号。仔细检查以确保您发送的COMMCONFIG 数据确实有效。将您的代码简化为您明确初始化 COMMCONFIG 的实例,并使用 known 值来工作。
  • @CaptainObvlious COMMCONFIG 是一个可变长度的结构,根据驱动程序的不同,它必须被放大以保存额外的信息。我在 StrBin(二进制缓冲区类)中执行此操作以管理此分配。
  • @CaptainObvlious 我要进一步指出,此代码适用于除使用 usbser.sys 驱动程序的端口之外的所有其他端口类型。它也适用于较旧的操作系统。
  • 设置的端口号是多少?请记住,带有“\\\\.\\COM20”之类的端口描述符将不起作用。另请参阅此帖子:stackoverflow.com/questions/13191777/…

标签: c++ winapi serial-port


【解决方案1】:

这是 usbser.sys 中的一个错误,并已在 2016 年 1 月 27 日的 Windows 10 更新 KB3124262 中得到修复。

微软员工解释说:

HKLM\HARDWARE\DEVICEMAP\SERIALCOMM 注册表中的 COM 端口名称不是以 NULL 结尾的。

Related discussion on MSDN

由于 Windows 10 的更新政策,此问题在未来不会再出现。

【讨论】:

    【解决方案2】:

    当您第二次调用 GetDefaultCommConfigW 时,您可能需要将 config-&gt;dwSize 设置为结构的新大小。例如:

    config->dwSize = config_size;
    

    【讨论】:

    • 我刚试过,似乎没什么区别。 GetDefaultCommConfig() 的文档指出 dwSize 参数应设置为 sizeof(COMMCONFIG)。
    • @JonTrauntvein 通常对于可以更改大小的结构,dwSize 成员设置为结构的实际大小。由于您正在重用缓冲区,因此您可能需要在每次调用时将其设置为 config_size 的值。您可能还需要在每次调用之前将缓冲区清零。
    • 查看msdn.microsoft.com/en-us/library/windows/desktop/… dwSize 的声明:“结构的大小,以字节为单位。调用者必须将此成员设置为 sizeof(COMMCONFIG)。”每次调用 GetDefaultCommConfig 之前,我都更改了代码以初始化结构,但这似乎没有任何区别。
    • @JonTrauntvein Microsoft 的文档有很多错误。根据文档,您的代码应该可以工作。
    • 我尝试将 dwSize 设置为分配的缓冲区大小,但根据我的经验,这个成员值似乎没有任何区别。我怀疑这是驱动程序实现问题。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多