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

📄 cdrom.c

📁 The CD ROM driver is used with Classpnp.sys to provide access to CD ROMs and DVD ROMs. It supports P
💻 C
📖 第 1 页 / 共 5 页
字号:
/*--

Copyright (C) Microsoft Corporation, 1991 - 1999

Module Name:

    cdrom.c

Abstract:

    The CDROM class driver tranlates IRPs to SRBs with embedded CDBs
    and sends them to its devices through the port driver.

Environment:

    kernel mode only

Notes:

    SCSI Tape, CDRom and Disk class drivers share common routines
    that can be found in the CLASS directory (..\ntos\dd\class).

Revision History:

--*/

#include "stddef.h"
#include "string.h"

#include "ntddk.h"

#include "ntddcdvd.h"
#include "classpnp.h"

#include "initguid.h"
#include "ntddstor.h"
#include "cdrom.h"

#include "cdrom.tmh"

#ifdef ALLOC_PRAGMA

#pragma alloc_text(INIT, DriverEntry)

#pragma alloc_text(PAGE, CdRomUnload)
#pragma alloc_text(PAGE, CdRomAddDevice)
#pragma alloc_text(PAGE, CdRomCreateDeviceObject)
#pragma alloc_text(PAGE, CdRomStartDevice)
#pragma alloc_text(PAGE, ScanForSpecial)
#pragma alloc_text(PAGE, ScanForSpecialHandler)
#pragma alloc_text(PAGE, CdRomRemoveDevice)
#pragma alloc_text(PAGE, CdRomGetDeviceType)
#pragma alloc_text(PAGE, CdRomReadWriteVerification)
#pragma alloc_text(PAGE, CdRomGetDeviceParameter)
#pragma alloc_text(PAGE, CdRomSetDeviceParameter)
#pragma alloc_text(PAGE, CdRomPickDvdRegion)
#pragma alloc_text(PAGE, CdRomIsPlayActive)

#pragma alloc_text(PAGEHITA, HitachiProcessError)
#pragma alloc_text(PAGEHIT2, HitachiProcessErrorGD2000)

#pragma alloc_text(PAGETOSH, ToshibaProcessErrorCompletion)
#pragma alloc_text(PAGETOSH, ToshibaProcessError)

#endif

#define IS_WRITE_REQUEST(irpStack)                                             \
 (irpStack->MajorFunction == IRP_MJ_WRITE)

#define IS_READ_WRITE_REQUEST(irpStack)                                        \
((irpStack->MajorFunction == IRP_MJ_READ)  ||                                  \
 (irpStack->MajorFunction == IRP_MJ_WRITE) ||                                  \
 ((irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) &&                        \
  (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_RAW_READ)))




NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This routine initializes the cdrom class driver.

Arguments:

    DriverObject - Pointer to driver object created by system.

    RegistryPath - Pointer to the name of the services node for this driver.

Return Value:

    The function value is the final status from the initialization operation.

--*/

{
    CLASS_INIT_DATA InitializationData = {0};
    PCDROM_DRIVER_EXTENSION driverExtension;
    NTSTATUS status;

    PAGED_CODE();

    WPP_INIT_TRACING(DriverObject, RegistryPath);

    TraceLog((CdromDebugTrace,
                "CDROM.SYS DriverObject %p loading\n", DriverObject));

    status = IoAllocateDriverObjectExtension(DriverObject,
                                             CDROM_DRIVER_EXTENSION_ID,
                                             sizeof(CDROM_DRIVER_EXTENSION),
                                             &driverExtension);

    if (!NT_SUCCESS(status)) {
        TraceLog((CdromDebugWarning,
                    "DriverEntry !! no DriverObjectExtension %x\n", status));
        return status;
    }

    //
    // always zero the memory, since we are now reloading the driver.
    //

    RtlZeroMemory(driverExtension, sizeof(CDROM_DRIVER_EXTENSION));

    //
    // Zero InitData
    //

    RtlZeroMemory (&InitializationData, sizeof(CLASS_INIT_DATA));

    //
    // Set sizes
    //

    InitializationData.InitializationDataSize = sizeof(CLASS_INIT_DATA);

    InitializationData.FdoData.DeviceExtensionSize = DEVICE_EXTENSION_SIZE;

    InitializationData.FdoData.DeviceType = FILE_DEVICE_CD_ROM;
    InitializationData.FdoData.DeviceCharacteristics =
        FILE_REMOVABLE_MEDIA | FILE_DEVICE_SECURE_OPEN;

    //
    // Set entry points
    //

    InitializationData.FdoData.ClassError = CdRomErrorHandler;
    InitializationData.FdoData.ClassInitDevice = CdRomInitDevice;
    InitializationData.FdoData.ClassStartDevice = CdRomStartDevice;
    InitializationData.FdoData.ClassStopDevice = CdRomStopDevice;
    InitializationData.FdoData.ClassRemoveDevice = CdRomRemoveDevice;

    InitializationData.FdoData.ClassReadWriteVerification = CdRomReadWriteVerification;
    InitializationData.FdoData.ClassDeviceControl = CdRomDeviceControlDispatch;

    InitializationData.FdoData.ClassPowerDevice = ClassSpinDownPowerHandler;
    InitializationData.FdoData.ClassShutdownFlush = CdRomShutdownFlush;
    InitializationData.FdoData.ClassCreateClose = NULL;

    InitializationData.ClassStartIo = CdRomStartIo;
    InitializationData.ClassAddDevice = CdRomAddDevice;

    InitializationData.ClassTick = CdRomTickHandler;
    InitializationData.ClassUnload = CdRomUnload;

    //
    // Call the class init routine
    //

    return ClassInitialize( DriverObject, RegistryPath, &InitializationData);

} // end DriverEntry()


