WUDF driver using WDFIoTargetOpen

I am developing a user mode driver that uses an I2c connection to the device. It’s a WUDF driver. In OnPrepareHardware entry I am able to get the connection and interrupt resource of the device.

To create an IO target for the device, I use WdfIoTargetCreate and then WdfIoTargetOpen with TargetDeviceName in open params structure dynamacilly set to \.\RESOURCE_HUB\000000000xx where xx is the connection ID received earlier in onpreparehardware entry point.

My issue is that WdfIoTargetOpen always fails with error invalid parameter. Is this call not allowed for user mode driver? All the GPIO and other WUDF samples use COM based OpenFileByName call to open a handle to the target device. Any help is appreciated.

You’re creating that target name using the RESOURCE_HUB_CREATE_PATH_FROM_ID macro, right?

Invalid parameter is an odd error to be getting:

a) Show us your code, please?

b) Enable WDF Verifier, enable verbose logging, repro your problem, and do a !wdflogdump to see what the log says.

That’s all I’ve got right now. Sorry, I’m not at my dev machine or I might be able to offer additional suggestions…

Peter
OSR
@OSRDrivers

Hi Peter,

code is like this:

WDFIOTARGET i2ccontroller;

WDF_OBJECT_ATTRIBUTES targetAttributes;
WDF_OBJECT_ATTRIBUTES_INIT(&targetAttributes);

status = WdfIoTargetCreate(
pDevice->FxDevice,
&targetAttributes,
&pDevice->i2ccontroller);

I can verify that this call passes and i2ccontroller has a valid address.

Later after getting connection id and interrupt line in the OnPrepareHardware routine I as you mentioned making use of RESOURCE_HUB_CREATE_PATH_FROM_ID do the following:

DECLARE_UNICODE_STRING_SIZE(i2cPath, RESOURCE_HUB_PATH_SIZE);

RESOURCE_HUB_CREATE_PATH_FROM_ID(
&i2cPath,
pDevice->PeripheralId.LowPart,
pDevice->PeripheralId.HighPart);

using definitions for UMDF ofcourse the i2cPath comes out to be : \.\RESOURCE_HUB\00000000016

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
&openParams,
&i2cPath,
(GENERIC_READ | GENERIC_WRITE));

openParams.ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
openParams.CreateDisposition = OPEN_EXISTING;
openParams.FileAttributes = FILE_FLAG_OVERLAPPED;

status = WdfIoTargetOpen(
pDevice->i2ccontroller,
&openParams);

at this point the status is 0xc000000d (Invalid parameter). I looked at wudflogdump and the log had something like WdfIoTargetOpen TargetDeviceName invalid parameter.

I have the same code working well for the same device if compiled as a KMDF driver so I am really not sure what could be going wrong here.

If someone has successfully used WdfIoTargetOpen in UMDF drivers please post me a working code snippet.

Given the Iwdfdevice interface and hence OpenFileByName and other methods are deprecated starting UMDF 2 I think WdfIoTargetOpen is the only way for a UMDF driver to talk to a physical resource?

–Saurabh

Well, I can say this much: You doing it the way I teach it.

You’ve got verbose logging enabled? And WDF verifier? And ALL the log says is bad parameter? Arrrgh.

Setting share access and create disposition shouldn’t be required, to the best of my knowledge. It’s not normally required when opening a typical I/o target. And… file_flag_overlapped seems an odd choice…

Try dropping all those parameters, maybe?

Peter
OSR
@OSRDrivers

Hi Peter, I have already tried all options for create dispositions and shared accesses.

Found this article on MSDN, is this something I am missing and hence no success with WdfIoTargetOpen?

http://msdn.microsoft.com/en-us/library/windows/hardware/hh439567(v=vs.85).aspx

as I said if the driver is compiled as a kernel mode entity there is no issue with the execution.

I can’t confirm that this should work, but try this:

ShareAccess - Don’t set it. I think this shouldn’t make a difference, but it is misleading, because for device access there may be other mechanisms in place to enforce exclusive access at the device level rather than the file handle level (which is what this does).

CreateDisposition - Don’t set it. It is already set to OPEN_EXISTING by WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME.

FileAttributes - This may be the one that is causing the error. I think you need to set it to FILE_ATTRIBUTE_NORMAL. However, you don’t need to explicitly set it because it is already set by WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME. You are overwriting the value by setting it to FILE_FLAG_OVERLAPPED (which is also unnecessary because WDF sets it later, and also because you are not going to use ReadFile/WriteFile/DeviceIoControl directly, you will use WDF I/O APIs). So TLDR; don’t set this as well.

Hi Peter/Rahul,

I was able to make it work. The problem was that for some reason when the driver is UMDF (and this is 2.15) DECLARE_UNICODE_STRING_SIZE was not setting the length of i2cPath UNICODE_STRING and was always 0. I manually set it to correct size after the Macro and WdfIoTargetOpen works fine and I can send IOs to the i2c device.

