示例#1
0
文件: wmi.c 项目: uri247/wdk80
//
// WMI System Call back functions
//
NTSTATUS
Bus_EvtStdDataSetItem(
    IN  WDFWMIINSTANCE WmiInstance,
    IN  ULONG DataItemId,
    IN  ULONG InBufferSize,
    IN  PVOID InBuffer
    )
/*++

Routine Description:

    This routine is a callback into the driver to set for the contents of
    an instance.

Arguments:

    WmiInstance is the instance being set

    DataItemId has the id of the data item being set

    InBufferSize has the size of the data item passed

    InBuffer has the new values for the data item

Return Value:

    status

--*/
{
    PFDO_DEVICE_DATA    fdoData;

    PAGED_CODE();

    fdoData = FdoGetData(WdfWmiInstanceGetDevice(WmiInstance));

    //
    // TODO: Use generated header's #defines for constants and sizes
    // (for the remainder of the file)
    //

    if (DataItemId == 2) {
        if (InBufferSize < sizeof(ULONG)) {
            return STATUS_BUFFER_TOO_SMALL;
        }

        BusEnumDebugLevel = fdoData->StdToasterBusData.DebugPrintLevel =
            *((PULONG)InBuffer);

        return STATUS_SUCCESS;
    }

    //
    // All other fields are read only
    //
    return STATUS_WMI_READ_ONLY;
}
示例#2
0
BOOLEAN
NICEvtInterruptIsr(
    IN WDFINTERRUPT Interrupt,
    IN ULONG        MessageID
    )
/*++
Routine Description:

    Interrupt handler for the device.

Arguments:

    Interupt - Address of the framework interrupt object
    MessageID -

Return Value:

     TRUE if our device is interrupting, FALSE otherwise.

--*/
{
    BOOLEAN    InterruptRecognized = FALSE;
    PFDO_DATA  FdoData = NULL;
    USHORT     IntStatus;

    UNREFERENCED_PARAMETER( MessageID );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INTERRUPT, "--> NICEvtInterruptIsr\n");

    FdoData = FdoGetData(WdfInterruptGetDevice(Interrupt));

    //
    // We process the interrupt if it's not disabled and it's active
    //
    if (!NIC_INTERRUPT_DISABLED(FdoData) && NIC_INTERRUPT_ACTIVE(FdoData))
    {
        InterruptRecognized = TRUE;

        //
        // Disable the interrupt (will be re-enabled in NICEvtInterruptDpc
        //
        NICDisableInterrupt(FdoData);

        //
        // Acknowledge the interrupt(s) and get the interrupt status
        //

        NIC_ACK_INTERRUPT(FdoData, IntStatus);

        WdfInterruptQueueDpcForIsr( Interrupt );

    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INTERRUPT, "<-- NICEvtInterruptIsr\n");

    return InterruptRecognized;
}
示例#3
0
NTSTATUS
NICEvtDeviceD0EntryPostInterruptsEnabled(
    IN WDFDEVICE     Device,
    IN WDF_POWER_DEVICE_STATE PreviousState
    )
/*++

Routine Description:

    This event is called so that driver can do PASSIVE_LEVEL work after
    the interrupt is connected and enabled. Here we start the watchdog timer.
    Watch dog timer is used to do the initial link detection during
    start and then used to make sure the device is not stuck for any reason.

    This function is not marked pageable because this function is in the
    device power up path. When a function is marked pagable and the code
    section is paged out, it will generate a page fault which could impact
    the fast resume behavior because the client driver will have to wait
    until the system drivers can service this page fault.

Arguments:

    Interrupt - Handle to a Framework interrupt object.

    AssociatedDevice - Handle to a Framework device object.

Return Value:

   STATUS_SUCCESS -  indicates success.

--*/
{
    PFDO_DATA  fdoData;

    UNREFERENCED_PARAMETER( PreviousState );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> NICEvtDeviceD0EntryPostInterruptsEnabled\n");

    fdoData = FdoGetData(Device);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- NICEvtDeviceD0EntryPostInterruptsEnabled\n");

    return STATUS_SUCCESS;

}
示例#4
0
文件: wmi.c 项目: uri247/wdk80
NTSTATUS
Bus_EvtStdDataQueryInstance(
    IN  WDFWMIINSTANCE WmiInstance,
    IN  ULONG OutBufferSize,
    IN  PVOID OutBuffer,
    OUT PULONG BufferUsed
    )
