📄 cdaudio.c
字号:
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 + -