Writing OIDs from IoT User Mode

The question I really need answered, in a nutshell, is what is Microsoft’s sanctioned way to write OID data from user mode IoT, and where is it documented?

Here’s the background:

A while back the topic of sending OID data came up in this thread:
https://community.osr.com/discussion/290232/issue-in-sending-data-buffer-using-deviceiocontrol-in-win10-iot

I’m porting some software from Windows CE to Windows 10 IoT Core, and there’s a user-mode component that needs to be able to send OID data down the NDIS stack. There seem to be two general approaches to this:

  1. Use WMI.
  2. Use DeviceIoControl() with ndisuio.

In the original thread, Doron Holan stated, “there is no WMI on IoT.” If true, that takes option 1 off the table.

Option 2 is a little strange in that I’ve only seen this documented for Windows CE. There is a driver named ndisuio.sys on Windows 10 desktop as well as Windows 10 IoT Core, but I have found no documentation on the web nor supporting headers in the SDK.

There’s a ndisprot sample at: https://github.com/Microsoft/Windows-driver-samples/tree/master/network/ndis/ndisprot/6x

Thinking that ndisuio.sys might be very nearly the same, I attempted to use ndisuio.sys with the IOCTLs and structures defined in that project, but with no success. From browsing the binary in a hex editor, I guessed that I might be able to call CreateFile() with either \\.\WwanProt or \\.\NdisUio as the device name; the former succeeds, the latter fails with a file share error code regardless of the file share parameters passed in. Beyond that point, though, I can’t get an open via DeviceIoControl()/IOCTL_NDISUIO_OPEN_DEVICE to work when the adapter GUID is passed in (I get a general failure error back).

But let’s step back a moment; this is silly. Reverse engineering Windows to find undocumented ways to do things is no path towards a stable application.

There is a third path available to me, I think, and that is to take the ndisprot sample and create my own parallel of the ndisuio.sys driver. It seems like a lot of messing around to do something simple that the OS supports internally, but it’s at least a path that isn’t explicitly unsupported.

My apologies if I’ve overlooked something obvious.

Thanks,
Dave

Reverse engineering Windows to find undocumented ways to do things is no path towards a stable application.

Right. NDISUIO is an implementation detail of the OS. It does happen to share a name and some code lineage from the CE driver of the same name, but its purpose has changed quite a bit.

We don’t generally encourge apps to interface directly with the NIC driver, since that’s usually too low-level and brittle. But with IOT, you do sometimes need to do low-level things.

There’s an ioctl off of \\.\NDIS that is publicly-documented: IOCTL_NDIS_QUERY_GLOBAL_STATS. Despite its name, it lets you issue RequestTypeQueryInformation for any OID, not just statistics.

However, there’s no documented ioctl to set an OID. (The reason is that NDIS doesn’t have any concept of identity for a usermode EXE. E.g., if an EXE tries to change the packet filter, to which protocol should the new packets be delivered? Should NDIS undo the change when the EXE exits?) So if you need to issue set or method type OID requests, you’d have to go the protocol driver route. Except we don’t yet have APIs in place to install 3rd party protocol drivers onto IOT Core. This is a feature we do want to offer, but which hasn’t made it to the top of our backlog yet.

Thanks, Jeffrey, your response is extremely helpful and points out the gap we need to have addressed. This will inform our next steps.

Dave