I am trying to intercept/interact with a Maschine Mikro 2 plugged into my Mac via USB. I have a IOUSBInterfaceInterface reference to the correct USB HID interface. However, whenever I try to call, USBInterfaceOpen on the interface, I always get the IOReturn value of 0x2c5, meaning another program already has exclusive access to this interface.
The only other program I could think of that would have this interface open is the Native Instruments device driver since it would need to write to this interface. However, if the driver has exclusive access to the interface, how is any other program supposed to read from it?
Does anyone have experience with the Native Instruments drivers and know how they expose the device to user-space? I would've expected a file of the form /dev/cu.* but none are created when the Mikro 2 is plugged in.
It turns out there is a daemon called NIHardwareAgent that I believe has exclusive access to the USB interface. Through reverse engineering the Maschine 2 app, I found that it communicates with the hardware agent through CFMessagePort's.
Related
I am trying to get reports from a PS4 like controller for which I don't have access to firmware.
I've successfully managed to communicate with the device on Windows platform, but having trouble with MacOSX (tried MacOS 10.12).
On Windows I've used HidD_SetOutputReport()/HidD_GetInputReport() functions which means that the device expects the requests as Control Transfers. Interrupt Transfers' WriteFile()/ReadFile() don't seem to be able to send data where the device expects it.
HID API uses IOHIDDeviceSetReport() for the hid_write() function which seems to behave like Windows' WriteFile(). Also tried libusb but it fails when trying to usb_claim_interface() with "another process has device opened for exclusive access". libusb_detach_kernel_driver() is only implemented for linux. I could use the codeless kext approach but the device is a HID controller it is supposed to work without a driver.
Do you know of any ways of sending a Control Transfer on MacOS?
I have an usb device (pole display), which i don't have driver for.
I installed generic usb driver and opened the port for sending(I use bulk transfer) data to device.
With usb monitoring software i see my data gets to device, but nothing much happens on device side.
The device commands(ESC/POS) work when transfered over (virtual) com port, but not over usb port.
Shouldn't device process commands the same way regardless connection type (com vs usb)?
How can i figure out what commands work with the device (for example, if i send some text, i want it to show on display)?
Any help is appreciated!
Look at the USB descriptors the device reports in order to determine its class. If it is a custom device and not a standard class then you'll likely not be able to work with it. There is a big difference between old RS-232 COM protocol and USB. USB devices can have multiple configurations and endpoints, each responding to data in different ways. Many classes exist and are pretty standard (CDC-ACM is typically used for virtual serial ports.) However, it's not uncommon for device manufacturers to include OEM specific configurations and endpoints which can be used for their own custom interfaces, firmware loading, etc.
Is there any initialization data transmitted through the COM port when connecting the device? The device surely can treat COM and USB different, but another possible thing that goes wrong is that the device needs to hear some sort of "I'm going to start sending commands"-signal from you first, and that signal may be different between COM and USB.
So what I would recommend is first (if you have not done that yet) see what data is sent to initialize the COM connection, and if that doesn't have an obvious USB counterpart, connect it to a PC where you do have drivers (assuming that is available somewhere and somehow, which is possible if e.g. you ask this due to OS incompatibility) and see how the connection is initialized there.
If the first doesn't work and the second is unavailable to you, then I'm afraid there's little I can do to help you, since it's usually not visible for you what commands the device wants to hear other than by guesswork, documentation, or comparing to similar devices where you do have that data available.
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.
inHi, this question is fast, but from my point of view its pretty hard. I have been messing with implementing USB device built from MCU. So I found project called V-USB which is software-emulated USB interface for Atmel MCUs. But this is not so important.
The question is, on their site, they say that using custom USB class, you can simply write host software on Unix, but you need driver DLL for Windows. The problem is, they dont explain why.
So, please, why? I dont know Unix based systems, but I thought that the very basics of different OS are the same becouse thay rise from the same hardware, and even Unix cannot do HW IO operations from user mode.
I know about libraries for USB communication like LibUSB and so, but I want to know the very reason why thay say that its easy on Unix. Thanks.
EDIT:
Thanks for answer, but can I have further question? How this everything is a file works? I mean, my vision of driver on Windows is a program running in kernel mode, thus allowed to access CPU IO ports, which either provides functions to OS by some standarts, to allow Windows to use it (for example HDD driver must be accessible from filesystem driver by standardised set of functions, to allow any HDD work the same).
With this all you have to do is call drivers via WinAPI function or directly call its functions. But USB implements new feature which is different classes. So there is main USB root driver to handle USB and calling right secondary drivers for right devices. Than there is the same procedure, you just call your USB driver.
But if in Unix everything is a file, how are handled different classes? I just cannot imahine how this works in some analogy to Windows way. Does that file represents the way to communicate with USB root driver?
Everything in UNIX is a file, which supports simple operations. No matter if you are communicating via a terminal or a via a usb device, everything is a stream of bytes to a file.
* read
* write
* lseek
* close
I am writing a UMDF sensor driver for a device that connects to the system via Bluetooth and is accessible as an HID input device. I saw the "Sensor Development Kit" sample driver and noticed that it works with the Freescale hardware via HID also though it connects to the system via USB. Is there any difference in the way the UMDF driver communicates with the device in case it connects to the system via Bluetooth? For some reason, I find that the call to CreateWdfFile returns ERROR_INVALID_FUNCTION even when I have the device paired with the system. I am able to access the device directly via HID just fine.
In the INF for the driver I have specified the hardware ID like so - HID\VID_1234&PID_5678 (haven't used the actual IDs here). Is this sufficient for the UMDF framework to determine which driver it should use further down the stack? Or is there something else that one needs to do?
I managed to resolve this one myself. Turns out I wasn't using the correct hardware ID. On a whim I looked up what hardware IDs the bluetooth device had been registered with under HKLM\SYSTEM\CurrentControlSet\Enum\HID and used another ID that had been given there and voila! - IWDFDevice::CreateWdfFile worked! :) And sure enough, this is described quite clearly on MSDN here. So, all's good!