Отправить IOCTL на драйвер устройства Windows - ошибка CreateFile - PullRequest
9 голосов
/ 25 ноября 2011

Я хочу отправить команду IOCTL на устройство чтения ПК / SC, подключенное к моему компьютеру (win7 64 bit).Чтобы отправить команду IOCTL, мне нужна РУЧКА на устройство, которое я не могу создать.

Устройство указано как «OMNIKEY 1021» в диспетчере устройств, имя объекта физического устройства - «\ Device \ USBPDO-15" .Использование "Winobj" инструмент, я могу обнаружить 2 символические ссылки: USB # VID_076B & PID_1021 # 5 & 291f6990 & 0 & 1 # {50dd5230-ba8a-11d1-bf5d-0000f805f530} USB # VID_076B & PID_1021 # 5 & 291f6990 & 0 & 1 # {a5dcbf10-6530-11d2-901f-00c04fb951ed}

Моя проблема: я не могу создать действительный дескриптор этого устройства с помощью функции CreateFile:

Я нашел несколько возможных форматов в MSDN / Google для использования в качестве параметра lpFileName в CreateFileфункция, но ни один из них, кажется, не работает:

\\?\Device\USBPDO-15
\\.\Device\USBPDO-15
\\GLOBAL??\Device\USBPDO-15
\GLOBAL??\Device\USBPDO-15
\\.\USBPDO-15
\\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

Пример кода :

#include <iostream>
#include <Windows.h>

int main (int argc, char* argv[])
{
    HANDLE handle = CreateFile (
        L"\\\\.\\Device\\USBPDO-15",
        0,
        FILE_SHARE_READ, //FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0, //FILE_FLAG_OVERLAPPED,
        NULL
    );

    if (handle == INVALID_HANDLE_VALUE)
        std::cout << "INVALID HANDLE" << std::endl;
    else
        std::cout << "HANDLE: " << std::hex << handle << std::endl;
}

Примечания:

  • Возвращенный дескриптор всегда недействителен
  • Всегда работает от имени администратора, поэтому привилегии не должны быть проблемой

edit:

Решение:

  • Служба ПК / SC получает исключительное право собственности на устройства, поэтому любая попытка вызова CreateFile всегда будет неудачной.
  • Решением является драйвер пространства ядра, это позволяет вам передавать IRP водителю.(Мне удалось реализовать драйвер фильтра KMDF для изменения данных, отправляемых / полученных на / с устройства)

Ответы [ 2 ]

7 голосов
/ 28 ноября 2011

Попробуй по-моему. Я использую Setup API для перечисления всех активных USB-устройств в системе и получения путей. Таким образом, вы можете узнать, является ли путь или другие аргументы, которые CreateFile не нравятся.

Я добавлю несколько комментариев чуть позже, если кому-то будет интересно.

HDEVINFO hDevInfo = SetupDiGetClassDevs( &_DEVINTERFACE_USB_DEVICE, 0, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    if(hDevInfo == INVALID_HANDLE_VALUE)
    {
        return ERR_FAIL;
    }

    std::vector<SP_INTERFACE_DEVICE_DATA> interfaces;

    for (DWORD i = 0; true; ++i)
    {
        SP_DEVINFO_DATA devInfo;
        devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
        BOOL succ = SetupDiEnumDeviceInfo(hDevInfo, i, &devInfo);
        if (GetLastError() == ERROR_NO_MORE_ITEMS)
            break;
        if (!succ) continue;

        SP_INTERFACE_DEVICE_DATA ifInfo;
        ifInfo.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
        if (TRUE != SetupDiEnumDeviceInterfaces(hDevInfo, &devInfo,  &(_DEVINTERFACE_USB_DEVICE), 0, &ifInfo))
        {
            if (GetLastError() != ERROR_NO_MORE_ITEMS)
                break;
        }
        interfaces.push_back(ifInfo);
    }

    std::vector<SP_INTERFACE_DEVICE_DETAIL_DATA*> devicePaths;
    for (size_t i = 0; i < interfaces.size(); ++i)
    {
        DWORD requiredSize = 0;
        SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), NULL, NULL, &requiredSize, NULL);
        SP_INTERFACE_DEVICE_DETAIL_DATA* data = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc(requiredSize);
        assert (data);
        data->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

        if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), data, requiredSize, NULL, NULL))
        {
            continue;
        }
        devicePaths.push_back(data);
    }
1 голос
/ 29 мая 2017

Просто попробуйте с CreateFile(L"\\\\.\\{GUID}",etc...

...