//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- 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; }
NTSTATUS SimSensorScanPendingQueue ( _In_ WDFDEVICE Device ) /*++ Routine Description: This routine scans the device's pending queue for retirable requests. N.B. This routine requires the QueueLock be held. Arguments: Device - Supplies a handle to the device. --*/ { WDFREQUEST CurrentRequest; PFDO_DATA DevExt; WDFREQUEST LastRequest; ULONG LowerBound; NTSTATUS Status; ULONG Temperature; ULONG UpperBound; DebugEnter(); PAGED_CODE(); DevExt = GetDeviceExtension(Device); Status = STATUS_SUCCESS; LastRequest = NULL; CurrentRequest = NULL; Temperature = SimSensorReadVirtualTemperature(Device); // // Prime the walk by finding the first request present. If there are no // requests, bail out immediately. // LowerBound = 0; UpperBound = (ULONG)-1; Status = WdfIoQueueFindRequest(DevExt->PendingRequestQueue, NULL, NULL, NULL, &CurrentRequest); // // Due to a technical limitation in SDV analysis engine, the following // analysis assume has to be inserted to supress a false defect for // the wdfioqueueretrievefoundrequest rule. // _Analysis_assume_(Status == STATUS_NOT_FOUND); while (NT_SUCCESS(Status)) { // // Walk past the current request. By walking past the current request // before checking it, the walk doesn't have to restart every time a // request is satisfied and removed form the queue. // LastRequest = CurrentRequest; Status = WdfIoQueueFindRequest(DevExt->PendingRequestQueue, LastRequest, NULL, NULL, &CurrentRequest); // // Process the last request. // SimSensorCheckQueuedRequest(Device, Temperature, &LowerBound, &UpperBound, LastRequest); WdfObjectDereference(LastRequest); if(Status == STATUS_NOT_FOUND) { // // LastRequest unexpectedly disappeared from the queue. Start over. // LowerBound = 0; UpperBound = (ULONG)-1; Status = WdfIoQueueFindRequest(DevExt->PendingRequestQueue, NULL, NULL, NULL, &CurrentRequest); } } // // Update the thresholds based on the latest contents of the queue. // SimSensorSetVirtualInterruptThresholds(Device, LowerBound, UpperBound); DebugExitStatus(Status); return Status; }