UMDF device names

Hi all,

I’m trying to learn UMDF driver development using the Microsoft WDF book. I’ve got to the stage of understanding most of the basic structure for the UMDF driver and getting the skelton code built and installed.

I know need to write a test app that talks to my device via the driver, but I’m stuck trying to find the name of the device that I open with createFile().

I’ve seen that in KMDF and WDM the driver is passed a device object, which you then assign a symbolic link to, thus giving you the static name for the device.

Unfortunately I can’t find anything similar for UMDF. I suspect I need to do something in my device callback class’ CreateInstance method.

I would very much appreciate it if someone could link me to something that describes how to assign a symbolic link to a device, and also how to enumerate devices from an application so the symbolic link is not needed.

Sorry for the nooby question, but I’ve spent the last two hours searching google and this mailing list with no luck.

Thanks in advance.
Andrew Parlane

Same thing in UMDF… You call your Driver Object’s CreateDevice method, get back a IWDFDevice. Then, invoke that device’s CreateSymbolicLink method.

You probably also want to create a device interface, while you’re at it.

Or, am I missing the point of your question entirely?

Peter

Hi, Thanks that’s helpful, I was just confused as to where this stuff needed to get called.

It unfortunately didn’t work, my windows app reported error 2 (file not found) on trying to open the driver.

I’m registering the symbolic link “??\cusbTest” and then trying to open “\.\cusbTest”
(Yes I am escaping the \s in my code).

I’m currently battling with getting traces out, I had it working fine, until I added more traces and recompiled / installed the driver, now traceview is reporting trace messages from an unknown guid, that doesn’t seem to be used in my driver or created in the tmf files. I’ll play some more with this and then hopefully I’ll be able to provide more information about what’s failing.

Thanks again for you help.

OK, so I fixed my tracing issues, and have done some debugging.

see: http://slexy.org/view/s20p5gOrus for my device.cpp file

Line 119 is my call to createSymbolicLink.

SYMBOLIC_NAME is defined in internal.h as:
#define SYMBOLIC_NAME L"\??\cusbTest"

Now when I try and open the device is my app, using: http://slexy.org/view/s20get45XH

It fails with error 2.

I can’t seem to find the sym link in sysinternal’s winobj, but i’m not sure where i’m supposed to be looking.

I used the setupDi functions to get the device interface details, and using the device name I succesfully opened it.

Any ideas, I’ve spent most of the day on this, searching around lots, but there seem to be relatively few examples of doing this, which seems odd in itself.

xxxxx@carallon.com wrote:

OK, so I fixed my tracing issues, and have done some debugging.

see: http://slexy.org/view/s20p5gOrus for my device.cpp file

Line 119 is my call to createSymbolicLink.

SYMBOLIC_NAME is defined in internal.h as:
#define SYMBOLIC_NAME L"\??\cusbTest"

Now when I try and open the device is my app, using: http://slexy.org/view/s20get45XH

It fails with error 2.

What’s the point of this code?

size_t nameSize = ARRAYSIZE(SYMBOLIC_NAME);
2.
WCHAR *symName = new WCHAR[nameSize];
3.
hr = StringCchPrintf(symName, nameSize, L"%ws",
SYMBOLIC_NAME);
4.
… hr = tmpIwdfDevice->CreateSymbolicLink(symName);

Why don’t you just do this:
tmpIwdfDevice->CreateSymbolicLink(SYMBOLIC_NAME);

It’s exactly the same, and you don’t have to worry about memory
allocations and off-by-one problems.


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

Tim Roberts wrote:

What’s the point of this code?

size_t nameSize = ARRAYSIZE(SYMBOLIC_NAME);
WCHAR *symName = new WCHAR[nameSize];
hr = StringCchPrintf(symName, nameSize, L"%ws", SYMBOLIC_NAME);
… hr = tmpIwdfDevice->CreateSymbolicLink(symName);

Why don’t you just do this:
tmpIwdfDevice->CreateSymbolicLink(SYMBOLIC_NAME);

It’s exactly the same, and you don’t have to worry about memory
allocations and off-by-one problems.

Actually, now that I think about it, it’s NOT exactly the same, and
that’s almost certainly the root cause of your problem. The “%ws”
printf descriptor does NOT mean “this is a Unicode string”. It means
“this is a string of the opposite character type from the rest of the
program”. So, in an ANSI program, where UNICODE is not defined, you’ll
call StringCchPrintfA, where “%ws” means Unicode. But if UNICODE is
defined, that will call StringCchPrintfW, where “%ws” means ANSI. You
are probably compiling with UNICODE.

