Ejemplo n.º 1
0
NTSTATUS
RoboDeviceEvtDeviceAdd(
    _In_    WDFDRIVER       Driver,
    _Inout_ PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. We create and initialize a device object to
    represent a new instance of the device.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS status;
    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "RoboDeviceEvtDeviceAdd" );

    WdfDeviceInitSetPowerPolicyOwnership( DeviceInit, FALSE );
    status = RoboDeviceCreateDevice(DeviceInit);

    DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "RoboDeviceEvtDeviceAdd exit %x", status );

    return status;
}
NTSTATUS
NfcCxEvtDeviceInitConfig(
    _In_ PNFCCX_DRIVER_GLOBALS NfcCxGlobals,
    _In_ PWDFDEVICE_INIT DeviceInit,
    _In_ PNFC_CX_CLIENT_CONFIG Config
    )
/*++
Routine Description:

    NfcCxEvtDeviceInitConfig is called by the client driver from within
    its AddDevice callback to finish initializing the device before creation.

Arguments:

    NfcCxGlobals - Pointer to the Class extension globals
    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
    Config - Pointer to a client provided structure with their configuration.

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS                          status = STATUS_SUCCESS; 
    WDFCX_FILEOBJECT_CONFIG           fileConfig;
    WDF_OBJECT_ATTRIBUTES             fileObjectAttributes;
    PWDFCXDEVICE_INIT                 exDeviceInit;
    PNFCCX_CLIENT_GLOBALS             nfcCxClientGlobal;

    TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);

    if (!VerifyPrivateGlobals(NfcCxGlobals)) {
        TRACE_LINE(LEVEL_ERROR, "Invalid CX global pointer");
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    if (NULL == Config ||
        sizeof(NFC_CX_CLIENT_CONFIG) != Config->Size ||
        NULL == Config->EvtNfcCxWriteNciPacket) {
        TRACE_LINE(LEVEL_ERROR, "Invalid Client Driver Configuration");
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    if (NFC_CX_DEVICE_MODE_NCI != Config->DeviceMode &&
        NFC_CX_DEVICE_MODE_DTA != Config->DeviceMode &&
        NFC_CX_DEVICE_MODE_RAW != Config->DeviceMode) {
        TRACE_LINE(LEVEL_ERROR, "Invalid Client Driver Device Mode %d", Config->DeviceMode);
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    nfcCxClientGlobal = GetPrivateGlobals(NfcCxGlobals);

    //
    // The CX is the power policy owner of this stack.
    //
    WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, TRUE);

    //
    // Allocate the CX DeviceInit
    //
    exDeviceInit = WdfCxDeviceInitAllocate(DeviceInit);
    if (NULL == exDeviceInit) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TRACE_LINE(LEVEL_ERROR,
            "Failed WdfCxDeviceInitAllocate, status=%!STATUS!", status);
        goto Done;
    }

    //
    // Enable SelfIoTarget
    //
    WdfDeviceInitAllowSelfIoTarget(DeviceInit);

    //
    // Initialize WDF_FILEOBJECT_CONFIG_INIT struct to tell the
    // per handle (fileobject) context.
    //
    WDFCX_FILEOBJECT_CONFIG_INIT(
                            &fileConfig,
                            NfcCxEvtDeviceFileCreate,
                            NfcCxEvtFileClose,
                            WDF_NO_EVENT_CALLBACK // not interested in Cleanup
                            );

    WDF_OBJECT_ATTRIBUTES_INIT(&fileObjectAttributes);
    fileObjectAttributes.SynchronizationScope = WdfSynchronizationScopeNone;

    WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&fileObjectAttributes,
                                            NFCCX_FILE_CONTEXT);

    WdfCxDeviceInitSetFileObjectConfig(exDeviceInit,
                                       &fileConfig,
                                       &fileObjectAttributes);

    TRACE_LINE(LEVEL_INFO, "DriverFlags=0x%x PowerIdleType=%d PowerIdleTimeout=%d",
                            Config->DriverFlags, Config->PowerIdleType, Config->PowerIdleTimeout);

    TraceLoggingWrite(g_hNfcCxProvider,
        "NfcCxClientConfig",
        TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY),
        TraceLoggingHexInt32(Config->DriverFlags, "DriverFlags"),
        TraceLoggingValue((INT32)(Config->PowerIdleType), "PowerIdleType"),
        TraceLoggingValue(Config->PowerIdleTimeout, "PowerIdleTimeout"));

    //
    // Save the client driver configs
    //
    RtlCopyMemory(&nfcCxClientGlobal->Config, Config, Config->Size);

Done:
    
    TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
    TRACE_LOG_NTSTATUS_ON_FAILURE(status);
    
    return status;
}
Ejemplo n.º 3
0
NTSTATUS
OnDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
/*++

Routine Description:

    OnDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager when a device is found. We create and 
    initialize a WDF device object to represent the new instance of 
    an touch device. Per-device objects are also instantiated.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry
    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS indicating success or failure

--*/
{
    WDF_OBJECT_ATTRIBUTES attributes;
    PDEVICE_EXTENSION devContext;
    WDFDEVICE fxDevice;
    WDF_INTERRUPT_CONFIG interruptConfig;  
    WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
    WDF_IO_QUEUE_CONFIG queueConfig;
    NTSTATUS status;
    
    UNREFERENCED_PARAMETER(Driver);
    PAGED_CODE();
    
    //
    // Relinquish power policy ownership because HIDCLASS acts a power
    // policy owner for ther HID stack.
    //
    WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, FALSE);

    //
    // This driver handles D0 Entry and Exit to power on and off the
    // controller. It also handles prepare/release hardware so that it 
    // can acquire and free SPB resources needed to communicate with the  
    // touch controller.
    //
    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

    pnpPowerCallbacks.EvtDeviceD0Entry = OnD0Entry;
    pnpPowerCallbacks.EvtDeviceD0Exit  = OnD0Exit;
    pnpPowerCallbacks.EvtDevicePrepareHardware = OnPrepareHardware;
    pnpPowerCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware;

    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
    
    //
    // Create a framework device object. This call will in turn create
    // a WDM device object, attach to the lower stack, and set the
    // appropriate flags and attributes.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_EXTENSION);

    status = WdfDeviceCreate(&DeviceInit, &attributes, &fxDevice);

    if (!NT_SUCCESS(status)) 
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_INIT,
            "WdfDeviceCreate failed - %!STATUS!",
            status);

        goto exit;
    }

    devContext = GetDeviceContext(fxDevice);
    devContext->FxDevice = fxDevice;
    devContext->InputMode = MODE_MULTI_TOUCH;
  
    //
    // Create a parallel dispatch queue to handle requests from HID Class
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
        &queueConfig, 
        WdfIoQueueDispatchParallel);

    queueConfig.EvtIoInternalDeviceControl = OnInternalDeviceControl;
    queueConfig.PowerManaged = WdfFalse;

    status = WdfIoQueueCreate(
        fxDevice,
        &queueConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &devContext->DefaultQueue);

    if (!NT_SUCCESS (status)) 
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_INIT,
            "Error creating WDF default queue - %!STATUS!",
            status);

        goto exit;
    }

    //
    // Register a manual I/O queue for Read Requests. This queue will be used 
    // for storing HID read requests until touch data is available to 
    // complete them.
    //
    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);

    queueConfig.PowerManaged = WdfFalse;

    status = WdfIoQueueCreate(
        fxDevice,
        &queueConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &devContext->PingPongQueue);

    if (!NT_SUCCESS(status)) 
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_INIT,
            "Error creating WDF read request queue - %!STATUS!",
            status);

        goto exit;
    }

    //
    // Register one last manual I/O queue for parking HIDClass's idle power
    // requests. This queue stores idle requests until they're cancelled,
    // and could be used to complete a wait/wake request.
    //

    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);

    queueConfig.PowerManaged = WdfFalse;

    status = WdfIoQueueCreate(
        fxDevice,
        &queueConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &devContext->IdleQueue
        );

    if (!NT_SUCCESS(status))
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_INIT,
            "Error creating WDF idle request queue - %!STATUS!", 
            status);

        goto exit;
    }

    //
    // Create an interrupt object for hardware notifications
    //
    WDF_INTERRUPT_CONFIG_INIT(
        &interruptConfig,
        OnInterruptIsr,
        NULL);
    interruptConfig.PassiveHandling = TRUE;

    status = WdfInterruptCreate(
        fxDevice,
        &interruptConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &devContext->InterruptObject);

    if (!NT_SUCCESS(status))
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_INIT,
            "Error creating WDF interrupt object - %!STATUS!",
            status);

        goto exit;
    }

exit:

    return status;
}