How windows drivers talk to Hardware? - windows

I am curious about the different ways windows drivers interact with the hardware. For example, some drivers might use a function, others a macro, and others might hard-code the register addresses directly into their code. There are probably other ways as well.
Can someone please let me know about the different ways of interaction.
Also, I would like to know, given a particular driver, How can we find out how is it interacting, if we have all the source files including the .vcxproj and other binaries. ?
Any help is really appreciated.
TIA. :-)

It depends on the type of device. for example, if it is a generic PCI Device then the access to the hardware is done "directly" to the HW, meaning Windows map the PCI MMIO to some virtual address and the driver interacts with it.
Microsoft recommended using HAL Function in order to prevent issues with compiler optimization, e.g. to use READ_REGISTER_UCHAR() macro to read BYTE from a device register.
USB, for example, is a subsystem that has a big stack and there is a USB controller that manages access to the device. so, in this case, you will need to use a function to access the device register.
You can find a lot of Microsoft driver samples in GitHub

Related

Using WinUSB within a DLL?

I'm working on a USB device that will talk to a single application. It looks like we may want to have a Windows driver that presents a nicer software interface to the application. (As opposed to having the application itself send lower-level commands to the device via WinUSB.)
Is it possible to use WinUSB from within a DLL? Choosing a driver model for developing a USB client driver doesn't address that specifically.
Are there reasons in this situation that I should instead consider writing a UMDF-based or KMDF-based driver, or a hybrid driver that calls WDM routines?
Using WinUSB is probably the right way to go. You can definitely use WinUSB within a DLL. In general, you can write a DLL that calls functions in another DLL, and there is nothing special about winusb.dll that prevents you from doing that. Also, it is already done in other projects like libusb and libusbp, which compile to a DLL that uses winusb.dll.
I would also encourage you to make your code cross-platform: don't call WinUSB directly from your DLL, but instead use a USB abstraction library such as libusb or libusbp. Even if you only want to support Windows, these libraries are lot easier to use than SetupAPI and WinUSB, so they should save development time. They will also save a lot of time if you ever want your code to work on different operating systems.
I think the only reason to write your own UMDF or KMDF driver in a situation like this is if you need advanced features of the Windows USB stack that are not supported by WinUSB. For instance, if you needed to switch your device to a different USB configuration, or do tricky stuff with power management, or allow multiple applications to use the device at once. If you just want to send some data back and forth, WinUSB is a fine choice.

How do you get a struct device for a Linux character device

