HID device programming - does it work with C ++ (SETUPAPI.dll and HID.dll)

I am new to @Stackoverflow, however this was the closest thing I have as a Bible (except for Ritchie C) especially these days of final projects for most of my topics. In any case, my question is about the libraries necessary for an application that communicates with a HID device and the ability to do this using C ++.

I do not need help with the firmware, my device is already working as I expect. However, my only experience in programming HID devices is with C (Windows - VS2010), and now I am in the final project for the Compilers class, in which we send information to a device with a matrix screen to display "material". My partner, however, must do something in C ++ , which can save us a lot of time (something nice, given its two-day period).

The whole point of this is to ask if it can be done in the same way as I already have in C (with its explicit settings) and some parts of the code in C ++ and are still compatible with SetupApi.DLL and HID. Dll

Any advice, pointers or instructions are deeply appreciated. I am including the code that I have used so far.

Sorry all the comments on the Spanish and promiscuous level, I could

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
#include <SETUPAPI.H>

//----------------------------------------------

#define RICH_VENDOR_ID      0x0000
#define RICH_USBHID_GENIO_ID    0x2012

#define INPUT_REPORT_SIZE   5
#define OUTPUT_REPORT_SIZE  2
//----------------------------------------------
char c=0x0;
DWORD BytesRead = 0;
DWORD BytesWritten = 0;
unsigned char reporteEntrada[INPUT_REPORT_SIZE+1];
unsigned char reporteSalida[OUTPUT_REPORT_SIZE+1];
int status = 0;
static unsigned char dato = 0x01;
static unsigned char numLED = 1;
unsigned char palabra[192]={0};
int desplegar,valorled;
desplegar=0;
valorled=0;
unsigned char temporal;
//unsigned char ch;
//unsigned int index;
typedef struct _HIDD_ATTRIBUTES {
    ULONG   Size; // = sizeof (struct _HIDD_ATTRIBUTES)
    USHORT  VendorID;
    USHORT  ProductID;
    USHORT  VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;

typedef VOID    (__stdcall *PHidD_GetProductString)(HANDLE, PVOID, ULONG);
typedef VOID    (__stdcall *PHidD_GetHidGuid)(LPGUID);
typedef BOOLEAN (__stdcall *PHidD_GetAttributes)(HANDLE, PHIDD_ATTRIBUTES);
typedef BOOLEAN (__stdcall *PHidD_SetFeature)(HANDLE, PVOID, ULONG);
typedef BOOLEAN (__stdcall *PHidD_GetFeature)(HANDLE, PVOID, ULONG);

//----------------------------------------------

HINSTANCE                       hHID                    = NULL;
PHidD_GetProductString          HidD_GetProductString   = NULL;
PHidD_GetHidGuid                HidD_GetHidGuid         = NULL;
PHidD_GetAttributes             HidD_GetAttributes      = NULL;
PHidD_SetFeature                HidD_SetFeature         = NULL;
PHidD_GetFeature                HidD_GetFeature         = NULL;
HANDLE                          DeviceHandle            = INVALID_HANDLE_VALUE;

unsigned int moreHIDDevices=TRUE;
unsigned int HIDDeviceFound=FALSE;

unsigned int terminaAbruptaEInstantaneamenteElPrograma=0;

void Load_HID_Library (void) {
    hHID = LoadLibrary("HID.DLL");
    if (!hHID) {
        printf("Failed to load HID.DLL\n");
        return;
    }

    HidD_GetProductString = (PHidD_GetProductString) GetProcAddress(hHID, "HidD_GetProductString");
    HidD_GetHidGuid       = (PHidD_GetHidGuid) GetProcAddress(hHID, "HidD_GetHidGuid");
    HidD_GetAttributes    = (PHidD_GetAttributes) GetProcAddress(hHID, "HidD_GetAttributes");
    HidD_SetFeature       = (PHidD_SetFeature) GetProcAddress(hHID, "HidD_SetFeature");
    HidD_GetFeature       = (PHidD_GetFeature) GetProcAddress(hHID, "HidD_GetFeature");

    if (   !HidD_GetProductString
        || !HidD_GetAttributes
        || !HidD_GetHidGuid
        || !HidD_SetFeature
        || !HidD_GetFeature ) {
        printf("Couldn't find one or more HID entry points\n");
        return;
    }
}

int Open_Device(void) {
    HDEVINFO                            DeviceInfoSet;
    GUID                                InterfaceClassGuid;
    SP_DEVICE_INTERFACE_DATA            DeviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA    pDeviceInterfaceDetailData;
    HIDD_ATTRIBUTES                     Attributes;  
    DWORD                               Result;
    DWORD                               MemberIndex = 0;
    DWORD                               Required;

    //Validar si se "cargó" la biblioteca (DLL)
    if (!hHID)
        return (0);

    //Obtener el Globally Unique Identifier (GUID) para dispositivos HID
    HidD_GetHidGuid (&InterfaceClassGuid);
    //Sacarle a Windows la información sobre todos los dispositivos HID instalados y activos en el sistema
    // ... almacenar esta información en una estructura de datos de tipo HDEVINFO
    DeviceInfoSet = SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
    if (DeviceInfoSet == INVALID_HANDLE_VALUE)
        return (0);

    //Obtener la interfaz de comunicación con cada uno de los dispositivos para preguntarles información específica
    DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    while (!HIDDeviceFound) {
        // ... utilizando la variable MemberIndex ir preguntando dispositivo por dispositivo ...
        moreHIDDevices = SetupDiEnumDeviceInterfaces (DeviceInfoSet, NULL, &InterfaceClassGuid,
                                                                        MemberIndex,&DeviceInterfaceData);
        if (!moreHIDDevices) {
            // ... si llegamos al fin de la lista y no encontramos al dispositivo ==> terminar y marcar error
            SetupDiDestroyDeviceInfoList(DeviceInfoSet);    
            return (0); //No more devices found
        } else {
            //Necesitamos preguntar, a través de la interfaz, el PATH del dispositivo, para eso ...
            // ... primero vamos a ver cuántos caracteres se requieren (Required)
            Result = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet,&DeviceInterfaceData,NULL,0,&Required,NULL);
            pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Required);
            if (pDeviceInterfaceDetailData == NULL) {
                printf("Error en SetupDiGetDeviceInterfaceDetail\n");
                return (0);
            }
            //Ahora si, ya que el "buffer" fue preparado (pDeviceInterfaceDetailData{DevicePath}), vamos a preguntar PATH
            pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            Result = SetupDiGetDeviceInterfaceDetail (DeviceInfoSet,&DeviceInterfaceData,pDeviceInterfaceDetailData,
                                                                                                    Required,NULL,NULL);
            if (!Result) {
                printf("Error en SetupDiGetDeviceInterfaceDetail\n");
                free(pDeviceInterfaceDetailData);
                return(0);
            }
            //Para este momento ya sabemos el PATH del dispositivo, ahora hay que preguntarle ...
            // ... su VID y PID, para ver si es con quien nos interesa comunicarnos
            printf("Found? ==> ");
            printf("Device: %s\n",pDeviceInterfaceDetailData->DevicePath);

            //Obtener un "handle" al dispositivo
            DeviceHandle = CreateFile (pDeviceInterfaceDetailData->DevicePath,
                                    GENERIC_READ|GENERIC_WRITE,
                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                                    (LPSECURITY_ATTRIBUTES)NULL,
                                    OPEN_EXISTING,
                                    0,
                                    NULL);

            if (DeviceHandle == INVALID_HANDLE_VALUE) {
                printf("¡¡¡Error en el CreateFile!!!\n");
            } else {
                //Preguntar por los atributos del dispositivo
                Attributes.Size = sizeof(Attributes);
                Result = HidD_GetAttributes (DeviceHandle,&Attributes);
                if (!Result) {
                    printf("Error en HIdD_GetAttributes\n");
                    CloseHandle(DeviceHandle);
                    free(pDeviceInterfaceDetailData);
                    return(0);
                }
                //Analizar los atributos del dispositivo para verificar el VID y PID
                printf("MemberIndex=%d,VID=%04x,PID=%04x\n",MemberIndex,Attributes.VendorID,Attributes.ProductID);
                if ((Attributes.VendorID == RICH_VENDOR_ID) && (Attributes.ProductID == RICH_USBHID_GENIO_ID)) {
                    printf("USB/HID GenIO ==> ");
                    printf("Device: %s\n",pDeviceInterfaceDetailData->DevicePath);
                    HIDDeviceFound=TRUE;
                } else
                    CloseHandle(DeviceHandle);    

            }
            MemberIndex++;
            free(pDeviceInterfaceDetailData);
            if (HIDDeviceFound) {
                printf("Dispositivo HID solicitado ... ¡¡¡localizado!!!, presione <ENTER>\n");
                getchar();
            }
        }
    }
    return(1);
}

