使用serialEnum的方法枚举设备管理器里面Ports上的com口;
实际上我有3个com口可以看到:
CFAN Newyork USB To RS232 (com6)
Prolific USB-to-Serial Comm Port (com8)
蓝牙通信端口 (com4)然而只能枚举出来两个:
Prolific USB-to-Serial Comm Port (com8)
蓝牙通信端口 (com4)希望大虾们指点一下,下面是驱动安装的inf文件以及部分的代码;(代码里面ii=2,error=0x103后退出的,没有异常的返回)我的安装stmcdc.inf文件是:
;
; STMicroelectronics Comunication Device Class driver instalation file
; (C)2006 Copyright STMicroelectronics
;[Version]
Signature="$Windows NT$"
Class=Ports
;ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%STM%
LayoutFile=layout.inf
DriverVer=01/03/2011,2.0.9.122[Manufacturer]
%STM%=DeviceList[DestinationDirs]
DefaultDestDir=12 [SourceDisksFiles][SourceDisksNames][DeviceList]
%DESCRIPTION%=STMUSB, USB\VID_0483&PID_5740 ;------------------------------------------------------------------------------
; Windows 2000/XP Sections
;------------------------------------------------------------------------------[STMUSB.nt]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles
AddReg=STMUSB.nt.AddReg [DriverCopyFiles]
usbser.sys,,,0x20[STMUSB.nt.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" [STMUSB.nt.Services]
AddService=usbser, 0x00000002, DriverService
[STMUSB.nt.HW]
include=mdmcpq.inf[DriverService]
DisplayName=%DESCRIPTION%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys ;------------------------------------------------------------------------------
; String Definitions
;------------------------------------------------------------------------------[Strings]
STM="CFAN Technology"
DESCRIPTION="CFAN Newyork USB To RS232"
我的代码是:
//long NYA10_enumserial()
extern "C" long __declspec(dllexport) __stdcall NYA10_enumserial()
{
CArray<SSerInfo,SSerInfo&> asi;
CString buffer;
unsigned long compos1,compos2;
unsigned long com_port;
// Populate the list of serial ports.
EnumSerialPorts(asi,FALSE/*include all*/);
// m_listPorts.ResetContent();
for (int ii=0; ii<asi.GetSize(); ii++) {
//m_listPorts.AddString(asi[ii].strFriendlyName);
if(!strcmp(asi[ii].strPortDesc,"CFAN Newyork USB To RS232"))
//if(!strcmp(asi[ii].strPortDesc,"Prolific USB-to-Serial Comm Port"))
{
buffer=asi[ii].strFriendlyName;
compos1=buffer.Find("COM");
compos2=buffer.Find(")");
com_port=atol(buffer.Mid(compos1+3,compos2-compos1-3));
}
}
if (ii>asi.GetSize())
return 0;
else
return com_port;
}
======
//---------------------------------------------------------------
// Routine for enumerating the available serial ports.
// Throws a CString on failure, describing the error that
// occurred. If bIgnoreBusyPorts is TRUE, ports that can't
// be opened for read/write access are not included.
void EnumSerialPorts(CArray<SSerInfo,SSerInfo&> &asi, BOOL bIgnoreBusyPorts)
{
// Clear the output array
asi.RemoveAll();
// Use different techniques to enumerate the available serial
// ports, depending on the OS we're using
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!::GetVersionEx(&vi)) {
CString str;
str.Format("Could not get OS version. (err=%lx)",
GetLastError());
throw str;
}
// Handle windows 9x and NT4 specially
if (vi.dwMajorVersion < 5) {
if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT)
EnumPortsWNt4(asi);
else
EnumPortsW9x(asi);
}
else {
// Win2k and later support a standard API for
// enumerating hardware devices.
EnumPortsWdm(asi);
}
for (int ii=0; ii<asi.GetSize(); ii++)
{
SSerInfo& rsi = asi[ii];
if (bIgnoreBusyPorts) {
// Only display ports that can be opened for read/write
HANDLE hCom = CreateFile(rsi.strDevPath,
GENERIC_READ | GENERIC_WRITE,
0, /* comm devices must be opened w/exclusive-access */
NULL, /* no security attrs */
OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
0, /* not overlapped I/O */
NULL /* hTemplate must be NULL for comm devices */
);
if (hCom == INVALID_HANDLE_VALUE) {
// It can't be opened; remove it.
asi.RemoveAt(ii);
ii--;
continue;
}
else {
// It can be opened! Close it and add it to the list
::CloseHandle(hCom);
}
}
// Come up with a name for the device.
// If there is no friendly name, use the port name.
if (rsi.strFriendlyName.IsEmpty())
rsi.strFriendlyName = rsi.strPortName;
// If there is no description, try to make one up from
// the friendly name.
if (rsi.strPortDesc.IsEmpty()) {
// If the port name is of the form "ACME Port (COM3)"
// then strip off the " (COM3)"
rsi.strPortDesc = rsi.strFriendlyName;
int startdex = rsi.strPortDesc.Find(" (");
int enddex = rsi.strPortDesc.Find(")");
if (startdex > 0 && enddex ==
(rsi.strPortDesc.GetLength()-1))
rsi.strPortDesc = rsi.strPortDesc.Left(startdex);
}
}
}
=====
void EnumPortsWdm(CArray<SSerInfo,SSerInfo&> &asi)
{
CString strErr;
// Create a device information set that will be the container for
// the device interfaces.
GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT;
HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
try {
hDevInfo = SetupDiGetClassDevs( guidDev,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
);
if(hDevInfo == INVALID_HANDLE_VALUE)
{
strErr.Format("SetupDiGetClassDevs failed. (err=%lx)",
GetLastError());
throw strErr;
}
// Enumerate the serial ports
BOOL bOk = TRUE;
SP_DEVICE_INTERFACE_DATA ifcData;
DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize];
// This is required, according to the documentation. Yes,
// it's weird.
ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
for (DWORD ii=0; bOk; ii++) {
bOk = SetupDiEnumDeviceInterfaces(hDevInfo,
NULL, guidDev, ii, &ifcData);
if (bOk) {
// Got a device. Get the details.
SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)};
bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,
&ifcData, pDetData, dwDetDataSize, NULL, &devdata);
if (bOk) {
CString strDevPath(pDetData->DevicePath);
// Got a path to the device. Try to get some more info.
TCHAR fname[256];
TCHAR desc[256];
BOOL bSuccess = SetupDiGetDeviceRegistryProperty(
hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,
(PBYTE)fname, sizeof(fname), NULL);
bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty(
hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,
(PBYTE)desc, sizeof(desc), NULL);
BOOL bUsbDevice = FALSE;
TCHAR locinfo[256];
if (SetupDiGetDeviceRegistryProperty(
hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL,
(PBYTE)locinfo, sizeof(locinfo), NULL))
{
// Just check the first three characters to determine
// if the port is connected to the USB bus. This isn't
// an infallible method; it would be better to use the
// BUS GUID. Currently, Windows doesn't let you query
// that though (SPDRP_BUSTYPEGUID seems to exist in
// documentation only).
bUsbDevice = (strncmp(locinfo, "USB", 3)==0);
}
if (bSuccess) {
// Add an entry to the array
SSerInfo si;
si.strDevPath = strDevPath;
si.strFriendlyName = fname;
si.strPortDesc = desc;
si.bUsbDevice = bUsbDevice;
asi.Add(si);
}
}
else {
strErr.Format("SetupDiGetDeviceInterfaceDetail failed. (err=%lx)",
GetLastError());
throw strErr;
}
}
else {
DWORD err = GetLastError();
if (err != ERROR_NO_MORE_ITEMS) {
strErr.Format("SetupDiEnumDeviceInterfaces failed. (err=%lx)", err);
throw strErr;
}
}
}
}
catch (CString strCatchErr) {
strErr = strCatchErr;
}
if (pDetData != NULL)
delete [] (char*)pDetData;
if (hDevInfo != INVALID_HANDLE_VALUE)
SetupDiDestroyDeviceInfoList(hDevInfo);
if (!strErr.IsEmpty())
throw strErr;
}
void EnumPortsWNt4(CArray<SSerInfo,SSerInfo&> &asi)
{
// NT4's driver model is totally different, and not that
// many people use NT4 anymore. Just try all the COM ports
// between 1 and 16
SSerInfo si;
for (int ii=1; ii<=16; ii++) {
CString strPort;
strPort.Format("COM%d",ii);
si.strDevPath = CString("\\\\.\\") + strPort;
si.strPortName = strPort;
asi.Add(si);
}
}
实际上我有3个com口可以看到:
CFAN Newyork USB To RS232 (com6)
Prolific USB-to-Serial Comm Port (com8)
蓝牙通信端口 (com4)然而只能枚举出来两个:
Prolific USB-to-Serial Comm Port (com8)
蓝牙通信端口 (com4)希望大虾们指点一下,下面是驱动安装的inf文件以及部分的代码;(代码里面ii=2,error=0x103后退出的,没有异常的返回)我的安装stmcdc.inf文件是:
;
; STMicroelectronics Comunication Device Class driver instalation file
; (C)2006 Copyright STMicroelectronics
;[Version]
Signature="$Windows NT$"
Class=Ports
;ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%STM%
LayoutFile=layout.inf
DriverVer=01/03/2011,2.0.9.122[Manufacturer]
%STM%=DeviceList[DestinationDirs]
DefaultDestDir=12 [SourceDisksFiles][SourceDisksNames][DeviceList]
%DESCRIPTION%=STMUSB, USB\VID_0483&PID_5740 ;------------------------------------------------------------------------------
; Windows 2000/XP Sections
;------------------------------------------------------------------------------[STMUSB.nt]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles
AddReg=STMUSB.nt.AddReg [DriverCopyFiles]
usbser.sys,,,0x20[STMUSB.nt.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" [STMUSB.nt.Services]
AddService=usbser, 0x00000002, DriverService
[STMUSB.nt.HW]
include=mdmcpq.inf[DriverService]
DisplayName=%DESCRIPTION%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys ;------------------------------------------------------------------------------
; String Definitions
;------------------------------------------------------------------------------[Strings]
STM="CFAN Technology"
DESCRIPTION="CFAN Newyork USB To RS232"
我的代码是:
//long NYA10_enumserial()
extern "C" long __declspec(dllexport) __stdcall NYA10_enumserial()
{
CArray<SSerInfo,SSerInfo&> asi;
CString buffer;
unsigned long compos1,compos2;
unsigned long com_port;
// Populate the list of serial ports.
EnumSerialPorts(asi,FALSE/*include all*/);
// m_listPorts.ResetContent();
for (int ii=0; ii<asi.GetSize(); ii++) {
//m_listPorts.AddString(asi[ii].strFriendlyName);
if(!strcmp(asi[ii].strPortDesc,"CFAN Newyork USB To RS232"))
//if(!strcmp(asi[ii].strPortDesc,"Prolific USB-to-Serial Comm Port"))
{
buffer=asi[ii].strFriendlyName;
compos1=buffer.Find("COM");
compos2=buffer.Find(")");
com_port=atol(buffer.Mid(compos1+3,compos2-compos1-3));
}
}
if (ii>asi.GetSize())
return 0;
else
return com_port;
}
======
//---------------------------------------------------------------
// Routine for enumerating the available serial ports.
// Throws a CString on failure, describing the error that
// occurred. If bIgnoreBusyPorts is TRUE, ports that can't
// be opened for read/write access are not included.
void EnumSerialPorts(CArray<SSerInfo,SSerInfo&> &asi, BOOL bIgnoreBusyPorts)
{
// Clear the output array
asi.RemoveAll();
// Use different techniques to enumerate the available serial
// ports, depending on the OS we're using
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!::GetVersionEx(&vi)) {
CString str;
str.Format("Could not get OS version. (err=%lx)",
GetLastError());
throw str;
}
// Handle windows 9x and NT4 specially
if (vi.dwMajorVersion < 5) {
if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT)
EnumPortsWNt4(asi);
else
EnumPortsW9x(asi);
}
else {
// Win2k and later support a standard API for
// enumerating hardware devices.
EnumPortsWdm(asi);
}
for (int ii=0; ii<asi.GetSize(); ii++)
{
SSerInfo& rsi = asi[ii];
if (bIgnoreBusyPorts) {
// Only display ports that can be opened for read/write
HANDLE hCom = CreateFile(rsi.strDevPath,
GENERIC_READ | GENERIC_WRITE,
0, /* comm devices must be opened w/exclusive-access */
NULL, /* no security attrs */
OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
0, /* not overlapped I/O */
NULL /* hTemplate must be NULL for comm devices */
);
if (hCom == INVALID_HANDLE_VALUE) {
// It can't be opened; remove it.
asi.RemoveAt(ii);
ii--;
continue;
}
else {
// It can be opened! Close it and add it to the list
::CloseHandle(hCom);
}
}
// Come up with a name for the device.
// If there is no friendly name, use the port name.
if (rsi.strFriendlyName.IsEmpty())
rsi.strFriendlyName = rsi.strPortName;
// If there is no description, try to make one up from
// the friendly name.
if (rsi.strPortDesc.IsEmpty()) {
// If the port name is of the form "ACME Port (COM3)"
// then strip off the " (COM3)"
rsi.strPortDesc = rsi.strFriendlyName;
int startdex = rsi.strPortDesc.Find(" (");
int enddex = rsi.strPortDesc.Find(")");
if (startdex > 0 && enddex ==
(rsi.strPortDesc.GetLength()-1))
rsi.strPortDesc = rsi.strPortDesc.Left(startdex);
}
}
}
=====
void EnumPortsWdm(CArray<SSerInfo,SSerInfo&> &asi)
{
CString strErr;
// Create a device information set that will be the container for
// the device interfaces.
GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT;
HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
try {
hDevInfo = SetupDiGetClassDevs( guidDev,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
);
if(hDevInfo == INVALID_HANDLE_VALUE)
{
strErr.Format("SetupDiGetClassDevs failed. (err=%lx)",
GetLastError());
throw strErr;
}
// Enumerate the serial ports
BOOL bOk = TRUE;
SP_DEVICE_INTERFACE_DATA ifcData;
DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize];
// This is required, according to the documentation. Yes,
// it's weird.
ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
for (DWORD ii=0; bOk; ii++) {
bOk = SetupDiEnumDeviceInterfaces(hDevInfo,
NULL, guidDev, ii, &ifcData);
if (bOk) {
// Got a device. Get the details.
SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)};
bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,
&ifcData, pDetData, dwDetDataSize, NULL, &devdata);
if (bOk) {
CString strDevPath(pDetData->DevicePath);
// Got a path to the device. Try to get some more info.
TCHAR fname[256];
TCHAR desc[256];
BOOL bSuccess = SetupDiGetDeviceRegistryProperty(
hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,
(PBYTE)fname, sizeof(fname), NULL);
bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty(
hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,
(PBYTE)desc, sizeof(desc), NULL);
BOOL bUsbDevice = FALSE;
TCHAR locinfo[256];
if (SetupDiGetDeviceRegistryProperty(
hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL,
(PBYTE)locinfo, sizeof(locinfo), NULL))
{
// Just check the first three characters to determine
// if the port is connected to the USB bus. This isn't
// an infallible method; it would be better to use the
// BUS GUID. Currently, Windows doesn't let you query
// that though (SPDRP_BUSTYPEGUID seems to exist in
// documentation only).
bUsbDevice = (strncmp(locinfo, "USB", 3)==0);
}
if (bSuccess) {
// Add an entry to the array
SSerInfo si;
si.strDevPath = strDevPath;
si.strFriendlyName = fname;
si.strPortDesc = desc;
si.bUsbDevice = bUsbDevice;
asi.Add(si);
}
}
else {
strErr.Format("SetupDiGetDeviceInterfaceDetail failed. (err=%lx)",
GetLastError());
throw strErr;
}
}
else {
DWORD err = GetLastError();
if (err != ERROR_NO_MORE_ITEMS) {
strErr.Format("SetupDiEnumDeviceInterfaces failed. (err=%lx)", err);
throw strErr;
}
}
}
}
catch (CString strCatchErr) {
strErr = strCatchErr;
}
if (pDetData != NULL)
delete [] (char*)pDetData;
if (hDevInfo != INVALID_HANDLE_VALUE)
SetupDiDestroyDeviceInfoList(hDevInfo);
if (!strErr.IsEmpty())
throw strErr;
}
void EnumPortsWNt4(CArray<SSerInfo,SSerInfo&> &asi)
{
// NT4's driver model is totally different, and not that
// many people use NT4 anymore. Just try all the COM ports
// between 1 and 16
SSerInfo si;
for (int ii=1; ii<=16; ii++) {
CString strPort;
strPort.Format("COM%d",ii);
si.strDevPath = CString("\\\\.\\") + strPort;
si.strPortName = strPort;
asi.Add(si);
}
}
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
但是在设备管理里面只有3个,分别是com4,com6,com8;
这个怎么准确的找出我需要的com6;
谢谢!