bool validateShortcut() { QString path = systemShortcutPath(); if (path.isEmpty() || cExeName().isEmpty()) return false; if (cAlphaVersion()) { path += qsl("TelegramAlpha.lnk"); if (validateShortcutAt(path)) return true; } else { if (validateShortcutAt(path + qsl("Telegram Desktop/Telegram.lnk"))) return true; if (validateShortcutAt(path + qsl("Telegram Win (Unofficial)/Telegram.lnk"))) return true; path += qsl("Telegram.lnk"); if (validateShortcutAt(path)) return true; } ComPtr<IShellLink> shellLink; HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink)); if (!SUCCEEDED(hr)) return false; hr = shellLink->SetPath(QDir::toNativeSeparators(cExeDir() + cExeName()).toStdWString().c_str()); if (!SUCCEEDED(hr)) return false; hr = shellLink->SetArguments(L""); if (!SUCCEEDED(hr)) return false; hr = shellLink->SetWorkingDirectory(QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath()).toStdWString().c_str()); if (!SUCCEEDED(hr)) return false; ComPtr<IPropertyStore> propertyStore; hr = shellLink.As(&propertyStore); if (!SUCCEEDED(hr)) return false; PROPVARIANT appIdPropVar; hr = InitPropVariantFromString(getId(), &appIdPropVar); if (!SUCCEEDED(hr)) return false; hr = propertyStore->SetValue(getKey(), appIdPropVar); PropVariantClear(&appIdPropVar); if (!SUCCEEDED(hr)) return false; PROPVARIANT startPinPropVar; hr = InitPropVariantFromUInt32(APPUSERMODEL_STARTPINOPTION_NOPINONINSTALL, &startPinPropVar); if (!SUCCEEDED(hr)) return false; hr = propertyStore->SetValue(pkey_AppUserModel_StartPinOption, startPinPropVar); PropVariantClear(&startPinPropVar); if (!SUCCEEDED(hr)) return false; hr = propertyStore->Commit(); if (!SUCCEEDED(hr)) return false; ComPtr<IPersistFile> persistFile; hr = shellLink.As(&persistFile); if (!SUCCEEDED(hr)) return false; hr = persistFile->Save(QDir::toNativeSeparators(path).toStdWString().c_str(), TRUE); if (!SUCCEEDED(hr)) return false; return true; }
// 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; }
// 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; }
void MediaFoundationTransform::SetUint32Property(PROPERTYKEY key, UINT32 value) { PROPVARIANT propVar; InitPropVariantFromUInt32(value, &propVar); HRESULT hr = _propertyStore->SetValue(key, propVar); hr = S_OK; }
//------------------------------------------------------------------------------ // 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; }
// 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; }
// 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; }
// 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; }
// 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; }
// 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; }
// This routine initializes the sensor to its default properties NTSTATUS CustomSensorDevice::Initialize( _In_ WDFDEVICE Device, // WDFDEVICE object _In_ SENSOROBJECT SensorInstance // SENSOROBJECT for each sensor instance ) { ULONG Size = 0; WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; FILETIME Time = {}; WDF_OBJECT_ATTRIBUTES TimerAttributes; WDF_TIMER_CONFIG TimerConfig; NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); // Store device and instance m_FxDevice = Device; m_SensorInstance = SensorInstance; m_Started = FALSE; // Initialize the CO2 simulator HardwareSimulator::Initialize(Device, &m_SimulatorInstance); // Create Lock Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_Lock); if (!NT_SUCCESS(Status)) { TraceError("CSTM %!FUNC! WdfWaitLockCreate failed %!STATUS!", Status); goto Exit; } // Create timer object for polling sensor samples WDF_TIMER_CONFIG_INIT(&TimerConfig, CustomSensorDevice::OnTimerExpire); WDF_OBJECT_ATTRIBUTES_INIT(&TimerAttributes); TimerAttributes.ParentObject = SensorInstance; TimerAttributes.ExecutionLevel = WdfExecutionLevelPassive; Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &m_Timer); if (!NT_SUCCESS(Status)) { TraceError("CSTM %!FUNC! WdfTimerCreate failed %!STATUS!", Status); goto Exit; } // Sensor Enumeration Properties Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_ENUMERATION_PROPERTIES_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_CUSTOM_SENSOR, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pEnumerationProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pEnumerationProperties) { TraceError("CSTM %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pEnumerationProperties, Size); m_pEnumerationProperties->Count = SENSOR_ENUMERATION_PROPERTIES_COUNT; // The sensor type must be GUID_SensorType_Custom, the driver must also define and "vendor defined subtype" m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Key = DEVPKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_Custom, &(m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Value)); m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Key = DEVPKEY_Sensor_Manufacturer; InitPropVariantFromString(L"Microsoft", &(m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Value)); m_pEnumerationProperties->List[SENSOR_MODEL].Key = DEVPKEY_Sensor_Model; InitPropVariantFromString(L"CO2 based sample Custom sensor V2", &(m_pEnumerationProperties->List[SENSOR_MODEL].Value)); m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Key = DEVPKEY_Sensor_PersistentUniqueId; InitPropVariantFromCLSID(GUID_CustomSensorDevice_UniqueID, &(m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Value)); m_pEnumerationProperties->List[SENSOR_CATEGORY].Key = DEVPKEY_Sensor_Category; InitPropVariantFromCLSID(GUID_SensorCategory_Other, &(m_pEnumerationProperties->List[SENSOR_CATEGORY].Value)); m_pEnumerationProperties->List[SENSOR_ISPRIMARY].Key = DEVPKEY_Sensor_IsPrimary; InitPropVariantFromBoolean(FALSE, &(m_pEnumerationProperties->List[SENSOR_ISPRIMARY].Value)); // This value should be set to TRUE if multiple custom sensors // with the same vendor defined type exist on the system and // this sensor is the primary sensor m_pEnumerationProperties->List[SENSOR_VENDOR_DEFINED_TYPE].Key = DEVPKEY_Sensor_VendorDefinedSubType; InitPropVariantFromCLSID(GUID_CustomSensorDevice_VendorDefinedSubTypeID, &(m_pEnumerationProperties->List[SENSOR_VENDOR_DEFINED_TYPE].Value)); // Supported Data-Fields Size = SENSOR_PROPERTY_LIST_SIZE(CSTM_DATA_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_CUSTOM_SENSOR, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pSupportedDataFields)); if (!NT_SUCCESS(Status) || nullptr == m_pSupportedDataFields) { TraceError("CSTM %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_PROPERTY_LIST_INIT(m_pSupportedDataFields, Size); m_pSupportedDataFields->Count = CSTM_DATA_COUNT; m_pSupportedDataFields->List[CSTM_DATA_TIMESTAMP] = PKEY_SensorData_Timestamp; m_pSupportedDataFields->List[CSTM_DATA_CO2_LEVEL_PERCENT] = PKEY_CustomSensorSampleData_CO2Level; // Data Size = SENSOR_COLLECTION_LIST_SIZE(CSTM_DATA_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_CUSTOM_SENSOR, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pData)); if (!NT_SUCCESS(Status) || nullptr == m_pData) { TraceError("CSTM %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pData, Size); m_pData->Count = CSTM_DATA_COUNT; m_pData->List[CSTM_DATA_TIMESTAMP].Key = PKEY_SensorData_Timestamp; GetSystemTimePreciseAsFileTime(&Time); InitPropVariantFromFileTime(&Time, &(m_pData->List[CSTM_DATA_TIMESTAMP].Value)); // Initialize the sample, at this point of time the sensor is not started yet, // So, initialize the sample to a default value m_pData->List[CSTM_DATA_CO2_LEVEL_PERCENT].Key = PKEY_CustomSensorSampleData_CO2Level; InitPropVariantFromFloat(CustomSensorDevice_Minimum_CO2Level, &(m_pData->List[CSTM_DATA_CO2_LEVEL_PERCENT].Value)); // Sensor Properties m_Interval = Cstm_Default_MinDataInterval_Ms; Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_COMMON_PROPERTIES_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_CUSTOM_SENSOR, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pProperties) { TraceError("CSTM %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pProperties, Size); m_pProperties->Count = SENSOR_COMMON_PROPERTIES_COUNT; m_pProperties->List[SENSOR_PROPERTY_STATE].Key = PKEY_Sensor_State; InitPropVariantFromUInt32(SensorState_Initializing, &(m_pProperties->List[SENSOR_PROPERTY_STATE].Value)); m_pProperties->List[SENSOR_PROPERTY_MIN_INTERVAL].Key = PKEY_Sensor_MinimumDataInterval_Ms; InitPropVariantFromUInt32(Cstm_Default_MinDataInterval_Ms, &(m_pProperties->List[SENSOR_PROPERTY_MIN_INTERVAL].Value)); m_pProperties->List[SENSOR_PROPERTY_MAX_DATAFIELDSIZE].Key = PKEY_Sensor_MaximumDataFieldSize_Bytes; InitPropVariantFromUInt32(CollectionsListGetMarshalledSize(m_pData), &(m_pProperties->List[SENSOR_PROPERTY_MAX_DATAFIELDSIZE].Value)); m_pProperties->List[SENSOR_PROPERTY_SENSOR_TYPE].Key = PKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_Custom, &(m_pProperties->List[SENSOR_PROPERTY_SENSOR_TYPE].Value)); // Data filed properties Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_DATA_FIELD_PROPERTY_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_CUSTOM_SENSOR, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pDataFieldProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pDataFieldProperties) { TraceError("CSTM %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } 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((float)CustomSensorDevice_Resolution, &(m_pDataFieldProperties->List[SENSOR_RESOLUTION].Value)); m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Key = PKEY_SensorDataField_RangeMinimum; InitPropVariantFromFloat(CustomSensorDevice_Minimum_CO2Level, &(m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Value)); m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Key = PKEY_SensorDataField_RangeMaximum; InitPropVariantFromFloat(CustomSensorDevice_Maximum_CO2Level, &(m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Value)); // Reset the FirstSample flag m_FirstSample = TRUE; Exit: SENSOR_FunctionExit(Status); return Status; }
//------------------------------------------------------------------------------ // Function: Initialize // // This routine initializes the sensor to its default properties // // Arguments: // Device: IN: WDFDEVICE object // SensorInstance: IN: SENSOROBJECT for each sensor instance // // Return Value: // NTSTATUS code //------------------------------------------------------------------------------ NTSTATUS PrxDevice::Initialize( _In_ WDFDEVICE Device, _In_ SENSOROBJECT SensorInstance ) { NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); // // Store device and instance // m_Device = Device; m_SensorInstance = SensorInstance; m_Started = FALSE; // // Create Lock // Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_Lock); if (!NT_SUCCESS(Status)) { TraceError("COMBO %!FUNC! PRX WdfWaitLockCreate failed %!STATUS!", Status); goto Exit; } // // Create timer object for polling sensor samples // { WDF_OBJECT_ATTRIBUTES TimerAttributes; WDF_TIMER_CONFIG TimerConfig; WDF_TIMER_CONFIG_INIT(&TimerConfig, OnTimerExpire); WDF_OBJECT_ATTRIBUTES_INIT(&TimerAttributes); TimerAttributes.ParentObject = SensorInstance; TimerAttributes.ExecutionLevel = WdfExecutionLevelPassive; Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &m_Timer); if (!NT_SUCCESS(Status)) { TraceError("COMBO %!FUNC! PRX WdfTimerCreate failed %!STATUS!", Status); goto Exit; } } // // Sensor Enumeration Properties // { WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; ULONG Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_PRX_ENUMERATION_PROPERTY_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_PROXIMITY, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pEnumerationProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pEnumerationProperties) { TraceError("COMBO %!FUNC! PRX WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pEnumerationProperties, Size); m_pEnumerationProperties->Count = SENSOR_ENUMERATION_PROPERTIES_COUNT; m_pEnumerationProperties->Count = SENSOR_PRX_ENUMERATION_PROPERTY_COUNT; m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Key = DEVPKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_Proximity, &(m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Value)); m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Key = DEVPKEY_Sensor_Manufacturer; InitPropVariantFromString(L"Manufacturer name", &(m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Value)); m_pEnumerationProperties->List[SENSOR_MODEL].Key = DEVPKEY_Sensor_Model; InitPropVariantFromString(L"PRX", &(m_pEnumerationProperties->List[SENSOR_MODEL].Value)); m_pEnumerationProperties->List[SENSOR_CONNECTION_TYPE].Key = DEVPKEY_Sensor_ConnectionType; // The DEVPKEY_Sensor_ConnectionType values match the SensorConnectionType enumeration InitPropVariantFromUInt32(static_cast<ULONG>(SensorConnectionType::Integrated), &(m_pEnumerationProperties->List[SENSOR_CONNECTION_TYPE].Value)); m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Key = DEVPKEY_Sensor_PersistentUniqueId; InitPropVariantFromCLSID(GUID_PrxDevice_UniqueID, &(m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Value)); m_pEnumerationProperties->List[SENSOR_ISPRIMARY].Key = DEVPKEY_Sensor_IsPrimary; InitPropVariantFromBoolean(FALSE, &(m_pEnumerationProperties->List[SENSOR_ISPRIMARY].Value)); m_pEnumerationProperties->List[SENSOR_PROPERTY_PRX_TYPE].Key = DEVPKEY_Sensor_ProximityType; InitPropVariantFromUInt32(PROXIMITY_TYPE::ProximityType_HumanProximity, &(m_pEnumerationProperties->List[SENSOR_PROPERTY_PRX_TYPE].Value)); m_pEnumerationProperties->List[SENSOR_ISWAKECAPABLE].Key = PKEY_Sensor_WakeCapable; InitPropVariantFromBoolean(FALSE, &(m_pEnumerationProperties->List[SENSOR_ISWAKECAPABLE].Value)); } // // Supported Data-Fields // { WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; ULONG Size = SENSOR_PROPERTY_LIST_SIZE(PRX_DATA_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_PROXIMITY, Size, &MemoryHandle, (PVOID*)&m_pSupportedDataFields); if (!NT_SUCCESS(Status) || m_pSupportedDataFields == nullptr) { TraceError("COMBO %!FUNC! PRX WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_PROPERTY_LIST_INIT(m_pSupportedDataFields, Size); m_pSupportedDataFields->Count = PRX_DATA_COUNT; m_pSupportedDataFields->List[PRX_DATA_TIMESTAMP] = PKEY_SensorData_Timestamp; m_pSupportedDataFields->List[PRX_DATA_DETECT] = PKEY_SensorData_ProximityDetection; m_pSupportedDataFields->List[PRX_DATA_DISTANCE] = PKEY_SensorData_ProximityDistanceMillimeters; } // // Data // { WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; ULONG Size = SENSOR_COLLECTION_LIST_SIZE(PRX_DATA_COUNT); FILETIME Time = {}; MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_PROXIMITY, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pData)); if (!NT_SUCCESS(Status) || nullptr == m_pData) { TraceError("COMBO %!FUNC! PRX WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pData, Size); m_pData->Count = PRX_DATA_COUNT; m_pData->List[PRX_DATA_TIMESTAMP].Key = PKEY_SensorData_Timestamp; GetSystemTimePreciseAsFileTime(&Time); InitPropVariantFromFileTime(&Time, &(m_pData->List[PRX_DATA_TIMESTAMP].Value)); m_pData->List[PRX_DATA_DETECT].Key = PKEY_SensorData_ProximityDetection; InitPropVariantFromBoolean(FALSE, &(m_pData->List[PRX_DATA_DETECT].Value)); m_pData->List[PRX_DATA_DISTANCE].Key = PKEY_SensorData_ProximityDistanceMillimeters; InitPropVariantFromUInt32(FALSE, &(m_pData->List[PRX_DATA_DISTANCE].Value)); m_CachedData.Detected = FALSE; m_CachedData.DistanceMillimeters = PrxDevice_Maximum_Millimeters; m_LastSample.Detected = FALSE; m_LastSample.DistanceMillimeters = PrxDevice_Maximum_Millimeters; } // // Sensor Properties // { WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; ULONG Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_COMMON_PROPERTY_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_PROXIMITY, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pProperties) { TraceError("COMBO %!FUNC! PRX WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pProperties, Size); m_pProperties->Count = SENSOR_COMMON_PROPERTY_COUNT; m_pProperties->List[SENSOR_COMMON_PROPERTY_STATE].Key = PKEY_Sensor_State; InitPropVariantFromUInt32(SensorState_Initializing, &(m_pProperties->List[SENSOR_COMMON_PROPERTY_STATE].Value)); m_pProperties->List[SENSOR_COMMON_PROPERTY_MIN_INTERVAL].Key = PKEY_Sensor_MinimumDataInterval_Ms; InitPropVariantFromUInt32(Prx_MinDataInterval_Ms, &(m_pProperties->List[SENSOR_COMMON_PROPERTY_MIN_INTERVAL].Value)); m_IntervalMs = Prx_MinDataInterval_Ms; m_MinimumIntervalMs = Prx_MinDataInterval_Ms; m_pProperties->List[SENSOR_COMMON_PROPERTY_MAX_DATAFIELDSIZE].Key = PKEY_Sensor_MaximumDataFieldSize_Bytes; InitPropVariantFromUInt32(CollectionsListGetMarshalledSize(m_pData), &(m_pProperties->List[SENSOR_COMMON_PROPERTY_MAX_DATAFIELDSIZE].Value)); m_pProperties->List[SENSOR_COMMON_PROPERTY_TYPE].Key = PKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_Proximity, &(m_pProperties->List[SENSOR_COMMON_PROPERTY_TYPE].Value)); } // // Data field properties // { WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; ULONG Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_DATA_FIELD_PROPERTY_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_PROXIMITY, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pDataFieldProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pDataFieldProperties) { TraceError("COMBO %!FUNC! PRX WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pDataFieldProperties, Size); m_pDataFieldProperties->Count = SENSOR_DATA_FIELD_PROPERTY_COUNT; m_pDataFieldProperties->List[SENSOR_RESOLUTION].Key = PKEY_SensorDataField_Resolution; InitPropVariantFromUInt32(PrxDevice_Resolution_Millimeters, &(m_pDataFieldProperties->List[SENSOR_RESOLUTION].Value)); m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Key = PKEY_SensorDataField_RangeMinimum; InitPropVariantFromUInt32(PrxDevice_Minimum_Millimeters, &(m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Value)); m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Key = PKEY_SensorDataField_RangeMaximum; InitPropVariantFromUInt32(PrxDevice_Maximum_Millimeters, &(m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Value)); } // // Set default threshold // { WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; ULONG Size = SENSOR_COLLECTION_LIST_SIZE(PRX_THRESHOLD_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSORV2_POOL_TAG_PROXIMITY, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pThresholds)); if (!NT_SUCCESS(Status) || nullptr == m_pThresholds) { TraceError("COMBO %!FUNC! PRX WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pThresholds, Size); m_FirstSample = TRUE; } Exit: SENSOR_FunctionExit(Status); return Status; }
// 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. NTSTATUS PedometerDevice::GetData( ) { PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(m_SimulatorInstance); BOOLEAN DataReady = FALSE; NTSTATUS Status = STATUS_SUCCESS; ULONG CachedStepCountLimit = 0; ULONG LastStepCountLimit = 0; PedometerSample Sample = {}; SENSOR_FunctionEnter(); if (nullptr == pSimulator) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("PED %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); goto Exit; } Status = pSimulator->GetSample(&Sample); if (!NT_SUCCESS(Status)) { TraceError("PED %!FUNC! GetSample failed %!STATUS!", Status); goto Exit; } if (FALSE != m_FirstSample) { Status = GetPerformanceTime(&m_StartTime); if (!NT_SUCCESS(Status)) { m_StartTime = 0; TraceError("PED %!FUNC! GetPerformanceTime failed %!STATUS!", Status); } m_SampleCount = 0; DataReady = TRUE; } else { if (0 == m_CachedThreshold || FALSE != Sample.IsFirstAfterReset) { // Streaming mode DataReady = TRUE; } else { if (FAILED(ULongAdd(Sample.UnknownStepCount, Sample.WalkingStepCount, &CachedStepCountLimit)) || FAILED(ULongAdd(Sample.RunningStepCount, CachedStepCountLimit, &CachedStepCountLimit))) { // If an overflow happened, we assume we reached the threshold // in other words, there is no threshold value that can be larger // than an overflowed value. DataReady = TRUE; } else if (FAILED(ULongAdd(m_LastSample.UnknownStepCount, m_LastSample.WalkingStepCount, &LastStepCountLimit)) || FAILED(ULongAdd(m_LastSample.RunningStepCount, LastStepCountLimit, &LastStepCountLimit))) { // If an overflow happened, we assume we reached the threshold // in other words, there is no threshold value that can be larger // than an overflowed value. DataReady = TRUE; } else if ((LastStepCountLimit < m_CachedThreshold && CachedStepCountLimit >= m_CachedThreshold) || (FALSE != Sample.IsFirstAfterReset)) { // Compare the change of data to threshold, and only push the data back to // clx if the change exceeds threshold or if this is the first sample after reset. This is usually done in HW. DataReady = TRUE; } } } if (FALSE != DataReady) { // update last sample m_LastSample = Sample; // push to clx InitPropVariantFromBoolean(m_LastSample.IsFirstAfterReset, &(m_pData->List[PEDOMETER_DATA_FIRST_AFTER_RESET].Value)); InitPropVariantFromUInt32(PedometerStepType_Unknown, &(m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_TYPE].Value)); InitPropVariantFromInt64(m_LastSample.UnknownStepDurationMs, &(m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_DURATION].Value)); InitPropVariantFromUInt32(m_LastSample.UnknownStepCount, &(m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_COUNT].Value)); InitPropVariantFromUInt32(PedometerStepType_Walking, &(m_pData->List[PEDOMETER_DATA_WALKING_STEP_TYPE].Value)); InitPropVariantFromInt64(m_LastSample.WalkingStepDurationMs, &(m_pData->List[PEDOMETER_DATA_WALKING_STEP_DURATION].Value)); InitPropVariantFromUInt32(m_LastSample.WalkingStepCount, &(m_pData->List[PEDOMETER_DATA_WALKING_STEP_COUNT].Value)); InitPropVariantFromUInt32(PedometerStepType_Running, &(m_pData->List[PEDOMETER_DATA_RUNNING_STEP_TYPE].Value)); InitPropVariantFromInt64(m_LastSample.RunningStepDurationMs, &(m_pData->List[PEDOMETER_DATA_RUNNING_STEP_DURATION].Value)); InitPropVariantFromUInt32(m_LastSample.RunningStepCount, &(m_pData->List[PEDOMETER_DATA_RUNNING_STEP_COUNT].Value)); // reset IsFirstAfterReset m_LastSample.IsFirstAfterReset = FALSE; InitPropVariantFromFileTime(&m_LastSample.Timestamp, &(m_pData->List[PEDOMETER_DATA_TIMESTAMP].Value)); SensorsCxSensorDataReady(m_SensorInstance, m_pData); m_FirstSample = FALSE; } else { Status = STATUS_DATA_NOT_ACCEPTED; TraceInformation("PED %!FUNC! Data did NOT meet the threshold"); } SENSOR_FunctionExit(Status); Exit: return Status; }
// This routine initializes the sensor's properties NTSTATUS ActivityDevice::InitializeSensorProperties() { WDF_OBJECT_ATTRIBUTES memoryAttributes = {}; WDFMEMORY memoryHandle = NULL; const ULONG size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_COMMON_PROPERTIES_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_pProperties)); if (!NT_SUCCESS(status) || nullptr == m_pProperties) { TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status); } else { SENSOR_COLLECTION_LIST_INIT(m_pProperties, size); m_pProperties->Count = SENSOR_COMMON_PROPERTIES_COUNT; m_pProperties->List[SENSOR_PROPERTY_STATE].Key = PKEY_Sensor_State; InitPropVariantFromUInt32(SensorState_Initializing, &(m_pProperties->List[SENSOR_PROPERTY_STATE].Value)); m_pProperties->List[SENSOR_PROPERTY_MIN_INTERVAL].Key = PKEY_Sensor_MinimumDataInterval_Ms; InitPropVariantFromUInt32(Act_Default_MinDataInterval_Ms, &(m_pProperties->List[SENSOR_PROPERTY_MIN_INTERVAL].Value)); m_pProperties->List[SENSOR_PROPERTY_MAX_DATAFIELDSIZE].Key = PKEY_Sensor_MaximumDataFieldSize_Bytes; InitPropVariantFromUInt32(CollectionsListGetMarshalledSize(m_pLastSample), &(m_pProperties->List[SENSOR_PROPERTY_MAX_DATAFIELDSIZE].Value)); m_pProperties->List[SENSOR_PROPERTY_SENSOR_TYPE].Key = PKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_ActivityDetection, &(m_pProperties->List[SENSOR_PROPERTY_SENSOR_TYPE].Value)); m_pProperties->List[SENSOR_PROPERTY_SENSOR_POWER].Key = PKEY_Sensor_Power_Milliwatts; InitPropVariantFromFloat((m_HistoryPowerInuW / 1000.0f), &(m_pProperties->List[SENSOR_PROPERTY_SENSOR_POWER].Value)); m_pProperties->List[SENSOR_PROPERTY_SUPPORTEDACTIVITIES].Key = PKEY_SensorData_SupportedActivityStates; InitPropVariantFromUInt32(Act_Default_SubscribedStates, &(m_pProperties->List[SENSOR_PROPERTY_SUPPORTEDACTIVITIES].Value)); m_pProperties->List[SENSOR_PROPERTY_MAX_HISTORYSIZE].Key = PKEY_SensorHistory_MaxSize_Bytes; InitPropVariantFromUInt32(SENSOR_COLLECTION_LIST_HEADER_SIZE + ((m_HistoryMarshalledRecordSize - SENSOR_COLLECTION_LIST_HEADER_SIZE) * m_HistorySizeInRecords), &(m_pProperties->List[SENSOR_PROPERTY_MAX_HISTORYSIZE].Value)); // History only logs one most probable state m_pProperties->List[SENSOR_PROPERTY_HISTORY_INTERVAL].Key = PKEY_SensorHistory_Interval_Ms; InitPropVariantFromUInt32(m_HistoryIntervalInMs, &(m_pProperties->List[SENSOR_PROPERTY_HISTORY_INTERVAL].Value)); m_pProperties->List[SENSOR_PROPERTY_MAX_HISTROYRECORDSIZE].Key = PKEY_SensorHistory_MaximumRecordSize_Bytes; InitPropVariantFromUInt32(m_HistoryMarshalledRecordSize, &(m_pProperties->List[SENSOR_PROPERTY_MAX_HISTROYRECORDSIZE].Value)); } SENSOR_FunctionExit(status); return status; }
// This routine initializes the sensor to its default properties NTSTATUS ActivityDevice::Initialize( _In_ WDFDEVICE device, // WDFDEVICE object _In_ SENSOROBJECT sensorInstance) // SENSOROBJECT for each sensor instance { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); // Initial configuration m_FxDevice = device; m_SensorInstance = sensorInstance; m_Interval = Act_Default_MinDataInterval_Ms; m_FirstSample = TRUE; m_Started = FALSE; m_HistorySizeInRecords = Act_Default_MaxHistoryEntries; m_HistoryPowerInuW = Act_Default_Power_uW; m_HistoryIntervalInMs = Act_Default_HistoryInterval_Ms; m_HistoryStarted = FALSE; m_HistoryRetrievalStarted = FALSE; m_History.FirstElemIndex = 0; m_History.LastElemIndex = 0; m_History.NumOfElems = 0; m_History.BufferLength = m_HistorySizeInRecords; m_hThread = NULL; // Initialize the activity simulator status = HardwareSimulator::Initialize(device, &m_SimulatorInstance); if (!NT_SUCCESS(status)) { TraceError("ACT %!FUNC! HardwareSimulator::Initialize failed %!STATUS!", status); status = STATUS_SUCCESS; // Failed to set up simulator should not fail the driver } // Create Lock status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_Lock); if (!NT_SUCCESS(status)) { TraceError("ACT %!FUNC! WdfWaitLockCreate failed %!STATUS!", status); } // Create history lock if (NT_SUCCESS(status)) { status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_HistoryLock); if (!NT_SUCCESS(status)) { TraceError("ACT %!FUNC! WdfWaitLockCreate failed %!STATUS!", status); } } // Create timer object for polling sensor samples if (NT_SUCCESS(status)) { WDF_OBJECT_ATTRIBUTES timerAttributes = {}; WDF_TIMER_CONFIG timerConfig = {}; WDF_TIMER_CONFIG_INIT(&timerConfig, ActivityDevice::OnTimerExpire); WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes); timerAttributes.ParentObject = sensorInstance; timerAttributes.ExecutionLevel = WdfExecutionLevelPassive; status = WdfTimerCreate(&timerConfig, &timerAttributes, &m_Timer); if (!NT_SUCCESS(status)) { TraceError("ACT %!FUNC! WdfTimerCreate failed %!STATUS!", status); } } // Create timer object for keeping history if (NT_SUCCESS(status)) { WDF_OBJECT_ATTRIBUTES timerAttributes = {}; WDF_TIMER_CONFIG timerConfig = {}; WDF_TIMER_CONFIG_INIT(&timerConfig, ActivityDevice::OnHistoryTimerExpire); WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes); timerAttributes.ParentObject = sensorInstance; timerAttributes.ExecutionLevel = WdfExecutionLevelPassive; status = WdfTimerCreate(&timerConfig, &timerAttributes, &m_HistoryTimer); if (!NT_SUCCESS(status)) { TraceError("ACT %!FUNC! WdfTimerCreate for history failed %!STATUS!", status); } } // Last available data if (NT_SUCCESS(status)) { // Allocate a buffer for max state count. 7 States and 1 timestamp, each // state has activity and confidence. The actual size will be adjusted when // data is ready to be pushed to clx. const ULONG size = SENSOR_COLLECTION_LIST_SIZE(Act_Max_State_Count * 2 + 1); WDF_OBJECT_ATTRIBUTES memoryAttributes = {}; WDFMEMORY memoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes); memoryAttributes.ParentObject = sensorInstance; status = WdfMemoryCreate(&memoryAttributes, PagedPool, SENSOR_POOL_TAG_ACTIVITY, size, &memoryHandle, reinterpret_cast<PVOID*>(&m_pLastSample)); if (!NT_SUCCESS(status) || nullptr == m_pLastSample) { TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status); } else { FILETIME time = {}; SENSOR_COLLECTION_LIST_INIT(m_pLastSample, size); m_pLastSample->Count = Act_Max_State_Count * 2 + 1; m_pLastSample->List[ACTIVITY_DATA_TIMESTAMP].Key = PKEY_SensorData_Timestamp; InitPropVariantFromFileTime(&time, &(m_pLastSample->List[ACTIVITY_DATA_TIMESTAMP].Value)); for (ULONG Count = 1; Count < Act_Max_State_Count * 2 + 1; Count += 2) { m_pLastSample->List[Count].Key = PKEY_SensorData_CurrentActivityState; InitPropVariantFromUInt32(ActivityState_Stationary, &(m_pLastSample->List[Count].Value)); m_pLastSample->List[Count + 1].Key = PKEY_SensorData_CurrentActivityStateConfidence_Percentage; InitPropVariantFromUInt16(100, &(m_pLastSample->List[Count + 1].Value)); } } } // Filtered data if (NT_SUCCESS(status) && nullptr != m_pLastSample && 0 != m_pLastSample->AllocatedSizeInBytes) { WDF_OBJECT_ATTRIBUTES memoryAttributes = {}; WDFMEMORY memoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes); memoryAttributes.ParentObject = sensorInstance; status = WdfMemoryCreate(&memoryAttributes, PagedPool, SENSOR_POOL_TAG_ACTIVITY, m_pLastSample->AllocatedSizeInBytes, &memoryHandle, reinterpret_cast<PVOID*>(&m_pFilteredSample)); if (!NT_SUCCESS(status) || nullptr == m_pFilteredSample) { TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status); } else { // It's safe to memcpy because there is no embedded pointer memcpy_s(m_pFilteredSample, m_pLastSample->AllocatedSizeInBytes, m_pLastSample, m_pLastSample->AllocatedSizeInBytes); } } // Get the Marshalled size for a single history record if (NT_SUCCESS(status)) { // Set the count to 3, as the History Record contains information about only // the most probable activity (unlike the Activity Data that can represent multiple activities) // { Timestamp, ActivityState, Confidence} m_pFilteredSample->Count = 3; // History Retrieval is not WOW64 compatible and hence will not involve // serializing the collections list. Should Use // CollectionsListGetMarshalledSizeWithoutSerialization instead of // CollectionsListGetMarshalledSize when dealing with History Collection list. m_HistoryMarshalledRecordSize = CollectionsListGetMarshalledSizeWithoutSerialization(m_pFilteredSample); } // Sensor Properties. This must be called after setting up m_pLastSample and m_HistoryMarshalledRecordSize if (NT_SUCCESS(status)) { status = InitializeSensorProperties(); } // Sensor Enumeration Properties. if (NT_SUCCESS(status)) { status = InitializeEnumerationProperties(); } // Supported Data-Fields if (NT_SUCCESS(status)) { status = InitializeSupportedDataFields(); } // Data field properties if (NT_SUCCESS(status)) { status = InitializeDataFieldProperties(); } // Set default threshold if (NT_SUCCESS(status)) { const ULONG size = SENSOR_COLLECTION_LIST_SIZE(ACTIVITY_THRESHOLD_COUNT); WDF_OBJECT_ATTRIBUTES memoryAttributes = {}; WDFMEMORY memoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes); memoryAttributes.ParentObject = sensorInstance; status = WdfMemoryCreate(&memoryAttributes, PagedPool, SENSOR_POOL_TAG_ACTIVITY, size, &memoryHandle, reinterpret_cast<PVOID*>(&m_pThresholds)); if (!NT_SUCCESS(status) || nullptr == m_pThresholds) { TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status); } else { SENSOR_COLLECTION_LIST_INIT(m_pThresholds, size); m_pThresholds->Count = ACTIVITY_THRESHOLD_COUNT; m_pThresholds->List[ACTIVITY_THRESHOLD_SUBSCRIBED_STATES].Key = PKEY_SensorData_SubscribedActivityStates; InitPropVariantFromUInt32(Act_Default_SubscribedStates, &(m_pThresholds->List[ACTIVITY_THRESHOLD_SUBSCRIBED_STATES].Value)); m_pThresholds->List[ACTIVITY_THRESHOLD_STREAMING].Key = PKEY_SensorData_ActivityStream; InitPropVariantFromBoolean(Act_Default_Streaming, &(m_pThresholds->List[ACTIVITY_THRESHOLD_STREAMING].Value)); m_pThresholds->List[ACTIVITY_THRESHOLD_CONFIDENCE].Key = PKEY_SensorData_ConfidenceThreshold_Percentage; InitPropVariantFromUInt16(Act_Default_ConfidenceThreshold_Percentage, &(m_pThresholds->List[ACTIVITY_THRESHOLD_CONFIDENCE].Value)); } } // Initialize history buffer if (NT_SUCCESS(status)) { const ULONG size = sizeof(ActivitySample) * m_HistorySizeInRecords; WDF_OBJECT_ATTRIBUTES memoryAttributes = {}; WDFMEMORY memoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes); memoryAttributes.ParentObject = sensorInstance; status = WdfMemoryCreate(&memoryAttributes, PagedPool, SENSOR_POOL_TAG_ACTIVITY, size, &memoryHandle, reinterpret_cast<PVOID*>(&(m_History.pData))); if (!NT_SUCCESS(status) || nullptr == m_History.pData) { TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status); } } // Create event for signaling the history retrieval thread to exit if (NT_SUCCESS(status)) { m_ExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (NULL == m_ExitEvent || INVALID_HANDLE_VALUE == m_ExitEvent) { status = STATUS_INSUFFICIENT_RESOURCES; TraceError("ACT %!FUNC! Failed to create an event %!STATUS!", status); } } SENSOR_FunctionExit(status); return status; }
// This routine initializes the sensor's enumeration properties NTSTATUS ActivityDevice::InitializeEnumerationProperties() { WDF_OBJECT_ATTRIBUTES memoryAttributes = {}; WDFMEMORY memoryHandle = NULL; const ULONG size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_ENUMERATION_PROPERTIES_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_pEnumerationProperties)); if (!NT_SUCCESS(status) || nullptr == m_pEnumerationProperties) { TraceError("ACT %!FUNC! WdfMemoryCreate failed %!STATUS!", status); } else { SENSOR_COLLECTION_LIST_INIT(m_pEnumerationProperties, size); m_pEnumerationProperties->Count = SENSOR_ENUMERATION_PROPERTIES_COUNT; m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Key = DEVPKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_ActivityDetection, &(m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Value)); m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Key = DEVPKEY_Sensor_Manufacturer; InitPropVariantFromString(L"Microsoft", &(m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Value)); m_pEnumerationProperties->List[SENSOR_MODEL].Key = DEVPKEY_Sensor_Model; InitPropVariantFromString(L"Fake ACTIVITY V2", &(m_pEnumerationProperties->List[SENSOR_MODEL].Value)); m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Key = DEVPKEY_Sensor_PersistentUniqueId; InitPropVariantFromCLSID(GUID_ActivityDevice_UniqueID, &(m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Value)); m_pEnumerationProperties->List[SENSOR_CATEGORY].Key = DEVPKEY_Sensor_Category; InitPropVariantFromCLSID(GUID_SensorCategory_Motion, &(m_pEnumerationProperties->List[SENSOR_CATEGORY].Value)); m_pEnumerationProperties->List[SENSOR_MIN_INTERVAL].Key = PKEY_Sensor_MinimumDataInterval_Ms; InitPropVariantFromUInt32(Act_Default_MinDataInterval_Ms, &(m_pEnumerationProperties->List[SENSOR_MIN_INTERVAL].Value)); m_pEnumerationProperties->List[SENSOR_POWER].Key = PKEY_Sensor_Power_Milliwatts; InitPropVariantFromFloat((m_HistoryPowerInuW / 1000.0f), &(m_pEnumerationProperties->List[SENSOR_POWER].Value)); m_pEnumerationProperties->List[SENSOR_SUPPORTEDACTIVITIES].Key = PKEY_SensorData_SupportedActivityStates; InitPropVariantFromUInt32(Act_Default_SubscribedStates, &(m_pEnumerationProperties->List[SENSOR_SUPPORTEDACTIVITIES].Value)); m_pEnumerationProperties->List[SENSOR_MAX_HISTORYSIZE].Key = PKEY_SensorHistory_MaxSize_Bytes; InitPropVariantFromUInt32(SENSOR_COLLECTION_LIST_HEADER_SIZE + ((m_HistoryMarshalledRecordSize - SENSOR_COLLECTION_LIST_HEADER_SIZE) * m_HistorySizeInRecords), &(m_pEnumerationProperties->List[SENSOR_MAX_HISTORYSIZE].Value)); // History only logs one most probable state } SENSOR_FunctionExit(status); return status; }
// This routine initializes the sensor to its default properties NTSTATUS PedometerDevice::Initialize( _In_ WDFDEVICE Device, // WDFDEVICE object _In_ SENSOROBJECT SensorInstance // SENSOROBJECT for each sensor instance ) { ULONG Size = 0; WDF_OBJECT_ATTRIBUTES MemoryAttributes; WDFMEMORY MemoryHandle = NULL; FILETIME Time = {}; WDF_OBJECT_ATTRIBUTES TimerAttributes; WDF_TIMER_CONFIG TimerConfig; NTSTATUS Status = STATUS_SUCCESS; PHardwareSimulator pSimulator = nullptr; ULONG HistorySizeInRecords = 0; SENSOR_FunctionEnter(); // Store device and instance m_FxDevice = Device; m_SensorInstance = SensorInstance; m_Started = FALSE; m_HistoryRetrievalStarted = FALSE; // Initialize the pedometer simulator Status = HardwareSimulator::Initialize(Device, &m_SimulatorInstance); if (!NT_SUCCESS(Status)) { TraceError("PED %!FUNC! HardwareSimulator::Initialize failed %!STATUS!", Status); goto Exit; } pSimulator = GetHardwareSimulatorContextFromInstance(m_SimulatorInstance); if (nullptr == pSimulator) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("PED %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); goto Exit; } // Create Lock Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_Lock); if (!NT_SUCCESS(Status)) { TraceError("PED %!FUNC! WdfWaitLockCreate failed %!STATUS!", Status); goto Exit; } // Create timer object for polling sensor samples WDF_TIMER_CONFIG_INIT(&TimerConfig, PedometerDevice::OnTimerExpire); WDF_OBJECT_ATTRIBUTES_INIT(&TimerAttributes); TimerAttributes.ParentObject = SensorInstance; TimerAttributes.ExecutionLevel = WdfExecutionLevelPassive; Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &m_Timer); if (!NT_SUCCESS(Status)) { TraceError("PED %!FUNC! WdfTimerCreate failed %!STATUS!", Status); goto Exit; } // Supported Data-Fields Size = SENSOR_PROPERTY_LIST_SIZE(PEDOMETER_DATAFIELD_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSOR_POOL_TAG_PEDOMETER, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pSupportedDataFields)); if (!NT_SUCCESS(Status) || nullptr == m_pSupportedDataFields) { TraceError("PED %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_PROPERTY_LIST_INIT(m_pSupportedDataFields, Size); m_pSupportedDataFields->Count = PEDOMETER_DATAFIELD_COUNT; m_pSupportedDataFields->List[PEDOMETER_DATAFIELD_TIMESTAMP] = PKEY_SensorData_Timestamp; m_pSupportedDataFields->List[PEDOMETER_DATAFIELD_FIRST_AFTER_RESET] = PKEY_SensorData_PedometerReset; m_pSupportedDataFields->List[PEDOMETER_DATAFIELD_STEP_TYPE] = PKEY_SensorData_PedometerStepType; m_pSupportedDataFields->List[PEDOMETER_DATAFIELD_STEP_COUNT] = PKEY_SensorData_PedometerStepCount; m_pSupportedDataFields->List[PEDOMETER_DATAFIELD_STEP_DURATION] = PKEY_SensorData_PedometerStepDuration_Ms; // Data Size = SENSOR_COLLECTION_LIST_SIZE(PEDOMETER_DATA_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSOR_POOL_TAG_PEDOMETER, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pData)); if (!NT_SUCCESS(Status) || nullptr == m_pData) { TraceError("PED %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pData, Size); m_pData->Count = PEDOMETER_DATA_COUNT; m_pData->List[PEDOMETER_DATA_TIMESTAMP].Key = PKEY_SensorData_Timestamp; GetSystemTimePreciseAsFileTime(&Time); InitPropVariantFromFileTime(&Time, &(m_pData->List[PEDOMETER_DATA_TIMESTAMP].Value)); m_pData->List[PEDOMETER_DATA_FIRST_AFTER_RESET].Key = PKEY_SensorData_PedometerReset; InitPropVariantFromBoolean(FALSE, &(m_pData->List[PEDOMETER_DATA_FIRST_AFTER_RESET].Value)); m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_TYPE].Key = PKEY_SensorData_PedometerStepType; InitPropVariantFromUInt32(static_cast<ULONG>(PedometerStepType_Unknown), &(m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_TYPE].Value)); m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_COUNT].Key = PKEY_SensorData_PedometerStepCount; InitPropVariantFromUInt32(600, &(m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_COUNT].Value)); m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_DURATION].Key = PKEY_SensorData_PedometerStepDuration_Ms; InitPropVariantFromInt64(123, &(m_pData->List[PEDOMETER_DATA_UNKNOWN_STEP_DURATION].Value)); m_pData->List[PEDOMETER_DATA_WALKING_STEP_TYPE].Key = PKEY_SensorData_PedometerStepType; InitPropVariantFromUInt32(static_cast<ULONG>(PedometerStepType_Walking), &(m_pData->List[PEDOMETER_DATA_WALKING_STEP_TYPE].Value)); m_pData->List[PEDOMETER_DATA_WALKING_STEP_COUNT].Key = PKEY_SensorData_PedometerStepCount; InitPropVariantFromUInt32(700, &(m_pData->List[PEDOMETER_DATA_WALKING_STEP_COUNT].Value)); m_pData->List[PEDOMETER_DATA_WALKING_STEP_DURATION].Key = PKEY_SensorData_PedometerStepDuration_Ms; InitPropVariantFromInt64(456, &(m_pData->List[PEDOMETER_DATA_WALKING_STEP_DURATION].Value)); m_pData->List[PEDOMETER_DATA_RUNNING_STEP_TYPE].Key = PKEY_SensorData_PedometerStepType; InitPropVariantFromUInt32(static_cast<ULONG>(PedometerStepType_Running), &(m_pData->List[PEDOMETER_DATA_RUNNING_STEP_TYPE].Value)); m_pData->List[PEDOMETER_DATA_RUNNING_STEP_COUNT].Key = PKEY_SensorData_PedometerStepCount; InitPropVariantFromUInt32(800, &(m_pData->List[PEDOMETER_DATA_RUNNING_STEP_COUNT].Value)); m_pData->List[PEDOMETER_DATA_RUNNING_STEP_DURATION].Key = PKEY_SensorData_PedometerStepDuration_Ms; InitPropVariantFromInt64(789, &(m_pData->List[PEDOMETER_DATA_RUNNING_STEP_DURATION].Value)); m_LastSample.Timestamp = Time; m_LastSample.UnknownStepCount = 0; m_LastSample.UnknownStepDurationMs = 0; m_LastSample.WalkingStepCount = 0; m_LastSample.WalkingStepDurationMs = 0; m_LastSample.RunningStepCount = 0; m_LastSample.RunningStepDurationMs = 0; m_LastSample.IsFirstAfterReset = FALSE; // Get the History Size to populate 'PKEY_SensorHistory_MaxSize_Bytes' // Typically the size needed to store a history record on the hardware is // smaller than the size needed to represent a history record as a // SENSOR_COLLECTION_LIST (collection of SENSOR_VALUE_PAIRs) // To be able to accurately represent the size of the history on the // hardware (simulator in this case), get the number of records that the HW // can store and multiply it with the marshalled size of // SENSOR_COLLECTION_LIST needed to represent a single record. HistorySizeInRecords = pSimulator->GetHistorySizeInRecords(); m_HistorySupported = (HistorySizeInRecords > 0) ? TRUE : FALSE; // Pedometer History format is exactly same as it's data sample. // so, we can simply reuse the 'm_pData' to compute the marshalled size // History Retrieval is not WOW64 compatible and hence will not involve // serializing the collections list. Should Use // CollectionsListGetMarshalledSizeWithoutSerialization instead of // CollectionsListGetMarshalledSize when dealing with History Collection list. m_HistoryMarshalledRecordSize = CollectionsListGetMarshalledSizeWithoutSerialization(m_pData); // Sensor Enumeration Properties Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_ENUMERATION_PROPERTIES_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSOR_POOL_TAG_PEDOMETER, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pEnumerationProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pEnumerationProperties) { TraceError("PED %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pEnumerationProperties, Size); m_pEnumerationProperties->Count = SENSOR_ENUMERATION_PROPERTIES_COUNT; m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Key = DEVPKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_Pedometer, &(m_pEnumerationProperties->List[SENSOR_TYPE_GUID].Value)); m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Key = DEVPKEY_Sensor_Manufacturer; InitPropVariantFromString(L"Microsoft", &(m_pEnumerationProperties->List[SENSOR_MANUFACTURER].Value)); m_pEnumerationProperties->List[SENSOR_MODEL].Key = DEVPKEY_Sensor_Model; InitPropVariantFromString(L"PEDOMETER", &(m_pEnumerationProperties->List[SENSOR_MODEL].Value)); m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Key = DEVPKEY_Sensor_PersistentUniqueId; InitPropVariantFromCLSID(GUID_PedometerDevice_UniqueID, &(m_pEnumerationProperties->List[SENSOR_PERSISTENT_UNIQUEID].Value)); m_pEnumerationProperties->List[SENSOR_CATEGORY].Key = DEVPKEY_Sensor_Category; InitPropVariantFromCLSID(GUID_SensorCategory_Motion, &(m_pEnumerationProperties->List[SENSOR_CATEGORY].Value)); m_pEnumerationProperties->List[SENSOR_ISPRIMARY].Key = DEVPKEY_Sensor_IsPrimary; InitPropVariantFromBoolean(FALSE, &(m_pEnumerationProperties->List[SENSOR_ISPRIMARY].Value)); // This value should be set to TRUE if multiple pedometers // exist on the system and this sensor is the primary sensor m_pEnumerationProperties->List[SENSOR_POWER].Key = PKEY_Sensor_Power_Milliwatts; InitPropVariantFromFloat(Pedometer_Default_Power_Milliwatts, &(m_pEnumerationProperties->List[SENSOR_POWER].Value)); m_pEnumerationProperties->List[SENSOR_MAX_HISTORYSIZE].Key = PKEY_SensorHistory_MaxSize_Bytes; InitPropVariantFromUInt32(((FALSE != m_HistorySupported) ? (SENSOR_COLLECTION_LIST_HEADER_SIZE + ((m_HistoryMarshalledRecordSize - SENSOR_COLLECTION_LIST_HEADER_SIZE) * HistorySizeInRecords)) : 0), &(m_pEnumerationProperties->List[SENSOR_MAX_HISTORYSIZE].Value)); m_pEnumerationProperties->List[SENSOR_SUPPORTED_STEPTYPES].Key = PKEY_SensorData_SupportedStepTypes; InitPropVariantFromUInt32(PedometerStepType_Unknown | PedometerStepType_Walking | PedometerStepType_Running, &(m_pEnumerationProperties->List[SENSOR_SUPPORTED_STEPTYPES].Value)); // Sensor Properties m_Interval = Pedometer_Default_MinDataInterval_Ms; Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_COMMON_PROPERTIES_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSOR_POOL_TAG_PEDOMETER, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pProperties) { TraceError("PED %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pProperties, Size); m_pProperties->Count = SENSOR_COMMON_PROPERTIES_COUNT; m_pProperties->List[SENSOR_PROPERTY_STATE].Key = PKEY_Sensor_State; InitPropVariantFromUInt32(SensorState_Initializing, &(m_pProperties->List[SENSOR_PROPERTY_STATE].Value)); m_pProperties->List[SENSOR_PROPERTY_MIN_INTERVAL].Key = PKEY_Sensor_MinimumDataInterval_Ms; InitPropVariantFromUInt32(Pedometer_Default_MinDataInterval_Ms, &(m_pProperties->List[SENSOR_PROPERTY_MIN_INTERVAL].Value)); m_pProperties->List[SENSOR_PROPERTY_MAX_DATAFIELDSIZE].Key = PKEY_Sensor_MaximumDataFieldSize_Bytes; InitPropVariantFromUInt32(CollectionsListGetMarshalledSize(m_pData), &(m_pProperties->List[SENSOR_PROPERTY_MAX_DATAFIELDSIZE].Value)); m_pProperties->List[SENSOR_PROPERTY_SENSOR_TYPE].Key = PKEY_Sensor_Type; InitPropVariantFromCLSID(GUID_SensorType_Pedometer, &(m_pProperties->List[SENSOR_PROPERTY_SENSOR_TYPE].Value)); m_pProperties->List[SENSOR_PROPERTY_SENSOR_POWER].Key = PKEY_Sensor_Power_Milliwatts; InitPropVariantFromFloat(Pedometer_Default_Power_Milliwatts, &(m_pProperties->List[SENSOR_PROPERTY_SENSOR_POWER].Value)); m_pProperties->List[SENSOR_PROPERTY_MAX_HISTORYSIZE].Key = PKEY_SensorHistory_MaxSize_Bytes; InitPropVariantFromUInt32(((FALSE != m_HistorySupported) ? (SENSOR_COLLECTION_LIST_HEADER_SIZE + ((m_HistoryMarshalledRecordSize - SENSOR_COLLECTION_LIST_HEADER_SIZE) * HistorySizeInRecords)) : 0), &(m_pProperties->List[SENSOR_PROPERTY_MAX_HISTORYSIZE].Value)); m_pProperties->List[SENSOR_PROPERTY_HISTORY_INTERVAL].Key = PKEY_SensorHistory_Interval_Ms; InitPropVariantFromUInt32(pSimulator->GetHistoryIntervalInMs(), &(m_pProperties->List[SENSOR_PROPERTY_HISTORY_INTERVAL].Value)); m_pProperties->List[SENSOR_PROPERTY_MAX_HISTROYRECORDSIZE].Key = PKEY_SensorHistory_MaximumRecordSize_Bytes; InitPropVariantFromUInt32(m_HistoryMarshalledRecordSize, &(m_pProperties->List[SENSOR_PROPERTY_MAX_HISTROYRECORDSIZE].Value)); m_pProperties->List[SENSOR_PROPERTY_SUPPORTED_STEPTYPES].Key = PKEY_SensorData_SupportedStepTypes; InitPropVariantFromUInt32(PedometerStepType_Unknown | PedometerStepType_Walking | PedometerStepType_Running, &(m_pProperties->List[SENSOR_PROPERTY_SUPPORTED_STEPTYPES].Value)); // Data field properties Size = SENSOR_COLLECTION_LIST_SIZE(SENSOR_DATA_FIELD_PROPERTY_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSOR_POOL_TAG_PEDOMETER, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pDataFieldProperties)); if (!NT_SUCCESS(Status) || nullptr == m_pDataFieldProperties) { TraceError("PED %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pDataFieldProperties, Size); m_pDataFieldProperties->Count = SENSOR_DATA_FIELD_PROPERTY_COUNT; m_pDataFieldProperties->List[SENSOR_RESOLUTION].Key = PKEY_SensorDataField_Resolution; InitPropVariantFromInt64(PedometerDevice_StepCount_Resolution, &(m_pDataFieldProperties->List[SENSOR_RESOLUTION].Value)); m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Key = PKEY_SensorDataField_RangeMinimum; InitPropVariantFromUInt32(PedometerDevice_StepCount_Minimum, &(m_pDataFieldProperties->List[SENSOR_MIN_RANGE].Value)); m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Key = PKEY_SensorDataField_RangeMaximum; InitPropVariantFromUInt32(PedometerDevice_StepCount_Maximum, &(m_pDataFieldProperties->List[SENSOR_MAX_RANGE].Value)); // Set default threshold m_FirstSample = TRUE; Size = SENSOR_COLLECTION_LIST_SIZE(PEDOMETER_THRESHOLD_COUNT); MemoryHandle = NULL; WDF_OBJECT_ATTRIBUTES_INIT(&MemoryAttributes); MemoryAttributes.ParentObject = SensorInstance; Status = WdfMemoryCreate(&MemoryAttributes, PagedPool, SENSOR_POOL_TAG_PEDOMETER, Size, &MemoryHandle, reinterpret_cast<PVOID*>(&m_pThresholds)); if (!NT_SUCCESS(Status) || nullptr == m_pThresholds) { TraceError("PED %!FUNC! WdfMemoryCreate failed %!STATUS!", Status); goto Exit; } SENSOR_COLLECTION_LIST_INIT(m_pThresholds, Size); m_pThresholds->Count = PEDOMETER_THRESHOLD_COUNT; m_pThresholds->List[PEDOMETER_THRESHOLD_STEP_COUNT].Key = PKEY_SensorData_PedometerStepCount; InitPropVariantFromUInt32(Pedometer_Default_Threshold_StepCount, &(m_pThresholds->List[PEDOMETER_THRESHOLD_STEP_COUNT].Value)); m_CachedThreshold = Pedometer_Default_Threshold_StepCount; Exit: SENSOR_FunctionExit(Status); return Status; }