【问题标题】:Kernel driver receives the struct, but it's still null内核驱动程序接收到结构,但它仍然为空
【发布时间】:2018-06-05 18:04:02
【问题描述】:

我有一个内核驱动程序,我正在尝试让 ReadFile 工作。这是我的驱动调度函数:

NTSTATUS DriverDispatch(PDEVICE_OBJECT DriverObject, PIRP irp)
{
UNREFERENCED_PARAMETER(DriverObject);
PIO_STACK_LOCATION io;
PGAME_INFO info;
NTSTATUS status = STATUS_SUCCESS;

io = IoGetCurrentIrpStackLocation(irp);
irp->IoStatus.Information = 0;

if (io->MajorFunction == IRP_MJ_WRITE)
{
    io = IoGetCurrentIrpStackLocation(irp);

    CHAR buffer[14] = "Got request\r\n";
    ULONG cb = 14;

    ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, buffer, cb, NULL, NULL);

    if (io)
    {
        info = (PGAME_INFO)irp->AssociatedIrp.SystemBuffer;
        if (info)
        {
            HANDLE Pid = info->pid;
            cb = 20;

            ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, Pid, cb, NULL, NULL);

            status = STATUS_SUCCESS;
        }
        else
        {
            CHAR buffer2[20] = "Struct was null\r\n";
            cb = 20;

            ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, buffer2, cb, NULL, NULL);
        }
    }
    else
    {
        CHAR buffer3[31] = "PIO_STACK_LOCATION is null\r\n";
        cb = 31;

        ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, buffer3, cb, NULL, NULL);
    }

    irp->IoStatus.Information = sizeof(GAME_INFO);
}
else 
{
    status = STATUS_SUCCESS;
}

irp->IoStatus.Status = status;

IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}

这是我正在使用的结构:

typedef struct _GAME_INFO {
HANDLE pid;
}GAME_INFO, *PGAME_INFO;

还有我的用户模式应用:

int main()
{
GAME_INFO GameInfo;

HANDLE hDevice = CreateFile("\\\\.\\Driver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hDevice == INVALID_HANDLE_VALUE)
{
    printf("\nError: Unable to connect to the driver (%d)\n", GetLastError());
    getchar();
    return -1;
}

getchar();

GameInfo.pid = (HANDLE)1234;
DWORD written;

if (!WriteFile(hDevice, &GameInfo, sizeof(GAME_INFO), &written, NULL))
{
    printf("\nError: Unable to write data to the driver (%d)\n", GetLastError());

    CloseHandle(hDevice);
    getchar();
    return -1;
}
else 
{
    printf("%lu", written);
    getchar();
}

CloseHandle(hDevice);
return 0;
}

驱动程序正在接收请求,但由于某种原因结构为空。我是内核驱动程序和一般 C 的新手,所以请随时纠正我的任何问题

【问题讨论】:

  • 当你打印出written时,它会打印什么?
  • 这只是测试的东西,它打印出通过WriteFile写入的缓冲区的大小。
  • 我只是想确保它打印出您所期望的。我会从你的回复中假设它确实如此。下一个问题:你是在驱动中使用直接IO还是缓冲IO?
  • 顺便说一句,你的“得到请求”字符串处理容易出错。养成做类似CHAR buffer[] = "Got request\r\n"; ULONG cb = sizeof(buffer); 的习惯,这样您或其他任何人都可以简单地更改字符串,其余的都是自动的。
  • 我正在使用直接,因为缓冲是 BSODing 我的电脑出现错误 KMODE_EXCEPTION_NOT_HANDLED

标签: c kernel driver


【解决方案1】:

基于一点点来回,这似乎是因为驱动 IO 设置为直接而不是缓冲。没有直接的系统缓冲区,因为它实际上没有缓冲,因此该字段应为 NULL。

接收代码需要通过 MDL 代替。

请参阅https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-mdls 了解起点。

【讨论】:

  • 我尝试使用 MmGetSystemAddressForMdlSafe,但它也不起作用。
  • @Smurfy - 实际上你的设备也没有使用直接 io。 DO_BUFFERED_IODO_DIRECT_IO 均未设置。所以你需要使用Irp->UserBuffer 来访问用户缓冲区。还因为看起来您总是同步处理请求 - 更好地使用快速 io 处理程序。对于使用FastIoReadFastIoWrite,您还需要将文件对象上的PrivateCacheMap 设置为任何非0 值。如果使用FastIoDeviceControl,则不需要PrivateCacheMap的技巧
猜你喜欢
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多