コード例 #1
0
// Called by Sensor CLX to set sampling rate of the sensor.
NTSTATUS
CustomSensorDevice::OnSetDataInterval(
    _In_ SENSOROBJECT SensorInstance, // sensor device object
    _In_ ULONG DataRateMs             // sampling rate in milliseconds
    )
{
    PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (nullptr == pDevice || Cstm_Default_MinDataInterval_Ms > DataRateMs)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! Sensor(%08X) parameter is invalid. Failed %!STATUS!", (INT) SensorInstance, Status);
        goto Exit;
    }

    pDevice->m_Interval = DataRateMs;

    // reschedule sample to return as soon as possible if it's started
    if (FALSE != pDevice->m_Started)
    {
        pDevice->m_Started = FALSE;
        WdfTimerStop(pDevice->m_Timer, TRUE);

        pDevice->m_Started = TRUE;
        pDevice->m_FirstSample = TRUE;
        WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(Cstm_Default_MinDataInterval_Ms));
    }

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #2
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;
}
コード例 #3
0
// Called by Sensor CLX to get sampling rate of the sensor.
NTSTATUS
CustomSensorDevice::OnGetDataInterval(
    _In_ SENSOROBJECT SensorInstance, // sensor device object
    _Out_ PULONG DataRateMs           // sampling rate in milliseconds
    )
{
    PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! Sensor(%08X) parameter is invalid. Failed %!STATUS!", (INT) SensorInstance, Status);
        goto Exit;
    }

    if (nullptr == DataRateMs)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! DataRateMs(%08X) parameter is invalid. Failed %!STATUS!", (INT)DataRateMs, Status);
        goto Exit;
    }

    *DataRateMs = pDevice->m_Interval;

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #4
0
// This callback is called when the simulator wait time has expired and the simulator
// is ready to switch to the next sample. The callback updates the sample index and 
// schedules the next wake up time.
VOID
HardwareSimulator::OnTimerExpire(
    _In_ WDFTIMER Timer) // WDF timer object
{
    HardwareSimulator *pSimulator = nullptr;
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    pSimulator = GetHardwareSimulatorContextFromInstance(WdfTimerGetParentObject(Timer));
    if (nullptr == pSimulator)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        TraceError("CSTM %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status);
    }

    if (NT_SUCCESS(Status))
    {
        // Increment the sample index, roll over if the index reach the end of the array
        WdfWaitLockAcquire(pSimulator->m_Lock, NULL);
        pSimulator->m_Index++;
        pSimulator->m_Index = pSimulator->m_Index % ARRAYSIZE(SimulatorData);
        WdfWaitLockRelease(pSimulator->m_Lock);

        WdfTimerStart(pSimulator->m_Timer, WDF_REL_TIMEOUT_IN_MS(SIMULATOR_HARDWARE_INTERVAL_MS));
    }

    SENSOR_FunctionExit(Status);
}
コード例 #5
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;
}
コード例 #6
0
// This routine initializes the supported data fields
NTSTATUS ActivityDevice::InitializeSupportedDataFields()
{
    WDF_OBJECT_ATTRIBUTES memoryAttributes = {};
    WDFMEMORY memoryHandle = NULL;
    const ULONG size = SENSOR_PROPERTY_LIST_SIZE(ACTIVITY_DATA_COUNT);
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes);
    memoryAttributes.ParentObject = m_SensorInstance;
    status = WdfMemoryCreate(&memoryAttributes,
        PagedPool,
        SENSOR_POOL_TAG_ACTIVITY,
        size,
        &memoryHandle,
        reinterpret_cast<PVOID*>(&m_pSupportedDataFields));
    if (!NT_SUCCESS(status) || nullptr == m_pSupportedDataFields)
    {
        TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status);
    }
    else
    {
        SENSOR_PROPERTY_LIST_INIT(m_pSupportedDataFields, size);
        m_pSupportedDataFields->Count = ACTIVITY_DATA_COUNT;

        m_pSupportedDataFields->List[ACTIVITY_DATA_TIMESTAMP] = PKEY_SensorData_Timestamp;
        m_pSupportedDataFields->List[ACTIVITY_DATA_CURRENT_STATE] = PKEY_SensorData_CurrentActivityState;
        m_pSupportedDataFields->List[ACTIVITY_DATA_CURRENT_CONFIDENCE] = PKEY_SensorData_CurrentActivityStateConfidence_Percentage;
    }

    SENSOR_FunctionExit(status);
    return status;
}
コード例 #7
0
// Called by Sensor CLX to begin continously sampling the sensor.
NTSTATUS
CustomSensorDevice::OnStart(
    _In_ SENSOROBJECT SensorInstance // sensor device object
    )
{
    PHardwareSimulator pSimulator = nullptr;
    PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("PED %!FUNC! Sensor(%08X) parameter is invalid. Failed %!STATUS!", (INT)SensorInstance, Status);
    }

    if (NT_SUCCESS(Status))
    {
        // Get the simulator context
        pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
        if (nullptr == pSimulator)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            TraceError("PED %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status);
        }
    }

    if (NT_SUCCESS(Status))
    {
        // Start the simulator
        pSimulator->Start();

        pDevice->m_FirstSample = TRUE;

        // Start polling
        pDevice->m_Started = TRUE;

        InitPropVariantFromUInt32(SensorState_Active,
            &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));


        // Start the sample polling timer.
        // Note1: the WDF timer is only as precise as the system resolution allows it to be.
        // In the case of the CO2 sensor, the reporting interval is 200 milliseconds. The default 
        // system resolution (15.6 milliseconds) is therefore fine enough to guarantee an accurate sample 
        // reporting interval. Some sensors using a lower reporting interval may want to reduce the system 
        // time resolution by calling into timeBeginPeriod() before starting the polling timer.
        //
        // Important consideration: calling into timeBeginPeriod() should be used with care as it has 
        // an adverse on the system performance and power consumption.
        //
        // Note2: The polling timer is configured to allow for the first sample to be reported immediately.
        // Some hardware may want to delay the first sample report a little to account for hardware start time.
        WdfTimerStart(pDevice->m_Timer, 0);
    }

    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #8
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;
}
コード例 #9
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);
}
コード例 #10
0
// UNSUPPORTED at this point of time
NTSTATUS
CustomSensorDevice::OnGetDataThresholds(
    _In_ SENSOROBJECT /*SensorInstance*/,                // sensor device object
    _Inout_opt_ PSENSOR_COLLECTION_LIST /*pThresholds*/, // pointer to a list of sensor thresholds
    _Out_ PULONG pSize                                   // number of bytes for the list of sensor thresholds
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    SENSOR_COLLECTION_LIST emptyList = {};

    SENSOR_FunctionEnter();

    if (nullptr == pSize)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! Invalid parameters! %!STATUS!", Status);
        goto Exit;
    }

    // Even though thresholds are not yet supported for custom sensors,
    // the minimum reported size must be that of an empty list for the 
    // class extension to work properly
    emptyList.AllocatedSizeInBytes = sizeof(emptyList);

    *pSize = CollectionsListGetMarshalledSize(&emptyList);

    SENSOR_FunctionExit(Status);