So, you are probably creating a symbolic link to "".


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

“Tim Roberts” wrote in message news:xxxxx@ntdev…

>The “%ws”
> printf descriptor does NOT mean “this is a Unicode string”. It means
> “this is a string of the opposite character type from the rest of the
> program”. So, in an ANSI program, where UNICODE is not defined, you’ll
> call StringCchPrintfA, where “%ws” means Unicode. But if UNICODE is
> defined, that will call StringCchPrintfW, where “%ws” means ANSI. You
> are probably compiling with UNICODE.

It seems that %ws always means wide string.
Opposite character type is capital %S and %C.
(see the test program below)

Regards,
–pa

-----------------cut here-----------------
#include <strsafe.h>
#pragma comment(lib, “strsafe.lib”)

wchar_t wbuf[100];
char buf[100];
int main()
{
StringCchPrintfW( wbuf, 100, L"1. wstr=%ws ns=%hs\n", L"wide", “normal”);
printf(“%ws”, wbuf);
StringCchPrintfW( wbuf, 100, L"2. wstr=%s ns=%S\n", L"wide", “normal”);
printf(“%ws”, wbuf);
StringCchPrintfA( buf, 100, “3. wstr=%ws ns=%hs\n”, L"wide", “normal”);
printf(“%s”, buf);
StringCchPrintfA( buf, 100, “4. wstr=%S ns=%s\n”, L"wide", “normal”);
printf(“%s”, buf);
StringCchPrintfA( buf, 100, “5. wstr=%wS ns=%hS\n”, L"wide", “normal”);
printf(“%s”, buf);
}
---------- cut here-------

it prints:

1. wstr=wide ns=normal
2. wstr=wide ns=normal
3. wstr=wide ns=normal
4. wstr=wide ns=normal
5. wstr=wide ns=normal</strsafe.h>

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Friday, August 06, 2010 7:34 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] UMDF device names

Actually, now that I think about it, it’s NOT exactly the same, and
that’s almost certainly the root cause of your problem. The “%ws”
printf descriptor does NOT mean “this is a Unicode string”. It means
“this is a string of the opposite character type from the rest of the
program”. So, in an ANSI program, where UNICODE is not
defined, you’ll
call StringCchPrintfA, where “%ws” means Unicode. But if UNICODE is
defined, that will call StringCchPrintfW, where “%ws” means ANSI. You
are probably compiling with UNICODE.

So, you are probably creating a symbolic link to "".

As Pavel said, it is not rigth, %ws always means UNICODE string. See
http://msdn.microsoft.com/en-us/library/tcxf1dw6(v=VS.71).aspx.

Anyway, you’re right this code makes no sense and using string constant
is better.

I’d add it makes no (good) sense to create symbolic link in UMDF driver
at all. Why not just register device interface, instead? Yes, user mode
code is more complicated, Setup API is obnoxious, but it can be written
once and reused forever. I don’t remember if I wrote this code 7 or 10
years before and still use it.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

Come, come… This is another one of my “hot button” topics. Symbolic link names make good sense exactly for the reason you state in the following statement:

Peter
OSR

Hey all,

Thanks for all the responses.

I originally had just the string constant, and it still didn’t work I changed my code to be as it is now, to base it on the one example of IWDFDevice::createSymbolicLink() I could find in the examples. In “C:\WinDDK\7600.16385.0\src\serial\VirtualSerial\device.cpp”.

I’ll change it back to a string constant.

I guess I don’t need to use symbolic links, but it makes things much neater, and it would be good to get it working, since it is meant to work.

I will be back working on this on Wednesday, so will do some more tests and post more when I can.

Thanks again.

OK, symbolic link can make sense if you create control device object.
But for PnP devices? It leads to more complicated and error prone code
inside the driver (handling multiple devices in various states). I guess
there was just a discussion about moving complexity from drivers to
apps. In addition, you have create this ugly code using Setup API sooner
or later anyway if you need to enumerate some OS or 3rd devices. Once
written, it is usable for everything.

Look at OP’s attempt to create a symbolic link. He crearly ignores the
fact there can be multiple device instances in given moment. Which is
true even if you don’t plan ever connect more than one device. If, for
example, an USB device is quickly disconnected and reconnected, there is
one device in S/R state (can wait until app closes the handle) and new
one. It can be handled, of course, but there are possible race
conditions. With device interfaces almost everything works
automagically.

