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

📄 cdaudio.c

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

    case CDAUDIO_NEC:
        MmLockPagableCodeSection((PVOID)CdAudioNECDeviceControl);
        break;

    case CDAUDIO_PIONEER:
    case CDAUDIO_PIONEER624:
        MmLockPagableCodeSection((PVOID)CdAudioPioneerDeviceControl);
        break;

    case CDAUDIO_DENON:
        MmLockPagableCodeSection((PVOID)CdAudioDenonDeviceControl);
        break;

    case CDAUDIO_HITACHI:
    case CDAUDIO_FUJITSU:
        MmLockPagableCodeSection((PVOID)CdAudioHitachiDeviceControl);
        break;

    case CDAUDIO_CDS535:
        MmLockPagableCodeSection((PVOID)CdAudio535DeviceControl);
        break;

    case CDAUDIO_CDS435:
        MmLockPagableCodeSection((PVOID)CdAudio435DeviceControl);
        break;

    case CDAUDIO_ATAPI:
        MmLockPagableCodeSection((PVOID)CdAudioAtapiDeviceControl);
        break;

    case CDAUDIO_HPCDR:
        MmLockPagableCodeSection((PVOID)CdAudioHPCdrDeviceControl);
        break;

    case CDAUDIO_SEARCH_ACTIVE:
    default:
        break;
    }

    //
    // Create the devObj so we are used
    //

    status = IoCreateDevice(DriverObject, sizeof(CD_DEVICE_EXTENSION),
                            NULL, FILE_DEVICE_CD_ROM, 0, FALSE, &deviceObject);

    if (!NT_SUCCESS(status)) {

        CdDump(( 0,
                 "AddDevice !! Unable to create device %lx\n",
                 status
                 ));

        // LOGLOG

        return status;
    }

    //
    // Set device object flags, device extension
    //

    deviceObject->Flags |= DO_DIRECT_IO;

    if (deviceObject->Flags & DO_POWER_INRUSH) {
        CdDump((0,
                "AddDevice ?? DO_POWER_INRUSH set for DO %p\n",
                deviceObject
                ));
    } else {
        deviceObject->Flags |= DO_POWER_PAGABLE;
    }


    extension = deviceObject->DeviceExtension;
    RtlZeroMemory(extension, sizeof(CD_DEVICE_EXTENSION));

    //
    // Useful to have next lower driver
    //

    extension->TargetDeviceObject =
        IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);

    if (!extension->TargetDeviceObject) {

        CdDump(( 0,
                 "AddDevice !! Unable to attach to device stack %lx\n",
                 STATUS_NO_SUCH_DEVICE
                 ));

        // LOGLOG

        IoDeleteDevice(deviceObject);
        return STATUS_NO_SUCH_DEVICE;
    }

    KeInitializeEvent(&extension->PagingPathCountEvent, SynchronizationEvent, TRUE);

    //
    // Must set Active flag, Pdo
    //

    extension->Active       = (UCHAR)regActive;
    extension->DeviceObject = deviceObject;
    extension->TargetPdo    = PhysicalDeviceObject;

    //
    // No longer initializing
    //

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;
}

NTSTATUS
    CdAudioSignalCompletion(
                           IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp,
                           IN PKEVENT Event
                           )

/*++

Routine Description:

    This completion routine will signal the event given as context and then
    return STATUS_MORE_PROCESSING_REQUIRED to stop event completion.  It is
    the responsibility of the routine waiting on the event to complete the
    request and free the event.

Arguments:

    DeviceObject - a pointer to the device object

    Irp - a pointer to the irp

    Event - a pointer to the event to signal

Return Value:

    STATUS_MORE_PROCESSING_REQUIRED

--*/

