程式語言 - MinGW - C/C++ - Enumerate USB HID



參考資訊:
http://www.winprog.org/tutorial/
http://winapi.freetechsecrets.com/win32/
https://github.com/gammasoft71/Examples_Win32
http://masm32.com/board/index.php?topic=3584.0
https://learn.microsoft.com/en-us/windows/win32/winmsg/window-styles

main.cpp

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <setupapi.h>

extern "C" {
    #include <hidsdi.h>
}

int enum_hid(void)
{
    GUID hidGuid;
    HANDLE hidHandle;

    HidD_GetHidGuid(&hidGuid);
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        printf("failed to SetupDiGetClassDevs\n");
        return 0;
    }

    int deviceNo = 0;
    SP_DEVICE_INTERFACE_DATA devInfoData;
    devInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    SetLastError(NO_ERROR);
    while (GetLastError() != ERROR_NO_MORE_ITEMS) {
        if (SetupDiEnumInterfaceDevice(hDevInfo, 0, &hidGuid, deviceNo, &devInfoData)) {
            printf("Index: %d\n", deviceNo);
            ULONG requiredLength = 0;
            SetupDiGetInterfaceDeviceDetail(hDevInfo, &devInfoData, NULL, 0, &requiredLength, NULL);
            PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA *)malloc(requiredLength);
            devDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
            if (SetupDiGetInterfaceDeviceDetail(hDevInfo, &devInfoData, devDetail, requiredLength, NULL, NULL)) {
                printf("Path: %s\n", devDetail->DevicePath);
                hidHandle = CreateFile(devDetail->DevicePath, 
                    GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                if (hidHandle != INVALID_HANDLE_VALUE) {
                    _HIDD_ATTRIBUTES hidAttributes;
                    if (HidD_GetAttributes(hidHandle, &hidAttributes)) {
                        printf("USB_VID:0x%04x, USB_PID:0x%04x\n", hidAttributes.VendorID, hidAttributes.ProductID);
                    }
                    CloseHandle(hidHandle);
                }
                free(devDetail);
            }
            deviceNo += 1;
        }
    }
    SetupDiDestroyDeviceInfoList(hDevInfo);
    return 1;
}

int main(int argc, char **argv)
{
    enum_hid();
    return 0;
}

編譯步驟:

$ i686-w64-mingw32-g++ -o main.exe main.cpp -lsetupapi -lhid -static -fpermissive

執行結果:

C:\> main.exe
    Index: 0
    Path: \\?\hid#vid_16c0&pid_0486&mi_00#7&259e7455&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
    USB_VID:0x16c0, USB_PID:0x0486