Exit:
    return Status;
}
コード例 #11
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;
}
コード例 #12
0
// Called by Sensor CLX to get sensor properties. The typical usage is to call
// this function once with buffer pointer as NULL to acquire the required size 
// for the buffer, allocate buffer, then call the function again to retrieve 
// sensor information.
NTSTATUS
CustomSensorDevice::OnGetProperties(
    _In_ SENSOROBJECT SensorInstance,                // sensor device object
    _Inout_opt_ PSENSOR_COLLECTION_LIST pProperties, // pointer to a list of sensor properties
    _Out_ PULONG pSize                               // number of bytes for the list of sensor properties
    )
{
    PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (nullptr == pSize)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! pSize: Invalid parameter! %!STATUS!", Status);
        goto Exit;
    }

    *pSize = 0;

    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! pDevice: Invalid parameter! %!STATUS!", Status);
        goto Exit;
    }

    if (nullptr == pProperties)
    {
        // Just return size
        *pSize = CollectionsListGetMarshalledSize(pDevice->m_pProperties);
    }
    else 
    {
        if (pProperties->AllocatedSizeInBytes < 
            CollectionsListGetMarshalledSize(pDevice->m_pProperties))
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            TraceError("CSTM %!FUNC! Buffer is too small. Failed %!STATUS!", Status);
            goto Exit;
        }

        // Fill out all data
        Status = CollectionsListCopyAndMarshall(pProperties, pDevice->m_pProperties);
        if (!NT_SUCCESS(Status))
        {
            TraceError("CSTM %!FUNC! CollectionsListCopyAndMarshall failed %!STATUS!", Status);
            goto Exit;
        }

        *pSize = CollectionsListGetMarshalledSize(pDevice->m_pProperties);
    }

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #13
0
//------------------------------------------------------------------------------
// Function: GetData
//
// This routine is called by worker thread to read a single sample, compare threshold
// and push it back to CLX. It simulates hardware thresholding by only generating data
// when the change of data is greater than threshold.
//
// Arguments:
//       None
//
// Return Value:
//      NTSTATUS code
//------------------------------------------------------------------------------
NTSTATUS
PrxDevice::GetData(
    )
{
    BOOLEAN DataReady = FALSE;
    FILETIME TimeStamp = {0};
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // new sample?
    if (m_FirstSample != FALSE)
    {
        Status = GetPerformanceTime(&m_StartTime);
        if (!NT_SUCCESS(Status))
        {
            m_StartTime = 0;
            TraceError("COMBO %!FUNC! PRX GetPerformanceTime %!STATUS!", Status);
        }

        m_SampleCount = 0;

        DataReady = TRUE;
    }
    else
    {
        // Compare the change of detection state, and only push the data back to
        // clx. This is usually done in HW.
        if (m_CachedData.Detected != m_LastSample.Detected)
        {
            DataReady = TRUE;
        }
    }

    if (DataReady != FALSE)
    {
        // update last sample
        m_LastSample = m_CachedData;

        // push to clx
        InitPropVariantFromBoolean(m_LastSample.Detected, &(m_pData->List[PRX_DATA_DETECT].Value));
        InitPropVariantFromUInt32(m_LastSample.DistanceMillimeters, &(m_pData->List[PRX_DATA_DISTANCE].Value));

        GetSystemTimePreciseAsFileTime(&TimeStamp);
        InitPropVariantFromFileTime(&TimeStamp, &(m_pData->List[PRX_DATA_TIMESTAMP].Value));

        SensorsCxSensorDataReady(m_SensorInstance, m_pData);
        m_FirstSample = FALSE;
    }
    else
    {
        Status = STATUS_DATA_NOT_ACCEPTED;
        TraceInformation("COMBO %!FUNC! PRX Data did NOT meet the threshold");
    }

    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #14
0
// Called by Sensor CLX to get supported data fields. The typical usage is to call
// this function once with buffer pointer as NULL to acquire the required size 
// for the buffer, allocate buffer, then call the function again to retrieve 
// sensor information.
NTSTATUS
CustomSensorDevice::OnGetSupportedDataFields(
    _In_ SENSOROBJECT SensorInstance,          // sensor device object
    _Inout_opt_ PSENSOR_PROPERTY_LIST pFields, // pointer to a list of supported properties
    _Out_ PULONG pSize                         // number of bytes for the list of supported properties
    )
{
    PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (nullptr == pSize)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! pSize: Invalid parameter! %!STATUS!", Status);
        goto Exit;
    }

    *pSize = 0;

    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! pDevice: Invalid parameter! %!STATUS!", Status);
        goto Exit;
    }

    if (nullptr == pFields)
    {
        // Just return size
        *pSize = pDevice->m_pSupportedDataFields->AllocatedSizeInBytes;
    }
    else 
    {
        if (pFields->AllocatedSizeInBytes < pDevice->m_pSupportedDataFields->AllocatedSizeInBytes)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            TraceError("CSTM %!FUNC! Buffer is too small. Failed %!STATUS!", Status);
            goto Exit;
        }

        // Fill out data
        Status = PropertiesListCopy (pFields, pDevice->m_pSupportedDataFields);
        if (!NT_SUCCESS(Status))
        {
            TraceError("CSTM %!FUNC! PropertiesListCopy failed %!STATUS!", Status);
            goto Exit;
        }

        *pSize = pDevice->m_pSupportedDataFields->AllocatedSizeInBytes;
    }

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #15
0
// Internal routine to perform simulator initialization
NTSTATUS
HardwareSimulator::InitializeInternal(
    _In_ WDFOBJECT SimulatorInstance)    // Instance of the WDF object for the simulator
{
    NTSTATUS Status = STATUS_SUCCESS;
    WDF_OBJECT_ATTRIBUTES TimerAttributes = {};
    WDF_TIMER_CONFIG TimerConfig = {};

    SENSOR_FunctionEnter();

    // Only initialize the simulator if it is in the "not initialized" state
    if (SimulatorState_NotInitialized == m_State)
    {
        // Create Lock
        Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_Lock);
        if (!NT_SUCCESS(Status))
        {
            m_Lock = NULL;

            TraceError("CSTM %!FUNC! WdfWaitLockCreate failed %!STATUS!", Status);
            goto Exit;
        }

        // Create a timer object for simulation updates
        WDF_TIMER_CONFIG_INIT(&TimerConfig, HardwareSimulator::OnTimerExpire);
        WDF_OBJECT_ATTRIBUTES_INIT(&TimerAttributes);
        TimerAttributes.ParentObject = SimulatorInstance;
        TimerAttributes.ExecutionLevel = WdfExecutionLevelPassive;

        Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &m_Timer);
        if (!NT_SUCCESS(Status))
        {
            m_Timer = NULL;

            TraceError("CSTM %!FUNC! WdfTimerCreate failed %!STATUS!", Status);
            goto Exit;
        }

        // Set the simulator state to "initialized"
        m_State = SimulatorState_Initialized;
        m_SimulatorInstance = SimulatorInstance;
    }

