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

📄 cdaudio.c

📁 The CD Audio sample allows some non-SCSI2 CD ROMs to support audio operations by intercepting the re
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (C) Microsoft Corporation, 1992 - 1999

Module Name:

    audio.c

Abstract:

    This driver filters scsi-2 cdrom audio commands for non-scsi-2
    compliant cdrom drives.  At initialization, the driver scans the
    scsi bus for a recognized non-scsi-2 cdrom drive, and if one is
    found attached, installs itself to intercept IO_DEVICE_CONTROL
    requests for this drive.

Environment:

    kernel mode only

Notes:

Revision History:


--*/

#include "ntddk.h"
#include "ntddscsi.h"
#include "ntddcdrm.h"
#include "stdio.h"
#include "scsi.h"
#include "cdaudio.h"

#ifdef POOL_TAGGING
    #ifdef ExAllocatePool
        #undef ExAllocatePool
    #endif
    #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,' AdC')
#endif



//
// Function declarations
//

NTSTATUS
    DriverEntry (
                IN PDRIVER_OBJECT DriverObject,
                IN PUNICODE_STRING RegistryPath
                );

NTSTATUS
    CdAudioCreate(
                 IN PDEVICE_OBJECT DeviceObject,
                 IN PIRP Irp
                 );

NTSTATUS
    CdAudioReadWrite(
                    IN PDEVICE_OBJECT DeviceObject,
                    IN PIRP Irp
                    );

NTSTATUS
    CdAudioDeviceControl(
                        IN PDEVICE_OBJECT DeviceObject,
                        IN PIRP Irp
                        );

NTSTATUS
    CdAudioSendToNextDriver(
                           IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp
                           );

BOOLEAN
    CdAudioIsPlayActive(
                       IN PDEVICE_OBJECT DeviceObject
                       );

BOOLEAN
    NecSupportNeeded(
                    PUCHAR InquiryData
                    );

NTSTATUS
    CdAudioNECDeviceControl(
                           IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp
                           );

NTSTATUS
    CdAudioPioneerDeviceControl(
                               IN PDEVICE_OBJECT DeviceObject,
                               IN PIRP Irp
                               );

NTSTATUS
    CdAudioDenonDeviceControl(
                             IN PDEVICE_OBJECT DeviceObject,
                             IN PIRP Irp
                             );

NTSTATUS
    CdAudioHitachiSendPauseCommand(
                                  IN PDEVICE_OBJECT DeviceObject
                                  );

NTSTATUS
    CdAudioHitachiDeviceControl(
                               IN PDEVICE_OBJECT DeviceObject,
                               IN PIRP Irp
                               );

NTSTATUS
    CdAudio535DeviceControl(
                           IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp
                           );


NTSTATUS
    CdAudio435DeviceControl(
                           IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp
                           );


NTSTATUS
    CdAudioPan533DeviceControl(
                              IN PDEVICE_OBJECT DeviceObject,
                              IN PIRP Irp
                              );

NTSTATUS
    CdAudioAtapiDeviceControl(
                             IN PDEVICE_OBJECT DeviceObject,
                             IN PIRP Irp
                             );

NTSTATUS
    CdAudioLionOpticsDeviceControl(
                                  IN PDEVICE_OBJECT DeviceObject,
                                  IN PIRP Irp
                                  );

NTSTATUS
    CdAudioHPCdrDeviceControl(
                             PDEVICE_OBJECT DeviceObject,
                             PIRP Irp
                             );

VOID
    HpCdrProcessLastSession(
                           IN PCDROM_TOC Toc
                           );

NTSTATUS
    HPCdrCompletion(
                   IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp,
                   IN PVOID Context
                   );

NTSTATUS
    CdAudioPower(
                 IN PDEVICE_OBJECT DeviceObject,
                 IN PIRP Irp
                 );

NTSTATUS
    CdAudioForwardIrpSynchronous(
                                 IN PDEVICE_OBJECT DeviceObject,
                                 IN PIRP Irp
                                 );

VOID CdAudioUnload(
                  IN PDRIVER_OBJECT DriverObject
                  );

//
// Define the sections that allow for discarding (i.e. paging) some of
// the code.  NEC is put into one section, all others go into another
// section.  This way unless there are both NEC and one of the other
// device brands, some amount of code is freed.
//

#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGECDNC, CdAudioNECDeviceControl)
#pragma alloc_text(PAGECDOT, CdAudioHitachiSendPauseCommand)
#pragma alloc_text(PAGECDOT, CdAudioHitachiDeviceControl)
#pragma alloc_text(PAGECDOT, CdAudioDenonDeviceControl)
#pragma alloc_text(PAGECDNC, CdAudio435DeviceControl)
#pragma alloc_text(PAGECDNC, CdAudio535DeviceControl)
#pragma alloc_text(PAGECDOT, CdAudioPioneerDeviceControl)
#pragma alloc_text(PAGECDNC, CdAudioPan533DeviceControl)
#pragma alloc_text(PAGECDOT, CdAudioAtapiDeviceControl)
#pragma alloc_text(PAGECDOT, CdAudioLionOpticsDeviceControl)
#pragma alloc_text(PAGECDOT, CdAudioHPCdrDeviceControl)
#pragma alloc_text(PAGECDOT, HpCdrProcessLastSession)
#pragma alloc_text(PAGECDOT, HPCdrCompletion)


NTSTATUS
    SendSrbSynchronous(
                      IN  PCD_DEVICE_EXTENSION    Extension,
                      IN  PSCSI_PASS_THROUGH      Srb,
                      IN  PVOID                   Buffer,
                      IN  ULONG                   BufferLength
                      )

