WdfDeviceCreateSymbolicLink issue

Hello Experts I am new bee learner windows driver development. By going through the following link " https://www.osr.com/nt-insider/2017-issue1/making-device-objects-accessible-safe/" At Kmdf: I have assigned a name to the FDO by calling “WdfDeviceInitAssignName” and followed by created wdfdevice by calling “WdfDeviceCreate’ function. And then called “WdfDeviceCreateSymbolicLink” as follows DECLARE_CONST_UNICODE_STRING(userDeviceName, L”\DosDevices\Ufx1000"); status = WdfDeviceCreateSymbolicLink(device, &userDeviceName); At User application: After this call I have called the “create file” from user application as follows, hFile = CreateFile(“\\.\Ufx1000”, GENERIC_READ|GENERIC_WRITE, // requested access 0, // share mode NULL, // security attributes OPEN_EXISTING, // create disposition 0, // flags NULL); However createFile fails and in the DosDevices registry key Ufx1000 device not get created. What is wrong I am doing here.? Thank you in advance Regards Lokesh

Are you talking about HKLM\System\MountedDevices? That only shows disk devices. You can use the SysInternals WinObj tool to look at the kernel’s name tree. DosDevices is shown as GLOBAL??.

What error do you get? Is it file not found, or is it access denied?

Don’t use names from samples or from the system (like Ufx1000). Use a name that is specific to your or your company. Otherwise, you end up with collisions.

First, it is not best practice to name your FDO. You don’t need to in KMDF in order to create a symbolic kink, So, while the 2017 article is correct, it is also not current best practice.

Second, if you do not change the protection on your device object, by default only apps running “as admin” will be able to open them by name.

Third, I don’t know what you mean by “the DOS Devices Registry Key”…

Peter

Tim & Peter,

Thank you for the responses.

Actually I am facing different issue.
I am in development of usb device side function class driver to perform transaction between User mode application and Usb function class extention driver(ufx01000.sys).
Here I am also developing usb function controller driver which is running as PDO and the ufx01000.sys will be loaded as a FDO.
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-drivers-for-usb-function-controllers

So my function class driver should forwards the IOCTLs called by the Application to ufx01000.sys which is loaded as child FDO of my custom Function controller driver which is running as PDO as above link explains.

If I call WdfDeviceCreateDeviceInterface function which registers the device interface for PDO and it can be retrieved by Function class driver, also I can call IOCTLs to talk with PDO if any.
What can I do if I want to call IOCTLs exposed by FDO(in my case it is ufx01000.sys) and following link explains the IOCTLs exposed by the same.
https://docs.microsoft.com/en-us/previous-versions/windows/hardware/drivers/mt188008(v=vs.85)

Best Regards
Lokesh

Hello Tim
Thank you for the response.
I have tried by setting following set of configuration values in the registry as per this link https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-registry-settings-for-a-function-controller-driver.
Can you please let me know if I am missing anything.?
And also please confirm what is the minimum configurations we need to be set to avoid errors.

Trial 1:
HKLM\System\CurrentControlSet\Control\USBFN\Configurations\Default
/v InterfaceList /t REG_MULTI_SZ /d “GENERICUSBFN\0MTP” /f
/v InterfaceDescriptor /t REG_BINARY /d 09040100020A000006 /f
/v InterfaceGUID /t REG_SZ /d “{B7E6B162-1130-4CE1-80FC-B1369717147E}” /f

Trial 2:
**HKLM\System\CurrentControlSet\Control\USBFN\Configurations\MyConfiguration **
/v InterfaceList /t REG_MULTI_SZ /d GENERICUSBFN\0MTP /f
/v InterfaceDescriptor /t REG_BINARY /d 09040100020A000006 /
/v InterfaceGUID /t REG_SZ /d “{B7E6B162-1130-4CE1-80FC-B1369717147E}” /f

Trial 3:
**HKLM\System\CurrentControlSet\Control\USBFN **
/v CurrentConfiguration /t REG_SZ /d MyConfiguration /f
**HKLM\System\CurrentControlSet\Control\USBFN\Interfaces\GENERICUSBFN **
/v InterfaceDescriptor /t REG_BINARY /d 09040100020A000006 /f
/v InterfaceGUID /t REG_SZ /d “{B7E6B162-1130-4CE1-80FC-B1369717147E}” /f
/v InterfaceNumber /t REG_DWORD /d 40 /f

Common Serrings:
**HKLM\System\CurrentControlSet\Control\USBFN **
/v IncludeDefaultCfg /t REG_DWORD /d 1 /f
HKLM\System\CurrentControlSet\Control\USBFN\default
/v bcdDevice /t REG_DWORD /d 0401 /f
/v bDeviceClass /t REG_DWORD /d 02 /f
/v bDeviceProtocol /t REG_DWORD /d 00 /f
/v bDeviceSubClass /t REG_DWORD /d 00 /f
/v idProduct /t REG_DWORD /d 0525 /f
/v idVendor /t REG_DWORD /d 0xA4A7 /f
/v iManufacturer /t REG_DWORD /d 01 /f
/v iSerialNumber /t REG_DWORD /d 00 /f
/v ManufacturerString /t REG_SZ /d “Minds Pvt Ltd” /f
/v ProductString /t REG_SZ /d “Datacolor” /f
/v bNumConfigurations /t REG_DWORD /d 03 /f
HKLM\System\CurrentControlSet\Control\USBFN\Configurations\Default
/v bmAttributes /t REG_DWORD /d 0xC0 /f
/v bMaxPower /t REG_DWORD /d 01 /f

Thank you & Regards
Lokesh

You’re advertising 3 configurations. That’s very rare in a real device, is somewhat difficult to handle, and doesn’t appear to be supported by your registry entries. Just use one configuration for now.

Your interface descriptor needs to include all of the endpoint descriptors as well, assuming you have to specify them. Didn’t you say this is a CDC device? If so, why are you advertising an MTP interface?

The names in the InterfaceList are supposed to be additional subkeys under USBFN\Interfaces to be added to the descriptor. If you’re just using ine interface, you shouldn’t need the InterfaceList.

Do you have a real device you’re modeling this after? Everything in the device descriptor does into the “default” key, and all of the bytes in your configuration descriptor should be in an InterfaceDescriptor somewhere. The system takes all of those interface descriptors and concatenates them together to produce your actual configuration descriptor.

Hello Tim
Thank you for the response.

You’re advertising 3 configurations. That’s very rare in a real device, is somewhat difficult to handle, and doesn’t appear to be supported by your registry entries. Just use one configuration for now.

Okay I will try with one configuration at a time.

Your interface descriptor needs to include all of the endpoint descriptors as well, assuming you have to specify them. Didn’t you say this is a CDC device? If so, why are you advertising an MTP interface?

Yes I need to use implement only CDC class, USBFN\Interfaces\GENERICUSBFN configurations sufficient in my case.
Endpoint descriptors?, can you please tell me where should I set in the registry. I am not seeing a place holder for the same in the link https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-registry-settings-for-a-function-controller-driver

Additional Query: Tim, Do we have any simple(short term) subscription options to get more specific support on this?

Regards
Lokesh

Hello Tim
I have set following configurations in the registries as per the link An Overview on USB Support and Dual Role for Windows 10 IoT Core - Windows IoT | Microsoft Learn.
Though I am not sure where to set the endpoint configurations in the registry.

**HKLM\System\ControlSet001\Control\USBFN\default **
BcdDevice=0x1
bDeviceClass=0x0
bDeviceProtocol=0x0
bDeviceSubClass= 0x0
idProduct= 0xc0c0
idVendor=0x045e
iManufacturer=1
iSerialNumber=3
ManufacturerString=OEMname
ProductString=“Windows IOT”
SerialNumberString=0x123

//Self powered
**HKLM\System\CurrentControlSet\Control\USBFN\Configurations\Default **
bmAttributes = 0xC0
bMaxPower = 0x1
InterfaceList = “GENERICUSBFN”
InterfaceDescriptor 0x09040100020A000006
InterfaceGUIDE= “{B7E6B162-1130-4CE1-80FC-B1369717147E}”

However still I am not seeing the Interface and GenericUsbFn.sys not in running state. I have also attached logs I am getting from UFX01000.sys for your reference. I will be very happy if it gives some clue.

How much have you looked into the USB standard? When you are becoming a USB device, either by programming microcode in a microprocessor or by creating descriptors for a higher-level library, you have to understand how the spec works.

Descriptors in USB are nested, in a sense. The term “configuration descriptor” has two meanings. There is a 9-byte “configuration descriptor” structure in the DDK include files. However, the thing we call a “configuration descriptor” actually includes that header PLUS all of the interface and endpoint descriptors that make up the configuration. The header has a two-byte field that gives the length of the whole descriptor. When the host system wants the config descriptor, it reads that 9-byte header, then uses the length field to re-read the entire descriptor.

Similarly, there is a 9-byte interface descriptor header, but the “interface descriptor” conceptually includes that header plus all of the endpoint descriptors that make up the interface. So, you can think of it as a nested set:

  • Configuration Descriptor
    • Interface #0 descriptor
      • Possible class-specific interface descriptors
      • Endpoint #1 descriptor
      • Possible class-specific endpoint descriptors
      • Endpoint #81 descriptor
      • Possible class-specific endpoint descriptors
    • Interface #1 descriptor
      • Endpoint #3 descriptor
      • Endpoint #83 descriptor

and so on. In order for the USBFN code to construct your full configuration descriptors, it has to have all of the others. Since there is no place to put them, I surmise that the “InterfaceDescriptor” registry value MUST INCLUDE all of the endpoint descriptors and class-specific descriptors for that interface, much like they would if you were programming a real device. That’s what I’m trying to say. NOWHERE in the configuration you have shown do you tell the system which endpoint numbers you wish to handle, what type they are (bulk, interrupt, isoch), or what the maximum packet size is. That all has to be declared before the system can expose a device for you.

1 Like

Hello Tim,
Thank you a lot for your time and for providing answers for our satisfaction. We will try to create a InterfaceDescriptor in such a way it should be combination of all the interface and endpoint descriptors. It would be really helpful if I will get any example or any tool which which help us in creating the same.

No, there are no tools, but they’re not hard. And, as I said, if you’re creating a USB device, then you really need to understand the USB spec (at least chapter 9) well enough to know how to fill in the descriptor fields.

1 Like

Hello Tim
Thank you for the response. I try to create a sample configuration descriptor and will give a try.
And along with that, somehow we missed the track of original query in this thread. In any case is it possible to create our own class driver to communicate with ufx01000.sys

@lokichitti said:
Tim & Peter,

Thank you for the responses.

Actually I am facing different issue.
I am in development of usb device side function class driver to perform transaction between User mode application and Usb function class extention driver(ufx01000.sys).
Here I am also developing usb function controller driver which is running as PDO and the ufx01000.sys will be loaded as a FDO.
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-drivers-for-usb-function-controllers

So my function class driver should forwards the IOCTLs called by the Application to ufx01000.sys which is loaded as child FDO of my custom Function controller driver which is running as PDO as above link explains.

If I call WdfDeviceCreateDeviceInterface function which registers the device interface for PDO and it can be retrieved by Function class driver, also I can call IOCTLs to talk with PDO if any.
What can I do if I want to call IOCTLs exposed by FDO(in my case it is ufx01000.sys) and following link explains the IOCTLs exposed by the same.
https://docs.microsoft.com/en-us/previous-versions/windows/hardware/drivers/mt188008(v=vs.85)

Best Regards
Lokesh

You call the functions in ufxclient.h. As the documentation states, the ufx01000.lib stub library will translate all of those calls into the ufx01000.sys ioctls.

1 Like

Hello Tim,
Yes I am doing the same thing, from function controller driver loading the ufx01000.sys as a FDO and calling the APIs exposed for function controller driver using ufxclient.h.
Function controller driver ↔ ufx01000.sys = no issues, it is working for us.
However I need to understand, how to build communication between class driver(if I create my own class driver) to ufx01000.sys.
From the following link Overview of Developing Windows Drivers for USB Function Controllers - Windows drivers | Microsoft Learn

From the above statement I got little confused.
** Do I need to load the ufx01000.sys as FDO of both function controller driver as well as function class driver?**

My only concern here is, from my custom function class driver somehow I need to call IOCTLs exposed by ufx01000.sys as explained in following link Usbfnioctl.h header - Windows drivers | Microsoft Learn. But I have lost on how to get the handle to the ufx01000.sys from function class driver.

Hello Tim,

@Tim_Roberts said:
You call the functions in ufxclient.h. As the documentation states, the ufx01000.lib stub library will translate all of those calls into the ufx01000.sys ioctls.

Yes I am doing the same thing from Function controller driver. I am creating ufx01000.sys as a FDO and calling ufxclient.h APIs and they are working fine for me.
But my only issue is I need to know how to communicate from my Custom Function class driver to ufx01000.sys using the IOCTLs which are available from usbfnioctl.h, Usbfnioctl.h header - Windows drivers | Microsoft Learn

From the following link Overview of Developing Windows Drivers for USB Function Controllers - Windows drivers | Microsoft Learn the below statement making me bit confused,

Do ufx01000.sys to be loaded as FDO of both Function controller driver and Function Class driver?
Please confirm on this. If not
from Function Class driver how can I get handle to the ufx01000.sys to call the IOCTLs available in ufxclient.h.?

Thank you

Hello Tim
Can you please provide some comment on this thread?

No, I can’t, because I don’t have any experience with this. What I have told you so far was all extracted from the Microsoft documentation.

If you read that documentation, it says that your USB class driver is sending requests to Ufx01000.sys. I don’t believe it says your USB class driver has to BE Ufx01000.sys. However, I’ve never done it.