I have a Linux kernel module that implements a character device driver. I've read through Linux Device Drivers and followed several tutorials. At this point, I have a simple module that provides open, release, and write file operations.
I'm trying to use the Generic DMA Layer to create a streaming DMA mapping. I'm confused by the following excerpt from LDD:
Many of the functions below require a struct device. This structure
is the low-level representation of a device within the Linux device
model. It is not something that drivers often have to work with
directly, but you do need ot when using the generic DMA layer.
Usually, you can find this structure buried inside the bus specific
that describes your device. For example, it can be found as the dev
field in struct pci_device or struct usb_device.
I read further into the Linux device model, and encountered the following:
At the lowest level, every device in a Linux system is represented by
an instance of struct device.
How can I get the struct device for my character device? Is there one being created for me behind the scenes, or do I need to create it?
I tried manually creating a class with class_create() and then using that to create a device with device_create(), but when I used that device to set up DMA mappings I think I just got a bogus address. Is this the correct approach?
For a little bit more information about my platform, I'm working on the Altera SoCFPGA platform (ARM), so my device isn't a true hardware device like a USB or PCI device, but rather logic implemented in an FPGA.
I found a lot of info in Chapter 14 of LDD that I think may be relevant (buses, devices, drivers, etc.), but I'm just not sure when or how to use it. To me, it seems like that chapter is discussing a lot of data structures that all devices and drivers use, but I'm confused because I haven't had to make use of any of it.
I ended up creating a platform driver and platform device. The platform device struct has it's own struct device associated with the platform bus, which is a 'pseudo-bus' designed exactly for things like this. The official documentation for platform drivers was helpful here.
In the end, my module ended up implementing both a platform driver and a character device driver. The part that gave me the most trouble was creating a platform device and associating it with my platform driver. I started by just manually creating the device (at module install time) with platform_device_alloc and platform_device_register. Once I had this working I ended up removing the manual device creation and instead relying on a device tree entry to create my device.
It depends. In one cases you may get device created by core, in other you have to do that. (I think you are at first group)
Device pointer you are using for DMA should represent the device which does actual DMA in hardware. So, your approach is wrong there.
It might be good to pre-order LDD4.
I ran into exactly this as well. This is hardly a complete answer, but it seems that the underlying assumption in most of these docs is that basic character devices (that aren't instantiated by some higher-level bus driver etc.) won't need access to DMA. I found another shortcut to get what I needed without a struct device, but it looked like you could create your own device using device_register() or similar.
It is maybe a six years old the answer, but because you are doing your own driver, you could later use the function device_create from Linux header include/linux/device.h to create dynamically not only your device in /dev/ folder, but it would also return a pointer to a struct device that you can use later on in the creation of a DMA mapping as the book suggest.
I found particular useful this video in case that the information of the book is not enough to get the variables that you need for the device_create function. How to create a Linux Character Driver

How do I create a virtual gamepad?

How would I go about creating a "gamepad" which appears to DirectInput applications as a normal game controller but the state of its controls is actually defined by software?
Write a device driver to pretend to be one.
Specifically, Windows device drivers handle what are called Interrupt Requests via the Interrupt Request Protocol - which boils down to a wrapped up structure and a set of buffers internally in the driver.
Now the next thing you need to know is that many drivers are actually layered, or stacked, or whichever name you want to use. So for example to write a disk driver, you might interface with the driver above it (as a disk class) but use a driver below it (scsi port, for example) to actually send commands to your devices.
That's how real devices work. Fake devices need to conform to the top level interface requirements, e.g. a disk, or a controller, or a mouse, or whatever it is. However, underneath they can do anything they like - return whatever values they like.
This opens up the possibility of controlling a driver via a user-mode application and pretending to "be" a device. To send a driver messages, you can DeviceIoControl to it; then to actually get those messages you can either:
Stuff them in the Irp that makes up that DeviceIoControl.
Have the driver read them out of your process' memory space.
Drivers can also access \\Registry\\Machine and various other, non-user-specific non-explorer registry areas, so it is possible to communicate that way.
Finally, there's no saying you can't filter existing IO, rather than make it all up via a new device. There are a great many options and ways you can go about doing this.
If you're going to do this, you'll need:
VirtualKD or an expensive debugger cable and two PCs.
You probably also want to start with the references on this blog post. You'll find that there are essentially a bazillion different names for driver code, so I'll interpret some of them:
WDM = Windows Driver Model, basically the NT driver model mixed with (some of) Windows 9x.
KMDF = Kernel mode driver framework - drivers of the above type use this, plus additionally WDF (Windows Driver Foundation) which is a set of libraries on top of WDM to make it quicker to use.
UMDF = User mode driver framework - write a driver without the danger of kernel mode. If you can, use this, as kernel mode drivers that go wrong will bluescreen (in driver parlance, bugcheck) your system.
Edit: I'm not massively knowledgeable on DirectInput - there may be a way to override the various API controls in use via DLL redirection and the like, which may be simpler than the way I've described.
There is vJoy opensource project: http://sourceforge.net/projects/vjoystick/ - can be worth looking at.
The easiest solution may be to emulate an XInput device (Xbox 360 and One). These are supported in most modern games and the set up is very simple. Here is a C++ project here that provides this without any installed drivers or external dependencies: https://github.com/shauleiz/vXboxInterface/
I know it is an old question but for anyone which is interested in this topic it is also worth looking at this project called ViGEm.
You can emulate some well known gamepads like Microsoft Xbox 360 Controller, Sony DualShock 4 Controller and Microsoft Xbox One Controller. The project offers also some API to interact with these virtual controllers. E.g. the C# API can be found here
The simplest solution I found was using vJoy and its C# wrapper.
You need to download the vJoy driver from here.
You can use the vJoy SDK for implementing a feeder program: https://github.com/njz3/vJoy/tree/master/SDK/c%23
Use the C# starter project for this, or simply add the two .dll-s to your existing project as references from the x86 or x64 folder.
You can find instructions on how to use the api in the readme.odt file.

Device driver without the device?

I'm creating an application that needs to use some kernel level modules, for which I've divided the app into 2: one user-level program and one kernel level program.
After reading about device drivers and walking through some tutorials, I'm a little confused.
Can there be a device driver without any specific device associated with it? Is there anything other than the device driver (kernel code or something) which works in kernel mode?
How do anti-virus programs and other such applications work in kernel mode? Is device driver the correct way or am I missing something?
Yes, device drivers can work without an actual piece of hardware (i.e. the device) attached to the machine. Just think of the different programs that emulate a connected SCSI drive (CD-ROM, whatever) for mounting ISO images. Or think about TrueCrypt, which emulates (removable) drives using containers, which are nothing more than encrypted files on your hard drive.
A word of warning, though: Driver development requires much more thought and has to be done more carefully, no shortcuts, good testing and in general expects you to know quite a good deal about the Windows driver model. Remember that faulty and poor drivers put the whole system's stability in jeopardy.
Honestly, I don't think reading a tutorial is sufficient here. You might want to at least invest in a decent book on that subject. Just my 2 cents, though.
Sorry, but the Windows Internals book is more of a general reading for the curious. I cannot recommend it if you want to engage in driver development - or at most as prerequisite reading to understand the architecture. There are plenty of other books around, although most of them are a bit older.
Depending on your goal, you may get away with one of the simpler driver models. That is not to say that driver development is trivial - in fact I second all aspects of the warning above and would even go further - but it means that you can save some of the more tedious work, if instead of writing a legacy file system filter you'd write one based on the filter manager. However, Windows XP before SP2 did not have it installed by default and Windows 2000 would require SP4+SRP+patch if I remember correctly. WDF (Windows Driver Foundation) makes writing drivers even easier, but it is not suitable for all needs.
The term device is somewhat of bad choice here. Device has a meaning in drivers as well, and it does not necessarily refer to the hardware device (as pointed out). Roughly there is a distinction between PDOs (physical device objects) and CDOs (control device objects). The latter are usually what you get to see in user mode and what can be accessed by means of CreateFile, ReadFile, WriteFile, DeviceIoControl and friends. CDOs are usually made visible to the Win32 realm by means of symbolic links (not to be confused with the file system entities of the same name). Drive letter assignments like C: are actually symbolic links to an underlying device. It depends on the driver whether that'd be a CDO or PDO. The distinction is more of a conceptual one taught as such in classes.
And that's what I would actually recommend. Take a class about Windows driver development. Having attended two seminars from OSR myself, I can highly recommend it. Those folks know what they're talking about. Oh, and sign up to their mailing lists over at OSR Online.
Use Sysinternals' WinObj to find out more about the device and driver objects and symlinks.
As for the question about AVs, yes they use file system filter drivers (briefly mentioned above). The only alternative to a full-fledged legacy FSFD is a mini-filter.
It is possible to load a special kind of DLL in kernel mode, too. But in general a driver is the way into the kernel mode and well documented as such.
Books you may want to consider (by ISBN): Most importantly "Programming the Windows Driver Model" (0735618038), "Windows NT Device Driver Development" (1578700582), "Windows NT File System Internals" (0976717514 (OSR's new edition)), "Undocumented Windows NT" (0764545698) and "Undocumented Windows 2000 Secrets" (0201721872) - and of course "Windows NT/2000 Native API Reference" (9781578701995) (classic). Although the last three more or less give you a better insight and are not strictly needed as reading for driver developers.
Anti-virus (and system recovery) software generally make use of file-system filter drivers. A device can have multiple filter drivers arranged like a stack, and any event/operation on this device has to pass through all the stacked up drivers. For example, anti-viruses install a filter driver for disk device so that they can intercept and scan all file system (read/write) operation.
As mentioned in above post, going through a good book would be a nice way to start. Also, install DDK/WDK and refer the bundled examples.

Controlling the USB from Windows

I know this probably is not the easiest thing to do, but I am trying to connect Microcontroller and PC using USB. I dont want to use internal USART of Microcontroller or USB to RS232 converted, its project indended to help me understand various principles.
So, getting the communication done from the Microcontroller side is piece of cake - I mean, when I know he protocol, its relativelly easy to implement it on Micro, becouse I am in direct control of evrything, even precise timing.
But this is not the case of PC. I am not very familiar with concept of Windows handling the devices connected. In one of my previous question I ask about how Windows works with devices thru drivers. I understood that for internal use of Windows, drivers must have some default set of functions available to OS. I mean, when OS wants to access HDD, it calls HDD driver (which is probably internal in OS), with specific "questions" so that means that HDD driver has to be written to cooperate with Windows, to have write function in the proper place to be called by the OS. Something similiar is for GPU, Even DirectX, I mean DirectX must call specific functions from drivers, so drivers must be written to work with DX. I know, many functions from WinAPI works on their own, but even "simple" window must be in the end written into framebuffer, using MMIO to adress specified by drivers. Am I right?
So, I expected that Windows have internal functions, parts of WinAPI designed to work with certain comonly used things. To call manufacturer-designed drivers. But this seems to not be entirely true becouse Windows has no way to communicate thru Paralel port. I mean, there is no function in the WinAPI to work with serial port, but there are funcions to work with HDD,GPU and so.
But now there comes the part I am getting very lost at. So, I think Windows must have some built-in functions to communicate thru USB, becouse for example it handles USB flash memory. So, is there any WinAPI function designed to let user to operate USB thru that function, or when I want to use USB myself, do I have to call desired USB-driver function myself? Becouse all you need to send to USB controller is device adress and the infromation right? I mean, I donĀ“t have to write any new drivers, am I right? Just to call WinAPI function if there is such, or directly call original USB driver. Does any of this make some sense?
To make your life easier, and avoid writing your own driver, try using the HID (Human Interface Device) API on top of USB. Although it says "Human Interface", it doesn't actually have to be for devices that a human controls. The advantage is that modern OSes already come with a HID driver and you can use sample code such as what you can find here to get started. Many microcontroller manufacturers provide suitable code for the embedded of the protocol.
Because OSes already understand HID, if you build a device using the HID interface you'll find that not only can you read from it from any OS, you may also find that many applications can already talk to your device if its communication is restricted to a small enough subset of HID. (For example, I built an input device for a music app, but amazingly I found I could literally plug it straight into a 3D animation app we use at work, running on a different OS, and have it work right away without writing a single additional line of code!)
This answer might aim you in the right direction.
The first answer here might also be helpful.
The answers to this have some actual code and links to yet other resources.
USB includes a set of stock functionality, much like supporting USB flash drives (USB Mass Storage class). The two most interesting for microcontroller interfacing are HID and CDC. CDC is easiest to use as it directly emulates an old fashioned serial port.
If you configure the microcontroller to act as a CDC device, Windows will enumerate it as a serial port, and all the old serial APIs will work on it.

Resources