Exit:
    if (!NT_SUCCESS(Status) && NULL != m_Lock)
    {
        WdfObjectDelete(m_Lock);
        m_Lock = NULL;
    }

    SENSOR_FunctionExit(Status);

    return Status;
}
コード例 #16
0
// Called by Sensor CLX to begin keeping history
NTSTATUS
PedometerDevice::OnStartHistory(
    _In_ SENSOROBJECT SensorInstance // Sensor device object
    )
{
    PPedometerDevice pDevice = GetPedometerContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;
    PHardwareSimulator pSimulator = nullptr;

    SENSOR_FunctionEnter();

    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("PED %!FUNC! Sensor(0x%p) parameter is invalid. Failed %!STATUS!", SensorInstance, Status);
        goto Exit;
    }

    if (FALSE == pDevice->m_HistorySupported)
    {
        Status = STATUS_NOT_SUPPORTED;
        TraceError("PED %!FUNC! History is not supported by the HW");
        goto Exit;
    }

    if (FALSE == pDevice->m_PoweredOn)
    {
        Status = STATUS_DEVICE_NOT_READY;
        TraceError("PED %!FUNC! Sensor is not powered on! %!STATUS!", Status);
        goto Exit;
    }

    pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);

    if (nullptr == pSimulator)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        TraceError("PED %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status);
        goto Exit;
    }

    // Start the pedometer history
    Status = pSimulator->StartHistory();
    if (!NT_SUCCESS(Status))
    {
        TraceError("PED %!FUNC! Start History failed %!STATUS!", Status);
    }

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #17
0
// Called by Sensor CLX to begin continuously sampling the sensor.
NTSTATUS
PedometerDevice::OnStart(
    _In_ SENSOROBJECT SensorInstance // Sensor device object
    )
{
    PHardwareSimulator pSimulator = nullptr;
    PPedometerDevice pDevice = GetPedometerContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("PED %!FUNC! Sensor(0x%p) parameter is invalid. Failed %!STATUS!", SensorInstance, Status);
        goto Exit;
    }

    // Get the simulator context
    pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
    if (nullptr == pSimulator)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        TraceError("PED %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status);
    }

    if (NT_SUCCESS(Status))
    {
        // Start the simulator
        pSimulator->Start();

        pDevice->m_FirstSample = TRUE;

        // Start polling

        pDevice->m_Started = TRUE;

        InitPropVariantFromUInt32(SensorState_Active,
            &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));

        // Start the sample polling timer.
        //
        // Note: The polling timer is configured to allow for the first sample to be reported immediately.
        // Some hardware may want to delay the first sample report a little to account for hardware start time.
        WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(Pedometer_Default_MinDataInterval_Ms));
    }
Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #18
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);
}
コード例 #19
0
// This routine returns the current sample from the driver at the current m_Index location.
// Returns one of the ABI::Windows::Devices::Sensors::SimpleOrientation enum values.
ABI::Windows::Devices::Sensors::SimpleOrientation HardwareSimulator::GetOrientation()
{
    ABI::Windows::Devices::Sensors::SimpleOrientation Sample = ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Faceup;
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    WdfWaitLockAcquire(m_Lock, NULL);
    Sample = OrientationData[m_Index];
    WdfWaitLockRelease(m_Lock);

    SENSOR_FunctionExit(Status);

    return Sample;
}
コード例 #20
0
// UNSUPPORTED at this point of time
NTSTATUS
CustomSensorDevice::OnSetDataThresholds(
    _In_ SENSOROBJECT /*SensorInstance*/,         // sensor device object
    _In_ PSENSOR_COLLECTION_LIST /*pThresholds*/  // pointer to a list of sensor thresholds
    )
{
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // Usupported at this point in time

    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #21
0
//------------------------------------------------------------------------------
// Function: OnDriverUnload
//
// This routine is called when the driver unloads.
//
// Arguments:
//      Driver: IN: driver object
//
// Return Value:
//      NTSTATUS code
//------------------------------------------------------------------------------
VOID
OnDriverUnload(
    _In_ WDFDRIVER Driver
    )
{
    SENSOR_FunctionEnter();

    UNREFERENCED_PARAMETER(Driver);

    SENSOR_FunctionExit(STATUS_SUCCESS);

    WPP_CLEANUP(Driver);

    return;
}
コード例 #22
0
// This routine stops the simulator
// Returns an NTSTATUS code
NTSTATUS HardwareSimulator::Stop()
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (SimulatorState_Started == m_State)
    {
        WdfTimerStop(m_Timer, TRUE);
        m_State = SimulatorState_Initialized;
    }

    SENSOR_FunctionExit(status);

    return status;
}
コード例 #23
0
// This routine returns the current sample from the driver at the current m_Index
// location
FLOAT
HardwareSimulator::GetSample()
{
    FLOAT Sample = 0.0f;
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    WdfWaitLockAcquire(m_Lock, NULL);
    Sample = SimulatorData[m_Index];
    WdfWaitLockRelease(m_Lock);

    SENSOR_FunctionExit(Status);

    return Sample;
}
コード例 #24
0
// This routine starts the simulator
// Returns an NTSTATUS code
NTSTATUS HardwareSimulator::Start()
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (SimulatorState_Initialized == m_State)
    {
        WdfTimerStart(m_Timer, WDF_REL_TIMEOUT_IN_MS(HardwareSimulator_HardwareInterval));
        m_State = SimulatorState_Started;
    }

    SENSOR_FunctionExit(status);

    return status;
}
コード例 #25
0
// Called by Sensor CLX to handle IOCTLs that clx does not support
NTSTATUS
CustomSensorDevice::OnIoControl(
    _In_ SENSOROBJECT /*SensorInstance*/, // WDF queue object
    _In_ WDFREQUEST /*Request*/,          // WDF request object
    _In_ size_t /*OutputBufferLength*/,   // number of bytes to retrieve from output buffer
    _In_ size_t /*InputBufferLength*/,    // number of bytes to retrieve from input buffer
    _In_ ULONG /*IoControlCode*/          // IOCTL control code
    )
{
    NTSTATUS Status = STATUS_NOT_SUPPORTED;

    SENSOR_FunctionEnter();

    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #26
0
// This routine is called when the driver unloads.
VOID
OnDriverUnload(
    _In_ WDFDRIVER Driver // Driver object
    )
{
    SENSOR_FunctionEnter();

    SENSOR_FunctionExit(STATUS_SUCCESS);

    // WPP_CLEANUP doesn't actually use the Driver parameter
    // So we need to set it as unreferenced.
    UNREFERENCED_PARAMETER(Driver);
    WPP_CLEANUP(WdfDriverWdmGetDriverObject(Driver));

    return;
}
コード例 #27
0
// Called by Sensor CLX to stop continously sampling the sensor.
NTSTATUS
CustomSensorDevice::OnStop(
    _In_ SENSOROBJECT SensorInstance // sensor device object
    )
{
    PHardwareSimulator pSimulator = nullptr;
    PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();
    
    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! Sensor(%08X) parameter is invalid. Failed %!STATUS!", (INT) SensorInstance, Status);
    }

    if (NT_SUCCESS(Status))
    {
        // Stop polling

        pDevice->m_Started = FALSE;

        // Waiting for the callback to complete, then stopping the timer
        WdfTimerStop(pDevice->m_Timer, TRUE);

        InitPropVariantFromUInt32(SensorState_Idle,
            &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));

        // Stop the simulator
        pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
        if (nullptr == pSimulator)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            TraceError("CSTM %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status);
            goto Exit;
        }

        pSimulator->Stop();
    }