/*++

Routine Description:

    This routine is a callback into the driver to set for the contents of
    a wmi instance

Arguments:

    WmiInstance is the instance being set

    OutBufferSize on has the maximum size available to write the data
        block.

    OutBuffer on return is filled with the returned data block

    BufferUsed pointer containing how many bytes are required (upon failure) or
        how many bytes were used (upon success)

Return Value:

    status

--*/
{
    PFDO_DEVICE_DATA fdoData;

    UNREFERENCED_PARAMETER(OutBufferSize);

    PAGED_CODE();

    fdoData = FdoGetData(WdfWmiInstanceGetDevice(WmiInstance));

    *BufferUsed = sizeof (TOASTER_BUS_WMI_STD_DATA);
    * (PTOASTER_BUS_WMI_STD_DATA) OutBuffer = fdoData->StdToasterBusData;

    return STATUS_SUCCESS;
}
示例#5
0
文件: wmi.c 项目: uri247/wdk80
NTSTATUS
Bus_EvtStdDataSetInstance(
    IN  WDFWMIINSTANCE WmiInstance,
    IN  ULONG InBufferSize,
    IN  PVOID InBuffer
    )
/*++

Routine Description:

    This routine is a callback into the driver to set for the contents of
    an instance.

Arguments:

    WmiInstance is the instance being set

    BufferSize has the size of the data block passed

    Buffer has the new values for the data block

Return Value:

    status

--*/
{
    PFDO_DEVICE_DATA   fdoData;

    UNREFERENCED_PARAMETER(InBufferSize);

    PAGED_CODE();

    fdoData = FdoGetData(WdfWmiInstanceGetDevice(WmiInstance));

    //
    // We will update only writable elements.
    //
    BusEnumDebugLevel = fdoData->StdToasterBusData.DebugPrintLevel =
        ((PTOASTER_BUS_WMI_STD_DATA)InBuffer)->DebugPrintLevel;

    return STATUS_SUCCESS;
}
示例#6
0
NTSTATUS
NICEvtDeviceD0ExitPreInterruptsDisabled(
    IN WDFDEVICE     Device,
    IN WDF_POWER_DEVICE_STATE TargetState
    )
/*++

Routine Description:

    This event is called so that driver can do PASSIVE_LEVEL work before
    the interrupt is disconnected and disabled.

Arguments:

    Interrupt - Handle to a Framework interrupt object.

    AssociatedDevice - Handle to a Framework device object.

Return Value:

    STATUS_SUCCESS -  indicates success.

--*/
{
    PFDO_DATA           fdoData;

    UNREFERENCED_PARAMETER(TargetState);

    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> NICEvtDeviceD0ExitPreInterruptsDisabled\n");

    fdoData = FdoGetData(Device);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- NICEvtDeviceD0ExitPreInterruptsDisabled\n");

    return STATUS_SUCCESS;

}
示例#7
0
NTSTATUS
NICEvtInterruptDisable(
    IN WDFINTERRUPT  Interrupt,
    IN WDFDEVICE     AssociatedDevice
    )
/*++

Routine Description:

    This event is called before the Framework moves the device to D1, D2 or D3
    and before EvtDeviceD0Exit.  The driver should disable its interrupt here.

    This function will be called at the device's assigned interrupt
    IRQL (DIRQL.)

Arguments:

    Interrupt - Handle to a Framework interrupt object.

    AssociatedDevice - Handle to a Framework device object.

Return Value:

    STATUS_SUCCESS -  indicates success.

--*/
{
    PFDO_DATA           fdoData;

    UNREFERENCED_PARAMETER(Interrupt);
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> NICEvtInterruptDisable\n");

    fdoData = FdoGetData(AssociatedDevice);
    NICDisableInterrupt(fdoData);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- NICEvtInterruptDisable\n");

    return STATUS_SUCCESS;
}
示例#8
0
NTSTATUS
NICEvtInterruptEnable(
    IN WDFINTERRUPT  Interrupt,
    IN WDFDEVICE     AssociatedDevice
    )
