Author Topic: Error while reading and writing the data to USB keyboard.  (Read 29903 times)

jain1.anuj

  • Member
  • ***
  • Posts: 28
Error while reading and writing the data to USB keyboard.
« on: February 09, 2012, 11:36:59 pm »
hello everyone,

i had a device that work as a usb keyboard. it has a ultra sonic proximity sensor which detects the person. if the user goes out of the range it fires the keystrokes for locking the computer that are stored in it. when the user comes in it's range, it again fires the keystrokes for unlocking the computer.
when i try to get the handle to the device for reading/writing purpose, application is throwing me the error

"Attempted to read or write protected memory. this is often an indication that other memory is corrupted"

can anyone help me in resolving this error?

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Error while reading and writing the data to USB keyboard.
« Reply #1 on: February 10, 2012, 11:42:13 am »
Windows 2000 and later have exclusive read/write access via CreateFile for HIDs that are configured as a system keyboards or mice.

Use RawInput instead.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: Error while reading and writing the data to USB keyboard.
« Reply #2 on: February 12, 2012, 11:41:01 pm »
Thanks JAN for your reply. If i use RAWINPUT than i will not be able to write data to the device. I want to perform both read/write operations.

here is the code for creating handle to the device with GUID as:-
Code: [Select]
GUID_DEVINTERFACE_KEYBOARD = new Guid("884b96c3-56ef-11d1-bc8c-00a0c91405dd");
create file method as :-

Code: [Select]
deviceHandle = CreateFile(devicePathName[0], 0/*GENERIC_WRITE | GENERIC_READ*/ , FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero,
            OPEN_EXISTING, 0, IntPtr.Zero);


code for getting capabilities and HID Usage is as follows:-