/*++

Routine Description:

    This routine sends the given SRB synchronously to the CDROM class driver.

Arguments:

    Extension       - Supplies the device extension.

    Srb             - Supplies the SRB.

    Buffer          - Supplies the return buffer.

    BufferLength    - Supplies the buffer length.

Return Value:

    NTSTATUS

--*/

{
    ULONG           ioctl;
    KEVENT          event;
    PIRP            irp = NULL;
    IO_STATUS_BLOCK ioStatus;
    NTSTATUS        status;

    Srb->Length = sizeof(SCSI_PASS_THROUGH);
    Srb->SenseInfoLength = 0;
    Srb->SenseInfoOffset = 0;

    if (Buffer) {
        Srb->DataIn = SCSI_IOCTL_DATA_IN;
        Srb->DataTransferLength = BufferLength;
        Srb->DataBufferOffset = (ULONG_PTR) Buffer;
        ioctl = IOCTL_SCSI_PASS_THROUGH_DIRECT;
    } else {
        Srb->DataIn = SCSI_IOCTL_DATA_OUT;
        Srb->DataTransferLength = 0;
        Srb->DataBufferOffset = 0;
        ioctl = IOCTL_SCSI_PASS_THROUGH;
    }

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoBuildDeviceIoControlRequest(ioctl, Extension->TargetDeviceObject,
                                        Srb, sizeof(SCSI_PASS_THROUGH),
                                        Srb, sizeof(SCSI_PASS_THROUGH),
                                        FALSE, &event, &ioStatus);
    if (!irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = IoCallDriver(Extension->TargetDeviceObject, irp);
    if (status == STATUS_PENDING) {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = ioStatus.Status;
    }

    return status;
}

NTSTATUS
    CdAudioAddDevice(
                    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;
    PDEVICE_OBJECT              deviceObject;
    PCD_DEVICE_EXTENSION        extension;
    ULONG                       regActive = CDAUDIO_SEARCH_ACTIVE;

    //
    // Use registry to potentially not load onto stack
    //

    {
        HANDLE                      deviceParameterHandle;
        RTL_QUERY_REGISTRY_TABLE    queryTable[2];

        //
        // See if key exists and is readable.
        //

        status = IoOpenDeviceRegistryKey(PhysicalDeviceObject,
                                         PLUGPLAY_REGKEY_DRIVER,
                                         KEY_READ,
                                         &deviceParameterHandle);

        if (!NT_SUCCESS(status)) {

            //
            // Pnp keys should always exist and be system-readable
            //

            CdDump((0, "AddDevice !! Registry key DNE?! %lx\n", status));

            ASSERT(FALSE);

            regActive = CDAUDIO_SEARCH_ACTIVE;
            goto AddDeviceEndRegistry;
        }

        //
        // Zero out the memory
        //

        RtlZeroMemory(&queryTable, sizeof(queryTable));

        //
        // Setup the structure for the read call
        //

        queryTable->Flags         =
            RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
        queryTable->Name          = CDAUDIO_ACTIVE_KEY_NAME;
        queryTable->EntryContext  = &regActive;
        queryTable->DefaultType   = REG_DWORD;
        queryTable->DefaultData   = NULL;
        queryTable->DefaultLength = 0;

        //
        // Get the value in regActive (using queryTable)
        //

        status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
                                        (PWSTR)deviceParameterHandle,
                                        queryTable,
                                        NULL,
                                        NULL);

        //
        // Check for failure...
        //

        if (!NT_SUCCESS(status)) {

            //
            // This is normal, as the key does not exist the first
            // time the system loads the driver for the device.
            //

            CdDump(( 2,
                     "AddDevice !! Read value, status %lx\n",
                     status));
            regActive = CDAUDIO_SEARCH_ACTIVE;

        } else if (regActive > CDAUDIO_MAX_ACTIVE) {

            //
            // The registry value has either been corrupted, or manually
            // set to CDAUDIO_SEARCH_ACTIVE.  Either way, the driver will
            // search for drive type later.
            //

            CdDump(( 2,
                     "AddDevice !! Need to search, value %x\n",
                     regActive));
            regActive = CDAUDIO_SEARCH_ACTIVE;

        } else {

            //
            // We read a valid value, which will override the mapping type.
            //

            CdDump(( 2,
                     "AddDevice => Read value %x\n",
                     regActive));

        }

        //
        // close the handle
        //

        ZwClose(deviceParameterHandle);

    } // Finished registry handling

    AddDeviceEndRegistry:

    //
    // We forcibly set to within these bounds above
    //

    if (( regActive >  CDAUDIO_MAX_ACTIVE ) &&
        ( regActive != CDAUDIO_SEARCH_ACTIVE )) {
        CdDump((0,
                "AddDevice => Invalid registry value for "
                "maptype %x, resetting\n",
                regActive
                ));
        regActive = CDAUDIO_SEARCH_ACTIVE;
    }



    CdDump((1,
            "AddDevice => Active == %x\n",
            regActive));

    //
    // The system will remove us from memory if we don't call IoCreateDevice
    //

    if (regActive == CDAUDIO_NOT_ACTIVE) {
        CdDump((2,
                "AddDevice => Not attaching for pdo %p\n",
                PhysicalDeviceObject
                ));
        return STATUS_SUCCESS;
    }

    //
    // Map support section into non-paged pool
    //

    switch (regActive) {

⌨️ 快捷键说明

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