示例#1
0
static VOID
CompleteHIDQueueRequest(
    PINPUT_DEVICE pContext,
    PINPUT_CLASS_COMMON pClass)
{
    WDFREQUEST request;
    NTSTATUS status;

    if (!pClass->bDirty)
    {
        // nothing to do
        return;
    }

    status = WdfIoQueueRetrieveNextRequest(pContext->HidQueue, &request);
    if (NT_SUCCESS(status))
    {
        status = RequestCopyFromBuffer(
            request,
            pClass->pHidReport,
            pClass->cbHidReportSize);
        WdfRequestComplete(request, status);
        if (NT_SUCCESS(status))
        {
            pClass->bDirty = FALSE;
        }
    }
}
示例#2
0
文件: usb.c 项目: 340211173/Driver
// This function gets called when the timeout period of debounce timer elapses.
// It reports a switch change by completing a pending request
//
void HidFx2EvtTimerFunction(_In_ WDFTIMER hTimer)
{
    WDFDEVICE           hDevice = NULL;
    WDFREQUEST          hRequest;
    PDEVICE_EXTENSION   pDevContext = NULL;
    NTSTATUS            status = STATUS_SUCCESS;
    size_t              cBytesReturned = 0;
    unsigned char       bToggledSwitch = 0;
    ULONG               cBytesToCopy = 0;
    PHIDFX2_IO_REPORT   pInputReport = NULL;

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


    hDevice = WdfTimerGetParentObject(hTimer);
    pDevContext = GetDeviceContext(hDevice);

    bToggledSwitch = pDevContext->bLatestToggledSwitch;
    TraceInfo(DBG_IOCTL, "(%!FUNC!) mode %d switch %d\n", pDevContext->driverMode, bToggledSwitch);

    if (!((pDevContext->driverMode == DM_BUTTON || pDevContext->driverMode == DM_BUTTON_AND_LED) && bToggledSwitch == 0))
    {
        // Check if there are any pending requests in the Interrupt Message Queue.
        // If a request is found then complete the pending request.
        status = WdfIoQueueRetrieveNextRequest(pDevContext->hInterruptMsgQueue, &hRequest);
        if (NT_SUCCESS(status))
        {
            cBytesToCopy = sizeof(pInputReport[0]);
            status = WdfRequestRetrieveOutputBuffer(hRequest,
                                                    cBytesToCopy,
                                                    &pInputReport,
                                                    &cBytesReturned); // BufferLength
            if (NT_SUCCESS(status))
            {
                TraceInfo(DBG_IOCTL, "(%!FUNC!) WdfRequestRetrieveOutputBuffer switch %d\n", bToggledSwitch);

                pInputReport->bReportId = GENERIC_DESKTOP_REPORT_ID;
                pInputReport->bData = bToggledSwitch;
                cBytesReturned = cBytesToCopy;
            }
            else // WdfRequestRetrieveOutputBuffer failed
            {
                TraceErr(DBG_IOCTL, "(%!FUNC!) WdfRequestRetrieveOutputBuffer failed with status: %!STATUS!\n", status);
            }

            WdfRequestCompleteWithInformation(hRequest, status, cBytesReturned);

        } 
        else if (status != STATUS_NO_MORE_ENTRIES)
        {
            TraceErr(DBG_IOCTL, "(%!FUNC!) WdfIoQueueRetrieveNextRequest status %!STATUS!\n", status);
        }
    }
    else
    {
        TraceInfo(DBG_IOCTL, "(%!FUNC!) ignore switch");
    }

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit\n");
}
示例#3
0
VOID
NICCheckForQueuedSends(
    IN  PFDO_DATA  FdoData
    )
/*++
Routine Description:

Arguments:

    FdoData     Pointer to our FdoData

Return Value:

--*/
{
    WDFREQUEST         request;
    WDFDMATRANSACTION  dmaTransaction;
    NTSTATUS           status;

    UNREFERENCED_PARAMETER( dmaTransaction );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> NICCheckForQueuedSends\n");

    //
    // If we queued any transmits because we didn't have any TCBs earlier,
    // dequeue and send those packets now, as long as we have free TCBs.
    //
    while (MP_TCB_RESOURCES_AVAIABLE(FdoData))
    {
        status = WdfIoQueueRetrieveNextRequest(
                     FdoData->PendingWriteQueue,
                     &request
                     );

        if(!NT_SUCCESS(status) ) {
            if(STATUS_NO_MORE_ENTRIES != status) {
                TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                    "WdfIoQueueRetrieveNextRequest failed %X\n", status);
            }
            break;
        }

        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                    "\t processing Request %p \n", request);

        status = NICInitiateDmaTransfer(FdoData, request);
        if(!NT_SUCCESS(status)) {
            WdfRequestCompleteWithInformation(request, status, 0);
        }

        FdoData->nWaitSend--;
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "<-- NICCheckForQueuedSends\n");
}
示例#4
0
VOID
NICFreeQueuedSendPackets(
    IN  PFDO_DATA  FdoData
    )
