//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsDequeue -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaEventsDequeue( DtaDeviceData* pDvcData, DtFileObject* pFile, DtaEvents* pEvents) // If not NULL, we don't need the file object { WDF_REQUEST_PARAMETERS Params; WDFREQUEST Request; WDFREQUEST Request2; NTSTATUS NtStatus = STATUS_SUCCESS; size_t BufSize; DtaIoctlOutputData* pOutBuf; // Get all pending requests from queue for this file object while (NtStatus == STATUS_SUCCESS) { WDF_REQUEST_PARAMETERS_INIT(&Params); NtStatus = WdfIoQueueFindRequest(pDvcData->m_IalData.m_EventQueue, NULL, DtFileGetHandle(pFile), &Params, &Request); if (NtStatus != STATUS_SUCCESS) // Don't use the NT_SUCCESS macro here break; NtStatus = WdfIoQueueRetrieveFoundRequest(pDvcData->m_IalData.m_EventQueue, Request, &Request2); WdfObjectDereference(Request); if (!NT_SUCCESS(NtStatus)) continue; if (NT_SUCCESS(NtStatus)) { NtStatus = WdfRequestRetrieveOutputBuffer(Request2, Params.Parameters.DeviceIoControl.OutputBufferLength, &pOutBuf, &BufSize); } if (NT_SUCCESS(NtStatus)) { DtStatus Status; BufSize = sizeof(DtaIoctlGetEventOutput); Status = DtaEventsGet(pDvcData, pFile, pEvents, &pOutBuf->m_GetEvent.m_EventType, &pOutBuf->m_GetEvent.m_Value1, &pOutBuf->m_GetEvent.m_Value2); } if (!NT_SUCCESS(NtStatus)) BufSize = 0; // Complete request, use DtStatus in the driver-defined information field WdfRequestCompleteWithInformation(Request2, NtStatus, (ULONG_PTR)BufSize); } return DT_STATUS_OK; }
VOID SimSensorCheckQueuedRequest ( _In_ WDFDEVICE Device, _In_ ULONG Temperature, _Inout_ PULONG LowerBound, _Inout_ PULONG UpperBound, _In_ WDFREQUEST Request ) /*++ Routine Description: Examines a request and performs one of the following actions: * Retires the request if it is satisfied (the sensor temperature has exceeded the bounds specified in the request) * Retires the request if it is expired (the timer due time is in the past) * Tightens the upper and lower bounds if the request remains in the queue. Arguments: Device - Supplies a handle to the device which owns this request. Temperature - Supplies the current thermal zone temperature. LowerBound - Supplies the lower bound threshold to adjust. UpperBound - Supplies the upper bound threshold to adjust. Request - Supplies a handle to the request. --*/ { ULONG BytesReturned; LARGE_INTEGER CurrentTime; PFDO_DATA DevExt; size_t Length; PREAD_REQUEST_CONTEXT Context; WDFREQUEST RetrievedRequest; PULONG RequestTemperature; NTSTATUS Status; DebugEnter(); PAGED_CODE(); KeQuerySystemTime(&CurrentTime); DevExt = GetDeviceExtension(Device); Context = WdfObjectGetTypedContext(Request, READ_REQUEST_CONTEXT); RetrievedRequest = NULL; // // Complete the request if: // // 1. The temperature has exceeded one of the request thresholds. // 2. The request timeout is in the past (but not negative). // if (SimSensorAreConstraintsSatisfied(Temperature, Context->LowTemperature, Context->HighTemperature, Context->ExpirationTime)) { Status = WdfIoQueueRetrieveFoundRequest(DevExt->PendingRequestQueue, Request, &RetrievedRequest); if(!NT_SUCCESS(Status)) { DebugPrint(SIMSENSOR_ERROR, "WdfIoQueueRetrieveFoundRequest() Failed. 0x%x", Status); // // Bail, likely because the request disappeared from the // queue. // goto CheckQueuedRequestEnd; } Status = WdfRequestRetrieveOutputBuffer(RetrievedRequest, sizeof(ULONG), &RequestTemperature, &Length); if(NT_SUCCESS(Status) && (Length == sizeof(ULONG))) { *RequestTemperature = Temperature; BytesReturned = sizeof(ULONG); } else { // // The request's return buffer is malformed. // BytesReturned = 0; Status = STATUS_INVALID_PARAMETER; DebugPrint(SIMSENSOR_ERROR, "WdfRequestRetrieveOutputBuffer() Failed. 0x%x", Status); } WdfRequestCompleteWithInformation(RetrievedRequest, Status, BytesReturned); } else { // // The request will remain in the queue. Update the bounds accordingly. // if (*LowerBound < Context->LowTemperature) { *LowerBound = Context->LowTemperature; } if (*UpperBound > Context->HighTemperature) { *UpperBound = Context->HighTemperature; } } CheckQueuedRequestEnd: DebugExit(); return; }