trying to read midi controller device name using winmm - windows

Long term goal, build software to implement midi control surface as a user interface for industrial control applications by using a prebuilt midi controller instead of building and wiring a custom control panel. Short term goal, read the name of the midi device plugged into the computer. Immediate problem, the compiler says 'illegal qualifier, szPname". I believe that szPname is a subset of the caps structure but I don't understand how to get to it.
I am using implementing winmm from FreePascal on a windows 10 machine.
here is my current code...
program asd;
uses mmSystem;
var
caps: ^MIDIINCAPS;
begin
writeln(midiInGetNumDevs());
midiInGetDevCaps(0,caps,SizeOf(MIDIINCAPS));
writeln(caps.szPname);
end.

The documentation says:
Error: Illegal qualifier
One of the following is happening:
You’re trying to access a field of a variable that is not a record.
You’re indexing a variable that is not an array.
You’re dereferencing a variable that is not a pointer.
In this case, caps is a pointer, so you must dereference it before you can access the record fields:
WriteLn(caps^.szPname);
(Other compilers can automatically dereference pointers to records. Apparently, FreePascal cannot.)
You also need to allocate memory for caps. (Or don't use a pointer.)

Related

How to handle device removal in Linux Kernel Driver?

You have done it a thousand times: you unplug some USB equipment and any device associated with that USB equipment is removed by the driver. Any program that uses some previously opened file handle will get an error. Somehow most Linux drivers take care of that.
I am currently struggling to implement the same in a simple driver. My driver creates a character device. When the device is opened, I set the private_data member of struct file to the address of some management data that exists once per character device. That management data also includes a mutex that I use to synchronize operations like read, write, and ioctl.
The problem now arises when the USB equipment is unplugged. I must not free the memory where that management data lives. First, any currently running read, write, or ioctl should finish. Any such running call will likely also hold a lock on the mutex and will attempt to unlock it. So the memory where the mutex lives will be accessed.
Any read, write, or ioctl call subsequent to unplugging the equipment should fail, so every such call must read some variable telling whether the USB equipment is still plugged in or not. Again, that variable must live somewhere and the memory where it lives must stay allocated as long as there are open file handles.
Long story short, it seems to me that I must do some sort reference counting: The management data must stay allocated until all file handles have been closed. I could implement that myself, but I have the feeling that I would reinvent the wheel. Such a thing must already exist, I'm not the first to have this problem.
Does Linux internally keep track of the number of open file handles? Can I define a callback that is called when all file handles have been closed? Is that even a viable thing? What is the proper way to remove a character device from the system?
Global variables shall not be avoided, since any number of USB devices can be attached.
As suggested by 0andriy, I have used reference counting to track the number of open file handles. Per character device, I have added a new struct containing a mutex, a kref, the cdev struct, and a pointer to further data. I use kref_get to increase the reference counter when a new file handle is opened. Accordingly, I use kref_put when file handles are released or the USB equipment is unplugged.
Since all I/O operations (read, write, ioctl, etc.) use the mutex, I can safely change the pointer to NULL when the USB equipment is unplugged. The I/O operations then start reporting errors.
The kref reference counter only returns to zero when the USB equipment is unplugged and all file handles are closed. So then I can also free the memory of the new struct.
This seems to work. It was a surprise that the cdev struct is referenced by file handles. It seems to be needed as long as there are open file handles.
But I'm still surprised that I had to go down this route. It seems redundant to implement that in every driver.
UPDATE: As it turns out, doing reference counting yourself is dangerous. In particular counting the number of open file handles is wrong. There is a whole reference-count-based garbage collection system in Linux and you need to use it.
For example, Linux calls cdev_get when a process opens a character device and cdev_put when the process exists and the file handle is still open. Unfortunately, the call to cdev_put would occur after the file handle's release function. As we would free the memory after the last file handle has been released, we would end up freeing the underlying memory of the cdev and the mutex before cdev_put is called.
The solution is to assign a parent to the cdev via cdev_set_parent. The parent kobject will have its reference counter increased whenever cdev_get is called and decreased after cdev_put is called. The kobject then can have its own release function which frees any memory required by the cdev. Basically I replaced the kref in my struct with a kobject.
Lesson learned: don't do reference counting on your own. Use the existing hierarchy of kobjects, which is the kernel's way of doing garbage collection.
UPDATE2: It turns out, we reinvented the wheel again. The device struct includes a release hook, which is called when the internal kobject reached a reference count of zero. This is the mechanism typically used in the kernel to release resources associated with an device - including the device struct itself.
I was looking for a release hook in the cdev struct. There was none. But it turns out I should have looked one step up in the hierarchy for such a hook.
Long story short: Use cdev_device_add in combination with the device release hook. cdev_device_add will internally call cdev_set_parent, so the device becomes the parent of the cdev. Those are the mechanism other kernel drivers (e.g. evdev) use to release their resources.

WinDbg not showing register values

Basically, this is the same question that was asked here.
When performing kernel debugging of a machine running Windows 7 or older, with WinDbg version 6.2 and up, the debugger doesn't show anything in the registers window. Pressing the Customize... button results in a message box that reads Registers are not yet known.
At the same time, issuing the r command results in perfectly valid register values being printed out.
What is the reason for this behaviour, and can it be fixed?
TL;DR: I wrote an extension DLL that fixes the bug. Available here.
The Problem
To understand the problem, we first need to understand that WinDbg is basically just a frontend to Microsoft's Windows Symbolic Debugger Engine, implemented inside dbgeng.dll. Other frontends include the command-line kd.exe (kernel debugger) and cdb.exe (user-mode debugger).
The engine implements everything we expect from a debugger: working with symbol files, read and writing memory and registers, setting breakpoitns, etc. The engine then exposes all of this functionality through COM-like interfaces (they implement IUnknown but are not registered components). This allows us, for instance, to write our own debugger (like this person did).
Armed with this knowledge, we can now make an educated guess as to how WinDbg obtains the values of the registers on the target machine.
The engine exposes the IDebugRegisters interface for manipulating registers. This interface declares the GetValues method for retrieving the values of multiple registers in one go. But how does WinDbg know how many registers are there? That why we have the GetNumberRegisters method.
So, to retrieve the values of all registers on the target, we'll have to do something like this:
Call IDebugRegisters::GetNumberRegisters to get the total number of registers.
Call IDebugRegisters::GetValues with the Count parameter set to the total number of registers, the Indices parameter set to NULL, and the Start parameter set to 0.
One tiny problem, though: the second call fails with E_INVALIDARG.
Ehm, excuse me? How can it fail? Especially puzzling is the documentation for this return value:
The value of the index of one of the registers is greater than the number of registers on the target machine.
But I just asked you how many registers there are, so how can that value be out of range? Okay, let's continue reading the docs anyway, maybe something will become clear:
If the return value is not S_OK, some of the registers still might have been read. If the target was not accessible, the return type is E_UNEXPECTED and Values is unchanged; otherwise, Values will contain partial results and the registers that could not be read will have type DEBUG_VALUE_INVALID.
(Emphasis mine.)
Aha! So maybe the engine just couldn't read one of the registers! But which one? Turns out that the engine chokes on the xcr0 register. From the Intel 64 and IA-32 Architectures Software Developer’s Manual:
Extended control register XCR0 contains a state-component bitmap that specifies the user state components that software has enabled the XSAVE feature set to manage. If the bit corresponding to a state component is clear in XCR0, instructions in the XSAVE feature set will not operate on that state component, regardless of the value of the instruction mask.
Okay, so the register controls the operation of the XSAVE instruction, which saves the state of the CPU's extended features (like XMM and AVX). According to the last comment on this page, this instruction requires some support from the operating system. Although the comment states that Windows 7 (that's what the VM I was testing on was running) does support this instruction, it seems that the issue at hand is related to the OS anyway, as when the target is Windows 8 everything works fine.
Really, it's unclear whether the bug is within the debugger engine, which reports more registers than it can retrieve values for, or within WinDbg, which refuses to show any values at all if the engine fails to produce all of them.
The Solution
We could, of course, bite the bullet and just use an older version of WinDbg for debugging older Windows versions. But where's the challenge in that?
Instead, I present to you a debugger extension that solves this problem. It does so by hooking (with the help of this library) the relevant debugger engine methods and returning S_OK if the only register that failed was xcr0. Otherwise, it propagates the failure. The extension supports runtime unload, so if you experience problems you can always disable the hooks.
That's it, have fun!