/*++
Routine Description:

    Free and complete the pended sends on SendQueueHead

    Assumption: This function is called with the Send SPINLOCK held.

Arguments:

    FdoData     Pointer to our FdoData

Return Value:

     None

--*/
{
    WDFREQUEST   request;
    NTSTATUS     status;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> NICFreeQueuedSendPackets\n");

    do {
        status = WdfIoQueueRetrieveNextRequest(
                     FdoData->PendingWriteQueue,
                     &request
                     );

        if(!NT_SUCCESS(status) ) {
            if(STATUS_NO_MORE_ENTRIES != status){
                TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                    "WdfIoQueueRetrieveNextRequest failed %x\n", status);
            }
            break;
        }

        FdoData->nWaitSend--;

        WdfSpinLockRelease(FdoData->SendLock);

        WdfRequestCompleteWithInformation(request, status, 0);

        WdfSpinLockAcquire(FdoData->SendLock);

    } WHILE (TRUE);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "<-- NICFreeQueuedSendPackets\n");

}
static VOID
XenPci_IoWatch(char *path, PVOID context)
{
  NTSTATUS status;
  watch_context_t *watch_context = context;
  WDFFILEOBJECT file_object = watch_context->file_object;
  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  KIRQL old_irql;
  struct xsd_sockmsg *rep;
  xenbus_read_queue_item_t *list_entry;
  size_t remaining;
  WDFREQUEST request;

  FUNCTION_ENTER();
  
  KeAcquireSpinLock(&xpdid->lock, &old_irql);
  
  remaining = sizeof(struct xsd_sockmsg) + strlen(path) + 1 + strlen(watch_context->token) + 1;
  rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg) + strlen(path) + 1 + strlen(watch_context->token) + 1, XENPCI_POOL_TAG);
  rep->type = XS_WATCH_EVENT;
  rep->req_id = 0;
  rep->tx_id = 0;
  rep->len = (ULONG)(strlen(path) + 1 + strlen(watch_context->token) + 1);
  remaining -= sizeof(struct xsd_sockmsg);
  RtlStringCbCopyA((PCHAR)(rep + 1), remaining, path);
  remaining -= strlen(path) + 1;
  RtlStringCbCopyA((PCHAR)(rep + 1) + strlen(path) + 1, remaining, watch_context->token);
  
  list_entry = (xenbus_read_queue_item_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(xenbus_read_queue_item_t), XENPCI_POOL_TAG);
  list_entry->data = rep;
  list_entry->length = sizeof(*rep) + rep->len;
  list_entry->offset = 0;
  InsertTailList(&xpdid->xenbus.read_list_head, (PLIST_ENTRY)list_entry);
    
  status = WdfIoQueueRetrieveNextRequest(xpdid->xenbus.io_queue, &request);
  if (NT_SUCCESS(status))
  {
    WDF_REQUEST_PARAMETERS parameters;
    WDF_REQUEST_PARAMETERS_INIT(&parameters);
    WdfRequestGetParameters(request, &parameters);
    
    KdPrint((__DRIVER_NAME "     found pending read - MinorFunction = %d, length = %d\n", (ULONG)parameters.MinorFunction, (ULONG)parameters.Parameters.Read.Length));
    XenBus_ProcessReadRequest(xpdid->xenbus.io_queue, request, parameters.Parameters.Read.Length);
    KeReleaseSpinLock(&xpdid->lock, old_irql);
    WdfRequestComplete(request, STATUS_SUCCESS);
  }
  else
  {
    KdPrint((__DRIVER_NAME "     no pending read (%08x)\n", status));
    KeReleaseSpinLock(&xpdid->lock, old_irql);
  }
  
  FUNCTION_EXIT();
}
// 中断Pipe回调函数。这样一旦设备产生了中断信息,驱动就能够读取到。
//
VOID InterruptRead(WDFUSBPIPE Pipe, WDFMEMORY Buffer, size_t NumBytesTransferred, WDFCONTEXT Context)
{
	NTSTATUS status;
	size_t size = 0;
	PDEVICE_CONTEXT pContext = (PDEVICE_CONTEXT)Context;
	WDFREQUEST Request = NULL;
	CHAR *pchBuf = NULL;

	KDBG(DPFLTR_INFO_LEVEL, "[InterruptRead]");
	UNREFERENCED_PARAMETER(Pipe);

	// Read数据缓冲区。注意到,缓冲区长度总是管道最大包长度的倍数。
	// 我们这里只用缓冲区的第一个有效字节。
	pchBuf = (CHAR*)WdfMemoryGetBuffer(Buffer, &size);
	if(pchBuf == NULL || size == 0)
		return;

	// 第一个字节为确认字节,一定是0xD4
	//if(pchBuf[0] != 0xD4)return;

	// 从队列中提取一个未完成请求
	status = WdfIoQueueRetrieveNextRequest(pContext->InterruptManualQueue, &Request);

	if(NT_SUCCESS(status))
	{
		CHAR* pOutputBuffer = NULL;
		status = WdfRequestRetrieveOutputBuffer(Request, 1, &pOutputBuffer, NULL);

		if(NT_SUCCESS(status))
		{
			// 把结果返回给应用程序
			pOutputBuffer[0] = pchBuf[1];
			WdfRequestCompleteWithInformation(Request, status, 1);
		}
		else
		{
			// 返回错误
			WdfRequestComplete(Request, status);
		}

		KDBG(DPFLTR_INFO_LEVEL, "Get and finish an interrupt read request.");
	}else{
		// 队列空,将放弃从设备获取的数据。
		KDBG(DPFLTR_INFO_LEVEL, "Manual interrupt queue is empty!!!");
	}
}
static VOID
XenBus_EvtIoRead(WDFQUEUE queue, WDFREQUEST request, size_t length)
{
  NTSTATUS status;
  WDFFILEOBJECT file_object = WdfRequestGetFileObject(request);
  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  KIRQL old_irql;

  UNREFERENCED_PARAMETER(queue);
  
  FUNCTION_ENTER();
  status = WdfRequestForwardToIoQueue(request, xpdid->xenbus.io_queue);
  if (!NT_SUCCESS(status))
  {
    KdPrint((__DRIVER_NAME "     could not forward request (%08x)\n", status));
  }
  KeAcquireSpinLock(&xpdid->lock, &old_irql);
  if (!IsListEmpty(&xpdid->xenbus.read_list_head))
  {
    status = WdfIoQueueRetrieveNextRequest(xpdid->xenbus.io_queue, &request);
    if (NT_SUCCESS(status))
    {
      KdPrint((__DRIVER_NAME "     found pending read\n"));
      XenBus_ProcessReadRequest(xpdid->xenbus.io_queue, request, length);
      KeReleaseSpinLock(&xpdid->lock, old_irql);
      WdfRequestComplete(request, STATUS_SUCCESS);
    }
    else
    {
      KdPrint((__DRIVER_NAME "     no pending read (%08x)\n", status));
      KeReleaseSpinLock(&xpdid->lock, old_irql);
    }
  }
  else
  {
    KdPrint((__DRIVER_NAME "     no data to read\n"));
    KeReleaseSpinLock(&xpdid->lock, old_irql);
  }
  
  FUNCTION_EXIT();
  return;
}
示例#8
0
文件: utils.c 项目: MHesham/bsp
VOID
SerialGetNextRequest(
    IN WDFREQUEST               * CurrentOpRequest,
    IN WDFQUEUE                   QueueToProcess,
    OUT WDFREQUEST              * NextRequest,
    IN BOOLEAN                    CompleteCurrent,
    IN PSERIAL_DEVICE_EXTENSION   Extension
    )

