WdfDeviceCreateDeviceInterface returning status code:c0000010

Hi All,

I have a user mode application and a kernel mode component and both use the same driver. This driver interacts with two DSPs. Lets say usermode application interacts with DSP1 and kernel mode component with DSP2. Initially my driver only had to interact with one DSP (I had only 1 app). I have made some changes to support 2 DSPs and I am facing some problems.

In the usermode application I am saying:
Createfile(TEXT(“\\.\DSP1”, …)

and in the kernel mode I am saying
ZwCreatefile()

In kernel mode I am initializing a UNICODE string:
RtlInitUnicodeString(&DeviceName,L"DSP2")
InitializeObjectAttributes(&attr,&DeviceName)
With the attr I am creating a device using Zwcreatefile.

Coming to my driver:
In the devicadd callback I am performing some initializations like:
DECLARE_CONST_UNICODE_STRING(ntdevicename,L"\Device\DSP1");
DECLARE_CONST_UNICODE_STRING(udevicename1,L"\DosDevices\DSP1");
DECLARE_CONST_UNICODE_STRING(udevicename2,L"\DosDevices\DSP1");

WdfDeviceInitAssignName -> I am assigning ntdevicname to device using this. Then I am creating the device using WdfDeviceCreate. Then WdfDeviceCreateSymbolicLink(Device, &udevicename1) and WdfDeviceCreateSymbolicLink(Device, &udevicename2). Calling create symbolic link twice failed for me. So I removed WdfDeviceCreateSymbolicLink and tried using WdfDeviceCreateDeviceInterface. I called it twice like this:

WdfDeviceCreateDeviceInterface(Device,&GUID,&utdevicename1);
WdfDeviceCreateDeviceInterface(Device,&GUID,&utdevicename2);

The first WdfDeviceCreateDeviceInterface is failing returning c0000010. I have a few questions regarding my approach:

  1. when do I need to use WdfDeviceInitAssignName ? is it necessary?
  2. when do I need to use WdfDeviceCreateSymbolicLink? is it necessary in my case?
  3. Why is WdfDeviceCreateDeviceInterface failing?
  4. In order to use WdfDeviceCreateDeviceInterface do I need to make any changes in my user mode app or kernel mode component. Any example code in user mode level or kernel mode level will be helpful.

Based on the utdevicename1 and utdevicename2 (reference strings) in EvtDeviceFileCreate callback I will either communicate with DSP1 or DSP2. Say in usermode app I make a createfile for DSP1, the EvtDeviceFileCreate in driver will be called .Since I am calling Createfile(TEXT(“\\.\DSP1”, …) I am expecting that when I do a WdfFileObjectGetFileName in EvtDeviceFileCreate , I can compare the filename with the reference string (udevicename1->L"\DosDevices\DSP1). Is my approach right? When I call WdfFileObjectGetFileName will I get DSP1 as the name?In order to use device interface class what are the required changes to be made in my application?

Is this a pnp driver? Decide interfaces are only available to pnp drivers, not legacy style drivers (which create devices in DriverEntry). If you want a second symbolic link, use the wdm apis to create and destroy it. Kmdf supports one symbolic link on a device as that is the common case and not worth the complexity in the framework to manage the rare edge case.

Get Outlook for Androidhttps:

________________________________
From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Tuesday, October 25, 2016 6:45:28 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WdfDeviceCreateDeviceInterface returning status code:c0000010

Hi All,

I have a user mode application and a kernel mode component and both use the same driver. This driver interacts with two DSPs. Lets say usermode application interacts with DSP1 and kernel mode component with DSP2. Initially my driver only had to interact with one DSP (I had only 1 app). I have made some changes to support 2 DSPs and I am facing some problems.

In the usermode application I am saying:
Createfile(TEXT(“\\.\DSP1”, …)

and in the kernel mode I am saying
ZwCreatefile()

In kernel mode I am initializing a UNICODE string:
RtlInitUnicodeString(&DeviceName,L"DSP2")
InitializeObjectAttributes(&attr,&DeviceName)
With the attr I am creating a device using Zwcreatefile.

Coming to my driver:
In the devicadd callback I am performing some initializations like:
DECLARE_CONST_UNICODE_STRING(ntdevicename,L"\Device\DSP1");
DECLARE_CONST_UNICODE_STRING(udevicename1,L"\DosDevices\DSP1");
DECLARE_CONST_UNICODE_STRING(udevicename2,L"\DosDevices\DSP1");

WdfDeviceInitAssignName -> I am assigning ntdevicname to device using this. Then I am creating the device using WdfDeviceCreate. Then WdfDeviceCreateSymbolicLink(Device, &udevicename1) and WdfDeviceCreateSymbolicLink(Device, &udevicename2). Calling create symbolic link twice failed for me. So I removed WdfDeviceCreateSymbolicLink and tried using WdfDeviceCreateDeviceInterface. I called it twice like this:

WdfDeviceCreateDeviceInterface(Device,&GUID,&utdevicename1);
WdfDeviceCreateDeviceInterface(Device,&GUID,&utdevicename2);

The first WdfDeviceCreateDeviceInterface is failing returning c0000010. I have a few questions regarding my approach:
1) when do I need to use WdfDeviceInitAssignName ? is it necessary?
2) when do I need to use WdfDeviceCreateSymbolicLink? is it necessary in my case?
3) Why is WdfDeviceCreateDeviceInterface failing?
4) In order to use WdfDeviceCreateDeviceInterface do I need to make any changes in my user mode app or kernel mode component. Any example code in user mode level or kernel mode level will be helpful.