VOID
CdRomUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    PAGED_CODE();
    UNREFERENCED_PARAMETER(DriverObject);
    TraceLog((CdromDebugTrace,
                "CDROM.SYS DriverObject %p unloading\n", DriverObject));
    WPP_CLEANUP(DriverObject);
    return;
} // end CdRomUnload()


NTSTATUS
CdRomAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )

/*++

Routine Description:

    This routine creates and initializes a new FDO for the corresponding
    PDO.  It may perform property queries on the FDO but cannot do any
    media access operations.

Arguments:

    DriverObject - CDROM class driver object.

    Pdo - the physical device object we are being added to

Return Value:

    status

--*/

{
    NTSTATUS status;

    PAGED_CODE();

    //
    // Get the address of the count of the number of cdroms already initialized.
    //

    status = CdRomCreateDeviceObject(DriverObject,
                                     PhysicalDeviceObject);

    //
    // Note: this always increments driver extension counter
    //       it will eventually wrap, and fail additions
    //       if an existing cdrom has the given number.
    //       so unlikely that we won't even bother considering
    //       this case, since the cure is quite likely worse
    //       than the symptoms.
    //

    if(NT_SUCCESS(status)) {

        //
        // keep track of the total number of active cdroms in IoGet(),
        // as some programs use this to determine when they have found
        // all the cdroms in the system.
        //

        TraceLog((CdromDebugTrace, "CDROM.SYS Add succeeded\n"));
        IoGetConfigurationInformation()->CdRomCount++;

    } else {

        TraceLog((CdromDebugWarning,
                    "CDROM.SYS Add failed! %x\n", status));

    }

    return status;
}


NTSTATUS
CdRomCreateDeviceObject(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )

/*++

Routine Description:

    This routine creates an object for the device and then calls the
    SCSI port driver for media capacity and sector size.

Arguments:

    DriverObject - Pointer to driver object created by system.
    PortDeviceObject - to connect to SCSI port driver.
    DeviceCount - Number of previously installed CDROMs.
    PortCapabilities - Pointer to structure returned by SCSI port
        driver describing adapter capabilites (and limitations).
    LunInfo - Pointer to configuration information for this device.

Return Value:

    NTSTATUS

--*/
{
    UCHAR ntNameBuffer[64] = {0};
    STRING ntNameString = {0};
    NTSTATUS status;

    PDEVICE_OBJECT lowerDevice = NULL;
    PDEVICE_OBJECT deviceObject = NULL;
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
    PCDROM_DATA cdData = NULL;
    PCDROM_DRIVER_EXTENSION driverExtension = NULL;
    ULONG deviceNumber;

    CCHAR                   dosNameBuffer[64] = {0};
    CCHAR                   deviceNameBuffer[64] = {0};
    STRING                  deviceNameString = {0};
    STRING                  dosString = {0};
    UNICODE_STRING          dosUnicodeString = {0};
    UNICODE_STRING          unicodeString = {0};

    PAGED_CODE();

    //
    // Claim the device. Note that any errors after this
    // will goto the generic handler, where the device will
    // be released.
    //

    lowerDevice = IoGetAttachedDeviceReference(PhysicalDeviceObject);

    status = ClassClaimDevice(lowerDevice, FALSE);

    if(!NT_SUCCESS(status)) {

        //
        // Someone already had this device - we're in trouble
        //

        ObDereferenceObject(lowerDevice);
        return status;
    }

    //
    // Create device object for this device by first getting a unique name
    // for the device and then creating it.
    //

    driverExtension = IoGetDriverObjectExtension(DriverObject,
                                                 CDROM_DRIVER_EXTENSION_ID);
    ASSERT(driverExtension != NULL);

    //
    // InterlockedCdRomCounter is biased by 1.
    //

    deviceNumber = InterlockedIncrement(&driverExtension->InterlockedCdRomCounter) - 1;
    sprintf(ntNameBuffer, "\\Device\\CdRom%d", deviceNumber);


    status = ClassCreateDeviceObject(DriverObject,
                                     ntNameBuffer,
                                     PhysicalDeviceObject,
                                     TRUE,
                                     &deviceObject);

    if (!NT_SUCCESS(status)) {
        TraceLog((CdromDebugWarning,
                    "CreateCdRomDeviceObjects: Can not create device %s\n",
                    ntNameBuffer));

        goto CreateCdRomDeviceObjectExit;
    }

    //
    // Indicate that IRPs should include MDLs.
    //

    SET_FLAG(deviceObject->Flags, DO_DIRECT_IO);

    fdoExtension = deviceObject->DeviceExtension;

    //
    // Back pointer to device object.
    //

    fdoExtension->CommonExtension.DeviceObject = deviceObject;

    //
    // This is the physical device.
    //

    fdoExtension->CommonExtension.PartitionZeroExtension = fdoExtension;

    //
    // Initialize lock count to zero. The lock count is used to
    // disable the ejection mechanism when media is mounted.
    //

    fdoExtension->LockCount = 0;

    //
    // Save system cdrom number
    //

    fdoExtension->DeviceNumber = deviceNumber;

    //
    // Set the alignment requirements for the device based on the
    // host adapter requirements
    //

    if (lowerDevice->AlignmentRequirement > deviceObject->AlignmentRequirement) {
        deviceObject->AlignmentRequirement = lowerDevice->AlignmentRequirement;

⌨️ 快捷键说明

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