/*++

Routine Description:

    This function is used to make the head of the particular
    queue the current request.  It also completes the what
    was the old current request if desired.

Arguments:

    CurrentOpRequest - Pointer to a pointer to the currently active
                   request for the particular work list.  Note that
                   this item is not actually part of the list.

    QueueToProcess - The list to pull the new item off of.

    NextIrp - The next Request to process.  Note that CurrentOpRequest
              will be set to this value under protection of the
              cancel spin lock.  However, if *NextIrp is NULL when
              this routine returns, it is not necessaryly true the
              what is pointed to by CurrentOpRequest will also be NULL.
              The reason for this is that if the queue is empty
              when we hold the cancel spin lock, a new request may come
              in immediately after we release the lock.

    CompleteCurrent - If TRUE then this routine will complete the
                      request pointed to by the pointer argument
                      CurrentOpRequest.

Return Value:

    None.

--*/

{
    WDFREQUEST       oldRequest = NULL;
    PREQUEST_CONTEXT reqContext;
    NTSTATUS         status;

    UNREFERENCED_PARAMETER(Extension);

    oldRequest = *CurrentOpRequest;
    *CurrentOpRequest = NULL;

    //
    // Check to see if there is a new request to start up.
    //

    status = WdfIoQueueRetrieveNextRequest(
                 QueueToProcess,
                 CurrentOpRequest
                 );

    if(!NT_SUCCESS(status)) {
        ASSERTMSG("WdfIoQueueRetrieveNextRequest failed",
                  status == STATUS_NO_MORE_ENTRIES);
    }

    *NextRequest = *CurrentOpRequest;

    if (CompleteCurrent) {

        if (oldRequest) {

            reqContext = SerialGetRequestContext(oldRequest);

            SerialCompleteRequest(oldRequest,
                                  reqContext->Status,
                                  reqContext->Information);
        }
    }
}
示例#9
0
文件: usb.c 项目: uri247/wdk80
VOID
HidFx2CompleteReadReport(
    WDFDEVICE Device
    )
/*++

Routine Description

    This method handles the completion of the pended request for the
    IOCTL_HID_READ_REPORT

Arguments:

    Device - Handle to a framework device.

Return Value:

    None.

--*/
{
    NTSTATUS             status = STATUS_SUCCESS;
    WDFREQUEST           request;
    PDEVICE_EXTENSION    pDevContext = NULL;
    size_t               bytesReturned = 0;
#ifndef USE_ALTERNATE_HID_REPORT_DESCRIPTOR
    UCHAR                toggledSwitch = 0;
#endif // USE_ALTERNATE_HID_REPORT_DESCRIPTOR
    ULONG                bytesToCopy = 0;
    PHIDFX2_INPUT_REPORT inputReport = NULL;

    pDevContext = GetDeviceContext(Device);

    //
    // Check if there are any pending requests in the Interrupt Message Queue.
    // If a request is found then complete the pending request.
    //
    status = WdfIoQueueRetrieveNextRequest(pDevContext->InterruptMsgQueue, &request);

    if (NT_SUCCESS(status)) {
        //
        // IOCTL_HID_READ_REPORT is METHOD_NEITHER so WdfRequestRetrieveOutputBuffer
        // will correctly retrieve buffer from Irp->UserBuffer. Remember that
        // HIDCLASS provides the buffer in the Irp->UserBuffer field
        // irrespective of the ioctl buffer type. However, framework is very
        // strict about type checking. You cannot get Irp->UserBuffer by using
        // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER
        // internal ioctl.
        //
        bytesToCopy = sizeof(HIDFX2_INPUT_REPORT);
        status = WdfRequestRetrieveOutputBuffer(request,
                                                bytesToCopy,
                                                &inputReport,
                                                &bytesReturned);// BufferLength

        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                "WdfRequestRetrieveOutputBuffer failed with status: 0x%x\n", status);
        } else {

#ifndef USE_ALTERNATE_HID_REPORT_DESCRIPTOR
            //
            // Map switch pack state. The lower 7 bits of switch pack
            // state are mapped to usages in consumer control collection
            // while the highest one bit is mapped to sleep usage in system
            // control collection
            //
            toggledSwitch = pDevContext->LatestToggledSwitch;

			if (toggledSwitch & CONSUMER_CONTROL_BUTTONS_BIT_MASK) {
                //
                //these are consumer control buttons
                //
                TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "Consumer control SwitchState: 0x%x\n", toggledSwitch);

                inputReport->ReportId = CONSUMER_CONTROL_REPORT_ID;
                inputReport->SwitchStateAsByte = toggledSwitch;
                bytesReturned = bytesToCopy;
            }
            else if (toggledSwitch & SYSTEM_CONTROL_BUTTONS_BIT_MASK) {
                //
                // these are system control buttons
                //
                TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "System Control SwitchState: 0x%x\n", toggledSwitch);

                inputReport->ReportId = SYSTEM_CONTROL_REPORT_ID;
                inputReport->SwitchStateAsByte = toggledSwitch;
                bytesReturned = bytesToCopy;
            }
            else {
                //
                // We can't be here since we already rejected the switch
                // state with no swicthes turned on
                //
                ASSERT(FALSE);
            }
