⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 firefly.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (c) Microsoft Corporation.  All rights reserved.

    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
    PURPOSE.


Module Name:

    firefly.c

Abstract:

    This module contains filter driver code for the firefly device.

Environment:

    Kernel mode

Revision History:

    Adrian J. Oney - Written March 17th, 2001
                     (based on Toaster DDK filter sample)

    Eliyas Yakub - Cleaned up for DDK - 18-Oct-2002                     

--*/

#include "firefly.h"

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, FireflyAddDevice)
#pragma alloc_text(PAGE, FireflyUnload)
#pragma alloc_text(PAGE, FireflyDispatchPnp)
#pragma alloc_text(PAGE, FireflyDispatchPower)
#pragma alloc_text(PAGE, FireflyDispatchWmi)
#pragma alloc_text(PAGE, FireflyRegisterWmi)
#pragma alloc_text(PAGE, FireflySetWmiDataItem)
#pragma alloc_text(PAGE, FireflySetWmiDataBlock)
#pragma alloc_text(PAGE, FireflyQueryWmiDataBlock)
#pragma alloc_text(PAGE, FireflyQueryWmiRegInfo)
#endif

UNICODE_STRING GlobalRegistryPath;

//
// Defines for the various WMI blocks we are exposing
//
#define WMI_FIREFLY_DRIVER_INFORMATION  0

//
// Guids for the various WMI blocks we are exposing
//
WMIGUIDREGINFO FireflyWmiGuidList[1] = {

    { &FIREFLY_WMI_STD_DATA_GUID, 1, 0 } // driver information
};

//
// Where they are described.
//
#define MOFRESOURCENAME L"FireflyWMI"

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    DriverObject - pointer to the driver object

    RegistryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.

Return Value:

    NT status code
    
