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; }
// 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; }
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__); }
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(); }
// 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; }
VOID EchoEvtRequestCancel( IN WDFREQUEST Request ) /*++ Routine Description: Called when an I/O request is cancelled after the driver has marked the request cancellable. This callback is automatically synchronized with the I/O callbacks since we have chosen to use frameworks Device level locking. Arguments: Request - Request being cancelled. Return Value: VOID --*/ { PQUEUE_CONTEXT queueContext = QueueGetContext(WdfRequestGetIoQueue(Request)); KdPrint(("EchoEvtRequestCancel called on Request 0x%p\n", Request)); // // The following is race free by the callside or DPC side // synchronizing completion by calling // WdfRequestMarkCancelable(Queue, Request, FALSE) before // completion and not calling WdfRequestComplete if the // return status == STATUS_CANCELLED. // WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L); // // This book keeping is synchronized by the common // Queue presentation lock // ASSERT(queueContext->CurrentRequest == Request); queueContext->CurrentRequest = NULL; return; }
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__); }
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 ); }
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__); }
VOID VIOSerialPortWriteRequestCancel(IN WDFREQUEST Request) { BOOLEAN cancel = FALSE; PVIOSERIAL_PORT Port = RawPdoSerialPortGetData( WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)))->port; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: 0x%p\n", __FUNCTION__, Request); if (Port->PendingWriteRequest) { Port->PendingWriteRequest = NULL; cancel = TRUE; } if (cancel) { WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L); } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__); }
VOID VirtRngEvtRequestCancel(IN WDFREQUEST Request) { PDEVICE_CONTEXT context = GetDeviceContext(WdfIoQueueGetDevice( WdfRequestGetIoQueue(Request))); PSINGLE_LIST_ENTRY iter; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "--> %!FUNC! Cancelled Request: %p", Request); WdfSpinLockAcquire(context->VirtQueueLock); WdfRequestComplete(Request, STATUS_CANCELLED); iter = &context->ReadBuffersList; while (iter->Next != NULL) { PREAD_BUFFER_ENTRY entry = CONTAINING_RECORD(iter->Next, READ_BUFFER_ENTRY, ListEntry); if (Request == entry->Request) { TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "Clear entry %p request.", entry); entry->Request = NULL; break; } else { iter = iter->Next; } }; WdfSpinLockRelease(context->VirtQueueLock); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<-- %!FUNC!"); }
/*++ Routine Description: This routine is used to cancel the current write. Arguments: Device - Wdf handle for the device Request - Pointer to the WDFREQUEST to be canceled. Return Value: None. --*/ _Use_decl_annotations_ VOID SerialCancelCurrentXoff( WDFREQUEST Request ) { PSERIAL_DEVICE_EXTENSION extension; WDFDEVICE device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)); UNREFERENCED_PARAMETER(Request); extension = SerialGetDeviceExtension(device); SerialTryToCompleteCurrent(extension, SerialGrabXoffFromIsr, STATUS_CANCELLED, &extension->CurrentXoffRequest, NULL, NULL, extension->XoffCountTimer, NULL, NULL, SERIAL_REF_CANCEL); }
VOID EvtRequestWriteCompletionRoutine( _In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_ PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, _In_ WDFCONTEXT Context ) /*++ Routine Description: This is the completion routine for reads/writes If the irp completes with success, we check if we need to recirculate this irp for another stage of transfer. Arguments: Context - Driver supplied context Device - Device handle Request - Request handle Params - request completion params Return Value: None --*/ { NTSTATUS status; size_t bytesWritten = 0; GUID activity = RequestToActivityId(Request); PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; UNREFERENCED_PARAMETER(Target); UNREFERENCED_PARAMETER(Context); status = CompletionParams->IoStatus.Status; // // For usb devices, we should look at the Usb.Completion param. // usbCompletionParams = CompletionParams->Parameters.Usb.Completion; bytesWritten = usbCompletionParams->Parameters.PipeWrite.Length; if (NT_SUCCESS(status)){ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "Number of bytes written: %I64d\n", (INT64)bytesWritten); } else { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "Write failed: request Status 0x%x UsbdStatus 0x%x\n", status, usbCompletionParams->UsbdStatus); } // // Log write stop event, using IRP activtiy ID if available or request // handle otherwise // EventWriteWriteStop(&activity, WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)), bytesWritten, status, usbCompletionParams->UsbdStatus); WdfRequestCompleteWithInformation(Request, status, bytesWritten); return; }
NTSTATUS HidFx2SetOutput(_In_ WDFREQUEST hRequest) { NTSTATUS status = STATUS_SUCCESS; PHID_XFER_PACKET pTransferPacket = NULL; WDF_REQUEST_PARAMETERS params; PHIDFX2_IO_REPORT pOutputReport = NULL; WDFDEVICE hDevice; PAGED_CODE(); TraceVerbose(DBG_IOCTL, "(%!FUNC!) Enter\n"); hDevice = WdfIoQueueGetDevice(WdfRequestGetIoQueue(hRequest)); WDF_REQUEST_PARAMETERS_INIT(¶ms); WdfRequestGetParameters(hRequest, ¶ms); if (params.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET)) { status = STATUS_BUFFER_TOO_SMALL; TraceErr(DBG_IOCTL, "(%!FUNC!) Userbuffer is small %!STATUS!\n", status); return status; } pTransferPacket = (PHID_XFER_PACKET) WdfRequestWdmGetIrp(hRequest)->UserBuffer; if (pTransferPacket == NULL) { status = STATUS_INVALID_DEVICE_REQUEST; TraceErr(DBG_IOCTL, "(%!FUNC!) Irp->UserBuffer is NULL %!STATUS!\n", status); return status; } if (pTransferPacket->reportBufferLen == 0) { status = STATUS_BUFFER_TOO_SMALL; TraceErr(DBG_IOCTL, "(%!FUNC!) HID_XFER_PACKET->reportBufferLen is 0, %!STATUS!\n", status); return status; } if (pTransferPacket->reportBufferLen < sizeof(UCHAR)) { status = STATUS_BUFFER_TOO_SMALL; TraceErr(DBG_IOCTL, "(%!FUNC!) HID_XFER_PACKET->reportBufferLen is too small, %!STATUS!\n", status); return status; } if (pTransferPacket->reportId != GENERIC_DESKTOP_REPORT_ID) { status = STATUS_INVALID_DEVICE_REQUEST; TraceErr(DBG_IOCTL, "(%!FUNC!) Incorrect report ID, %!STATUS!\n", status); return status; } pOutputReport = (PHIDFX2_IO_REPORT)pTransferPacket->reportBuffer; if (pOutputReport->bData == 0) { status = SendVendorCommand(hDevice, HIDFX2_SET_BARGRAPH_DISPLAY, BARGRAPH_LED_ALL_OFF); } else { status = SendVendorCommand(hDevice, HIDFX2_SET_BARGRAPH_DISPLAY, BARGRAPH_LED_ALL_ON); } TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit status %!STATUS!\n", status); return status; }
NTSTATUS HidFx2GetInput(_In_ WDFREQUEST hRequest) { NTSTATUS status = STATUS_SUCCESS; WDF_REQUEST_PARAMETERS params; WDFDEVICE hDevice; PHID_XFER_PACKET pTransferPacket = NULL; PHIDFX2_IO_REPORT pOutputReport = NULL; unsigned char bSwitchState = 0; PAGED_CODE(); TraceVerbose(DBG_IOCTL, "(%!FUNC!) Enter\n"); hDevice = WdfIoQueueGetDevice(WdfRequestGetIoQueue(hRequest)); WDF_REQUEST_PARAMETERS_INIT(¶ms); WdfRequestGetParameters(hRequest, ¶ms); if (params.Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_XFER_PACKET)) { status = STATUS_BUFFER_TOO_SMALL; TraceErr(DBG_IOCTL, "(%!FUNC!) Userbuffer is small %!STATUS!\n", status); return status; } pTransferPacket = (PHID_XFER_PACKET) WdfRequestWdmGetIrp(hRequest)->UserBuffer; if (pTransferPacket == NULL) { status = STATUS_INVALID_DEVICE_REQUEST; TraceErr(DBG_IOCTL, "(%!FUNC!) Irp->UserBuffer is NULL %!STATUS!\n", status); return status; } if (pTransferPacket->reportBufferLen == 0) { status = STATUS_BUFFER_TOO_SMALL; TraceErr(DBG_IOCTL, "(%!FUNC!) HID_XFER_PACKET->reportBufferLen is 0, %!STATUS!\n", status); return status; } if (pTransferPacket->reportBufferLen < sizeof(UCHAR)) { status = STATUS_BUFFER_TOO_SMALL; TraceErr(DBG_IOCTL, "(%!FUNC!) HID_XFER_PACKET->reportBufferLen is too small, %!STATUS!\n", status); return status; } if (pTransferPacket->reportId != GENERIC_DESKTOP_REPORT_ID) { status = STATUS_INVALID_DEVICE_REQUEST; TraceErr(DBG_IOCTL, "(%!FUNC!) Incorrect report ID, %!STATUS!\n", status); return status; } pOutputReport = (PHIDFX2_IO_REPORT)pTransferPacket->reportBuffer; // Get the switch state directly from the hardware status = HidFx2GetSwitchState(hDevice, &bSwitchState); TraceVerbose(DBG_IOCTL, "(%!FUNC!) switch state 0x%x\n", bSwitchState); //Mask off everything except the actual switch bit bSwitchState &= RADIO_SWITCH_BUTTONS_BIT_MASK; TraceVerbose(DBG_IOCTL, "(%!FUNC!) maskedswitch state 0x%x\n", bSwitchState); pOutputReport->bReportId = GENERIC_DESKTOP_REPORT_ID; pOutputReport->bData = bSwitchState; TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit status %!STATUS!\n", status); return status; }
NTSTATUS CBCardTracking( PSMARTCARD_EXTENSION SmartcardExtension ) /*++ CBCardTracking: callback handler for SMCLIB RDF_CARD_TRACKING. the requested event was validated by the smclib (i.e. a card removal request will only be passed if a card is present). for a win95 build STATUS_PENDING will be returned without any other action. for NT the cancel routine for the irp will be set to the drivers cancel routine. Arguments: SmartcardExtension context of call Return Value: STATUS_PENDING --*/ { WDFREQUEST request; PDEVICE_EXTENSION DeviceExtension; NTSTATUS status; SmartcardDebug( DEBUG_TRACE, ( "PSCR!CBCardTracking: Enter\n" ) ); request = GET_WDFREQUEST_FROM_IRP(SmartcardExtension->OsData->NotificationIrp); DeviceExtension = GetDeviceExtension(WdfIoQueueGetDevice(WdfRequestGetIoQueue(request))); IoMarkIrpPending(SmartcardExtension->OsData->NotificationIrp); // // Move the stack pointer back to where it was when the IRP // was delivered to the driver. This compensates for the // IoSetNextIrpStackLocation that we did when we presented the IRP // to the smartcard libarary. // IoSkipCurrentIrpStackLocation(SmartcardExtension->OsData->NotificationIrp); status = WdfRequestForwardToIoQueue(request, DeviceExtension->NotificationQueue); if (!NT_SUCCESS(status)) { NT_ASSERT(NT_SUCCESS(status)); InterlockedExchangePointer( &(SmartcardExtension->OsData->NotificationIrp), NULL ); WdfRequestComplete(request, status); } status = STATUS_PENDING; SmartcardDebug( DEBUG_TRACE, ( "PSCR!CBCardTracking: Exit \n" ) ); return status; }
VOID EvtRequestReadCompletionRoutine( __in WDFREQUEST Request, __in WDFIOTARGET Target, __in PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, __in WDFCONTEXT Context ) /*++ Routine Description: This is the completion routine for reads/writes If the irp completes with success, we check if we need to recirculate this irp for another stage of transfer. Arguments: Context - Driver supplied context Device - Device handle Request - Request handle Params - request completion params Return Value: None --*/ { NTSTATUS status; size_t bytesRead = 0; GUID activity = RequestToActivityId(Request); PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; UNREFERENCED_PARAMETER(Target); UNREFERENCED_PARAMETER(Context); status = CompletionParams->IoStatus.Status; usbCompletionParams = CompletionParams->Parameters.Usb.Completion; bytesRead = usbCompletionParams->Parameters.PipeRead.Length; if (NT_SUCCESS(status)){ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ, "Number of bytes read: %I64d\n", (INT64)bytesRead); } else { TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "Read failed - request status 0x%x UsbdStatus 0x%x\n", status, usbCompletionParams->UsbdStatus); } // // Log read stop event, using request as activity id // EventWriteReadStop(&activity, WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)), bytesRead, status, usbCompletionParams->UsbdStatus); WdfRequestCompleteWithInformation(Request, status, bytesRead); return; }