/*++

Routine Description:

    This event is called when the Framework moves the device to D0, and after
    EvtDeviceD0Entry.  The driver should enable its interrupt here.

    This function will be called at the device's assigned interrupt
    IRQL (DIRQL.)

Arguments:

    Interrupt - Handle to a Framework interrupt object.

    AssociatedDevice - Handle to a Framework device object.

Return Value:

    BOOLEAN - TRUE indicates that the interrupt was successfully enabled.

--*/
{
    PFDO_DATA           fdoData;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> NICEvtInterruptEnable\n");

    fdoData = FdoGetData(AssociatedDevice);
    NICEnableInterrupt(Interrupt, fdoData);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- NICEvtInterruptEnable\n");

    return STATUS_SUCCESS;
}
示例#9
0
VOID
PciDrvEvtIoWrite(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN size_t           Length
    )
/*++

Routine Description:

    Called by the framework as soon as it receive a write IRP.
    If the device is not ready, fail the request. Otherwise
    get scatter-gather list for this request and send the
    packet to the hardware for DMA.

Arguments:

    Queue - Handle to the framework queue object that is associated
            with the I/O request.
    Request - Handle to a framework request object.

    Length - Length of the IO operation
                 The default property of the queue is to not dispatch
                 zero lenght read & write requests to the driver and
                 complete is with status success. So we will never get
                 a zero length request.

Return Value:


--*/
{
    NTSTATUS        status;
    PFDO_DATA       FdoData;
    WDFDEVICE       hDevice;
    PMDL            mdl = NULL;

    UNREFERENCED_PARAMETER(Length);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> PciDrvEvtIoWrite Request %p\n", Request);

    hDevice = WdfIoQueueGetDevice(Queue);
    FdoData = FdoGetData(hDevice);

    status = WdfRequestRetrieveInputWdmMdl(Request, &mdl);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                    "WdfRequestRetrieveInputWdmMdl failed %x\n", status);
        WdfRequestCompleteWithInformation(Request, status, 0);

    } else {

        status = NICInitiateDmaTransfer(FdoData, Request);
        if(!NT_SUCCESS(status)) {

            WdfRequestCompleteWithInformation(Request, status, 0);
        }
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "<-- PciDrvEvtIoWrite %X\n", status);

    return;
}
示例#10
0
BOOLEAN
NICEvtProgramDmaFunction(
    IN  WDFDMATRANSACTION       Transaction,
    IN  WDFDEVICE               Device,
    IN  PVOID                   Context,
    IN  WDF_DMA_DIRECTION       Direction,
    IN  PSCATTER_GATHER_LIST    ScatterGather
    )
/*++

Routine Description:

Arguments:

Return Value:

--*/
{
    PFDO_DATA           fdoData;
    WDFREQUEST          request;
    NTSTATUS            status;

    UNREFERENCED_PARAMETER( Context );
    UNREFERENCED_PARAMETER( Direction );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> NICEvtProgramDmaFunction\n");

    fdoData = FdoGetData(Device);
    request = WdfDmaTransactionGetRequest(Transaction);


    WdfSpinLockAcquire(fdoData->SendLock);

    //
    // If tcb or link is not available, queue the request
    //
    if (!MP_TCB_RESOURCES_AVAIABLE(fdoData))
    {
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "Resource is not available: queue Request %p\n", request);

        //
        // Must abort the transaction before deleting.
        //
        (VOID) WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
        ASSERT(NT_SUCCESS(status));
        WdfObjectDelete( Transaction );

        //
        // Queue the request for later processing.
        //
        status = WdfRequestForwardToIoQueue(request,
                                           fdoData->PendingWriteQueue);

        if(!NT_SUCCESS(status)) {
            ASSERTMSG(" WdfRequestForwardToIoQueue failed ", FALSE);
            WdfSpinLockRelease(fdoData->SendLock);
            WdfRequestCompleteWithInformation(request, STATUS_UNSUCCESSFUL, 0);
            return FALSE;
        }
        fdoData->nWaitSend++;

    } else {

        status = NICWritePacket(fdoData, Transaction, ScatterGather);

        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                        "<-- NICEvtProgramDmaFunction returning %!STATUS!\n",
                        status);
            //
            // Must abort the transaction before deleting.
            //
            (VOID )WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
            ASSERT(NT_SUCCESS(status));
            WdfObjectDelete( Transaction );

            WdfSpinLockRelease(fdoData->SendLock);
            WdfRequestCompleteWithInformation(request, STATUS_UNSUCCESSFUL, 0);
            return FALSE;
        }
    }


    WdfSpinLockRelease(fdoData->SendLock);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "<-- NICEvtProgramDmaFunction\n");

    return TRUE;
}
示例#11
0
文件: wmi.c 项目: 340211173/Driver
    OutBuffer on return is filled with the returned data block

    BufferUsed pointer containing how many bytes are required (upon failure) or
        how many bytes were used (upon success)

