コード例 #1
0
//读操作
VOID RamDiskEvtIoRead(IN WDFQUEUE Queue,IN WDFREQUEST Request,IN size_t Length)
{
    PDEVICE_EXTENSION      devExt = QueueGetExtension(Queue)->DeviceExtension;
    //从队列对象获得设备扩展
    NTSTATUS               Status = STATUS_INVALID_PARAMETER;
    WDF_REQUEST_PARAMETERS Parameters;
    LARGE_INTEGER          ByteOffset;
    WDFMEMORY              hMemory;

    //__analysis_assume(Length > 0);
    //参数清0
    WDF_REQUEST_PARAMETERS_INIT(&Parameters);
    //从请求中获取信息
    WdfRequestGetParameters(Request, &Parameters);
    //读取偏移
    ByteOffset.QuadPart = Parameters.Parameters.Read.DeviceOffset;
    //检测读取是否合法
    if (RamDiskCheckParameters(devExt, ByteOffset, Length))
    {
        //获得内存状态
        Status = WdfRequestRetrieveOutputMemory(Request, &hMemory);
        if(NT_SUCCESS(Status))
        {
            // Destination # Offset into the destination # source
            Status = WdfMemoryCopyFromBuffer(hMemory,0, devExt->DiskImage + ByteOffset.LowPart, Length);
        }
    }

    WdfRequestCompleteWithInformation(Request, Status, (ULONG_PTR)Length);
}
コード例 #2
0
ファイル: ramdisk.c プロジェクト: SouthernIslands/learngit
VOID
RamDiskEvtIoRead(
    IN WDFQUEUE Queue,
    IN WDFREQUEST Request,
    IN size_t Length
    )
/*++

Routine Description:

    This event is called when the framework receives IRP_MJ_READ request.

Arguments:

    Queue -  Handle to the framework queue object that is associated with the
             I/O request.

    Request - Handle to a framework request object.

    Length - Length of the data buffer associated with the request.
             The default property of the queue is to not dispatch
             zero length read & write requests to the driver and
             complete is with status success. So we will never get
             a zero length request.

Return Value:

    VOID

--*/
{
    PDEVICE_EXTENSION      devExt = QueueGetExtension(Queue)->DeviceExtension;
    NTSTATUS               Status = STATUS_INVALID_PARAMETER;
    WDF_REQUEST_PARAMETERS Parameters;
    LARGE_INTEGER          ByteOffset;
    WDFMEMORY              hMemory;

    _Analysis_assume_(Length > 0);

    WDF_REQUEST_PARAMETERS_INIT(&Parameters);
    WdfRequestGetParameters(Request, &Parameters);

    ByteOffset.QuadPart = Parameters.Parameters.Read.DeviceOffset;

    if (RamDiskCheckParameters(devExt, ByteOffset, Length)) {

        Status = WdfRequestRetrieveOutputMemory(Request, &hMemory);
        if(NT_SUCCESS(Status)){

            Status = WdfMemoryCopyFromBuffer(hMemory,   // Destination
                                             0,         // Offset into the destination
                                             devExt->DiskImage + ByteOffset.LowPart, // source
                                             Length);
        }
    }

    WdfRequestCompleteWithInformation(Request, Status, (ULONG_PTR)Length);
}
コード例 #3
0
ファイル: queue.c プロジェクト: 340211173/Driver
VOID
EchoEvtIoRead(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN size_t      Length
    )
