DeviceIoControl输出缓冲区为空

时间:2014-08-04 04:00:44

标签: c++ windows kernel driver

我正在尝试将一些数据从我的内核驱动程序传递到用户应用程序。

我已经在我的驱动程序和应用程序共享的头文件中定义了结构:

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

在我的驱动程序中,我有一个switch语句

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;
    }

我尝试使用DbgPrint调试代码,if语句没有任何问题,因为outputBufferLength是12而PCB_INFO是8。

对于我的应用程序中的DeviceIoControl代码:

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

我检查了bytesReturn并且它没有返回0,它返回12.

其他信息: 我使用的是64位Windows 7。

我真的不知道出了什么问题,真的很感激任何形式的帮助。如果您需要更多详细信息,我很乐意提供更多代码。这可能与我在64位平台上编写驱动程序有关,还是我的代码出错?

提前致谢!

1 个答案:

答案 0 :(得分:3)

首先,PCB_INFO是指针类型,因此sizeof(PCB_INFO)是指针的大小,而不是您指向的缓冲区的大小。请改用sizeof(CB_INFO)sizeof(*PCB_INFO)。问题中显示的代码实际上是在缓冲区的末尾写入,因此结果是不可预测的。

其次,您的结构包含两个类型为HANDLE的元素,它们在32位和64位体系结构中具有不同的大小。在大多数情况下,Windows会自动负责在32位和64位结构之间进行转换(" thunking"),但在I / O控制代码的情况下,这是您的驱动程序的责任。这在DDK文章Supporting 32-Bit I/O in Your 64-Bit Driver中有所描述。

或者,您可以将应用程序设置为64位,或者更改结构以使其仅使用常量大小的元素。