Brendan
Brendan

Reputation: 19413

Can I programmatically determine from a WPF app which Virtual COM ports are incoming and which are outgoing?

I have a Bluetooth serial device I need to connect to. I can query the WMI data base to find the Bluetooth ports that I need by using

Get-WmiObject -query "select DeviceID,PNPDeviceID from Win32_SerialPort"

or using the registry by inspecting

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM\Device\BthModem0

however I can't find an exposed API that allows me to determine which of the two created Virtual COM ports are incoming and outgoing.

This information is displayed by Windows if you dig deep enough in the Device Manager and so I should be available (by a PInvoke or something?) but I need to find out a way to find it programatically from a WPF application.

Upvotes: 0

Views: 635

Answers (1)

Luis Ramirez
Luis Ramirez

Reputation: 424

What you are looking for is to get the device capabilities.

Note the difference: Incoming Ports are Incoming vs Outgoing Port Capabilities

I have created a sample C++ sample that does what you need based on the following example. You will need to use PINVOKE to call the appropriate methods. I am sorry I cannot provide the C# code as its for my work.

This depends on the Microsoft Bluetooth stack. You will need some modifications for widcomm or the Toshiba Bluetooth stack.

You can fetch the sample from Github

To get it to work you will need to add the following to the linker options

Setupapi.lib Ole32.lib

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>
#include "Objbase.h"

int main(int argc, char *argv[], char *envp[])
{
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i;
    CLSID guid;
    //Class = Ports
    //ClassGuid = { 4d36e978 - e325 - 11ce - bfc1 - 08002be10318}


    LPCOLESTR  guidString = L"{86E0D1E0-8089-11D0-9CE4-08003E301F73}";
    HRESULT a = CLSIDFromString(guidString, &guid);
    // Create a HDEVINFO with all present devices.
    hDevInfo = SetupDiGetClassDevs(&guid,
        0, // Enumerator
        0,
        DIGCF_DEVICEINTERFACE);

    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        // Insert error handling here.
        return 1;
    }

    // Enumerate through all devices in Set.

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    for (i = 0;SetupDiEnumDeviceInfo(hDevInfo, i,
        &DeviceInfoData);i++)
    {
        DWORD DataT;
        LPTSTR buffer = (LPTSTR)LocalAlloc(LPTR, 4096 * 2);
        DWORD buffersize = 4096;

        LPBYTE buffer2 = (LPBYTE)LocalAlloc(LPTR, 4096 * 2);



        SetupDiGetDeviceRegistryProperty(
            hDevInfo,
            &DeviceInfoData,
            SPDRP_FRIENDLYNAME,
            &DataT,
            (PBYTE)buffer,
            buffersize,
            &buffersize);





        if (wcsstr(buffer, L"Standard Serial over Bluetooth link"))
        {
            SetupDiGetDeviceRegistryProperty(
                hDevInfo,
                &DeviceInfoData,
                SPDRP_CAPABILITIES,
                &DataT,
                (PBYTE)buffer2,
                buffersize,
                &buffersize);

            wprintf(L"Result:%s - ", buffer);
            int a = *buffer2;
            if (a == 0xC0)
            {
                wprintf(L"Incoming");
            }
            else if (a == 0xC4)
            {
                wprintf(L"Outgoing");
            }

            wprintf(L"\n", buffer);

        }

        if (buffer) LocalFree(buffer);
    }


    if (GetLastError() != NO_ERROR &&
        GetLastError() != ERROR_NO_MORE_ITEMS)
    {
        // Insert error handling here.
        return 1;
    }

    //  Cleanup
    SetupDiDestroyDeviceInfoList(hDevInfo);
    getchar();
    return 0;
}

Result

Upvotes: 0

Related Questions