Using SetupDiSetDeviceRegistryProperty with SPDRP_HARDWAREID

The docs for the SetupDiSetDeviceRegistryProperty function say,
The following values are reserved for use by the operating system and
cannot be used in the Property parameter ...
SPDRP_HARDWAREID
However, there are lots of examples of code out there, including MS DevCon utility which uses this function with the SPDRP_HARDWAREID parameter, ie:
SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
(LPBYTE)hwIdList,
(lstrlen(hwIdList)+1+1)*sizeof(TCHAR)))
They also have an article which suggests doing so:
If an installer detects a non-PnP device, the installer should select a driver for the device as follows: create a device information element (SetupDiCreateDeviceInfo), set the SPDRP_HARDWAREID property by calling SetupDiSetDeviceRegistryProperty
I'd like to (and do) use this function to set Hardware ID for my virtual device. The question is - is it a typo in the manual, or it's some sort of unsupported behavior and therefore it can stop working any time?
TL;DR: If you're creating a root-enumerated device node, you're free to set SPDRP_HARDWAREID/SPDRP_COMPATIBLEIDS yourself by calling SetupDiSetDeviceRegistryProperty. Otherwise you're not allowed to do so.
This was an error in the docs that was fixed at some point.
Today the docs of SetupDiSetDeviceRegistryProperty read:
SPDRP_HARDWAREID or SPDRP_COMPATIBLEIDS can only be used when DeviceInfoData represents a root-enumerated device. For other devices, the bus driver reports hardware and compatible IDs when enumerating a child device after receiving IRP_MN_QUERY_ID. [Emphasis mine]
... which is exactly what DevCon does.

