_Use_decl_annotations_
VOID MouFilter_IoRead(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length)
{
	PDEVICE_EXTENSION devExt;
	MOUSE_REPORT* mouseReport;
	NTSTATUS status = STATUS_SUCCESS;
	WDFDEVICE hDevice;

	UNREFERENCED_PARAMETER(Length);

	PAGED_CODE();

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

	status = WdfRequestRetrieveOutputBuffer(Request, sizeof(MOUSE_REPORT), (void**) &mouseReport, NULL);

	if (!NT_SUCCESS(status)){
		DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status));
	} else {
		DebugPrint(("Setting mouse report data to (%d, %d)", 50, 50));
		mouseReport->xData = 50;
		mouseReport->yData = 50;
		mouseReport->ReportId = 0x01;
	}

	WdfRequestComplete(Request, status);
}
Пример #2
0
VOID VIOSerialPortWriteRequestCancel(IN WDFREQUEST Request)
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(
        WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)))->port;
    PSINGLE_LIST_ENTRY iter;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: 0x%p\n",
        __FUNCTION__, Request);

    // synchronize with VIOSerialReclaimConsumedBuffers because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(Port->OutVqLock);
    iter = &Port->WriteBuffersList;
    while ((iter = iter->Next) != NULL)
    {
        PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter, WRITE_BUFFER_ENTRY, ListEntry);
        if (entry->Request == Request)
        {
            entry->Request = NULL;
            break;
        }
    }
    WdfSpinLockRelease(Port->OutVqLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
Пример #3
0
VOID VIOSerialPortWriteIoStop(IN WDFQUEUE Queue,
                              IN WDFREQUEST Request,
                              IN ULONG ActionFlags)
{
   PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData(
      WdfIoQueueGetDevice(Queue));
   PVIOSERIAL_PORT pport = pdoData->port;

   TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "--> %s\n", __FUNCTION__);

   WdfSpinLockAcquire(pport->OutVqLock);
   if (ActionFlags & WdfRequestStopActionSuspend)
   {
      WdfRequestStopAcknowledge(Request, FALSE);
   }
   else if (ActionFlags & WdfRequestStopActionPurge)
   {
      if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED)
      {
         pport->PendingWriteRequest = NULL;
         WdfRequestComplete(Request, STATUS_OBJECT_NO_LONGER_EXISTS);
      }
   }
   WdfSpinLockRelease(pport->OutVqLock);

   TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