{
    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS
    CdAudioStartDevice(
                      IN  PDEVICE_OBJECT  DeviceObject,
                      IN  PIRP            Irp
                      )

/*++

Routine Description:

    Dispatch for START DEVICE.

Arguments:

    DeviceObject    - Supplies the device object.

    Irp             - Supplies the I/O request packet.

Return Value:

    NTSTATUS

--*/

{
    PCD_DEVICE_EXTENSION     deviceExtension = DeviceObject->DeviceExtension;
    NTSTATUS                 status;
    KEVENT                   event;

#if DBG
    UCHAR string[17];
#endif

    CdDump((2, "StartDevice => Entering.\n"));

    status = CdAudioForwardIrpSynchronous(DeviceObject, Irp);

    if (!NT_SUCCESS(status)) {

        // LOGLOG - Should put some message into the system log

        return status;
    }

    ///
    /// From this point forward, not matter what occurs, we should
    /// return STATUS_SUCCESS.  The rest of the code is non-critical,
    /// and the worst occurance is that audio will not play on a CDROM.
    ///

    CdDump((2, "StartDevice => Starting\n"));

    //
    // Initialize device extension data
    //

    deviceExtension->Paused = CDAUDIO_NOT_PAUSED;
    deviceExtension->PausedM  = 0;
    deviceExtension->PausedS  = 0;
    deviceExtension->PausedF  = 0;
    deviceExtension->LastEndM = 0;
    deviceExtension->LastEndS = 0;
    deviceExtension->LastEndF = 0;

    //
    // deviceExtension->Active possibly set from registry in AddDevice
    //

    ASSERT(deviceExtension->Active > 0);
    ASSERT((deviceExtension->Active <= CDAUDIO_MAX_ACTIVE) ||
           (deviceExtension->Active == CDAUDIO_SEARCH_ACTIVE));

    //
    // Search for the type of translation via the inquiry data
    // if registry value DNE or says to.  Otherwise, use the
    // registry value (gotten in CdAudioAddDevice) as the Active Value
    //

    if (deviceExtension->Active == (UCHAR)CDAUDIO_SEARCH_ACTIVE) {

        SCSI_PASS_THROUGH        srb;
        PCDB                     cdb = (PCDB) srb.Cdb;
        PUCHAR                   inquiryDataPtr = NULL;
        UCHAR                    attempt = 0;

        CdDump(( 1,
                 "StartDevice => Searching for map type via InquiryData\n"
                 ));

        //
        // Allocate buffer for returned inquiry data
        //

        inquiryDataPtr = (PUCHAR)ExAllocatePool( NonPagedPoolCacheAligned,
                                                 INQUIRYDATABUFFERSIZE
                                               );
        if (!inquiryDataPtr) {
            CdDump(( 0,
                     "StartDevice !! Insufficient resources for inquiry data\n"
                     ));
            deviceExtension->Active = CDAUDIO_NOT_ACTIVE;
            // LOGLOG
            return STATUS_SUCCESS;
        }

        //
        // Force it into the loop
        //
        status = STATUS_UNSUCCESSFUL;

        CdDump(( 4,
                 "StartDevice => Inquiry Data at %p\n",
                 inquiryDataPtr
                 ));

        //
        // Try to get inquiry data a few times
        //
        while (
               !(NT_SUCCESS(status)) &&
               (attempt++ < MAXIMUM_RETRIES)
               ) {
            CdDump(( 1,
                     "StartDevice => Inquiry attempt %d\n",
                     attempt
                     ));

            //
            // Zero SRB (including cdb)
            //

            RtlZeroMemory( &srb, sizeof(SCSI_PASS_THROUGH) );

            //
            // Just for safety, zero the inquiryDataPtr
            //

            RtlZeroMemory( inquiryDataPtr, INQUIRYDATABUFFERSIZE );

            //
            // Fill in CDB for INQUIRY to CDROM
            //

            cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
            cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;


            //
            // Inquiry length is 6, with timeout
            //

            srb.CdbLength = 6;
            srb.TimeOutValue = AUDIO_TIMEOUT;

            status = SendSrbSynchronous( deviceExtension,
                                         &srb,
                                         inquiryDataPtr,
                                         INQUIRYDATABUFFERSIZE
                                       );
            CdDump(( 2,
                     "StartDevice => Inquiry status for attempt %d is %lx\n",
                     attempt,
                     status
                     ));
        }

        //
        // So if it failed a bunch of times....
        //
        if (!NT_SUCCESS(status)) {

            CdDump(( 1, "StartDevice !! Inquiry failed! %lx\n", status ));
            ExFreePool( inquiryDataPtr );

            // LOGLOG

            //
            // Do not translate any commands if we cannot determine
            // the drive type.  Better to lose audio than to lose
            // data functionality.
            //

            deviceExtension->Active = CDAUDIO_NOT_ACTIVE;
            return STATUS_SUCCESS;
        }

#if DBG
        RtlZeroMemory( string, 17 );
        RtlCopyMemory( string, &(inquiryDataPtr[8]), 8 );
        CdDump((2, "StartDevice => Vendor '%s'\n", string));
        RtlZeroMemory( string, 17 );
        RtlCopyMemory( string, &(inquiryDataPtr[16]), 16 );
        CdDump((2, "StartDevice => Drive '%s'\n", string));
#endif


        //
        // Conduct a search by the inquiry data
        //

        {
            //
            // Set the default value to NONE (not SEARCH_ACTIVE)
            //

            deviceExtension->Active = CDAUDIO_NOT_ACTIVE;

            //
            // Check for NEC drive
            //

            if ( RtlEqualMemory( &(inquiryDataPtr[8]), "NEC     ", 8 )) {
                if (NecSupportNeeded(inquiryDataPtr)) {
                    MmLockPagableCodeSection((PVOID)CdAudioNECDeviceControl);
                    deviceExtension->Active = CDAUDIO_NEC;
                }
            }

            //
            // Check for PIONEER DRM-600 and DRM-600x drives
            //

            if ( (RtlEqualMemory( &(inquiryDataPtr[8]), "PIONEER ", 8 )) &&
                 (RtlEqualMemory( &(inquiryDataPtr[16]), "CD-ROM DRM-600", 15 ))
                 ) {
                MmLockPagableCodeSection((PVOID)CdAudioPioneerDeviceControl);
                deviceExtension->Active = CDAUDIO_PIONEER;
            }

            //
            // Check for DENON drive
            //

            if ((inquiryDataPtr[8] =='D') &&
                (inquiryDataPtr[9] =='E') &&
                (inquiryDataPtr[10]=='N') &&
                (inquiryDataPtr[16]=='D') &&
                (inquiryDataPtr[17]=='R') &&
                (inquiryDataPtr[18]=='D') &&
                (inquiryDataPtr[20]=='2') &&
                (inquiryDataPtr[21]=='5') &&
                (inquiryDataPtr[22]=='X')) {
                MmLockPagableCodeSection((PVOID)CdAudioDenonDeviceControl);
                deviceExtension->Active = CDAUDIO_DENON;
            }

            if ( RtlEqualMemory( &(inquiryDataPtr[8]), "CHINON", 6 )) {

                //
                // Check for Chinon CDS-535
                //

                if ((inquiryDataPtr[27]=='5') &&
                    (inquiryDataPtr[28]=='3') &&
                    (inquiryDataPtr[29]=='5') &&
                    (inquiryDataPtr[32]=='Q')
                    ) {
                    MmLockPagableCodeSection((PVOID)CdAudio535DeviceControl);
                    deviceExtension->Active = CDAUDIO_CDS535;
                }

                //
                // Check for Chinon CDS-435 or CDS-431
                //  (willing to handle versions M/N, S/U, and H)
                //

                if ((inquiryDataPtr[27]=='4') &&
                    (inquiryDataPtr[28]=='3') &&
                    ((inquiryDataPtr[29]=='5') ||
                     (inquiryDataPtr[29]=='1')
                     )                        &&
                    ((inquiryDataPtr[32]=='M') ||
                     (inquiryDataPtr[32]=='N') ||
                     (inquiryDataPtr[32]=='S') ||
                     (inquiryDataPtr[32]=='U') ||
                     (inquiryDataPtr[32]=='H')
                     )
                    ) {
                    MmLockPagableCodeSection((PVOID)CdAudio435DeviceControl);
                    deviceExtension->Active = CDAUDIO_CDS435;
                }

                //
                // End of the Chinon drives
                //
            }


            //
            // Check for HITACHI drives
            //

            if ( (RtlEqualMemory( &(inquiryDataPtr[8]), "HITACHI ", 8 )) &&
                 ( (RtlEqualMemory( &(inquiryDataPtr[16]), "CDR-3650/1650S  ", 16 )) ||
                   (RtlEqualMemory( &(inquiryDataPtr[16]), "CDR-1750S       ", 16 ))
                   )
                 ) {
                MmLockPagableCodeSection((PVOID)CdAudioHitachiDeviceControl);
                deviceExtension->Active = CDAUDIO_HITACHI;
            }

            //
            // Check for Atapi drives that require support.
            //

⌨️ 快捷键说明

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