2016-05-13 20 views
10

EDIT: Problem zgłoszony tutaj: https://github.com/signal11/hidapi/issues/276CreateFileA nie otwiera urządzenie HID w Windows

Inkling to urządzenie pióra firmy Wacom. (InklingReader) to projekt typu open source, który pobiera z niego dane w czasie rzeczywistym.

Próbuję uporządkować InklingReader używać HIDAPI zamiast libusb(jak to działa na wyższym poziomie: HID zamiast surowego USB, więc jest znacznie bardziej zwarty & Nadaje się również libusb nie na ostatnim OSX.).

Interfejs API HID to mała biblioteka: jedna .h, jedna (na platformę) .c.

Mój kod wygląda następująco:

unsigned short inklingVendorId = 0x056a, inklingProductId = 0x0221; 
    if (hid_init() == FAIL) return; 
    handle = hid_open(inklingVendorId, inklingProductId, nullptr); 

W Windows hid_open zawiedzie. Pojedyncze stepping ujawnia punkt fail-here:

// path = "\\\\?\\hid#vid_056a&pid_0221&mi_00&col01#8&1ea90857&0&0000#" 
//  "{4d1e55b2-f16f-11cf-88cb-001111000030}" 
// 
static HANDLE open_device(const char *path, BOOL enumerate) 
{ 
    HANDLE handle; 
    DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ); 
    DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; 

    // enumerate = 0 
    handle = CreateFileA(path, 
     desired_access, 
     share_mode, 
     NULL, 
     OPEN_EXISTING, 
     FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/ 
     0); 

    int err = GetLastError(); // 5 i.e. ERROR_ACCESS_DENIED 

    return handle; // returns 0xffffffff i.e. INVALID_HANDLE 
} 

Teraz autor HIDAPI mówi „HIDAPI nie będzie działać z klawiatur i myszy w systemie Windows Windows jako środek bezpieczeństwa nie zezwala na otwarcie myszki i klawiatury. Hids . " (here)

I jeśli wyliczyć urządzeń HID:

