0

I am trying to pass some data from my kernel driver up to the user application.

I have defined the structure in my header file shared by my driver and application:

    typedef struct _CallBack
{
    HANDLE  hParId;
    HANDLE  hProId;
    BOOLEAN bCreate;
}CB_INFO, *PCB_INFO;

In my driver, I have a switch statement

case IOCTL_CODE:    
if (outputBufferLength >= sizeof(PCB_INFO))
    {
           callback->hParId = deviceExtension->hParId;
           callback->hProId = deviceExtension->hProId;
           callback->bCreate = deviceExtension->bCreate;

           Irp->IoStatus.Information = outputBufferLength;

           Status = STATUS_SUCCESS;
    }

I have tried debugging the code by using DbgPrint, there was nothing wrong with the if statement, as outputBufferLength is 12 and PCB_INFO is 8.

As for the DeviceIoControl code in my application:

    DeviceIoControl(
                driver,
                IOCTL_CODE,
                0,
                0,
                &callback,
                sizeof(callback),
                &bytesReturn,
                NULL);

I have checked the bytesReturn and it does not return 0, it returns a 12.

Other info: I am using 64-bit Windows 7.

I really have no idea what is wrong, and really would appreciate any form of help. I would be glad to provide more of my code if you need more details. Could it be something to do with me writing the driver on a 64-bit platform, or is there just something wrong with my code?

Thanks in advance!

winston
  • 39
  • 1
  • 11
  • 2
    PCB_INFO is a pointer, so sizeof(PCB_INFO) is wrong, you should be using sizeof(CB_INFO). Also, since sizeof(callback) is 12 your application must be 32-bit. HANDLE is only 4 bytes in 32-bit code, but is 8 bytes in 64-bit code, including your device driver, so your structures are mismatched. Either make your application 64-bit or use a type with a constant size such as QWORD. – Harry Johnston Aug 04 '14 at 04:24
  • If the application must be 32-bit, see [Supporting 32-Bit I/O in Your 64-Bit Driver](http://msdn.microsoft.com/en-us/library/ff563897%28v=vs.85%29.aspx). – Harry Johnston Aug 04 '14 at 04:30
  • @HarryJohnston Thank you so much for your help! It finally worked! Do you want to answer this question so I can accept your answer? – winston Aug 04 '14 at 05:37
  • I have a similar trouble but not understood how to fix my trouble https://stackoverflow.com/questions/45780993/ioctl-driver-systembuffer-always-null?rq=1 – Martin Novák Sep 24 '18 at 16:59

1 Answers1

3

Firstly, PCB_INFO is a pointer type, so sizeof(PCB_INFO) is the size of a pointer, not the size of the buffer you're pointing to. Use sizeof(CB_INFO) or sizeof(*PCB_INFO) instead. The code shown in the question is actually writing past the end of the buffer, so the results are unpredictable.

Secondly, your structure includes two elements of type HANDLE which has a different size in 32-bit and 64-bit architectures. In most situations Windows automatically takes care of converting ("thunking") between 32-bit and 64-bit structures, but in the case of I/O control codes this is your driver's responsibility. This is described in the DDK article Supporting 32-Bit I/O in Your 64-Bit Driver.

Alternatively you can make your application 64-bit, or change the structure so that it uses only elements of constant size.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158