Updated EnumSer.cpp file from PJ Naughter http://www.naughter.com/enumser.html

Tidied up the code in a few places because I wanted to borrow the COM Enumeration stuff for another project
Compiled with Visual Studio VS2019
This commit is contained in:
AndyWhittaker 2019-06-11 11:09:48 +01:00
parent 71483070cf
commit 47e80ab30e
13 changed files with 406 additions and 448 deletions

View File

@ -92,13 +92,13 @@ BEGIN_MESSAGE_MAP(CDetailDlg, CTTPropertyPage)
ON_BN_CLICKED(IDC_STOP, OnStop)
ON_BN_CLICKED(IDC_HIDE, OnHide)
ON_CBN_SELENDOK(IDC_COMSELECT, OnSelendokComselect)
ON_CBN_KILLFOCUS(IDC_COMSELECT, OnKillfocusComselect)
ON_BN_CLICKED(IDC_LISTEN, OnListen)
ON_BN_CLICKED(IDC_INTERACT, OnInteract)
ON_BN_CLICKED(IDC_CSV, OnCsv)
ON_BN_CLICKED(IDC_CSVOPTIONS, OnCsvoptions)
ON_CBN_SELENDOK(IDC_MODEL, OnSelendokModel)
ON_BN_CLICKED(IDC_FORCE, OnForce)
ON_CBN_KILLFOCUS(IDC_COMSELECT, OnKillfocusComselect)
ON_BN_CLICKED(IDC_DEGC, OnDegC)
ON_BN_CLICKED(IDC_DEGF, OnDegF)
ON_BN_CLICKED(IDC_KPH, OnKph)
@ -219,12 +219,12 @@ void CDetailDlg::OnStartlog()
if (!(m_pMainDlg->StartLog(TRUE)))
m_bLogFirstTime = TRUE;// Call may have failed
else
m_StartLog.SetWindowText("Stop Logging");
m_StartLog.SetWindowText(_T("Stop Logging"));
}
else
{
m_bLogFirstTime = TRUE;
m_StartLog.SetWindowText("Log ECU Coms to Disk");
m_StartLog.SetWindowText(_T("Log ECU Coms to Disk"));
m_pMainDlg->StartLog(FALSE);
}
}
@ -237,7 +237,7 @@ void CDetailDlg::OnStart()
m_pMainDlg->StartComs();
m_Stop.EnableWindow(TRUE); // enable the stop monitoring button
m_Start.SetWindowText("Restart"); // Start monitoring button's text
m_Start.SetWindowText(_T("Restart")); // Start monitoring button's text
m_Start.EnableWindow(FALSE); // disable the start monitoring button
m_ComSelect.EnableWindow(FALSE); // Disable COM Port changes
}
@ -296,13 +296,13 @@ BOOL CDetailDlg::OnInitDialog()
// Enumerate the serial ports available on this computer
void CDetailDlg::Enumerate(void)
{
TRACE("Enumerating serial ports in Machine. ");
TRACE(_T("Enumerating serial ports in this Machine. "));
m_EnumSerial.UsingCreateFile(m_cuPorts);
int i=m_cuPorts.size();
TRACE("Done, %d serial ports found\n", i);
TRACE(_T("Done, %d serial ports found\n"), i);
}
// When the "Com Port Select" combobox is closed, handle the new com port.

View File