Based on the utdevicename1 and utdevicename2 (reference strings) in EvtDeviceFileCreate callback I will either communicate with DSP1 or DSP2. Say in usermode app I make a createfile for DSP1, the EvtDeviceFileCreate in driver will be called .Since I am calling Createfile(TEXT(“\\.\DSP1”, …) I am expecting that when I do a WdfFileObjectGetFileName in EvtDeviceFileCreate , I can compare the filename with the reference string (udevicename1->L"\DosDevices\DSP1). Is my approach right? When I call WdfFileObjectGetFileName will I get DSP1 as the name?In order to use device interface class what are the required changes to be made in my application?


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></https:>

Hi Holan,

My driver is a PnP driver. The DeviceAdd routine in my driver is called in response to add device call in the PnP manager. When I do not specify any reference string:
WdfDeviceCreateDeviceInterface(Device,&GUID,NULL);

The device create interface passes! Only by specifying a reference string it is failing. Also I am not planning to use symbolic links. Based on the reference string (third parameter in above call) I want to make a decision to talk to either DSP1 or DSP2

What is the reference string value? Utdevicename is not shown in your code. The pattern you want to use is the right one. Run !wdfkd.wdflogdump (your driver name) after the error is returned to see why. I am guessing it has to do with the format of the ref string

Get Outlook for Androidhttps:

________________________________
From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Tuesday, October 25, 2016 7:44:14 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WdfDeviceCreateDeviceInterface returning status code:c0000010

Hi Holan,

My driver is a PnP driver. The DeviceAdd routine in my driver is called in response to add device call in the PnP manager. When I do not specify any reference string:
WdfDeviceCreateDeviceInterface(Device,&GUID,NULL);

The device create interface passes! Only by specifying a reference string it is failing. Also I am not planning to use symbolic links. Based on the reference string (third parameter in above call) I want to make a decision to talk to either DSP1 or DSP2


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></https:>

xxxxx@gmail.com wrote:

In the usermode application I am saying:
Createfile(TEXT(“\\.\DSP1”, …)

and in the kernel mode I am saying
ZwCreatefile()

In kernel mode I am initializing a UNICODE string:
RtlInitUnicodeString(&DeviceName,L"DSP2")
InitializeObjectAttributes(&attr,&DeviceName)
With the attr I am creating a device using Zwcreatefile.

Just DSP2? Not “\DosDevices\DSP2”?

Coming to my driver:
In the devicadd callback I am performing some initializations like:
DECLARE_CONST_UNICODE_STRING(ntdevicename,L"\Device\DSP1");
DECLARE_CONST_UNICODE_STRING(udevicename1,L"\DosDevices\DSP1");
DECLARE_CONST_UNICODE_STRING(udevicename2,L"\DosDevices\DSP1");

Those two both have the same file name. Were you retyping this, or do
you really have a typo in the driver?

Calling create symbolic link twice failed for me. So I removed WdfDeviceCreateSymbolicLink and tried using WdfDeviceCreateDeviceInterface.

That’s probably a better plan anyway.

I called it twice like this:

WdfDeviceCreateDeviceInterface(Device,&GUID,&utdevicename1);
WdfDeviceCreateDeviceInterface(Device,&GUID,&utdevicename2);

The first WdfDeviceCreateDeviceInterface is failing returning c0000010. I have a few questions regarding my approach:

  1. when do I need to use WdfDeviceInitAssignName ? is it necessary?

Only if you’re going to call the driver by that name from kernel mode.
Most drivers don’t need it.

  1. when do I need to use WdfDeviceCreateSymbolicLink? is it necessary in my case?

Only if you need to access the device by name from user mode using the
\.\xxxx mechanism. If you’re using device interfaces, you’ll use the
SetupDi APIs to find the driver’s file name.

  1. In order to use WdfDeviceCreateDeviceInterface do I need to make any changes in my user mode app or kernel mode component. Any example code in user mode level or kernel mode level will be helpful.

Well, the process of finding the driver’s file name is entirely
different. You can’t just use “\\.\DSP1”. You have to use the
SetupDi APIs to enumerate the devices that implement your device
interface. SetupDiGetClassDevs, then SetupDiEnumDeviceInterfaces, then
SetupDiGetDeviceInterfaceDetail. That gives you the base driver file
name. You then append the reference string, and pass that to CreateFile.

For your kernel code, you use WdfIoTargetQueryForInterface to find the
symbolic link.

Based on the utdevicename1 and utdevicename2 (reference strings) in EvtDeviceFileCreate callback I will either communicate with DSP1 or DSP2. Say in usermode app I make a createfile for DSP1, the EvtDeviceFileCreate in driver will be called .Since I am calling Createfile(TEXT(“\\.\DSP1”, …) I am expecting that when I do a WdfFileObjectGetFileName in EvtDeviceFileCreate , I can compare the filename with the reference string (udevicename1->L"\DosDevices\DSP1). Is my approach right?

No. When you create a device interface, WDM creates a new symbolic link
for you, with a long name based on the hardware identifier and the
device interface GUID. Something like
\?\usb#vid_1a45&pid_2001#00a0720001-001#{3a8db48f-e27d-49c9-a7a9-90cde2dbfc0e}.
You fetch that name using the SetupDi interfaces I mentioned above. To
that, you will then append your reference string, making
\?\usb#vid_1a45&pid_2001#00a0720001-001#{3a8db48f-e27d-49c9-a7a9-90cde2dbfc0e}\DSP1.
That’s the file name you’ll pass to CreateFile.

When I call WdfFileObjectGetFileName will I get DSP1 as the name?

You will get \DSP1. The filename passed to the driver is everything
past the symbolic link name.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim Roberts wrote:

xxxxx@gmail.com wrote:
> Coming to my driver:
> In the devicadd callback I am performing some initializations like:
> DECLARE_CONST_UNICODE_STRING(ntdevicename,L"\Device\DSP1");
> DECLARE_CONST_UNICODE_STRING(udevicename1,L"\DosDevices\DSP1");
> DECLARE_CONST_UNICODE_STRING(udevicename2,L"\DosDevices\DSP1");
Those two both have the same file name. Were you retyping this, or do
you really have a typo in the driver?

By the way, your driver will not be able to tell the difference between
those two. The symbolic link name is stripped off of the file name
handed to the driver. Think about a file system driver, for example.
It doesn’t care what it’s drive letter is. If it is mounted on C: and
the user requests C:\Tmp\abc.txt, all the file system driver receives is
\Tmp\abc.txt.

So, you could have created one symbolic link (\DosDevices\MyDsp), and
then opened it from user mode as \.\MyDsp\Dev_1 and from kernel mode as
\DosDevices\MyDsp\Dev_2. That way, your driver will receive \Dev_1 or
\Dev_2 as the file name.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc

https://blogs.msdn.microsoft.com/doronh/2006/08/18/how-do-i-know-which-device-interface-is-being-opened/
https://blogs.msdn.microsoft.com/doronh/2006/08/23/how-do-i-know-which-symbolic-link-is-being-opened/

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, October 25, 2016 10:26 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WdfDeviceCreateDeviceInterface returning status code:c0000010

Tim Roberts wrote:
> xxxxx@gmail.com wrote:
>> Coming to my driver:
>> In the devicadd callback I am performing some initializations like:
>> DECLARE_CONST_UNICODE_STRING(ntdevicename,L"\Device\DSP1");
>> DECLARE_CONST_UNICODE_STRING(udevicename1,L"\DosDevices\DSP1");
>> DECLARE_CONST_UNICODE_STRING(udevicename2,L"\DosDevices\DSP1");
> Those two both have the same file name. Were you retyping this, or do
> you really have a typo in the driver?

By the way, your driver will not be able to tell the difference between those two. The symbolic link name is stripped off of the file name handed to the driver. Think about a file system driver, for example.
It doesn’t care what it’s drive letter is. If it is mounted on C: and the user requests C:\Tmp\abc.txt, all the file system driver receives is \Tmp\abc.txt.

So, you could have created one symbolic link (\DosDevices\MyDsp), and then opened it from user mode as \.\MyDsp\Dev_1 and from kernel mode as \DosDevices\MyDsp\Dev_2. That way, your driver will receive \Dev_1 or
\Dev_2 as the file name.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Hi @Tim and @Doron,

Thanks for your valuable suggestions. It cleared a lot of questions . Thanks a ton

@Tim,

> DECLARE_CONST_UNICODE_STRING(udevicename1,L"\DosDevices\DSP1");
> DECLARE_CONST_UNICODE_STRING(udevicename2,L"\DosDevices\DSP1");

It was a typo , in my code it is L"\DosDevices\DSP2")

Also like you suggested since I am creating one file in kernel and other in user mode , I have decided to open from user mode and kernel mode with two different names instead of working with device interfaces.

So taking your suggestion , from the usermode app I am making a call:
Createfile(Createfile(TEXT(“\\.\DSP1”, …)

and in my deviceadd callback in my driver I am assigning a symbolic name like this:
WdfDeviceCreateSymbolicLink(Device,&userDeviceName) where userDeviceName is L"\DosDevices\DSP1

For kernel mode I am making a call:
ZwCreateFile() with device name L"\Device\DSP2

and in my deviceadd in my driver I am calling WdfDeviceInitAssignName and assigning a name
L"\Device\DSP2 to the device.

So when I try to open from user mode , since the symbolic name is the same as the name that I am opening during createfile it should call devicefilecreate in my driver and for kernel mode since the name in WdfDeviceInitAssignName is same as the one that I have initialized in zwcreatefile it should call devicefilecreate in my driver. Am I right?

However, I am facing a problem . In the devicefilecreate callback with the help of the fileobject I am trying to retrieve the filename using this piece of code:

fileName = WdfFileObjectGetFileName(WdfRequestGetFileObject(Request));

With The help of the filename I want to either communicate with DSP1 or DSP2.
But the filename is returning NULL! Is this the right way to retrieve filename? In my deviceadd callback I have also made this call WdfDeviceInitSetFileObjectConfig.

Reread the second link I sent. You need your symbolic link to point to a path under the device name

Bent by my phone


From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Wednesday, October 26, 2016 7:23:57 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WdfDeviceCreateDeviceInterface returning status code:c0000010

Hi @Tim and @Doron,

Thanks for your valuable suggestions. It cleared a lot of questions . Thanks a ton

@Tim,
>> DECLARE_CONST_UNICODE_STRING(udevicename1,L"\DosDevices\DSP1");
>> DECLARE_CONST_UNICODE_STRING(udevicename2,L"\DosDevices\DSP1");

It was a typo , in my code it is L"\DosDevices\DSP2<file:>“)

Also like you suggested since I am creating one file in kernel and other in user mode , I have decided to open from user mode and kernel mode with two different names instead of working with device interfaces.

So taking your suggestion , from the usermode app I am making a call:
Createfile(Createfile(TEXT(”\\.\DSP1", …)

and in my deviceadd callback in my driver I am assigning a symbolic name like this:
WdfDeviceCreateSymbolicLink(Device,&userDeviceName) where userDeviceName is L"<file:></file:>\DosDevices\DSP1

For kernel mode I am making a call:
ZwCreateFile() with device name L"<file:></file:>\Device\DSP2

and in my deviceadd in my driver I am calling WdfDeviceInitAssignName and assigning a name
L"<file:></file:>\Device\DSP2 to the device.

So when I try to open from user mode , since the symbolic name is the same as the name that I am opening during createfile it should call devicefilecreate in my driver and for kernel mode since the name in WdfDeviceInitAssignName is same as the one that I have initialized in zwcreatefile it should call devicefilecreate in my driver. Am I right?

However, I am facing a problem . In the devicefilecreate callback with the help of the fileobject I am trying to retrieve the filename using this piece of code:

fileName = WdfFileObjectGetFileName(WdfRequestGetFileObject(Request));

With The help of the filename I want to either communicate with DSP1 or DSP2.
But the filename is returning NULL! Is this the right way to retrieve filename? In my deviceadd callback I have also made this call WdfDeviceInitSetFileObjectConfig.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></file:>

It looks like you are breaking the device interface concept.

Imagine that your code is working and a second device with the same ID appears on the system. Than your EvtDriverDeviceAdd routine would run again and try to create symlinks that already exist (because of the first run) and fail.

But if you just create a device interface (without a reference string because reference strings are used to distinguish between instances), the PNP Manager would just register a new instance of the same interface anytime a device with your device’s ID is enumerated. So your EvtDriverDeviceAdd would be able to run and succeed 10 times if needed without failing.

Have you looked at IoGetDeviceInterfaces to open the device from kernel mode ?

PS: my guess is that WdfDeviceCreateDeviceInterface fails because the reference string contains a '' character which is prohibited. You need to look at IoRegisterDeviceInterface to know about this.

xxxxx@gmail.com wrote:

So when I try to open from user mode , since the symbolic name is the same as the name that I am opening during createfile it should call devicefilecreate in my driver and for kernel mode since the name in WdfDeviceInitAssignName is same as the one that I have initialized in zwcreatefile it should call devicefilecreate in my driver. Am I right?

It does.

However, I am facing a problem . In the devicefilecreate callback with the help of the fileobject I am trying to retrieve the filename using this piece of code:

fileName = WdfFileObjectGetFileName(WdfRequestGetFileObject(Request));

With The help of the filename I want to either communicate with DSP1 or DSP2.
But the filename is returning NULL!

Right, which is exactly what I told you would happen. The file name
passed to the driver has the base name stripped out. If you define nine
different symbolic links, the driver has absolutely no way of telling
which one was used. That is why I suggested that you create a single
symbolic link (like \DosDevices\MyDSP). Then, when you want to use
DSP1, you can open the file \.\MyDSP\DSP1 . When you want to use DSP2,
you can open the file \.\MyDSP\DSP2. WdfFileObjectGetFileName would
then have either \DSP1 or \DSP2.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Sorry, the WDF equivalent of IoGetDeviceInterfaces is WdfDeviceRetrieveDeviceInterfaceString.

No, it is not an equivalent. The Io call gets all instances of the interface, there is no kmdf wrapper for it. The Wdf call returns the specific instance string.

Bent by my phone


From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Thursday, October 27, 2016 7:42:23 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WdfDeviceCreateDeviceInterface returning status code:c0000010

Sorry, the WDF equivalent of IoGetDeviceInterfaces is WdfDeviceRetrieveDeviceInterfaceString.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

>No, it is not an equivalent. The Io call gets all instances of the interface, there is no kmdf wrapper for it. The Wdf call returns the specific instance string.

Oh yes you are right Doron. They are equivalent only in the case where the PDO is passed as a filtering parameter to IoGetDeviceInterfaces. Sorry (again) about that.