#else
            //
            // Using vendor collection reports instead of HID collections that integrate
            // into consumer and system control
            //
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                "Vendor SwitchState: 0x%x\n", pDevContext->CurrentSwitchState);

            inputReport->ReportId = DIP_SWITCHES_REPORT_ID;
            inputReport->SwitchStateAsByte = pDevContext->CurrentSwitchState;
            bytesReturned = bytesToCopy;

#endif // USE_ALTERNATE_HID_REPORT_DESCRIPTOR

        }

        WdfRequestCompleteWithInformation(request, status, bytesReturned);

    } else if (status != STATUS_NO_MORE_ENTRIES) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
            "WdfIoQueueRetrieveNextRequest status %08x\n", status);
    }

    return;
}
示例#10
0
///////////////////////////////////////////////////////////////////////////////
//
//  BasicUsbInterruptPipeReadComplete
//
//    This is the callback we supplied for the continuous reader
//    on the interrupt IN pipe. It is called whenever the user
//    changes the state of the switches on the switch pack
//
//  INPUTS:
//
//      Pipe    - Our interrupt IN pipe
//
//      Buffer  - The WDFMEMORY object associated with the
//                 transfer. The buffer of thie memory contains
//                 the state of the switch pack
//
//      NumBytesTransferred - Self explanatory
//
//      Context - One of our per device context structures
//                (passed as a parameter to
//                 WDF_USB_CONTINUOUS_READER_CONFIG_INIT)
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_SUCCESS, otherwise an error indicating why the driver could not
//                      load.
//
//  IRQL:
//
//      This routine is called at IRQL <= DISPATCH_LEVEL.
//
//  NOTES:
//
//      Even though we've applied a PASSIVE_LEVEL execution
//      level constraint on our device, this callback falls
//      outstide of the callbacks that the constraint is
//      enforced on.
//
///////////////////////////////////////////////////////////////////////////////
VOID
BasicUsbInterruptPipeReadComplete(
    IN WDFUSBPIPE Pipe,
    IN WDFMEMORY Buffer,
    IN size_t NumBytesTransferred,
    IN WDFCONTEXT Context
    ) {

    PUCHAR                   dataBuffer;
    WDFREQUEST               stateChangeRequest;
    PBASICUSB_DEVICE_CONTEXT devContext;
    PUCHAR                   userBuffer;
    NTSTATUS                 status;

    UNREFERENCED_PARAMETER(Pipe);
    UNREFERENCED_PARAMETER(NumBytesTransferred);
    UNREFERENCED_PARAMETER(Context);

    //
    // Someone toggled the switch pack. Complete a pending user
    // request if there is one.
    //

    devContext = (PBASICUSB_DEVICE_CONTEXT)Context;

    dataBuffer = (PUCHAR)WdfMemoryGetBuffer(Buffer, NULL);

#if DBG
    DbgPrint("Interrupt read complete. Bytes transferred = 0x%x, Data = 0x%x\n",
             (ULONG)NumBytesTransferred, *dataBuffer);
#endif

    //
    // See if there is anyone waiting to be notified of the state
    // change.
    //
    status = WdfIoQueueRetrieveNextRequest(
                                        devContext->SwitchPackStateChangeQueue,
                                        &stateChangeRequest);

    if (NT_SUCCESS(status)) {

#if DBG
        DbgPrint("State change request 0x%p pending\n", 
                 stateChangeRequest);
#endif
        //
        // Yup, someone waiting. Complete their request with the switch
        // pack state.
        //
        status = WdfRequestRetrieveOutputBuffer(stateChangeRequest, 
                                                sizeof(UCHAR),
                                                (PVOID *)&userBuffer,
                                                NULL);

        if (NT_SUCCESS(status)) {

            //
            // Stuff the value into the buffer...
            //
            *userBuffer = *dataBuffer;

            //
            // And complete the request, indicating the proper number of
            // bytes transferred.
            //
            WdfRequestCompleteWithInformation(stateChangeRequest,
                                              STATUS_SUCCESS,
                                              sizeof(UCHAR));
        } else {
#if DBG
            DbgPrint("Failed to get user buffer ofState change request 0x%x\n",
                     status);
#endif
            WdfRequestComplete(stateChangeRequest, status);

        }

    } else {
#if DBG
        DbgPrint("No state change requests pending? (0x%x)\n", 
                 status);
#endif

    }

    return;
}
示例#11
0
VOID
OsrUsbIoctlGetInterruptMessage(
    _In_ WDFDEVICE Device,
    _In_ NTSTATUS  ReaderStatus
    )
