Пример #1
0
NTSTATUS
ToasterEvtDeviceAdd(
    IN WDFDRIVER       Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    ToasterEvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. We create and initialize a WDF device object to
    represent a new instance of toaster 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 = STATUS_SUCCESS;
    PFDO_DATA              fdoData;
    WDF_IO_QUEUE_CONFIG    queueConfig;
    WDF_OBJECT_ATTRIBUTES  fdoAttributes;
    WDFDEVICE              hDevice;
    WDFQUEUE               queue;

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    KdPrint(("ToasterEvtDeviceAdd called\n"));

    //
    // Initialize attributes and a context area for the device object.
    //
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DATA);

    //
    // 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.
    //
    status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &hDevice);
    if (!NT_SUCCESS(status)) {
        KdPrint( ("WdfDeviceCreate failed with status code 0x%x\n", status));
        return status;
    }

    //
    // Get the device context by using the accessor function specified in
    // the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for FDO_DATA.
    //
    fdoData = ToasterFdoGetData(hDevice);

    //
    // Tell the Framework that this device will need an interface
    //
    status = WdfDeviceCreateDeviceInterface(
                 hDevice,
                 (LPGUID) &GUID_DEVINTERFACE_TOASTER,
                 NULL // ReferenceString
             );

    if (!NT_SUCCESS (status)) {
        KdPrint( ("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));
        return status;
    }

    //
    // Register I/O callbacks to tell the framework that you are interested
    // in handling IRP_MJ_READ, IRP_MJ_WRITE, and IRP_MJ_DEVICE_CONTROL requests.
    // If a specific callback function is not specified for one ofthese,
    // the request will be dispatched to the EvtIoDefault handler, if any.
    // If there is no EvtIoDefault handler, the request will be failed with
    // STATUS_INVALID_DEVICE_REQUEST.
    // WdfIoQueueDispatchParallel means that we are capable of handling
    // all the I/O requests simultaneously and we are responsible for protecting
    // data that could be accessed by these callbacks simultaneously.
    // A default queue gets all the requests that are not
    // configured for forwarding using WdfDeviceConfigureRequestDispatching.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig,  WdfIoQueueDispatchParallel);

    queueConfig.EvtIoRead = ToasterEvtIoRead;
    queueConfig.EvtIoWrite = ToasterEvtIoWrite;
    queueConfig.EvtIoDeviceControl = ToasterEvtIoDeviceControl;

    status = WdfIoQueueCreate(
        hDevice,
        &queueConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &queue
        );

    if (!NT_SUCCESS (status)) {

        KdPrint( ("WdfIoQueueCreate failed 0x%x\n", status));
        return status;
    }

    return status;
}
Пример #2
0
NTSTATUS
ToasterEvtDeviceAdd(
    IN WDFDRIVER       Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    ToasterEvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. We create and initialize a WDF device object to
    represent a new instance of toaster 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 = STATUS_SUCCESS;
    PFDO_DATA              fdoData;
    WDF_IO_QUEUE_CONFIG    queueConfig;
    WDF_OBJECT_ATTRIBUTES  fdoAttributes;
    WDFDEVICE              hDevice;
    WDFQUEUE               queue;

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    KdPrint(("ToasterEvtDeviceAdd called\n"));

    //
    // Initialize attributes and a context area for the device object.
    //
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DATA);

    //
    // 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.
    //
    status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &hDevice);
    if (!NT_SUCCESS(status)) {
        KdPrint( ("WdfDeviceCreate failed with status code 0x%x\n", status));
        return status;
    }

    //
    // Get the device context by using the accessor function specified in
    // the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for FDO_DATA.
    //
    fdoData = ToasterFdoGetData(hDevice);

    //
    // Tell the Framework that this device will need an interface
    //
    status = WdfDeviceCreateDeviceInterface(
                 hDevice,
                 (LPGUID) &GUID_DEVINTERFACE_TOASTER,
                 NULL // ReferenceString
             );

    if (!NT_SUCCESS (status)) {
        KdPrint( ("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));
        return status;
    }

    //
    // Register I/O callbacks to tell the framework that you are interested
    // in handling IRP_MJ_READ, IRP_MJ_WRITE, and IRP_MJ_DEVICE_CONTROL requests.
    // If a specific callback function is not specified for one ofthese,
    // the request will be dispatched to the EvtIoDefault handler, if any.
    // If there is no EvtIoDefault handler, the request will be failed with
    // STATUS_INVALID_DEVICE_REQUEST.
    // WdfIoQueueDispatchParallel means that we are capable of handling
    // all the I/O requests simultaneously and we are responsible for protecting
    // data that could be accessed by these callbacks simultaneously.
    // A default queue gets all the requests that are not
    // configured for forwarding using WdfDeviceConfigureRequestDispatching.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig,  WdfIoQueueDispatchParallel);

    queueConfig.EvtIoRead = ToasterEvtIoRead;
    queueConfig.EvtIoWrite = ToasterEvtIoWrite;
    queueConfig.EvtIoDeviceControl = ToasterEvtIoDeviceControl;

    //
    // By default, Static Driver Verifier (SDV) displays a warning if it 
    // doesn't find the EvtIoStop callback on a power-managed queue. 
    // The 'assume' below causes SDV to suppress this warning. If the driver 
    // has not explicitly set PowerManaged to WdfFalse, the framework creates
    // power-managed queues when the device is not a filter driver.  Normally 
    // the EvtIoStop is required for power-managed queues, but for this driver
    // it is not needed b/c the driver doesn't hold on to the requests or 
    // forward them to other drivers. This driver completes the requests 
    // directly in the queue's handlers. If the EvtIoStop callback is not 
    // implemented, the framework waits for all driver-owned requests to be
    // done before moving in the Dx/sleep states or before removing the 
    // device, which is the correct behavior for this type of driver.
    // If the requests were taking an indeterminate amount of time to complete,
    // or if the driver forwarded the requests to a lower driver/another stack,
    // the queue should have an EvtIoStop/EvtIoResume.
    //
    __analysis_assume(queueConfig.EvtIoStop != 0);
    status = WdfIoQueueCreate(
        hDevice,
        &queueConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &queue
        );
    __analysis_assume(queueConfig.EvtIoStop == 0);

    if (!NT_SUCCESS (status)) {

        KdPrint( ("WdfIoQueueCreate failed 0x%x\n", status));
        return status;
    }

    return status;
}
Пример #3
0
NTSTATUS
ToasterWmiRegistration(
    _In_ WDFDEVICE Device
    )

/*++

Routine Description

    Registers with WMI as a data provider for this instance of the device.

Arguments:

    Device - The Framework device object for which the WMI provider instances
        are to be created and registered. This device object will be the parent
        object of the new WMI instance objects.

Return Value:

    NT Status code.

--*/

{
    NTSTATUS status;
    PFDO_DATA fdoData;
    PToasterDeviceInformation pData;
    PToasterControl controlData;

    WDFWMIINSTANCE instance;
    WDF_OBJECT_ATTRIBUTES woa;
    WDF_WMI_PROVIDER_CONFIG providerConfig;
    WDF_WMI_INSTANCE_CONFIG instanceConfig;
    DECLARE_CONST_UNICODE_STRING(mofResourceName, MOFRESOURCENAME);

    PAGED_CODE();

    fdoData = ToasterFdoGetData(Device);

    //
    // Register the MOF resource names of any customized WMI data providers
    // that are not defined in wmicore.mof.
    //
    status = WdfDeviceAssignMofResourceName(Device, &mofResourceName);
    if (!NT_SUCCESS(status)) {

        WppPrintDeviceError(fdoData->WppRecorderLog,
                            "[Toaster] Status = 0x%08x, WdfDeviceAssignMofResourceName failed\n",
                            status);
        return status;
    }

    //
    // Initialize the config structures for the Provider and the Instance and
    // define event callback functions that support a WMI client's request to
    // access the driver's WMI data blocks.
    //

    WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &ToasterDeviceInformation_GUID);

    //
    // Specify minimum expected buffer size for query and set instance requests.
    // Since the query block size is different than the set block size, set it
    // to zero and manually check for the buffer size for each operation.
    //
    providerConfig.MinInstanceBufferSize = 0;

    //
    // The WDFWMIPROVIDER handle is needed if multiple instances for the provider
    // has to be created or if the instances have to be created sometime after
    // the provider is created. In case below, the provider handle is not needed
    // because only one instance is needed and can be created when the provider
    // is created.
    //
    WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);

    //
    // Create the Provider object as part of the Instance creation call by setting
    // the Register value in the Instance Config to TRUE. This eliminates the
    // need to call WdfWmiProviderRegister.
    //
    instanceConfig.Register = TRUE;

    instanceConfig.EvtWmiInstanceQueryInstance = EvtWmiInstanceStdDeviceDataQueryInstance;
    instanceConfig.EvtWmiInstanceSetInstance   = EvtWmiInstanceStdDeviceDataSetInstance;
    instanceConfig.EvtWmiInstanceSetItem       = EvtWmiInstanceStdDeviceDataSetItem;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&woa, ToasterDeviceInformation);

    //
    // Create the WMI instance object for this data block.
    //
    status = WdfWmiInstanceCreate(Device,
                                  &instanceConfig,
                                  &woa,
                                  &instance);
    if (!NT_SUCCESS(status)) {

        WppPrintDeviceError(fdoData->WppRecorderLog,
                            "[Toaster] Status = 0x%08x, WdfWmiInstanceCreate failed\n",
                            status);
        return status;
    }

    pData = ToasterWmiGetData(instance);

    pData->ConnectorType = TOASTER_WMI_STD_USB;
    pData->Capacity = 2000;
    pData->ErrorCount = 0;
    pData->Controls = 5;
    pData->DebugPrintLevel = DebugLevel;

    WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT);
    providerConfig.Flags = WdfWmiProviderEventOnly;

    //
    // Specify minimum expected buffer size for query and set instance requests.
    // Since the query block size is different than the set block size, set it
    // to zero and manually check for the buffer size for each operation.
    //
    providerConfig.MinInstanceBufferSize = 0;

    WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);
    instanceConfig.Register = TRUE;

    //
    // Create the WMI instance object for this data block.
    //
    status = WdfWmiInstanceCreate(Device,
                                  &instanceConfig,
                                  WDF_NO_OBJECT_ATTRIBUTES,
                                  &fdoData->WmiDeviceArrivalEvent);

    if (!NT_SUCCESS(status)) {

        WppPrintDeviceError(fdoData->WppRecorderLog,
                            "[Toaster] Status = 0x%08x, WdfWmiInstanceCreate failed\n",
                            status);
        return status;
    }


    //
    // Register the Toaster Control class.
    //

    //
    // Initialize the config structures for the Provider and the Instance and
    // define event callback functions that support a WMI client's request to
    // access the driver's WMI data blocks.
    //

    WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &ToasterControl_GUID);

    //
    // Specify minimum expected buffer size for query and set instance requests.
    //
    providerConfig.MinInstanceBufferSize = ToasterControl_SIZE;

    //
    // The WDFWMIPROVIDER handle is needed if multiple instances for the provider
    // has to be created or if the instances have to be created sometime after
    // the provider is created. In case below, the provider handle is not needed
    // because only one instance is needed and can be created when the provider
    // is created.
    //
    WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);

    //
    // Create the Provider object as part of the Instance creation call by setting
    // the Register value in the Instance Config to TRUE. This eliminates the
    // need to call WdfWmiProviderRegister.
    //
    instanceConfig.Register = TRUE;

    instanceConfig.EvtWmiInstanceQueryInstance = EvtWmiInstanceToasterControlQueryInstance;
    instanceConfig.EvtWmiInstanceSetInstance   = EvtWmiInstanceToasterControlSetInstance;
    instanceConfig.EvtWmiInstanceSetItem       = EvtWmiInstanceToasterControlSetItem;
    instanceConfig.EvtWmiInstanceExecuteMethod = EvtWmiInstanceToasterControlExecuteMethod;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&woa, ToasterControl);

    //
    // Create the WMI instance object for this data block.
    //
    status = WdfWmiInstanceCreate(Device,
                                  &instanceConfig,
                                  &woa,
                                  &instance);
    if (!NT_SUCCESS(status)) {

        WppPrintDeviceError(fdoData->WppRecorderLog,
                            "[Toaster] Status = 0x%08x, WdfWmiInstanceCreate failed\n",
                            status);
        return status;
    }

    controlData = ToasterWmiGetControlData(instance);
    controlData->ControlValue = 25;

    return status;
}