I'm writing a C++ program that should check Driver Device ID.
My input is the driver name as it should appear in the Device Manager.
I tried to Google, and I figured that:
I could get the driver pointer using this sample code http://msdn.microsoft.com/en-us/library/ms682619%28VS.85%29.aspx
I should use IRP_MN_QUERY_ID function to get the device ID- http://msdn.microsoft.com/en-us/library/windows/hardware/ff551679(v=vs.85).aspx.
However, I couldn't find any examples or code snippets for how to actually do it, and how those two functions connect?
I have no experience in drivers, sample code will be very appreciated...
On windows there are no device ids (as name =) ). Device matches by hardware id and compatible ids. From this ids system generate instance id - uniquely identifies the device on specific port on bus. You can get hardware/compatible id without sending IRPs, by using IoGetDeviceProperty function (http://msdn.microsoft.com/en-us/library/windows/hardware/ff549203(v=vs.85).aspx), it`s more easy than roll up your own IRP.
Related
I am writing a C++ Linux userspace driver for a USB device using the C library libusb. I have two copies of the same device (same vendor ID and product ID) and would like to know how to handle this case.
Here are the possibilities I can think of:
libusb_get_device_list() returns only devices that are not currently in use
I can differentiate the used vs. unused devices using information of the device descriptor, using libusb_get_device_descriptor()
libusb_open() on the currently in-use device will fail, by returning either LIBUSB_ERROR_ACCESS or LIBUSB_ERROR
How should I deal with this? Which of the preceding options, if any, is the behaviour of libusb when dealing with many of the same devices? How can I differentiate between the in-use device and the idle one?
As #fiscblog said in his answer, "Identification is done via the device descriptor (use the serialnumber which should always be unique)". My problem here is that, in order to do so, the two drivers should communicate to know which instance is handling which device (using, for instance, a file), and I would like to avoid this. I also would like to avoid having to introduce multithreading and manage two devices with one driver, as I don't have the skills to do so in an efficient and well-controlled way (nasty race conditions ... !)
The correct handling is:
enumerate all devices (get device list)
identify the requested device and open it
Identification is done via the device descriptor (use the serialnumber which should always be unique), as you discovered yourself.
How to know if a device is in use?
If a device is open, the endpoints will be bound and configured for I/O. Therefore you cannot open it again but will get the error codes you mentioned.
According to the documentation on libusb_claim_interface():
Interface claiming is used to instruct the underlying operating system that your application wishes to take ownership of the interface.
so you should be able to call libusb_claim_interface() on each device and it should only succeed on the unclaimed one:
It is legal to attempt to claim an already-claimed interface, in which case libusb just returns 0 without doing anything.
libusb is written in C and follows the same basic general guidelines for accessing devices, file descriptors, streams, etc.
1 - Connect to de device
2 - Check the connection, if there's an error, inform and return
3 - There's no error!! Interact
Following this basic flow, the solution in your case IMHO is as simple as:
Identify the devices
Iterate througth them trying to connect until one throws no failure
do something
close
I have a device without knowing the used gatt profile, I only know that is something "homemade" and not anything known on the bluetooth-database.
In Linux the command
gatttool -i hci0 -b xx:xx:xx:xx:xx:xx --char-read --handle=42
returns the value as expected (with the target device mac at xx:xx:xx:xx:xx:xx).
In Qt I am using the Heartbeat-Example from http://doc-snapshot.qt-project.org/qt5-5.4/qtbluetooth-heartlistener-example.html
there they connect using a gattprofile, QBluetoothUuid::HeartRate and QBluetoothUuid::HeartRateMeasurement
I wasn't able to modify the example code in a way to read handle 42.
Can you explain where I have to put which values, that it connects to the "standard profile" as the gattool command does? If I use gatttool in interactive mode and ask primary it returns two uuids, but using them instead of the QBluetoothUuid::HeartRate did not work.
It doesn't appear that the Qt Bluetooth Low Energy API provides means for obtaining access to characteristics based on their handle value. (Neither does the Windows 8 BLE API.) You should use the UUID. Even if it's a homemade device, all services and characteristics are required by the GATT protocol to have UUIDs. The lowenergyscanner demo app can discover and display both the UUIDs and handles of all of the device's services and characteristics. I've used lowenergyscanner to deal with BLE devices I'm developing.
device discovering is by uuid, even if you create a new profile with a new service and a new characteristic, you have to give the new characteristic uuid in setup.
But i dont know, how to add multiple characteristics to one service, it does not work with me.
have fun
I am trying to write a function to return all the GUIDs of the devices attached to the machine, as well as returning the BIOS Id. How would I achieve this? I can only seem to find ways of doing it on a windows machine, but not a linux.
Linux does not assign a GUID to everything. Hardware is identified by hardware-native means, e.g. USB and PCI devices are identifies by vendor and device ID (and serial number).
You can see what data the kernel offers by browsing /sys. I'd also check the source of tools like lspci and lsusb to get an idea on how one retrieves data programmatically (i.e. without parsing files in /sys).
There is, by the way, also a tool called dmidecode, that does operate directly on DMI data.
I'm trying to write a program that sends COM port information to devices that may get unplugged and end up with a different COM port number. Using SetupDi, I know it's possible to list all the COM ports on a computer by number, but given that the number might change I'm trying to find a better way to access the COM ports.
The COM devices I'm using are FTDI serial-to-com adapters that let me program the device model. I'd love to be able to choose a COM port based on the device model. I've tried (almost) all of the properties that I can get to using SetupDi, but no dice. It looks like there's a difference between the device list SetupDi lets me access, and the devices that show up under Devices and Printers (where the model name does show up). Is there any way to get devices in the Devices and Printers window programmatically and map them to COM port using Windows APIs?
The link below is a great (if not the only) comprehensive overview on how to enumerate COM ports on Windows and extract extra information in various ways:
http://www.naughter.com/enumser.html
What we use in our own software (Docklight) is according to what the "UsingSetupAPI1" way from the enumser.cpp file shows (SetupAPI - GUID_DEVINTERFACE_COMPORT). The UsingSetupAPI1 example demonstrates how to extract the device name as shown in the Windows Device Manager, along with the COM number. This is called "friendlyNames" in the enumser.cpp code.
Another way to identify and communicating to your device could be not asking Windows in the first place, but the FTDI D2XX API:
http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples.htm
We use the D2XX API for communication when we know it is always a FTDI device. Identification is simpler and we have much better performance / less latency than using Windows Communications API via "virtual COM port".
If we need to correlate between COM port numbers and a FTDI device ID, we use the FTDI D2XX API's ListDevices and GetComPortNumber functions.
How do I most properly use libusb to talk to connected USB devices?
Specifically, how do I transfer data to the USB devices, receive information from the devices, find out the name of the connected device, if they have storage, etc.
More specifically, I will be running this on a Mac OS X machine, so I know I can't just use Windows header files.
If there is a good explanation on libusb and USB devices, that would be helpful too.
Here is a post on a similar question that might be useful to you. I include plenty of links.
But maybe you'd rather see it here. So in that case, here it goes!
Libusb allows you to enumerate devices and select the one you want based on a specific Vendor/Product id (V/P Id). If you don't know this and can't find it online with the product's description then you can easily find it.
If it is not online you will need to use an app similar to lsusb on Linux. (I don't believe it is on Mac.) When you run lsusb it lists connected devices and their V/P Ids. You can easily find your device by unplugging, running lsusb, and plugging the device back in and comparing. It's a piece of cake. Any usb list app on Mac will hopefully display the V/P ID like lsusb does.
Then once you have this V/P ID you will use libusb (if using 0.1) to enumerate all devices and find the device that matches that id. (I support using libusbx which happens to have a single find device function based on V/P id - in fact, libusbx is a whole lot more concise all around.)
After selecting your device you will send a packet using either Feature or Output Reports. This is the most complicated part because the packet you send is dependent on the individual device I believe. It is 8 bytes of data and only one of which is a single character you wish to send to the usb device. (If you wanted to send 8 characters, you would have to loop through an array of chars and send a feature or output report for each character.)
As an example feel free to reference a rather specific terminal example I wrote for controlling two LEDS. If it's helpful, great! It contains a libusbx and libusb-0.1 example.
I hope this helps!
The official site for libusb 1.0 (the newer and recommended version) is https://libusb.info/. The API documentation is at http://api.libusb.info. Click on the Modules section to walk through the different function areas. The source is at https://github.com/libusb/libusb and you can see some working examples at https://github.com/libusb/libusb/tree/master/examples. Hope that helps!
The article from #user2469202 is a good basic intro also.
The process that you can follow is:
Get the VID, PID for the device that you want to communicate using lsusb
Try to open the device and read the device descriptor
If you want name of the device use string descriptor to get that
Check if any kernel driver is attached. If it is, then detach it and do some raw data transfer
After getting the response again re-attach the driver.