I'm working on a virtual audio/midi driver and although its already working, I'm wondering whether my implementation is ... proper..
Usually, the midi hardware triggers interrupts in the driver to send / receive / process data, however as my driver is virtual, there is no hardware that could trigger the interrupts.
The way I handled this is that I set up a DPC timer for 100ms that calls the processing / sending routines, data received is still handles via interrupt from the OS.
Now that obviously isn't quite what DPCs are for, are they. However I cannot think of another implementation that works as well.
So.. any suggestions would be greatly appreciated :)
Regards,
Xaser
Related
I'm new to Linux device drivers writing and I'm trying to make a device driver that handles an UART chip. For this I decided to use work ques as my bottom half processing because I have to use some semaphores when handling the data that I get from the UART chip.
A work queue handler that was scheduled earlier in an interrupt now gets executed and during it's execution it will sleep at a semaphore. During this time the interrupt handler is called again and schedules the same work queue handler. Will the work queue handler be executed again before the first execution of it finishes ?
Thanks.
The default behavior of work queues is to allow concurrent execution on different CPUs. There is a flag WQ_NON_REENTRANT that changes this behavior. More information can be found in this post http://lwn.net/Articles/403891/
But it seems that in recent kernels work queues are non-reentrant by default - see
http://lwn.net/Articles/511190
I need a two-way communication between a kernel-mode WFP driver and a user-mode application. The driver initiates the communication by passing a URL to the application which then does a categorization of that URL (Entertainment, News, Adult, etc.) and passes that category back to the driver. The driver needs to know the category in the filter function because it may block certain web pages based on that information. I had a thread in the application that was making an I/O request that the driver would complete with the URL and a GUID, and then the application would write the category into the registry under that GUID where the driver would pick it up. Unfortunately, as the driver verifier pointed out, this is unstable because the Zw registry functions have to run at PASSIVE_LEVEL. I was thinking about trying the same thing with mapped memory buffers, but I’m not sure what the interrupt requirements are for that. Also, I thought about lowering the interrupt level before the registry function calls, but I don't know what the side effects of that are.
You just need to have two different kinds of I/O request.
If you're using DeviceIoControl to retrieve the URLs (I think this would be the most suitable method) this is as simple as adding a second I/O control code.
If you're using ReadFile or equivalent, things would normally get a bit messier, but as it happens in this specific case you only have two kinds of operations, one of which is a read (driver->application) and the other of which is a write (application->driver). So you could just use WriteFile to send the reply, including of course the GUID so that the driver can match up your reply to the right query.
Another approach (more similar to your original one) would be to use a shared memory buffer. See this answer for more details. The problem with that idea is that you would either need to use a spinlock (at the cost of system performance and power consumption, and of course not being able to work on a single-core system) or to poll (which is both inefficient and not really suitable for time-sensitive operations).
There is nothing unstable about PASSIVE_LEVEL. Access to registry must be at PASSIVE_LEVEL so it's not possible directly if driver is running at higher IRQL. You can do it by offloading to work item, though. Lowering the IRQL is usually not recommended as it contradicts the OS intentions.
Your protocol indeed sounds somewhat cumbersome and doing a direct app-driver communication is probably preferable. You can find useful information about this here: http://msdn.microsoft.com/en-us/library/windows/hardware/ff554436(v=vs.85).aspx
Since the callouts are at DISPATCH, your processing has to be done either in a worker thread or a DPC, which will allow you to use ZwXXX. You should into inverted callbacks for communication purposes, there's a good document on OSR.
I've just started poking around WFP but it looks like even in the samples that they provide, Microsoft reinject the packets. I haven't looked into it that closely but it seems that they drop the packet and re-inject whenever processed. That would be enough for your use mode engine to make the decision. You should also limit the packet capture to a specific port (80 in your case) so that you don't do extra processing that you don't need.
I have a Windows XP application that is using a driver called TVicHW32 which allows me to create an interrupt handler for OS interrupts. Currently I am using a custom ISA card in an industrial chassis with IRQ 5
The interrupt handler code is working and I can see a variable being incremented so the code that sets up and handles the interrupt is working.
The issue I have is that an IO access call fails to generate any IO activity on the ISA bus. I have an address at 0x308 that is used to trigger a start pulse on the ISA bus interface board.
If I trigger this pulse from the main code, for example, from a timer, the pulse is detected on the ISA bus and the card responds.
If I call the exact same function call to access that IO address from within the interrupt handler, nothing appears on the ISA bus. A logic analyser confirms this.
I have emailed the supplier of the driver but that can't help so I was wondering if anyone here has come across this situation and can offer a solution. This is critical to getting this project working and the only solution I can think of is to develop a custom driver with the DDK but as this requires a steep learning curve, I would hope to find an alternative solution.
Thanks
Dave...
I'm writing a windows utility that communicates to a a USB Device. The driver is a custom driver, supplied by Analog Devices (the manufacturer of the controller chip used in the device).
I've adapted one of their example Windows apps for communcicating with the device. Communication is done via named pipes, and can be synchronous or asynchronous. The problem I've found during testing is that calls to the WriteFile api function can sometimes fail to return if the device is switched off during a write (the device has a hard power switch). The same thing is observed using async or sync calls - I see no timeout happening when using aysnc.
After this has happened, I need to restart my app, as the thread dealing with USB communications is hung.
Is there a way I can prevent the WriteFile from failing to return in this case?
Thanks
Tom Davies.
You can cancel IO operations using CancelSynchronousIo and CancelIoEx. You could do this if you detect that your comm thread is unexpectedly blocking during writes.
Possible deal breakers:
Available only in Windows Vista and newer
Driver has to support cancellation
I'd like to call my app from my driver when an interesting event happens in the Windows kernel. I need to be able to pass at least 4 bytes of data back to user mode. How to achieve this? These events might happen quite, but not too, often, so I don't want to build a queue system and use IOCTLs.
I was thinking of something like the driver gets loaded, the user mode app registers its callback using IOCTL and kernel keeps calling that callback when events happen and finally the user mode client unregisters the callback and no more data is send to user mode. Is this possible?
I'm new to kernel programming, so after a day of googling I decided to ask here. I've noticed that there isn't much discussion about the kernel and drivers. And even less proper docs.