Search code examples
windowsdriverioctl

Passing a struct via IOCTL to kernel-mode driver


I'm trying to pass several distinct pieces of information to a kernel-mode driver from a user-mode application in Windows. I won't pretend to know fully what I'm doing, so if I have any fundamental misconceptions, clarification would be greatly appreciated.

User-mode application (send IOCTL to Driver):

typedef struct {
    unsigned int write;
    ULONG reg_addr;
    ULONG reg_val;
} reg_parameters;

...

reg_parameters regvals;
regvals.write = 0;
regvals.reg_addr = 0xDEADBEEF;
regvals.reg_val = 0XBBBBBBBB;
ULONG value;

...

DeviceIoControl(driver,(ULONG)IOCTL_OMAPCONF_REG, &regvals, sizeof(regvals),
                     &value, sizeof(ULONG), &size, NULL);

Kernel-mode driver (read memory at reg_addr and store value in location specified by reg_val):

NTSTATUS OmapConfDrvDispatch(IN PDEVICE_OBJECT DeviceObject,
                    IN PIRP           Irp)
{
    PVOID               ioBuffer;

    ....

    ioBuffer  = Irp->AssociatedIrp.SystemBuffer;

    ....

Now, the question: How do I access the individual struct members from ioBuffer in the driver?

For example, why isn't it as simple as ioBuffer.reg_addr?

Thoughts?


Solution

  • Cast the Irp->AssociatedIrp.SystemBuffer as a reg_parameters pointer:

    reg_parameters* regvals = (reg_parameters*)Irp->AssociatedIrp.SystemBuffer;
    if (regvals->reg_addr == 0xDEADBEEF) {
       // mmmm - beef
    }
    

    This assumes that you have the reg_parameters defined in your driver code.