@ -1,7 +1,7 @@
/*
Module : enumser.cpp
Purpose: Implementation for a class to enumerate the serial ports installed on a PC using a number
of different approaches.
of different approaches.
Created: PJN / 03-10-1998
History: PJN / 23-02-1999 Code now uses QueryDosDevice if running on NT to determine
which serial ports are available. This avoids having to open
@ -187,8 +187,21 @@ History: PJN / 23-02-1999 Code now uses QueryDosDevice if running on NT to deter
4. Removed the CENUMERATESERIAL_USE_STL define and instead introduced a new
CENUMERATESERIAL_MFC_EXTENSIONS define which by default is not defined.
PJN / 15-11-2017 1. Updated the code to compile cleanly when _ATL_NO_AUTOMATIC_NAMESPACE is defined.
PJN / 19-05-2018 1. Updated copyright details.
2. Addition of a tenth and hopefully final method to enumerate serial ports. The
function is called "UsingGetCommPorts" and enumerates the ports by calling the Win32
GetCommPorts API which is available on Windows 10 1803 or later.
PJN / 08-07-2018 1. Updated copyright details.
2. Fixed a number of C++ core guidelines compiler warnings. These changes mean that
the code will now only compile on VC 2017 or later.
3. Remove the code path which supported CENUMERATESERIAL_MFC_EXTENSIONS
PJN / 16-09-2018 1. Fixed a number of compiler warnings when using VS 2017 15.8.4
PJN / 15-01-2019 1. Updated copyright details.
2. Updated the sample app to log the time each method call takes
3. Fixed a compilation error "unknown identifier 'HDEVINFO'" in enumser.h. Thanks to Drew Freer for
reporting this issue.
Copyright (c) 1998 - 2017 by PJ Naughter (Web: www.naughter.com, Email: pjna@naughter.com)
Copyright (c) 1998 - 2019 by PJ Naughter (Web: www.naughter.com, Email: pjna@naughter.com)
All rights reserved.
@ -212,13 +225,6 @@ to maintain a single distribution point for the source code.
/////////////////////////////// Macros / Defines //////////////////////////////
#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
#include <winioctl.h>
#ifndef _INC_SETUPAPI
#pragma message("To avoid this message, please put setupapi.h in your pre compiled header (normally stdafx.h)")
#include <setupapi.h>
#endif //#ifndef _INC_SETUPAPI
#pragma comment(lib, "setupapi.lib")
#endif //#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
@ -258,23 +264,14 @@ to maintain a single distribution point for the source code.
#pragma comment(lib, "msports.lib")
#endif //#ifndef NO_CENUMERATESERIAL_USING_COMDB
__if_not_exists(LSTATUS)
{
typedef _Return_type_success_(return == ERROR_SUCCESS) LONG LSTATUS;
}
///////////////////////////// Implementation //////////////////////////////////
#ifndef NO_CENUMERATESERIAL_USING_CREATEFILE
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingCreateFile(_Inout_ CPortsArray& ports)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingCreateFile(_Inout_ CPortsArray& ports)
{
//Make sure we clear out any elements which may already be in the array
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
#else
ports.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
//Up to 255 COM ports are supported so we iterate through all of them seeing
//if we can open them or if we fail to open them, get an access denied or general error error.
@ -282,147 +279,131 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingCreateFile(_Inout
for (UINT i=1; i<256; i++)
{
//Form the Raw device name
TCHAR szPort[32];
szPort[0] = _T('\0');
_stprintf_s(szPort, _T("\\\\.\\COM%u"), i);
ATL::CAtlString sPort;
sPort.Format(_T("\\\\.\\COM%u"), i);
//Try to open the port
BOOL bSuccess = FALSE;
ATL::CHandle port(CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0));
bool bSuccess = false;
ATL::CHandle port(CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr));
if (port == INVALID_HANDLE_VALUE)
{
DWORD dwError = GetLastError();
const DWORD dwError = GetLastError();
//Check to see if the error was because some other app had the port open or a general failure
if (dwError == ERROR_ACCESS_DENIED || dwError == ERROR_GEN_FAILURE || dwError == ERROR_SHARING_VIOLATION || dwError == ERROR_SEM_TIMEOUT)
bSuccess = TRUE;
if ((dwError == ERROR_ACCESS_DENIED) || (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || (dwError == ERROR_SEM_TIMEOUT))
bSuccess = true;
}
else
{
//The port was opened successfully
bSuccess = TRUE;
bSuccess = true;
}
//Add the port number to the array which will be returned
if (bSuccess)
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#pragma warning(suppress: 26489)
ports.push_back(i);
#else
ports.Add(i);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
}
}
//Return the success indicator
return TRUE;
return true;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_CREATEFILE
#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
_Return_type_success_(return != 0) BOOL CEnumerateSerial::RegQueryValueString(_In_ ATL::CRegKey& key, _In_ LPCTSTR lpValueName, _Out_ LPTSTR& pszValue)
#pragma warning(suppress: 26429)
_Return_type_success_(return != false) bool CEnumerateSerial::RegQueryValueString(_In_ ATL::CRegKey& key, _In_ LPCTSTR lpValueName, _Inout_ String& sValue)
{
//Initialize the output parameter
pszValue = nullptr;
sValue.clear();
//First query for the size of the registry value
//First query for the size of the registry value
ULONG nChars = 0;
LSTATUS nStatus = key.QueryStringValue(lpValueName, nullptr, &nChars);
if (nStatus != ERROR_SUCCESS)
{
SetLastError(nStatus);
return FALSE;
return false;
}
//Allocate enough bytes for the return value
DWORD dwAllocatedSize = ((nChars + 1)*sizeof(TCHAR)); //+1 is to allow us to null terminate the data if required
pszValue = reinterpret_cast<LPTSTR>(LocalAlloc(LMEM_FIXED, dwAllocatedSize));
if (pszValue == nullptr)
return FALSE;
#pragma warning(suppress: 26472 26489)
sValue.resize(static_cast<size_t>(nChars) + 1); //+1 is to allow us to null terminate the data if required
const DWORD dwAllocatedSize = ((nChars + 1)*sizeof(TCHAR));
//We will use RegQueryValueEx directly here because ATL::CRegKey::QueryStringValue does not handle non-null terminated data
DWORD dwType = 0;
ULONG nBytes = dwAllocatedSize;
pszValue[0] = _T('\0');
nStatus = RegQueryValueEx(key, lpValueName, nullptr, &dwType, reinterpret_cast<LPBYTE>(pszValue), &nBytes);
#pragma warning(suppress: 26446 26489 26490)
nStatus = RegQueryValueEx(key, lpValueName, nullptr, &dwType, reinterpret_cast<LPBYTE>(&(sValue[0])), &nBytes);
if (nStatus != ERROR_SUCCESS)
{
LocalFree(pszValue);
pszValue = nullptr;
SetLastError(nStatus);
return FALSE;
return false;
}
if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
{
LocalFree(pszValue);
pszValue = nullptr;
SetLastError(ERROR_INVALID_DATA);
return FALSE;
return false;
}
if ((nBytes % sizeof(TCHAR)) != 0)
{
LocalFree(pszValue);
pszValue = nullptr;
SetLastError(ERROR_INVALID_DATA);
return FALSE;
return false;
}
if (pszValue[(nBytes / sizeof(TCHAR)) - 1] != _T('\0'))
#pragma warning(suppress: 26446 26489)
if (sValue[(nBytes / sizeof(TCHAR)) - 1] != _T('\0'))
{
//Forcibly null terminate the data ourselves
pszValue[(nBytes / sizeof(TCHAR))] = _T('\0');
#pragma warning(suppress: 26446 26489)
sValue[(nBytes / sizeof(TCHAR))] = _T('\0');
}
return TRUE;
return true;
}
_Return_type_success_(return != 0) BOOL CEnumerateSerial::QueryRegistryPortName(_In_ ATL::CRegKey& deviceKey, _Out_ int& nPort)
_Return_type_success_(return != false) bool CEnumerateSerial::QueryRegistryPortName(_In_ ATL::CRegKey& deviceKey, _Out_ int& nPort)
{
//What will be the return value from the method (assume the worst)
BOOL bAdded = FALSE;
bool bAdded = false;
//Read in the name of the port
LPTSTR pszPortName = nullptr;
if (RegQueryValueString(deviceKey, _T("PortName"), pszPortName))
String sPortName;
if (RegQueryValueString(deviceKey, _T("PortName"), sPortName))
{
//If it looks like "COMX" then
//add it to the array which will be returned
size_t nLen = _tcslen(pszPortName);
const size_t nLen = sPortName.length();
if (nLen > 3)
{
if ((_tcsnicmp(pszPortName, _T("COM"), 3) == 0) && IsNumeric((pszPortName + 3), FALSE))
#pragma warning(suppress: 26481)
if ((_tcsnicmp(sPortName.c_str(), _T("COM"), 3) == 0) && IsNumeric((sPortName.c_str() + 3), false))
{
//Work out the port number
nPort = _ttoi(pszPortName + 3);
bAdded = TRUE;
#pragma warning(suppress: 26481)
nPort = _ttoi(sPortName.c_str() + 3);
bAdded = true;
}
}
LocalFree(pszPortName);
}
return bAdded;
}
_Return_type_success_(return != 0) BOOL CEnumerateSerial::QueryUsingSetupAPI(const GUID& guid, _In_ DWORD dwFlags, _Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames)
_Return_type_success_(return != false) bool CEnumerateSerial::QueryUsingSetupAPI(const GUID& guid, _In_ DWORD dwFlags, _Inout_ CPortAndNamesArray& ports)
{
//Set our output parameters to sane defaults
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
friendlyNames.clear();
#else
ports.RemoveAll();
friendlyNames.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
//Create a "device information set" for the specified GUID
HDEVINFO hDevInfoSet = SetupDiGetClassDevs(&guid, nullptr, nullptr, dwFlags);
if (hDevInfoSet == INVALID_HANDLE_VALUE)
return FALSE;
return false;
//Finally do the enumeration
BOOL bMoreItems = TRUE;
bool bMoreItems = true;
int nIndex = 0;
SP_DEVINFO_DATA devInfo;
SP_DEVINFO_DATA devInfo = { 0 };
while (bMoreItems)
{
//Enumerate the current device
@ -431,7 +412,9 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::QueryUsingSetupAPI(con
if (bMoreItems)
{
//Did we find a serial port for this device
BOOL bAdded = FALSE;
bool bAdded = false;
std::pair<UINT, String> pair;
//Get the registry key which stores the ports settings
ATL::CRegKey deviceKey;
@ -439,37 +422,21 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::QueryUsingSetupAPI(con
if (deviceKey != INVALID_HANDLE_VALUE)
{
int nPort = 0;
#pragma warning(suppress: 26486)
if (QueryRegistryPortName(deviceKey, nPort))
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.push_back(nPort);
#else
ports.Add(nPort);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
bAdded = TRUE;
pair.first = nPort;
bAdded = true;
}
}
//If the port was a serial port, then also try to get its friendly name
if (bAdded)
{
ATL::CHeapPtr<BYTE> byFriendlyName;
if (QueryDeviceDescription(hDevInfoSet, devInfo, byFriendlyName))
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
friendlyNames.push_back(reinterpret_cast<LPCTSTR>(byFriendlyName.m_pData));
#else
friendlyNames.Add(reinterpret_cast<LPCTSTR>(byFriendlyName.m_pData));
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
}
else
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
friendlyNames.push_back(_T(""));
#else
friendlyNames.Add(_T(""));
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
}
#pragma warning(suppress: 26489)
if (QueryDeviceDescription(hDevInfoSet, devInfo, pair.second))
#pragma warning(suppress: 26489)
ports.push_back(pair);
}
}
@ -480,10 +447,10 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::QueryUsingSetupAPI(con
SetupDiDestroyDeviceInfoList(hDevInfoSet);
//Return the success indicator
return TRUE;
return true;
}
_Return_type_success_(return != 0) BOOL CEnumerateSerial::QueryDeviceDescription(HDEVINFO hDevInfoSet, SP_DEVINFO_DATA& devInfo, ATL::CHeapPtr<BYTE>& byFriendlyName)
_Return_type_success_(return != false) bool CEnumerateSerial::QueryDeviceDescription(_In_ HDEVINFO hDevInfoSet, _In_ SP_DEVINFO_DATA& devInfo, _Inout_ String& sFriendlyName)
{
DWORD dwType = 0;
DWORD dwSize = 0;
@ -491,119 +458,121 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::QueryDeviceDescription
if (!SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, nullptr, 0, &dwSize))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
return false;
}
#pragma warning(suppress: 6102)
if (!byFriendlyName.Allocate(dwSize))
sFriendlyName.resize(dwSize / sizeof(TCHAR));
#pragma warning(suppress: 26446 26490)
if (!SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, reinterpret_cast<PBYTE>(&(sFriendlyName[0])), dwSize, &dwSize))
return false;
if (dwType != REG_SZ)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
SetLastError(ERROR_INVALID_DATA);
return false;
}
return SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, byFriendlyName.m_pData, dwSize, &dwSize) && (dwType == REG_SZ);
return true;
}
#endif //#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
_Return_type_success_(return != 0) BOOL CEnumerateSerial::IsNumeric(_In_ LPCSTR pszString, _In_ BOOL bIgnoreColon)
#pragma warning(suppress: 26429)
_Return_type_success_(return != false) bool CEnumerateSerial::IsNumeric(_In_z_ LPCSTR pszString, _In_ bool bIgnoreColon) noexcept
{
size_t nLen = strlen(pszString);
const size_t nLen = strlen(pszString);
if (nLen == 0)
return FALSE;
return false;
//What will be the return value from this function (assume the best)
BOOL bNumeric = TRUE;
bool bNumeric = true;
for (size_t i=0; i<nLen && bNumeric; i++)
{
bNumeric = (isdigit(static_cast<int>(pszString[i])) != 0);
#pragma warning(suppress: 26481)
if (bIgnoreColon && (pszString[i] == ':'))
bNumeric = TRUE;
bNumeric = true;
else
#pragma warning(suppress: 26472 26481)
bNumeric = (isdigit(static_cast<int>(pszString[i])) != 0);
}
return bNumeric;
}
_Return_type_success_(return != 0) BOOL CEnumerateSerial::IsNumeric(_In_ LPCWSTR pszString, _In_ BOOL bIgnoreColon)
#pragma warning(suppress: 26429)
_Return_type_success_(return != false) bool CEnumerateSerial::IsNumeric(_In_z_ LPCWSTR pszString, _In_ bool bIgnoreColon) noexcept
{
size_t nLen = wcslen(pszString);
const size_t nLen = wcslen(pszString);
if (nLen == 0)
return FALSE;
return false;
//What will be the return value from this function (assume the best)
BOOL bNumeric = TRUE;
bool bNumeric = true;
for (size_t i=0; i<nLen && bNumeric; i++)
{
bNumeric = (iswdigit(pszString[i]) != 0);
#pragma warning(suppress: 26481)
if (bIgnoreColon && (pszString[i] == L':'))
bNumeric = TRUE;
bNumeric = true;
else
#pragma warning(suppress: 26481)
bNumeric = (iswdigit(pszString[i]) != 0);
}
return bNumeric;
}
#ifndef NO_CENUMERATESERIAL_USING_QUERYDOSDEVICE
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingQueryDosDevice(_Inout_ CPortsArray& ports)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingQueryDosDevice(_Inout_ CPortsArray& ports)
{
//Make sure we clear out any elements which may already be in the array
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
#else
ports.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
//Use QueryDosDevice to look for all devices of the form COMx. Since QueryDosDevice does
//not consitently report the required size of buffer, lets start with a reasonable buffer size
//not consistently report the required size of buffer, lets start with a reasonable buffer size
//of 4096 characters and go from there
int nChars = 4096;
BOOL bWantStop = FALSE;
bool bWantStop = false;
while (nChars && !bWantStop)
{
ATL::CHeapPtr<TCHAR> devices;
if (!devices.Allocate(nChars))
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
std::vector<TCHAR> devices;
devices.resize(nChars);
DWORD dwChars = QueryDosDevice(nullptr, devices.m_pData, nChars);
#pragma warning(suppress: 26446)
const DWORD dwChars = QueryDosDevice(nullptr, &(devices[0]), nChars);
if (dwChars == 0)
{
DWORD dwError = GetLastError();
const DWORD dwError = GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER)
{
//Expand the buffer and loop around again
nChars *= 2;
}
else
return FALSE;
return false;
}
else
{
bWantStop = TRUE;
bWantStop = true;
size_t i = 0;
#pragma warning(suppress: 6385)
while (devices.m_pData[i] != _T('\0'))
#pragma warning(suppress: 6385 26446)
while (devices[i] != _T('\0'))
{
//Get the current device name
LPCTSTR pszCurrentDevice = &(devices.m_pData[i]);
#pragma warning(suppress: 26429 26446)
LPCTSTR pszCurrentDevice = &(devices[i]);
//If it looks like "COMX" then
//add it to the array which will be returned
size_t nLen = _tcslen(pszCurrentDevice);
const size_t nLen = _tcslen(pszCurrentDevice);
if (nLen > 3)
{
if ((_tcsnicmp(pszCurrentDevice, _T("COM"), 3) == 0) && IsNumeric(&(pszCurrentDevice[3]), FALSE))
#pragma warning(suppress: 26481)
if ((_tcsnicmp(pszCurrentDevice, _T("COM"), 3) == 0) && IsNumeric(&(pszCurrentDevice[3]), false))
{
//Work out the port number
int nPort = _ttoi(&pszCurrentDevice[3]);
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#pragma warning(suppress: 26481)
const int nPort = _ttoi(&pszCurrentDevice[3]);
#pragma warning(suppress: 26489)
ports.push_back(nPort);
#else
ports.Add(nPort);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
}
}
@ -613,142 +582,121 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingQueryDosDevice(_I
}
}
return TRUE;
return true;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_QUERYDOSDEVICE
#ifndef NO_CENUMERATESERIAL_USING_GETDEFAULTCOMMCONFIG
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingGetDefaultCommConfig(_Inout_ CPortsArray& ports)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingGetDefaultCommConfig(_Inout_ CPortsArray& ports)
{
//Make sure we clear out any elements which may already be in the array
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
#else
ports.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
//Up to 255 COM ports are supported so we iterate through all of them seeing
//if we can get the default configuration
for (UINT i=1; i<256; i++)
{
//Form the Raw device name
TCHAR szPort[32];
szPort[0] = _T('\0');
_stprintf_s(szPort, _T("COM%u"), i);
ATL::CAtlString sPort;
sPort.Format(_T("COM%u"), i);
COMMCONFIG cc;
COMMCONFIG cc = { 0 };
DWORD dwSize = sizeof(COMMCONFIG);
if (GetDefaultCommConfig(szPort, &cc, &dwSize))
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
if (GetDefaultCommConfig(sPort, &cc, &dwSize))
#pragma warning(suppress: 26489)
ports.push_back(i);
#else
ports.Add(i);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
}
}
//Return the success indicator
return TRUE;
return true;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_GETDEFAULTCOMMCONFIG
#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI1
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingSetupAPI1(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingSetupAPI1(_Inout_ CPortAndNamesArray& ports)
{
//Delegate the main work of this method to the helper method
return QueryUsingSetupAPI(GUID_DEVINTERFACE_COMPORT, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, ports, friendlyNames);
return QueryUsingSetupAPI(GUID_DEVINTERFACE_COMPORT, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, ports);
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI1
#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI2
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingSetupAPI2(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingSetupAPI2(_Inout_ CPortAndNamesArray& ports)
{
//Delegate the main work of this method to the helper method
return QueryUsingSetupAPI(GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, DIGCF_PRESENT, ports, friendlyNames);
return QueryUsingSetupAPI(GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, DIGCF_PRESENT, ports);
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI2
#ifndef NO_CENUMERATESERIAL_USING_ENUMPORTS
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingEnumPorts(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingEnumPorts(_Inout_ CPortAndNamesArray& ports)
{
//Set our output parameters to sane defaults
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
friendlyNames.clear();
#else
ports.RemoveAll();
friendlyNames.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
//Call the first time to determine the size of the buffer to allocate
DWORD cbNeeded = 0;
DWORD dwPorts = 0;
if (!EnumPorts(nullptr, 2, nullptr, 0, &cbNeeded, &dwPorts))
{
DWORD dwError = GetLastError();
const DWORD dwError = GetLastError();
if (dwError != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
return false;
}
//What will be the return value
BOOL bSuccess = FALSE;
bool bSuccess = false;
//Allocate the buffer and recall
ATL::CHeapPtr<BYTE> portsBuffer;
if (!portsBuffer.Allocate(cbNeeded))
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
bSuccess = EnumPorts(nullptr, 2, portsBuffer.m_pData, cbNeeded, &cbNeeded, &dwPorts);
std::vector<BYTE> portsBuffer;
portsBuffer.resize(cbNeeded);
#pragma warning(suppress: 26446)
bSuccess = EnumPorts(nullptr, 2, &(portsBuffer[0]), cbNeeded, &cbNeeded, &dwPorts);
if (bSuccess)
{
PORT_INFO_2* pPortInfo = reinterpret_cast<PORT_INFO_2*>(portsBuffer.m_pData);
#pragma warning(suppress: 26429 26490)
const PORT_INFO_2* pPortInfo = reinterpret_cast<const PORT_INFO_2*>(portsBuffer.data());
for (DWORD i=0; i<dwPorts; i++)
{
//If it looks like "COMX" then
//add it to the array which will be returned
size_t nLen = _tcslen(pPortInfo->pPortName);
#pragma warning(suppress: 26486 26489)
const size_t nLen = _tcslen(pPortInfo->pPortName);
if (nLen > 3)
{
if ((_tcsnicmp(pPortInfo->pPortName, _T("COM"), 3) == 0) && IsNumeric(&(pPortInfo->pPortName[3]), TRUE))
#pragma warning(suppress: 26486 26481 26489)
if ((_tcsnicmp(pPortInfo->pPortName, _T("COM"), 3) == 0) && IsNumeric(&(pPortInfo->pPortName[3]), true))
{
//Work out the port number
int nPort = _ttoi(&(pPortInfo->pPortName[3]));
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.push_back(nPort);
friendlyNames.push_back(pPortInfo->pDescription);
#else
ports.Add(nPort);
friendlyNames.Add(pPortInfo->pDescription);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#pragma warning(suppress: 26481 26489)
const int nPort = _ttoi(&(pPortInfo->pPortName[3]));
std::pair<UINT, String> pair;
pair.first = nPort;
#pragma warning(suppress: 26486 26489)
pair.second = pPortInfo->pDescription;
#pragma warning(suppress: 26489)
ports.push_back(pair);
}
}
#pragma warning(suppress: 26481)
pPortInfo++;
}
}
return bSuccess;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_ENUMPORTS
#ifndef NO_CENUMERATESERIAL_USING_WMI
HRESULT CEnumerateSerial::UsingWMI(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames)
HRESULT CEnumerateSerial::UsingWMI(_Inout_ CPortAndNamesArray& ports)
{
//Set our output parameters to sane defaults
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
friendlyNames.clear();
#else
ports.RemoveAll();
friendlyNames.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
//Create the WBEM locator
ATL::CComPtr<IWbemLocator> pLocator;
#pragma warning(suppress: 26490)
HRESULT hr = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<void**>(&pLocator));
if (FAILED(hr))
return hr;
@ -772,76 +720,69 @@ HRESULT CEnumerateSerial::UsingWMI(_Inout_ CPortsArray& ports, _Inout_ CNamesArr
{
ULONG uReturned = 0;
ATL::CComPtr<IWbemClassObject> apObj[10];
#pragma warning(suppress: 26490)
hr = pClassObject->Next(WBEM_INFINITE, 10, reinterpret_cast<IWbemClassObject**>(apObj), &uReturned);
if (SUCCEEDED(hr))
{
for (ULONG n=0; n<uReturned; n++)
{
ATL::CComVariant varProperty1;
HRESULT hrGet = apObj[n]->Get(L"DeviceID", 0, &varProperty1, nullptr, nullptr);
if (SUCCEEDED(hrGet) && (varProperty1.vt == VT_BSTR) && (wcslen(varProperty1.bstrVal) > 3))
#pragma warning(suppress: 26446 26482 26489 26486)
const HRESULT hrGet = apObj[n]->Get(L"DeviceID", 0, &varProperty1, nullptr, nullptr);
#pragma warning(suppress: 26446 26482 26489 26486)
if (SUCCEEDED(hrGet) && (varProperty1.vt == VT_BSTR) && (wcslen(varProperty1.bstrVal) > 3))
{
//If it looks like "COMX" then add it to the array which will be returned
if ((_wcsnicmp(varProperty1.bstrVal, L"COM", 3) == 0) && IsNumeric(&(varProperty1.bstrVal[3]), TRUE))
#pragma warning(suppress: 26481 26486 26489)
if ((_wcsnicmp(varProperty1.bstrVal, L"COM", 3) == 0) && IsNumeric(&(varProperty1.bstrVal[3]), true))
{
//Work out the port number
int nPort = _wtoi(&(varProperty1.bstrVal[3]));
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.push_back(nPort);
#else
ports.Add(nPort);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#pragma warning(suppress: 26481 26489)
const int nPort = _wtoi(&(varProperty1.bstrVal[3]));
std::pair<UINT, String> pair;
pair.first = nPort;
//Also get the friendly name of the port
ATL::CComVariant varProperty2;
#pragma warning(suppress: 26446 26482 26486)
if (SUCCEEDED(apObj[n]->Get(L"Name", 0, &varProperty2, nullptr, nullptr)) && (varProperty2.vt == VT_BSTR))
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#ifdef _UNICODE
std::wstring szName(varProperty2.bstrVal);
#else
std::string szName(ATL::CW2A(varProperty2.bstrVal));
#pragma warning(suppress: 26446 26482 26489 26486)
std::string szName(ATL::CW2A(varProperty2.bstrVal));
#endif //#ifdef _UNICODE
friendlyNames.push_back(szName);
#else
friendlyNames.Add(CString(varProperty2.bstrVal));
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
}
else
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
friendlyNames.push_back(_T(""));
#else
friendlyNames.Add(_T(""));
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#pragma warning(suppress: 26489)
pair.second = szName;
}
#pragma warning(suppress: 26486 26489)
ports.push_back(pair);
}
}
}
}
}
return S_OK;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_WMI
#ifndef NO_CENUMERATESERIAL_USING_COMDB
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingComDB(_Inout_ CPortsArray& ports)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingComDB(_Inout_ CPortsArray& ports)
{
//Set our output parameters to sane defaults
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
#else
ports.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
//First need to open up the DB
HCOMDB hComDB = nullptr;
LONG nSuccess = ComDBOpen(&hComDB);
if (nSuccess != ERROR_SUCCESS)
{
SetLastError(nSuccess);
return FALSE;
return false;
}
//Work out the size of the buffer required
@ -851,62 +792,49 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingComDB(_Inout_ CPo
{
ComDBClose(hComDB);
SetLastError(nSuccess);
return FALSE;
return false;
}
//Allocate some heap space and recall the function
ATL::CHeapPtr<BYTE> portBytes;
if (!portBytes.Allocate(dwMaxPortsReported))
{
ComDBClose(hComDB);
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
LONG nStatus = ComDBGetCurrentPortUsage(hComDB, portBytes.m_pData, dwMaxPortsReported, CDB_REPORT_BYTES, &dwMaxPortsReported);
//Allocate some space and recall the function
std::vector<BYTE> portBytes;
portBytes.resize(dwMaxPortsReported);
#pragma warning(suppress: 26446)
const LONG nStatus = ComDBGetCurrentPortUsage(hComDB, &(portBytes[0]), dwMaxPortsReported, CDB_REPORT_BYTES, &dwMaxPortsReported);
if (nStatus != ERROR_SUCCESS)
{
ComDBClose(hComDB);
SetLastError(nStatus);
return FALSE;
return false;
}
//Work thro the byte bit array for ports which are in use
for (DWORD i=0; i<dwMaxPortsReported; i++)
{
if (portBytes.m_pData[i])
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#pragma warning(suppress: 26446)
if (portBytes[i])
#pragma warning(suppress: 26489)
ports.push_back(i + 1);
#else
ports.Add(i + 1);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
}
}
//Close the DB
ComDBClose(hComDB);
return TRUE;
return true;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_COMDB
#ifndef NO_CENUMERATESERIAL_USING_REGISTRY
_Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingRegistry(_Inout_ CNamesArray& ports)
_Return_type_success_(return != false) bool CEnumerateSerial::UsingRegistry(_Inout_ CNamesArray& ports)
{
//Set our output parameters to sane defaults
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.clear();
#else
ports.RemoveAll();
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ATL::CRegKey serialCommKey;
LSTATUS nStatus = serialCommKey.Open(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"), KEY_QUERY_VALUE);
if (nStatus != ERROR_SUCCESS)
{
SetLastError(nStatus);
return FALSE;
return false;
}
//Get the max value name and max value lengths
@ -915,45 +843,74 @@ _Return_type_success_(return != 0) BOOL CEnumerateSerial::UsingRegistry(_Inout_
if (nStatus != ERROR_SUCCESS)
{
SetLastError(nStatus);
return FALSE;
return false;
}
DWORD dwMaxValueNameSizeInChars = dwMaxValueNameLen + 1; //Include space for the null terminator
const DWORD dwMaxValueNameSizeInChars = dwMaxValueNameLen + 1; //Include space for the null terminator
//Allocate some space for the value name
ATL::CHeapPtr<TCHAR> valueName;
if (!valueName.Allocate(dwMaxValueNameSizeInChars))
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
std::vector<TCHAR> valueName;
valueName.resize(dwMaxValueNameSizeInChars);
//Enumerate all the values underneath HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
BOOL bContinueEnumeration = TRUE;
bool bContinueEnumeration = true;
DWORD dwIndex = 0;
while (bContinueEnumeration)
{
DWORD dwValueNameSize = dwMaxValueNameSizeInChars;
valueName.m_pData[0] = _T('\0');
bContinueEnumeration = (RegEnumValue(serialCommKey, dwIndex, valueName.m_pData, &dwValueNameSize, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS);
#pragma warning(suppress: 26446)
valueName[0] = _T('\0');
#pragma warning(suppress: 26446)
bContinueEnumeration = (RegEnumValue(serialCommKey, dwIndex, &(valueName[0]), &dwValueNameSize, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS);
if (bContinueEnumeration)
{
LPTSTR pszPortName = nullptr;
if (RegQueryValueString(serialCommKey, valueName.m_pData, pszPortName))
{
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
ports.push_back(pszPortName);
#else
ports.Add(pszPortName);
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
LocalFree(pszPortName);
}
String sPortName;
#pragma warning(suppress: 26446 26486)
if (RegQueryValueString(serialCommKey, &(valueName[0]), sPortName))
#pragma warning(suppress: 26489)
ports.push_back(sPortName);
//Prepare for the next loop
++dwIndex;
}
}
return TRUE;
return true;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_REGISTRY
#ifndef NO_CENUMERATESERIAL_USING_GETCOMMPORTS
_Return_type_success_(return != false) bool CEnumerateSerial::UsingGetCommPorts(_Inout_ CPortsArray& ports)
{
//Make sure we clear out any elements which may already be in the array
ports.clear();
typedef ULONG (__stdcall GETCOMMPORTS)(PULONG, ULONG, PULONG);
HMODULE hDLL = LoadLibrary(_T("api-ms-win-core-comm-l1-1-0.dll"));
if (hDLL == nullptr)
return false;
#pragma warning(suppress: 26490)
GETCOMMPORTS* pGetCommPorts = reinterpret_cast<GETCOMMPORTS*>(GetProcAddress(hDLL, "GetCommPorts"));
if (pGetCommPorts == nullptr)
return false;
std::vector<ULONG> intPorts;
intPorts.resize(255);
ULONG nPortNumbersFound = 0;
#pragma warning(suppress: 26446 26472)
const ULONG nReturn = pGetCommPorts(&(intPorts[0]), static_cast<ULONG>(intPorts.size()), &nPortNumbersFound);
FreeLibrary(hDLL);
if (nReturn != ERROR_SUCCESS)
{
SetLastError(nReturn);
return false;
}
for (ULONG i=0; i<nPortNumbersFound; i++)
#pragma warning(suppress: 26446 26489)
ports.push_back(intPorts[i]);
//Return the success indicator
return true;
}
#endif //#ifndef NO_CENUMERATESERIAL_USING_GETCOMMPORTS

119
EnumSer.h
View File

@ -3,7 +3,7 @@ Module : enumser.h
Purpose: Defines the interface for a class to enumerate the serial ports installed on a PC
using a number of different approaches
Copyright (c) 1998 - 2017 by PJ Naughter (Web: www.naughter.com, Email: pjna@naughter.com)
Copyright (c) 1998 - 2019 by PJ Naughter (Web: www.naughter.com, Email: pjna@naughter.com)
All rights reserved.
@ -29,52 +29,43 @@ to maintain a single distribution point for the source code.
#define CENUMERATESERIAL_EXT_CLASS
#endif //#ifndef CENUMERATESERIAL_EXT_CLASS
#ifndef _Return_type_success_
#define _Return_type_success_(expr)
#endif //#ifndef _Return_type_success_
#ifndef _In_
#define _In_
#endif //#ifndef _In_
#ifndef _Out_
#define _Out_
#endif //#ifndef _Out_
#ifndef _Inout_
#define _Inout_
#endif //#ifndef _Inout_
///////////////////////// Includes ////////////////////////////////////////////
///////////////////////// Includes ////////////////////////////////////////////
#ifndef __ATLBASE_H__
#pragma message("To avoid this message, please put atlbase.h in your pre compiled header (normally stdafx.h)")
#include <atlbase.h>
#endif //#ifndef __ATLBASE_H__
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#ifndef _VECTOR_
#pragma message("To avoid this message, please put vector in your pre compiled header (normally stdafx.h)")
#include <vector>
#endif //#ifndef _VECTOR_
#ifndef _STRING_
#pragma message("To avoid this message, please put string in your pre compiled header (normally stdafx.h)")
#include <string>
#endif //#ifndef _STRING_
#else
#ifdef _AFX
#ifndef __AFXTEMPL_H__
#pragma message("To avoid this message, please put afxtempl.h in your pre compiled header (normally stdafx.h)")
#include <afxtempl.h>
#endif //#ifndef __AFXTEMPL_H__
#else
#ifndef __ATLSTR_H__
#pragma message("To avoid this message, please put atlstr.h in your pre compiled header (normally stdafx.h)")
#include <atlstr.h>
#endif //#ifndef __ATLSTR_H__
#endif //#ifdef _AFX
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
#ifndef _VECTOR_
#pragma message("To avoid this message, please put vector in your pre compiled header (normally stdafx.h)")
#include <vector>
#endif //#ifndef _VECTOR_
#ifndef _STRING_
#pragma message("To avoid this message, please put string in your pre compiled header (normally stdafx.h)")
#include <string>
#endif //#ifndef _STRING_
#ifndef _UTILITY_
#pragma message("To avoid this message, please put utility in your pre compiled header (normally stdafx.h)")
#include <utility>
#endif //#ifndef _UTILITY_
#ifndef __ATLSTR_H__
#pragma message("To avoid this message, please put atlstr.h in your pre compiled header (normally stdafx.h)")
#include <atlstr.h>
#endif //#ifndef __ATLSTR_H__
#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
#include <winioctl.h>
#ifndef _INC_SETUPAPI
#pragma message("To avoid this message, please put setupapi.h in your pre compiled header (normally stdafx.h)")
#include <setupapi.h>
#endif //#ifndef _INC_SETUPAPI
#endif //#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
///////////////////////// Classes /////////////////////////////////////////////
@ -83,68 +74,66 @@ class CENUMERATESERIAL_EXT_CLASS CEnumerateSerial
{
public:
//Typdefs
#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
typedef std::vector<UINT> CPortsArray;
#ifdef _UNICODE
typedef std::vector<std::wstring> CNamesArray;
typedef std::wstring String;
#else
typedef std::vector<std::string> CNamesArray;
typedef std::string String;
#endif
#elif defined _AFX
typedef CUIntArray CPortsArray;
typedef CStringArray CNamesArray;
#else
typedef CSimpleArray<UINT> CPortsArray;
typedef CSimpleArray<ATL::CString> CNamesArray;
#endif //#ifndef CENUMERATESERIAL_MFC_EXTENSIONS
typedef std::vector<String> CNamesArray;
typedef std::vector<std::pair<UINT, String> > CPortAndNamesArray;
//Methods
#ifndef NO_CENUMERATESERIAL_USING_CREATEFILE
static _Return_type_success_(return != 0) BOOL UsingCreateFile(_Inout_ CPortsArray& ports);
static _Return_type_success_(return != false) bool UsingCreateFile(_Inout_ CPortsArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_CREATEFILE
#ifndef NO_CENUMERATESERIAL_USING_QUERYDOSDEVICE
static _Return_type_success_(return != 0) BOOL UsingQueryDosDevice(_Inout_ CPortsArray& ports);
static _Return_type_success_(return != false) bool UsingQueryDosDevice(_Inout_ CPortsArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_QUERYDOSDEVICE
#ifndef NO_CENUMERATESERIAL_USING_GETDEFAULTCOMMCONFIG
static _Return_type_success_(return != 0) BOOL UsingGetDefaultCommConfig(_Inout_ CPortsArray& ports);
static _Return_type_success_(return != false) bool UsingGetDefaultCommConfig(_Inout_ CPortsArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_GETDEFAULTCOMMCONFIG
#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI1
static _Return_type_success_(return != 0) BOOL UsingSetupAPI1(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames);
static _Return_type_success_(return != false) bool UsingSetupAPI1(_Inout_ CPortAndNamesArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI1
#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI2
static _Return_type_success_(return != 0) BOOL UsingSetupAPI2(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames);
static _Return_type_success_(return != false) bool UsingSetupAPI2(_Inout_ CPortAndNamesArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_SETUPAPI2
#ifndef NO_CENUMERATESERIAL_USING_ENUMPORTS
static _Return_type_success_(return != 0) BOOL UsingEnumPorts(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames);
static _Return_type_success_(return != false) bool UsingEnumPorts(_Inout_ CPortAndNamesArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_ENUMPORTS
#ifndef NO_CENUMERATESERIAL_USING_WMI
static HRESULT UsingWMI(_Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames);
static HRESULT UsingWMI(_Inout_ CPortAndNamesArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_WMI
#ifndef NO_CENUMERATESERIAL_USING_COMDB
static _Return_type_success_(return != 0) BOOL UsingComDB(_Inout_ CPortsArray& ports);
static _Return_type_success_(return != false) bool UsingComDB(_Inout_ CPortsArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_COMDB
#ifndef NO_CENUMERATESERIAL_USING_REGISTRY
static _Return_type_success_(return != 0) BOOL UsingRegistry(_Inout_ CNamesArray& ports);
static _Return_type_success_(return != false) bool UsingRegistry(_Inout_ CNamesArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_REGISTRY
#ifndef NO_CENUMERATESERIAL_USING_GETCOMMPORTS
static _Return_type_success_(return != false) bool UsingGetCommPorts(_Inout_ CPortsArray& ports);
#endif //#ifndef NO_CENUMERATESERIAL_USING_REGISTRY
protected:
//Methods
#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
static _Return_type_success_(return != 0) BOOL RegQueryValueString(_In_ ATL::CRegKey& key, _In_ LPCTSTR lpValueName, _Out_ LPTSTR& pszValue);
static _Return_type_success_(return != 0) BOOL QueryRegistryPortName(_In_ ATL::CRegKey& deviceKey, _Out_ int& nPort);
static _Return_type_success_(return != 0) BOOL QueryUsingSetupAPI(const GUID& guid, _In_ DWORD dwFlags, _Inout_ CPortsArray& ports, _Inout_ CNamesArray& friendlyNames);
static _Return_type_success_(return != 0) BOOL QueryDeviceDescription(HDEVINFO hDevInfoSet, SP_DEVINFO_DATA& devInfo, ATL::CHeapPtr<BYTE>& byFriendlyName);
static _Return_type_success_(return != false) bool RegQueryValueString(_In_ ATL::CRegKey& key, _In_ LPCTSTR lpValueName, _Inout_ String& sValue);
static _Return_type_success_(return != false) bool QueryRegistryPortName(_In_ ATL::CRegKey& deviceKey, _Out_ int& nPort);
static _Return_type_success_(return != false) bool QueryUsingSetupAPI(const GUID& guid, _In_ DWORD dwFlags, _Inout_ CPortAndNamesArray& ports);
static _Return_type_success_(return != false) bool QueryDeviceDescription(_In_ HDEVINFO hDevInfoSet, _In_ SP_DEVINFO_DATA& devInfo, _Inout_ String& sFriendlyName);
#endif //#if !defined(NO_CENUMERATESERIAL_USING_SETUPAPI1) || !defined(NO_CENUMERATESERIAL_USING_SETUPAPI2)
static _Return_type_success_(return != 0) BOOL IsNumeric(_In_ LPCSTR pszString, _In_ BOOL bIgnoreColon);
static _Return_type_success_(return != 0) BOOL IsNumeric(_In_ LPCWSTR pszString, _In_ BOOL bIgnoreColon);
static _Return_type_success_(return != false) bool IsNumeric(_In_z_ LPCSTR pszString, _In_ bool bIgnoreColon) noexcept;
static _Return_type_success_(return != false) bool IsNumeric(_In_z_ LPCWSTR pszString, _In_ bool bIgnoreColon) noexcept;
};

View File

@ -56,7 +56,7 @@ BOOL CFreeScanApp::InitInstance()
if (!GetVersionEx(&version))
{
CString s;
s.Format("Error getting Version Info: %d", GetLastError());
s.Format(_T("Error getting Version Info: %d"), GetLastError());
AfxMessageBox(s, MB_ICONSTOP | MB_OK);
return FALSE;
}
@ -71,13 +71,13 @@ BOOL CFreeScanApp::InitInstance()
break;
case VER_PLATFORM_WIN32s:
// Not supported
AfxMessageBox("Sorry, Windows 3.1 Win32s is not supported by FreeScan", MB_ICONSTOP | MB_OK);
AfxMessageBox(_T("Sorry, Windows 3.1 Win32s is not supported by FreeScan"), MB_ICONSTOP | MB_OK);
return FALSE;
break;
default:
{
char szBuffer[100];
sprintf_s(szBuffer, "Untested Win32 Version: %d\nFreeScan may not run correctly\nPlease Email fs@andywhittaker.com with this error.", version.dwPlatformId);
sprintf_s(szBuffer, _T("Untested Win32 Version: %d\nFreeScan may not run correctly\nPlease Email mail@andywhittaker.com with this error."), version.dwPlatformId);
AfxMessageBox(szBuffer, MB_ICONEXCLAMATION | MB_OK);
//return FALSE;
}
@ -91,7 +91,7 @@ BOOL CFreeScanApp::InitInstance()
// the specific initialization routines you do not need.
// Setup the registry for our application
SetRegistryKey("arw Software");
SetRegistryKey(_T("ECUFix"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
CFreeScanDlg dlg(IDS_TITLE, NULL);

View File

@ -401,8 +401,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,1,0,1
PRODUCTVERSION 3,1,0,1
FILEVERSION 3,2,0,1
PRODUCTVERSION 3,2,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -420,13 +420,13 @@ BEGIN
VALUE "Comments", "FreeScan ECU ALDL scantool."
VALUE "CompanyName", "Andy Whittaker - mail@andywhittaker.com"
VALUE "FileDescription", "Scantool for monitoring ECUs/PCMs"
VALUE "FileVersion", "3.1.0.1"
VALUE "FileVersion", "3.2.0.1"
VALUE "InternalName", "FreeScan"
VALUE "LegalCopyright", "Copyright (C) 1999-2018 Andy Whittaker, mail@andywhittaker.com"
VALUE "LegalTrademarks", "www.andywhittaker.com"
VALUE "OriginalFilename", "FreeScan.exe"
VALUE "ProductName", "FreeScan"
VALUE "ProductVersion", "3.1.0.1"
VALUE "ProductVersion", "3.2.0.1"
END
END
BLOCK "VarFileInfo"
@ -3956,6 +3956,17 @@ BEGIN
END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_DETAIL AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table

View File

@ -15,20 +15,20 @@
<SccLocalPath />
<Keyword>MFCProj</Keyword>
<ProjectGuid>{D1DDC93D-3507-E8EE-01A1-AF3073C7D24A}</ProjectGuid>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>Static</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>Static</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -60,7 +60,6 @@
<Optimization>Disabled</Optimization>
<SuppressStartupBanner>true</SuppressStartupBanner>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>true</MinimalRebuild>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AssemblerListingLocation>.\Debug\</AssemblerListingLocation>
<BrowseInformation>true</BrowseInformation>

View File

@ -282,7 +282,7 @@ BOOL CFreeScanDlg::OnInitDialog()
m_pStatusDlg->Create(NULL);
buf = buf + " by Andy Whittaker";
WriteStatus(buf);
WriteStatus("Starting Up..");
WriteStatus(_T("Starting Up.."));
// Initialise the communications supervisor
m_pSupervisor = new CSupervisor(this, m_pStatusDlg);
@ -300,7 +300,7 @@ BOOL CFreeScanDlg::OnInitDialog()
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
WriteStatus("Ready..");
WriteStatus(_T("Ready.."));
return TRUE; // return TRUE unless you set the focus to a control
}

View File

@ -9,7 +9,7 @@ What helped was having a friendly dealer who offered me a few supervised hours s
The result was FreeScan was born and can be seen [on my website HERE](https://www.andywhittaker.com/ecu/freescan/)
## I want to try this right now
In this era of pre-OBD-II protocols, each manufacturer has their own way of talking and interfacing to the ECU. Whereas OBD-II is a 12V protocol, ALDL is a 5V protocol. They also use their own type of interface connector too with a non-standard 8197 baud signalling speed.
In this era of pre-OBD-II protocols, each manufacturer had their own way of talking and interfacing to the ECU. Whereas OBD-II is a 12V protocol, ALDL is a 5V protocol. They also use their own type of interface connector too with a non-standard 8197 baud signalling speed.
This project is what kick-started my (ECUFix)(https://www.ecufix.com/shop/) business where years later I did the same thing to my Audi S4's ECU which was somewhat more complicated... Anyway, I used to sell ALDL interfaces but you could still hack one of the [USB FTDI FT232R ISO OBD-II / VAGCOM / Fiat ECU Scan / IAW Scan2](https://www.ecufix.com/shop/index.php?main_page=product_info&cPath=1&products_id=182) OBD-II interfaces to give you the +-5V signalling required - oh and it's USB too since trying to find an RS232 port on a computer is very difficult nowadays.

View File

@ -122,8 +122,8 @@ CSerialPort::CSerialPort()
// Recall previous settings from the registry, default Com 1 in case 1st time run.
CWinApp* pApp = AfxGetApp();
m_nPortNr = pApp->GetProfileInt("Communications", "Port", 1);
m_nWriteDelay = pApp->GetProfileInt("Communications", "WriteDelay", 100);
m_nPortNr = pApp->GetProfileInt(_T("Communications"), _T("Port"), 1);
m_nWriteDelay = pApp->GetProfileInt(_T("Communications"), _T("WriteDelay"), 100);
}
// Delete dynamic memory
@ -131,8 +131,8 @@ CSerialPort::~CSerialPort()
{
// Save our settings to the registry
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileInt("Communications", "Port", m_nPortNr);
pApp->WriteProfileInt("Communications", "WriteDelay", m_nWriteDelay);
pApp->WriteProfileInt(_T("Communications"), _T("Port"), m_nPortNr);
pApp->WriteProfileInt(_T("Communications"), _T("WriteDelay"), m_nWriteDelay);
// resume the thread if it was suspended. Needed to process m_hShutdownEvent!
if(m_Thread != NULL)
@ -149,7 +149,7 @@ CSerialPort::~CSerialPort()
SetEvent(m_hShutdownEvent);
}
while (m_bThreadAlive);
TRACE("Thread ended\n");
TRACE(_T("Thread ended\n"));
}
// close handles to avoid memory leaks
@ -193,9 +193,9 @@ BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (re
if (portnr == NULL)
{// Use the last port setting.
TRACE("CSerialPort::InitPort - Setting COM Port to last value\n");
TRACE(_T("CSerialPort::InitPort - Setting COM Port to last value\n"));
CWinApp* pApp = AfxGetApp();
m_nPortNr = pApp->GetProfileInt("Communications", "Port", 1);
m_nPortNr = pApp->GetProfileInt(_T("Communications"), _T("Port"), 1);
}
else
m_nPortNr = portnr;
@ -218,18 +218,18 @@ BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (re
ASSERT(pPortOwner != NULL);
CWinApp* pApp = AfxGetApp();
m_nPortNr = pApp->GetProfileInt("Communications", "Port", 1);
TRACE("CSerialPort::InitPort - Com Port %d\n", m_nPortNr);
m_nPortNr = pApp->GetProfileInt(_T("Communications"), _T("Port"), 1);
TRACE(_T("CSerialPort::InitPort - Com Port %d\n"), m_nPortNr);
if (m_nPortNr < 1)
{// This should never happen, however a mistake could have been made in the registry.
TRACE("CSerialPort::InitPort - Com Port cannot be 0");
TRACE(_T("CSerialPort::InitPort - Com Port cannot be 0"));
return FALSE;
}
if (m_nPortNr > 255)
{// This should never happen, however a mistake could have been made in the registry.
TRACE("CSerialPort::InitPort - Com Port cannot be greater than 255");
TRACE(_T("CSerialPort::InitPort - Com Port cannot be greater than 255"));
return FALSE;
}
@ -240,7 +240,7 @@ BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (re
{
SetEvent(m_hShutdownEvent);
} while (m_bThreadAlive);
TRACE("Thread ended\n");
TRACE(_T("Thread ended\n"));
}
// create events
@ -288,8 +288,8 @@ BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (re
}
// prepare port strings
sprintf_s(szPort, 50, "COM%d", m_nPortNr);
sprintf_s(szBaud, 50, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);
sprintf_s(szPort, 50, _T("COM%d"), m_nPortNr);
sprintf_s(szBaud, 50, _T("baud=%d parity=%c data=%d stop=%d"), baud, parity, databits, stopbits);
// get a handle to the port
m_hComm = CreateFile(szPort, // communication port string (COMX)
@ -342,19 +342,19 @@ BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (re
if (SetCommState(m_hComm, &m_dcb))
; // normal operation... continue
else
ProcessErrorMessage("SetCommState()");
ProcessErrorMessage(_T("SetCommState()"));
}
else
ProcessErrorMessage("BuildCommDCB()");
ProcessErrorMessage(_T("BuildCommDCB()"));
}
else
ProcessErrorMessage("GetCommState()");
ProcessErrorMessage(_T("GetCommState()"));
}
else
ProcessErrorMessage("SetCommMask()");
ProcessErrorMessage(_T("SetCommMask()"));
}
else
ProcessErrorMessage("SetCommTimeouts()");
ProcessErrorMessage(_T("SetCommTimeouts()"));
delete [] szPort;
delete [] szBaud;
@ -368,7 +368,7 @@ BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (re
EscapeCommFunction(m_hComm, SETDTR); // This is needed for self-powered interfaces
EscapeCommFunction(m_hComm, SETRTS); // This is needed for self-powered interfaces
TRACE("Initialisation for Com Port %d completed.\n",
TRACE(_T("Initialisation for Com Port %d completed.\n"),
m_nPortNr);
return TRUE;
@ -381,7 +381,7 @@ UINT CSerialPort::CommThread(LPVOID pParam)
// a pointer of CSerialPort class
CSerialPort *port = (CSerialPort*)pParam;
TRACE("Com Port %d thread is starting.\n", port->m_nPortNr);
TRACE(_T("Com Port %d thread is starting.\n"), port->m_nPortNr);
// Set the status variable in the dialog class to
// TRUE to indicate the thread is running.
@ -537,19 +537,19 @@ UINT CSerialPort::CommThread(LPVOID pParam)
} // close forever loop
// when we get here, the thread is about to shutdown and exit.
TRACE("Com Port %d thread about to die.\n", port->m_nPortNr);
TRACE(_T("Com Port %d thread about to die.\n"), port->m_nPortNr);
return 0;
}
// Start comm watching
BOOL CSerialPort::StartMonitoring()
{
TRACE("Com Port %d starting monitoring.\n", m_nPortNr);
TRACE(_T("Com Port %d starting monitoring.\n"), m_nPortNr);
if (!(m_Thread = AfxBeginThread(CommThread, this, THREAD_PRIORITY_NORMAL)))
return FALSE;
// Clear buffer
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
TRACE("Thread %ld started\n", (DWORD)m_Thread->m_nThreadID);
TRACE(_T("Thread %ld started\n"), (DWORD)m_Thread->m_nThreadID);
return TRUE;
}
@ -557,7 +557,7 @@ BOOL CSerialPort::StartMonitoring()
// Restart the comm thread
BOOL CSerialPort::RestartMonitoring()
{
TRACE("Com Port %d re-starting monitoring.\n", m_nPortNr);
TRACE(_T("Com Port %d re-starting monitoring.\n"), m_nPortNr);
// Clear buffer
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
if(m_Thread != NULL)
@ -573,7 +573,7 @@ BOOL CSerialPort::StopMonitoring()
{
if(m_Thread != NULL)
{
TRACE("Com Port %d stopped monitoring.\n", m_nPortNr);
TRACE(_T("Com Port %d stopped monitoring.\n"), m_nPortNr);
m_Thread->SuspendThread();
}
// Clear buffer
@ -599,9 +599,9 @@ void CSerialPort::ProcessErrorMessage(char* ErrorText)
NULL
);
sprintf_s(Temp, 200, "WARNING: %s Failed with the following error: \n%s\nPort: %d\n",
sprintf_s(Temp, 200, _T("WARNING: %s Failed with the following error: \n%s\nPort: %d\n"),
(char*)ErrorText, (char*)lpMsgBuf, m_nPortNr);
MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);
MessageBox(NULL, Temp, _T("Application Error"), MB_ICONSTOP);
LocalFree(lpMsgBuf);
delete[] Temp;
@ -649,7 +649,7 @@ void CSerialPort::WriteChar(CSerialPort* port)
default:
{
// all other error codes
port->ProcessErrorMessage("WriteFile()");
port->ProcessErrorMessage(_T("WriteFile()"));
AfxThrowSerialException();
}
}
@ -676,7 +676,7 @@ void CSerialPort::WriteChar(CSerialPort* port)
// deal with the error code
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
port->ProcessErrorMessage(_T("GetOverlappedResults() in WriteFile()"));
AfxThrowSerialException();
if (GetLastError() != ERROR_IO_PENDING)
@ -690,7 +690,7 @@ void CSerialPort::WriteChar(CSerialPort* port)
// Verify that the data size sent equals what we tried to send
if (BytesSent != (DWORD)port->m_nActualWriteBufferSize)
{
TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n",
TRACE(_T("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n"),
BytesSent, port->m_nActualWriteBufferSize);
}
}
@ -789,7 +789,7 @@ void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
// deal with the error code
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
port->ProcessErrorMessage(_T("GetOverlappedResults() in ReadFile()"));
AfxThrowSerialException();
}
} // close if (!bRead)
@ -870,8 +870,8 @@ UINT CSerialPort::GetPort(void)
void CSerialPort::SetPort(UINT nPort)
{
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileInt("Communications", "Port", nPort);
TRACE(_T("Comms port number changed\n"));
pApp->WriteProfileInt(_T("Communications"), _T("Port"), nPort);
TRACE(_T(_T("Comms port number changed\n")));
}
// Returns the minimum number of milliseconds the TX routine will wait before returning
@ -886,6 +886,6 @@ void CSerialPort::SetWriteDelay(DWORD nDelay)
m_nWriteDelay = nDelay;
// Write this to the registry
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileInt("Communications", "WriteDelay", m_nWriteDelay);
pApp->WriteProfileInt(_T("Communications"), _T("WriteDelay"), m_nWriteDelay);
TRACE(_T("Comms port write delay changed\n"));
}

View File

@ -29,8 +29,8 @@ CStatusDlg::CStatusDlg(CWnd* pParent /*=NULL*/)
//}}AFX_DATA_INIT
//Load hide status
CWinApp* pApp = AfxGetApp();
m_hidden = pApp->GetProfileInt("StatusDlg", "Hide Status", FALSE);
m_csLogFile = pApp->GetProfileString("StatusDlg", "Log Filename", "");
m_hidden = pApp->GetProfileInt(_T("StatusDlg"), _T("Hide Status"), FALSE);
m_csLogFile = pApp->GetProfileString(_T("StatusDlg"), _T("Log Filename"), _T(""));
m_WindowPos.left = 0;
m_WindowPos.right = 0;
@ -48,8 +48,8 @@ CStatusDlg::~CStatusDlg()
//Save hide status
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileInt("StatusDlg", "Hide Status", m_hidden);
pApp->WriteProfileString("StatusDlg", "Log Filename", m_csLogFile);
pApp->WriteProfileInt(_T("StatusDlg"), _T("Hide Status"), m_hidden);
pApp->WriteProfileString(_T("StatusDlg"), _T("Log Filename"), m_csLogFile);
StartLog(FALSE);// close the logging file when we exit.
}
@ -80,7 +80,7 @@ void CStatusDlg::WriteStatus(CString csText)
if (m_hidden) // don't write to window when hidden
return;
// TRACE("%s\n", csText);
// TRACE_T(("%s\n"), csText);
if (IsWindow(m_hWnd))
{
PumpMessages();
@ -95,7 +95,7 @@ void CStatusDlg::WriteStatus(CString csText)
if (m_file.m_pStream != NULL) // i.e. we have a file open
{
csText = csText + "\n"; // Line Feed while we log to disk
csText = csText + _T("\n"); // Line Feed while we log to disk
m_file.WriteString(csText);
}
if (IsWindow(m_hWnd))
@ -181,11 +181,11 @@ BOOL CStatusDlg::StartLog(BOOL bStart)
{ // we want to close the logging file
if (m_file.m_hFile != CFile::hFileNull)
{
WriteStatusLogged("Log file stopped");
WriteStatusLogged(_T("Log file stopped"));
m_file.Close(); // close the logging file when we exit.
}
else
WriteStatusLogged("Log file is already closed");
WriteStatusLogged(_T("Log file is already closed"));
return FALSE;
}
@ -203,12 +203,13 @@ BOOL CStatusDlg::StartLog(BOOL bStart)
ofn.nMaxFile = _countof(szFileName);
ofn.lpstrFileTitle = (LPTSTR)szFileTitle;
ofn.nMaxFileTitle = _countof(szFileTitle);
ofn.lpstrTitle = "Create/Open Logging File";
ofn.lpstrFilter = "log Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0\0";
ofn.lpstrInitialDir = m_csLogFile;
ofn.lpstrTitle = _T("Create/Open Logging File");
ofn.lpstrFilter = _T("log Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0\0");
ofn.lpstrInitialDir = m_csLogFile.GetString();
// setup initial file name from the registry
lstrcpyn(szFileName, m_csLogFile, _countof(szFileName));
//lstrcpyn(szFileName, m_csLogFile, _countof(szFileName));//unsafe
StringCchCopy(szFileName, _countof(szFileName), m_csLogFile.GetString());
ofn.Flags = OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
@ -220,26 +221,26 @@ BOOL CStatusDlg::StartLog(BOOL bStart)
switch (dwerror)
{
case 0 : // no error
csBuf.Format("User cancelled/closed file Dialog");
csBuf.Format(_T("User cancelled/closed file Dialog"));
break; // cancel or closed was pressed
case FNERR_BUFFERTOOSMALL :
csBuf.Format("Buffer too small");
csBuf.Format(_T("Buffer too small"));
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
break;
case FNERR_INVALIDFILENAME :
csBuf.Format("Invalid file name");
csBuf.Format(_T("Invalid file name"));
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
break;
case CDERR_MEMALLOCFAILURE :
csBuf.Format("Memory allocation failure");
csBuf.Format(_T("Memory allocation failure"));
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
break;
case CDERR_MEMLOCKFAILURE :
csBuf.Format("Memory lock failure");
csBuf.Format(_T("Memory lock failure"));
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
break;
default:
csBuf.Format("An unknown error has occured - %ld", dwerror);
csBuf.Format(_T("An unknown error has occured - %ld"), dwerror);
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
}
WriteStatus(csBuf);
@ -247,17 +248,17 @@ BOOL CStatusDlg::StartLog(BOOL bStart)
}
// Copy filename from our dialog to the CString member variable
m_csLogFile.Format("%s",ofn.lpstrFile);
m_csLogFile.Format(_T("%s"),ofn.lpstrFile);
if (!m_file.Open(m_csLogFile, CFile::modeCreate | CFile::modeReadWrite | CFile::typeText))
{
csBuf.Format("Cannot open %s", m_csLogFile);
csBuf.Format(_T("Cannot open %s"), m_csLogFile.GetString());
WriteStatus(csBuf);
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
return FALSE;
}
WriteStatusLogged("Log file has started");
WriteStatusLogged(_T("Log file has started"));
/*
// Construct our File Dialog
@ -338,7 +339,7 @@ void CStatusDlg::PumpMessages(void)
void CStatusDlg::PrintRect(LPRECT lpR)
{
CString csData;
csData.Format("Rect Data:\nleft = %li\ntop = %li\nright = %li\nbottom = %li",
csData.Format(_T("Rect Data:\nleft = %li\ntop = %li\nright = %li\nbottom = %li"),
lpR->left, lpR->top, lpR->right, lpR->bottom);
AfxMessageBox(csData, MB_OK | MB_ICONINFORMATION);
}
@ -350,8 +351,8 @@ BOOL CStatusDlg::OnInitDialog()
{
//Retrieve the Window Position from the registry
CWinApp* pApp = AfxGetApp();
m_WindowPos.left = pApp->GetProfileInt("StatusDlg", "left pos", 0);
m_WindowPos.top = pApp->GetProfileInt("StatusDlg", "top pos", 0);
m_WindowPos.left = pApp->GetProfileInt(_T("StatusDlg"), _T("left pos"), 0);
m_WindowPos.top = pApp->GetProfileInt(_T("StatusDlg"), _T("top pos"), 0);
// Set the window position
SetWindowPos( &wndBottom, m_WindowPos.left, m_WindowPos.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
@ -396,8 +397,8 @@ void CStatusDlg::OnDestroy()
{
//Save the current window position
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileInt("StatusDlg", "left pos", m_WindowPos.left);
pApp->WriteProfileInt("StatusDlg", "top pos", m_WindowPos.top);
pApp->WriteProfileInt(_T("StatusDlg"), _T("left pos"), m_WindowPos.left);
pApp->WriteProfileInt(_T("StatusDlg"), _T("top pos"), m_WindowPos.top);
CDialog::OnDestroy();
}

View File

@ -42,6 +42,7 @@
#include <WBemCli.h>
#include <comdef.h>
#include <Afxpriv.h>
#include <strsafe.h> // For the new safe string functions
//For CENUMERATESERIAL
#include <vector>

View File

@ -44,8 +44,8 @@ CSupervisor::CSupervisor(CFreeScanDlg* pMainDlg, CStatusDlg* pStatusDlg)
// Recall previous settings from the registry.
CFreeScanApp* pApp = (CFreeScanApp*) AfxGetApp();
m_bCentigrade = pApp->GetProfileInt("Supervisor", "Centigrade", TRUE);
m_bMiles = pApp->GetProfileInt("Supervisor", "Miles", TRUE);
m_bCentigrade = pApp->GetProfileInt(_T("Supervisor"), _T("Centigrade"), TRUE);
m_bMiles = pApp->GetProfileInt(_T("Supervisor"), _T("Miles"), TRUE);
m_dwBytesSent = 0;
m_dwBytesReceived = 0;
@ -82,8 +82,8 @@ CSupervisor::~CSupervisor()
{
// Save our settings to the registry
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileInt("Supervisor", "Centigrade", m_bCentigrade);
pApp->WriteProfileInt("Supervisor", "Miles", m_bMiles);
pApp->WriteProfileInt(_T("Supervisor"), _T("Centigrade"), m_bCentigrade);
pApp->WriteProfileInt(_T("Supervisor"), _T("Miles"), m_bMiles);
delete m_ucF005;
delete m_ucF00A;
@ -439,9 +439,9 @@ BOOL CSupervisor::Start(void)
ASSERT(m_pCom != NULL);
// This sets the com port up
if (!m_pCom->StartMonitoring())
WriteStatus("CSupervisor- Failed to start the Com Port");
WriteStatus(_T("CSupervisor- Failed to start the Com Port"));
else
WriteStatus("CSupervisor- Com Port started");
WriteStatus(_T("CSupervisor- Com Port started"));
return TRUE;
}
@ -452,11 +452,11 @@ BOOL CSupervisor::Restart(void)
// This sets the com port up
if (!m_pCom->RestartMonitoring())
{
WriteStatus("CSupervisor- Failed to restart the Com Port");
WriteStatus(_T("CSupervisor- Failed to restart the Com Port"));
return FALSE;
}
else
WriteStatus("CSupervisor- Com Port restarted");
WriteStatus(_T("CSupervisor- Com Port restarted"));
::SendMessage(m_ProtocolWnd, WM_PROT_CMD_RESETSTATE, (WPARAM) NULL, (LPARAM) NULL);
return TRUE;
}
@ -470,11 +470,11 @@ BOOL CSupervisor::Stop(void)
// This sets the com port up
if (!m_pCom->StopMonitoring())
{
WriteStatus("CSupervisor- Failed to stop the Com Port");
WriteStatus(_T("CSupervisor- Failed to stop the Com Port"));
return FALSE;
}
else
WriteStatus("CSupervisor- Com Port stopped");
WriteStatus(_T("CSupervisor- Com Port stopped"));
return TRUE;
}

Binary file not shown.