// 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;
}
// 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
CustomSensorDevice::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.

{
    PCustomSensorDevice pDevice = nullptr;
    WDF_OBJECT_ATTRIBUTES SensorAttr = {};
    SENSOR_CONFIG SensorConfig = {};
    SENSOROBJECT SensorInstance = nullptr;
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // Construct sensor instance

    // Create WDFOBJECT for the sensor
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&SensorAttr, CustomSensorDevice);

    // Register sensor instance with clx
    Status = SensorsCxSensorCreate(Device, &SensorAttr, &SensorInstance);
    if (!NT_SUCCESS(Status))
    {
        TraceError("CSTM %!FUNC! SensorsCxSensorCreate failed %!STATUS!", Status);
        goto Exit;
    }

    pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    if (nullptr == pDevice)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        TraceError("CSTM %!FUNC! GetCustomSensorContextFromSensorInstance failed %!STATUS!", Status);
        goto Exit;
    }

    // Fill out properties
    Status = pDevice->Initialize(Device, SensorInstance);
    if (!NT_SUCCESS(Status))
    {
        TraceError("CSTM %!FUNC! Initialize device object failed %!STATUS!", Status);
        goto Exit;
    }

    SENSOR_CONFIG_INIT(&SensorConfig);
    SensorConfig.pEnumerationList = pDevice->m_pEnumerationProperties;
    Status = SensorsCxSensorInitialize(SensorInstance, &SensorConfig);
    if (!NT_SUCCESS(Status))
    {
        TraceError("CSTM %!FUNC! SensorsCxSensorInitialize failed %!STATUS!", Status);
        goto Exit;
    }


Exit:
    SENSOR_FunctionExit(Status);

    return Status;
}