/*++

Routine Description:

    This event is called when the framework receives IRP_MJ_READ request.
    It will copy the content from the queue-context buffer to the request buffer.
    If the driver hasn't received any write request earlier, the read returns zero.

Arguments:

    Queue -  Handle to the framework queue object that is associated with the
             I/O request.

    Request - Handle to a framework request object.

    Length  - number of bytes to be read.
              The default property of the queue is to not dispatch
              zero lenght read & write requests to the driver and
              complete is with status success. So we will never get
              a zero length request.

Return Value:

    VOID

--*/
{
    NTSTATUS Status;
    PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);
    WDFMEMORY memory;
    size_t writeMemoryLength;

    _Analysis_assume_(Length > 0);

    KdPrint(("EchoEvtIoRead Called! Queue 0x%p, Request 0x%p Length %d\n",
             Queue,Request,Length));
    //
    // No data to read
    //
    if( (queueContext->WriteMemory == NULL)  ) {
        WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, (ULONG_PTR)0L);
        return;
    }

    //
    // Read what we have
    //
    WdfMemoryGetBuffer(queueContext->WriteMemory, &writeMemoryLength);
    _Analysis_assume_(writeMemoryLength > 0);

    if( writeMemoryLength < Length ) {
        Length = writeMemoryLength;
    }

    //
    // Get the request memory
    //
    Status = WdfRequestRetrieveOutputMemory(Request, &memory);
    if( !NT_SUCCESS(Status) ) {
        KdPrint(("EchoEvtIoRead Could not get request memory buffer 0x%x\n", Status));
        WdfVerifierDbgBreakPoint();
        WdfRequestCompleteWithInformation(Request, Status, 0L);
        return;
    }

    // Copy the memory out
    Status = WdfMemoryCopyFromBuffer( memory, // destination
                             0,      // offset into the destination memory
                             WdfMemoryGetBuffer(queueContext->WriteMemory, NULL),
                             Length );
    if( !NT_SUCCESS(Status) ) {
        KdPrint(("EchoEvtIoRead: WdfMemoryCopyFromBuffer failed 0x%x\n", Status));
        WdfRequestComplete(Request, Status);
        return;
    }

    // Set transfer information
    WdfRequestSetInformation(Request, (ULONG_PTR)Length);

    // Mark the request is cancelable
    WdfRequestMarkCancelable(Request, EchoEvtRequestCancel);


    // Defer the completion to another thread from the timer dpc
    queueContext->CurrentRequest = Request;
    queueContext->CurrentStatus  = Status;

    return;
}
コード例 #4
0
// Finds the Report descriptor and copies it into the buffer provided by the Request.
//
NTSTATUS HidFx2GetReportDescriptor(_In_ WDFDEVICE hDevice, _In_ WDFREQUEST hRequest)
{
    NTSTATUS                status = STATUS_SUCCESS;
    WDFMEMORY               memory;
    PDEVICE_EXTENSION       pDevContext = NULL;
    PVOID                   pBuffer = (PVOID)c_ButtonDescriptor;
    size_t                  cBytesToCopy = sizeof(c_ButtonDescriptor);


    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Entry\n");

    status = WdfRequestRetrieveOutputMemory(hRequest, &memory);
    if (NT_SUCCESS(status))
    {
        pDevContext = GetDeviceContext(hDevice);
        if (pDevContext != NULL)
        {
           // Select a non default report descriptor
            switch (pDevContext->driverMode)
            {
            case DM_BUTTON_AND_LED:
                pBuffer = (PVOID)c_ButtonWithLedDescriptor;
                cBytesToCopy = sizeof(c_ButtonWithLedDescriptor);
                break;
            case DM_SLIDER_SWITCH:
                pBuffer = (PVOID)c_SliderSwitchDescriptor;
                cBytesToCopy = sizeof(c_SliderSwitchDescriptor);
                break;
            case DM_SLIDER_SWITCH_AND_LED:
                pBuffer = (PVOID)c_SliderSwitchWithLedDescriptor;
                cBytesToCopy = sizeof(c_SliderSwitchWithLedDescriptor);
                break;
            case DM_LED_ONLY:
                pBuffer = (PVOID)c_LedOnlyDescriptor;
                cBytesToCopy = sizeof(c_LedOnlyDescriptor);
                break;
            default:
                break;
            }
        }
        if (cBytesToCopy != 0)
        {
            status = WdfMemoryCopyFromBuffer(memory, 0, pBuffer, cBytesToCopy);
            if (NT_SUCCESS(status))
            {
                // Report how many bytes were copied
                WdfRequestSetInformation(hRequest, cBytesToCopy);
            }
            else // WdfMemoryCopyFromBuffer failed
            {
                TraceErr(DBG_IOCTL, "(%!FUNC!) WdfMemoryCopyFromBuffer failed %!STATUS!\n", status);
            }
        }
        else // report length is zero
        {
            status = STATUS_INVALID_DEVICE_STATE;
            TraceErr(DBG_IOCTL, "(%!FUNC!) c_DefaultHidDescriptor's reportLength is zero, %!STATUS!\n", status);
        }
    }
    else // WdfRequestRetrieveOutputMemory failed
    {
        TraceErr(DBG_IOCTL, "(%!FUNC!)WdfRequestRetrieveOutputMemory failed %!STATUS!\n", status);

    }

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit = %!STATUS!\n", status);
    return status;
}
コード例 #5
0
// Finds the HID descriptor and copies it into the buffer provided by the Request.
//
NTSTATUS HidFx2GetHidDescriptor(_In_ WDFDEVICE hDevice, _In_ WDFREQUEST hRequest)
{
    NTSTATUS            status = STATUS_SUCCESS;
    size_t              cBytesToCopy = 0;
    WDFMEMORY           memory;
    PDEVICE_EXTENSION   pDevContext = NULL;
    HID_DESCRIPTOR      hidDescriptor;


    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Entry\n");

    status = WdfRequestRetrieveOutputMemory(hRequest, &memory);
    if (NT_SUCCESS(status))
    {
        hidDescriptor.bLength= sizeof(hidDescriptor);               // length of HID descriptor
        hidDescriptor.bDescriptorType= HID_HID_DESCRIPTOR_TYPE;     // descriptor type == HID  0x21
        hidDescriptor.bcdHID= HID_CLASS_SPEC_RELEASE_1_00;          // hid spec release
        hidDescriptor.bCountry= HID_COUNTRY_NON_LOCALIZED;          // country code
        hidDescriptor.bNumDescriptors= 0x01;                        // number of HID class descriptors
        hidDescriptor.DescriptorList[0].bReportType =HID_REPORT_DESCRIPTOR_TYPE;
        hidDescriptor.DescriptorList[0].wReportLength = sizeof(c_ButtonDescriptor);

        pDevContext = GetDeviceContext(hDevice);
        if (pDevContext != NULL)
        {
        // Set length of non default report descriptor
            switch (pDevContext->driverMode)
            {
            case DM_BUTTON_AND_LED:
                hidDescriptor.DescriptorList[0].wReportLength = sizeof(c_ButtonWithLedDescriptor);
                break;
            case DM_SLIDER_SWITCH:
                hidDescriptor.DescriptorList[0].wReportLength = sizeof(c_SliderSwitchDescriptor);
                break;
            case DM_SLIDER_SWITCH_AND_LED:
                hidDescriptor.DescriptorList[0].wReportLength = sizeof(c_SliderSwitchWithLedDescriptor);
                break;
            case DM_LED_ONLY:
                hidDescriptor.DescriptorList[0].wReportLength = sizeof(c_LedOnlyDescriptor);
                break;
            default:
                break;
            }
        }
        cBytesToCopy = hidDescriptor.bLength;
        if (cBytesToCopy != 0)
        {
            status = WdfMemoryCopyFromBuffer(memory, 0, (PVOID)&hidDescriptor, cBytesToCopy);
            if (NT_SUCCESS(status))
            {
                // Report how many bytes were copied
                WdfRequestSetInformation(hRequest, cBytesToCopy);
            }
            else // WdfMemoryCopyFromBuffer failed
            {
                TraceErr(DBG_IOCTL, "(%!FUNC!) WdfMemoryCopyFromBuffer failed %!STATUS!\n", status);
                return status;
            }
        }
        else // length is zero
        {
            status = STATUS_INVALID_DEVICE_STATE;
            TraceErr(DBG_IOCTL, "(%!FUNC!) c_DefaultHidDescriptor is zero, %!STATUS!\n", status);
            return status;
        }

    }
    else // WdfRequestRetrieveOutputMemory failed
    {
        TraceErr(DBG_IOCTL, " (%!FUNC!) WdfRequestRetrieveOutputMemory failed %!STATUS!\n", status);
        return status;
    }

    TraceVerbose(DBG_IOCTL, " (%!FUNC!) HidFx2GetHidDescriptor Exit = %!STATUS!\n", status);
    return status;
}
コード例 #6
0
ファイル: Queue.c プロジェクト: killbug2004/thundergate
VOID
tgwinkEvtIoDeviceControl(
    _In_ WDFQUEUE Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t OutputBufferLength,
    _In_ size_t InputBufferLength,
    _In_ ULONG IoControlCode
    )
{
    WDFMEMORY mem;
    NTSTATUS status;
    WDFDEVICE dev;
    PDEVICE_CONTEXT context;
    void *uBase = NULL;
    LARGE_INTEGER offset;
    size_t size;

    dev = WdfIoQueueGetDevice(Queue);
    context = DeviceGetContext(dev);

    switch (IoControlCode) {
    case IOCTL_TGWINK_SAY_HELLO:
        
        if (OutputBufferLength != 4) {
            WdfRequestComplete(Request, STATUS_BAD_DATA);
            break;
        }

        status = WdfRequestRetrieveOutputMemory(Request, &mem);
        if (!NT_SUCCESS(status)) {
            KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status);
            WdfVerifierDbgBreakPoint();
            WdfRequestComplete(Request, status);
            break;
        }

        *((DWORD32 *)(WdfMemoryGetBuffer(mem, NULL))) = 0x5a5aa5a5;
        WdfRequestComplete(Request, STATUS_SUCCESS);
        break;

    case IOCTL_TGWINK_MAP_BAR_0:
        if (sizeof(void *) > OutputBufferLength) {
            KdPrint("tgwinkEvtIoDeviceControl needs a larger buffer (%d > %d)!\n", sizeof(void *), OutputBufferLength);
            WdfRequestComplete(Request, STATUS_BUFFER_TOO_SMALL);
            break;
        }

        offset = context->bar[0].phyAddr;
        size = context->bar[0].length;

        status = ZwMapViewOfSection(context->hMemory, ZwCurrentProcess(), &uBase, 0, 0, &offset, &size, ViewUnmap, 0, PAGE_READWRITE);
        if (!NT_SUCCESS(status)) {

            KdPrint("tgwinkEvtIoDeviceControl could not map view of section, status ");
            switch (status) {
            case STATUS_CONFLICTING_ADDRESSES: 
                KdPrint("STATUS_CONFLICTING_ADDRESSES\n"); 
                break;
            case STATUS_INVALID_PAGE_PROTECTION: 
                KdPrint("STATUS_INVALID_PAGE_PROTECTION\n"); 
                break;
            case STATUS_SECTION_PROTECTION: 
                KdPrint("STATUS_SECTION_PROTECTION\n"); 
                break;
            default: 
                KdPrint("0x % x\n", status); 
                break;
            }
            WdfRequestComplete(Request, status);
            break;
        }

        status = WdfRequestRetrieveOutputMemory(Request, &mem);
        if (!NT_SUCCESS(status)) {
            KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status);
            WdfVerifierDbgBreakPoint();
            WdfRequestComplete(Request, status);
            break;
        }

        *((void **)(WdfMemoryGetBuffer(mem, NULL))) = uBase;

        WdfRequestComplete(Request, STATUS_SUCCESS);
        break;

    case IOCTL_TGWINK_READ_PHYS:
    {
        PVOID buf;
        ULONG_PTR page, ofs, vtgt = 0;
        SIZE_T vsz = 0;

        if (InputBufferLength != sizeof(PVOID)) {
            KdPrint("tgwinkEvtIoDeviceControl requires a %d-byte buffer for this ioctl (got %d)\n", sizeof(PVOID), OutputBufferLength);
            WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES);
            break;
        }
        
        status = WdfRequestRetrieveInputBuffer(Request, sizeof(PVOID), &buf, NULL);
        if (!NT_SUCCESS(status)) {
            KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status);
            WdfRequestComplete(Request, status);
            break;
        }

        ofs = *((ULONG_PTR *)buf);
        page = ofs & ~0xfff;
        vsz = OutputBufferLength + (page ^ ofs);
        buf = NULL;

        status = WdfRequestRetrieveOutputMemory(Request, &mem);
        if (!NT_SUCCESS(status)) {
            KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status);
            WdfRequestComplete(Request, status);
            break;
        }

        status = ZwMapViewOfSection(context->hMemory, (HANDLE)-1, (PVOID *)&vtgt, 0, 0, (PLARGE_INTEGER)&page, &vsz, ViewUnmap, 0, PAGE_READONLY);
        if (!NT_SUCCESS(status)) {
            KdPrint("tgwinkEvtIoDeviceControl could not map view of physical memory section, status 0x%x\n", status);
            WdfRequestComplete(Request, status);
            break;
        }

        ofs -= page;
        status = WdfMemoryCopyFromBuffer(mem, 0, (PVOID)(vtgt + ofs), OutputBufferLength);
        if (!NT_SUCCESS(status)) {
            KdPrint("tgwinkEvtIoDeviceControl failed to copy data from memory to buffer, status 0x%x\n", status);
            WdfRequestComplete(Request, status);
            break;
        }

        status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)vtgt);
        if (!NT_SUCCESS(status)) {
            KdPrint("tgwinkEvtIoDeviceControl failed to unmap view of physical memory section, status 0x%x\n", status);
            WdfRequestComplete(Request, status);
            break;
        }
    
        WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, OutputBufferLength);
    } break;

    case IOCTL_TGWINK_PEND_INTR:
    {
        WdfWaitLockAcquire(context->nnLock, NULL);
        if (context->notifyNext) {
            PINTERRUPT_CONTEXT pCtx = InterruptGetContext(context->hIrq);
            status = WdfRequestRetrieveOutputMemory(Request, &mem);
            if (!NT_SUCCESS(status)) {
                KdPrint("tgwinkEvtIoDeviceControl failed to retrieve output memory, status 0x%x\n", status);
                WdfRequestComplete(Request, status);
            }
            status = WdfMemoryCopyFromBuffer(mem, 0, &pCtx->serial, 8);
            if (!NT_SUCCESS(status)) {
                KdPrint("tgwinkEvtIoDeviceControl failed to copy interrupt number to buffer, status 0x%x\n", status);
                WdfRequestComplete(Request, status);
            }
            WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 8);
            context->notifyNext = 0;
            KdPrint("tgwinkEvtIoDeviceControl satisfied interrupt notification request synchronously.\n");
            //WdfInterruptEnable(context->hIrq);
        } else {
            KdPrint("tgwinkEvtIoDeviceControl forwarding PEND_INTR request to notification queue\n");
            WdfRequestForwardToIoQueue(Request, context->NotificationQueue);
        }
        WdfWaitLockRelease(context->nnLock);
    } break;

    default:
        WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
    }
}
コード例 #7
0
ファイル: kbfiltr.c プロジェクト: 340211173/Driver
VOID
KbFilter_EvtIoDeviceControlFromRawPdo(
    IN WDFQUEUE      Queue,
    IN WDFREQUEST    Request,
    IN size_t        OutputBufferLength,
    IN size_t        InputBufferLength,
    IN ULONG         IoControlCode
    )
