// This routine is the AddDevice entry point for the custom sensor client
// driver. This routine is called by the framework in response to AddDevice
// call from the PnP manager. It will create and initialize the device object
// to represent a new instance of the sensor client.
NTSTATUS CustomSensorDevice::OnDeviceAdd(
    _In_ WDFDRIVER /*Driver*/,            // Supplies a handle to the driver object created in DriverEntry
    _Inout_ PWDFDEVICE_INIT pDeviceInit   // Supplies a pointer to a framework-allocated WDFDEVICE_INIT structure
)
{
    WDF_PNPPOWER_EVENT_CALLBACKS Callbacks;
    WDFDEVICE Device = nullptr;
    WDF_OBJECT_ATTRIBUTES FdoAttributes;
    ULONG Flag = 0;
    SENSOR_CONTROLLER_CONFIG SensorConfig;
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    WDF_OBJECT_ATTRIBUTES_INIT(&FdoAttributes);

    // Initialize FDO attributes and set up file object with sensor extension
    Status = SensorsCxDeviceInitConfig(pDeviceInit, &FdoAttributes, Flag);
    if (!NT_SUCCESS(Status))
    {
        TraceError("CSTM %!FUNC! SensorsCxDeviceInitConfig failed %!STATUS!", Status);
        goto Exit;
    }

    // Register the PnP callbacks with the framework.
    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&Callbacks);
    Callbacks.EvtDevicePrepareHardware = CustomSensorDevice::OnPrepareHardware;
    Callbacks.EvtDeviceReleaseHardware = CustomSensorDevice::OnReleaseHardware;
    Callbacks.EvtDeviceD0Entry = CustomSensorDevice::OnD0Entry;
    Callbacks.EvtDeviceD0Exit = CustomSensorDevice::OnD0Exit;

    WdfDeviceInitSetPnpPowerEventCallbacks(pDeviceInit, &Callbacks);

    // Call the framework to create the device
    Status = WdfDeviceCreate(&pDeviceInit, &FdoAttributes, &Device);
    if (!NT_SUCCESS(Status))
    {
        TraceError("CSTM %!FUNC! WdfDeviceCreate failed %!STATUS!", Status);
        goto Exit;
    }

    // Register CLX callback function pointers
    SENSOR_CONTROLLER_CONFIG_INIT(&SensorConfig);
    SensorConfig.DriverIsPowerPolicyOwner = WdfUseDefault;

    SensorConfig.EvtSensorStart                     = CustomSensorDevice::OnStart;
    SensorConfig.EvtSensorStop                      = CustomSensorDevice::OnStop;
    SensorConfig.EvtSensorGetSupportedDataFields    = CustomSensorDevice::OnGetSupportedDataFields;
    SensorConfig.EvtSensorGetDataInterval           = CustomSensorDevice::OnGetDataInterval;
    SensorConfig.EvtSensorSetDataInterval           = CustomSensorDevice::OnSetDataInterval;
    SensorConfig.EvtSensorGetDataFieldProperties    = CustomSensorDevice::OnGetDataFieldProperties;
    SensorConfig.EvtSensorGetDataThresholds         = CustomSensorDevice::OnGetDataThresholds;
    SensorConfig.EvtSensorSetDataThresholds         = CustomSensorDevice::OnSetDataThresholds;
    SensorConfig.EvtSensorGetProperties             = CustomSensorDevice::OnGetProperties;
    SensorConfig.EvtSensorDeviceIoControl           = CustomSensorDevice::OnIoControl;

    // Set up power capabilities and IO queues
    Status = SensorsCxDeviceInitialize(Device, &SensorConfig);
    if (!NT_SUCCESS(Status))
    {
        TraceError("CSTM %!FUNC! SensorsCxDeviceInitialize failed %!STATUS!", Status);
        goto Exit;
    }

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
// This routine is the AddDevice entry point for the fake activity client
// driver. This routine is called by the framework in response to AddDevice
// call from the PnP manager. It will create and initialize the device object
// to represent a new instance of the sensor client.
NTSTATUS ActivityDevice::OnDeviceAdd(
    _In_ WDFDRIVER /*driver*/,              // Supplies a handle to the driver object created in DriverEntry
    _Inout_ PWDFDEVICE_INIT pDeviceInit)    // Supplies a pointer to a framework-allocated WDFDEVICE_INIT structure
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // Initialize FDO attributes and set up file object with sensor extension
    WDF_OBJECT_ATTRIBUTES fdoAttributes = {};
    ULONG flag = 0;

    WDF_OBJECT_ATTRIBUTES_INIT(&fdoAttributes);
    status = SensorsCxDeviceInitConfig(pDeviceInit, &fdoAttributes, flag);
    if (!NT_SUCCESS(status))
    {
        TraceError("ACT %!FUNC! SensorsCxDeviceInitConfig failed %!STATUS!", status);
    }
    else
    {
        WDF_PNPPOWER_EVENT_CALLBACKS callbacks = {};
        WDFDEVICE device = NULL;

        // Register the PnP callbacks with the framework.
        WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&callbacks);
        callbacks.EvtDevicePrepareHardware = ActivityDevice::OnPrepareHardware;
        callbacks.EvtDeviceReleaseHardware = ActivityDevice::OnReleaseHardware;
        callbacks.EvtDeviceD0Entry = ActivityDevice::OnD0Entry;
        callbacks.EvtDeviceD0Exit = ActivityDevice::OnD0Exit;
        WdfDeviceInitSetPnpPowerEventCallbacks(pDeviceInit, &callbacks);

        // Call the framework to create the device
        status = WdfDeviceCreate(&pDeviceInit, &fdoAttributes, &device);
        if (!NT_SUCCESS(status))
        {
            TraceError("ACT %!FUNC! WdfDeviceCreate failed %!STATUS!", status);
        }
        else
        {
            SENSOR_CONTROLLER_CONFIG sensorConfig = {};

            // Register CLX callback function pointers
            SENSOR_CONTROLLER_CONFIG_INIT(&sensorConfig);
            sensorConfig.DriverIsPowerPolicyOwner = WdfUseDefault;

            sensorConfig.EvtSensorStart = ActivityDevice::OnStart;
            sensorConfig.EvtSensorStop = ActivityDevice::OnStop;
            sensorConfig.EvtSensorGetSupportedDataFields = ActivityDevice::OnGetSupportedDataFields;
            sensorConfig.EvtSensorGetDataInterval = ActivityDevice::OnGetDataInterval;
            sensorConfig.EvtSensorSetDataInterval = ActivityDevice::OnSetDataInterval;
            sensorConfig.EvtSensorGetDataFieldProperties = ActivityDevice::OnGetDataFieldProperties;
            sensorConfig.EvtSensorGetDataThresholds = ActivityDevice::OnGetDataThresholds;
            sensorConfig.EvtSensorSetDataThresholds = ActivityDevice::OnSetDataThresholds;
            sensorConfig.EvtSensorGetProperties = ActivityDevice::OnGetProperties;
            sensorConfig.EvtSensorDeviceIoControl = ActivityDevice::OnIoControl;
            sensorConfig.EvtSensorStartHistory = ActivityDevice::OnStartHistory;
            sensorConfig.EvtSensorStopHistory = ActivityDevice::OnStopHistory;
            sensorConfig.EvtSensorClearHistory = ActivityDevice::OnClearHistory;
            sensorConfig.EvtSensorStartHistoryRetrieval = ActivityDevice::OnStartHistoryRetrieval;
            sensorConfig.EvtSensorCancelHistoryRetrieval = ActivityDevice::OnCancelHistoryRetrieval;

            // Set up power capabilities and IO queues
            status = SensorsCxDeviceInitialize(device, &sensorConfig);
            if (!NT_SUCCESS(status))
            {
                TraceError("ACT %!FUNC! SensorsCxDeviceInitialize failed %!STATUS!", status);
            }
        }
    }

    SENSOR_FunctionExit(status);
    return status;
}