WdfDeviceCreateDeviceInterface failed with satus c0000010

Hi All,
I am developing a usb driver in kmdf , I like to assign unique name to each device(of same type) when they are plugged to system. So that client application can use this name to access the perticular device.
For that I used WdfDeviceCreateDeviceInterface to assign unique name to each device when they are plugged. Please look the below code how I implimented that

//UniqueDeviceName = “MyDevice_0” … “MyDevice_1” …“MyDevice_N”

status = WdfDeviceCreateDeviceInterface(device,
(LPGUID) &GUID_DEVINTERFACE,
&UniqueDeviceName);// Reference String
if (!NT_SUCCESS(status)) {
KdPrint( (“WdfDeviceCreateDeviceInterface failed %x\n”, status));
return status;
}

But when i trying to install the driver, the above function is failing with status value C0000010. Apart from above code I did not write any thing else for multiple uinque device names.

Can anybody help me in solving this problem .Is anything else i have to implement to achieve my task.

regards
siva

See the documentation for IoRegisterDeviceInterface. Either your reference string contains an invalid character or your device is not valid.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-281752-
xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, March 27, 2007 3:26 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WdfDeviceCreateDeviceInterface failed with satus
c0000010

Hi All,
I am developing a usb driver in kmdf , I like to assign unique name
to each device(of same type) when they are plugged to system. So that
client application can use this name to access the perticular device.
For that I used WdfDeviceCreateDeviceInterface to assign unique name to
each device when they are plugged. Please look the below code how I
implimented that

//UniqueDeviceName = “MyDevice_0” … “MyDevice_1” …“MyDevice_N”

status = WdfDeviceCreateDeviceInterface(device,
(LPGUID) &GUID_DEVINTERFACE,
&UniqueDeviceName);// Reference String
if (!NT_SUCCESS(status)) {
KdPrint( (“WdfDeviceCreateDeviceInterface failed %x\n”,
status));
return status;
}

But when i trying to install the driver, the above function is failing
with status value C0000010. Apart from above code I did not write any
thing else for multiple uinque device names.

Can anybody help me in solving this problem .Is anything else i have to
implement to achieve my task.

regards
siva


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

First, I am assuming that you are creating a device interface on a pnp device, if it is a control device, STATUS_INVALID_DEVICE_REQUEST is the expected return value. I hope that the type of UniqueDeviceName is UNICODE_STRING and not just a string constant.

Does !wdfkd.wdflogdump give you any indication of KMDF returning this error vs the underlying API?

Have you manually deleted keys in the registry dealing with device installation and device interfaces? If so, you probably put these entries into an unknown state.

