Absolute Paths for ZwCreateFile no longer allowed for HLK Tests

Dear all,

I am trying to get my WDM Virtual Storport Miniport through the HLK tests. It simulates a USB drive based on an image file. The location of the image file is communicated to the driver by IOCTLs. When the driver opens the path with ZwCreateFile or IoCreateFile, HLK tests fail with the issue that the driver must not used absolute paths for opening files. So basically all tests causing the drive to eject and open again are affected.

For a file backed virtual disk I do not understand what Microsoft expects me to do here. Does anybody faces a similar issue and found a solution?

What test specifically fails? Is it a Verifier error?

I assume it is the Verifier, since the error appears in the DV Events section (DV = Driver Verifier).

Driver fails so far the tests:

  • Detect Malicious Software
  • DF - PNP DIF Remove Device Test
  • DF - Reboot restart with IO before and after
  • DF - SimpleIO stress test with IO process termination
  • TDI filters and LSPs are not allowed

All tests fail, because the driver opens the image file with an absolute path, according to the error log:

  • RuleId 0x210002
  • ErrorMessage: File operations should not use absolute paths. Detected opening for write access of file \DosDevices\C:\HLK\img.raw

Interesting! The goal of this verification is to prevent hardcoded paths within drivers, but it being specified to the driver via IOCTL presumably looks the same to driver verifier.

You can request an errata for this, or if you wanted to make a change to work better with driver isolation guidelines, it should work fine if you made it so all the files were under \DriverData

Hi Zac,

Thanks for your insights. Yes, I am thinking the same, especially since I need to store the path to open the file when I am guaranteed to be in the passive IRQL.

Putting all the images under a fixed location under C:\Windows\System32\drivers\DriverData (this is where DriverData points to) is not an option. I would like to see the reactions if Microsoft decides that all users can only create their VHDs in this folder on the C drive only :wink:

This issue seems too major to me, since this would mean anybody who writes a file backed virtual device must run into this issue at some point. However I did not find a big yelp, yet. So I assume I am doing something wrong. But I will also look into the topic on how to request an errata.

Are you sure the error message is correct?

Maybe it only doesn’t want \DsDevices and using nonpersistent paths works?

Complete prevention is totally bonkers.

I googled a bit, and it seems that this is a part of the driver isolation concept Microsoft decided to enforce.

Apparently, the drivers should never access arbitrary files, but only those that “belong” to the driver and located inside the driver-specific path obtained via IoGetDeviceDirectory().

From what I’ve read, it’s enforced on Windows Drivers, but not on Windows Desktop Drivers, so if you’re not targeting server OS versions it should still work (but don’t quote me on that). And no, that document does not answer the question about what a developer should do if the driver does need to access an arbitrary file.

@Dejan_Maksimovic I am positive that the error message is correct. I also went through this error message for registry paths and logging paths. So removing absolute paths for logs (which makes sense) fixed this issue. I will try to switch from \\DosDevices\\ to \\??\\. At least Master AI claims it might also bring performance boost :wink:

@CaptainFlint Thanks for this page. I also understand that the isolation is not enforced for Windows Desktop Drivers. I checked my MSVS project, but driver settings there were already specified for a Desktop driver. But I will try to play around with these options.

What is the HLK testsuite and the target OS that you’re running tests for?

I use HLK for Windows 11, version 25H2. The target OS, if my understanding is correct, is Windows 10.0.26100. My WDK version is 10.0.28000 and I am building with MSVS 2026. Maybe I should downgrade…

By target I meant the client machines in the HLK tests. But I guess they are Win11 25H2, to fit the HLK version?

I don’t think downgrading WDK will help. The tests checks the actual behavior of the driver in the specific client OS, it doesn’t matter what version the driver was built for.

In that case errata sounds more and more like the only option. Well, apart from abandoning HLK and going with Attestation, obviously.

Yes, the client machines have Windows 10.0.26100. I stumbled across it, because you can no longer install a non matching HLK client.

Why not let userspace pass an image file handle to the driver instead? You’re also less likely to run into TOCTOU issues that way.

1 Like

I was not even aware that this is a valid approach and userspace and driverspace can exchange handles :wink:. But this seems to fix my issue:

So here is my solution in case someone else is struggling

  • USERSPACE: Open file with CreateFile and pass HANDLE via ioctl to driver
  • DRIVER: Receive Handle and use
    • ObReferenceObjectByHandle (userSpaceHandle,
         FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE,
        *IoFileObjectType,
         UserMode,
        (PVOID*)&fileObjectPoiner,NULL);
      

      to generate a FILE_OBJECT

    • ObOpenObjectByPointer (fileObjectPointer,
                             OBJ_KERNEL_HANDLE,
                             NULL,
                             FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE,
                             *IoFileObjectType,
                             KernelMode,
                             &handle); 
      

      to generate a file handle to be used with ZwRead and ZwWrite

Userspace can close its handle after Kernel handle was created.

Driver needs to close fileObjectPointer with ObDereferenceObject

1 Like

Never mind, I didn't see that your ObReferenceObjectByHandle already does the check.

FYI there’s no difference between a windows driver and a desktop driver. For a time we made a distinction because we wanted to have stricter requirements for newer platforms (phone, etc.) but now they’re the same, with the requirements getting more stringent over time via HLK.

Related to this topic is the question how the kernel-space HANDLES can survive a disable/enable cycle of the device. The HLK test DF - Sleep and PnP (disable and enable) is performing such an operation. I found the routine IoAllocateDriverObjectExtension to create persistent memory for the driver to act as storage for file handles. However, the HLK test seems to recreate the driverObject and therefor also purges the driver object extension.

Since I cannot store handles in the registry (I assume ;-)) and cannot use absolute file paths to reopen the files, is there another solution to this issue?

" how the kernel-space HANDLES can survive a disable/enable cycle of the device"

  • they can't. You need to close all open handles on disable and open them on enable. How ever you opened them originally, do that again. Also, DriverObject extensions are generally not a good place to store much of anything, and if your DriverObject is being deleted, all of your related devices have been deleted, and your entire driver object and memory is being deleted. Device specific state goes into the device extension. Driver global data is no different than dll global data, it persists as long as the dll persists.

Thanks for your answer. This is indeed a downer.

So far I just stored the paths in the driver registry and simply reopened the file. This is due to the new restriction of using absolute paths in the driver no longer allowed.

Now, if my understanding is correct, I need to write an additional service in user-space, which receives the list of current devices from my driver on disable, awaits the enable of my driver to reopen all files and sends the handles back into it.

I am sorry, but I fail to see the benefit of this approach. What does Microsoft drive to forbid opening absolute paths in kernel-space in the first place. The complexity for a file backed virtual storport is certainly higher than before. :frowning: