|
does anyone know how to modify the enumseral code so that only the usb port can be populated on the output screen? i've been trying to modify it but haven't find any luck.
|
|
|
|
|
Hi
In VS2008 C++ this code works fine but in Borland C++ 6.0 SetupDiGetDeviceInterfaceDetail fails with ERROR_INVALID_USER_BUFFER.
I also tried this:
SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, NULL, 0, &dwDetDataSize, &devdata);
pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize];
pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, pDetData, dwDetDataSize, &dwDetDataSize, &devdata);
and it failed too with same error.
Do you have any idea why?
|
|
|
|
|
I have a situation in which I need to communicate with USB printer bidirectionally. This I can do, but there may be 2 identical printers on one system. I need to be able to recognize which is which based on friendly (spooler) name for printer.
Anyone?
|
|
|
|
|
Hello,
I don't find here strPortName the simple port name. also i need the baudrate,data bits, parity, stop bits, flow control etc properties.
Can u help me in this regard?
Thanks in advance
Mazhar
|
|
|
|
|
The link error occurred while the source was done with vc++2005 in build.
|
|
|
|
|
What is the benefit of testing if the COM port has a connection to the USB bus?
Is this useful to distinguish virtual COM ports that actually are USB devices from "real" COM ports?
|
|
|
|
|
Does anyone know how to obtain the PortName (i.e. COM1, COM2...) using this SetupDi.. API. I can obviously parse it from the friendly name but is this the right way to go?
|
|
|
|
|
1. I'm using CM_Get_Device_ID_List_Size to get the Removal Relations of devices. The function works fine on XP, but in win2k, I wasn't able to get the information (it returns no removal relations)
2. I want to disable the use of USB 2.0, So I want to disable the Enhaced Host Controller, Does anyone know of a way to check which of the Host Controllers is an Enhanced Host Controller?
Thanx,
Yona
|
|
|
|
|
hi
i try to write program for installing RamDrive Driver by using SetupAPI Function , but i can't Because i have not Good Sample code or Document about SetupAPI Functions ,like SetupInstallFile and ...
please help me
mtaghiloo@yahoo.com
majid taghiloo
|
|
|
|
|
This is a general question regarding serial ports..
How do you actually release and claim a serial port e.g. COM5.
I have implemented a VirtualSerialPort and everytime I use a different port e.g. COM5, COM6
the ports stay registered and I cannot use them next time I reboot the system as they are registered in the registry.
Is there a way of releasing those ports without having to delete them from the registry?
Anyone have a clue?
Hint: I want to change the status of the COM port in the "Port Settings->Advanced->Com Port Number" from "(in use)"
into a clear field for each COM port
P.S. CreateFile does not give you a handle if e.g. COM5 port was used by a device which is not present. So
this port must be released in some way first..
|
|
|
|
|
Hi. There are at least 15 types of USB/Serial cables available at the moment. Very few of them seem to conform to ANYthing "standard".
For example, the KEYSPAN USA19QW has its own non-conforming registry key: HKLM\Enum\KEYSPAN\*USA19WMAP\00_00. This key cannot be found in Win98 and WinME by EnumSerial currently because of this line:
BOOL bMatch = (strcmp(acSubSubEnum,"*PNP0500")==0 ||
strcmp(acSubSubEnum,"*PNP0501")==0 ||
bUsbDevice);
I was able to find the KEYSPAN cable and presumably all other USB/Serial cables (assuming they do not depart even further from the "standard") by setting:
bMatch = TRUE;
(This will slow down the performance slightly of course since now more subkeys must be searched. However this is apparently what Device Manager is doing or KEYSPAN would not have been able to place their key where they have placed it...)
I also then had to filter out LPT ports and anything non-"COM" in SearchPnpKeyW9x:
if (!bDup) {
// Add an entry to the array
if(strPortName.Left(3) == "COM"){//Add COM ports only
asi.Add(si);
}
}
Of course if there is some serial port that has a name that does NOT start with COM, it would then not be listed... (Something I read indicated that COM ports do not HAVE to be named "COM" ports... Why are "standards" so non-standard?)
This is not the appropriate thread but I have discovered MANY problems with USB/Serial cables. Very few behave like a UART. For example, if you wire CTS to RTS on the Keyspan cable then assert RTS, the cable cannot see its own RTS signal on the CTS pin until 24 milliseconds have elapsed... (We use this to see if the user has our board plugged in...) Lots of little odds and ends that make these cables a nightmare if your software has to support their use...
Thanks,
Howard
Howard in Arizona
http://www.astroshow.com
|
|
|
|
|
For diagnosis it could be helpfull to get the application which
blocks an comprt.
Any idea?
|
|
|
|
|
I wish I knew how - I've often wanted this for files. Windows tells me a file is in use, but not which process has it open.
|
|
|
|
|
Many thanks to Zach Gorman.
You did really a good job.
Because of my need for using it on Windows NT machines I've tried to replace the fixed linking to setupapi.lib to the LoadLibrary stuff.
(Don't know if it really works on W2K / not testet at the moment)
Know I' searching for a possibility to get the friendly names on NT, too?
How can I do this?
|
|
|
|
|
On the LoadLibrary note, it turns out that there is an easier way in Visual Studio 6 (I assume it's there in .net too but haven't tried it). In the Link tab of 'Project Settings' for all builds, include 'delayimp.lib' under "Object/library modules." Then, at the bottom of "Project Options" add '/delayload:setupapi.dll'
This invokes the compiler's built-in support for delay loading; your program will not attempt to load setupapi.dll until you call a function that lives in it. Since no code in the NT4 execution path calls SetupDi functions, this enables NT4 support.
Regarding friendly names on NT4, I wasn't able to find any during my preliminary search. If they exist at all, you may be able to find them by digging around in the registry; my suggestion is to crack open a copy of regedit and search for COM1 on an NT4 box.
If they exist in the registry, you can add a function to dig them out based on EnumSerial's W98 code. If not, you can always just make up a friendly name - most ports end up being called "Communications Port" anyway.
|
|
|
|
|
Zach Gorman wrote:
On the LoadLibrary note, it turns out that there is an easier way in Visual Studio 6 (I assume it's there in .net too but haven't tried it). In the Link tab of 'Project Settings' for all builds, include 'delayimp.lib' under "Object/library modules." Then, at the bottom of "Project Options" add '/delayload:setupapi.dll'
Thank you for this tip. It works good.
But for my use it will be better to use it with LoadLibrary because it will be easier to share the code between different projects or with other people here on this site.
It seems that on NT no friendly names are used. But there is another way to enumerate serial ports using "QueryDosDevice()".
I'll try to add it to your code on weekend and send it to you by email.
Bye
|
|
|
|
|
It doesn't found USB <-> Serial converter in Win 98. The key of FTDI converter is placed in the HKLM\Enum\FTDIBUS section.
Other thing: I'm looking for a solution to exclude modems from obtained list. I have PCI modem wich was also detected as a port in Win XP. There is a problem with it, because it takes a lot of time to operate on it.
P_awe_L
|
|
|
|
|
Sorry for the delayed reply. I tested the prolific & aten usb2serial converters; I haven't tried the ftdi. If you have a code patch to add ftdi compatibility, post it here.
Regarding filtering out modems, the only approach I can think of off the top of my head is to hack it and look for the word "modem" in the device description.
|
|
|
|
|
Hi,
Regarding modems, why not try to enumerate the MODEMS class instead of the PORTS class.
regards
// Christian
|
|
|
|
|
I have an Edgeport USB Converter with 4 serial ports, which are not found by the code.
I can sometimes find the ports reading straight from registry HKLM\HARDWARE\DEVICEMAP\SERIALCOMM,
but this seems not to be foolproof, as sometimes the ports are not found.
Anyone know why?
|
|
|
|
|
|
The "strPortName" part of the SSerInfo structure does not seem to get populated in the EnumPortsWdm method. It does in SearchPnpKeyW9x and EnumPortsWNt4 (although that one is a bit of a no-brainer.) Is this an oversight? What is the "reccomended" method for pulling the port name using the Wdm method? I imagine it could be stripped off of the Firendly Name, but only when the port is not taken up by a device (a practical example is a friendly name of "Xircom Cardbus Ethernet 100 + Modem 56 (Modem Interface)" when the same item is inserted into the PCMCIA slot of a laptop. It "ties up" COM2, but I cannot determine COM2 from the Friendly Name or the Port Desc...)
Ideas? Suggestions? Thanks much
--JMG
|
|
|
|
|
The SetupDi API didn't provide any simple port name, so I left it out of the WDM method. I didn't need it for my application, so I gave up without much of a fight.
Perhaps the information you need is available through the SetupDiGetDeviceRegistryProperty( ..., SPDRP_LOCATION_INFORMATION, ...) call.
|
|
|
|
|
Hi,
Attached is my version of portlister for w2k that I used a couple of years ago. There is a SetupApi for W9x aswell that can be used with the same result, not suplied here.
Pros:
It uses the ClassName "PORTS" instead of the hard-coded guid.
It also extracts the PortName from the registry in a proper way.
Enjoy!
// Christian
// portlister.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "tchar.h"
#include "setupapi.h"
int main(int argc, char* argv[])
{
GUID ClassGuid[1];
DWORD dwRequiredSize;
BOOL bRet;
HDEVINFO DeviceInfoSet = NULL;
SP_DEVINFO_DATA DeviceInfoData;
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DWORD dwMemberIndex = 0;
// Get ClassGuid from ClassName for PORTS class
bRet = SetupDiClassGuidsFromName(_T("PORTS"), (LPGUID)&ClassGuid, 1, &dwRequiredSize);
if (!bRet) goto cleanup;
// Get class devices
DeviceInfoSet = SetupDiGetClassDevs(ClassGuid, NULL, NULL, DIGCF_PROFILE);
if (DeviceInfoSet)
{
// Enumerate devices
dwMemberIndex = 0;
while (SetupDiEnumDeviceInfo(DeviceInfoSet, dwMemberIndex++, &DeviceInfoData))
{
TCHAR szFriendlyName[MAX_PATH];
TCHAR szPortName[MAX_PATH];
TCHAR szMessage[MAX_PATH];
DWORD dwReqSize = 0;
DWORD dwPropType;
DWORD dwType = REG_SZ;
HKEY hKey = NULL;
// Get friendlyname
bRet = SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
&DeviceInfoData,
SPDRP_FRIENDLYNAME,
&dwPropType,
(LPBYTE)szFriendlyName,
sizeof(szFriendlyName),
&dwReqSize);
// Open device parameters reg key
hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
&DeviceInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DEV,
KEY_READ);
if (hKey)
{
// Qurey for portname
dwReqSize = sizeof(szPortName);
long lRet = RegQueryValueEx(hKey,
_T("PortName"),
0,
&dwType,
(LPBYTE)&szPortName,
&dwReqSize);
// Close reg key
RegCloseKey(hKey);
}
wsprintf(szMessage, _T("Name: %s\nPort: %s\n"), szFriendlyName, szPortName);
MessageBox(NULL, szMessage, _T("Found Port"), MB_OK);
}
}
cleanup:
// Destroy device info list
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return 0;
}
|
|
|
|
|
Hi,
I have added parts of the proposed code to my EnumSerial, in
void EnumPortsWdm(CArray<sserinfo,sserinfo&> &asi)
right before
if
(bSuccess) { // ...
// Open device parameters reg key
HKEY hKey = SetupDiOpenDevRegKey
(hDevInfo, &devdata, DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_READ);
TCHAR szPortName[MAX_PATH];
if (hKey)
{
DWORD dwType = REG_SZ;
DWORD dwReqSize = sizeof(szPortName);
// Query for portname
long lRet = RegQueryValueEx
(hKey,_T("PortName"), 0, &dwType, (LPBYTE)&szPortName, &dwReqSize);
if (lRet == ERROR_SUCCESS)
bSuccess &= TRUE;
else
bSuccess &= FALSE;
}
else
bSuccess &= FALSE;
and add the folllowing line in
if (bSuccess) {
si.strPortName = szPortName;
|
|
|
|
|