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

📄 cdrom.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:

#ifdef _PPC_
NTSTATUS
FindScsiAdapter (
    IN HANDLE KeyHandle,
    IN UNICODE_STRING ScsiUnicodeString[],
    OUT PUCHAR IntermediateController
    );
#endif

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, DriverEntry)
#pragma alloc_text(PAGE, ScsiCdRomFindDevices)
#pragma alloc_text(PAGE, CreateCdRomDeviceObject)
#pragma alloc_text(PAGE, ScanForSpecial)
//#pragma alloc_text(PAGE, CdRomDeviceControl)
#pragma alloc_text(PAGE, HitachProcessError)
#pragma alloc_text(PAGE, CdRomIsPlayActive)
#pragma alloc_text(PAGE, ScsiCdRomReadVerification)
#pragma alloc_text(INIT, CdRomCheckRegistryForMediaChangeValue)
#pragma alloc_text(INIT, IsThisAnAtapiChanger)
#pragma alloc_text(INIT, IsThisASanyo)
#pragma alloc_text(INIT, IsThisAMultiLunDevice)
#pragma alloc_text(INIT, CdRomCreateNamedEvent)
#ifdef _PPC_
#pragma alloc_text(PAGE, FindScsiAdapter)
#endif
#endif

ULONG NoLoad = 0;


NTSTATUS
STDCALL
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;

    if(NoLoad) {
        return STATUS_NO_SUCH_DEVICE;
    }

    //
    // Zero InitData
    //

    RtlZeroMemory (&InitializationData, sizeof(CLASS_INIT_DATA));

    //
    // Set sizes
    //

    InitializationData.InitializationDataSize = sizeof(CLASS_INIT_DATA);
    InitializationData.DeviceExtensionSize = DEVICE_EXTENSION_SIZE;

    InitializationData.DeviceType = FILE_DEVICE_CD_ROM;
    InitializationData.DeviceCharacteristics = FILE_REMOVABLE_MEDIA | FILE_READ_ONLY_DEVICE;

    //
    // Set entry points
    //

    InitializationData.ClassReadWriteVerification = ScsiCdRomReadVerification;
    InitializationData.ClassDeviceControl = CdRomDeviceControl;
    InitializationData.ClassFindDevices = ScsiCdRomFindDevices;
    InitializationData.ClassShutdownFlush = NULL;
    InitializationData.ClassCreateClose = NULL;
    InitializationData.ClassStartIo = ScsiCdRomStartIo;

    //
    // Call the class init routine
    //

    return ScsiClassInitialize( DriverObject, RegistryPath, &InitializationData);

} // end DriverEntry()


BOOLEAN
STDCALL
ScsiCdRomFindDevices(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath,
    IN PCLASS_INIT_DATA InitializationData,
    IN PDEVICE_OBJECT PortDeviceObject,
    IN ULONG PortNumber
    )

/*++

Routine Description:

    Connect to SCSI port driver. Get adapter capabilities and
    SCSI bus configuration information. Search inquiry data
    for CDROM devices to process.

Arguments:

    DriverObject - CDROM class driver object.
    PortDeviceObject - SCSI port driver device object.
    PortNumber - The system ordinal for this scsi adapter.

Return Value:

    TRUE if CDROM device present on this SCSI adapter.

--*/

{
    PIO_SCSI_CAPABILITIES portCapabilities;
    PULONG cdRomCount;
    PCHAR buffer;
    PSCSI_INQUIRY_DATA lunInfo;
    PSCSI_ADAPTER_BUS_INFO  adapterInfo;
    PINQUIRYDATA inquiryData;
    ULONG scsiBus;
    NTSTATUS status;
    BOOLEAN foundDevice = FALSE;

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

    status = ScsiClassGetCapabilities(PortDeviceObject, &portCapabilities);

    if (!NT_SUCCESS(status)) {
        DebugPrint((1,"FindScsiDevices: ScsiClassGetCapabilities failed\n"));
        return foundDevice;
    }

    //
    // Call port driver to get inquiry information to find cdroms.
    //

    status = ScsiClassGetInquiryData(PortDeviceObject, (PSCSI_ADAPTER_BUS_INFO *) &buffer);

    if (!NT_SUCCESS(status)) {
        DebugPrint((1,"FindScsiDevices: ScsiClassGetInquiryData failed\n"));
        return foundDevice;
    }

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

    cdRomCount = &IoGetConfigurationInformation()->CdRomCount;
    adapterInfo = (PVOID) buffer;

    //
    // For each SCSI bus this adapter supports ...
    //

    for (scsiBus=0; scsiBus < adapterInfo->NumberOfBuses; scsiBus++) {

        //
        // Get the SCSI bus scan data for this bus.
        //

        lunInfo = (PVOID) (buffer + adapterInfo->BusData[scsiBus].InquiryDataOffset);

        //
        // Search list for unclaimed disk devices.
        //

        while (adapterInfo->BusData[scsiBus].InquiryDataOffset) {

            inquiryData = (PVOID)lunInfo->InquiryData;

            if ((inquiryData->DeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE) &&
                (inquiryData->DeviceTypeQualifier == 0) &&
                (!lunInfo->DeviceClaimed)) {

                DebugPrint((1,"FindScsiDevices: Vendor string is %.24s\n",
                            inquiryData->VendorId));

                //
                // Create device objects for cdrom
                //

                status = CreateCdRomDeviceObject(DriverObject,
                                                 PortDeviceObject,
                                                 PortNumber,
                                                 cdRomCount,
                                                 portCapabilities,
                                                 lunInfo,
                                                 InitializationData,
                                                 RegistryPath);

                if (NT_SUCCESS(status)) {

                    //
                    // Increment system cdrom device count.
                    //

                    (*cdRomCount)++;

                    //
                    // Indicate that a cdrom device was found.
                    //

                    foundDevice = TRUE;
                }
            }

            //
            // Get next LunInfo.
            //

            if (lunInfo->NextInquiryDataOffset == 0) {
                break;
            }

            lunInfo = (PVOID) (buffer + lunInfo->NextInquiryDataOffset);
        }
    }

    ExFreePool(buffer);


    return foundDevice;

} // end FindScsiCdRoms()


VOID
STDCALL
CdRomCreateNamedEvent(
    IN PDEVICE_EXTENSION DeviceExtension,
    IN ULONG DeviceNumber
    )

/*++

Routine Description:

    Create the named synchronization event for notification of media change
    events to the system.  The event is reset before this function returns.

Arguments:

    DeviceExtension - the device extension pointer for storage of the event pointer.

Return Value:

    None.

--*/

{
    UNICODE_STRING    unicodeString;
    OBJECT_ATTRIBUTES objectAttributes;
    CCHAR             eventNameBuffer[MAXIMUM_FILENAME_LENGTH];
    STRING            eventNameString;
    HANDLE            handle;
    NTSTATUS          status;


    sprintf(eventNameBuffer,"\\Device\\MediaChangeEvent%d",
            DeviceNumber);

    RtlInitString(&eventNameString,
                  eventNameBuffer);

    status = RtlAnsiStringToUnicodeString(&unicodeString,
                                          &eventNameString,
                                          TRUE);

    if (!NT_SUCCESS(status)) {
        return;
    }

    InitializeObjectAttributes(&objectAttributes,
                               &unicodeString,
                               OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
                               NULL,
                               NULL);

    DeviceExtension->MediaChangeEvent = IoCreateSynchronizationEvent(&unicodeString,
                                                                     &handle);
    DeviceExtension->MediaChangeEventHandle = handle;

    KeClearEvent(DeviceExtension->MediaChangeEvent);

    RtlFreeUnicodeString(&unicodeString);
}


NTSTATUS
STDCALL
CreateCdRomDeviceObject(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PortDeviceObject,
    IN ULONG          PortNumber,
    IN PULONG         DeviceCount,
    IN PIO_SCSI_CAPABILITIES PortCapabilities,
    IN PSCSI_INQUIRY_DATA LunInfo,
    IN PCLASS_INIT_DATA   InitializationData,
    IN PUNICODE_STRING    RegistryPath
    )

/*++

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];
    STRING ntNameString;
    UNICODE_STRING ntUnicodeString;
    NTSTATUS status;
    BOOLEAN changerDevice;
    SCSI_REQUEST_BLOCK srb;
    ULONG          length;
    PCDROM_DATA    cddata;
    PCDB           cdb;
    PVOID          senseData = NULL;
    PDEVICE_OBJECT deviceObject = NULL;
    PDEVICE_EXTENSION deviceExtension = NULL;
    PUCHAR         buffer;
    ULONG          bps;
    ULONG          lastBit;
    ULONG          timeOut;
    BOOLEAN        srbListInitialized = FALSE;

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

    status = ScsiClassClaimDevice(PortDeviceObject,
                                  LunInfo,
                                  FALSE,
                                  &PortDeviceObject);

    if (!NT_SUCCESS(status)) {
        return(status);
    }

    //
    // Create device object for this device.
    //

    sprintf(ntNameBuffer,
            "\\Device\\CdRom%d",
            *DeviceCount);

    status = ScsiClassCreateDeviceObject(DriverObject,
                                         ntNameBuffer,
                                         NULL,
                                         &deviceObject,
                                         InitializationData);

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

        RtlFreeUnicodeString(&ntUnicodeString);
        goto CreateCdRomDeviceObjectExit;
    }

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

    deviceObject->Flags |= DO_DIRECT_IO;

    //
    // Set up required stack size in device object.
    //

    deviceObject->StackSize = PortDeviceObject->StackSize + 2;

    deviceExtension = deviceObject->DeviceExtension;

    //
    // Allocate spinlock for split request completion.
    //

    KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);

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

⌨️ 快捷键说明

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