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(); }
/////////////////////////////////////////////////////////////////////////////// // // 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; }
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); }
VOID FilterForwardRequestWithCompletionRoutine( IN WDFREQUEST Request, IN WDFIOTARGET Target ) /*++ Routine Description: This routine forwards the request to a lower driver with a completion so that when the request is completed by the lower driver, it can regain control of the request and look at the result. --*/ { BOOLEAN ret; NTSTATUS status; // // The following funciton essentially copies the content of // current stack location of the underlying IRP to the next one. // WdfRequestFormatRequestUsingCurrentType(Request); WdfRequestSetCompletionRoutine(Request, FilterRequestCompletionRoutine, WDF_NO_CONTEXT); ret = WdfRequestSend(Request, Target, WDF_NO_SEND_OPTIONS); if (ret == FALSE) { status = WdfRequestGetStatus (Request); KdPrint( ("WdfRequestSend failed: 0x%x\n", status)); WdfRequestComplete(Request, status); } return; }
/////////////////////////////////////////////////////////////////////////////// // 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
VOID SimSensorIoDeviceControl( WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode ) /*++ Routine Description: Handles requests to read or write the simulated device state. Arguments: Queue - Supplies a handle to the framework queue object that is associated with the I/O request. Request - Supplies a handle to a framework request object. This one represents the IRP_MJ_DEVICE_CONTROL IRP received by the framework. OutputBufferLength - Supplies the length, in bytes, of the request's output buffer, if an output buffer is available. InputBufferLength - Supplies the length, in bytes, of the request's input buffer, if an input buffer is available. IoControlCode - Supplies the Driver-defined or system-defined I/O control code (IOCtl) that is associated with the request. Return Value: VOID --*/ { ULONG BytesReturned; WDFDEVICE Device; BOOLEAN Result; WDF_REQUEST_SEND_OPTIONS RequestSendOptions; NTSTATUS Status; UNREFERENCED_PARAMETER(InputBufferLength); UNREFERENCED_PARAMETER(OutputBufferLength); PAGED_CODE(); Device = WdfIoQueueGetDevice(Queue); DebugPrint(SIMSENSOR_NOTE, "SimSensorIoDeviceControl: 0x%p\n", Device); BytesReturned = 0; switch(IoControlCode) { case IOCTL_THERMAL_READ_TEMPERATURE: // // This call will either complete the request or put it in the pending // queue. // SimSensorAddReadRequest(Device, Request); break; default: // // Unrecognized IOCtls must be forwarded down the stack. // WDF_REQUEST_SEND_OPTIONS_INIT( &RequestSendOptions, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); WdfRequestFormatRequestUsingCurrentType(Request); Result = WdfRequestSend( Request, WdfDeviceGetIoTarget(Device), &RequestSendOptions); if (Result == FALSE) { Status = WdfRequestGetStatus(Request); DebugPrint(SIMSENSOR_WARN, "WdfRequestSend() Failed. Request Status = 0x%x\n", Status); WdfRequestComplete(Request, Status); } break; } }