Personally, I’d take writing device interfaces enumeration code as a
test of an ability to write drivers :wink: It is obnoxious, complicated,
APIs have names obscured with long prefix, relations are insufficiently
documented and you have to study an WDK example to make it working. If a
developer survives it, s/he knows what to expect in kernel land.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@osr.com
Sent: Sunday, August 08, 2010 4:11 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] UMDF device names

Come, come… This is another one of my “hot button” topics.
Symbolic link names make good sense exactly for the reason
you state in the following statement:

Peter
OSR


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

Michal Vodicka wrote:

Personally, I’d take writing device interfaces enumeration code as a
test of an ability to write drivers :wink:

Pssht, it is test of an ability to use cut-and-paste. No one writes
that code more than once.


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

I dunno, dude… I almost *always* name my device objects. To not do so is silly, I think.

You DO? Most of the standard OS-created devices have names.

LOOK… I don’t want to turn this into a long, torturous, thread about naming device objects. I’ve discussed, whined, pontificated, and vented on this topic at length in the past.

I *get* the advantages… I *get* the whole issue with device removal creating a “hole” in the sequential numbering scheme and whether or not it makes sense to re-use the number from the “hole” or just keep monotonically increasing the unit number (and that in either case your app can wind-up with something it didn’t expect).

And PLEASE don’t anybody say “Naming your FDO opens a security hole” because this is blatantly incorrect, assuming you do things correctly: http://www.osronline.com/article.cfm?article=507 and http://www.osronline.com/article.cfm?article=508

Unless and until the folks at Microsoft make the whole device interface thing easier to use, I just don’t think FORCING users to use device interface GUIDs is a friendly idea. After all:

Yeah… They COULD fix this you know. They could make it both easier to name your Device Objects securely and properly (which I realize they don’t want to encourage), AND they could make it easier for folks to open named/unamed Device Objects using Device Interface GUIDs. Just a few lines of code…

Peter
OSR

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, August 09, 2010 8:54 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] UMDF device names

Pssht, it is test of an ability to use cut-and-paste. No one writes
that code more than once.

Sure, one test is enough :wink: And ability to use Google to find existing
code is also useful :slight_smile:

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@osr.com
Sent: Monday, August 09, 2010 9:11 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] UMDF device names

I dunno, dude… I almost *always* name my device objects.
To not do so is silly, I think.

Control devices (if any) yes, PnP not. I don’t see a reason when I
already have this enumeration code.

You DO? Most of the standard OS-created devices have names.

I’m sure I used some which had only GUID names but I don’t remember what
it was. BTW, for biometric drivers implementing WBDI is mandatory to
use GUID interface and maybe even the only allowed choice (too lazy to
check specification now).

LOOK… I don’t want to turn this into a long, torturous,
thread about naming device objects. I’ve discussed, whined,
pontificated, and vented on this topic at length in the past.

Sure, me too. I remember your articles but don’t completely agree in
this case.

And PLEASE don’t anybody say “Naming your FDO opens a
security hole” because this is blatantly incorrect, assuming
you do things correctly:

That’s the whole problem. Correctly. You can surely afford it but what
about a beginner in this land? I don’t think so, reading some questions
here. A bug in enumeration code at app side would lead to app
malfunction or crash, bug in driver is worse.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

I intend to use this for a control device. The intention is to have a device map, that enumerates all the devices made by my company along with their serial numbers and other stuff.

We have an old WDM version of this driver, but when I was asked to port it to 64 bit windows 7, I had a few problems, and was seeing multiple blue screens, so it was decided to rewrite it using UMDF.

In the WDM version the device map is implemented as an additional device, which provides a symbolic name and a few basic control functions. Allowing our apps to open it and get the device map, and all the device serial numbers, without having to open each newly detected device in turn.

I’m unsure if this is the best way to go about this, but is the route I have been heading for.

As for the symbolic link question, I would like to get it working, just out of principal if nothing else, as the docs say it should be possible, and it has started to annoy me now.

> In the WDM version the device map is implemented as an additional device, which provides a

symbolic name and a few basic control functions. Allowing our apps to open it and get the device
map, and all the device serial numbers, without having to open each newly detected device in turn.

For me, this is a bad idea.