As for using a reference string so that the application receives a unique name, that is not how device interfaces and their reference strings work. The application must treat the entire device interface string as opaque and should never parse it. The reference string is for the *driver*, not the application. The driver uses reference strings to distinguish between 2 different interfaces being opened (see http://blogs.msdn.com/doronh/archive/2006/08/18/706717.aspx for more info). If you want to assign your device a unique name that the application can use, store the name in the registry (using a device coinstaller). The application can then read the value out of the registry when it is notified about interface arrival.

d

xxxxx@gmail.com wrote:

I am developing a usb driver in kmdf , I like to assign unique name to each device(of same type) when they are plugged to system. So that client application can use this name to access the perticular device.
For that I used WdfDeviceCreateDeviceInterface to assign unique name to each device when they are plugged. Please look the below code how I implimented that

//UniqueDeviceName = “MyDevice_0” … “MyDevice_1” …“MyDevice_N”

status = WdfDeviceCreateDeviceInterface(device,
(LPGUID) &GUID_DEVINTERFACE,
&UniqueDeviceName);// Reference String
if (!NT_SUCCESS(status)) {
KdPrint( (“WdfDeviceCreateDeviceInterface failed %x\n”, status));
return status;
}

But when i trying to install the driver, the above function is failing with status value C0000010.

Can we see how you create UniqueDeviceName? It’s surprisingly easy to
mess up the management of a UNICODE_STRING.


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

xxxxx@Microsoft.com wrote:

As for using a reference string so that the application receives a unique name, that is not how device interfaces and their reference strings work. The application must treat the entire device interface string as opaque and should never parse it. The reference string is for the *driver*, not the application. The driver uses reference strings to distinguish between 2 different interfaces being opened (see http://blogs.msdn.com/doronh/archive/2006/08/18/706717.aspx for more info).

I have to admit that this is a matter of some confusion to me as well.
Your blog post says this:

But there is a problem! How you can tell if the application
meant to open GUID_DEVINTERFACE_EXCLUSIVE,
but left off the reference string and opened
GUID_DEVINTERFACE_NON_EXCLUSIVE instead?

That implies that the application has to specify the reference string
when opening the driver, presumably by appending to the opaque name it
got from SetupDi. But the description of IoRegisterDeviceInterface
implies that the reference string is a private communication between the
driver and the I/O manager, and that the application will never need to
know about it.

Which is correct?


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

When you retrieve the device interface string (i.e. the value you pass to CreateFile) it already has the reference string built into it. The application doesn’t even know there is a reference string, it just gets a string that is a bit longer than usual ;). The ref string is a private mechanism between the driver and the I/O manage treats the ref string as a file name and passes it to the driver (it will strip off the base device interface string in the process). So, this allows the driver writer to specify extra information that is opaque to all parties in the interface string. The I/O manager helps out by stripping out the parts of the string that it can parse on its own.

d

hi & thanks for ur suggessions , let me explain breifly.

my device is a dongle device , with that i do read and write operations. to access multiple devices i named each device with unique name( unicode string ). for that i have used WdfDeviceInitAssignName and WdfDeviceCreateSymbolicLink .
I am able install the driver and successfully performing read and write operations for one device.but when i plugged one more device on another port it is showing error that driver for this device not installed.
I wrote code like this…

#define DEVICE_NAME L"\device\Mydevice"

//for naming multiple devices i created one driver structure for array of names and
// i created a index variable in device structure to append that index to the MyDevice0, MyDevice1…

RtlInitUnicodeString(&DeviceName, DEVICE_NAME);

//appending index at the end of unicode string
status = RtlAppendUnicodeStringToString(&DeviceFullName,&Index);
if (!NT_SUCCESS(status)) {
KdPrint((“FAIL – Device String cancatination failed 0x%0x … MYString : %wZ … Des: %wZ\n”, status,&DeviceFullName,&Index));
return(status);
}


status = WdfDeviceInitAssignName(DeviceInit, &DeviceFullName);

status = WdfDeviceCreateSymbolicLink(device, &DeviceFullName);

By using debug view i observed the messages of device naming it showing correctly for one device but not for two.
so please tell me where i was doing mistake.

regards
siva.

You do not need to assign a name to your device. You can create a symbolic link to an unnamed FDO (KMDF will set up the link against the PDO’s name). In fact, naming your FDO can lead to security problems.

What is the initial value of DeviceFUllName? you show initializing DeviceName, but not DeviceFullName. Also, why are you using the same string for the device name and the symbolic link? Usually the device name is \Device\Xxx and the symbolic link is ??\Xxx.

Names assigned to device objects persist for the entire lifetime of the device. This means that a device can be surprise removed (but not removed) and then when you try to reuse the name, it will fail because it is still in use. Symbolic links can be removed at any time, KMDF will remove the symbolic link duriing surprise removal so that you can reuse the link name if the device is plugged back in.

But I don’t understand why you are creating a symbolic link and using a device interface. Since you control the app, just use the device interface and all of this headache goes away. Device interfaces automatically manage the naming problems associated with PnP arrival, removal, discovery/iteration of existing names, and notification about arrival. Symbolic links do not get these nice solutions.

d

You cannot assign the same name to the device object and to its symbolic link. If you want the symbolic link to be visible to user space use L"\DosDevices\XXXXXN" .

You do not need to set a device name at all.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-281865-
xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, March 28, 2007 1:59 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WdfDeviceCreateDeviceInterface failed with satus
c0000010

hi & thanks for ur suggessions , let me explain breifly.

my device is a dongle device , with that i do read and write
operations. to access multiple devices i named each device with unique
name( unicode string ). for that i have used WdfDeviceInitAssignName
and WdfDeviceCreateSymbolicLink .
I am able install the driver and successfully performing read and
write operations for one device.but when i plugged one more device on
another port it is showing error that driver for this device not
installed.
I wrote code like this…

#define DEVICE_NAME L"\device\Mydevice"

//for naming multiple devices i created one driver structure for array
of names and
// i created a index variable in device structure to append that index
to the MyDevice0, MyDevice1…

RtlInitUnicodeString(&DeviceName, DEVICE_NAME);

//appending index at the end of unicode string
status = RtlAppendUnicodeStringToString(&DeviceFullName,&Index);
if (!NT_SUCCESS(status)) {
KdPrint((“FAIL – Device String cancatination failed 0x%0x …
MYString : %wZ … Des: %wZ\n”, status,&DeviceFullName,&Index));
return(status);
}


status = WdfDeviceInitAssignName(DeviceInit, &DeviceFullName);

status = WdfDeviceCreateSymbolicLink(device, &DeviceFullName);

By using debug view i observed the messages of device naming it showing
correctly for one device but not for two.
so please tell me where i was doing mistake.

regards
siva.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

hi & thanks for ur suggessions , let me explain breifly.

my device is a dongle device , with that i do read and write operations. to access multiple devices i named each device with unique name( unicode string ). for that i have used WdfDeviceInitAssignName and WdfDeviceCreateSymbolicLink .
I am able install the driver and successfully performing read and write operations for one device.but when i plugged one more device on another port it is showing error that driver for this device not installed.
I wrote code like this…

#define DEVICE_NAME L"\device\Mydevice"

//for naming multiple devices i created one driver structure for array of names and
// i created a index variable in device structure to append that index to the MyDevice0, MyDevice1…

RtlInitUnicodeString(&DeviceName, DEVICE_NAME);

//appending index at the end of unicode string
status = RtlAppendUnicodeStringToString(&DeviceFullName,&Index);

This demonstrates exactly why I wanted to see the code where you created
DeviceName. This code contains a very common kernel bug. Remember that
a UNICODE_STRING has a “current length” and a “maximum length”. When
you use RtlInitUnicodeString, it sets BOTH values to the length of the
initialization string. Therefore, there is NO ROOM in the buffer for
you to append anything. The append will fail, and DeviceName will
ALWAYS contain “\device\Mydevice”.

The answer is either to initialize the UNICODE_STRING by hand, pointing
it to a larger buffer, or use “wsprintf” to create the final string and
pass that to RtlInitUnicodeString.

Oddly enough, I had a private email conversation earlier this week that
had exactly the same problem.


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

As Time pointed out, if you stick with UNICODE_STRING the entire time you don’t have a problem. I would like to suggest an alternative to flipping between CRT functions and UNICODE_STRINGs. Just stick with UNICODE_STRING and format it with the functions in ntstrsafe.h since ntstrsafe.h now contains support for UNICODE_STRINGs (http://blogs.msdn.com/doronh/archive/2006/02/27/540160.aspx). For instance, ntstrsafe.h contains functions to sprintf into a UNICODE_STRING.

Another aspect of the solution is the macro DECLARE_UNICODE_STRING_SIZE in wdfcore.h. This simplifies the initialization of the UNICODE_STRING fields when using a sized buffer. Your code would now look like

DECLARE_UNICODE_STRING_SIZE(deviceName, 80); // 80 is just a value i picked out of thin air

status = RtlUnicodeStringPrintf(&deviceName, DEVICE_NAME L"%d", Index);
if (NT_SUCCESS(status)) {
status = WdfDeviceCreateSymbolicLink(device, &deviceName);
}

d

> That implies that the application has to specify the reference string

when opening the driver, presumably by appending to the opaque name it
got from SetupDi. But the description of IoRegisterDeviceInterface
implies that the reference string is a private communication between the
driver and the I/O manager, and that the application will never need to
know about it.

Correct, the application will get the name with the reference string already
appended from SetupDi.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com