/*++

Routine Description

    This method handles the completion of the pended request for the IOCTL
    IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE.

Arguments:

    Device - Handle to a framework device.

Return Value:

    None.

--*/
{
    NTSTATUS            status;
    WDFREQUEST          request;
    PDEVICE_CONTEXT     pDevContext;
    size_t              bytesReturned = 0;
    PSWITCH_STATE       switchState = NULL;

    pDevContext = GetDeviceContext(Device);

    do {

        //
        // Check if there are any pending requests in the Interrupt Message Queue.
        // If a request is found then complete the pending request.
        //
        status = WdfIoQueueRetrieveNextRequest(pDevContext->InterruptMsgQueue, &request);

        if (NT_SUCCESS(status)) {
            status = WdfRequestRetrieveOutputBuffer(request,
                                                    sizeof(SWITCH_STATE),
                                                    &switchState,
                                                    NULL);// BufferLength

            if (!NT_SUCCESS(status)) {

                TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                    "User's output buffer is too small for this IOCTL, expecting a SWITCH_STATE\n");
                bytesReturned = sizeof(SWITCH_STATE);

            } else {

                //
                // Copy the state information saved by the continuous reader.
                //
                if (NT_SUCCESS(ReaderStatus)) {
                    switchState->SwitchesAsUChar = pDevContext->CurrentSwitchState;
                    bytesReturned = sizeof(SWITCH_STATE);
                } else {
                    bytesReturned = 0;
                }
            }

            //
            // Complete the request.  If we failed to get the output buffer then 
            // complete with that status.  Otherwise complete with the status from the reader.
            //
            WdfRequestCompleteWithInformation(request, 
                                              NT_SUCCESS(status) ? ReaderStatus : status, 
                                              bytesReturned);
            status = STATUS_SUCCESS;

        } else if (status != STATUS_NO_MORE_ENTRIES) {
            KdPrint(("WdfIoQueueRetrieveNextRequest status %08x\n", status));
        }

        request = NULL;

    } while (status == STATUS_SUCCESS);

    return;

}
示例#12
0
VOID
CBUpdateCardState(
                 PSMARTCARD_EXTENSION SmartcardExtension,
                 UCHAR IccState,
                 BOOLEAN SystemWakeUp
                 )
{
    ULONG oldState;
    NTSTATUS status;
    KIRQL irql;
    WDFREQUEST request;
    PDEVICE_EXTENSION       DeviceExtension;


    KeAcquireSpinLock(
                     &SmartcardExtension->OsData->SpinLock,
                     &irql
                     );

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBUpdateCardState: Enter \n" )
                  );

    oldState =
    (SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT ?
     SCARD_PRESENT : SCARD_ABSENT);

    SmartcardExtension->ReaderCapabilities.CurrentState =
    (IccState == PSCR_ICC_PRESENT ? SCARD_PRESENT : SCARD_ABSENT);

    SmartcardDebug(
                  DEBUG_DRIVER,
                  ( "PSCR!CBUpdateCardState: Smart card %s\n",
                    IccState == PSCR_ICC_PRESENT ? "inserted" : "removed")
                  );

    if ( SmartcardExtension->OsData->NotificationIrp != NULL &&
         (SystemWakeUp &&
          (oldState == SCARD_PRESENT ||
           SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_PRESENT) ||
          SmartcardExtension->ReaderCapabilities.CurrentState != oldState)) {
        PIRP notificationIrp ;

        notificationIrp = InterlockedExchangePointer(
                                 &(SmartcardExtension->OsData->NotificationIrp),
                                 NULL
                                 );

        DeviceExtension = GetDeviceExtension(WdfWdmDeviceGetWdfDeviceHandle(SmartcardExtension->OsData->DeviceObject));

        KeReleaseSpinLock(
             &SmartcardExtension->OsData->SpinLock,
             irql
             );

        status = WdfIoQueueRetrieveNextRequest(
                            DeviceExtension->NotificationQueue,
                            &request);
        if (NT_SUCCESS(status)) {

            SmartcardDebug(
                          DEBUG_DRIVER,
                          ( "PSCR!CBUpdateCardState: Completing Irp %p\n",
                            notificationIrp)
                          );

            WdfRequestCompleteWithInformation(request, status, 0);
        }
        else {
            NT_ASSERTMSG("WdfIoQueueRetrieveNextRequest failed",
                      status == STATUS_NO_MORE_ENTRIES);
        }
    } else {
        KeReleaseSpinLock(
                          &SmartcardExtension->OsData->SpinLock,
                          irql
                          );
    }

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBUpdateCardState: Exit \n" )
                  );
}
示例#13
0
VOID
NICServiceReadIrps(
    PFDO_DATA   FdoData,
    PMP_RFD     *PacketArray,
    ULONG       PacketArrayCount
    )