VOID
VIOSerialPortIoStop(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN ULONG      ActionFlags
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(Queue));
    PVIOSERIAL_PORT    pport = pdoData->port;

    ASSERT(pport->PendingReadRequest == Request);
    TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "-->%s\n", __FUNCTION__);

    WdfSpinLockAcquire(pport->InBufLock);
    if (ActionFlags &  WdfRequestStopActionSuspend )
    {
        WdfRequestStopAcknowledge(Request, FALSE);
    }
    else if(ActionFlags &  WdfRequestStopActionPurge)
    {
        if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED)
        {
           pport->PendingReadRequest = NULL;
           WdfRequestCompleteWithInformation(Request , STATUS_CANCELLED, 0L);
        }
    }
    WdfSpinLockRelease(pport->InBufLock);
    return;
}
VOID
VIOSerialPortReadRequestCancel(
    IN WDFREQUEST Request
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)));
    BOOLEAN reqComplete = FALSE;

    TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "-->%s called on request 0x%p\n", __FUNCTION__, Request);

    WdfSpinLockAcquire(pdoData->port->InBufLock);
    ASSERT(pdoData->port->PendingReadRequest == Request);
    if (pdoData->port->PendingReadRequest)
    {
        pdoData->port->PendingReadRequest = NULL;
        reqComplete = TRUE;
    }
    WdfSpinLockRelease(pdoData->port->InBufLock);

    if (reqComplete)
    {
        WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);
    }
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE,"<-- %s\n", __FUNCTION__);
    return;
}
Пример #6
0
// Fill in the given struct _HID_DEVICE_ATTRIBUTES
//
NTSTATUS HidFx2GetDeviceAttributes(_In_ WDFREQUEST hRequest)
{
    NTSTATUS                 status = STATUS_SUCCESS;
    PHID_DEVICE_ATTRIBUTES   pDeviceAttributes = NULL;
    PUSB_DEVICE_DESCRIPTOR   pUsbDeviceDescriptor = NULL;
    PDEVICE_EXTENSION        pDeviceInfo = NULL;

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

    pDeviceInfo = GetDeviceContext(WdfIoQueueGetDevice(WdfRequestGetIoQueue(hRequest)));
    status = WdfRequestRetrieveOutputBuffer(hRequest, sizeof (HID_DEVICE_ATTRIBUTES), &pDeviceAttributes, NULL);
    if (NT_SUCCESS(status))
    {
        // Retrieve USB device descriptor saved in device context
        pUsbDeviceDescriptor = WdfMemoryGetBuffer(pDeviceInfo->hDeviceDescriptor, NULL);
        pDeviceAttributes->Size = sizeof (HID_DEVICE_ATTRIBUTES);
        pDeviceAttributes->VendorID = pUsbDeviceDescriptor->idVendor;
        pDeviceAttributes->ProductID = pUsbDeviceDescriptor->idProduct;
        pDeviceAttributes->VersionNumber = pUsbDeviceDescriptor->bcdDevice;
        // Report how many bytes were copied
        WdfRequestSetInformation(hRequest, sizeof (HID_DEVICE_ATTRIBUTES));
    }
    else // WdfRequestRetrieveOutputBuffer failed
    {
        TraceErr(DBG_IOCTL, "(%!FUNC!) WdfRequestRetrieveOutputBuffer failed %!STATUS!\n", status);
    }

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit = %!STATUS!\n", status);
    return status;
}
Пример #7
0
VOID
XenUsb_EvtRequestCancelPvUrb(WDFREQUEST request) {
  WDFDEVICE device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(request));
  PXENUSB_DEVICE_DATA xudd = GetXudd(device);
  WDF_REQUEST_PARAMETERS wrp;
  partial_pvurb_t *partial_pvurb;
  pvurb_t *pvurb;
  KIRQL old_irql;

  FUNCTION_ENTER();
  FUNCTION_MSG("cancelling request %p\n", request);

  WDF_REQUEST_PARAMETERS_INIT(&wrp);
  KeAcquireSpinLock(&xudd->urb_ring_lock, &old_irql);

  WdfRequestGetParameters(request, &wrp);
  pvurb = (pvurb_t *)wrp.Parameters.Others.Arg1;
  FUNCTION_MSG("pvurb = %p\n", pvurb);
  ASSERT(pvurb);

  partial_pvurb = (partial_pvurb_t *)xudd->partial_pvurb_queue.Flink;
  while (partial_pvurb != (partial_pvurb_t *)&xudd->partial_pvurb_queue) {
    partial_pvurb_t *next_partial_pvurb = (partial_pvurb_t *)partial_pvurb->entry.Flink;
    ASSERT(!partial_pvurb->on_ring);
    FUNCTION_MSG("partial_pvurb = %p is not yet on ring\n", partial_pvurb);
    RemoveEntryList(&partial_pvurb->entry);
    ExFreePoolWithTag(partial_pvurb, XENUSB_POOL_TAG);
    pvurb->ref--;
    partial_pvurb = next_partial_pvurb;
  }
  partial_pvurb = (partial_pvurb_t *)xudd->partial_pvurb_ring.Flink;
  while (partial_pvurb != (partial_pvurb_t *)&xudd->partial_pvurb_ring) {
    partial_pvurb_t *next_partial_pvurb = (partial_pvurb_t *)partial_pvurb->entry.Flink;
    partial_pvurb_t *partial_pvurb_cancel;
    FUNCTION_MSG("partial_pvurb = %p is on ring\n", partial_pvurb);
    ASSERT(partial_pvurb->on_ring);
    partial_pvurb_cancel = ExAllocatePoolWithTag(NonPagedPool, sizeof(*partial_pvurb_cancel), XENUSB_POOL_TAG); /* todo - use lookaside */
    ASSERT(partial_pvurb_cancel); /* what would we do if this failed? */
    partial_pvurb_cancel->req = partial_pvurb->req;
    partial_pvurb_cancel->req.pipe = usbif_setunlink_pipe(partial_pvurb_cancel->req.pipe);
    partial_pvurb_cancel->req.u.unlink.unlink_id = partial_pvurb->req.id;
    partial_pvurb_cancel->pvurb = pvurb;
    partial_pvurb_cancel->mdl = NULL;
    partial_pvurb_cancel->other_partial_pvurb = partial_pvurb;
    partial_pvurb->other_partial_pvurb = partial_pvurb_cancel;
    partial_pvurb_cancel->on_ring = FALSE;
    pvurb->ref++;
    InsertHeadList(&xudd->partial_pvurb_queue, &partial_pvurb_cancel->entry);
    partial_pvurb = next_partial_pvurb;
  }
  if (pvurb->ref) {
    PutRequestsOnRing(xudd);
    KeReleaseSpinLock(&xudd->urb_ring_lock, old_irql);
  } else {
    KeReleaseSpinLock(&xudd->urb_ring_lock, old_irql);
    WdfRequestComplete(request, STATUS_CANCELLED);
  }
  FUNCTION_EXIT();
}
Пример #8
0
VOID
DefaultQueue_EvtIoDeviceControl(
    _In_ WDFQUEUE Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t OutputBufferLength,
    _In_ size_t InputBufferLength,
    _In_ ULONG IoControlCode
    )
