Interface USB HID et gcc sous xp? lundi 28 juillet 2008 16:47:13 |
Membre depuis : 15 ans Messages: 4 |
#include <iostream> #include <windows.h> #include "mcHID.h" using namespace std; int main() { HIDBufferOut BufferOut; char inputChr; cout << "Chargement de mcHID.dll ... "; if (LoadHID()){ cout << "erreur"; return 0; } else cout << "ok"; // first element is the report ID BufferOut[0] = 0; BufferOut[1] = 1; BufferOut[2] = 10; BufferOut[3] = 25; if (WriteEx(VENDOR_ID, PRODUCT_ID, BufferOut)) cout << "write erreur"; else cout << "write ok"; } // UnloadHID(); return 0; }
Re: Interface USB HID et gcc sous xp? lundi 28 juillet 2008 21:41:57 |
Administrateur Membre depuis : 18 ans Messages: 640 |
Re: Interface USB HID et gcc sous xp? mardi 29 juillet 2008 08:09:31 |
Membre depuis : 15 ans Messages: 4 |
Re: Interface USB HID et gcc sous xp? mardi 29 juillet 2008 11:58:38 |
Administrateur Membre depuis : 18 ans Messages: 640 |
Re: Interface USB HID et gcc sous xp? vendredi 12 septembre 2008 09:56:34 |
Membre depuis : 15 ans Messages: 4 |
#include <windows.h> extern "C" {//Pour une compilation C++ #include <setupapi.h> #include "hidsdi.h" #include "hidpi.h" } int VID = 1240; int PID = 5; int bufLength = 65; //64 + 1 octet de reportId HANDLE usbHandle = INVALID_HANDLE_VALUE; HANDLE getUsbHandle(void) { GUID hidGuid; /* GUID for HID driver */ HDEVINFO deviceInfoList; SP_DEVICE_INTERFACE_DATA deviceInfo; SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL; DWORD size; int usbDeviceIndex; int openFlag = FILE_FLAG_OVERLAPPED; //ReadFile et WriteFile non bloquant //FILE_ATTRIBUTE_NORMAL -> ReadFile et WriteFile bloquant HIDD_ATTRIBUTES deviceAttributes; //Returns the device interface GUID for HIDClass devices HidD_GetHidGuid(&hidGuid); //Returns a handle to a device information set that contains requested device information elements for a local machine deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); deviceInfo.cbSize = sizeof(deviceInfo); for(usbDeviceIndex = 0 ;; usbDeviceIndex++){ if(usbHandle != INVALID_HANDLE_VALUE){ CloseHandle(usbHandle); usbHandle = INVALID_HANDLE_VALUE; } //Enumerates the device interfaces that are contained in a device information set if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, usbDeviceIndex, &deviceInfo)) break; //* no more entries */ //First do a dummy call just to determine the actual size required //Returns details about a device interface SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL); if(deviceDetails != NULL) free(deviceDetails); deviceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*)malloc(size); deviceDetails->cbSize = sizeof(*deviceDetails); //This call is for real: //Returns details about a device interface SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL); hidPathQstr = QString::fromWCharArray(deviceDetails->DevicePath); //Attempt opening for R/W -- we don't care about devices which can't be accessed //Creates or opens a file or I/O device usbHandle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL); if(usbHandle == INVALID_HANDLE_VALUE){ errorCode = USBCOM_CNX_ERROR_FAILED_OPENING; DBG(<< "Open USB port (failed opening) code : " << GetLastError()); //La fonction in GetLastError(void) permet d'obtenir le code d'erreur exacte //errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore continue; } deviceAttributes.Size = sizeof(deviceAttributes); HidD_GetAttributes(usbHandle, &deviceAttributes); if(deviceAttributes.VendorID != VID || deviceAttributes.ProductID != PID) continue; /* ignore this device */ errorCode = USBCOM_NO_ERROR; break; /* we have found the device we are looking for! */ } vendorNameQstr = QString(); productNameQstr = QString(); if (errorCode == USBCOM_NO_ERROR){ //usb détecté, on cherche le nom de vendor & product int bufLength = 512; char buffer[bufLength]; //Returns a top-level collection's embedded string that identifies the manufacturer if (HidD_GetManufacturerString(usbHandle, buffer, sizeof(buffer))){ //buffer l'identifiant du vendor } //Returns a top-level collection's embedded string that identifies the product if (HidD_GetProductString(usbHandle, buffer, sizeof(buffer))){ //buffer l'identifiant du product } } //Deletes a device information set and frees all associated memory SetupDiDestroyDeviceInfoList(deviceInfoList); if(deviceDetails != NULL) free(deviceDetails); return usbHandle; } bool waitingOnReadBl = false; int readTimeout = 200; //en ms bool read(char *buffer) { if (usbHandle == INVALID_HANDLE_VALUE || waitingOnReadBl) return false; char reportID = 0; DWORD bufLengthToRead = bufLength; DWORD bufLengthRead = 0; buffer[0] = reportID; bool readBl = false; //Ce controle permet d'éviter qu'une procédure de lecture ne soit lancée avant que la précédante ne soit terminée if(!ReadFile(usbHandle, buffer, bufLengthToRead, &bufLengthRead, &overlapped)){ //Erreur de lecture? if (GetLastError() != ERROR_IO_PENDING){ //Le ReadFile n'a pas abouti et la procédure de lecture n'est pas en cours, il y a eu une erreur de liaison //Traiter l'erreur de lecture DBG(<< "Erreur de lecture (lecture directe) code : " << GetLastError()); readBl = false; } else { //La procédure de lecture est en cours, attendre qu'elle se termine waitingOnReadBl = true; } } else { // read completed immediately //Lecture des data dans buffer sur une longueur de bufLengthRead readBl = true; } if (waitingOnReadBl){ // Si la réponse du readFile n'a pas été immédiate // on l'attend pendant une durée max de readTimeout DWORD dwRes = WaitForSingleObject(overlapped.hEvent, readTimeout); switch (dwRes){ // Read completed. case WAIT_OBJECT_0: if (!GetOverlappedResult(usbHandle, &overlapped, &bufLengthRead, FALSE)){ // Error in communications; report it. DBG(<< "Erreur de lecture (lecture différée) code : " << GetLastError()); readBl = false; } else { // Read completed successfully. // Lecture des data dans buffer sur une longueur de bufLengthRead // Reset flag so that another opertion can be issued. readBl = true; } break; case WAIT_TIMEOUT: // Operation isn't complete yet. waitingOnReadBl flag isn't // changed since I'll loop back around, and I don't want // to issue another read until the first one finishes. readBl = false; break; default: // Error in the WaitForSingleObject; abort. // This indicates a problem with the OVERLAPPED structure's // event handle. DBG(<< "Erreur de lecture (OVERLAPPED structure's error) code : " << GetLastError()); readBl = false; break; } } waitingOnReadBl = false; return readBl; } bool write(char *buffer) { if (usbHandle == INVALID_HANDLE_VALUE) return false; DWORD bufLengthToWrite = bufLength; DWORD bytesWritten; DWORD dwRes; bool writeBl; // Issue write. if (!WriteFile(usbHandle, buffer, bufLengthToWrite, &bytesWritten, &overlapped)) { if (GetLastError() != ERROR_IO_PENDING){ //WriteFile failed, but isn't delayed. Report error and abort. DBG(<< "Erreur d'écriture (écriture immédiate) code : " << GetLastError()); writeBl = FALSE; } else { //On attend la fin de l'opération d'écriture. dwRes = WaitForSingleObject(overlapped.hEvent, INFINITE); switch (dwRes){ // OVERLAPPED structure's event has been signaled. case WAIT_OBJECT_0: if (!GetOverlappedResult(usbHandle, &overlapped, &bytesWritten, FALSE)){ DBG(<< "Erreur d'écriture (écriture différée) code : " << GetLastError()); writeBl = FALSE; } else // Write operation completed successfully. writeBl = TRUE; break; default: // An error has occurred in WaitForSingleObject. // This usually indicates a problem with the // OVERLAPPED structure's event handle. DBG(<< "Erreur d'écriture (OVERLAPPED structure's error) code : " << GetLastError()); writeBl = FALSE; break; } } } else { // WriteFile completed immediately. writeBl = TRUE; } return writeBl; }