Code: [Select]
Capabilities = GetDeviceCapabilities(deviceHandle);

                    MessageBox.Show("capabilities: " + Capabilities.ToString());

                    hidUsage = GetHidUsage(Capabilities);

                    MessageBox.Show("usage : " + hidUsage);

                   internal HIDP_CAPS GetDeviceCapabilities(SafeFileHandle hidHandle)
        {
            IntPtr preparsedData = new System.IntPtr();
            Int32 result = 0;
            Boolean success = false;
           
            try
            {
                success = HidD_GetPreparsedData(hidHandle, ref preparsedData);

                result = HidP_GetCaps(preparsedData, ref Capabilities);
                if ((result != 0))
                {
                    MessageBox.Show("");
                    MessageBox.Show("  Usage: " + Convert.ToString(Capabilities.Usage, 16));
                    MessageBox.Show("  Usage Page: " + Convert.ToString(Capabilities.UsagePage, 16));
                    MessageBox.Show("  Input Report Byte Length: " + Capabilities.InputReportByteLength);
                    MessageBox.Show("  Output Report Byte Length: " + Capabilities.OutputReportByteLength);
                    MessageBox.Show("  Feature Report Byte Length: " + Capabilities.FeatureReportByteLength);
                    MessageBox.Show("  Number of Link Collection Nodes: " + Capabilities.NumberLinkCollectionNodes);
                    MessageBox.Show("  Number of Input Button Caps: " + Capabilities.NumberInputButtonCaps);
                    MessageBox.Show("  Number of Input Value Caps: " + Capabilities.NumberInputValueCaps);
                    MessageBox.Show("  Number of Input Data Indices: " + Capabilities.NumberInputDataIndices);
                    MessageBox.Show("  Number of Output Button Caps: " + Capabilities.NumberOutputButtonCaps);
                    MessageBox.Show("  Number of Output Value Caps: " + Capabilities.NumberOutputValueCaps);
                    MessageBox.Show("  Number of Output Data Indices: " + Capabilities.NumberOutputDataIndices);
                    MessageBox.Show("  Number of Feature Button Caps: " + Capabilities.NumberFeatureButtonCaps);
                    MessageBox.Show("  Number of Feature Value Caps: " + Capabilities.NumberFeatureValueCaps);
                    MessageBox.Show("  Number of Feature Data Indices: " + Capabilities.NumberFeatureDataIndices);

                    Int32 vcSize = Capabilities.NumberInputValueCaps;
                    Byte[] valueCaps = new Byte[vcSize];

                    result = HidP_GetValueCaps(HidP_Input, valueCaps, ref vcSize, preparsedData);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace.ToString());
               
            }
            finally
            {
             

                if (preparsedData != IntPtr.Zero)
                {
                    success = HidD_FreePreparsedData(preparsedData);
                }
            }

            return Capabilities;
        }         

          internal String GetHidUsage(HIDP_CAPS MyCapabilities)
        {
            Int32 usage = 0;
            String usageDescription = "";

            try
            {
                MessageBox.Show("page : " + Capabilities.UsagePage.ToString());
                usage = MyCapabilities.UsagePage * 256 + MyCapabilities.Usage;

                MessageBox.Show("usage in method : " + usage.ToString());

                if (usage == Convert.ToInt32(0X102))
                {
                    usageDescription = "mouse";
                }

                if (usage == Convert.ToInt32(0X106))
                {
                    usageDescription = "keyboard";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            MessageBox.Show("description : " + usageDescription);
            return usageDescription;
           
        }         




code for read and write handle is as follows:-

Code: [Select]
readHandle = CreateFile(devicePathName[0],0 /*GENERIC_READ*/, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero);

                MessageBox.Show("read handle : " + readHandle.DangerousGetHandle().ToString());
                if (readHandle.IsInvalid)
                {
                    exclusiveAccess = true;
                }
                else
                {
                    writeHandle = CreateFile(devicePathName[0], GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

                    MessageBox.Show("write handle : " + writeHandle.DangerousGetHandle().ToString());

                    Boolean res = HidD_FlushQueue(deviceHandle);

                    MessageBox.Show("flush quese: " + res.ToString());


                }




« Last Edit: February 13, 2012, 01:21:14 am by jain1.anuj »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Error while reading and writing the data to USB keyboard.
« Reply #3 on: February 13, 2012, 09:53:55 am »
« Last Edit: June 27, 2015, 09:55:47 am by Jan Axelson »

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: Error while reading and writing the data to USB keyboard.
« Reply #4 on: February 13, 2012, 10:48:14 pm »
Thanks JAN

I followed your advice but it was not working with my device. As i told you that my device works as a USB KEYBOARD. So please help me in this regard.

I am getting the error that i had specified in my first post in the following code:-

Code: [Select]
Capabilities = GetDeviceCapabilities(deviceHandle);

           hidUsage = GetHidUsage(Capabilities);
         

 
           internal HIDP_CAPS GetDeviceCapabilities(SafeFileHandle hidHandle)
        {
            IntPtr preparsedData = new System.IntPtr();
            Int32 result = 0;
            Boolean success = false;
           
            try
            {
                success = HidD_GetPreparsedData(hidHandle, ref preparsedData);

                result = HidP_GetCaps(preparsedData, ref Capabilities);
                if ((result != 0))
                {
                    MessageBox.Show("");
                    MessageBox.Show("  Usage: " + Convert.ToString(Capabilities.Usage, 16));
                    MessageBox.Show("  Usage Page: " + Convert.ToString(Capabilities.UsagePage, 16));
                    MessageBox.Show("  Input Report Byte Length: " + Capabilities.InputReportByteLength);
                    MessageBox.Show("  Output Report Byte Length: " + Capabilities.OutputReportByteLength);
                    MessageBox.Show("  Feature Report Byte Length: " + Capabilities.FeatureReportByteLength);
                    MessageBox.Show("  Number of Link Collection Nodes: " + Capabilities.NumberLinkCollectionNodes);
                    MessageBox.Show("  Number of Input Button Caps: " + Capabilities.NumberInputButtonCaps);
                    MessageBox.Show("  Number of Input Value Caps: " + Capabilities.NumberInputValueCaps);
                    MessageBox.Show("  Number of Input Data Indices: " + Capabilities.NumberInputDataIndices);
                    MessageBox.Show("  Number of Output Button Caps: " + Capabilities.NumberOutputButtonCaps);
                    MessageBox.Show("  Number of Output Value Caps: " + Capabilities.NumberOutputValueCaps);
                    MessageBox.Show("  Number of Output Data Indices: " + Capabilities.NumberOutputDataIndices);
                    MessageBox.Show("  Number of Feature Button Caps: " + Capabilities.NumberFeatureButtonCaps);
                    MessageBox.Show("  Number of Feature Value Caps: " + Capabilities.NumberFeatureValueCaps);
                    MessageBox.Show("  Number of Feature Data Indices: " + Capabilities.NumberFeatureDataIndices);

                    Int32 vcSize = Capabilities.NumberInputValueCaps;
                    Byte[] valueCaps = new Byte[vcSize];

                    result = HidP_GetValueCaps(HidP_Input, valueCaps, ref vcSize, preparsedData);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace.ToString());
               
            }
            finally
            {
             

                if (preparsedData != IntPtr.Zero)
                {
                    success = HidD_FreePreparsedData(preparsedData);
                }
            }

            return Capabilities;
        }




internal String GetHidUsage(HIDP_CAPS MyCapabilities)
        {
            Int32 usage = 0;
            String usageDescription = "";

            try
            {
                MessageBox.Show("page : " + Capabilities.UsagePage.ToString());
                usage = MyCapabilities.UsagePage * 256 + MyCapabilities.Usage;

                MessageBox.Show("usage in method : " + usage.ToString());

                if (usage == Convert.ToInt32(0X102))
                {
                    usageDescription = "mouse";
                }

                if (usage == Convert.ToInt32(0X106))
                {
                    usageDescription = "keyboard";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            MessageBox.Show("description : " + usageDescription);
            return usageDescription;
           
        }         




When i call the GetDeviceCapabilities() method, it gives me the the error specified in my first post. Can you help me in this problem ?



ANUJ
« Last Edit: February 13, 2012, 11:28:39 pm by jain1.anuj »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Error while reading and writing the data to USB keyboard.
« Reply #5 on: February 14, 2012, 10:26:07 am »
To send data to the device with WriteFile, you need to redesign the device as a generic HID or add a generic HID interface in addition to the keyboard interface.

Another option for sending data to the device is to define a Feature report and open a handle without read/write access. See my example code.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: Error while reading and writing the data to USB keyboard.
« Reply #6 on: February 15, 2012, 04:10:22 am »
Thanks a lot JAN!!!
 
Now my device is reading and writing the Feature Reports. :)

Now can i read and write the Input/Output Reports too?
Or it is with the help of feature report i can do my task? i am little bit confused.

my aim is to read/write data from the device and save it in the file.
can you help me in this regard? Waiting for your reply.

« Last Edit: February 15, 2012, 04:12:18 am by jain1.anuj »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Error while reading and writing the data to USB keyboard.
« Reply #7 on: February 15, 2012, 10:37:38 am »
To read Input reports from a device that enumerates as a system keyboard, use Raw Input or Feature reports.

To read reports from a generic HID, you can also use ReadFile.

To write reports to a device that enumerates as a system keyboard, use Feature reports.

To write reports to a generic HID, you can also use WriteFile.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: Error while reading and writing the data to USB keyboard.
« Reply #8 on: February 15, 2012, 10:33:19 pm »
Thanks again JAN

As my device enumerates as a Keyboard, so i must use Feature Report to read/write data to the device ??

I don't want to use RAW INPUT because it only reads data. So i must concentrate on Feature Reports. :)

At present, i am using FileStream to Write data to the device and it is working fine. I am able to write the values to the device. But the problem i am facing is the low outputBufferSize. It is only 2 bytes so i am unable to write the whole data. I want to read/write the keystrokes from the device that will be configured by the user through application.  

So, how can i manage the memory of outputBuffer to write the whole data that is needed by the user?
Also, what is the maximum size that i can generate for feature report?

When i use FileStream to read the data from the device, it gives me the error. it says that "ACCESS DENIED". So, how can i read the data to the device?

At present i am testing my application with only one device. This application will be distributed among many users, each would have there own devices. So, is it feasible to use only VendorID to detect the device? All the device are manufactured by the same company. So, i think that all the devices wiolud have the same VendorID.

Also i want my device to be detected automatically as soon as it is plugged in the system. How can i do that? At what point should i call the FindTheHid() method to proceed further?

If the device is removed in between, it should stop functioning and display the message that it has been removed from the system. How can i capture the surprise removal of device?
« Last Edit: February 16, 2012, 06:05:00 am by jain1.anuj »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Error while reading and writing the data to USB keyboard.
« Reply #9 on: February 16, 2012, 11:40:36 pm »
>So, how can i manage the memory of outputBuffer to write the whole data that is needed by the user?
Also, what is the maximum size that i can generate for feature report?

You can increase the buffer size. You will also want to define a longer report to fill the buffer. With firmware support, report data can use multiple transactions.

>When i use FileStream to read the data from the device, it gives me the error. it says that "ACCESS DENIED". So, how can i read the data to the device?

Use Feature reports. Open the handle without read/write access.

>At present i am testing my application with only one device. This application will be distributed among many users, each would have there own devices. So, is it feasible to use only VendorID to detect the device? All the device are manufactured by the same company. So, i think that all the devices wiolud have the same VendorID.

You might want to check the Product ID as well.

>Also i want my device to be detected automatically as soon as it is plugged in the system. How can i do that? At what point should i call the FindTheHid() method to proceed further?

See my HID example code, which detects device attachment and removal.

http://www.lvr.com/hidpage.htm#MyExampleCode

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: Error while reading and writing the data to USB keyboard.
« Reply #10 on: February 20, 2012, 01:07:21 am »
Thanks JAN

You said to check Product ID as well.
If i talk about present scenario, i have the details about Vendor ID and Product ID so i am able to check them. But when the user will use the device, he will not be asked to enter the Product ID/Vendor ID in the application because the device gets detected automatically.
So how will i be able to check the Product ID in my application?

Only checking the Vendor ID can't make my device to gets detected ?

Note:- All the devices are manufactured by the same company.

My code for checking the Product/Vendor ID is below:-

Code: [Select]
        myProductID = Int32.Parse("2BFA", System.Globalization.NumberStyles.AllowHexSpecifier);
         myVendorID = Int32.Parse("18C8", System.Globalization.NumberStyles.AllowHexSpecifier);
        
         if ((DeviceAttributes.VendorID == myVendorID) && (DeviceAttributes.ProductID == myProductID))
                            {
                                MessageBox.Show("My device detected");

                                myDeviceDetected = true;
    
                                myDevicePathName = devicePathName[memberIndex];
                            }

« Last Edit: February 20, 2012, 01:09:33 am by jain1.anuj »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Error while reading and writing the data to USB keyboard.
« Reply #11 on: February 20, 2012, 10:34:28 am »
Your code already checks the Product ID so I don't know what your question is.

You can use just the Vendor ID if that vendor has and will never have more than one product or multiple products that can use the same host software.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: Error while reading and writing the data to USB keyboard.
« Reply #12 on: February 20, 2012, 10:30:04 pm »
My question is that this application will be distributed among many users, each would have there own devices. So, is it feasible to use only Vendor ID to detect the device? All the device are manufactured by the same company. So, i think that all the devices would have the same Vendor ID. User would not be asked to enter details like Vendor/Product ID.

One more thing i need to ask is that can i control the LED lights on my device.
My device has a LED which changes it's color according to the status.
If the person is in range of device than it will be in Green color.
If the person is out of range of device than it will be in Red color.
There is one transition state which changes the color to Yellow.

« Last Edit: February 21, 2012, 01:54:33 am by jain1.anuj »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Error while reading and writing the data to USB keyboard.
« Reply #13 on: February 21, 2012, 09:48:04 am »
The product ID is in the device descriptor. The user doesn't set it.

Use a Feature report for the LEDs.

Jan




jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: Error while reading and writing the data to USB keyboard.
« Reply #14 on: February 21, 2012, 11:38:37 pm »
Thanks a lot JAN.

Can you please refer me any example or guide me how i can use Feature Report for LED controlling? I had never done this before.
Can i control the Proximity sensor too using Feature report?
My device has a Proximity sensor which detects the position of the user. If the user is out of range from the device, than the device will fire the keystrokes that are configured by the user using the application.
How can i determine the correct position of the user?
« Last Edit: February 22, 2012, 04:28:11 am by jain1.anuj »