Ich habe ein Gerät im Kernelraum erstellt und den Zugriff im Userspace mit CreateFile
Ich bin in der Lage, ioctl an den Treiber zu senden, und sie werden ordnungsgemäß ausgeführt. Das weiß nicht, wie man verfolgt, was nach WdfRequestComplete
passiert und bei der Rückkehr beende ich mit Fehler 1 (ungültige Funktion). Bevor dies als dup markiert wird, beachten Sie bitte, dass es einen Unterschied mit this gibt, in dem ich meinen Treiber ioctl schreibe und in dem ich synch io nicht asynch benutze.DeviceIoControl Fehler 1 falsche Funktion
im User-Space:
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
und in Kernel Raum
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);
Update 1:
ich versucht habe WdfRequestCompleteWithInformation(Request, status, OutputBufferLength);
aber dasselbe Ergebnis.
Auch ich bemerke, dass die Adresse von inputBuffer und outputBuffer die gleichen sind.
Update 2: Ich habe versucht zu tun
temp = ExAllocatePoolWithTag(
NonPagedPool,
PAGE_SIZE,
MEMORY_TAG
);
// other code to
RtlCopyMemory((VirtioQCArg*)outputBuffer, temp, OutputBufferLength);
noch Fehler 1
Sie müssen mit einer grundlegenden Fehlerbehebung beginnen: Verwenden Sie DbgPrint großzügig, um zu sehen, welche Funktion fehlschlägt und mit welchem Fehlercode. Ohne diese Informationen können wir Ihnen wahrscheinlich nicht helfen. –
Ich bin in der Lage, auf das Ergebnis im Benutzerraum zuzugreifen, nachdem ich 'outputBuffer = irp-> AssociatedIrp.SystemBuffer' anstelle von 'WdfRequestRetrieveOutputBuffer' verwendet habe, aber ich weiß nicht warum. Ich habe DbgPrint verwendet und mit windbg verfolgt, um zu überprüfen, warum ich immer noch Fehler 1 bekomme, aber alles scheint in EvtIoDeviceControl korrekt ausgeführt zu werden. – Luis
Welchen Datenübertragungstyp verwendet die IOCTL? Siehe https://msdn.microsoft.com/en-us/library/windows/hardware/ff540663(v=vs.85).aspx? –