/*++

Routine Description:

    This routine is the dispatch routine for device control requests.

Arguments:

    Queue - Handle to the framework queue object that is associated
            with the I/O request.
    Request - Handle to a framework request object.

    OutputBufferLength - length of the request's output buffer,
                        if an output buffer is available.
    InputBufferLength - length of the request's input buffer,
                        if an input buffer is available.

    IoControlCode - the driver-defined or system-defined I/O control code
                    (IOCTL) that is associated with the request.

Return Value:

   VOID

--*/
{
    NTSTATUS status = STATUS_SUCCESS;
    WDFDEVICE hDevice;
    WDFMEMORY outputMemory;
    PDEVICE_EXTENSION devExt;
    size_t bytesTransferred = 0;

    UNREFERENCED_PARAMETER(InputBufferLength);

    DebugPrint(("Entered KbFilter_EvtIoInternalDeviceControl\n"));

    hDevice = WdfIoQueueGetDevice(Queue);
    devExt = FilterGetData(hDevice);

    //
    // Process the ioctl and complete it when you are done.
    //

    switch (IoControlCode) {
    case IOCTL_KBFILTR_GET_KEYBOARD_ATTRIBUTES:
        
        //
        // Buffer is too small, fail the request
        //
        if (OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES)) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        status = WdfRequestRetrieveOutputMemory(Request, &outputMemory);
        
        if (!NT_SUCCESS(status)) {
            DebugPrint(("WdfRequestRetrieveOutputMemory failed %x\n", status));
            break;
        }
        
        status = WdfMemoryCopyFromBuffer(outputMemory,
                                    0,
                                    &devExt->KeyboardAttributes,
                                    sizeof(KEYBOARD_ATTRIBUTES));

        if (!NT_SUCCESS(status)) {
            DebugPrint(("WdfMemoryCopyFromBuffer failed %x\n", status));
            break;
        }

        bytesTransferred = sizeof(KEYBOARD_ATTRIBUTES);
        
        break;    
    default:
        status = STATUS_NOT_IMPLEMENTED;
        break;
    }
    
    WdfRequestCompleteWithInformation(Request, status, bytesTransferred);

    return;
}