/*++

Routine Description:

    EvtIoDeviceControl handler for the default Queue

Arguments:

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

    Request - Handle to a framework request object.

    OutputBufferLength - Size of the output buffer in bytes

    InputBufferLength - Size of the input buffer in bytes

    IoControlCode - I/O control code.

--*/
{
    WDFDEVICE WdfDevice;
    PCONTROLLER_CONTEXT ControllerContext;
    BOOLEAN HandledbyUfx;   

    TraceEntry();

    TraceVerbose("Queue 0x%p, Request 0x%p, OutputBufferLength %d, "
                  "InputBufferLength %d, IoControlCode %d",
                  Queue, Request, (int) OutputBufferLength, 
                  (int) InputBufferLength, IoControlCode);
    
    WdfDevice = WdfIoQueueGetDevice(Queue);
    ControllerContext = DeviceGetControllerContext(WdfDevice);

    HandledbyUfx = UfxDeviceIoControl(
                        ControllerContext->UfxDevice,
                        Request,
                        OutputBufferLength,
                        InputBufferLength,
                        IoControlCode);

    if (!HandledbyUfx) {
        TraceError("Recieved an unsupported IOCTL");
        WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
    }

    TraceExit();
}
Пример #9
0
VOID CY001Drv::DeviceIoControlSerial_sta(IN WDFQUEUE  Queue,
										   IN WDFREQUEST  Request,
										   IN size_t  OutputBufferLength,
										   IN size_t  InputBufferLength,
										   IN ULONG  IoControlCode)
{
	CY001Drv* pThis = (CY001Drv*)CY001Drv::GetDrvClassFromDevice(WdfIoQueueGetDevice(Queue));
	pThis->DeviceIoControlParallel(Queue, Request, OutputBufferLength, InputBufferLength, IoControlCode);
}
Пример #10
0
// Pass down Idle notification request to lower driver
//
NTSTATUS HidFx2SendIdleNotification(_In_ WDFREQUEST hRequest)
{
    NTSTATUS                   status = STATUS_SUCCESS;
    WDF_REQUEST_SEND_OPTIONS   options;
    WDFIOTARGET                hNextLowerDriver;
    WDFDEVICE                  hDevice;
    PIO_STACK_LOCATION         pCurrentIrpStack = NULL;
    IO_STACK_LOCATION          nextIrpStack;

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

    hDevice = WdfIoQueueGetDevice(WdfRequestGetIoQueue(hRequest));
    pCurrentIrpStack = IoGetCurrentIrpStackLocation(WdfRequestWdmGetIrp(hRequest));

    // Convert the request to corresponding USB Idle notification request
    if (pCurrentIrpStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO))
    {
        ASSERT(sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO) == sizeof(USB_IDLE_CALLBACK_INFO));
        #pragma warning(suppress :4127)  // conditional expression is constant warning
        if (sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO) == sizeof(USB_IDLE_CALLBACK_INFO))
        {
            // prepare next stack location
            RtlZeroMemory(&nextIrpStack, sizeof(IO_STACK_LOCATION));
            nextIrpStack.MajorFunction = pCurrentIrpStack->MajorFunction;
            nextIrpStack.Parameters.DeviceIoControl.InputBufferLength = pCurrentIrpStack->Parameters.DeviceIoControl.InputBufferLength;
            nextIrpStack.Parameters.DeviceIoControl.Type3InputBuffer = pCurrentIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
            nextIrpStack.Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
            nextIrpStack.DeviceObject = WdfIoTargetWdmGetTargetDeviceObject(WdfDeviceGetIoTarget(hDevice));

            // Format the I/O request for the driver's local I/O target by using the contents of the specified WDM I/O stack location structure.
            WdfRequestWdmFormatUsingStackLocation(hRequest, &nextIrpStack);

            // Send the request down using Fire and forget option.
            WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);
            hNextLowerDriver = WdfDeviceGetIoTarget(hDevice);
            if (WdfRequestSend(hRequest, hNextLowerDriver, &options) == FALSE)
            {
                status = STATUS_UNSUCCESSFUL;
            }
        }
        else // Incorrect DeviceIoControl.InputBufferLength
        {
            status = STATUS_INFO_LENGTH_MISMATCH;
            TraceErr(DBG_IOCTL, "(%!FUNC!) Incorrect DeviceIoControl.InputBufferLength, %!STATUS!\n", status);
            return status;
        }
    }
    else // DeviceIoControl.InputBufferLength too small
    {
        status = STATUS_BUFFER_TOO_SMALL;
        TraceErr(DBG_IOCTL, "(%!FUNC!) DeviceIoControl.InputBufferLength too small, %!STATUS!\n", status);
        return status;
    }

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit = %!STATUS!\n", status);
    return status;
}
Пример #11
0
void MouseTrapEvtIoInternalDeviceControl(WDFQUEUE queue, WDFREQUEST request, size_t outputBufferLength, size_t inputBufferLength, ULONG ioControlCode) {
	UNREFERENCED_PARAMETER(outputBufferLength);
	UNREFERENCED_PARAMETER(inputBufferLength);

	NTSTATUS status = STATUS_SUCCESS;

	PAGED_CODE(); // Ensure paging is allowed in current IRQL

	// Get extension data
	WDFDEVICE hDevice = WdfIoQueueGetDevice(queue);
	PDEVICE_CONTEXT context = DeviceGetContext(hDevice);

	if(ioControlCode == IOCTL_INTERNAL_MOUSE_CONNECT) {
		// Only allow one connection.
		if(context->UpperConnectData.ClassService == NULL) {
			// Copy the connection parameters to the device extension.
			PCONNECT_DATA connectData;
			size_t length;
			status = WdfRequestRetrieveInputBuffer(request, sizeof(CONNECT_DATA), &connectData, &length);
			if(NT_SUCCESS(status)) {
				// Hook into the report chain (I am not sure this is correct)
				context->UpperConnectData = *connectData;
				connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice);

				#pragma warning(push)
				#pragma warning(disable:4152)
				connectData->ClassService = MouseTrapServiceCallback;
				#pragma warning(pop)
			}
			else {
				DebugPrint(("[MouseTrap] WdfRequestRetrieveInputBuffer failed %x\n", status));
			}
		}
		else {
			status = STATUS_SHARING_VIOLATION;
		}
	}
	else if(ioControlCode == IOCTL_INTERNAL_MOUSE_DISCONNECT) {
		status = STATUS_NOT_IMPLEMENTED;
	}

	// Complete on error
	if(!NT_SUCCESS(status)) {
		WdfRequestComplete(request, status);
		return;
	}

	// Dispatch to higher level driver
	WDF_REQUEST_SEND_OPTIONS options;
	WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

	if(WdfRequestSend(request, WdfDeviceGetIoTarget(hDevice), &options) == FALSE) {
		NTSTATUS status = WdfRequestGetStatus(request);
		DebugPrint(("[MouseTrap] WdfRequestSend failed: 0x%x\n", status));
		WdfRequestComplete(request, status);
	}
}
Пример #12
0
VOID
Rio500_EvtIoWrite(
  _In_ WDFQUEUE   Queue,
  _In_ WDFREQUEST Request,
  _In_ size_t     Length
)
/*++

Routine Description:

    Called by the framework when it receives Write requests.

Arguments:

    Queue - Default queue handle
    Request - Handle to the read/write request
    Lenght - Length of the data buffer associated with the request.
                 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

--*/
{
  WDFUSBPIPE               pipe;
  WDF_USB_PIPE_INFORMATION pipeInfo;

  PAGED_CODE();

  //
  // Get the pipe associate with this request.
  //
  WDFDEVICE device = WdfIoQueueGetDevice(Queue);
  PDEVICE_CONTEXT pDevContext = GetDeviceContext(device);

  pipe = pDevContext->WritePipe;
  if (pipe == NULL) {
    Rio500_DbgPrint(1, ("Write pipe handle is NULL\n"));
    WdfRequestCompleteWithInformation(Request, STATUS_INVALID_PARAMETER, 0);
    return;
  }
  WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
  WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);

  if (WdfUsbPipeTypeBulk == pipeInfo.PipeType) {
    ReadWriteBulkEndPoints(Queue, Request, (ULONG)Length, WdfRequestTypeWrite);
    return;
  } 

  Rio500_DbgPrint(1, ("ISO transfer is not supported for buffered I/O transfer\n"));
  WdfRequestCompleteWithInformation(Request, STATUS_INVALID_DEVICE_REQUEST, 0);
}
Пример #13
0
VOID
OnTopLevelIoDefault(
    _In_  WDFQUEUE    FxQueue,
    _In_  WDFREQUEST  FxRequest
    )
