I am looking for example code in ansi c/c++ that will find usb devices by their pid/vid/sn# and then find the associated comport number. I have multiple FTDI usb serial ports connected to a pc and need to identify each port by the known SN#. This code I found will display the HWID info but how do I use it to get the comport number? Here is a response to the below code for one of the devices: USB\VID_0403&PID_6001\FTAME7HK
Are there an online tutorial that runs through examples for this type of code?
#include <windows.h>
#include <ansi_c.h>
#include <Setupapi.h>
#include <devguid.h>
#include <Setupapi.h>
HDEVINFO deviceInfoSet;
GUID *guidDev = (GUID*) &GUID_DEVCLASS_USB;
TCHAR buffer [4000];
DWORD buffersize =4000;
int memberIndex = 0;
main()
{
deviceInfoSet = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
while (TRUE) {
SP_DEVINFO_DATA deviceInfoData;
ZeroMemory(&deviceInfoData, sizeof(SP_DEVINFO_DATA));
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (SetupDiEnumDeviceInfo(deviceInfoSet, memberIndex, &deviceInfoData) == FALSE) {
if (GetLastError() == ERROR_NO_MORE_ITEMS)
{
break;
}
}
DWORD nSize=0 ;
SetupDiGetDeviceInstanceId (deviceInfoSet, &deviceInfoData, buffer, sizeof(buffer), &nSize);
buffer [nSize] ='\0';
printf ("%s\n", buffer);
memberIndex++;
}
if (deviceInfoSet) {
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
getchar();
return 0;
}
If you want the friendly name, which typically includes the parenthesized com port number, this should do it:
{
wchar_t friendly_name[128];
if (!SetupDiGetDeviceRegistryPropertyW(device_list, &device_data, SPDRP_FRIENDLYNAME, nullptr, reinterpret_cast<PBYTE>(friendly_name), sizeof friendly_name, nullptr))
return;
StringCopyW(buffer, friendly_name);
}
To get the two parameters device_list and device_data for the above call, I use this function:
void rescan_ports( void )
{
SP_DEVINFO_DATA device_data = { sizeof device_data };
HDEVINFO device_list = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_COMPORT, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
DWORD error = GetLastError();
if (!device_list && device_list == INVALID_HANDLE_VALUE) return;
bool ended = false;
for( int i = 0; i < 6000 && !ended; i++ ) {
if (SetupDiEnumDeviceInfo(device_list, i, &device_data))
format_and_add_port_detail(device_list, device_data);
else
ended = (GetLastError() == ERROR_NO_MORE_ITEMS);
}
SetupDiDestroyDeviceInfoList(device_list);
}
It's very similar to what you wrote, except that mine uses GUID_DEVINTERFACE_COMPORT to find only serial ports.
Related
I have a measurment device and want to make a series of measurments and store them to a file.
For this I need to read out the com port properly. All I get back with this code is some weird signs.
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
int main() {
// opening the serial port
HANDLE hSerial;
fprintf(stderr, "Opening serial port...");
hSerial = CreateFile("\\\\.\\COM2",
GENERIC_READ | GENERIC_WRITE, 0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Error\n");
CloseHandle(hSerial);
return 1;
} else
fprintf(stderr, "OK\n");
// settings to communicate with device
DCB dcbSerialParams;
ZeroMemory(&dcbSerialParams, sizeof(dcbSerialParams));
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
//error getting state
fprintf(stderr,"error getting state ... ");
}
dcbSerialParams.BaudRate = 9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
//error setting state
fprintf(stderr,"error setting state ...");
}
char out_message[] = "fetch?"; // request for the device to send voltage and
current
char in_message[32];
DWORD BytesToWrite = sizeof(out_message);
DWORD BytesWritten;
DWORD BytesToRead = sizeof(in_message);
DWORD BytesRead;
WriteFile(hSerial, out_message, BytesToWrite, &BytesWritten, NULL);
ReadFile(hSerial, &in_message, BytesToRead, &BytesRead, NULL);
string buffer;
for (unsigned int i = 0; i < sizeof(in_message); i++) {
buffer += in_message[i];
}
buffer[sizeof(in_message) - 1] = '\0';
// try outs of different outputs
cout << buffer << "\n";
const char*c = buffer.c_str();
printf("%s\n",c);
CloseHandle(hSerial);
return 0;
}
I guess I cannot write to com an read out immediately?
Or is there a mistake in the conversion in_message to buffer?
I have been trying to fix it for last 3 days, and tried many options, but didn't get to work.
I have the following code in C++.
#include <winsock2.h>
#include <iphlpapi.h>
#include<stdio.h>
#include <stdlib.h>
#include <typeinfo>
#include <string>
// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")
#define _CRT_SECURE_NO_WARNINGS
#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
/* Note: could also use malloc() and free() */
int __cdecl main(int argc, char **argv)
{
/* Declare and initialize variables */
DWORD dwSize = 0;
DWORD dwRetVal = 0;
unsigned int i = 0;
// Set the flags to pass to GetAdaptersAddresses
ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
// default to unspecified address family (both)
ULONG family = AF_UNSPEC;
LPVOID lpMsgBuf = NULL;
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
ULONG outBufLen = 0;
ULONG Iterations = 0;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
IP_ADAPTER_PREFIX *pPrefix = NULL;
// Allocate a 15 KB buffer to start with.
outBufLen = WORKING_BUFFER_SIZE;
std::string str;
char Buffer[255];
do {
pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen);
if (pAddresses == NULL) {
printf
("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
//exit(1);
}
dwRetVal =
GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = NULL;
}
else {
break;
}
Iterations++;
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));
if (dwRetVal == NO_ERROR) {
// If successful, output some information from the data we received
pCurrAddresses = pAddresses;
while (pCurrAddresses) {
if (wcscmp(pCurrAddresses->FriendlyName, L"Ethernet") == 0) {
if (pCurrAddresses->PhysicalAddressLength != 0) {
printf("\tPhysical address: ");
for (i = 0; i < (int)pCurrAddresses- >PhysicalAddressLength;
i++) {
if (i == (pCurrAddresses->PhysicalAddressLength - 1)) {
printf("%.2X\n", (int)pCurrAddresses- >PhysicalAddress[i]);
//str.append(pCurrAddresses- >PhysicalAddress[i]);
// str += (int)pCurrAddresses- >PhysicalAddress[i];
//sprintf(Buffer + strlen(Buffer), "%.2X", (int)pCurrAddresses->PhysicalAddress[i]);
}
else {
printf("%.2X-", (int)pCurrAddresses- >PhysicalAddress[i]);
//str.append(pCurrAddresses- >PhysicalAddress[i]);
//str += (int)pCurrAddresses- >PhysicalAddress[i];
}
}
}
}
pCurrAddresses = pCurrAddresses->Next;
}
}
else {
printf("Call to GetAdaptersAddresses failed with error: %d\n",
dwRetVal);
if (dwRetVal == ERROR_NO_DATA)
printf("\tNo addresses were found for the requested parameters\n");
else {
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
// Default language
(LPTSTR)& lpMsgBuf, 0, NULL)) {
printf("\tError: %s", lpMsgBuf);
LocalFree(lpMsgBuf);
if (pAddresses)
FREE(pAddresses);
//exit(1);
}
}
}
if (pAddresses) {
FREE(pAddresses);
}
MessageBoxA(NULL, str.c_str(), "testx", MB_OK);
system("pause");
return 0;
}
I want to print the mac address in MessageBox (winapi) using type LPCSTR at once, not in the loop, as it is happening now with printf().
I then have to send the mac address in URL using InternetOpenUrl() which has the data type of LPCSTR or LPWCSTR, I'll do the rest, once I succeed in printing and storing mac address in MessageBox and LPCSTR format respectively.
EDIT: My question is:
1. How to append the value of mac address into char array or string in loop?
2. How to store the mac address in LPCSTR to display in MessageBox()?
char MAC[18] = {0};
if (pCurrAddresses->PhysicalAddressLength != 0) {
// a MAC is usually 6 bytes in size...
sprintf(MAC, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
pCurrAddresses->PhysicalAddress[0],
pCurrAddresses->PhysicalAddress[1],
pCurrAddresses->PhysicalAddress[2],
pCurrAddresses->PhysicalAddress[3],
pCurrAddresses->PhysicalAddress[4],
pCurrAddresses->PhysicalAddress[5]);
printf("\tPhysical address: %s\n", MAC);
str.append(MAC);
}
If you want to be "politically correct" then format the actual number of bytes reported by PhysicalAddressLength (which can technically be as high as 8):
char MAC[24] = {0};
if (pCurrAddresses->PhysicalAddressLength != 0) {
char fmt[] = "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X";
if (pCurrAddresses->PhysicalAddressLength < 8)
fmt[(pCurrAddresses->PhysicalAddressLength * 5)-1] = 0;
sprintf(MAC, fmt,
pCurrAddresses->PhysicalAddress[0],
pCurrAddresses->PhysicalAddress[1],
pCurrAddresses->PhysicalAddress[2],
pCurrAddresses->PhysicalAddress[3],
pCurrAddresses->PhysicalAddress[4],
pCurrAddresses->PhysicalAddress[5]
pCurrAddresses->PhysicalAddress[6],
pCurrAddresses->PhysicalAddress[7]);
printf("\tPhysical address: %s\n", MAC);
str.append(MAC);
}
In C++, with VS2012, i would like to get the Mac adress and convert it in car formatting.
I Use sprintf_s function() in order to convert in car mode.
In debug mode, all is ok, but, in release mode, the sprint_s function don't execute properly ! It appear to exit my programm !
I don't know why !
Anyone could help me please ?
Here is a little sample which demonstrate my problem. I tested in on severals pc's :
#include "stdafx.h"
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "iphlpapi.lib")
#define MACADDR_SIZE (6*3)
#define MAC_DIM 6
#define MACHINE_CODE_DIM 6
#define SOFTWAREKEY_DIM 6
enum RETVALUE
{
SUCCESS,
ERROR_API_CALL_FAILED,
ERROR_FAILURE_WHILE_LOADING_LIBRARY,
ERROR_OS_VERSION_NOT_SUPPORTED,
ERROR_SOFTWAREKEY_NOT_FOUND,
ERROR_CONVERSION_CHAR_2_WCHAR_FAILED
};
int _tmain(int argc, _TCHAR* argv[])
{
char * mac_addr = (char*)malloc(MACADDR_SIZE + 1);
// Declare and initialize variables
DWORD dwSize = 0;
DWORD dwRetVal = 0;
int i = 0;
ULONG flags, outBufLen = 0, family;
LPVOID lpMsgBuf;
PIP_ADAPTER_ADDRESSES pAddresses;
PIP_ADAPTER_ADDRESSES pCurrAddresses;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast;
PIP_ADAPTER_ANYCAST_ADDRESS pAnycast;
PIP_ADAPTER_MULTICAST_ADDRESS pMulticast;
IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
IP_ADAPTER_PREFIX *pPrefix = NULL;
// Set the flags to pass to GetAdaptersAddresses
flags = GAA_FLAG_INCLUDE_PREFIX;
// default to unspecified address family (both)
family = AF_UNSPEC;
lpMsgBuf = NULL;
pAddresses = NULL;
pCurrAddresses = NULL;
pUnicast = NULL;
pAnycast = NULL;
pMulticast = NULL;
family = AF_INET;
outBufLen = sizeof (IP_ADAPTER_ADDRESSES);
pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen);
if (pAddresses == NULL)
{
printf("Memory allocation failed for IP_ADAPTER_ADDRESSES struct!\n");
exit(1);
}
else
printf("Memory allocation for IP_ADAPTER_ADDRESSES struct is OK!\n");
// Make an initial call to GetAdaptersAddresses to get the
// size needed into the outBufLen variable
if (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
{
printf("Not enough buffer! Re-allocating...\n");
free(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen);
}
else
printf("Buffer allocation is OK!\n");
if (pAddresses == NULL)
{
printf("Memory allocation failed for IP_ADAPTER_ADDRESSES struct!\n");
exit(1);
}
else
printf("Memory allocation for IP_ADAPTER_ADDRESSES struct is OK!\n");
// Make a second call to GetAdapters Addresses to get the actual data we want
printf("Memory allocated for GetAdapterAddresses = %d bytes\n", outBufLen);
printf("Calling GetAdaptersAddresses function with family = ");
if (family == AF_INET)
printf("AF_INET\n");
dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
if (dwRetVal == NO_ERROR)
{
// If successful, output some information from the data we received
pCurrAddresses = pAddresses;
if (pCurrAddresses->PhysicalAddressLength != 0)
{
printf("\tPhysical address: ");
for (i = 0; i < (int)pCurrAddresses->PhysicalAddressLength; i++)
{
if (i == (pCurrAddresses->PhysicalAddressLength - 1))
printf("%.2X\n", (int)pCurrAddresses->PhysicalAddress[i]);
else
printf("%.2X-", (int)pCurrAddresses->PhysicalAddress[i]);
}
}
sprintf_s(mac_addr, MACADDR_SIZE + 1, "%c%c%c%c%c%c",
pCurrAddresses->PhysicalAddress[0], pCurrAddresses->PhysicalAddress[1],
pCurrAddresses->PhysicalAddress[2], pCurrAddresses->PhysicalAddress[3],
pCurrAddresses->PhysicalAddress[4], pCurrAddresses->PhysicalAddress[5]);
printf("Mac adress in car formatting is :");
printf(mac_addr);
getchar();
free(pAddresses);
}
return 0;
}
Thanks a lot :)
Best regards,
Nixeus
You can't use %c to print the bytes of a MAC address, as those bytes may not be printable characters.
The code that printf "Physical address" using %.2X is the one to use.
Your code works well in Debug or Release mode for me (VS2012), but as my first NIC has 0x00 as first byte, the final printf prints nothing.
I have asked a similar question previously, but 1. no one answered and 2. it is a bit different. I have managed to get the correct file Path and created a handler by using CreateFile. I have then tried to use the HidD_GetFeature() function, but when I print out the report, it is all in symbols - not letters, numbers or readable sign. Does anyone know why it is doing that?? Here's my code:
/*****************************Mainframe.cpp**************************************/
#include"DeviceManager.h"
int main()
{
int iQuit;
DeviceManager deviceManager;
//deviceManager.ListAllDevices();
deviceManager.GetDevice("8888", "0308");
std::cin >> iQuit;
return 0;
}
/***********************************DeviceManager.h***************************/
#include <windows.h>
//#include <hidsdi.h>
#include <setupapi.h>
#include <iostream>
#include <cfgmgr32.h>
#include <tchar.h>
#include <devpkey.h>
extern "C"{
#include <hidsdi.h>
}
//#pragma comment (lib, "setupapi.lib")
class DeviceManager
{
public:
DeviceManager();
~DeviceManager();
void ListAllDevices();
void GetDevice(std::string vid, std::string pid);
HANDLE PSMove;
byte reportBuffer[57];
GUID guid;
private:
HDEVINFO deviceInfoSet; //A list of all the devices
SP_DEVINFO_DATA deviceInfoData; //A device from deviceInfoSet
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;
};
/********************************DeviceManager.cpp*********************************/
#include"DeviceManager.h"
DeviceManager::DeviceManager()
{
HidD_GetHidGuid(&guid);
deviceInfoSet = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); //Gets all Devices
}
DeviceManager::~DeviceManager()
{
}
void DeviceManager::ListAllDevices()
{
DWORD deviceIndex = 0;
deviceInfoData.cbSize = sizeof(deviceInfoData);
while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
{
deviceInfoData.cbSize = sizeof(deviceInfoData);
ULONG tcharSize;
CM_Get_Device_ID_Size(&tcharSize, deviceInfoData.DevInst, 0);
TCHAR* deviceIDBuffer = new TCHAR[tcharSize]; //the device ID will be stored in this array, so the tcharSize needs to be big enough to hold all the info.
//Or we can use MAX_DEVICE_ID_LEN, which is 200
CM_Get_Device_ID(deviceInfoData.DevInst, deviceIDBuffer, MAX_PATH, 0); //gets the devices ID - a long string that looks like a file path.
/*
//SetupDiGetDevicePropertyKeys(deviceInfoSet, &deviceInfoData, &devicePropertyKey, NULL, 0, 0);
if( deviceIDBuffer[8]=='8' && deviceIDBuffer[9]=='8' && deviceIDBuffer[10]=='8' && deviceIDBuffer[11]=='8' && //VID
deviceIDBuffer[17]=='0' && deviceIDBuffer[18]=='3' && deviceIDBuffer[19]=='0' && deviceIDBuffer[20]=='8') //PID
{
std::cout << deviceIDBuffer << "\t<-- Playstation Move" << std::endl;
}
else
{
std::cout << deviceIDBuffer << std::endl;
}*/
std::cout << deviceIDBuffer << std::endl;
deviceIndex++;
}
}
void DeviceManager::GetDevice(std::string vid, std::string pid)
{
DWORD deviceIndex = 0;
deviceInfoData.cbSize = sizeof(deviceInfoData);
while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
{
deviceInfoData.cbSize = sizeof(deviceInfoData);
ULONG IDSize;
CM_Get_Device_ID_Size(&IDSize, deviceInfoData.DevInst, 0);
TCHAR* deviceID = new TCHAR[IDSize];
CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_PATH, 0);
if( deviceID[8]==vid.at(0) && deviceID[9]==vid.at(1) && deviceID[10]==vid.at(2) && deviceID[11]==vid.at(3) && //VID
deviceID[17]==pid.at(0) && deviceID[18]==pid.at(1) && deviceID[19]==pid.at(2) && deviceID[20]==pid.at(3)) //PID
{
DWORD deviceInterfaceIndex = 0;
deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
//HDEVINFO deviceInterfaceSet = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE);
if(SetupDiEnumDeviceInterfaces(deviceInfoSet, &deviceInfoData, &guid, deviceInterfaceIndex, &deviceInterfaceData))
{
deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
deviceInterfaceDetailedData.cbSize = sizeof(deviceInterfaceDetailedData);
DWORD requiredSize;
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &requiredSize, &deviceInfoData); //Gets the size
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, &deviceInterfaceDetailedData, requiredSize, NULL, NULL); //Sets the deviceInterfaceDetailedData
//std::cout << deviceInterfaceDetailedData.DevicePath << std::endl;
PSMove = CreateFile(deviceInterfaceDetailedData.DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
reportBuffer[0] = 0;
ULONG reportBufferLength = sizeof(reportBuffer);
HidD_GetFeature(PSMove, &reportBuffer, reportBufferLength);
std::cout << reportBuffer << std::endl;
//deviceInterfaceIndex++;
}
break;
}
deviceIndex++;
}
}
the HidD_GetFeature() function is at the bottom of this huge block of code.
UPDATE: I've managed to print the report now, but it is just a random 8 bit hex. Everytime I close the program down and run it again, it prints out different results. Why's that?
The ListAllDevices() function isn't displaying the info correctly because you're outputting a wchar_t* to std::cout. You need to use std::wcout for wide chars.
When I connect my embedded device to my system, I am running my program which will write to the port my embedded is connect and it prints the reply to console.
When I connect my device and run this program it is not giving any output.
But when I connect my device and use PUTTY to send some commands first and then run my program it is working.
Maybe there is a problem in the way I am starting communication?
My source code is:
#include "stdafx.h"
#include <iostream>
//#include <windows.h>
#include <afx.h>
int main()
{
using namespace std;
int i=0;
// cout << "Hello world!" << endl;
HANDLE hSerial;
hSerial = CreateFile("COM5",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hSerial==INVALID_HANDLE_VALUE)
{
if(GetLastError()==ERROR_FILE_NOT_FOUND)
{
// TRACE("serial port does not exist for reading\n");
//serial port does not exist. Inform user.
}
// TRACE("some other error,serial port does not exist for reading\n");
//some other error occurred. Inform user.
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams))
{
// TRACE("error getting state for reading\n");
//error getting state
}
dcbSerialParams.BaudRate=9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams))
{
//TRACE("error setting state for reading\n");
//error setting serial port state
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;
if(!SetCommTimeouts(hSerial, &timeouts))
{
// TRACE("some error occured for reading\n");
//error occureed. Inform user
}
int n=100,n1=100;
char szBuff[100];
DWORD dwBytesRead = 0;
char szBuff1[100];
DWORD dwByteswrote = 0;
memset(szBuff1,0,100);
memcpy(szBuff1,"LIST\r",5);
if(!WriteFile(hSerial, szBuff1,5, &dwByteswrote, NULL))
{
cout << "error writing" ;
}
cout << szBuff1 << endl;
cout << dwByteswrote << endl;
while(1)
{
if(!ReadFile(hSerial, szBuff, n1, &dwBytesRead, NULL))
{
cout << "error reading";
break;
}
else
{
cout << dwBytesRead << endl;
szBuff[dwBytesRead]='\0';
if(dwBytesRead>0)
{
cout << (szBuff);
break;
}
}
}
cin >> i;
}
Try this... you will probably need to do the code for exceptions (ex: if the response is bigger than 2024)
bool SendModemATCommand(const string &strCommand, int iModemPort, string &strRetValue)
{
bool bRetValue = false;
strRetValue = "";
char cBuffer[2024];
HANDLE hCom = NULL;
char cComPort[64];
sprintf_s(cComPort,"\\\\.\\COM%d", iModemPort);
hCom = CreateFile( cComPort,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (hCom != INVALID_HANDLE_VALUE)
{
COMMTIMEOUTS comTimeOuts;
comTimeOuts.ReadIntervalTimeout = MAXDWORD;
comTimeOuts.ReadTotalTimeoutMultiplier = MAXDWORD;
comTimeOuts.ReadTotalTimeoutConstant = 0;//MAXDWORD;
comTimeOuts.WriteTotalTimeoutMultiplier = 0;
comTimeOuts.WriteTotalTimeoutConstant = 0;
if(SetCommTimeouts(hCom, &comTimeOuts))
{
DCB dcb;
dcb.DCBlength = sizeof(DCB);
if(GetCommState(hCom, &dcb))
{
DWORD dwBytesWritten = 0;
DWORD dwBytesRead = 0;
DWORD dwBytesTotal = 0;
if( WriteFile(hCom, strCommand.c_str(), (int)strCommand.size(), &dwBytesWritten, NULL) )
{
if(dwBytesWritten == strCommand.size())
{
dwBytesRead = 0;
DWORD tickStart = GetTickCount();
bool bTimeOut = false;
while(true)
{
while(ReadFile(hCom, cBuffer + dwBytesTotal, 1, &dwBytesRead, NULL))
{
if(dwBytesRead == 0 && dwBytesTotal != dwBytesWritten)
break;
dwBytesTotal += dwBytesRead;
}
if ( dwBytesTotal == 0 )
{
// timeout
if ( GetTickCount() - tickStart > 10000) // 10 Seconds
{
bTimeOut = true;
break;
}
}
else
break;
}
cBuffer[dwBytesTotal] = '\0';
strRetValue = cBuffer;
if(bTimeOut)
strRetValue = "Timed out:" + strCommand;
else
bRetValue = true;
}
}
}
}
CloseHandle(hCom);
}
return bRetValue;
}
Most likely the problem is with your initialization.
I recall having this type of trouble before and Com Timeouts structure was particularly troublesome.
I suggest you get a null modem cable from COM5 to another port on the machine (if you have one), or to another computer. Then use a terminal program to open up the other port and see you can see the "List" command coming through when you run the program. If not then it's very likely to be related to the way you are initializing & opening the com port.
This link may prove useful. Just strip out the Afx stuff and look particularly at the initialization.
http://www.codeproject.com/KB/system/chaiyasit_t.aspx
One other suggestion, you only send List once. If the device is not already plugged in and ready, nothing will happen. Maybe it should keep sending the list command until it gets a
Response.
Also, do you need "List\r\n" or just "List\r"? What is the other ends expecting?