Return Value:

    status

--*/
{
    PFDO_DEVICE_DATA fdoData;

    UNREFERENCED_PARAMETER(OutBufferSize);

    PAGED_CODE();

    fdoData = FdoGetData(WdfWmiInstanceGetDevice(WmiInstance));

    *BufferUsed = sizeof (fdoData->StdToasterBusData);
    if (OutBufferSize < sizeof(fdoData->StdToasterBusData)) {
        return STATUS_BUFFER_TOO_SMALL;
    }

    * (PTOASTER_BUS_WMI_STD_DATA) OutBuffer = fdoData->StdToasterBusData;

    return STATUS_SUCCESS;
}

示例#12
0
VOID
NICEvtInterruptDpc(
    IN WDFINTERRUPT WdfInterrupt,
    IN WDFOBJECT    WdfDevice
    )

/*++

Routine Description:

    DPC callback for ISR.

Arguments:

    WdfInterrupt - Handle to the framework interrupt object

    WdfDevice - Associated device object.

Return Value:

--*/
{
    PFDO_DATA fdoData = NULL;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "--> NICEvtInterruptDpc\n");

    fdoData = FdoGetData(WdfDevice);


    WdfSpinLockAcquire(fdoData->RcvLock);

    NICHandleRecvInterrupt(fdoData);


    WdfSpinLockRelease(fdoData->RcvLock);

    //
    // Handle send interrupt
    //

    WdfSpinLockAcquire(fdoData->SendLock);

    NICHandleSendInterrupt(fdoData);


    WdfSpinLockRelease(fdoData->SendLock);

    //
    // Check if any queued Sends need to be reprocessed.
    //
    NICCheckForQueuedSends(fdoData);

    //
    // Start the receive unit if it had stopped
    //

    WdfSpinLockAcquire(fdoData->RcvLock);

    NICStartRecv(fdoData);


    WdfSpinLockRelease(fdoData->RcvLock);

    //
    // Re-enable the interrupt (disabled in MPIsr)
    //
    WdfInterruptSynchronize(
        WdfInterrupt,
        NICEnableInterrupt,
        fdoData);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "<-- NICEvtInterruptDpc\n");

}
示例#13
0
文件: busenum.c 项目: uri247/wdk80
NTSTATUS
Bus_PlugInDevice(
    _In_ WDFDEVICE  Device,
    _In_ PWCHAR     HardwareIds,
    _In_ ULONG      SerialNo
    )

/*++

Routine Description:

    The user application has told us that a new device on the bus has arrived.

    We therefore need to create a new PDO, initialize it, add it to the list
    of PDOs for this FDO bus, and then tell Plug and Play that all of this
    happened so that it will start sending prodding IRPs.

--*/

{
    NTSTATUS         status = STATUS_SUCCESS;
    BOOLEAN          unique = TRUE;
    WDFDEVICE        hChild;
    PPDO_DEVICE_DATA pdoData;
    PFDO_DEVICE_DATA deviceData;

    PAGED_CODE ();

    //
    // First make sure that we don't already have another device with the
    // same serial number.
    // Framework creates a collection of all the child devices we have
    // created so far. So acquire the handle to the collection and lock
    // it before walking the item.
    //
    deviceData = FdoGetData(Device);
    hChild = NULL;

    //
    // We need an additional lock to synchronize addition because
    // WdfFdoLockStaticChildListForIteration locks against anyone immediately
    // updating the static child list (the changes are put on a queue until the
    // list has been unlocked).  This type of lock does not enforce our concept
    // of unique IDs on the bus (ie SerialNo).
    //
    // Without our additional lock, 2 threads could execute this function, both
    // find that the requested SerialNo is not in the list and attempt to add
    // it.  If that were to occur, 2 PDOs would have the same unique SerialNo,
    // which is incorrect.
    //
    // We must use a passive level lock because you can only call WdfDeviceCreate
    // at PASSIVE_LEVEL.
    //
    WdfWaitLockAcquire(deviceData->ChildLock, NULL);
    WdfFdoLockStaticChildListForIteration(Device);

    while ((hChild = WdfFdoRetrieveNextStaticChild(Device,
                            hChild, WdfRetrieveAddedChildren)) != NULL) {
        //
        // WdfFdoRetrieveNextStaticChild returns reported and to be reported
        // children (ie children who have been added but not yet reported to PNP).
        //
        // A surprise removed child will not be returned in this list.
        //
        pdoData = PdoGetData(hChild);

        //
        // It's okay to plug in another device with the same serial number
        // as long as the previous one is in a surprise-removed state. The
        // previous one would be in that state after the device has been
        // physically removed, if somebody has an handle open to it.
        //
        if (SerialNo == pdoData->SerialNo) {
            unique = FALSE;
            status = STATUS_INVALID_PARAMETER;
            break;
        }
    }

    if (unique) {
        //
        // Create a new child device.  It is OK to create and add a child while
        // the list locked for enumeration.  The enumeration lock applies only
        // to enumeration, not addition or removal.
        //
        status = Bus_CreatePdo(Device, HardwareIds, SerialNo);
    }

    WdfFdoUnlockStaticChildListFromIteration(Device);
    WdfWaitLockRelease(deviceData->ChildLock);

    return status;
}
示例#14
0
文件: busenum.c 项目: uri247/wdk80
NTSTATUS
Bus_EvtDeviceAdd(
    IN WDFDRIVER        Driver,
    IN PWDFDEVICE_INIT  DeviceInit
    )
/*++
Routine Description:

    Bus_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 toaster bus.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    WDF_IO_QUEUE_CONFIG        queueConfig;
    WDF_OBJECT_ATTRIBUTES      attributes;
    NTSTATUS                   status;
    WDFDEVICE                  device;
    PFDO_DEVICE_DATA           deviceData;
    PNP_BUS_INFORMATION        busInfo;
    WDFQUEUE                   queue;

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE ();

    KdPrint(("Bus_EvtDeviceAdd: 0x%p\n", Driver));

    //
    // Initialize all the properties specific to the device.
    // Framework has default values for the one that are not
    // set explicitly here. So please read the doc and make sure
    // you are okay with the defaults.
    //
    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
    WdfDeviceInitSetExclusive(DeviceInit, TRUE);

    //
    // Initialize attributes structure to specify size and accessor function
    // for storing device context.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, FDO_DEVICE_DATA);

    //
    // Create a framework device object. In response to this call, framework
    // creates a WDM deviceobject.
    //
    status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Get the device context.
    //
    deviceData = FdoGetData(device);

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = device;
    //
    // Purpose of this lock is documented in Bus_PlugInDevice routine below.
    //
    status = WdfWaitLockCreate(&attributes, &deviceData->ChildLock);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Configure a default queue so that requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
    // other queues get dispatched here.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
        &queueConfig,
        WdfIoQueueDispatchParallel
    );

    queueConfig.EvtIoDeviceControl = Bus_EvtIoDeviceControl;

    //
    // 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(device,
                            &queueConfig,
                            WDF_NO_OBJECT_ATTRIBUTES,
                            &queue
                            );
    __analysis_assume(queueConfig.EvtIoStop == 0);

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

    //
    // Create device interface for this device. The interface will be
    // enabled by the framework when we return from StartDevice successfully.
    //
    status = WdfDeviceCreateDeviceInterface(
                                            device,
                                            &GUID_DEVINTERFACE_BUSENUM_TOASTER,
                                            NULL // No Reference String
                                            );
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // This value is used in responding to the IRP_MN_QUERY_BUS_INFORMATION
    // for the child devices. This is an optional information provided to
    // uniquely idenitfy the bus the device is connected.
    //
    busInfo.BusTypeGuid = GUID_DEVCLASS_TOASTER;
    busInfo.LegacyBusType = PNPBus;
    busInfo.BusNumber = 0;

    WdfDeviceSetBusInformationForChildren(device, &busInfo);

    status = Bus_WmiRegistration(device);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    status = Bus_DoStaticEnumeration(device);

    return status;
}
示例#15
0
VOID
NICWatchDogEvtTimerFunc(
    IN WDFTIMER Timer
    )
/*++

Routine Description:

    This DPC is used to do both link detection during hardware init and
    after that for hardware hang detection.

Arguments:


Return Value:

    None

--*/
{
    PFDO_DATA           FdoData = NULL;
    LARGE_INTEGER       DueTime;
    NTSTATUS            status = STATUS_SUCCESS;

    FdoData = FdoGetData(WdfTimerGetParentObject(Timer));

    DueTime.QuadPart = NIC_CHECK_FOR_HANG_DELAY;


    if(!FdoData->CheckForHang){
        //
        // We are still doing link detection
        //
        status = NICLinkDetection(FdoData);
        if(status == STATUS_PENDING) {
            // Wait for 100 ms
            FdoData->bLinkDetectionWait = TRUE;
            DueTime.QuadPart = NIC_LINK_DETECTION_DELAY;
        }else {
            FdoData->CheckForHang = TRUE;
        }
    }else {
        //
        // Link detection is over, let us check to see
        // if the hardware is stuck.
        //
        if(NICCheckForHang(FdoData)){

            status = NICReset(FdoData);
            if(!NT_SUCCESS(status)){
                goto Exit;
            }
        }
    }

    WdfTimerStart(FdoData->WatchDogTimer,   // Timer
                DueTime.QuadPart                     // DueTime
                );

    return;

Exit:
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "WatchDogTimer is exiting %x\n", status);
    return;

}
示例#16
0
文件: wmi.c 项目: uri247/wdk80
NTSTATUS
Bus_WmiRegistration(
    WDFDEVICE      Device
    )
/*++
Routine Description

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

--*/
{
    WDF_WMI_PROVIDER_CONFIG providerConfig;
    WDF_WMI_INSTANCE_CONFIG instanceConfig;
    PFDO_DEVICE_DATA deviceData;
    NTSTATUS status;
    DECLARE_CONST_UNICODE_STRING(busRsrcName, BUSRESOURCENAME);

    PAGED_CODE();

    deviceData = FdoGetData(Device);

    //
    // Register WMI classes.
    // First specify the resource name which contain the binary mof resource.
    //
    status = WdfDeviceAssignMofResourceName(Device, &busRsrcName);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &ToasterBusInformation_GUID);
    providerConfig.MinInstanceBufferSize = sizeof(TOASTER_BUS_WMI_STD_DATA);

    //
    // You would want to create a WDFWMIPROVIDER handle separately if you are
    // going to dynamically create instances on the provider.  Since we are
    // statically creating one instance, there is no need to create the provider
    // handle.
    //

    WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);

    //
    // By setting Regsiter to TRUE, we tell the framework to create a provider
    // as part of the Instance creation call. This eliminates the need to
    // call WdfWmiProviderRegister.
    //
    instanceConfig.Register = TRUE;
    instanceConfig.EvtWmiInstanceQueryInstance = Bus_EvtStdDataQueryInstance;
    instanceConfig.EvtWmiInstanceSetInstance = Bus_EvtStdDataSetInstance;
    instanceConfig.EvtWmiInstanceSetItem = Bus_EvtStdDataSetItem;

    status = WdfWmiInstanceCreate(
        Device,
        &instanceConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        WDF_NO_HANDLE
        );

    if (NT_SUCCESS(status)) {
        deviceData->StdToasterBusData.ErrorCount = 0;
    }

    return status;
}
示例#17
0
文件: busenum.c 项目: kcrazy/winekit
NTSTATUS
Bus_EvtDeviceAdd(
    IN WDFDRIVER        Driver,
    IN PWDFDEVICE_INIT  DeviceInit
    )
/*++
Routine Description:

    Bus_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 toaster bus.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    WDF_CHILD_LIST_CONFIG      config;
    WDF_OBJECT_ATTRIBUTES      fdoAttributes;
    NTSTATUS                   status;
    WDFDEVICE                  device;
    WDF_IO_QUEUE_CONFIG        queueConfig;
    PNP_BUS_INFORMATION        busInfo;
    PFDO_DEVICE_DATA           deviceData;
    WDFQUEUE                   queue;

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE ();

    KdPrint(("Bus_EvtDeviceAdd: 0x%p\n", Driver));

    //
    // Initialize all the properties specific to the device.
    // Framework has default values for the one that are not
    // set explicitly here. So please read the doc and make sure
    // you are okay with the defaults.
    //
    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
    WdfDeviceInitSetExclusive(DeviceInit, TRUE);

    //
    // Since this is pure software bus enumerator, we don't have to register for
    // any PNP/Power callbacks. Framework will take the default action for
    // all the PNP and Power IRPs.
    //


    //
    // WDF_ DEVICE_LIST_CONFIG describes how the framework should handle
    // dynamic child enumeration on behalf of the driver writer.
    // Since we are a bus driver, we need to specify identification description
    // for our child devices. This description will serve as the identity of our
    // child device. Since the description is opaque to the framework, we
    // have to provide bunch of callbacks to compare, copy, or free
    // any other resources associated with the description.
    //
    WDF_CHILD_LIST_CONFIG_INIT(&config,
                                sizeof(PDO_IDENTIFICATION_DESCRIPTION),
                                Bus_EvtDeviceListCreatePdo // callback to create a child device.
                                );
    //
    // This function pointer will be called when the framework needs to copy a
    // identification description from one location to another.  An implementation
    // of this function is only necessary if the description contains description
    // relative pointer values (like  LIST_ENTRY for instance) .
    // If set to NULL, the framework will use RtlCopyMemory to copy an identification .
    // description. In this sample, it's not required to provide these callbacks.
    // they are added just for illustration.
    //
    config.EvtChildListIdentificationDescriptionDuplicate =
                                Bus_EvtChildListIdentificationDescriptionDuplicate;

    //
    // This function pointer will be called when the framework needs to compare
    // two identificaiton descriptions.  If left NULL a call to RtlCompareMemory
    // will be used to compare two identificaiton descriptions.
    //
    config.EvtChildListIdentificationDescriptionCompare =
                                Bus_EvtChildListIdentificationDescriptionCompare;
    //
    // This function pointer will be called when the framework needs to free a
    // identification description.  An implementation of this function is only
    // necessary if the description contains dynamically allocated memory
    // (by the driver writer) that needs to be freed. The actual identification
    // description pointer itself will be freed by the framework.
    //
    config.EvtChildListIdentificationDescriptionCleanup =
                                Bus_EvtChildListIdentificationDescriptionCleanup;

    //
    // Tell the framework to use the built-in childlist to track the state
    // of the device based on the configuration we just created.
    //
    WdfFdoInitSetDefaultChildListConfig(DeviceInit,
                                         &config,
                                         WDF_NO_OBJECT_ATTRIBUTES);

    //
    // Initialize attributes structure to specify size and accessor function
    // for storing device context.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DEVICE_DATA);

    //
    // Create a framework device object. In response to this call, framework
    // creates a WDM deviceobject and attach to the PDO.
    //
    status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);

    if (!NT_SUCCESS(status)) {
        KdPrint(("Error creating device 0x%x\n", status));
        return status;
    }

    //
    // Configure a default queue so that requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
    // other queues get dispatched here.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
        &queueConfig,
        WdfIoQueueDispatchParallel
    );

    queueConfig.EvtIoDeviceControl = Bus_EvtIoDeviceControl;

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

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

    //
    // Get the device context.
    //
    deviceData = FdoGetData(device);

    //
    // Create device interface for this device. The interface will be
    // enabled by the framework when we return from StartDevice successfully.
    // Clients of this driver will open this interface and send ioctls.
    //
    status = WdfDeviceCreateDeviceInterface(
        device,
        &GUID_DEVINTERFACE_BUSENUM_TOASTER,
        NULL // No Reference String. If you provide one it will appended to the
        );   // symbolic link. Some drivers register multiple interfaces for the same device
             // and use the reference string to distinguish between them
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // This value is used in responding to the IRP_MN_QUERY_BUS_INFORMATION
    // for the child devices. This is an optional information provided to
    // uniquely idenitfy the bus the device is connected.
    //
    busInfo.BusTypeGuid = GUID_DEVCLASS_TOASTER;
    busInfo.LegacyBusType = PNPBus;
    busInfo.BusNumber = 0;

    WdfDeviceSetBusInformationForChildren(device, &busInfo);

    status = Bus_WmiRegistration(device);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Check the registry to see if we need to enumerate child devices during
    // start.
    //
    status = Bus_DoStaticEnumeration(device);

    return status;
}