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

📄 class.c

📁 This is the library for all storage drivers. It simplifies writing a storage driver by implementing
💻 C
📖 第 1 页 / 共 5 页
字号:
    )
{
    PCLASS_DRIVER_EXTENSION driverExtension;

    NTSTATUS        status;

    PAGED_CODE();

    driverExtension = IoGetDriverObjectExtension( DriverObject,
                                                  CLASS_DRIVER_EXTENSION_KEY
                                                  );
    if (IsEqualGUID(Guid, &ClassGuidQueryRegInfoEx))
    {
        PCLASS_QUERY_WMI_REGINFO_EX_LIST List;

        //
        // Indicate the device supports PCLASS_QUERY_REGINFO_EX
        // callback instead of PCLASS_QUERY_REGINFO callback.
        //
        List = (PCLASS_QUERY_WMI_REGINFO_EX_LIST)Data;

        if (List->Size == sizeof(CLASS_QUERY_WMI_REGINFO_EX_LIST))
        {
            driverExtension->ClassFdoQueryWmiRegInfoEx = List->ClassFdoQueryWmiRegInfoEx;
            driverExtension->ClassPdoQueryWmiRegInfoEx = List->ClassPdoQueryWmiRegInfoEx;
            status = STATUS_SUCCESS;
        } else {
            status = STATUS_INVALID_PARAMETER;
        }
    } else {
        status = STATUS_NOT_SUPPORTED;
    }

    return(status);

} // end ClassInitializeEx()

/*++////////////////////////////////////////////////////////////////////////////

ClassUnload()

Routine Description:

    called when there are no more references to the driver.  this allows
    drivers to be updated without rebooting.

Arguments:

    DriverObject - a pointer to the driver object that is being unloaded

Status:

--*/
VOID
ClassUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    PCLASS_DRIVER_EXTENSION driverExtension;
    NTSTATUS status;

    PAGED_CODE();

    ASSERT( DriverObject->DeviceObject == NULL );

    driverExtension = IoGetDriverObjectExtension( DriverObject,
                                                  CLASS_DRIVER_EXTENSION_KEY
                                                  );

    ASSERT(driverExtension != NULL);
    ASSERT(driverExtension->RegistryPath.Buffer != NULL);
    ASSERT(driverExtension->InitData.ClassUnload != NULL);

    DebugPrint((1, "ClassUnload: driver unloading %wZ\n",
                &driverExtension->RegistryPath));

    //
    // attempt to process the driver's unload routine first.
    //

    driverExtension->InitData.ClassUnload(DriverObject);

    //
    // free own allocated resources and return
    //

    ExFreePool( driverExtension->RegistryPath.Buffer );
    driverExtension->RegistryPath.Buffer = NULL;
    driverExtension->RegistryPath.Length = 0;
    driverExtension->RegistryPath.MaximumLength = 0;

    return;
} // end ClassUnload()

/*++////////////////////////////////////////////////////////////////////////////

ClassAddDevice()

Routine Description:

    SCSI class driver add device routine.  This is called by pnp when a new
    physical device come into being.

    This routine will call out to the class driver to verify that it should
    own this device then will create and attach a device object and then hand
    it to the driver to initialize and create symbolic links

Arguments:

    DriverObject - a pointer to the driver object that this is being created for
    PhysicalDeviceObject - a pointer to the physical device object

Status: STATUS_NO_SUCH_DEVICE if the class driver did not want this device
    STATUS_SUCCESS if the creation and attachment was successful
    status of device creation and initialization

--*/
NTSTATUS
ClassAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
{
    PCLASS_DRIVER_EXTENSION driverExtension =
        IoGetDriverObjectExtension(DriverObject,
                                   CLASS_DRIVER_EXTENSION_KEY);

    NTSTATUS status;

    PAGED_CODE();

    status = driverExtension->InitData.ClassAddDevice(DriverObject,
                                                      PhysicalDeviceObject);
    return status;
} // end ClassAddDevice()

/*++////////////////////////////////////////////////////////////////////////////

ClassDispatchPnp()

Routine Description:

    Storage class driver pnp routine.  This is called by the io system when
    a PNP request is sent to the device.

Arguments:

    DeviceObject - pointer to the device object

    Irp - pointer to the io request packet

Return Value:

    status

--*/
NTSTATUS
ClassDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
    BOOLEAN isFdo = commonExtension->IsFdo;

    PCLASS_DRIVER_EXTENSION driverExtension;
    PCLASS_INIT_DATA initData;
    PCLASS_DEV_INFO devInfo;

    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);

    NTSTATUS status = Irp->IoStatus.Status;
    BOOLEAN completeRequest = TRUE;
    BOOLEAN lockReleased = FALSE;

    ULONG isRemoved;

    PAGED_CODE();

    //
    // Extract all the useful information out of the driver object
    // extension
    //

    driverExtension = IoGetDriverObjectExtension(DeviceObject->DriverObject,
                                                 CLASS_DRIVER_EXTENSION_KEY);
    if (driverExtension){

        initData = &(driverExtension->InitData);

        if(isFdo) {
            devInfo = &(initData->FdoData);
        } else {
            devInfo = &(initData->PdoData);
        }

        isRemoved = ClassAcquireRemoveLock(DeviceObject, Irp);

        DebugPrint((2, "ClassDispatchPnp (%p,%p): minor code %#x for %s %p\n",
                       DeviceObject, Irp,
                       irpStack->MinorFunction,
                       isFdo ? "fdo" : "pdo",
                       DeviceObject));
        DebugPrint((2, "ClassDispatchPnp (%p,%p): previous %#x, current %#x\n",
                       DeviceObject, Irp,
                       commonExtension->PreviousState,
                       commonExtension->CurrentState));

        switch(irpStack->MinorFunction) {

            case IRP_MN_START_DEVICE: {

                //
                // if this is sent to the FDO we should forward it down the
                // attachment chain before we start the FDO.
                //

                if (isFdo) {
                    status = ClassForwardIrpSynchronous(commonExtension, Irp);
                }
                else {
                    status = STATUS_SUCCESS;
                }

                if (NT_SUCCESS(status)){
                    status = Irp->IoStatus.Status = ClassPnpStartDevice(DeviceObject);
                }

                break;
            }


            case IRP_MN_QUERY_DEVICE_RELATIONS: {

                DEVICE_RELATION_TYPE type =
                    irpStack->Parameters.QueryDeviceRelations.Type;

                PDEVICE_RELATIONS deviceRelations = NULL;

                if(!isFdo) {

                    if(type == TargetDeviceRelation) {

                        //
                        // Device relations has one entry built in to it's size.
                        //

                        status = STATUS_INSUFFICIENT_RESOURCES;

                        deviceRelations = ExAllocatePoolWithTag(PagedPool,
                                                         sizeof(DEVICE_RELATIONS),
                                                         '2CcS');

                        if(deviceRelations != NULL) {

                            RtlZeroMemory(deviceRelations,
                                          sizeof(DEVICE_RELATIONS));

                            Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;

                            deviceRelations->Count = 1;
                            deviceRelations->Objects[0] = DeviceObject;
                            ObReferenceObject(deviceRelations->Objects[0]);

                            status = STATUS_SUCCESS;
                        }

                    } else {
                        //
                        // PDO's just complete enumeration requests without altering
                        // the status.
                        //

                        status = Irp->IoStatus.Status;
                    }

                    break;

                } else if (type == BusRelations) {

                    ASSERT(commonExtension->IsInitialized);

                    //
                    // Make sure we support enumeration
                    //

                    if(initData->ClassEnumerateDevice == NULL) {

                        //
                        // Just send the request down to the lower driver.  Perhaps
                        // It can enumerate children.
                        //

                    } else {

                        //
                        // Re-enumerate the device
                        //

                        status = ClassPnpQueryFdoRelations(DeviceObject, Irp);

                        if(!NT_SUCCESS(status)) {
                            completeRequest = TRUE;
                            break;
                        }
                    }
                }

                IoCopyCurrentIrpStackLocationToNext(Irp);
                ClassReleaseRemoveLock(DeviceObject, Irp);
                status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
                completeRequest = FALSE;

                break;
            }

            case IRP_MN_QUERY_ID: {

                BUS_QUERY_ID_TYPE idType = irpStack->Parameters.QueryId.IdType;
                UNICODE_STRING unicodeString;

                if(isFdo) {

                    //
                    // FDO's should just forward the query down to the lower
                    // device objects
                    //

                    IoCopyCurrentIrpStackLocationToNext(Irp);
                    ClassReleaseRemoveLock(DeviceObject, Irp);

                    status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
                    completeRequest = FALSE;
                    break;
                }

                //
                // PDO's need to give an answer - this is easy for now
                //

                RtlInitUnicodeString(&unicodeString, NULL);

                status = ClassGetPdoId(DeviceObject,
                                       idType,
                                       &unicodeString);

                if(status == STATUS_NOT_IMPLEMENTED) {
                    //
                    // The driver doesn't implement this ID (whatever it is).
                    // Use the status out of the IRP so that we don't mangle a
                    // response from someone else.
                    //

                    status = Irp->IoStatus.Status;
                } else if(NT_SUCCESS(status)) {
                    Irp->IoStatus.Information = (ULONG_PTR) unicodeString.Buffer;
                } else {
                    Irp->IoStatus.Information = (ULONG_PTR) NULL;
                }

                break;
            }

            case IRP_MN_QUERY_STOP_DEVICE:
            case IRP_MN_QUERY_REMOVE_DEVICE: {

⌨️ 快捷键说明

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