struct hid_device_info *devs, *cur_dev; 

    devs = hid_enumerate(inklingVendorId, inklingProductId); 
    cur_dev = devs; 
    while (cur_dev) { 
     DBG2("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); 
     DBG2(""); 
     DBG2(" Manufacturer: %ls", cur_dev->manufacturer_string); 
     DBG2(" Product:  %ls", cur_dev->product_string); 
     DBG2(" Release:  %hx", cur_dev->release_number); 
     DBG2(" Interface: %d", cur_dev->interface_number); 
     DBG2(" Usage Page: %d", cur_dev->usage_page); 
     DBG2(" Usage:  %d", cur_dev->usage); 
     DBG2(""); 
     cur_dev = cur_dev->next; 
    } 
    hid_free_enumeration(devs); 

... I nie dostać jeden, ale dwa wpisy:

Device Found 
    type: 056a 0221 
    path: \\?\hid#vid_056a&pid_0221&mi_00&col01#8&1ea90857&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} 
    serial_number: 2B0400001C90C22A0002DD07FE8B022A 

    Manufacturer: Wacom, Inc. 
    Product:  MSC Device 
    Release:  1256 
    Interface: 0 
    Usage Page: 1 
    Usage:  2 

Device Found 
    type: 056a 0221 
    path: \\?\hid#vid_056a&pid_0221&mi_00&col02#8&1ea90857&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030} 
    serial_number: 2B0400001C90C22A0002DD07FE8B022A 

    Manufacturer: Wacom, Inc. 
    Product:  MSC Device 
    Release:  1256 
    Interface: 0 
    Usage Page: 13 
    Usage:  2 

(Uwaga: OSX informuje tylko drugi wpis On! OSX nie ma problemu)

Porównując path:
ścieżka: \ \ ukrył # vid_056a & pid_0221 & mi_00 & col01 # 8 & 1ea90857 # ...
ścieżka: \ \ ukrył # vid_056a & pid_0221 & mi_00 & col02 # 8 & 1ea90857 # ...

Zgodnie z http://www.usb.org/developers/hidpage/Hut1_12v2.pdf,

UsagePage/Usage = 1/2 = {Ogólne ustawienia pulpitu}/{Mysz}.
UsagePage/Usage = 13/2 = {Digitizers}/{Pen}.

(EDYCJA: Czasami pierwsza ścieżka to 1/2, a druga to 13/2, innym razem jest zamieniona).

A HIDAPI to only taking the first one it finds.

Wygląda więc na to, że powinno to być rozwiązanie. Inkling wystawiał 2 "urządzenia", a hidapi brało niewłaściwą (mysz), a Windows nie pozwala na dostęp do myszy lub urządzeń klawiatury.

Koryguję kod ...

while (cur_dev) { 
    if (cur_dev->vendor_id == vendor_id && 
     cur_dev->product_id == product_id && 
     cur_dev->usage_page == 13) 
    { 

... aby uzyskać prawidłowy wpis, powinien działać poprawnie?

Nie, CreateFileA prostu podnosi inny błąd:

usage_page == 1 => kod błędu 5 (ERROR_ACCESS_DENIED)
usage_page == 13 => błędu kodu 32 (ERROR_SHARING_VIOLATION)

ble. To jest dość denerwujące. Wydaje mi się, że jestem w ślepym zaułku!

Próbowałem manipulować przy użyciu parametrów CreateFileA, np. zastępując GENERIC_READ | GENERIC_WRITE z STANDARD_RIGHTS_READ | STANDARD_RIGHTS_WRITE - teraz szczęśliwie tworzy uchwyt. Ale kolejne hid_read -s nie zbierają żadnych danych.

Googling, https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/af869f90-7bda-483d-ba2d-51680073fe9f/createfile-returns-invalid-handle-while-trying-to-access-hid-device-on-windows-8-desktop-app?forum=wdk wydaje się zawierać kilka sugerowanych obejścia:

both toaster and firefly can work in the HID stack. toaster shows how to address the filter through a raw PDO, firefly shows how to access it with WMI. From a C perspective, I think the raw PDO is much simpler to code to, WMI is a bit nasty and complicated.

firefly
toaster

Autor zaleca coś w tosterze, ale jest to duży kodzie i nie wiem mieć doświadczenie w programowaniu sterowników Windows.

Wygląda na to, że będę musiała przekopać się przez bardzo nieznane terytorium, aby coś działało, więc zanim zacznę, proszę. Jeśli nikt nie odpowie, a ja to wymyślę, odpowiem na własne pytanie.

Jedyna rzecz, o której mogę pomyśleć, to to, że inny proces już angażuje tę ścieżkę. Może jeśli mogę zakończyć ten proces, CreateFileA może się powieść? Roem's libusb obejmuje odłączanie sterownika jądra: https://github.com/roelj/inklingreader/blob/master/src/usb/online-mode.c#L98

PS Gdzieś czytałem, że jeśli inny proces już otworzył to urządzenie, nasze otwarte musi pasować do uprawnień z poprzedniego otwierania. Przeczytałem również, że Windows automatycznie otwiera wszystkie urządzenia HID po wykryciu.

Find out which process has an exclusive lock on a USB device handle

PPS może jeden pomysł jest, aby spróbować alternatywę HID lib What is the best usb library to communicate with usb HID devices on Windows?

PPP może trzeba uruchomić mój kod jako administrator. Ale to nie jest dobre rozwiązanie.

+3

Windows ma wbudowaną wbudowaną digitalizator, z pewnością walczysz z jego użyciem na tablecie. Dostępne gałki powodują wyłączenie usługi (należy ją nazwać "usługą wprowadzania danych na komputerze typu Tablet" lub "Dotykową klawiaturą i usługą pisma ręcznego" lub "TabletServiceWacom") lub wyłączaniem "Urządzenia Wacom Virtual HID" w Menedżerze urządzeń. Korzystanie z nieprzetworzonych danych wejściowych byłoby chyba lepszym, lepszym podejściem. –

Odpowiedz

1

Widziałem podobne zachowanie. Problem ERROR_SHARING_VIOLATION zaczął występować po uaktualnieniu do edycji Windows 10 Anniversary. Problem występuje tylko w przypadku urządzeń USB HID podłączonych podczas uruchamiania systemu Windows. Jeśli odłączysz i włączysz urządzenie USB po uruchomieniu systemu Windows, to CreateFile powiodło się. Nie znalazłem jeszcze podstawowej przyczyny ani rozwiązania.

Powiązane problemy