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

📄 class.c

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

Copyright (C) Microsoft Corporation, 1991 - 1999

Module Name:

    class.c

Abstract:

    SCSI class driver routines

Environment:

    kernel mode only

Notes:


Revision History:

--*/

#define CLASS_INIT_GUID 1
#include "classp.h"
#include "debug.h"

#ifdef ALLOC_PRAGMA
    #pragma alloc_text(INIT, DriverEntry)
    #pragma alloc_text(PAGE, ClassAddDevice)
    #pragma alloc_text(PAGE, ClassClaimDevice)
    #pragma alloc_text(PAGE, ClassCreateDeviceObject)
    #pragma alloc_text(PAGE, ClassDispatchPnp)
    #pragma alloc_text(PAGE, ClassGetDescriptor)
    #pragma alloc_text(PAGE, ClassGetPdoId)
    #pragma alloc_text(PAGE, ClassInitialize)
    #pragma alloc_text(PAGE, ClassInitializeEx)
    #pragma alloc_text(PAGE, ClassInvalidateBusRelations)
    #pragma alloc_text(PAGE, ClassMarkChildMissing)
    #pragma alloc_text(PAGE, ClassMarkChildrenMissing)
    #pragma alloc_text(PAGE, ClassModeSense)
    #pragma alloc_text(PAGE, ClassPnpQueryFdoRelations)
    #pragma alloc_text(PAGE, ClassPnpStartDevice)
    #pragma alloc_text(PAGE, ClassQueryPnpCapabilities)
    #pragma alloc_text(PAGE, ClassQueryTimeOutRegistryValue)
    #pragma alloc_text(PAGE, ClassRemoveDevice)
    #pragma alloc_text(PAGE, ClassRetrieveDeviceRelations)
    #pragma alloc_text(PAGE, ClassUpdateInformationInRegistry)
    #pragma alloc_text(PAGE, ClassSendDeviceIoControlSynchronous)
    #pragma alloc_text(PAGE, ClassUnload)
    #pragma alloc_text(PAGE, ClasspAllocateReleaseRequest)
    #pragma alloc_text(PAGE, ClasspFreeReleaseRequest)
    #pragma alloc_text(PAGE, ClasspInitializeHotplugInfo)
    #pragma alloc_text(PAGE, ClasspRegisterMountedDeviceInterface)
    #pragma alloc_text(PAGE, ClasspScanForClassHacks)
    #pragma alloc_text(PAGE, ClasspScanForSpecialInRegistry)
#endif

ULONG ClassPnpAllowUnload = TRUE;
ULONG ClassMaxInterleavePerCriticalIo = CLASS_MAX_INTERLEAVE_PER_CRITICAL_IO;
CONST LARGE_INTEGER Magic10000 = {0xe219652c, 0xd1b71758};

#define FirstDriveLetter 'C'
#define LastDriveLetter  'Z'



/*++////////////////////////////////////////////////////////////////////////////

DriverEntry()

Routine Description:

    Temporary entry point needed to initialize the class system dll.
    It doesn't do anything.

Arguments:

    DriverObject - Pointer to the driver object created by the system.

Return Value:

   STATUS_SUCCESS

--*/
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    return STATUS_SUCCESS;
}




/*++////////////////////////////////////////////////////////////////////////////

ClassInitialize()

Routine Description:

    This routine is called by a class driver during its
    DriverEntry routine to initialize the driver.

Arguments:

    Argument1          - Driver Object.
    Argument2          - Registry Path.
    InitializationData - Device-specific driver's initialization data.

Return Value:

    A valid return code for a DriverEntry routine.

--*/
ULONG
ClassInitialize(
    IN  PVOID            Argument1,
    IN  PVOID            Argument2,
    IN  PCLASS_INIT_DATA InitializationData
    )
{
    PDRIVER_OBJECT  DriverObject = Argument1;
    PUNICODE_STRING RegistryPath = Argument2;

    PCLASS_DRIVER_EXTENSION driverExtension;

    NTSTATUS        status;

    PAGED_CODE();

    DebugPrint((3,"\n\nSCSI Class Driver\n"));

    ClasspInitializeDebugGlobals();

    //
    // Validate the length of this structure. This is effectively a
    // version check.
    //

    if (InitializationData->InitializationDataSize != sizeof(CLASS_INIT_DATA)) {

        //
        // This DebugPrint is to help third-party driver writers
        //

        DebugPrint((0,"ClassInitialize: Class driver wrong version\n"));
        return (ULONG) STATUS_REVISION_MISMATCH;
    }

    //
    // Check that each required entry is not NULL. Note that Shutdown, Flush and Error
    // are not required entry points.
    //

    if ((!InitializationData->FdoData.ClassDeviceControl) ||
        (!((InitializationData->FdoData.ClassReadWriteVerification) ||
           (InitializationData->ClassStartIo))) ||
        (!InitializationData->ClassAddDevice) ||
        (!InitializationData->FdoData.ClassStartDevice)) {

        //
        // This DebugPrint is to help third-party driver writers
        //

        DebugPrint((0,
            "ClassInitialize: Class device-specific driver missing required "
            "FDO entry\n"));

        return (ULONG) STATUS_REVISION_MISMATCH;
    }

    if ((InitializationData->ClassEnumerateDevice) &&
        ((!InitializationData->PdoData.ClassDeviceControl) ||
         (!InitializationData->PdoData.ClassStartDevice) ||
         (!((InitializationData->PdoData.ClassReadWriteVerification) ||
            (InitializationData->ClassStartIo))))) {

        //
        // This DebugPrint is to help third-party driver writers
        //

        DebugPrint((0, "ClassInitialize: Class device-specific missing "
                       "required PDO entry\n"));

        return (ULONG) STATUS_REVISION_MISMATCH;
    }

    if((InitializationData->FdoData.ClassStopDevice == NULL) ||
        ((InitializationData->ClassEnumerateDevice != NULL) &&
         (InitializationData->PdoData.ClassStopDevice == NULL))) {

        //
        // This DebugPrint is to help third-party driver writers
        //

        DebugPrint((0, "ClassInitialize: Class device-specific missing "
                       "required PDO entry\n"));
        ASSERT(FALSE);
        return (ULONG) STATUS_REVISION_MISMATCH;
    }

    //
    // Setup the default power handlers if the class driver didn't provide
    // any.
    //

    if(InitializationData->FdoData.ClassPowerDevice == NULL) {
        InitializationData->FdoData.ClassPowerDevice = ClassMinimalPowerHandler;
    }

    if((InitializationData->ClassEnumerateDevice != NULL) &&
       (InitializationData->PdoData.ClassPowerDevice == NULL)) {
        InitializationData->PdoData.ClassPowerDevice = ClassMinimalPowerHandler;
    }

    //
    // warn that unload is not supported
    //
    // ISSUE-2000/02/03-peterwie
    // We should think about making this a fatal error.
    //

    if(InitializationData->ClassUnload == NULL) {

        //
        // This DebugPrint is to help third-party driver writers
        //

        DebugPrint((0, "ClassInitialize: driver does not support unload %wZ\n",
                    RegistryPath));
    }

    //
    // Create an extension for the driver object
    //

    status = IoAllocateDriverObjectExtension(DriverObject,
                                             CLASS_DRIVER_EXTENSION_KEY,
                                             sizeof(CLASS_DRIVER_EXTENSION),
                                             &driverExtension);

    if(NT_SUCCESS(status)) {

        //
        // Copy the registry path into the driver extension so we can use it later
        //

        driverExtension->RegistryPath.Length = RegistryPath->Length;
        driverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;

        driverExtension->RegistryPath.Buffer =
            ExAllocatePoolWithTag(PagedPool,
                                  RegistryPath->MaximumLength,
                                  '1CcS');

        if(driverExtension->RegistryPath.Buffer == NULL) {

            status = STATUS_INSUFFICIENT_RESOURCES;
            return status;
        }

        RtlCopyUnicodeString(
            &(driverExtension->RegistryPath),
            RegistryPath);

        //
        // Copy the initialization data into the driver extension so we can reuse
        // it during our add device routine
        //

        RtlCopyMemory(
            &(driverExtension->InitData),
            InitializationData,
            sizeof(CLASS_INIT_DATA));

        driverExtension->DeviceCount = 0;

    } else if (status == STATUS_OBJECT_NAME_COLLISION) {

        //
        // The extension already exists - get a pointer to it
        //

        driverExtension = IoGetDriverObjectExtension(DriverObject,
                                                     CLASS_DRIVER_EXTENSION_KEY);

        ASSERT(driverExtension != NULL);

    } else {

        DebugPrint((1, "ClassInitialize: Class driver extension could not be "
                       "allocated %lx\n", status));
        return status;
    }

    //
    // Update driver object with entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE] = ClassCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = ClassCreateClose;
    DriverObject->MajorFunction[IRP_MJ_READ] = ClassReadWrite;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = ClassReadWrite;
    DriverObject->MajorFunction[IRP_MJ_SCSI] = ClassInternalIoControl;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ClassDeviceControlDispatch;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ClassShutdownFlush;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ClassShutdownFlush;
    DriverObject->MajorFunction[IRP_MJ_PNP] = ClassDispatchPnp;
    DriverObject->MajorFunction[IRP_MJ_POWER] = ClassDispatchPower;
    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = ClassSystemControl;

    if (InitializationData->ClassStartIo) {
        DriverObject->DriverStartIo = ClasspStartIo;
    }

    if ((InitializationData->ClassUnload) && (ClassPnpAllowUnload == TRUE)) {
        DriverObject->DriverUnload = ClassUnload;
    } else {
        DriverObject->DriverUnload = NULL;
    }

    DriverObject->DriverExtension->AddDevice = ClassAddDevice;

    status = STATUS_SUCCESS;
    return status;
} // end ClassInitialize()

/*++////////////////////////////////////////////////////////////////////////////

ClassInitializeEx()

Routine Description:

    This routine is allows the caller to do any extra initialization or
    setup that is not done in ClassInitialize. The operation is
    controlled by the GUID that is passed and the contents of the Data
    parameter is dependent upon the GUID.

    This is the list of supported operations:

    Guid - GUID_CLASSPNP_QUERY_REGINFOEX
    Data - A PCLASS_QUERY_WMI_REGINFO_EX callback function pointer

        Initialized classpnp to callback a PCLASS_QUERY_WMI_REGINFO_EX
        callback instead of a PCLASS_QUERY_WMI_REGINFO callback. The
        former callback allows the driver to specify the name of the
        mof resource.

Arguments:

    DriverObject
    Guid
    Data

Return Value:

    Status Code

--*/
ULONG
ClassInitializeEx(
    IN  PDRIVER_OBJECT   DriverObject,
    IN  LPGUID           Guid,
    IN  PVOID            Data

⌨️ 快捷键说明

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