您的位置:首页 > 其它

Seeking USB Serial Com Port in Windows Automatically : via PID VID

2016-03-24 10:27 585 查看
After you read
previous article, you 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), I assure there is only one CH340 connected to the computer, I could seek the comport via pid(product id) and vid (vendor
id).



If you do not know what is vid/pid : Briefly say, it is USB device firmware replying computer what device it is in seral number. We could use pid/vid + google to indentify the device, even there is no correspending driver.

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.


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: