2016-04-22 28 views
1

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

+0

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. –

+0

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

+0

Welchen Datenübertragungstyp verwendet die IOCTL? Siehe https://msdn.microsoft.com/en-us/library/windows/hardware/ff540663(v=vs.85).aspx? –

Antwort

1

erhalten hatte ich meine ioctl cmds als Aufzählungen in meinem Linux-Treiber definiert (was gut funktioniert) und wenn der Fahrer in den Fenstern der Umsetzung Ich habe die gleiche Definition verwendet.

enum 
{ 
    // Module & Execution control (driver API) 
    VIRTIQC_SET = 200, 
    VIRTIQC_UNSET, 
    // more cmds..... 
} 

In Fenstern, die Steuercodes definieren, ein wenig mehr. Wie in here erläutert, sollte das Makro CTL_CODE verwendet werden, um neue IOCTL-Steuercodes zu definieren.

#define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)

In meinem Fall habe ich mit der Definition dieses endete:

#define VIRTQC_MAP CTL_CODE(FILE_DEVICE_NETWORK, 0xC8, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA) 
#define VIRTQC_UNMAP CTL_CODE(FILE_DEVICE_NETWORK, 0xC9, METHOD_OUT_DIRECT, FILE_READ_DATA) 

Ich kenne den Funktionscode weniger als 0x800 für MS reserviert sind, aber das Gerät auf meinem Host erfordert dieses Codes, so I‘ Ich gebe nur, was gefragt wird.

+1

Für die Aufzeichnung müssen die IOCTL-Codes nicht den Hardware-Codes entsprechen, so dass es wahrscheinlich sicher wäre, die richtige Nummerierung zu verwenden. –