コード例 #1
0
ファイル: Events.c プロジェクト: planetlabs/dta
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- 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;
}
コード例 #2
0
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;
}