I am using a barcode scanner connected to Windows PC. It is configured to work as USB HID device, and it is the most reliable mode for this scanner to work. I have developed some software to register input from it. The thing is that I want to have some program running in background and intercepting data from barcode scanner and sending the obtained data over network. I have checked some similar solutions, but seems like that people mostly go with having a background window.
Reading USB HID barcode scanner input without knowing VID&PID - here is a similar question, but the answer describes a swing KeyListener child for Java GUI form
https://stackoverflow.com/a/14106511 - also points to similar idea.
It is an app for internal usage, so I may even manually specify VID and PID of device.
Is there any way to read and intercept input from barcode scanner without GUI window?
Related
Hello fellow community,
I'm currently trying to differentiate between multiple HID input sources connected to a RDP client running Windows 10 Business build 19045.2251. The server itself is a Microsoft Windows Server 2019 build 17763 running a custom C# 4.7 .NET application.
The application shall then differentiate betweeen a barcode reader, an RFID reader and a keyboard respectively.
My naive idea is to only allow inputs coming from the barcode reader and only when an authorized person gives permission by means of his/her RFID chip, keyboard inputs are permitted.
Running the application locally for testing purposes allowed to perform the distinction using the vendor and product ID of a given input device using raw inputs.
Unfortunately, this breaks once I move the application onto the server and try obtaining raw inputs from the device connected to the client, as shown below:
raw information of USB device connected to client
So far I tried activating remoteFx in the hope of gettig device specific information, but to no avail.
I could not find any helpful resources on the internet and thus I am turning to you, hoping anybody could provide me with some hints on how to go on.
Also if this approach is flawed to begin with, I am happy to adapt the logic in order for it to work.
Thanks in advance for any input!
I am writing a controlling software for a generic USB HID device within a team, working on Windows 7. Due to my status as an intern, my possibilities are limited:
the software must work on Windows
the software must use the default HID driver Windows supplies
My problem is that however I try to access the device while using the HidUSB driver (according to Zadig) my interrupt transfer read attempts always result with a timeout while the device actually does send data. Writing to the device works all the time, whether I use HIDAPI, whether I use libusb, only reading fails. (this is a primitive device atm and even the final packet data specification isn't done, currently it just sends an ON or an OFF string towards the host, and writing to the device changes the state of a LED between 7 colors and off state, so that one's certainly working)
I can't think of the device being faulty, because if I replace the driver on Windows to the WinUSB driver with Zadig, it works with libusb (and hidapi can't open the device thereafter) and on Linux, just by reading /dev/hidraw also returns the data fine. I have also read the HID and the USB specifications and I know that the device descriptors state that the USB packetsizes are 8, while the HID input report's size is capped at 20, tho I don't know what report ID the device uses.
Checking the Windows communications with USBPcap and Wireshark, the sole difference I can notice among the handling of the device is the host packets asking for data is filled with 00s against the HidUSB driver compared to the CCs when used with the WinUSB driver.
For the record, I have already tried libusb, hidapi, HidLibrary and noone within the team has an idea what to do now.
I have also read that Windows disables access to HID keyboards and mice but I found no actual example of a device config ending up as an USB mice. The Device Manager lists my device twice under HID tho, once as HID-compliant device or how it calls (localized Win7 here) and once as USB Input Device, but doesn't list it among the Mouse or Keyboard option.
Sorted it out a while ago, but I think I'll write it down here if someone ends up with a similar issue in the future.
The Windows HID driver invalidates any incoming packet if the report's data size does not match the length of the sent data iow the size within the report descriptor. Linux and the device itself didn't cared that's why I also ruled that out as source during the time I brought the question here. In the above example the on/off message being 4-5 byte vs the reported 20 byte length was the problem, now that the device sends 20B messages, all the solutions which could write via HidUSB can read as well.
I wonder if anyone can help at all, a bit of a specialist problem this.
I have an application that needs to read and analyse a number of USB devices (not simultaneously, they are each run in seperate tests and could in theory be run on different machines).
Each of the USB devices is based on the USB HID class, and are manufactured by different companies, none of these USB devices are designed to be run on PC, but are meant for a different platform, however for the purposes of testing the devices the client has requested that the test application is run from a PC.
Some of the devices will start up, be recognised by windows which will initialise and start them correctly using the generic HID class driver built into windows, the devices will then start sending correct data packets of the data to be tested.
Some of the devices will start up, be recognised by windows which will try to start them but fail to fully to initialise them leaving them in a half initialised state. This is fine, as I can use my beagle protocol analyser to capture the initialisation packets from the genuine platform and then use the LibUSBDotNet library to replicate the remaining packets in the initialisation sequence and get them to start sending the packets correctly.
The problem I have is with one particular device (though there are some more I haven't tested yet so it's quite possible one of those may also exhibit the same problem). The issue is the the Windows HID class driver recognises the device and trys to initialise and start it, this works after a fashion and the device starts sending data.
The problem is that the data being sent is different to that which is sent to the genuine platform (containing only a subset of the full data). It's as though windows has initialised the device into a different mode.
When I capture the initialisation packets from both the PC and the genuine platform using my USB protocol analyser I see that Windows is sending some slightly different initialisation packets. Using LibUSBDotNet to resend the correct packets once Windows has already started the device seems to have no effect.
My problem is that I need to stop windows from trying to initialise the device using the standard HID class driver, I've tried removing the driver in Device Manager but it still initialises it (and the driver is magically reassigned in device manager). I've done some investigation and there are possible alternatives:
Create a specific driver which windows will assign to the particular VID/PID of the device but that does nothing, then I can use LibUSBDotNet to send the correct initialisation sequence to the device from within my own code.
Use something like WinUSB to create a proper driver for the device (or possibly to create a "dead" driver like 1.
Will a driver with a specific VID/PID defined be used by windows in preference to it's inbuilt USB HID class driver? If not then I would be wasting my time going down this route?
Note, my mac initialises the problem device correctly, and I've asked the question of the client whether the application can be developed for Mac and their answer was frustrating Windows only.
I've no experience in writing proper Windows drivers, though I have experience in talking to USB at a relatively low level (so that part doesn't worry too much). Can anyone suggest a good course of action (before I potentially waste weeks investigating how to write drivers for the PC only to find my selected course of action can't deliver what I required).
Any help or suggest much appreciated.
Thanks,
Rich
Added after trying suggestions below:
I tried using the LibUsbDotNet inf wizard to create the necessary files and install them and this appeared to work - certainly the device was now appearing in Device Manager as a libusb-win32 device - not HID device and the associated driver was libusb driver. Even after doing this the device still seems to become initialised and start sending the wrong type of data packets although now those packets are no longer handled by the class driver and are just lost.
I also came across Zadig which has a similar inf creation wizard for WinUSB and this had exactly the same result.
A colleague has suggested that it might not be windows itself that is switching the device into this mode, rather the device identifying that it is connected to a windows machine and switching itself into this mode. I suspect this is the case, in which case I am stuck - time to have another conversation with the client.
Many thanks for the help.
You're using libusb-win32 as a filter driver; that is, the HidUsb device driver is assigned and loaded for your device, but then the libusb-win32 driver is loaded on top and gives you unobstructed access to the hardware.
If you don't want a HidUsb (or any other class driver) to perform any communication "on your behalf", simply associate libusb-win32 as a device driver with your hardware. For this, you'd have to create an .INF file associating it with the VID/PID/Revision of each USB device. If I recall correctly, libusb-win32 even comes with a utility to generate such .INF files.
If you install this .INF file e.g. with PnpUtil.exe (available on Vista or higher), you might still run into issues where, although you're a better match than the generic HID driver, the HID driver is still selected.
The generic HID driver matches devices by their Compatible IDs (i.e. by a USB interface class) while you'd be matching by Hardware IDs (which have higher priority). However, Windows might give priority to other aspects, such as your driver being unsigned. Read: How Windows Selects Drivers
Luckily, even in that scenario, signing drivers with a self-generated certificate (use CertUtil.exe, MakeCat.exe and SignTool.exe) is not too difficult.
I wonder if I understand correctly...
Say, if I want to control how my mouse work, i.e Left Button open window, Right Button send keystroke 'A' etc.
But I am not talking about writting something like follows in an application:
void MouseDown(xxxxEventArgs e, sender object)
{
}
I want to completely controls how the device work, then I will need to write a driver for it? From what I learn in assembly before, controlling a device I should need to know their port to communicate with the device. But say if I buy a Logitech mouse, is it possible to write a mouse driver myself to use it?
Because I saw some project that they buy a usb web cam from store, and they could able to control the web came to rotate, recevie the image from the web cam, I wonder if that's because the web cam has API provided them?
Thanks in advance.
If you want to control the device in it's entirety, then you need to write a device driver indeed. This is a non-trivial task and you should read up on it. There is a tutorial on it here and there a book for windows driver development here.
If you want to write device drivers, you should be very well versed with C and/or C++.
You do not need to write a device driver for what you are trying to do.The device driver has nothing but as per the data sheet of the device address of registers where it can read,write,do IOMMU etc or some other stuff.What you will need is some kind of hacking the application programming part of the thing which you are trying to achieve.
Because device driver code just reads the data from device and writes back it is the application which is concerned for it.Though in some case device driver programmer provide a method (function) to application programmer so that they can write their application and invoke those methods.In your case you need to just understand how the application code is talking to device driver.
In case you want to write a device driver check this
http://www.freesoftwaremagazine.com/articles/drivers_linux?page=0%2C0
In such kind of cases you can proceed with writing your own device driver by C++ and assemb
lyem
I have an extremely simple application running off a series of deprecated scanners that picks up a barcode scan off a serial port and sends back to the scanner an ok that it received the scan. Based on that, the scanner flashes green and the user knows they can continue.
I like this model over my understanding of a keyboard wedge because if something happens to the application picking up the scan (the application hangs, the form with the focus gets changed, the PC hangs, the PC can't keep up picking up the scans), the person holding the scan gun will know there is a problem because they won't receive the green flash and they won't be able to continue scanning.
I'm looking at adding some scanners and it seems many people are using barcode scanners that effectively act as keyboard wedges. Some of these scanners have ranges that exceed 100 feet, implying people are using them far away from the PC (as my users are). So I'm wondering if I'm missing something regarding the keyboard wedge model. Is there some mechanism I'm missing to ensure that a scan decoded by a scanner acting as a keyboard wedge actually reaches the application running on the PC? A full-blown hand-held computer running something like Windows Mobile seems like massive overkill for just wanting to ensure my user is not scanning data that isn't going into the application and so does even a mid-range scanner with a keypad and screen, but is the latter the entry point for any sort of programmatibility of the scanner?
You are correct- there isn't a feedback loop to the scanner when running as a wedge. We use wedge scanners a lot, and in a modern environment (ie, Windows, multiple apps, etc), focus, "dropped scans", etc, are all real problems.
We're in the middle of switching over to a different way. If you have your choice of hardware, many new USB barcode scanners have the ability to operate in a serial emulation mode that allows the same kind of interaction you describe (where you can prevent a second scan until the host has ACK'd the first, or you can beep/flash something on the scanner as an ACK). Also, there's a USB HID POS (point of sale) mode that some higher-end USB scanners support that gives you an even greater degree of flexibility, with the added bonus of "driver free" installation (it looks like a generic HID device to the system, like a joystick or keyboard, but with 2-way comm ability). The downside of POS mode is that it's a little harder than serial programming, but there are abstraction layers available for different platforms.
RF mobile computers with built in scanners, like the Symbol MC9090-G, are by far the most flexible and what we use the most. As for wedges, depending on the distance from the PC and factory environment - we have used visual feedback via the PC screen and audio via the PC speakers. The users listen for the audio feedback after each scan and when they don't hear it they look back to the PC screen for visual feedback as to the problem. Not perfect but it has worked well.