예제 #1
0
// This callback is called when interval wait time has expired and driver is ready
// to collect new sample. The callback reads current value, compare value to threshold,
// pushes it up to CLX framework, and schedule next wake up time.
VOID ActivityDevice::OnTimerExpire(_In_ WDFTIMER timer)
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(WdfTimerGetParentObject(timer));
    if (nullptr == pDevice)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status);
    }
    else
    {
        // Get data and push to clx
        WdfWaitLockAcquire(pDevice->m_Lock, NULL);
        status = pDevice->GetData();
        if (!NT_SUCCESS(status) && STATUS_DATA_NOT_ACCEPTED != status)
        {
            TraceError("ACT %!FUNC! GetAccData Failed %!STATUS!", status);
        }
        WdfWaitLockRelease(pDevice->m_Lock);

        // Schedule next wake up time
        if (Act_Default_MinDataInterval_Ms <= pDevice->m_Interval &&
            FALSE != pDevice->m_PoweredOn &&
            FALSE != pDevice->m_Started)
        {
            WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval));
        }
    }

    SENSOR_FunctionExit(status);
}
예제 #2
0
// Called by Sensor CLX to begin keeping history
NTSTATUS ActivityDevice::OnStartHistory(_In_ SENSOROBJECT sensorInstance)
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
    if (nullptr == pDevice)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status);
    }
    else if (0 == pDevice->m_HistorySizeInRecords)
    {
        status = STATUS_NOT_SUPPORTED;
        TraceError("ACT %!FUNC! Sensor does not support History");
    }
    else if (FALSE == pDevice->m_PoweredOn)
    {
        status = STATUS_DEVICE_NOT_READY;
        TraceError("ACT %!FUNC! Sensor is not powered on! %!STATUS!", status);
    }
    else
    {
        // Start keeping history
        pDevice->m_HistoryStarted = TRUE;
        WdfTimerStart(pDevice->m_HistoryTimer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_HistoryIntervalInMs));
    }

    SENSOR_FunctionExit(status);
    return status;
}
예제 #3
0
// Called by Sensor CLX to clear all history stored in the sensor.
NTSTATUS ActivityDevice::OnClearHistory(_In_ SENSOROBJECT sensorInstance)
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
    if (nullptr == pDevice)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status);
    }
    else
    {
        WdfWaitLockAcquire(pDevice->m_HistoryLock, NULL);
        status = pDevice->ClearHistoryBuffer();
        if (!NT_SUCCESS(status))
        {
            TraceError("ACT %!FUNC! ClearHistoryBuffer Failed %!STATUS!", status);
        }
        WdfWaitLockRelease(pDevice->m_HistoryLock);
    }

    SENSOR_FunctionExit(status);
    return status;
}
예제 #4
0
// Called by Sensor CLX to stop continously sampling the sensor.
NTSTATUS ActivityDevice::OnStop(_In_ SENSOROBJECT sensorInstance)
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();
    
    PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
    if (nullptr == pDevice)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status);
    }
    else
    {
        // Stop sensing
        pDevice->m_Started = FALSE;
        WdfTimerStop(pDevice->m_Timer, TRUE);
        InitPropVariantFromUInt32(SensorState_Idle, &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));
    
        // Stop simulation
        if (NULL != pDevice->m_SimulatorInstance)
        {
            PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
            if (nullptr != pSimulator)
            {
                pSimulator->Stop();
            }
        }
    }
    
    SENSOR_FunctionExit(status);
    return status;
}
예제 #5
0
// This routine is called by the framework when the PnP manager sends an
// IRP_MN_START_DEVICE request to the driver stack. This routine is
// responsible for performing operations that are necessary to make the
// driver's device operational (for e.g. mapping the hardware resources
// into memory).
NTSTATUS ActivityDevice::OnPrepareHardware(
    _In_ WDFDEVICE device,                      // Supplies a handle to the framework device object
    _In_ WDFCMRESLIST /*ResourcesRaw*/,         // Supplies a handle to a collection of framework resource
                                                // objects. This collection identifies the raw (bus-relative) hardware
                                                // resources that have been assigned to the device.
    _In_ WDFCMRESLIST /*ResourcesTranslated*/)  // Supplies a handle to a collection of framework
                                                // resource objects. This collection identifies the translated
                                                // (system-physical) hardware resources that have been assigned to the
                                                // device. The resources appear from the CPU's point of view.
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // Create WDFOBJECT for the sensor
    WDF_OBJECT_ATTRIBUTES sensorAttributes = {};
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&sensorAttributes, ActivityDevice);
    
    // Register sensor instance with clx
    SENSOROBJECT sensorInstance = NULL;
    status = SensorsCxSensorCreate(device, &sensorAttributes, &sensorInstance);
    if (!NT_SUCCESS(status))
    {
        TraceError("ACT %!FUNC! SensorsCxSensorCreate failed %!STATUS!", status);
    }
    else
    {
        PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
        if (nullptr == pDevice)
        {
            status = STATUS_INSUFFICIENT_RESOURCES;
            TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status);
        }
        else
        {
            // Fill out properties
            status = pDevice->Initialize(device, sensorInstance);
            if (!NT_SUCCESS(status))
            {
                TraceError("ACT %!FUNC! Initialize device object failed %!STATUS!", status);
            }
            else
            {
                SENSOR_CONFIG sensorConfig = {};
                SENSOR_CONFIG_INIT(&sensorConfig);
                sensorConfig.pEnumerationList = pDevice->m_pEnumerationProperties;
                status = SensorsCxSensorInitialize(sensorInstance, &sensorConfig);
                if (!NT_SUCCESS(status))
                {
                    TraceError("ACT %!FUNC! SensorsCxSensorInitialize failed %!STATUS!", status);
                }
            }
        }
    }

    SENSOR_FunctionExit(status);
    return status;
}
예제 #6
0
// This callback is called when interval wait time has expired and driver is ready
// to collect new sample. The callback stores activity data in history buffer,
// and schedules next wake up time.
VOID ActivityDevice::OnHistoryTimerExpire(_In_ WDFTIMER historyTimer)
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(WdfTimerGetParentObject(historyTimer));
    if (nullptr == pDevice)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status);
    }
    else
    {
        ActivitySample data = {};
        if (NULL != pDevice->m_SimulatorInstance)
        {
            PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
            if (nullptr != pSimulator)
            {
                status = pSimulator->GetSample(&data);
            }
            else
            {
                status = STATUS_INVALID_PARAMETER;
            }
        }
        GetSystemTimePreciseAsFileTime(&(data.Timestamp));

        if (NT_SUCCESS(status))
        {
            // Add data to the buffer
            WdfWaitLockAcquire(pDevice->m_HistoryLock, NULL);
            status = pDevice->AddDataElementToHistoryBuffer(&data);
            if (!NT_SUCCESS(status))
            {
                TraceError("ACT %!FUNC! AddDataElementToHistoryBuffer Failed %!STATUS!", status);
            }
            WdfWaitLockRelease(pDevice->m_HistoryLock);
        }

        // Schedule next wake up time
        if (FALSE != pDevice->m_HistoryStarted)
        {
            WdfTimerStart(pDevice->m_HistoryTimer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_HistoryIntervalInMs));
        }
    }

    SENSOR_FunctionExit(status);
}
예제 #7
0
// Called by Sensor CLX to begin continously sampling the sensor.
NTSTATUS ActivityDevice::OnStart(_In_ SENSOROBJECT sensorInstance)
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
    if (nullptr == pDevice)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status);
    }
    else
    {
        if (FALSE == pDevice->m_PoweredOn)
        {
            status = STATUS_DEVICE_NOT_READY;
            TraceError("ACT %!FUNC! Sensor is not powered on! %!STATUS!", status);
        }
        else
        {
            // Start simulation
            if (NULL != pDevice->m_SimulatorInstance)
            {
                PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
                if (nullptr != pSimulator)
                {
                    pSimulator->Start();
                }
            }

            // Start sensing
            pDevice->m_FirstSample = TRUE;
            pDevice->m_Started = TRUE;
            InitPropVariantFromUInt32(SensorState_Active, &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));
            WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(Act_Default_MinDataInterval_Ms));
        }
    }

    SENSOR_FunctionExit(status);
    return status;
}
예제 #8
0
// This routine is invoked by the framework to program the device to goto 
// D0, which is the working state. The framework invokes callback every
// time the hardware needs to be (re-)initialized.  This includes after
// IRP_MN_START_DEVICE, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE,
// and IRP_MN_SET_POWER-D0.
NTSTATUS ActivityDevice::OnD0Entry(
    _In_ WDFDEVICE device,                          // Supplies a handle to the framework device object
    _In_ WDF_POWER_DEVICE_STATE /*PreviousState*/)  // WDF_POWER_DEVICE_STATE-typed enumerator that identifies the device
                                                    // power state that the device was in before this transition to D0.
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

     // Get sensor instance
    SENSOROBJECT sensorInstance = NULL;
    ULONG sensorInstanceCount = 1;

    status = SensorsCxDeviceGetSensorList(device, &sensorInstance, &sensorInstanceCount);
    if (!NT_SUCCESS(status) || sensorInstanceCount == 0 || sensorInstance == NULL)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! SensorsCxDeviceGetSensorList failed %!STATUS!", status);
    }
    else
    {

        PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
        if (nullptr == pDevice)
        {
            status = STATUS_INVALID_PARAMETER;
            TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status);
        }
        else
        {
            // Power on sensor
            pDevice->m_PoweredOn = TRUE;
            InitPropVariantFromUInt32(SensorState_Idle, &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));
        }
    }

    SENSOR_FunctionExit(status);
    return status;
}
예제 #9
0
// Called by Sensor CLX to stop keeping history.
NTSTATUS ActivityDevice::OnStopHistory(_In_ SENSOROBJECT sensorInstance)
{ 
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
    if (nullptr == pDevice)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status);
    }
    else
    {
        // Stop keeping history
        pDevice->m_HistoryStarted = FALSE;
        WdfTimerStop(pDevice->m_HistoryTimer, TRUE);
    }

    SENSOR_FunctionExit(status);
    return status;
}
예제 #10
0
// This routine is invoked by the framework to program the device to go into
// a certain Dx state. The framework invokes callback every the the device is 
// leaving the D0 state, which happens when the device is stopped, when it is 
// removed, and when it is powered off.
NTSTATUS ActivityDevice::OnD0Exit(
    _In_ WDFDEVICE device,                          // Supplies a handle to the framework device object.
    _In_ WDF_POWER_DEVICE_STATE /*TargetState*/)    // Supplies the device power state which the device 
                                                    // will be put in once the callback is complete.
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // Get sensor instance
    SENSOROBJECT sensorInstance = NULL;
    ULONG sensorInstanceCount = 1;
    status = SensorsCxDeviceGetSensorList(device, &sensorInstance, &sensorInstanceCount);
    if (!NT_SUCCESS(status) || sensorInstanceCount == 0 || sensorInstance == NULL)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! SensorsCxDeviceGetSensorList failed %!STATUS!", status);
    }
    else
    {

        PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
        if (nullptr == pDevice)
        {
            status = STATUS_INVALID_PARAMETER;
            TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status);
        }
        else
        {
            // Power off sensor
            pDevice->m_PoweredOn = FALSE;
        }
    }

    SENSOR_FunctionExit(status);
    return status;
}
예제 #11
0
// This routine is called by the framework when the PnP manager is revoking
// ownership of our resources. This may be in response to either
// IRP_MN_STOP_DEVICE or IRP_MN_REMOVE_DEVICE. This routine is responsible for
// performing cleanup of resources allocated in PrepareHardware callback.
// This callback is invoked before passing  the request down to the lower driver.
// This routine will also be invoked by the framework if the prepare hardware
// callback returns a failure.
NTSTATUS ActivityDevice::OnReleaseHardware(
    _In_ WDFDEVICE device,                      // Supplies a handle to the framework device object
    _In_ WDFCMRESLIST /*ResourcesTranslated*/)  // Supplies a handle to a collection of framework
                                                // resource objects. This collection identifies the translated
                                                // (system-physical) hardware resources that have been assigned to the
                                                // device. The resources appear from the CPU's point of view.
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // Get sensor instance
    SENSOROBJECT sensorInstance = NULL;
    ULONG sensorInstanceCount = 1;    // only expect 1 sensor instance

    status = SensorsCxDeviceGetSensorList(device, &sensorInstance, &sensorInstanceCount);
    if (!NT_SUCCESS(status) || sensorInstanceCount == 0 || sensorInstance == NULL)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! SensorsCxDeviceGetSensorList failed %!STATUS!", status);
    }
    else
    {
        PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
        if (nullptr == pDevice)
        {
            status = STATUS_INVALID_PARAMETER;
            TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status);
        }
        else
        {
            // Cleanup activity simulator
            if (NULL != pDevice->m_SimulatorInstance)
            {
                PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
                if (nullptr != pSimulator)
                {
                    pSimulator->Deinitialize();
                }
                // Continue tearing down
                WdfObjectDelete(pDevice->m_SimulatorInstance);
                pDevice->m_SimulatorInstance = NULL;
            }

            // Close handle to history retrieval thread
            if (NULL != pDevice->m_hThread)
            {
                SetEvent(pDevice->m_ExitEvent);

                DWORD result = WaitForSingleObjectEx(pDevice->m_hThread, Act_TimeoutForHistoryThread_Ms, FALSE);
                if (WAIT_OBJECT_0 != result)
                {
                    // continue tearing down
                    status = NTSTATUS_FROM_WIN32(result);
                    TraceError("ACT %!FUNC! WaitForSingleObjectEx failed %!STATUS!", status);
                }

                CloseHandle(pDevice->m_hThread);
                pDevice->m_hThread = NULL;
            }

            // Close handle to exit event
            if (NULL != pDevice->m_ExitEvent)
            {
                CloseHandle(pDevice->m_ExitEvent);
                pDevice->m_ExitEvent = NULL;
            }

            // Delete history lock
            if (NULL != pDevice->m_HistoryLock)
            {
                WdfObjectDelete(pDevice->m_HistoryLock);
                pDevice->m_HistoryLock = NULL;
            }

            // Delete lock
            if (NULL != pDevice->m_Lock)
            {
                WdfObjectDelete(pDevice->m_Lock);
                pDevice->m_Lock = NULL;
            }

            // Delete sensor instance.
            if (NULL != pDevice->m_SensorInstance)
            {
                // Memory created by WdfMemoryCreate with m_SensorInstance as parent object will be
                // destroyed automatically when m_SensorInstance is deleted. pDevice will be no longer
                // accessible at beyond this point.
                WdfObjectDelete(pDevice->m_SensorInstance);
                pDevice = nullptr;
            }
        }
    }
 
    SENSOR_FunctionExit(status);
    return status;
}
예제 #12
0
    SENSOR_FunctionExit(status);
    return status;
}

// Called by Sensor CLX to start retrieving history.
NTSTATUS ActivityDevice::OnStartHistoryRetrieval(
    _In_ SENSOROBJECT sensorInstance,
    _Inout_updates_bytes_(historySizeInBytes) PSENSOR_COLLECTION_LIST pHistoryBuffer,
    _In_ ULONG historySizeInBytes
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
    if (nullptr == pDevice)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status);
    }
    else
    {
        // Check if the previously created history retrieval thread finished.
        // When StartHistoryRetrieval is called again before we signal to CLX that history retrieval is
        // completed, fail the second call.
        WdfWaitLockAcquire(pDevice->m_HistoryLock, NULL);
        BOOLEAN IsStarted = pDevice->m_HistoryRetrievalStarted;
        WdfWaitLockRelease(pDevice->m_HistoryLock);

        if (FALSE != IsStarted)