Определение наличия СОМ портов
От: Dimer  
Дата: 12.02.02 07:05
Оценка:
Программе нужно определить наличие на РС СОМ портов. Имеется ли для этого API-функция или надо обязательно читать реестр, или лезть в ASM вставки ?
Re: Определение наличия СОМ портов
От: GAV  
Дата: 12.02.02 09:43
Оценка:
BOOL TestPort(int n)
{
BOOL result = FALSE;
char buf[16];
sprintf(buf, "\\\\.\\COM%d", n); // для COM1-COM9 можно просто "COMn"
HANDLE HandleCom = CreateFile(buf, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if(HandleCom != NULL)
{
CloseHandle(HandleCom);
result = TRUE;
}
return result;
}
Re[2]: Определение наличия СОМ портов
От: Dimer  
Дата: 12.02.02 10:08
Оценка:
Здравствуйте GAV, Вы писали:


GAV>BOOL TestPort(int n)

GAV>{
GAV> BOOL result = FALSE;
GAV> char buf[16];
GAV> sprintf(buf, "\\\\.\\COM%d", n); // для COM1-COM9 можно просто "COMn"
GAV> HANDLE HandleCom = CreateFile(buf, GENERIC_READ | GENERIC_WRITE, 0, NULL,
GAV> OPEN_EXISTING, 0, NULL);
GAV> if(HandleCom != NULL)
GAV> {
GAV> CloseHandle(HandleCom);
GAV> result = TRUE;
GAV> }
GAV> return result;
GAV>}

Ну это уж совсем примитив

Re: Определение наличия СОМ портов
От: Vovkos Россия https://ioninja.com
Дата: 12.02.02 14:04
Оценка:
Здравствуйте Dimer, Вы писали:

D>Программе нужно определить наличие на РС СОМ портов. Имеется ли для этого API-функция или надо обязательно читать реестр, или лезть в ASM вставки ?


Способ 1

DEFINE_GUID(GUID_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18);
HDEVINFO hDevInfoSet = ::SetupDiGetClassDevs((LPGUID) &GUID_PORTS, NULL, HWND_DESKTOP, DIGCF_PRESENT);
SP_DEVINFO_DATA DevInfoData = { sizeof(SP_DEVINFO_DATA) };    
CHAR     szFriendlyName[MAX_PATH],
    szPortName[MAX_PATH];

for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfoSet, i, &DevInfoData); i++)
{
    ::SetupDiGetDeviceRegistryProperty(
        hDevInfoSet, &DevInfoData, SPDRP_FRIENDLYNAME,
        NULL, (PBYTE)szFriendlyName, MAX_PATH, NULL);

    HKEY hKey = ::SetupDiOpenDevRegKey(
        hDevInfoSet, &DevInfoData,
        DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_ALL_ACCESS);

    DWORD size = MAX_PATH;
    ::RegQueryValueEx(hKey, "PortName", NULL, NULL, (PBYTE)szPortName, &size);

    if (_strnicmp(szPortName, "COM", 3) == 0) // skip LPT ports
        cout << szPortName << " - " << szFriendlyName << endl;
}

::SetupDiDestroyDeviceInfoList(hDevInfoSet);


Способ 2

HKEY hKey = NULL;
RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", &hKey);

CHAR    szDeviceMapEntry[MAX_PATH],
    szDeviceMapValue[MAX_PATH];

for (DWORD i = 0;;i++)
{
    DWORD    dwEntryType = REG_SZ,
        dwEntrySize = MAX_PATH, 
        dwValueSize = MAX_PATH;

    if (ERROR_SUCCESS != RegEnumValue(
        hKey, i, szDeviceMapEntry, &dwEntrySize, 
        NULL, &dwEntryType, (PBYTE)szDeviceMapValue, &dwValueSize))
        break;

    cout << szDeviceMapValue << endl;
}

::RegCloseKey(hKey);


Способ 2 считается основным. Но способ 1 лучше (если не требуется поддерживать NT4 и 95 — там он работать не будет), так как ты задарма получаешь многие бонусы типа friendlyname, pnpid, параметры порта и др.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.