📄 cdaudio.c
字号:
if ( ((RtlEqualMemory( &(inquiryDataPtr[8]), "WEARNES ", 8 )) &&
(RtlEqualMemory( &(inquiryDataPtr[16]), "RUB", 3 ))
) ||
((RtlEqualMemory( &(inquiryDataPtr[8]), "OTI ", 8)) &&
(RtlEqualMemory( &(inquiryDataPtr[16]), "DOLPHIN ", 8))
)
) {
MmLockPagableCodeSection((PVOID)CdAudioAtapiDeviceControl);
deviceExtension->Active = CDAUDIO_ATAPI;
inquiryDataPtr[25] = (UCHAR)0;
}
//
// Check for FUJITSU drives
//
if (RtlEqualMemory( &(inquiryDataPtr[8]), "FUJITSU ", 8 )) {
//
// It's a Fujitsu drive...is it one we want to
// handle...?
if ((inquiryDataPtr[16]=='C') &&
(inquiryDataPtr[17]=='D') &&
(inquiryDataPtr[18]=='R') &&
(inquiryDataPtr[20]=='3') &&
(inquiryDataPtr[21]=='6') &&
(inquiryDataPtr[22]=='5') &&
(inquiryDataPtr[23]=='0')) {
//
// Yes, we want to handle this as HITACHI compatible drive
//
MmLockPagableCodeSection((PVOID)CdAudioHitachiDeviceControl);
deviceExtension->Active = CDAUDIO_HITACHI;
inquiryDataPtr[25] = (UCHAR)0;
} else if ((inquiryDataPtr[16]=='F') &&
(inquiryDataPtr[17]=='M') &&
(inquiryDataPtr[18]=='C') &&
(inquiryDataPtr[21]=='1') &&
(inquiryDataPtr[22]=='0') &&
((inquiryDataPtr[23]=='1') ||
(inquiryDataPtr[23]=='2')) ) {
//
// Yes, we want to handle this as FUJITSU drive
//
MmLockPagableCodeSection((PVOID)CdAudioHitachiDeviceControl);
deviceExtension->Active = CDAUDIO_FUJITSU;
inquiryDataPtr[25] = (UCHAR)0;
}
}
//
// Check for HP CDR
//
if ((RtlEqualMemory( &(inquiryDataPtr[8]), "HP ", 8 )) &&
(RtlEqualMemory( &(inquiryDataPtr[16]), "C4324/C4325", 11 ))
) {
MmLockPagableCodeSection((PVOID)CdAudioHPCdrDeviceControl);
deviceExtension->Active = CDAUDIO_HPCDR;
}
}
ExFreePool( inquiryDataPtr );
}
CdDump((2,
"StartDevice => Active is set to %x\n",
deviceExtension->Active));
//
// Store the value in the registry so the inquiry data does
// not have to be read and searched.
//
{
HANDLE deviceParameterHandle;
ULONG keyValue = (ULONG)deviceExtension->Active;
//
// Open a handle to the key
//
status = IoOpenDeviceRegistryKey(deviceExtension->TargetPdo,
PLUGPLAY_REGKEY_DRIVER,
KEY_WRITE,
&deviceParameterHandle);
if (!NT_SUCCESS(status)) {
CdDump(( 0,
"StartDevice !! Failed to open registry %lx\n",
status
));
// LOGLOG
//
// Handle not open, so just
//
return STATUS_SUCCESS;
}
//
// Write the value
//
status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE,
(PWSTR) deviceParameterHandle,
CDAUDIO_ACTIVE_KEY_NAME,
REG_DWORD,
&keyValue,
sizeof(keyValue));
if (!NT_SUCCESS(status)) {
//
// This is a non-fatal error, so just write to debugger?
//
CdDump(( 0,
"StartDevice !! Failed to write registry %lx\n",
status
));
// LOGLOG
//
// But fall through to close the handle to the registry
//
}
//
// Don't forget to close what we open...
//
ZwClose(deviceParameterHandle);
CdDump(( 2,
"StartDevice => Wrote value %x successfully\n",
deviceExtension->Active
));
}
return STATUS_SUCCESS;
}
NTSTATUS
CdAudioPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Dispatch for PNP
Arguments:
DeviceObject - Supplies the device object.
Irp - Supplies the I/O request packet.
Return Value:
NTSTATUS
--*/
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_NOT_SUPPORTED;
switch (irpSp->MinorFunction) {
case IRP_MN_START_DEVICE: {
status = CdAudioStartDevice(DeviceObject, Irp);
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
case IRP_MN_DEVICE_USAGE_NOTIFICATION: {
ULONG count;
BOOLEAN setPagable;
PCD_DEVICE_EXTENSION deviceExtension;
if (irpSp->Parameters.UsageNotification.Type != DeviceUsageTypePaging) {
return CdAudioSendToNextDriver(DeviceObject, Irp);
}
deviceExtension = DeviceObject->DeviceExtension;
//
// wait on the paging path event
//
status = KeWaitForSingleObject(&deviceExtension->PagingPathCountEvent,
Executive, KernelMode,
FALSE, NULL);
//
// if removing last paging device, need to clear DO_POWER_PAGABLE
// bit here, and possible re-set it below on failure.
//
setPagable = FALSE;
if (!irpSp->Parameters.UsageNotification.InPath &&
deviceExtension->PagingPathCount == 1 ) {
//
// removing the last paging file
// must have DO_POWER_PAGABLE bits set
//
if (DeviceObject->Flags & DO_POWER_INRUSH) {
CdDump((2, "Pnp: Last paging file removed "
"but DO_POWER_INRUSH set, so not setting PAGABLE bit "
"for DO %p\n", DeviceObject));
} else {
CdDump((2, "Pnp: Setting PAGABLE bit "
"for DO %p\n", DeviceObject));
DeviceObject->Flags |= DO_POWER_PAGABLE;
setPagable = TRUE;
}
}
//
// send the irp synchronously
//
status = CdAudioForwardIrpSynchronous(DeviceObject, Irp);
//
// now deal with the failure and success cases.
// note that we are not allowed to fail the irp
// once it is sent to the lower drivers.
//
if (NT_SUCCESS(status)) {
IoAdjustPagingPathCount(
&deviceExtension->PagingPathCount,
irpSp->Parameters.UsageNotification.InPath);
if (irpSp->Parameters.UsageNotification.InPath) {
if (deviceExtension->PagingPathCount == 1) {
CdDump((2, "Pnp: Clearing PAGABLE bit "
"for DO %p\n", DeviceObject));
DeviceObject->Flags &= ~DO_POWER_PAGABLE;
}
} // end InPath if/else
} else {
//
// cleanup the changes done above
//
if (setPagable == TRUE) {
CdDump((2, "Pnp: Un-setting pagable bit for DO %p\n", DeviceObject));
DeviceObject->Flags &= ~DO_POWER_PAGABLE;
setPagable = FALSE;
}
}
//
// set the event so the next one can occur.
//
KeSetEvent(&deviceExtension->PagingPathCountEvent,
IO_NO_INCREMENT, FALSE);
//
// and complete the irp
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
break;
}
default:
return CdAudioSendToNextDriver(DeviceObject, Irp);
}
}
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Initialize CdAudio driver.
This is the system initialization entry point
when the driver is linked into the kernel.
Arguments:
DriverObject
Return Value:
NTSTATUS
--*/
{
ULONG i;
//
// Send everything down unless specifically handled.
//
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = CdAudioSendToNextDriver;
}
DriverObject->MajorFunction[IRP_MJ_READ] = CdAudioReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = CdAudioReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CdAudioDeviceControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = CdAudioPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = CdAudioPower;
DriverObject->DriverExtension->AddDevice = CdAudioAddDevice;
DriverObject->DriverUnload = CdAudioUnload;
return STATUS_SUCCESS;
}
#define NEC_CDAUDIO_SUPPORT_DRIVES 12
BOOLEAN
NecSupportNeeded(
PUCHAR InquiryData
)
/*++
Routine Description:
This routine determines whether the NEC drive in question
needs assistance from this driver.
Arguments:
InquiryData - Pointer to the inquiry data buffer.
Return Value:
TRUE - if support is needed.
--*/
{
PINQUIRYDATA inquiryData = (PINQUIRYDATA)InquiryData;
ULONG i;
PUCHAR badDriveList[NEC_CDAUDIO_SUPPORT_DRIVES] = {
"CD-ROM DRIVE:80 ", // must be 16 byte long
"CD-ROM DRIVE:82 ",
"CD-ROM DRIVE:83 ",
"CD-ROM DRIVE:84 ",
"CD-ROM DRIVE:841",
"CD-ROM DRIVE:38 ",
"CD-ROM DRIVE 4 M",
"CD-ROM DRIVE:500",
"CD-ROM DRIVE:400",
"CD-ROM DRIVE:401",
"CD-ROM DRIVE:501",
"CD-ROM DRIVE:900"};
for (i = 0; i < NEC_CDAUDIO_SUPPORT_DRIVES; i++) {
if (RtlCompareMemory(inquiryData->ProductId, badDriveList[i], 16)==16) {
return TRUE;
}
}
return FALSE;
}
NTSTATUS
CdAudioReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the driver entry point for read and write requests
to the cdrom. Since we only want to trap device control requests,
we will just pass these requests on to the original driver.
Arguments:
DeviceObject - pointer to device object for disk partition
Irp - NT IO Request Packet
Return Value:
NTSTATUS - status of request
--*/
{
PCD_DEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
//
// If the cd is playing music then reject this request.
//
if (deviceExtension->PlayActive) {
Irp->IoStatus.Status = STATUS_DEVICE_BUSY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_DEVICE_BUSY;
}
//
// simply return status of driver below us...
//
return CdAudioSendToNextDriver(DeviceObject, Irp);
}
NTSTATUS
CdAudioDeviceControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
/*++
Routine Description:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -