Как получить серийный номер клавиатуры USB через IOCTL_HID_GET_SERIALNUMBER_STRING? - PullRequest
0 голосов
/ 10 марта 2020

Я пытаюсь получить серийный номер клавиатуры USB в консольном приложении C / C ++ Windows. Я могу успешно получить аппаратный идентификатор клавиатуры в GetDeviceName() следующим образом:

#define IOCTL_GET_HARDWARE_ID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x880, METHOD_BUFFERED, FILE_ANY_ACCESS)

unsigned int interception_get_hardware_id(InterceptionContext context, InterceptionDevice device, void *hardware_id_buffer, unsigned int buffer_size)
{
    InterceptionDeviceArray device_array = (InterceptionDeviceArray)context;
    DWORD output_size = 0;

    if(context == 0 || interception_is_invalid(device)) return 0;

    DeviceIoControl(device_array[device - 1].handle, IOCTL_GET_HARDWARE_ID, NULL, 0, hardware_id_buffer, buffer_size, &output_size, NULL);

    return output_size;
}

char *Interception::GetDeviceName(void)
{
    wchar_t hardware_id[500];

    size_t length = interception_get_hardware_id(context, device, hardware_id, sizeof(hardware_id));
    if(length > 0 && length < sizeof(hardware_id)) {
        wcstombs(deviceName, hardware_id, 4096);
        return deviceName;
    }

    return NULL;
}

Теперь я хочу получить серийный номер. Когда я следую подобному шаблону, я получаю невероятно большое значение length в GetDeviceSerialNumber() и, таким образом, никогда не заполняю широкий массив символов:

#define IOCTL_HID_GET_SERIALNUMBER_STRING CTL_CODE(FILE_DEVICE_UNKNOWN, 0x920, METHOD_BUFFERED, FILE_ANY_ACCESS) // I picked 0x920 as an arbitrary number, and is possibly wrong. Should it be 112? 0x000b01c2?

unsigned int interception_get_serialnumber(InterceptionContext context, InterceptionDevice device, void *serial_number_buffer, unsigned int buffer_size)
{
    InterceptionDeviceArray device_array = (InterceptionDeviceArray)context;
    DWORD output_size = 0;

    if (context == 0 || interception_is_invalid(device)) return 0;

    DeviceIoControl(device_array[device - 1].handle, IOCTL_HID_GET_SERIALNUMBER_STRING, NULL, 0, serial_number_buffer, buffer_size, &output_size, NULL);

    return output_size;
}

char *Interception::GetDeviceSerialNumber(void)
{
    wchar_t serial_number[500];

    size_t length = interception_get_serialnumber(context, device, serial_number, sizeof(serial_number));
    if (length > 0 && length < sizeof(serial_number)) {
        wcstombs(deviceSerialNumber, serial_number, 4096);
        return deviceSerialNumber;
    }

    return NULL;
}

Я почти уверен, что проблема связана с как я настроил свой CTRL_CODE для IOCTL_HID_GET_SERIALNUMBER_STRING. Я перепробовал несколько подходов, но пока мне не повезло. Любая помощь будет принята с благодарностью!

...