/*++
Routine Description:

    Copy the data from the recv buffers to pending read IRP buffers
    and complete the IRP. When used as network driver, copy operation
    can be avoided by devising a private interface between us and the
    NDIS-WDM filter and have the NDIS-WDM edge to indicate our buffers
    directly to NDIS.

    Called at DISPATCH_LEVEL. Take advantage of that fact while
     acquiring spinlocks.

Arguments:

    FdoData     Pointer to our FdoData

Return Value:

     None

--*/
{
    PMP_RFD             pMpRfd = NULL;
    ULONG               index;
    NTSTATUS            status;
    PVOID               buffer;
    WDFREQUEST          request;
    size_t              bufLength=0;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "--> NICServiceReadIrps\n");


    for(index=0; index < PacketArrayCount; index++)
    {
        pMpRfd = PacketArray[index];
        ASSERT(pMpRfd);

        status = WdfIoQueueRetrieveNextRequest( FdoData->PendingReadQueue,
                                                &request );

        if(NT_SUCCESS(status)){

            WDF_REQUEST_PARAMETERS  params;
            ULONG                   length = 0;

            WDF_REQUEST_PARAMETERS_INIT(&params);

            WdfRequestGetParameters(
                request,
                &params
                 );

            ASSERT(status == STATUS_SUCCESS);

            bufLength = params.Parameters.Read.Length;

            status = WdfRequestRetrieveOutputBuffer(request,
                                                    bufLength,
                                                    &buffer,
                                                    &bufLength);
            if(NT_SUCCESS(status) ) {

                length = min((ULONG)bufLength, pMpRfd->PacketSize);

                RtlCopyMemory(buffer, pMpRfd->Buffer, length);

                Hexdump((TRACE_LEVEL_VERBOSE, DBG_READ,
                         "Received Packet Data: %!HEXDUMP!\n",
                         log_xstr(buffer, (USHORT)length)));
                FdoData->BytesReceived += length;
            }

            WdfRequestCompleteWithInformation(request, status, length);
        }else {
            ASSERTMSG("WdfIoQueueRetrieveNextRequest failed",
                      (status == STATUS_NO_MORE_ENTRIES ||
                       status == STATUS_WDF_PAUSED));
        }

        WdfSpinLockAcquire(FdoData->RcvLock);

        ASSERT(MP_TEST_FLAG(pMpRfd, fMP_RFD_RECV_PEND));
        MP_CLEAR_FLAG(pMpRfd, fMP_RFD_RECV_PEND);


        if (FdoData->RfdShrinkCount < NIC_RFD_SHRINK_THRESHOLD)
        {
            NICReturnRFD(FdoData, pMpRfd);
        }
        else
        {
            ASSERT(FdoData->CurrNumRfd > FdoData->NumRfd);
            status = PciDrvQueuePassiveLevelCallback(FdoData,
                                    NICFreeRfdWorkItem, (PVOID)pMpRfd,
                                    NULL);
            if(NT_SUCCESS(status)){

                FdoData->RfdShrinkCount = 0;
                FdoData->CurrNumRfd--;
                TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "Shrink... CurrNumRfd = %d\n",
                                                    FdoData->CurrNumRfd);
            } else {
                //
                // We couldn't queue a workitem to free memory, so let us
                // put that back in the main pool and try again next time.
                //
                NICReturnRFD(FdoData, pMpRfd);
            }
        }


        WdfSpinLockRelease(FdoData->RcvLock);

    }// end of loop

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<-- NICServiceReadIrps\n");

    return;

}
static VOID
XenBus_EvtIoWrite(WDFQUEUE queue, WDFREQUEST request, size_t length)
{
  NTSTATUS status;
  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfIoQueueGetDevice(queue));
  WDFFILEOBJECT file_object = WdfRequestGetFileObject(request);
  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  KIRQL old_irql;
  WDFREQUEST read_request;

  PUCHAR buffer;
  PUCHAR src_ptr;
  ULONG src_len;
  PUCHAR dst_ptr;
  ULONG copy_len;
  struct xsd_sockmsg *rep;
  xenbus_read_queue_item_t *list_entry;
  watch_context_t *watch_context;
  PCHAR watch_path;
  PCHAR watch_token;
  PCHAR msg;
  
  FUNCTION_ENTER();
  
  status = WdfRequestRetrieveInputBuffer(request, length, &buffer, NULL);
  ASSERT(NT_SUCCESS(status));
  
  src_ptr = (PUCHAR)buffer;
  src_len = (ULONG)length;
  dst_ptr = xpdid->xenbus.u.buffer + xpdid->xenbus.len;
  while (src_len != 0)
  {
    KdPrint((__DRIVER_NAME "     %d bytes of write buffer remaining\n", src_len));
    /* get a complete msg header */
    if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg))
    {
      copy_len = min(sizeof(xpdid->xenbus.u.msg) - xpdid->xenbus.len, src_len);
      if (!copy_len)
        continue;
      memcpy(dst_ptr, src_ptr, copy_len);
      dst_ptr += copy_len;
      src_ptr += copy_len;
      src_len -= copy_len;
      xpdid->xenbus.len += copy_len;
    }
    /* exit if we can't get that */
    if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg))
      continue;
    /* get a complete msg body */
    if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg) + xpdid->xenbus.u.msg.len)
    {
      copy_len = min(sizeof(xpdid->xenbus.u.msg) + xpdid->xenbus.u.msg.len - xpdid->xenbus.len, src_len);
      if (!copy_len)
        continue;
      memcpy(dst_ptr, src_ptr, copy_len);
      dst_ptr += copy_len;
      src_ptr += copy_len;
      src_len -= copy_len;
      xpdid->xenbus.len += copy_len;
    }
    /* exit if we can't get that */
    if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg) + xpdid->xenbus.u.msg.len)
    {
      continue;
    }
    
    switch (xpdid->xenbus.u.msg.type)
    {
    case XS_WATCH:
    case XS_UNWATCH:
      KeAcquireSpinLock(&xpdid->lock, &old_irql);
      watch_context = (watch_context_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(watch_context_t), XENPCI_POOL_TAG);
      watch_path = (PCHAR)(xpdid->xenbus.u.buffer + sizeof(struct xsd_sockmsg));
      watch_token = (PCHAR)(xpdid->xenbus.u.buffer + sizeof(struct xsd_sockmsg) + strlen(watch_path) + 1);
      RtlStringCbCopyA(watch_context->path, ARRAY_SIZE(watch_context->path), watch_path);
      RtlStringCbCopyA(watch_context->token, ARRAY_SIZE(watch_context->path), watch_token);
      watch_context->file_object = file_object;
      if (xpdid->xenbus.u.msg.type == XS_WATCH)
        InsertTailList(&xpdid->xenbus.watch_list_head, &watch_context->entry);
      KeReleaseSpinLock(&xpdid->lock, old_irql);
      if (xpdid->xenbus.u.msg.type == XS_WATCH)
        msg = XenBus_AddWatch(xpdd, XBT_NIL, watch_path, XenPci_IoWatch, watch_context);
      else
        msg = XenBus_RemWatch(xpdd, XBT_NIL, watch_path, XenPci_IoWatch, watch_context);
      KeAcquireSpinLock(&xpdid->lock, &old_irql);
      if (msg != NULL)
      {
        rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg) + strlen(msg) + 1, XENPCI_POOL_TAG);
        rep->type = XS_ERROR;
        rep->req_id = xpdid->xenbus.u.msg.req_id;
        rep->tx_id = xpdid->xenbus.u.msg.tx_id;
        rep->len = (ULONG)(strlen(msg) + 0);
        RtlStringCbCopyA((PCHAR)(rep + 1), strlen(msg) + 1, msg);
        if (xpdid->xenbus.u.msg.type == XS_WATCH)
          RemoveEntryList(&watch_context->entry);
      }
      else
      {
        if (xpdid->xenbus.u.msg.type == XS_WATCH)
        {
          WdfObjectReference(file_object);
        }
        else
        {
          RemoveEntryList(&watch_context->entry);
          WdfObjectDereference(file_object);
        }
        rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg), XENPCI_POOL_TAG);
        rep->type = xpdid->xenbus.u.msg.type;
        rep->req_id = xpdid->xenbus.u.msg.req_id;
        rep->tx_id = xpdid->xenbus.u.msg.tx_id;
        rep->len = 0;
      }
      KeReleaseSpinLock(&xpdid->lock, old_irql);
      break;
    default:
      rep = XenBus_Raw(xpdd, &xpdid->xenbus.u.msg);
      break;
    }
    xpdid->xenbus.len = 0;
    
    KeAcquireSpinLock(&xpdid->lock, &old_irql);
    list_entry = (xenbus_read_queue_item_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(xenbus_read_queue_item_t), XENPCI_POOL_TAG);
    list_entry->data = rep;
    list_entry->length = sizeof(*rep) + rep->len;
    list_entry->offset = 0;
    InsertTailList(&xpdid->xenbus.read_list_head, (PLIST_ENTRY)list_entry);

	// Check if someone was waiting for the answer already
	status = WdfIoQueueRetrieveNextRequest(xpdid->xenbus.io_queue, &read_request);
    if (NT_SUCCESS(status))
    {
		WDF_REQUEST_PARAMETERS parameters;
		KdPrint((__DRIVER_NAME "     post-write: found pending read\n"));
		WDF_REQUEST_PARAMETERS_INIT(&parameters);
		WdfRequestGetParameters(read_request, &parameters);
		XenBus_ProcessReadRequest(xpdid->xenbus.io_queue, read_request, parameters.Parameters.Read.Length);
		WdfRequestComplete(read_request, STATUS_SUCCESS);
    }
    else
    {
		KdPrint((__DRIVER_NAME "     post-write: no pending read (%08x)\n", status));
    }

    KeReleaseSpinLock(&xpdid->lock, old_irql);
  }
  KdPrint((__DRIVER_NAME "     completing request with length %d\n", length));
  WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, length);

  FUNCTION_EXIT();
}
示例#15
0
VOID
kmdf1394_BusResetRoutine(
                         IN PVOID    Context)
{
    WDFDEVICE device= Context;
    PDEVICE_EXTENSION deviceExtension = GetDeviceContext(device);
    NTSTATUS ntStatus    = STATUS_SUCCESS;
    WDFREQUEST request;
    WDF_WORKITEM_CONFIG workItemConfig;
    WDFWORKITEM workItem;
    WDF_OBJECT_ATTRIBUTES attributes;

    ENTER("kmdf1394_BusResetRoutine");

    TRACE(TL_TRACE, ("Context = 0x%x\n", Context));

    WDF_WORKITEM_CONFIG_INIT (&workItemConfig, kmdf1394_BusResetRoutineWorkItem);

    WDF_OBJECT_ATTRIBUTES_INIT (&attributes);
    attributes.ParentObject = device;

    ntStatus = WdfWorkItemCreate( &workItemConfig,
        &attributes,
        &workItem);
    if (!NT_SUCCESS (ntStatus)) 
    {
        TRACE(TL_ERROR, ("Failed to create workitem %x\n", ntStatus));
        return;
    }

    //
    // Execute this work item.
    //
    WdfWorkItemEnqueue (workItem);

    //
    // If we have any bus reset notify irps, then nows the
    // time to complete them.
    //
    WHILE (TRUE)
    {
        ntStatus = WdfIoQueueRetrieveNextRequest (
            deviceExtension->BusResetRequestsQueue,
            &request);
        if(NT_SUCCESS (ntStatus))
        {
            TRACE(TL_TRACE, ("Completing BusReset Request = 0x%p\n", request));
            WdfRequestCompleteWithInformation (request, STATUS_SUCCESS, 0);
            // continue;
        }
        else if (STATUS_NO_MORE_ENTRIES == ntStatus)
        {
            TRACE (TL_TRACE, ("Request Queue is empty.\n"));
            break;
        }
        else 
        {
            ASSERTMSG (
                "WdfIoQueueRetrieveNextRequest failed", 
                ntStatus);
            break;
        }
    }

    EXIT("kmdf1394_BusResetRoutine", ntStatus);
} // kmdf1394_BusResetRoutine
示例#16
0
VOID
BusDogAddTraceToFifo(
    WDFDEVICE device,
    ULONG DeviceId,
    BUSDOG_REQUEST_TYPE Type,
    BUSDOG_REQUEST_PARAMS Params,
    PVOID TraceBuffer,
    ULONG BufferLength
    )
{
    PBUSDOG_FILTER_TRACE_FIFO_ITEM pTraceItem = NULL; 
    WDFREQUEST request;
    NTSTATUS status;

    WdfSpinLockAcquire(BusDogTraceFifoLock);

    //
    // First add trace to the fifo
    //

    pTraceItem = BusDogTraceFifo.TraceItems[BusDogTraceFifo.WriteIndex];

    pTraceItem = 
        __BusDogCreateTrace(
            pTraceItem,
            DeviceId,
            Type,
            Params,
            TraceBuffer,
            BufferLength);

    BusDogTraceFifo.TraceItems[BusDogTraceFifo.WriteIndex] = 
        pTraceItem;

    BusDogTraceFifo.WriteIndex++;

    if (BusDogTraceFifo.WriteIndex >= BUSDOG_FILTER_TRACE_FIFO_LENGTH)
        BusDogTraceFifo.WriteIndex = 0;

    if (BusDogTraceFifo.WriteIndex == BusDogTraceFifo.ReadIndex)
    {
        BusDogPrint(BUSDOG_DEBUG_ERROR, "On noes! We have overflow\n");
    }

    //
    // Now see if we can complete a request from the manual queue
    //
    
    status = WdfIoQueueRetrieveNextRequest(
            BufferRequestQueue,
            &request);

    if (NT_SUCCESS(status))
    {
        size_t bytesWritten;

        status = __BusDogFufillRequestWithTraces(request, &bytesWritten);

        //
        // Ok for better or worse we finally completed this request
        //

        WdfRequestCompleteWithInformation(request, status, bytesWritten);
    }
    else
    {
        if (status != STATUS_NO_MORE_ENTRIES)
        {
            BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfIoQueueRetrieveNextRequest failed - 0x%x\n",
                status);
        }
    }

    WdfSpinLockRelease(BusDogTraceFifoLock);
}
示例#17
0
VOID
CyCompleteIoctlRequest(
    __in WDFDEVICE WdfDevice
    )
{
	NTSTATUS            NtStatus;
    WDFREQUEST          request;
    PDEVICE_CONTEXT     pDevContext;
    size_t              szBytesReturned = 0;
    PUCHAR              pucData;
	PREQUEST_CONTEXT    pReqContext;

    pDevContext = CyGetDeviceContext(WdfDevice);

    do 
	{
       //check for pending request
        NtStatus = WdfIoQueueRetrieveNextRequest(pDevContext->IntInMsgQ, &request);
        if (NT_SUCCESS(NtStatus))
		{
			pReqContext = CyGetRequestContext(request);
			if(pReqContext->IsNeitherIO)
			{
				pucData = WdfMemoryGetBuffer(pReqContext->OutputMemoryBufferWrite,NULL);
				*pucData = pDevContext->ucIntInData;
				szBytesReturned = sizeof(UCHAR);
			}
			else
			{
				NtStatus = WdfRequestRetrieveOutputBuffer(request,
														sizeof(UCHAR),
														&pucData,
														NULL);// BufferLength

				if (!NT_SUCCESS(NtStatus)) 
				{

					CyTraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
						"User's output buffer is too small for this IOCTL, expecting a SWITCH_STATE\n");
					szBytesReturned = sizeof(UCHAR);

				}
				else
				{
				   *pucData = pDevContext->ucIntInData;
					szBytesReturned = sizeof(UCHAR);
				}
			}

            WdfRequestCompleteWithInformation(request, NtStatus, szBytesReturned);
            NtStatus = STATUS_SUCCESS;

        }
		else if (NtStatus != STATUS_NO_MORE_ENTRIES)
		{
            CyTraceEvents(TRACE_LEVEL_ERROR,DBG_IOCTL,"WdfIoQueueRetrieveNextRequest status %08x\n", NtStatus);
        }
        request = NULL;
    } while (NtStatus == STATUS_SUCCESS);

}