Auto Seeking USB Com Port in Windows

After you read previous article, I might know how to operate a com port in Windows.

But that example requires programmer (or user, if you modified that example being able to support inputting command line) to set a com port number, it is not consummate. I will fill the flaw in here.

You need to check the device enumeration path zeroth. In here, I use CH340 (USB com port chip from China)

You need to set hSerial as invalid in the begining of that code:

hSerial = INVALID_HANDLE_VALUE;

And you should replace that as the code below:

 hSerial = CreateFile(&comPortName[0], GENERIC_READ|GENERIC_WRITE, 0, NULL,
                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

as

 if(0 == strncmp(&comPortName[0], "\\\\.\\COM0", MAX_STR_LEN))
 {
  unsigned int i;

  COMMCONFIG comConfig;
  DWORD dwSize;
  dwSize = sizeof(comConfig);

  ZeroMemory(&comConfig, sizeof(COMMCONFIG));

  for(i = 1; i< 256; i++){
   TCHAR comName[16];

   sprintf(&comName[0], "COM%d", i);

   if(FALSE != GetDefaultCommConfig(&comName[0], &comConfig, &dwSize))
    printf("found %s\n", &comName[0]);
  }/*for */

 }

 if(0 == strncmp(&comPortName[0], "\\\\.\\COM0", MAX_STR_LEN))
 {
  DWORD dwGuids;
  GUID *pGuids;  

  HDEVINFO hDevInfo;
  SP_DEVICE_INTERFACE_DATA devInterfaceData;
  SP_DEVINFO_DATA devInfoData;
  unsigned int index;

  dwGuids = 0;

  isSuc = SetupDiClassGuidsFromName("Ports", NULL, 0, &dwGuids);

  pGuids = (GUID*)malloc(dwGuids*sizeof(GUID));
  ZeroMemory(pGuids, dwGuids*sizeof(GUID));
  isSuc = SetupDiClassGuidsFromName("Ports", pGuids, dwGuids, &dwGuids);

  hDevInfo = SetupDiGetClassDevs(pGuids, NULL, NULL,
  /*DIGCF_ALLCLASSES | DIGCF_PRESENT |*/ DIGCF_DEVICEINTERFACE);  

  index = 0;

  ZeroMemory(&devInfoData, sizeof(SP_DEVINFO_DATA));
  devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

        while(SetupDiEnumDeviceInfo(hDevInfo, index, &devInfoData))
  {   

   TCHAR szDeviceInstanceID[1024];            

   index++;

   isSuc = CM_Get_Device_ID(devInfoData.DevInst,
     &szDeviceInstanceID[0] , sizeof(szDeviceInstanceID), 0);

   //printf("%s\n", &szDeviceInstanceID[0]);

   if(0 == strncmp(&szDeviceInstanceID[0], "USB\\VID_1A86&PID_7523",
    strlen("USB\\VID_1A86&PID_7523")) )
   {

    DWORD requiredSize;
    GUID classGuid;

    SP_DEVICE_INTERFACE_DATA   devInterfaceData;
    SP_DEVICE_INTERFACE_DETAIL_DATA *pDevInterfaceDetailData;

    printf("&szDeviceInstanceID[0] = %s\n", &szDeviceInstanceID[0]);

    ZeroMemory(&devInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA)); 

    devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    classGuid = devInfoData.ClassGuid;

    isSuc = SetupDiEnumDeviceInterfaces(hDevInfo, &devInfoData, pGuids,
     0, &devInterfaceData);    

    isSuc = SetupDiGetDeviceInterfaceDetail(hDevInfo,
     &devInterfaceData, NULL, NULL, &requiredSize, NULL);

    //printf ("%s\n", GetLastErrorMessage( GetLastError() ) );

    pDevInterfaceDetailData = (SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(requiredSize);       

    pDevInterfaceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

    isSuc = SetupDiGetDeviceInterfaceDetail( hDevInfo,
     &devInterfaceData, pDevInterfaceDetailData, requiredSize,
     &requiredSize, &devInfoData);

    printf("devInterfaceDetailData.DevicePath = %s\n",
     pDevInterfaceDetailData->DevicePath);

    hSerial = CreateFile(pDevInterfaceDetailData->DevicePath,
     GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
     FILE_ATTRIBUTE_NORMAL, NULL );

    free(pDevInterfaceDetailData); pDevInterfaceDetailData = NULL;

    if(INVALID_HANDLE_VALUE != hSerial)
     break;
   }
  }           

  free(pGuids); pGuids = NULL;
  SetupDiDestroyDeviceInfoList(hDevInfo);

  if(INVALID_HANDLE_VALUE == hSerial)
  {
   printf("auto seeking com number fail!!\n");
   return 0;
  }
 }
 else /*non auto seeking com port*/
 {
  hSerial = CreateFile(&comPortName[0], GENERIC_READ | GENERIC_WRITE,
   0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
 }/*if auto seeking com port*/

("\\\\.\\COM0" be  auto-seeking mode in here.)

You have to modify the USB\\VID_1A86&PID_7523 as your device‘s.

( If you use FTDI‘s FT232B  or FT232R, that should be

FTDIBUS\\VID_0403+PID_6001

)

That would support auto-seeking com-port.

Note the line :

        while(SetupDiEnumDeviceInfo(hDevInfo, index, &devInfoData))

You would find NOT ONLY one device as VID_1A86&PID_7523, even you have plugged only one CH340. If you print that seeking result (it is just the line : printf("&szDeviceInstanceID[0] = %s\n", &szDeviceInstanceID[0]);), you would watch the printing as:

&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&1
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&1#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&2
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&2#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&3
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&3#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&4
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&4#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&5
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&5#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\7&107B0B49&0&2
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#7&107b0b49&0&2#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\7&14F85601&0&1
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#7&14f85601&0&1#{4d
36e978-e325-11ce-bfc1-08002be10318}

I do not know why Windows lists so much device path. AlI I could do, is to try opening each. you could find that the actual one‘s last 4 characters (like &0&4, &0&2..etc) would change with port number, that depends on which
USB socket you plug.

时间: 2024-11-06 09:43:54

Auto Seeking USB Com Port in Windows的相关文章

Methods Collection of Enumerating Com Port in Windows, by C

According to this stack overflow thread, PJ Naughter has implemented 9 methods to emunerate com port in Windows. That code was namedEnumSerialPorts. As my using, I found some method would list non-existed com ports. for example: My computer com port

将cocos2dx+lua创建的游戏port到windows phone

在整个Port的过程中遇到的问题总结如下 1.一定要使用最新版本的cocos2dx,原因大家看一下changelog就知道了,最近的cocos2dx版本都是在修windows phone上的bug,所以为了避免少出问题,还是直接升级到最新版本吧 2.如果你使用的是cocos2dx + lua方式,目前的project-creator并不支持lua版本的windows phone平台,但是cpp版本是支持的,因此我们可以在cpp版本的基础上把libcocoslua以及liblua两个工程加到项目中

ali Linux Web 渗透测试视频教—第二十课-利用kali linux光盘或者usb启动盘破解windows密码

Kali Linux Web 渗透测试视频教—第二十课-利用kali linux光盘或者usb启动盘破解windows密码 文/玄魂 目录 Kali Linux Web 渗透测试视频教—第二十课-利用kali linux光盘或者usb启动盘破解windows密码.......................................................................................................................

力特ZE398C驱动光盘-USB转RS232-支持Windows 10/Mac

这个工具是USB1.1的,相对来说比较老,一开始做小白鼠不知道买了USB1.1的,所以我不建议买这个,还有其它的型号,支持USB2.0和USB3.0,不过价格也相对来说比较贵,这个才30块钱左右. 关键力特使用了PL2303芯片,兼容性很好,Widnows 7+.Linux 2+.Mac 10.9+都可以支持. 比较吭的是驱动下载,官网上下载的驱动对于ZE398C是不能使用,只能驱动光盘的内容才能装的上,并且这个驱动光盘官网上不提供入口,但居然给我找到了:http://www.z-tek.com

[随笔] 老谢与Google的一次正面&quot;交锋&quot;

[随笔] 老谢与Google的一次正面"交锋" 一.废话 话说智能电视,国内液晶电视厂商确实引领着时代潮流.而从全球来看,继几年前Google I/O大会之后,也渐渐掀起一股智能电视热潮.Google Android开放系统在智能电视中的应用也开始崭露头角.Google和MediaTek在智能电视方向的绑定式发展也必将再次将Android智能电视的发展推向另外一个高度. 老谢有幸加入了Andriod大流,最近处理了一题,想和大家分享分享.与其说这次是老谢与Google的一次正面交锋,不

从USB驱动器运行Windows 10

我相信很多人和我一样.梦想着有个随身携带的U盘版操作系统.无论走到哪里,只要有电脑都可以随时运行自己配置好的操作系统.本篇博文就会一步步的教你如何从USB驱动器加载和运行Windows 10. 让我想象一个场景.也许你使用的电脑不是你自己的,里面的系统也许是XP或Win7 Win8,系统的设置也不太符合你工作的要求(比如他的计算机装的VS2005),肿么办呢,答案就是用自己配置好的并且挂载再USB驱动器里的操作系统. 首先,你需要一个USB闪存驱动器或外部硬盘驱动器,至少有16GB的可用空间,但

UEFI Bootable USB Flash Drive - Create in Windows(WIN7 WIN8)

How to Create a Bootable UEFI USB Flash Drive for Installing Windows 7, Windows 8, or Windows 8.1 Information This tutorial will show you how to create a Windows 7 or Windows 8 or 8.1 installation bootable USB flash drive for UEFIfrom either a Window

AM335x(TQ335x)学习笔记——USB驱动移植

对于AM335x来讲,TI维护的USB驱动已经非常完善了,本文称之为移植,实际上仅仅是配置内核选项使能USB HOST/OTG功能.废话少说,直接动手开启AM335x的USB驱动配置项. Step1. 配置内核支持USB 默认的配置项没有配置USB相关的选项,但是DTS已经配置好了,我们不需要对DTS作任何修改,详细的内核配置项如下: Device Drivers ---> [*] USB support ---> [*] OTG support <*> EHCI HCD (USB

USB组合设备 Interface Association Descriptor (IAD)

Communication Device Class,简称CDCUSB Compound Device,USB复合设备USB Composite Device,USB组合设备 摘要USB复合设备 Compound Device内嵌Hub和多个Function,每个Function都相当于一个独立的USB外设,有自己的PID/VID.USB组合设备Composite Device内只有一个Function,只有一套PID/VID,通过将不同的interface定义为不同的类来实现多个功能的组合.