Exit:
    SENSOR_FunctionExit(Status);

    return Status;
}
コード例 #28
0
//------------------------------------------------------------------------------
// Function: DriverEntry
//
// This routine is the driver initialization entry point.
//
// Arguments:
//      DriverObject: IN: Pointer to the driver object created by the I/O manager
//      RegistryPath: IN: Pointer to the driver specific registry key
//
// Return Value:
//      NTSTATUS code
//------------------------------------------------------------------------------
NTSTATUS
DriverEntry(
    _In_  PDRIVER_OBJECT  DriverObject,
    _In_  PUNICODE_STRING RegistryPath
    )
{
    WDF_DRIVER_CONFIG DriverConfig;
    NTSTATUS Status = STATUS_SUCCESS;

    //
    // Initialize WPP Tracing
    //
    WPP_INIT_TRACING(DriverObject, NULL);

    SENSOR_FunctionEnter();

    DriverConfig.DriverPoolTag = SENSORV2_POOL_TAG_COMBO;

    //
    // Initialize the driver configuration structure.
    //
    WDF_DRIVER_CONFIG_INIT(&DriverConfig, OnDeviceAdd);
    DriverConfig.EvtDriverUnload = OnDriverUnload;

    //
    // Create a framework driver object to represent our driver.
    //
    Status = WdfDriverCreate(DriverObject,
                             RegistryPath,
                             WDF_NO_OBJECT_ATTRIBUTES,
                             &DriverConfig,
                             WDF_NO_HANDLE);

    if (!NT_SUCCESS(Status))
    {
        TraceError("COMBO %!FUNC! WdfDriverCreate failed: %!STATUS!", Status);
        goto Exit;
    }

Exit:
    SENSOR_FunctionExit(Status);

    return Status;
}
コード例 #29
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
PedometerDevice::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
{
    PPedometerDevice pDevice;
    SENSOROBJECT SensorInstance = NULL;
    ULONG SensorInstanceCount = 1;
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

     // Get sensor instance
    Status = SensorsCxDeviceGetSensorList(Device, &SensorInstance, &SensorInstanceCount);
    if (!NT_SUCCESS(Status) ||
        0 == SensorInstanceCount ||
        NULL == SensorInstance)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("PED %!FUNC! SensorsCxDeviceGetSensorList failed %!STATUS!", Status);
        goto Exit;
    }

    pDevice = GetPedometerContextFromSensorInstance(SensorInstance);
    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("PED %!FUNC! GetPedometerContextFromSensorInstance failed %!STATUS!", Status);
        goto Exit;
    }

    //
    // Power on sensor
    //
    pDevice->m_PoweredOn = TRUE;
    InitPropVariantFromUInt32(SensorState_Idle, 
                              &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
コード例 #30
0
// This routine initializes the data field properties
NTSTATUS ActivityDevice::InitializeDataFieldProperties()
{
    WDF_OBJECT_ATTRIBUTES memoryAttributes = {};
    WDFMEMORY memoryHandle = NULL;
    const ULONG size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_DATA_FIELD_PROPERTY_COUNT);
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes);
    memoryAttributes.ParentObject = m_SensorInstance;
    status = WdfMemoryCreate(&memoryAttributes,
        PagedPool,
        SENSOR_POOL_TAG_ACTIVITY,
        size,
        &memoryHandle,
        reinterpret_cast<PVOID*>(&m_pDataFieldProperties));
    if (!NT_SUCCESS(status) || nullptr == m_pDataFieldProperties)
    {
        TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status);
    }
    else
    {
        SENSOR_COLLECTION_LIST_INIT(m_pDataFieldProperties, size);
        m_pDataFieldProperties->Count = SENSOR_DATA_FIELD_PROPERTY_COUNT;

        m_pDataFieldProperties->List[SENSOR_RESOLUTION].Key = PKEY_SensorDataField_Resolution;
        InitPropVariantFromFloat(ActivityFakeDevice_Confidence_Resolution,
            &(m_pDataFieldProperties->List[SENSOR_RESOLUTION].Value));

        m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Key = PKEY_SensorDataField_RangeMinimum;
        InitPropVariantFromFloat(ActivityFakeDevice_Confidence_Minimum,
            &(m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Value));

        m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Key = PKEY_SensorDataField_RangeMaximum;
        InitPropVariantFromFloat(ActivityFakeDevice_Confidence_Maximum,
            &(m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Value));
    }

    SENSOR_FunctionExit(status);
    return status;
}