A bit of simple SetupDi code + CreateFile + DeviceIoControl in user mode (to enumerate all your devices with their serials), for me, looks much more pleasant then additional kmode code, which includes the additional device object not used for anything other.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> I’m registering the symbolic link “??\cusbTest” and then trying to open

“\.\cusbTest”

I’ve seen this working in a UMDF driver that registered the symbolic link
“\DosDevices\Global\MySymbolicLinkDevice”, with an app that tried to open
“\\.\MySymbolicLinkDevice”. (I haven’t removed the escaping ''s).
I don’t remember offhand how this differs from the "??" prefix that you
added, but you could give this a shot.

wrote in message news:xxxxx@ntdev…
> Hi, Thanks that’s helpful, I was just confused as to where this stuff
> needed to get called.
>
> It unfortunately didn’t work, my windows app reported error 2 (file not
> found) on trying to open the driver.
>
> I’m registering the symbolic link “??\cusbTest” and then trying to open
> “\.\cusbTest”
> (Yes I am escaping the \s in my code).
>
> I’m currently battling with getting traces out, I had it working fine,
> until I added more traces and recompiled / installed the driver, now
> traceview is reporting trace messages from an unknown guid, that doesn’t
> seem to be used in my driver or created in the tmf files. I’ll play some
> more with this and then hopefully I’ll be able to provide more information
> about what’s failing.
>
> Thanks again for you help.
>

If you create the link in the system context, then it will be global.

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Abhishek Ram
Sent: Tuesday, August 10, 2010 5:03 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] UMDF device names

I’m registering the symbolic link “??\cusbTest” and then trying to
open “\.\cusbTest”

I’ve seen this working in a UMDF driver that registered the symbolic link
“\DosDevices\Global\MySymbolicLinkDevice”, with an app that tried to open
“\\.\MySymbolicLinkDevice”. (I haven’t removed the escaping ''s).
I don’t remember offhand how this differs from the "??" prefix that you
added, but you could give this a shot.

wrote in message news:xxxxx@ntdev…
> Hi, Thanks that’s helpful, I was just confused as to where this stuff
> needed to get called.
>
> It unfortunately didn’t work, my windows app reported error 2 (file
> not
> found) on trying to open the driver.
>
> I’m registering the symbolic link “??\cusbTest” and then trying to
> open “\.\cusbTest”
> (Yes I am escaping the \s in my code).
>
> I’m currently battling with getting traces out, I had it working fine,
> until I added more traces and recompiled / installed the driver, now
> traceview is reporting trace messages from an unknown guid, that
> doesn’t seem to be used in my driver or created in the tmf files. I’ll
> play some more with this and then hopefully I’ll be able to provide
> more information about what’s failing.
>
> Thanks again for you help.
>


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

The UMDF host process runs in the LocalService context, which is why the
Global is needed.

“M. M. O’Brien” wrote in message
news:xxxxx@ntdev…
> If you create the link in the system context, then it will be global.
>
>
> mm
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Abhishek Ram
> Sent: Tuesday, August 10, 2010 5:03 PM
> To: Windows System Software Devs Interest List
> Subject: Re:[ntdev] UMDF device names
>
>> I’m registering the symbolic link “??\cusbTest” and then trying to
>> open “\.\cusbTest”
>
> I’ve seen this working in a UMDF driver that registered the symbolic link
> “\DosDevices\Global\MySymbolicLinkDevice”, with an app that tried to
> open
> “\\.\MySymbolicLinkDevice”. (I haven’t removed the escaping ''s).
> I don’t remember offhand how this differs from the "??" prefix that you
> added, but you could give this a shot.
>
>
> wrote in message news:xxxxx@ntdev…
>> Hi, Thanks that’s helpful, I was just confused as to where this stuff
>> needed to get called.
>>
>> It unfortunately didn’t work, my windows app reported error 2 (file
>> not
>> found) on trying to open the driver.
>>
>> I’m registering the symbolic link “??\cusbTest” and then trying to
>> open “\.\cusbTest”
>> (Yes I am escaping the \s in my code).
>>
>> I’m currently battling with getting traces out, I had it working fine,
>> until I added more traces and recompiled / installed the driver, now
>> traceview is reporting trace messages from an unknown guid, that
>> doesn’t seem to be used in my driver or created in the tmf files. I’ll
>> play some more with this and then hopefully I’ll be able to provide
>> more information about what’s failing.
>>
>> Thanks again for you help.
>>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>