Jump to App from custom bootloader in TMS320 digital media processor

I am working on a boot loader for TMS320DM6437. The idea is to create 2 independent firmware that one will update another. In firmware1 I will download firmware2 file and write it to NOR flash in a specified address. Both firmware are stored in NOR flash in ais format. Now I have two applications in flash. One is my custom boot loader and the second one is my main project. I want to know how I can jump from the first program to the second program located at a specified address. I also expect information about documents which may help me to create custom bootloader
Any recommendations?
You can jump to the entry point. I'm using this approach on TMS320 2802x and 2803x, but it should be the same.
The symbol of the entry point is c_int00.
To get to know the address of c_int00 in the second application, you have to fix the Run-Time Support (RTS) library at a specific address, by modifying the linker command file.
Otherwise you can leave the RTS unconstrained, and create a C variable (at a fixed address) that is initialized with the value of cint_00. Using this method your memory map is more flexible and you can add, togheter with the C variable, a comprehensive data structure with other information for your bootloader, e.g. CRC, version number, etc.
Be carefull with the (re)initialization of the peripherals in the second application, since you are not starting from a hardware reset, and you may need to explicity reset some more registers, or clear interrupt requests.

How do I port a serial port device driver from Linux 2.6.21 to 2.6.36?

It appears that some time between these two kernels a lot of data structures were changed, and it breaks my driver in several places.
First, in 2.6.21 the struct uart_port had a field "struct uart_info *info" which I relied on in several places. I test several places to make sure it is non-null, and if non-null I additionally test if it's sub-field (struct tty_struct *tty) is non-null, and I uses these to check if flow control is enabled and if we are stopped transmitting.
In 2.6.36 the info back pointer has been removed and I'm not sure how to get at it, or if the semantics of what I am trying to do are even valid any more, as the only serial driver that even uses this appears to have ifdef'ed out the code dealing with it, and additionally holds all this data in its own structures (how does that work to even correctly maintain state with the kernel)???
Additionally, save_and_cli() and restore_flags() are missing. I see new functions local_irq_save() and local_irq_restore(), can I just switch to using those, or are there any gotchas?
Finally, __ioremap is missing. Looks like maybe ioremap_noncache is the replacement, but again I'm not sure if there are any semantic differences or gotchas. I would assume I don't want ioremap() since I am talking directly to hardware, but some other drivers appear to do so and I don't know why that would work.
Looking at how an in-tree driver that uses the same functionality has changed between the two versions is usually the best way to go. For example, the ioc4_serial driver uses the info member of struct uart_port in kernel 2.6.21, but has switched to using the struct uart_state *state member by kernel 2.6.36.
That driver obtains the tty_struct with:
state = the_port->state;
tty = state->port.tty;

Resources