ntddk.h bug in IO_DRIVER_CREATE_CONTEXT definition in WDK 10.0.10586.0

Correct me if I am wrong but, the IO_DRIVER_CREATE_CONTEXT is defined in the header like this for everything Vista and above ( for WDK 10.0.10586.0 )

typedef struct _IO_DRIVER_CREATE_CONTEXT {
CSHORT Size;
struct _ECP_LIST *ExtraCreateParameter;
PVOID DeviceObjectHint;
PTXN_PARAMETER_BLOCK TxnParameters;
PESILO SiloContext;
} IO_DRIVER_CREATE_CONTEXT, *PIO_DRIVER_CREATE_CONTEXT;

But the PESILO member is only available only after windows 10 threshold (see here: https://msdn.microsoft.com/en-us/library/windows/hardware/ff548565(v=vs.85).aspx ). The structure should have a definition something like this:

typedef struct _IO_DRIVER_CREATE_CONTEXT {
CSHORT Size;
struct _ECP_LIST *ExtraCreateParameter;
PVOID DeviceObjectHint;
PTXN_PARAMETER_BLOCK TxnParameters;
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
PESILO SiloContext;
#endif
} IO_DRIVER_CREATE_CONTEXT, *PIO_DRIVER_CREATE_CONTEXT;

The reason is that FltCreateFileEx2 will return STATUS_INVALID_PARAMETER when checking the size of the structure. It is going to expect 0x20 but IoInitializeDriverCreateContext will initialize it to 0x28.

So basically you could fix it yourself by dynamically decreasing the Size member of the structure by a sizeof(PVOID) for versions of windows below threshold. At least that’s how I made it work for me.
Let me know if you guys saw this or if it is something I am missing or misusing. This seems like a header bug to me.

Good luck,
Gabriel.
www.kasardia.com

This has been already fixed – I observed the same problem, because
“IoInitializeDriverCreateContext()” is a macro and it set Size to “sizeof(
IO_DRIVER_CREATE_CONTEXT )”, but FltCreateFileEx2 didn’t reflect that (this
was fixed in some pre-RS1 builds). See RS1 WDK how they changed
IO_DRIVER_CREATE_CONTEXT struct, IoInitializeDriverCreateContext() and added
IO_DRIVER_CREATE_CONTEXT_* defines.

OK thanks, good to know. So I just need to update my WDK.

Thanks again,
Gabriel
www.kasardia.com

What makes this worse is that in 8.1 the OS checks to make sure the Size field is exactly sizeof(IO_DRIVER_CONTEXT), so you lose binary compatibility. The solution I implemented was to construct a wrapper around this:

Use_decl_annotations
VOID
OsrInitializeDriverCreateContext(PIO_DRIVER_CREATE_CONTEXT DriverContext)
{
// Initialize the context
IoInitializeDriverCreateContext(DriverContext);

#if defined(NTDDI_WIN10)
//
// Note that pre-Windows 10 cannot handle the larger structure
//
if (!RtlIsNtDdiVersionAvailable(NTDDI_WIN10)) {
DriverContext->Size = FIELD_OFFSET(IO_DRIVER_CREATE_CONTEXT, SiloContext);
}
#endif

}

This allows us to build against Windows 10 headers and run the binary on Windows 8.1.

Tony
OSR

On 07/12/2016 10:48 AM, Tony Mason wrote:

What makes this worse is that in 8.1 the OS checks to make sure the Size field is exactly sizeof(IO_DRIVER_CONTEXT), so you lose binary compatibility. The solution I implemented was to construct a wrapper around this:

Use_decl_annotations
VOID
OsrInitializeDriverCreateContext(PIO_DRIVER_CREATE_CONTEXT DriverContext)
{
// Initialize the context
IoInitializeDriverCreateContext(DriverContext);

#if defined(NTDDI_WIN10)
//
// Note that pre-Windows 10 cannot handle the larger structure
//
if (!RtlIsNtDdiVersionAvailable(NTDDI_WIN10)) {
DriverContext->Size = FIELD_OFFSET(IO_DRIVER_CREATE_CONTEXT, SiloContext);
}
#endif

}

Careful…

The field was added for the 10586 release but was not in the 10240
release. 10240 is still the current long term support release for
enterprises who want that kind of thing. I think your logic here will
fail if you compile with a 10586 WDK and deploy on 10240. I think you
want NTDDI_WIN10_TH2.

Also note the docs linked to in the original post suggest this is a new
field for RS1. Lies…

  • M

PS. I have some responsibility for this. Sorry for all the pain.

Ah, a compelling argument for installing old versions of the WDK around (since the machine is newer than 10586, the 1024 WDK is not installed on it). Of course, I’d also argue that the assert would have been better if it had said <= but that’s a moot point.

Tony
OSR