--*/
{
    USHORT              regPathLen;
    ULONG               ulIndex;
    PDRIVER_DISPATCH  * dispatch;

    DebugPrint(("Entered the Driver Entry\n"));

    //
    // Cache away the registry path.
    //
    regPathLen = RegistryPath->Length;
    GlobalRegistryPath.MaximumLength = regPathLen + sizeof(UNICODE_NULL);
    GlobalRegistryPath.Length = regPathLen;
    GlobalRegistryPath.Buffer = ExAllocatePoolWithTag(
                                            PagedPool,
                                            GlobalRegistryPath.MaximumLength,
                                            POOL_TAG
                                            );

    if (GlobalRegistryPath.Buffer == NULL) {

        DebugPrint(("Couldn't allocate pool for registry path!\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlCopyUnicodeString(&GlobalRegistryPath, RegistryPath);

    //
    // Create dispatch points
    //
    for (ulIndex = 0, dispatch = DriverObject->MajorFunction;
         ulIndex <= IRP_MJ_MAXIMUM_FUNCTION;
         ulIndex++, dispatch++) {

        *dispatch = FireflyForwardIrp;
    }

    DriverObject->MajorFunction[IRP_MJ_PNP]            = FireflyDispatchPnp;
    DriverObject->MajorFunction[IRP_MJ_POWER]          = FireflyDispatchPower;
    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = FireflyDispatchWmi;
    DriverObject->DriverExtension->AddDevice           = FireflyAddDevice;
    DriverObject->DriverUnload                         = FireflyUnload;

    return STATUS_SUCCESS;
}


NTSTATUS
FireflyAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++

Routine Description:

   The Plug & Play subsystem is handing us a brand new PDO, for which we (by
   means of INF registration) have been asked to provide a driver.

   We need to determine if we need to be in the driver stack for the device.
   Create a function device object to attach to the stack
   Initialize that device object
   Return status success.

   Remember: We can NOT actually send ANY non pnp IRPS to the given driver
   stack, UNTIL we have received an IRP_MN_START_DEVICE.

Arguments:

   DeviceObject - pointer to a device object.

   PhysicalDeviceObject -  pointer to a device object created by the
                           underlying bus driver.

Return Value:

   NT status code.

--*/
{
    NTSTATUS                status;
    PDEVICE_OBJECT          deviceObject;
    PDEVICE_EXTENSION       deviceExtension = NULL;

    PAGED_CODE();

    //
    // Create a filter device object.
    //
    
    status = IoCreateDevice(
        DriverObject,
        sizeof(DEVICE_EXTENSION),
        NULL,                       // No Name
        FILE_DEVICE_UNKNOWN,
        FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
        FALSE,
        &deviceObject
        );

    if (!NT_SUCCESS(status)) {

        //
        // Returning failure here prevents the entire stack from functioning,
        // but most likely the rest of the stack will not be able to create
        // device objects either, so it is still OK.
        //
        return status;
    }

    DebugPrint((
        "AddDevice PDO (0x%x) FDO (0x%x)\n",
        PhysicalDeviceObject,
        deviceObject
        ));

    //
    // Get a pointer to our device extension.
    //
    deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;

    //
    // Save some information for later.
    //
    deviceExtension->Self = deviceObject;
    deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;

    deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack(
        deviceObject,
        PhysicalDeviceObject
        );

    //
    // Failure for attachment is an indication of a broken plug & play system.
    //
    if (NULL == deviceExtension->NextLowerDriver) {
        IoDeleteDevice(deviceObject);
        return STATUS_UNSUCCESSFUL;
    }

    deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags &
                            (DO_BUFFERED_IO | DO_DIRECT_IO |
                            DO_POWER_PAGABLE  | DO_POWER_INRUSH);

    deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType;

    deviceObject->Characteristics =
                          deviceExtension->NextLowerDriver->Characteristics;

    //
    // Set the initial state of the Filter DO
    //
    INITIALIZE_PNP_STATE(deviceExtension);

    //
    // Let us use remove lock to keep count of IRPs so that we don't 
    // deteach or delete our deviceobject until all pending I/Os in our
    // devstack are completed. Remlock is required to protect us from
    // various race conditions.
    //
    
    IoInitializeRemoveLock (&deviceExtension->RemoveLock , 
                            POOL_TAG,
                            1, // MaxLockedMinutes 
                            5); // HighWatermark, this parameter is 
                                // used only on checked build.
                                
    DebugPrint((
        "AddDevice: %x to %x->%x \n",
        deviceObject,
        deviceExtension->NextLowerDriver,
        PhysicalDeviceObject
        ));

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;
}


VOID
FireflyUnload(
    IN PDRIVER_OBJECT DriverObject
    )
/*++

Routine Description:

    Free all the allocated resources in DriverEntry, etc.

Arguments:

    DriverObject - pointer to a driver object.

Return Value:

    VOID.

--*/
{
    PAGED_CODE();

    //
    // There should be no remaining device object(s) now.
    //
    ASSERT(DriverObject->DeviceObject == NULL);

    //
    // Free the registry path we cached away.
    //
    if (GlobalRegistryPath.Buffer) {

        ExFreePool(GlobalRegistryPath.Buffer);
    }

    //
    // We should not be unloaded until all the devices we control
    // have been removed from our queue.
    //
    DebugPrint(("unload\n"));

    return;
}


NTSTATUS
FireflyDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

   The plug and play dispatch routines.

   Most of these the driver will completely ignore. In all cases it must pass
   on the IRP to the lower driver.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

   NT status code

--*/
{
    PDEVICE_EXTENSION           deviceExtension;
    PIO_STACK_LOCATION          irpStack, nextStack;
    NTSTATUS                    status;
    KEVENT                      event;

    PAGED_CODE();

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    DebugPrint((
        "FilterDO %s IRP:0x%x \n",
        PnPMinorFunctionString(irpStack->MinorFunction),
        Irp
        ));

   status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
    if (!NT_SUCCESS (status)) {
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }
    
    switch(irpStack->MinorFunction) {

    case IRP_MN_START_DEVICE:

        //
        // The device is starting.
        //
        // We cannot touch the device (send it any non pnp irps) until a
        // start device has been passed down to the lower drivers.
        //
        KeInitializeEvent(&event,
                          NotificationEvent,
                          FALSE
                          );

        IoCopyCurrentIrpStackLocationToNext(Irp);

        IoSetCompletionRoutine(
            Irp,
            FireflySynchronousCompletionRoutine,
            &event,
            TRUE,
            TRUE,
            TRUE
            );

        status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);

        if (STATUS_PENDING == status) {

            KeWaitForSingleObject(
               &event,
               Executive, // Waiting for reason of a driver
               KernelMode, // Waiting in kernel mode
               FALSE, // No alert
               NULL // No timeout
               );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -