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

📄 class.c

📁 This is the library for all storage drivers. It simplifies writing a storage driver by implementing
💻 C
📖 第 1 页 / 共 5 页
字号:
                        IoAdjustPagingPathCount(
                            &commonExtension->HibernationPathCount,
                            irpStack->Parameters.UsageNotification.InPath
                            );
                        status = ClassForwardIrpSynchronous(commonExtension, Irp);
                        if (!NT_SUCCESS(status)) {
                            IoAdjustPagingPathCount(
                                &commonExtension->HibernationPathCount,
                                !irpStack->Parameters.UsageNotification.InPath
                                );
                        }

                        break;
                    }

                    case DeviceUsageTypeDumpFile: {
                        IoAdjustPagingPathCount(
                            &commonExtension->DumpPathCount,
                            irpStack->Parameters.UsageNotification.InPath
                            );
                        status = ClassForwardIrpSynchronous(commonExtension, Irp);
                        if (!NT_SUCCESS(status)) {
                            IoAdjustPagingPathCount(
                                &commonExtension->DumpPathCount,
                                !irpStack->Parameters.UsageNotification.InPath
                                );
                        }

                        break;
                    }

                    default: {
                        status = STATUS_INVALID_PARAMETER;
                        break;
                    }
                }
                break;
            }

            case IRP_MN_QUERY_CAPABILITIES: {

                DebugPrint((2, "ClassDispatchPnp (%p,%p): QueryCapabilities\n",
                            DeviceObject, Irp));

                if(!isFdo) {

                    status = ClassQueryPnpCapabilities(
                                DeviceObject,
                                irpStack->Parameters.DeviceCapabilities.Capabilities
                                );

                    break;

                } else {

                    PDEVICE_CAPABILITIES deviceCapabilities;
                    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
                    PCLASS_PRIVATE_FDO_DATA fdoData;

                    fdoExtension = DeviceObject->DeviceExtension;
                    fdoData = fdoExtension->PrivateFdoData;
                    deviceCapabilities =
                        irpStack->Parameters.DeviceCapabilities.Capabilities;

                    //
                    // forward the irp before handling the special cases
                    //

                    status = ClassForwardIrpSynchronous(commonExtension, Irp);
                    if (!NT_SUCCESS(status)) {
                        break;
                    }

                    //
                    // we generally want to remove the device from the hotplug
                    // applet, which requires the SR-OK bit to be set.
                    // only when the user specifies that they are capable of
                    // safely removing things do we want to clear this bit
                    // (saved in WriteCacheEnableOverride)
                    //
                    // setting of this bit is done either above, or by the
                    // lower driver.
                    //
                    // note: may not be started, so check we have FDO data first.
                    //

                    if (fdoData &&
                        fdoData->HotplugInfo.WriteCacheEnableOverride) {
                        if (deviceCapabilities->SurpriseRemovalOK) {
                            DebugPrint((1, "Classpnp: Clearing SR-OK bit in "
                                        "device capabilities due to hotplug "
                                        "device or media\n"));
                        }
                        deviceCapabilities->SurpriseRemovalOK = FALSE;
                    }
                    break;

                } // end QUERY_CAPABILITIES for FDOs

                ASSERT(FALSE);
                break;


            } // end QUERY_CAPABILITIES

            default: {

                if (isFdo){
                    IoCopyCurrentIrpStackLocationToNext(Irp);

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

                    completeRequest = FALSE;
                }

                break;
            }
        }
    }
    else {
        ASSERT(driverExtension);
        status = STATUS_INTERNAL_ERROR;
    }

    if (completeRequest){
        Irp->IoStatus.Status = status;

        if (!lockReleased){
            ClassReleaseRemoveLock(DeviceObject, Irp);
        }

        ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);

        DBGTRACE(ClassDebugTrace, ("ClassDispatchPnp (%p,%p): leaving with previous %#x, current %#x.", DeviceObject, Irp, commonExtension->PreviousState, commonExtension->CurrentState));
    }
    else {
        /*
         *  The irp is already completed so don't touch it.
         *  This may be a remove so don't touch the device extension.
         */
        DBGTRACE(ClassDebugTrace, ("ClassDispatchPnp (%p,%p): leaving.", DeviceObject, Irp));
    }

    return status;
} // end ClassDispatchPnp()

