Call WdfDriverCreate with a modified RegistryPath

Hello,

I have full source code of a very old driver written in WDM.
Attached the code of : DriverEntry
As you can see, the driver’s name is set by IoCreateDevice:

// Controller device name
RtlInitUnicodeString(&ustrNtDeviceName, MG_NT_DEVICE_NAME);

	// Create controller device
	ntStatus = IoCreateDevice(pDrvObj, 0, &ustrNtDeviceName, MG_DRV_DEVICE_TYPE, FILE_DEVICE_SECURE_OPEN, TRUE, &pDvcObj);
...

I have to rewrite the driver in WDF but I cannot change anything in the interface to the user level application.
In the application, the driver is opened with:

m_hDriver = CreateFileW(L"\\.\" MG_DRV_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

In WDF the driver’s name is set also in DriverEntry by:

status = WdfDriverCreate( DriverObject,
RegistryPath,
&attributes,
&config,
WDF_NO_HANDLE);

My question is:
Can I modify RegistryPath and set a name as in the old driver ?

Thank you,
Zvika

Drivers do not have names. Devices have names. The equivalent of IoCreateDevice is WdfDeviceCreate, and you’ll find that WdfDeviceInitAssignName does what you want.

Hi Tim, All,

In the echo sample I added:

#define MG_DRV_NAME L"MgdDrv"
#define MG_NT_DEVICE_NAME L"\Device\" MG_DRV_NAME

DECLARE_CONST_UNICODE_STRING(ntDeviceName, MG_NT_DEVICE_NAME);

status = WdfDeviceInitAssignName(DeviceInit, &ntDeviceName);
if (!NT_SUCCESS(status))
{
return status;
}
KdPrint((“WdfDeviceInitAssignName. status=%d\n”, status));

just before:

status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);

The status for all calls is 0.

The driver was successfully installed with: devcon install echo.inf root\ECHO

So the device name is:

L"\Device\MgdDrv"

What is the device name I should use in the application ?
Currently the name in the legacy application is:

L"\\.\MgdDrv"

But CreateFileW returned -1.

Thank you,
Zvika

Hi Tim, All,

Base on this link:
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdfdevice/nf-wdfdevice-wdfdevicecreatesymboliclink

I used the following code:

#define SYMBOLIC_NAME_STRING L"\DosDevices\NONPNP"
DECLARE_CONST_UNICODE_STRING(symbolicLinkName, SYMBOLIC_NAME_STRING);

status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);

status = WdfDeviceCreateSymbolicLink(device, &symbolicLinkName);
if (!NT_SUCCESS(status))
{
return status;
}

In the application I used the following code:
#define MONITOR_DOS_NAME L"\\.\NONPNP"
m_hDriver = CreateFileW(MONITOR_DOS_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

This time I got a valid handle.

Can you please approve that this is the right solution ?

Best regards,
Zvika

I am curious to know why you didn’t just cut-and-paste the name string from your other driver. If that worked, then it will work for you.

The \.\ alias in user mode maps to the \DosDevices tree in kernel mode. The \Device tree is only available in kernel mode. And yes, the correct path is to create a symbolic link inside \DosDevices.

BTW, I originally wrote this up with a caution about backslashes, but after seeing my own post, I now see that the markdown editor “helpfully” changes double backslashes to single. Thus, I will assume that your code was actually correct to begin with.

For future generations, the code actually needed to be:
#define SYMBOLIC_NAME_STRING L"\ \ D o s D e v i c e s \ \ N O N P N P"
and
#define MONITOR_DOS_NAME L"\ \ \ \ . \ \ N O N P N P"

Hi Tim,

Thank you very much !
Zvika

Drivers do not have names
Not so fast.
DRIVER_OBJECT.DriverName

The other thing you’ll want to be careful of, is that when you create a named WDFDEVICE in KMDF, the protection on that Device Object is set to only allow admins to open it by name. This is different from the WDM equivalent.

To make the device that you create accessible to all users, without having to run accessing apps “as admin” assign an appropriate ACL to the device object. See https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdfdevice/nf-wdfdevice-wdfdeviceinitassignsddlstring

Peter

Not so fast. DRIVER_OBJECT.DriverName

For the purposes of this tutelage, I’ll stand by what I said. Drivers do not have ASSIGNABLE names. Driver names are not generally useful. The driver name is not what he wanted.

2 Likes

Drivers do not have ASSIGNABLE names.
I like precision!

If you like precision, then you’ll realize that – of COURSE drivers have ASSIGNABLE names. If the name wasn’t ASSIGNABLE it wouldn’t HAVE a name.

Driver Objects have names in the Object Manager namespace, assigned when the driver is loaded, by the I/O Manager. The Object Manager name is what’s stored in the UNICODE_STRING pointed to by DRIVER_OBJECT.DriverName.

You see… there is a fine line between precision and pedantry. Answering questions from learners is an art that involves understanding what’s asked and not providing too much details. That is very difficult for us engineers. C. S. Lewis has a wonderful quote about this, and about why “two schoolboys”, but not the teacher, can often answer each other’s questions:

When you took the problem to a master, as we all remember, he was very likely to explain what you understood already, to add a great deal of information which you didn’t want, and say nothing at all about the thing that was puzzling you.

Peter

Well, this is clearly a variation on the classic ‘a problem well stated is a problem nearly solved’. But Feynman (Manhattan project, QED) has a quote on this too.
I can’t lay my hands on it just at the moment as my children have been ‘helping’ me ‘reorganize’ my books and papers over the last few weeks in absence of any actual school work. But it runs something like one of his life’s regrets was that as a young man (probably a grad student of some kind) he made a presentation to Einstein and other prominent persons, but that he could not understand or remember their criticism.

Yes, as we try to help others we ought to try as best we can to capitulate the points in ways that we think are most relevant and expedient to the problem in hand, but sometimes the textbook answer is the correct one none the less

of COURSE drivers have ASSIGNABLE names
In kernel mode all memory is ASSIGNABLE in such sense (of course, i know about patchguard, hypervisor and other things to prevent this). You are right - we need to stop somewhere in our precision.