Thanks a lot for all the help you guys kept my interest going. There is always something to learn from this forum.

The DECLARE_UNICODE_STRING_SIZE sets the Length member to 0 by design (see
ntdef.h for definition). It’s not a bug. The macro just allocates large
enough buffer on the stack, and sets MaximumLength appropriately. The Length
member is set either by another API that copies the string to this new
variable or you set it manually when you assign the string.

-kumar

wrote in message news:xxxxx@ntdev…

Hi Peter/Rahul,

I was able to make it work. The problem was that for some reason when the
driver is UMDF (and this is 2.15) DECLARE_UNICODE_STRING_SIZE was not
setting the length of i2cPath UNICODE_STRING and was always 0. I manually
set it to correct size after the Macro and WdfIoTargetOpen works fine and I
can send IOs to the i2c device.

Thanks a lot for all the help you guys kept my interest going. There is
always something to learn from this forum.

[quote]
I was able to make it work. The problem was that for some reason when the driver
is UMDF (and this is 2.15) DECLARE_UNICODE_STRING_SIZE was not setting the
length of i2cPath UNICODE_STRING and was always 0.

[quote]

To follow-up Mr. Rajeev’s note: He’s (of course) exactly correct. DECLARE_UNICODE_STRING_SIZE allocates the space for, declares the UNICODE_STRING structure, and sets the Buffer and MaximumLength fields of the structure. It’s not SUPPOSED to set the length. How could it? The string hasn’t been placed into the Buffer yet!!

Soooo… you might ask, in the programming pattern:

[>>>INCORRECT CODE FOLLOWS<<<]

DECLARE_UNICODE_STRING_SIZE(i2cPath, RESOURCE_HUB_PATH_SIZE);

RESOURCE_HUB_CREATE_PATH_FROM_ID(
&i2cPath,
pDevice->PeripheralId.LowPart,
pDevice->PeripheralId.HighPart);

It’s the call RESOURCE_HUB_CREATE_PATH_FROM_ID that builds the string and sets the length member of the UNICODE_STRING.

So, why didn’t that work in your case??

Because apparently you’re not checking the return status from RESOURCE_HUB_CREATE_PATH_FROM_ID. Which, I bet, is failing.

Your code should look like the following:

[>>>CORRECTED CODE FOLLOWS<<<]

DECLARE_UNICODE_STRING_SIZE(i2cPath, RESOURCE_HUB_PATH_SIZE);

status = RESOURCE_HUB_CREATE_PATH_FROM_ID(
&i2cPath,
pDevice->PeripheralId.LowPart,
pDevice->PeripheralId.HighPart);

if(!NT_SUCCESS(status)) {
… do something … log something …
return;
}

Remember, Mr. Tripathi… Don’t stop working on an issue as soon as you find *a* fix that will fix the symptoms of your bug. Really try to discover what the root cause the problem. Given that there are MANY WDK sample drivers that use the programming pattern you’ve used, and that DECLARE_UNICODE_STRING_SIZE isn’t new, it’s *very* unlikely that there’s a bug in that macro or in the pattern that’s being illustrated.

Soooo… it *real* bug must lie somewhere else.

Continue to search. Solving problems at the root cause whenever possible (sometimes it is not politically possible or practical to do this, it’s also important to recognize when that’s the case), and not merely eliminating symptoms, will make you a strong engineer that everyone will want to work with.

Peter
OSR
@OSRDrivers

I am sorry I had meant RESOURCE_HUB_CREATE_PATH_FROM_ID MACRO not setting the length correctly and not the DECLARE_UNICODE_STRING_SIZE and I know why too :wink:

thanks for the help and useful suggestions…

Would you care to explain why it was failing? It might be useful for someone looking at this thread in the future.

Mr. Ramadas said what I was just thinking.

Mr. Tripathi… Please take the time to share what was happening to benefit those who come-across this thread after you and have a similar issue.

Peter
OSR
@OSRDrivers

Mr. Tripathi… where are you? I’m running into what I think is the same issue. What did you find?

I’m trying to follow the sample here and having WdfIoTargetOpen() fail after WdfIoTargetCreate() succeeds just fine. I suspect the name I’m using in my call to WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME is malformed by the call to RESOURCE_HUB_CREATE_PATH_FROM_ID. The UNICODE_STRING is being returned as:
.length = 0x4a
.MaximumLength = 0xc8
.Buffer = “\Device\RESOURCE_HUB\0000000000000001”

You’re seriously trying to resurrect a four year old thread? With a guy who had at that time a total of eight posts?

I think you’d have better luck starting a new thread and putting a link to the old topic and asking if anyone can help. But, you know, that’s just me.

Peter

It felt like the right thing to do considering the thread ended with a request to share their results so some poor soul in the future (me) could be enlightened. Now it’s just awkward if I start a new thread :confused: I suppose shame has rarely slowed me down before.