/*++

  Routine Description:

    Accepts all incoming requests and pends or forwards appropriately.

  Arguments:

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

  Return Value:

    None.

--*/
{
    FuncEntry(TRACE_FLAG_SPBAPI);
    
    UNREFERENCED_PARAMETER(FxQueue);

    WDFDEVICE device;
    PDEVICE_CONTEXT pDevice;
    WDF_REQUEST_PARAMETERS params;
    NTSTATUS status;

    device = WdfIoQueueGetDevice(FxQueue);
    pDevice = GetDeviceContext(device);

    WDF_REQUEST_PARAMETERS_INIT(&params);

    WdfRequestGetParameters(FxRequest, &params);

	status = WdfRequestForwardToIoQueue(FxRequest, pDevice->SpbQueue);

	if (!NT_SUCCESS(status))
	{
		CyapaPrint(
			DEBUG_LEVEL_ERROR,
			DBG_IOCTL,
			"Failed to forward WDFREQUEST %p to SPB queue %p - %!STATUS!",
			FxRequest,
			pDevice->SpbQueue,
			status);
		
		WdfRequestComplete(FxRequest, status);
	}

    FuncExit(TRACE_FLAG_SPBAPI);
}
Пример #14
0
VOID FireShockEvtIoWrite(
    _In_ WDFQUEUE   Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t     Length
)
{
    NTSTATUS            status;
    PDEVICE_CONTEXT     pDeviceContext;
    LPVOID              buffer;
    size_t              bufferLength;
    size_t              transferred = 0;

    pDeviceContext = DeviceGetContext(WdfIoQueueGetDevice(Queue));

    switch (pDeviceContext->DeviceType)
    {
    case DualShock3:

        status = WdfRequestRetrieveInputBuffer(
            Request,
            DS3_HID_OUTPUT_REPORT_SIZE,
            &buffer,
            &bufferLength);

        if (NT_SUCCESS(status) && Length == bufferLength)
        {
            status = SendControlRequest(
                pDeviceContext,
                BmRequestHostToDevice,
                BmRequestClass,
                SetReport,
                USB_SETUP_VALUE(HidReportRequestTypeOutput, HidReportRequestIdOne),
                0,
                buffer,
                (ULONG)bufferLength);

            if (!NT_SUCCESS(status))
            {
                TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE,
                    "SendControlRequest failed with status %!STATUS!",
                    status);
                break;
            }

            transferred = bufferLength;
        }

        break;
    default:
        status = STATUS_NOT_SUPPORTED;
        break;
    }

    WdfRequestCompleteWithInformation(Request, status, transferred);
}
Пример #15
0
// Bulk管道写操作
//
VOID BulkWrite(IN WDFQUEUE  Queue, IN WDFREQUEST  Request, IN size_t  Length)
{
	NTSTATUS status = STATUS_SUCCESS;
	WDFMEMORY hMem = NULL;
	WDFDEVICE hDevice = NULL;
	WDFUSBPIPE BulkOutputPipe = NULL;
	UCHAR* lpBuf;

	UNREFERENCED_PARAMETER(Length);

	KDBG(DPFLTR_INFO_LEVEL, "[BulkWrite] size: %d", Length);

	// 获取管道句柄
	hDevice = WdfIoQueueGetDevice(Queue);
	BulkOutputPipe = GetBulkPipe(FALSE, hDevice);

	if(NULL == BulkOutputPipe)
	{
		KDBG(DPFLTR_ERROR_LEVEL, "BulkOutputPipe = NULL");
		WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
		return;
	}

	status = WdfRequestRetrieveInputMemory(Request, &hMem);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_ERROR_LEVEL, "WdfRequestRetrieveInputMemory failed(status = 0x%0.8x)!!!", status);
		WdfRequestComplete(Request, status);
		return;
	}

	// 打印出offset值。
	// 在写缓冲的前两个字节中存有write offset的值
	lpBuf = (UCHAR*)WdfMemoryGetBuffer(hMem, 0);
	KDBG(DPFLTR_TRACE_LEVEL, "write offset: %hd", *(WORD*)lpBuf);

	// 把当前的Request对象进行重利用,发送给USB总线。
	// 格式化Request对象,设置Pipe句柄、完成函数等。
	status = WdfUsbTargetPipeFormatRequestForWrite(BulkOutputPipe, Request, hMem, NULL);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_ERROR_LEVEL, "WdfUsbTargetPipeFormatRequestForWrite(status 0x%0.8x)!!!", status);
		WdfRequestComplete(Request, status);
		return;
	}

	WdfRequestSetCompletionRoutine(Request, BulkWriteComplete, BulkOutputPipe); 
	if(FALSE == WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(BulkOutputPipe), NULL))
	{
		status = WdfRequestGetStatus(Request);
		KDBG(DPFLTR_ERROR_LEVEL, "WdfRequestSend failed with status 0x%0.8x\n", status);		
		WdfRequestComplete(Request, status);
	}
}
Пример #16
0
VOID
EvtIoDeviceControl(IN WDFQUEUE Queue,
		   IN WDFREQUEST Request,
		   IN size_t OutputBufferLength,
		   IN size_t InputBufferLength, IN ULONG IoControlCode)
{
	WDFDEVICE Device = WdfIoQueueGetDevice(Queue);

	UNREFERENCED_PARAMETER(OutputBufferLength);
	UNREFERENCED_PARAMETER(InputBufferLength);

	switch (IoControlCode) {
	case IOCTL_PCIDTF_GET_INFO:
		PciDtfDeviceGetInfo(Device, Request);
		break;
	case IOCTL_PCIDTF_READ_CFG:
		PciDtfDeviceReadWriteCfg(Device, Request, TRUE);
		break;
	case IOCTL_PCIDTF_WRITE_CFG:
		PciDtfDeviceReadWriteCfg(Device, Request, FALSE);
		break;
	case IOCTL_PCIDTF_GET_REG:
		PciDtfDeviceGetReg(Device, Request);
		break;
	case IOCTL_PCIDTF_READ_REG:
		PciDtfDeviceReadWriteReg(Device, Request, TRUE);
		break;
	case IOCTL_PCIDTF_WRITE_REG:
		PciDtfDeviceReadWriteReg(Device, Request, FALSE);
		break;
	case IOCTL_PCIDTF_ALLOC_DMA:
		PciDtfDeviceAllocDma(Device, Request);
		break;
	case IOCTL_PCIDTF_FREE_DMA:
		PciDtfDeviceFreeDma(Device, Request);
		break;
	case IOCTL_PCIDTF_READ_DMA:
		PciDtfDeviceReadWriteDma(Device, Request, TRUE);
		break;
	case IOCTL_PCIDTF_WRITE_DMA:
		PciDtfDeviceReadWriteDma(Device, Request, FALSE);
		break;
	case IOCTL_PCIDTF_GET_DMA_INFO:
		PciDtfDeviceGetDma(Device, Request);
		break;
	default:
		TRACE_MSG(TRACE_LEVEL_ERROR, TRACE_FLAG_QUEUE,
			  "Unsupported I/O control code=0x%X (0x%X)\n",
			  IoControlCode,
			  IoGetFunctionCodeFromCtlCode(IoControlCode));
		WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
		break;
	}
}
Пример #17
0
VOID
EvtIoRead(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN size_t           Length
    )
{
    WDFUSBPIPE                  pipe;
    NTSTATUS                    status;
    WDFMEMORY                   reqMemory;
    PDEVICE_CONTEXT             pDeviceContext;
    BOOLEAN                     ret;

    UNREFERENCED_PARAMETER(Length);

    pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    pipe = pDeviceContext->BulkReadPipe;

    status = WdfRequestRetrieveOutputMemory(Request, &reqMemory);
    if(!NT_SUCCESS(status)){
        goto Exit;
    }

    status = WdfUsbTargetPipeFormatRequestForRead(pipe,
                                        Request,
                                        reqMemory,
                                        NULL // Offsets
                                        );
    if (!NT_SUCCESS(status)) {
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(
                            Request,
                            EvtRequestReadCompletionRoutine,
                            pipe);

    ret = WdfRequestSend(Request,
                    WdfUsbTargetPipeGetIoTarget(pipe),
                    WDF_NO_SEND_OPTIONS);
    if (ret == FALSE) {
        status = WdfRequestGetStatus(Request);
        goto Exit;
    } else {
        return;
    }

Exit:
    WdfRequestCompleteWithInformation(Request, status, 0);

    return;
}
Пример #18
0
VOID
SimSensorIoInternalDeviceControl (
    WDFQUEUE Queue,
    WDFREQUEST Request,
    size_t OutputBufferLength,
    size_t InputBufferLength,
    ULONG IoControlCode)

/*++

Description:

    The system uses IoInternalDeviceControl requests to communicate with the
    ACPI driver on the device stack. For proper operation of thermal zones,
    these requests must be forwarded unless the driver knows how to handle
    them.

--*/

{
    WDF_REQUEST_SEND_OPTIONS RequestSendOptions;
    BOOLEAN Return;
    NTSTATUS Status;

    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);
    UNREFERENCED_PARAMETER(IoControlCode);

    DebugEnter();

    WdfRequestFormatRequestUsingCurrentType(Request);

    WDF_REQUEST_SEND_OPTIONS_INIT(
        &RequestSendOptions,
        WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

    Return = WdfRequestSend(
                Request,
                WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)),
                &RequestSendOptions);

    if (Return == FALSE) {
        Status = WdfRequestGetStatus(Request);
        DebugPrint(SIMSENSOR_WARN,
                   "WdfRequestSend() Failed. Request Status=0x%x\n",
                   Status);

        WdfRequestComplete(Request, Status);
    }

    DebugExit();
}
Пример #19
0
///////////////////////////////////////////////////////////////////////////////
// SmplFilterEvtIoDefault
///////////////////////////////////////////////////////////////////////////////
VOID SmplFilterEvtIoDefault(
  __in  WDFQUEUE Queue,
  __in  WDFREQUEST Request
)
{
    WDF_REQUEST_PARAMETERS RequestParameters;
    BOOLEAN bResult;

    WDF_REQUEST_PARAMETERS_INIT(&RequestParameters);
    WdfRequestGetParameters(Request, &RequestParameters);
    if(WdfRequestTypeRead == RequestParameters.Type)
    {
        DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "SmplFilterEvtIoDefault WdfRequestTypeRead\n");
        WdfRequestFormatRequestUsingCurrentType(Request);
        WdfRequestSetCompletionRoutine(Request, SmplFilterCompletionRoutineRead, NULL);
        bResult = WdfRequestSend(Request,
                                WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)),
                                NULL);
    }
    else
    {
        WDF_REQUEST_SEND_OPTIONS Options;
        WDF_REQUEST_SEND_OPTIONS_INIT(&Options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

        DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "SmplFilterEvtIoDefault other Request type\n");

        bResult = WdfRequestSend(Request,
                                WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)),
                                &Options);
    }

    if(FALSE == bResult)
    {
        DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "WdfRequestSend failed!\n");
        WdfRequestComplete(Request, WdfRequestGetStatus(Request));
    }
} // end SmplFilterEvtIoDefault
Пример #20
0
///////////////////////////////////////////////////////////////////////////////
// SmplQueueEvtStatePoFxStopComplete
// Callback invoked by KMDF when stop transiton of the supplied queue has
// completed.
///////////////////////////////////////////////////////////////////////////////
VOID
SmplQueueEvtStatePoFxStopComplete(
    _In_ WDFQUEUE Queue,
    _In_ WDFCONTEXT Context
    )
{
    DEVICE_CONTEXT *pDeviceContext = WdfObjectGetTypedContext(WdfIoQueueGetDevice(Queue), DEVICE_CONTEXT);

    UNREFERENCED_PARAMETER(Context);
    
    //
    // Queue has been stopped. Complete the idle transition.
    //
    PoFxCompleteIdleCondition(pDeviceContext->PoHandle, 0 /* Component */);

} // end SmplQueueEvtStatePoFxStopComplete
Пример #21
0
VOID
EvtIoDeviceControl(
    __in WDFQUEUE IoQueue,
    __in WDFREQUEST Request,
    __in size_t OutBufferLength,
    __in size_t InBufferLength,
    __in ULONG IoControlCode
    )
{
    PDEVICE_CONTEXT DeviceContext;
    ULONG_PTR Information;
    NTSTATUS Status;
    
    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "--> EvtIoDeviceControl(%x)\n", IoControlCode);

    //
    // Get the pointer to the device's context area.
    // We are using the queue handle to get the device handle.
    //
    
    DeviceContext = GetDeviceContext(WdfIoQueueGetDevice(IoQueue));
    Information = 0;
    
    switch(IoControlCode) {
        case IOCTL_SHOW_DATA:
            //Status = EraseFirstSector(WdfIoQueueGetDevice(IoQueue));
            //ShowFwhRegisters(DeviceContext->Lpc);
            //ShowRcrbRegisters(DeviceContext->Rcrb);
            //ShowSpiRegisters(DeviceContext->Rcrb + SPIBAR_OFFSET);
            Status = STATUS_SUCCESS;
            break;
        
        default:
            Status = STATUS_INVALID_DEVICE_REQUEST;
            break;
    }
    
    //
    // Complete the I/O request
    //
    
    WdfRequestCompleteWithInformation(Request, Status, Information);
    
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "<-- EvtIoDeviceControl(%x)\n", IoControlCode);
}
Пример #22
0
///////////////////////////////////////////////////////////////////////////////
//
//  CDFilterEvtRead
//
//    This routine is called by the framework for read requests
//    being sent to the device we're filtering
//
//  INPUTS:
//
//      Queue    - Our default queue
//
//      Request  - A read request
//
//      Length   - The length of the read operation
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//      This routine is called at IRQL <= DISPATCH_LEVEL
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID
CDFilterEvtRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length)
{
    NTSTATUS status;
    PFILTER_DEVICE_CONTEXT devContext;

#if DBG
    DbgPrint("CDFilterEvtRead: Processing read. Length = 0x%x\n", Length);
#endif

    //
    // Get the context that we setup during DeviceAdd processing
    //
    devContext = CDFilterGetDeviceContext(WdfIoQueueGetDevice(Queue));

    //
    // Setup the request for the next driver
    //
    WdfRequestFormatRequestUsingCurrentType(Request);

    //
    // Set the completion routine...
    //
    WdfRequestSetCompletionRoutine(Request,
                                   CDFilterReadComplete,
                                   NULL);

    //
    // And send it!
    // 
    if (!WdfRequestSend(Request, 
                        devContext->TargetToSendRequestsTo, 
                        WDF_NO_SEND_OPTIONS)) {

        //
        // Oops! Something bad happened, complete the request
        //
        status = WdfRequestGetStatus(Request);
#if DBG
        DbgPrint("WdfRequestSend failed - 0x%x\n", status);
#endif
        WdfRequestComplete(Request, status);
    }

    return;

}
Пример #23
0
VOID VIOSerialPortWriteRequestCancel(IN WDFREQUEST Request)
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(
        WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)))->port;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: 0x%p\n",
        __FUNCTION__, Request);

    // synchronize with VIOSerialReclaimConsumedBuffers because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(Port->OutVqLock);
    Port->PendingWriteRequest = NULL;
    WdfSpinLockRelease(Port->OutVqLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
Пример #24
0
VOID
SerialCancelImmediate(
    IN WDFREQUEST Request
    )

/*++

Routine Description:

    This routine is used to cancel a request that is waiting on
    a comm event.

Arguments:

    Request - Pointer to the WDFREQUEST for the current request

Return Value:

    None.

--*/

{
    PSERIAL_DEVICE_EXTENSION Extension = NULL;
    WDFDEVICE  device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request));

    UNREFERENCED_PARAMETER(Request);

    Extension = SerialGetDeviceExtension(device);

    SerialTryToCompleteCurrent(
        Extension,
        SerialGrabImmediateFromIsr,
        STATUS_CANCELLED,
        &Extension->CurrentImmediateRequest,
        NULL,
        NULL,
        Extension->ImmediateTotalTimer,
        NULL,
        SerialGetNextImmediate,
        SERIAL_REF_CANCEL
        );

}
Пример #25
0
// Bulk管道读操作
//
VOID BulkRead(IN WDFQUEUE  Queue, IN WDFREQUEST  Request, IN size_t  Length)
{
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_CONTEXT pContext = NULL;
	WDFUSBPIPE BulkInputPipe;
	WDFMEMORY hMem;
	WDFDEVICE hDevice = WdfIoQueueGetDevice(Queue);

	KDBG(DPFLTR_INFO_LEVEL, "[BulkRead] size: %d", Length);

	// 取管道
	pContext = GetDeviceContext(hDevice);
	BulkInputPipe = GetBulkPipe(TRUE, hDevice);
	if(NULL == BulkInputPipe){
		WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
		return;
	}

	status = WdfRequestRetrieveOutputMemory(Request, &hMem);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_INFO_LEVEL, "WdfRequestRetrieveOutputMemory failed with status 0x%0.8x!!!", status);
		WdfRequestComplete(Request, status);
		return;
	}

	// 和写一样,仍然是对Request对象的重利用
	// 除了重利用外,也可以新建一个Request对象。新建的方法在本工程其他地方用得较多。
	status = WdfUsbTargetPipeFormatRequestForRead(BulkInputPipe, Request, hMem, NULL);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_INFO_LEVEL, "WdfUsbTargetPipeFormatRequestForRead failed with status 0x%08x\n", status);
		WdfRequestComplete(Request, status);
		return;
	}

	WdfRequestSetCompletionRoutine(Request, BulkReadComplete, BulkInputPipe);
	if(FALSE == WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pContext->UsbBulkInPipe), NULL))
	{
		status = WdfRequestGetStatus(Request);
		KDBG(DPFLTR_INFO_LEVEL, "WdfRequestSend failed with status 0x%08x\n", status);
		WdfRequestComplete(Request, status);
	}
}
Пример #26
0
VOID
ForwardRequestToIoTarget(
    _In_ WDFQUEUE   queue,
    _In_ WDFREQUEST request,
    _In_ size_t     length)
{
    TraceEntry();
    Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! - Queue 0x%p, Request 0x%p Length %Iu", queue, request, length);

    auto device = WdfIoQueueGetDevice(queue);
    auto context = GetDeviceContext(device);

    if (length > context->MaxLengthInBytesForRWTransfers) {
        TraceError("%!FUNC! - Buffer Length to big %Iu, Max is %Iu. Status - %!STATUS!",
            length, context->MaxLengthInBytesForRWTransfers, STATUS_BUFFER_OVERFLOW);

        WdfRequestCompleteWithInformation(request, STATUS_BUFFER_OVERFLOW, NULL);
        return;
    }

    auto targetDevice = WdfDeviceGetIoTarget(device);

    WdfRequestFormatRequestUsingCurrentType(request);

    WDF_REQUEST_SEND_OPTIONS options;

    WDF_REQUEST_SEND_OPTIONS_INIT(
        &options,
        WDF_REQUEST_SEND_OPTION_SYNCHRONOUS | WDF_REQUEST_SEND_OPTION_TIMEOUT);

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options, WDF_ABS_TIMEOUT_IN_SEC(10));

    auto sendSuccess = WdfRequestSend(request, targetDevice, &options);
    auto status = WdfRequestGetStatus(request);
    if (!sendSuccess || !NT_SUCCESS(status))
    {
        TraceError("%!FUNC! - WdfRequestSend returned %d with status: %!STATUS!", sendSuccess, status);
        WdfRequestCompleteWithInformation(request, status, NULL);
        return;
    }

    WdfRequestComplete(request, status);
}
Пример #27
0
VOID
VIOSerialPortReadRequestCancel(
    IN WDFREQUEST Request
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)));

    TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "-->%s called on request 0x%p\n", __FUNCTION__, Request);

    // synchronize with VIOSerialQueuesInterruptDpc because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(pdoData->port->InBufLock);
    pdoData->port->PendingReadRequest = NULL;
    WdfSpinLockRelease(pdoData->port->InBufLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
Пример #28
0
VOID VirtRngEvtIoRead(IN WDFQUEUE Queue,
                      IN WDFREQUEST Request,
                      IN size_t Length)
{
    PDEVICE_CONTEXT context = GetDeviceContext(WdfIoQueueGetDevice(Queue));
    NTSTATUS status;
    PVOID buffer;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ,
        "--> %!FUNC! Queue: %p Request: %p Length: %d",
        Queue, Request, (ULONG)Length);

    status = WdfRequestRetrieveOutputBuffer(Request, Length, &buffer, NULL);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
            "WdfRequestRetrieveOutputBuffer failed: %!STATUS!", status);
        WdfRequestComplete(Request, status);
        return;
    }

    status = WdfRequestMarkCancelableEx(Request, VirtRngEvtRequestCancel);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
            "WdfRequestMarkCancelableEx failed: %!STATUS!", status);
        WdfRequestComplete(Request, status);
        return;
    }

    status = VirtQueueAddBuffer(context, Request, Length);
    if (!NT_SUCCESS(status))
    {
        if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED)
        {
            WdfRequestComplete(Request, status);
        }
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<-- %!FUNC!");
}
Пример #29
0
VOID FireShockEvtIoRead(
    _In_ WDFQUEUE   Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t     Length
)
{
    NTSTATUS            status;
    PDEVICE_CONTEXT     pDeviceContext;

    UNREFERENCED_PARAMETER(Length);

    pDeviceContext = DeviceGetContext(WdfIoQueueGetDevice(Queue));

    status = WdfRequestForwardToIoQueue(Request, pDeviceContext->IoReadQueue);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR,
            TRACE_QUEUE, "WdfRequestForwardToIoQueue failed with status %!STATUS!", status);
        WdfRequestComplete(Request, status);
    }
}
Пример #30
0
VOID
LoopbackEvtIoDeviceControl(
    _In_ WDFQUEUE   Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t     OutputBufferLength,
    _In_ size_t     InputBufferLength,
    _In_ ULONG      IoControlCode)
{
    UNREFERENCED_PARAMETER((OutputBufferLength, InputBufferLength));

    TraceEntry();

    NTSTATUS status = STATUS_SUCCESS;

    if (IoControlCode != LOOPBACK_IOCTL_ALTER_MAX_LENGTH || InputBufferLength != 4)
    {
        status = STATUS_UNSUCCESSFUL;

        goto Cleanup;
    }

    PUINT32 buffer;
    status = WdfRequestRetrieveInputBuffer(Request, 4, (PVOID*)&buffer, nullptr);

    if (!NT_SUCCESS(status))
    {
        TraceError("%!FUNC! - Unable to read IOCTL input buffer. Status - %!STATUS!", status);

        goto Cleanup;
    }

    auto device = WdfIoQueueGetDevice(Queue);
    auto context = GetDeviceContext(device);

    context->MaxLengthInBytesForRWTransfers = *buffer;

Cleanup:

    WdfRequestComplete(Request, status);
}