Author Topic: reading IN endpoint gails  (Read 15263 times)

embeddedaebi

  • Member
  • ***
  • Posts: 6
reading IN endpoint gails
« on: July 03, 2013, 07:12:09 am »
Hello all.
I am working on a project in which I need to send around 4kb data every other second to PC. I am able to send and receive reports through the control end point but not through interrupt endpoint. When I use readfile, it is failing with error code 5 (access denied). Please help me how it can be sorted.
The firmware seems to be sending the report successfully as the LEDs get on when the hardware clears the txcmpl(transmission complete) flag on interrupt endpoint.
Here is the code..

#include <windows.h>
#include <setupapi.h>
#include <iostream.h>

struct ReportOut
{
   unsigned int id;
    char ch[4];
}report,*preport;

typedef struct _HIDD_ATTRIBUTES
{
    ULONG   Size;
    USHORT  VendorID;
    USHORT  ProductID;
    USHORT  VersionNumber;
} HIDD_ATTRIBUTES,*PHIDD_ATTRIBUTES;

int main()
{   
   int NumOfReportRequest,UserChoice,VID=0x03EB,PID=0x2001,MemberIndex=0,i,a=0;
    char InputReportBuffer[256];
   bool MyDeviceDetected,LastDevice = FALSE;
   DWORD NumberOfBytesRead=32;
   DWORD BytesWritten=0;

   for(i=0;i<256;i++)
      InputReportBuffer=0;

   HIDD_ATTRIBUTES Attributes;
   SP_DEVICE_INTERFACE_DATA devInfoData;
   PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
   HANDLE DeviceHandle = NULL;
   HANDLE hEventObject;
   HANDLE hDevInfo;
   GUID HidGuid;
   ULONG Length = 0;   
   ULONG Required;
   HMODULE hHID = 0;
   LONG Result;

   hHID = LoadLibrary("hid.dll");
   if(!hHID)
   {
      cout<<"Can't find hid.dll";
      return 0;
   }
   else
      cout<<"\n HID loaded successfully \n";

   typedef void (__stdcall*GETHIDGUID) (OUT LPGUID HidGuid);
   typedef BOOLEAN (__stdcall*GETATTRIBUTES)(IN HANDLE HidDeviceObject,OUT PHIDD_ATTRIBUTES Attributes);
   typedef BOOLEAN (__stdcall*SETNUMINPUTBUFFERS)(IN  HANDLE HidDeviceObject,OUT ULONG  NumberBuffers);
   typedef BOOLEAN (__stdcall*GETREPORT) (IN  HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
   typedef BOOLEAN (__stdcall*SETREPORT) (IN  HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength);
   
   GETHIDGUID HidD_GetHidGuid=0;
   GETATTRIBUTES HidD_GetAttributes=0;
   SETNUMINPUTBUFFERS HidD_SetNumInputBuffers=0;
   GETREPORT HidD_GetInputReport=0;
   SETREPORT HidD_SetOutputReport=0;
      
   HidD_GetHidGuid=(GETHIDGUID)GetProcAddress(hHID,"HidD_GetHidGuid");
   HidD_GetAttributes=(GETATTRIBUTES)GetProcAddress(hHID,"HidD_GetAttributes");
   HidD_SetNumInputBuffers=(SETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_SetNumInputBuffers");
   HidD_GetInputReport=(GETREPORT)GetProcAddress(hHID,"HidD_GetInputReport");
   HidD_SetOutputReport=(SETREPORT)GetProcAddress(hHID,"HidD_SetOutputReport");
   
   if((HidD_GetHidGuid==NULL)||(HidD_GetAttributes==NULL)||(HidD_GetInputReport==NULL)||(HidD_SetOutputReport==NULL)||(HidD_SetNumInputBuffers==NULL))
   {
      cout<<"\n....Some procedure of HID.dll is not loaded successfully.... \n";
      return -1;      
   }

   HMODULE hSAPI=0;
   hSAPI = LoadLibrary("setupapi.dll");
   if(!hSAPI)
   {
      cout<<"\n....Can't find setupapi.dll....\n";
      return 0;
   }
   else
      cout<<"\n SETUPAPI loaded successfully \n";

    typedef HDEVINFO (WINAPI* SETUPDIGETCLASSDEVS) (CONST GUID*,PCSTR,HWND,DWORD);
   typedef BOOL (WINAPI* SETUPDIENUMDEVICEINTERFACES) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,DWORD,PSP_DEVICE_INTERFACE_DATA);
   typedef BOOL (WINAPI* SETUPDIGETDEVICEINTERFACEDETAIL) (HDEVINFO,PSP_DEVICE_INTERFACE_DATA,PSP_DEVICE_INTERFACE_DETAIL_DATA_A,DWORD,PDWORD,PSP_DEVINFO_DATA);
   typedef BOOL (WINAPI* SETUPDIDESTROYDEVICEINFOLIST) (HDEVINFO);   
   typedef BOOL (WINAPI* SETUPDISETDEVICEREGISTRYPROPERTY) (HDEVINFO,PSP_DEVINFO_DATA,DWORD,CONST BYTE *,DWORD);
   typedef BOOL (WINAPI* SETUPDICREATEDEVICEINTERFACE) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,PCSTR,DWORD,PSP_DEVICE_INTERFACE_DATA);
   
   SETUPDIGETCLASSDEVS SetupDiGetClassDevsA=0;
   SETUPDIENUMDEVICEINTERFACES SetupDiEnumDeviceInterfaces=0;
   SETUPDIGETDEVICEINTERFACEDETAIL SetupDiGetDeviceInterfaceDetailA=0;
   SETUPDIDESTROYDEVICEINFOLIST SetupDiDestroyDeviceInfoList=0;

   SetupDiGetClassDevsA=(SETUPDIGETCLASSDEVS) GetProcAddress(hSAPI,"SetupDiGetClassDevsA");
   SetupDiEnumDeviceInterfaces=(SETUPDIENUMDEVICEINTERFACES) GetProcAddress(hSAPI,"SetupDiEnumDeviceInterfaces");
   SetupDiGetDeviceInterfaceDetailA=(SETUPDIGETDEVICEINTERFACEDETAIL) GetProcAddress(hSAPI,"SetupDiGetDeviceInterfaceDetailA");
   SetupDiDestroyDeviceInfoList=(SETUPDIDESTROYDEVICEINFOLIST) GetProcAddress(hSAPI,"SetupDiDestroyDeviceInfoList");

   if((SetupDiGetClassDevsA==NULL)||(SetupDiEnumDeviceInterfaces==NULL)||(SetupDiGetDeviceInterfaceDetailA==NULL)||(SetupDiDestroyDeviceInfoList==NULL))
   {
      cout<<"\n....Some procedure of HID.dll is not loaded successfully.... \n";
      return -1;      
   }
   
   HidD_GetHidGuid(&HidGuid);                        
   hDevInfo = SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
   devInfoData.cbSize = sizeof(devInfoData);

   report.id = 0;
   report.ch[0] = 'a';
   report.ch[1] = 'e';
   report.ch[2] = 'b;
   report.ch[3] = 'i';
   preport = &report;
   do
   {   
      Result = SetupDiEnumDeviceInterfaces(hDevInfo,0,&HidGuid,MemberIndex,&devInfoData);
      if (Result != 0)                                                    
      {         
         Result = SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,NULL,0,&Length,NULL);
         detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
         detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
         Result = SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,detailData,Length,&Required,NULL);
         DeviceHandle=CreateFile(detailData->DevicePath,0,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
         Attributes.Size = sizeof(Attributes);
         Result = HidD_GetAttributes(DeviceHandle,&Attributes);
         MyDeviceDetected = FALSE;
         if (Attributes.VendorID == VID)
         {
            if (Attributes.ProductID == PID)
            {
               MyDeviceDetected = TRUE;
               cout<<"\n Found MY_USB_DEVICE \n";
               hEventObject = CreateEvent(NULL,TRUE,TRUE,"");
            }
            else
               CloseHandle(DeviceHandle);
         }
         else
            CloseHandle(DeviceHandle);

         //free(detailData);
      }
      else
         LastDevice=TRUE;
      
      MemberIndex++;
   }while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
   
   //SetupDiDestroyDeviceInfoList(hDevInfo);
   
   if (MyDeviceDetected == FALSE)
   {
      cout<<"....\n Can't find device .... \n";
      return -1;
   }
   
   if (MyDeviceDetected)
   {
      cout<<"\n Press 1 to start the process \n ";
      cin>>UserChoice;
      if(UserChoice==1)
      {
         if(DeviceHandle == INVALID_HANDLE_VALUE)
         {
            cout<<"Invalid Handle\n";
            return 1;
         }
         if(!(ReadFile(DeviceHandle,InputReportBuffer, NumberOfBytesRead, &BytesWritten, NULL)))//&HIDOverlapped)))
         {
            cout<<"..Readfile Failiure..\n"<<GetLastError();         // THIS EXECUTES and error code is 5.
         }
         else
         {
            i=0;
            while(BytesWritten--)
               cout<<(char *)InputReportBuffer[i++];
         }
   
      else
         cout<<"\n Bye \n";
   }
   else
      cout<<"\n Device not found \n";
         
   return 0;
}


Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: reading IN endpoint gails
« Reply #1 on: July 03, 2013, 03:02:10 pm »
Windows 2000 and later have exclusive ReadFile/WriteFile access to HIDs whose descriptors define the device as a system keyboard or mouse. If you don't know how to change that, post the descriptors.

vadimcher

  • Member
  • ***
  • Posts: 1
Re: reading IN endpoint gails
« Reply #2 on: July 29, 2013, 07:31:28 am »
Windows 2000 and later have exclusive ReadFile/WriteFile access to HIDs whose descriptors define the device as a system keyboard or mouse. If you don't know how to change that, post the descriptors.

A similar problem arose in me, too. How to cope with the prohibition of direct access to input-output byte sequence in the system USB keyboard?

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: reading IN endpoint gails
« Reply #3 on: July 29, 2013, 10:35:51 am »
Use the Raw Input API or DirectX's DirectInput to read keyboards.