Перед вами
очередной выпуск рассылки "Программирование на WinApi" Переводы многих функций Win32API, которые часто используются
в данной рассылке, вы можете получать, подписавшись на дружественную
рассылку "WinAPI на
русском". Справочник по функциям Win32API вы
можете посмотреть на сайте BcbDev.ru в разделе MSDN
по-русски.
Как узнать какие COM
порты доступны в системе?
В разных
системах это делается по-разному. Ниже приведён пример, показывающий
методы определения доступных портов в системах Windows 9x и Windows NT.
#include <windows.h>
#include <TCHAR.H >
#include <conio.h>
#include <stdio.h>
void EnumerateSerialPorts()
{
//В какой системе работаем?
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
BOOL bGetVer = GetVersionEx(&osvi);
//В NT используем API QueryDosDevice
if (bGetVer && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT))
{
//Используем QueryDosDevice для просмотра всех устройств похожих на COMx.
//Это наилучшее решение, так как порты не требуется открывать
TCHAR szDevices[65535];
DWORD dwChars = QueryDosDevice(NULL, szDevices, 65535);
if (dwChars)
{
int i=0;
for (;;)
{
//Получаем текущее имя устройства
TCHAR* pszCurrentDevice = &szDevices[i];
//Если похоже на "COMX" выводим на экран
int nLen = _tcslen(pszCurrentDevice);
if (nLen > 3 && _tcsnicmp(pszCurrentDevice, _T("COM"), 3) == 0)
{
printf(pszCurrentDevice);
printf("\n");
}
// Переходим к следующему символу терминатору
while(szDevices[i] != _T('\0'))
i++;
// Перескакиваем на следующую строку
i++;
// Список завершается двойным символом терминатором, так что если символ
// NULL, мы дошли до конца
if (szDevices[i] == _T('\0'))
break;
}
}
}
else
{
//В 95/98 открываем каждый порт для определения его существования
//Поддерживается до 255 COM портов, так что мы проходим по всему списку
//Если мы не можем открыть порт, или происходит ошибка при открытии,
//получаем access denied или общую ошибку все эти случаи указывают на
//то, что под таким номером есть порт.
for (UINT i=1; i<256; i++)
{
//Формируем сырое имя устройства
char sPort[10];
sprintf(sPort,"\\\\.\\COM%d", i);
//Пытаемся открыть каждый порт
BOOL bSuccess = FALSE;
HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hPort == INVALID_HANDLE_VALUE)
{
DWORD dwError = GetLastError();
//Смотрим что получилось при открытии
if (dwError == ERROR_ACCESS_DENIED || dwError == ERROR_GEN_FAILURE)
bSuccess = TRUE;
}
else
{
//Порт открыт успешно
bSuccess = TRUE;
//Не забываем закрывать каждый открытый порт,
//так как мы не собираемся с ним работать...
CloseHandle(hPort);
}
//Выводим на экран название порта
if (bSuccess)
{
printf(sPort);
printf("\n");
}
}
}
}
int main()
{
EnumerateSerialPorts();
getch();
return 0;
}