Я создал устройство в пространстве ядра и получил к нему доступ в пользовательском пространстве, используя CreateFile
. Я могу отправить ioctl драйверу, и они выполняются правильно. Не знаю, как отследить, что происходит после WdfRequestComplete
, и по возвращении я заканчиваю с ошибкой 1 (недопустимая функция). Прежде чем это будет помечено как дубликат, обратите внимание, что есть разница с этим в том, что я пишу свой драйвер ioctl, и в том, что я использую синхронизацию ввода-вывода, а не асинхронность.
В пространстве пользователя:
fd = CreateFile(dev_path,
(FILE_GENERIC_READ | FILE_GENERIC_WRITE),
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL, OPEN_EXISTING, 0, NULL);
// ... error checking code here
DeviceIoControl(fd, // device handler
VIRTQC_CMD_MMAP, // command to send
&inputBuffer,
inputBufferLength,
&outputBuffer,
outputBufferLength,
&returnLength,
(LPOVERLAPPED)NULL); // overlapped structure not needed using sync io
и в пространстве ядра
status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &inputBuffer, NULL);
if (!NT_SUCCESS(status))
{
WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
return;
}
inputVirtArg = (VirtioQCArg*)inputBuffer;
status = WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &outputBuffer, NULL);
if (!NT_SUCCESS(status))
{
WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
return;
}
outputVirtArg = (VirtioQCArg*)outputBuffer;
switch (IoControlCode)
{
case VIRTQC_CMD_MMAP:
if (PsGetCurrentThread() == irp->Tail.Overlay.Thread)
{
status = CreateAndMapMemory(device, &(inputVirtArg), &(outputVirtArg));
outputVirtArg->flag = (!NT_SUCCESS(status)) ? 0 : 1;
}
else
status = STATUS_UNSUCCESSFUL;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
WdfRequestComplete(Request, status);
Обновление 1:
Я пробовал WdfRequestCompleteWithInformation(Request, status, OutputBufferLength);
, но тот же результат.
Также я заметил, что адреса inputBuffer и outputBuffer совпадают.
Обновление 2: я пытался сделать
temp = ExAllocatePoolWithTag(
NonPagedPool,
PAGE_SIZE,
MEMORY_TAG
);
// other code to
RtlCopyMemory((VirtioQCArg*)outputBuffer, temp, OutputBufferLength);
все равно получаю ошибку 1
outputBuffer = irp->AssociatedIrp.SystemBuffer
вместоWdfRequestRetrieveOutputBuffer
, но я не знаю, почему. Я использовал DbgPrint и проследил с помощью windbg, чтобы проверить, почему я все еще получаю ошибку 1, но все, кажется, выполняется правильно в EvtIoDeviceControl. - person Luis   schedule 24.04.2016