1

EDIT: through another question on the forum, I learned that DeviceIoControl can be async, so question 4 is now just question 2

The extensive Windows driver documentation says little, that I've found, about how a client user-mode app can communicate directly to a specific device. I understand that normally such operations are managed by the Win32 api, but in the case of specific devices or (what I'm interested in) software drivers, I don't know many ways in which it can be done

The docs say that one can use CreateFile, ReadFile, WriteFile etc. to "open" the driver as a "file" and then r/w from/to it, maybe asynchronously if you want. That sounds good but it feels like that can't be the best option for everything, nor is it the only option. DeviceIoControl can have specific control codes and you can command a driver like that, but I can't see any async capabilities in the docs there.

In the driver docs, it's clear a driver must write its callbacks routines for dispatch calls which are sent to it, but I don't understand where these dispatch calls come from, or how a user-mode client might interact with that directly.

Using Valorant's Vanguard as an example software driver, I highly doubt it just r/w'd from a "file" in operation - it seems too abstract to be fast, or not specific enough for a complex system, as all you can do in fileapi.h is read, and write, without any real parametrisation - right?

My questions are:

  1. Must a software driver write routines for all dispatch calls that the docs recommend even though they have nothing to do with hardware?

  2. Are there other techniques than the R/W file api and the DeviceIoControl function to communicate with a specific (software) driver?

  3. Are there efficient, "lean and mean" solutions, when our software driver is entirely custom to the targeted user app, as Vanguard was?

  4. (ignore) Are the async R/W file operations the only way to get this done in a multi-threaded async manner, where the client submits many possibly overlapping calls, or can DeviceIoControl leverage threading and asynchronicity?

FShrike
  • 323
  • 1
  • 10
  • 1
    Straight from the [DeviceIoControl](https://learn.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol) documentation: *"To retrieve a device handle, use the [CreateFile](https://learn.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea) function. For more information, see Remarks."* The *Remarks* section seems to answer your question. – IInspectable Feb 22 '21 at 11:30
  • @IInspectable ... I ask if this is the only way, and retrieving a device handle was not part of the question! – FShrike Feb 22 '21 at 11:32
  • @IInspectable are software driver developers limited to making their interfaces only accept bytestream r/w or DeviceIoControl calls? – FShrike Feb 22 '21 at 11:34
  • 1
    Download Windows Driver Kit - WDK to develop drivers. There are examples of blank drivers for most peripheral devices. – i486 Feb 22 '21 at 11:48
  • @i486 I don't care about peripheral devices – FShrike Feb 22 '21 at 11:55
  • @i486 I don't know very much at all, which is why I ask humbly about software drivers and the specific mechanisms for user-mode communications - maybe read the question fully before attacking me. To me, "peripheral devices" refers to things like mice and keyboards and headsets; if it pertains to software drivers communicating in user space too, perhaps you should have said – FShrike Feb 22 '21 at 12:00
  • @IdioticShrike And I tell you to install WDK and read its documentation and API-s. Probably you will find answer for some of your questions. I guess you don't know what is WDK (aka DDK). – i486 Feb 22 '21 at 12:06
  • @i486 I've installed the WDK and I don't know where in the mess of samples (that I have to separately download ?) I might find what I'm looking for - all my questions can be answered in a single sentence each, with a reference to an API of some sort – FShrike Feb 22 '21 at 12:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229038/discussion-between-idiotic-shrike-and-i486). – FShrike Feb 22 '21 at 13:04

1 Answers1

1

To answer your questions

  1. No. Not all dispatch calls needs to be implemented for a software driver. I think only CREATE/CLOSE/DEVICE CONTROL needs to be implemented. You dont even need to implement unload but then you will not be able to unload the driver, which is required for testing. If there are any other required dispatch methods, you can simply return not implemented from those implementation.

  2. Yes. You can use named pipe between driver and application as another way to communicate.

  3. Not sure how much more lean can you get than just implementing the minimum dispatch methods.

  4. You can use multiple threads and synchronous operations OR you can use single thread and asynchronous operation. Depends on what model is best for you.

Security Guard
  • 414
  • 2
  • 7
  • Thank you so much for taking the time to actually read my question! Query about answer 4: can a driver be instanced or exist for each of the multiple threads so each thread can access its “bit”, or is there only one object/service that threads must queue up to use – FShrike Feb 23 '21 at 23:54
  • When you call CreateFile or OpenFile, each thread that called the function to open your driver owns that handle. So if you have multiple threads that call CreateFile/OpenFile on your driver, they will all get their own handle that they can operate independently on. For eg the following function can be called from multiple threads at the same time :- ``` void TalkToDriver() { HANDLE hDriver = CreateFile("Driver"): DeviceIoCtrl(hDriver): CloseFile(hDriver); } – Security Guard Feb 25 '21 at 00:58
  • Sorry to bother, (thank you for your time so far)... I noticed that in the only WDK sample I've taken the time to understand so far, the driver was only accessed with CreateFile and DeviceIoControl after being created first as a running service. Is this is necessity - must all drivers be first running as a service to be used? And is the notion of a service the only way for a driver to be in execution - I'm pretty sure a driver can't be loaded with CreateProcess but is there another paradigm? – FShrike Feb 25 '21 at 10:28
  • 1
    That is correct. You have to tell the operating system that the file you compiled is a driver and the only way to tell that to windows is by creating a service. While creating a service you can specify if the driver is loaded automatically during boot, or is a demand load driver and if it can be unloaded. This is an important step and needs to be done only once. BTW - I hope you are using virtual machine to test your driver and not loading it on your development box. – Security Guard Feb 25 '21 at 18:47
  • 1
    As for it is the only way, the answer is not. If you do not want to create service, you will have to specify the INF file (which is a configuration file) for your driver. Windows can parse the INF file and will create a service entry for you. This is more complicated way and generally creating service is the preferred way for software only driver. – Security Guard Feb 25 '21 at 18:49
  • Thank you I am done with the questions now! You've helped me immeasurably – FShrike Feb 25 '21 at 20:35