/*++////////////////////////////////////////////////////////////////////////////

ClassPnpStartDevice()

Routine Description:

    Storage class driver routine for IRP_MN_START_DEVICE requests.
    This routine kicks off any device specific initialization

Arguments:

    DeviceObject - a pointer to the device object

    Irp - a pointer to the io request packet

Return Value:

    none

--*/
NTSTATUS ClassPnpStartDevice(IN PDEVICE_OBJECT DeviceObject)
{
    PCLASS_DRIVER_EXTENSION driverExtension;
    PCLASS_INIT_DATA initData;

    PCLASS_DEV_INFO devInfo;

    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
    BOOLEAN isFdo = commonExtension->IsFdo;

    BOOLEAN isMountedDevice = TRUE;
    UNICODE_STRING  interfaceName;

    BOOLEAN timerStarted = FALSE;

    NTSTATUS status = STATUS_SUCCESS;

    PAGED_CODE();

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

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

    ASSERT(devInfo->ClassInitDevice != NULL);
    ASSERT(devInfo->ClassStartDevice != NULL);

    if (!commonExtension->IsInitialized){

        //
        // perform FDO/PDO specific initialization
        //

        if (isFdo){
            STORAGE_PROPERTY_ID propertyId;

            //
            // allocate a private extension for class data
            //

            if (fdoExtension->PrivateFdoData == NULL) {
                fdoExtension->PrivateFdoData =
                    ExAllocatePoolWithTag(NonPagedPool,
                                          sizeof(CLASS_PRIVATE_FDO_DATA),
                                          CLASS_TAG_PRIVATE_DATA
                                          );
            }

            if (fdoExtension->PrivateFdoData == NULL) {
                DebugPrint((0, "ClassPnpStartDevice: Cannot allocate for "
                            "private fdo data\n"));
                return STATUS_INSUFFICIENT_RESOURCES;
            }

            //
            // initialize the struct's various fields.
            //
            RtlZeroMemory(fdoExtension->PrivateFdoData, sizeof(CLASS_PRIVATE_FDO_DATA));
            KeInitializeTimer(&fdoExtension->PrivateFdoData->Retry.Timer);
            KeInitializeDpc(&fdoExtension->PrivateFdoData->Retry.Dpc,
                            ClasspRetryRequestDpc,
                            DeviceObject);
            KeInitializeSpinLock(&fdoExtension->PrivateFdoData->Retry.Lock);
            fdoExtension->PrivateFdoData->Retry.Granularity = KeQueryTimeIncrement();
            commonExtension->Reserved4 = (ULONG_PTR)(' GPH'); // debug aid
            InitializeListHead(&fdoExtension->PrivateFdoData->DeferredClientIrpList);

            /*
             *  Anchor the FDO in our static list.
             *  Pnp is synchronized, so we shouldn't need any synchronization here.
             */
            InsertTailList(&AllFdosList, &fdoExtension->PrivateFdoData->AllFdosListEntry);

            //
            // NOTE: the old interface allowed the class driver to allocate
            // this.  this was unsafe for low-memory conditions. allocate one
            // unconditionally now, and modify our internal functions to use
            // our own exclusively as it is the only safe way to do this.
            //

            status = ClasspAllocateReleaseQueueIrp(fdoExtension);
            if (!NT_SUCCESS(status)) {
                DebugPrint((0, "ClassPnpStartDevice: Cannot allocate the private release queue irp\n"));
                return status;
            }

            //
            // Call port driver to get adapter capabilities.
            //

            propertyId = StorageAdapterProperty;

            status = ClassGetDescriptor(
                        commonExtension->LowerDeviceObject,
                        &propertyId,
                        &fdoExtension->AdapterDescriptor);
            if (!NT_SUCCESS(status)) {
                DebugPrint((0, "ClassPnpStartDevice: ClassGetDescriptor [ADAPTER] failed %lx\n", status));
                return status;
            }

            //
            // Call port driver to get device descriptor.
            //

            propertyId = StorageDeviceProperty;

            status = ClassGetDescriptor(
                        commonExtension->LowerDeviceObject,
                        &propertyId,
                        &fdoExtension->DeviceDescriptor);
            if (NT_SUCCESS(status)){

                ClasspScanForSpecialInRegistry(fdoExtension);
                ClassScanForSpecial(fdoExtension, ClassBadItems, ClasspScanForClassHacks);

                //
                // allow perf to be re-enabled after a given number of failed IOs
                // require this number to be at least CLASS_PERF_RESTORE_MINIMUM
                //

                {
                    ULONG t = CLASS_PERF_RESTORE_MINIMUM;

                    ClassGetDeviceParameter(fdoExtension,
                                            CLASSP_REG_SUBKEY_NAME,
                                            CLASSP_REG_PERF_RESTORE_VALUE_NAME,
                                            &t);
                    if (t >= CLASS_PERF_RESTORE_MINIMUM) {
                        fdoExtension->PrivateFdoData->Perf.ReEnableThreshhold = t;
                    }
                }

                //
                // compatibility comes first.  writable cd media will not
                // get a SYNCH_CACHE on power down.
                //
                if (fdoExtension->DeviceObject->DeviceType != FILE_DEVICE_DISK) {
                    SET_FLAG(fdoExtension->PrivateFdoData->HackFlags, FDO_HACK_NO_SYNC_CACHE);
                }

                //
                // initialize the hotplug information only after the ScanForSpecial
                // routines, as it relies upon the hack flags.
                //
                status = ClasspInitializeHotplugInfo(fdoExtension);
                if (NT_SUCCESS(status)){
                    /*
                     *  Allocate/initialize TRANSFER_PACKETs and related resources.
                     */
                    status = InitializeTransferPackets(DeviceObject);
                }
                else {
                    DebugPrint((1, "ClassPnpStartDevice: Could not initialize hotplug information %lx\n", status));
                }
            }
            else {
                DebugPrint((0, "ClassPnpStartDevice: ClassGetDescriptor [DEVICE] failed %lx\n", status));
            }

        }

        //
        // ISSUE - drivers need to disable write caching on the media
        //         if hotplug and !useroverride.  perhaps we should
        //         allow registration of a callback to enable/disable
        //         write cache instead.
        //

        if (NT_SUCCESS(status)){
            status = devInfo->ClassInitDevice(DeviceObject);
        }

    }

    if (!NT_SUCCESS(status)){

        //
        // Just bail out - the remove that comes down will clean up the
        // initialized scraps.
        //

        return status;
    } else {
        commonExtension->IsInitialized = TRUE;

        if (commonExtension->IsFdo) {
            fdoExtension->PrivateFdoData->Perf.OriginalSrbFlags = fdoExtension->SrbFlags;
        }

    }

    //
    // If device requests autorun functionality or a once a second callback

⌨️ 快捷键说明

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