DeviceIoControl输出缓冲区为空

DeviceIoControl output buffer is empty

本文关键字:缓冲区 输出 DeviceIoControl      更新时间:2023-10-16

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

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

    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位平台上编写驱动程序有关,或者只是我的代码有问题?

提前感谢!

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

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

或者你可以让你的应用程序64位,或者改变结构,使它只使用固定大小的元素。