void Close_Device (void) {
    if (DeviceHandle != NULL) {
        CloseHandle(DeviceHandle);
        DeviceHandle = NULL;
    }
}

int chToIndex(unsigned char ch){
    if((ch>='0')&&(ch<='9')){
        return ch-48;
    }else if((ch>='A')&&(ch<='Z')){
        return ch-55;
    }else if((ch>='a')&&(ch<='z')){
        return ch-61;
    }else{
        switch (ch){
        case '*': return 62;
        //  break;
        case '+': return 63;
        //  break;
        case '-': return 64;
            //break;
        case '/': return 65;
            //break;
        case '=': return 66;
        //  break;
        case '>': return 67;
        //  break;
        case '<': return 68;
        //  break;
        case '!': return 69;
        //  break;
        case '.': return 70;
        //  break;
        case '&': return 71;
        //  break;
        case '^': return 72;
        //  break;
        case '(': return 73;
        //  break;
        case ')': return 74;
        //  break;
        case '[': return 75;
        //  break;
        case ']': return 76;
        //  break;
        case ',': return 77;
        //  break;
        case ';': return 78;
        //  break;
        case ':': return 79;
        //  break;
        case 0x20: return 80;
        default: return 81;
        //  break;
        }
    }


}
int Touch_Device (void) {
    int z;
    int index;
    int col,lin;
    unsigned char ch;

    if (DeviceHandle == NULL)   //Validar que haya comunicacion con el dispositivo
        return 0;

        if(c != '27' )
        {
            printf("Selecciona accion:\n1) Limpiar Pantalla\n2) Imprimir todos caracteres\n3) Escribir caracter\n4) Escribir string\n5) Salir\n");
            desplegar=getch();
            desplegar=getch();
            if((desplegar=='5')||(desplegar==(char)'27')){
                terminaAbruptaEInstantaneamenteElPrograma=1;
            }
            else if(desplegar=='4'){
                lin=0;
                col=0;
                index=0;
                printf("Escribe texto (termina con Enter):\n");
                scanf("%s",palabra);
                while(palabra[index]!='\0'){
                    z++;
                }
                printf("Longitud de palabra: %d",z);
                while((palabra[index]!='\0')){
                    if((palabra[index]==NULL)&&(palabra[index+1]!=NULL))
                        palabra[index]=0x20;
                    reporteSalida[0]=0x00;
                    reporteSalida[1]=0x04;
                    reporteSalida[2]=(char)chToIndex(palabra[index]);
                    reporteSalida[3]=(char)lin;
                    reporteSalida[4]=(char)col;
                    status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
                    if (!status)
                        printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
                    else
                        printf("Se enviaron %d bytes al dispositivo (posX=%d, posY=%d, dato=%d)\n",BytesWritten,reporteSalida[4],reporteSalida[3],reporteSalida[2]);
                    if(col>=23){
                        lin++;
                        col=0;
                    }
                    if(lin>=7){
                        lin=0;
                    }
                    col++;
                    index++;
                }
            }
            else if (desplegar=='3'){
                reporteSalida[0]=0x00;
                reporteSalida[1]=0x04;
                printf("Que caracter deseas desplegar: ");
                ch=getch();
                printf("\n");
                z=chToIndex(ch);
                reporteSalida[2]=(char)z;
                do{
                printf("En que renglon en y (0-7): ");
                scanf("%d",&desplegar);
                printf("\n");
                }while((desplegar<0)&&(desplegar>7));
                reporteSalida[3]=(char)desplegar;
                do{
                printf("En que columna en x (0-23): ");
                scanf("%d",&desplegar);
                printf("\n");
                }while((desplegar<0)&&(desplegar>23));
                reporteSalida[4]=(char)desplegar;
                printf("ReporteSalida: %02X %02X %02X %02X %02X \n",(unsigned char)reporteSalida[0],
                    (unsigned char)reporteSalida[1],
                    (unsigned char)reporteSalida[2],
                    (unsigned char)reporteSalida[3],
                    (unsigned char)reporteSalida[4]);

                status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
                if (!status)
                    printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
                else
                    printf("Se enviaron %d bytes al dispositivo (posX=%d, posY=%d, dato=%d)\n",BytesWritten,reporteSalida[4],reporteSalida[3],reporteSalida[2]);

            }
            else if (desplegar=='2'){
                lin=0;
                col=0;
                for (index=0;index<=80;index++){
                    reporteSalida[0]=0x00;
                    reporteSalida[1]=0x04;
                    reporteSalida[2]=(char)index;
                    reporteSalida[3]=(char)lin;
                    reporteSalida[4]=(char)col;
                    status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
                    if (!status)
                        printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
                    else
                        printf("Se enviaron %d bytes al dispositivo (posX=%d, posY=%d, dato=%d)\n",BytesWritten,reporteSalida[4],reporteSalida[3],reporteSalida[2]);
                    if(col>=23){
                        lin++;
                        col=0;
                    }
                    if(lin>=7){
                        lin=0;
                    }
                    col++;
                }
            }
            else if(desplegar=='1'){
                printf("Limpiando pantalla ...\n");
                reporteSalida[0]=0x00;
                reporteSalida[1]=0x03;
                reporteSalida[2]=0;
                status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
                if (!status)
                    printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
                else
                    printf("Escritos %d\n",BytesWritten);
            }
            else{
                Touch_Device();
            }
        }
    return status;
}

void main () {
    Load_HID_Library();
    if (Open_Device()) {
        printf("Vamos bien\n");
        while ((c=getch()!=27)
            &&(!terminaAbruptaEInstantaneamenteElPrograma)) {
                Touch_Device();
                Sleep(500);
        }

    } else {
        printf(">:(\n");
    }
    Close_Device();
}
+3
source share
2 answers

In general, you can compile any C code as C ++. Did you try to compile it as C ++ and did you get any errors?

The answer to your question is yes, you can use SETUPAPI.DLL and HID.DLL from C ++ in the same way as with C.

0
source

Change the source C file to C ++. If you use VS, it can be as simple as changing the file extension (.c → .cpp) and fixing some warning problems.


++ setupapi.dll( C), API , .

( )

#ifdef __cplusplus
extern "C" {
#endif

int declaration_of_c_function(...);

#ifdef __cplusplus
}
#endif

extern "C" - , ++ C/++.

, , ++.

0

All Articles