📄 cdaudio.c
字号:
/*++
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 = ®Active;
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 + -