📄 vcdrom.c
字号:
VCDRomReadToc(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION io_stack;
PCDROM_TOC cdrom_toc;
status = STATUS_SUCCESS;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (DeviceExtension->FileObject == NULL)
{
return IoCommonComplete(STATUS_NO_MEDIA_IN_DEVICE, 0, Irp);
}
if ((DeviceObject->Flags & DO_VERIFY_VOLUME) != 0 &&
(io_stack->Flags & SL_OVERRIDE_VERIFY_VOLUME) == 0)
{
return VCDRomSetHardErrorOrVerifyDevice(DeviceObject, Irp);
}
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(CDROM_TOC))
{
return IoCommonComplete(STATUS_BUFFER_TOO_SMALL,
sizeof(CDROM_TOC),
Irp);
}
cdrom_toc = (PCDROM_TOC) Irp->AssociatedIrp.SystemBuffer;
//RtlZeroMemory(cdrom_toc, sizeof(CDROM_TOC));
cdrom_toc->Length[0] = 0;
cdrom_toc->Length[1] = 8;
cdrom_toc->FirstTrack = 1;
cdrom_toc->LastTrack = 1;
VCDRomGetTrackData(&cdrom_toc->TrackData[0],
TOC_DATA_TRACK,
0,
1,
0x96
);
VCDRomGetTrackData(&cdrom_toc->TrackData[1],
TOC_DATA_TRACK,
0,
0xAA,
0x96 + (ULONG)(DeviceExtension->EndOfFile.QuadPart >> DeviceExtension->ShiftBits)
);
return IoCommonComplete(STATUS_SUCCESS, sizeof(CDROM_TOC), Irp);
}
NTSTATUS
VCDRomReadTocEx(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION io_stack;
PCDROM_READ_TOC_EX inputBuffer;
PCDROM_TOC cdrom_toc;
status = STATUS_SUCCESS;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (DeviceExtension->FileObject == NULL)
{
return IoCommonComplete(STATUS_NO_MEDIA_IN_DEVICE, 0, Irp);
}
if ((DeviceObject->Flags & DO_VERIFY_VOLUME) != 0 &&
(io_stack->Flags & SL_OVERRIDE_VERIFY_VOLUME) == 0)
{
return VCDRomSetHardErrorOrVerifyDevice(DeviceObject, Irp);
}
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(CDROM_READ_TOC_EX))
{
return IoCommonComplete(STATUS_INFO_LENGTH_MISMATCH,
sizeof(CDROM_READ_TOC_EX),
Irp);
}
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(CDROM_TOC))
{
return IoCommonComplete(STATUS_BUFFER_TOO_SMALL,
sizeof(CDROM_TOC),
Irp);
}
inputBuffer = (PCDROM_READ_TOC_EX) Irp->AssociatedIrp.SystemBuffer;
if ((inputBuffer->Reserved1 != 0) ||
(inputBuffer->Reserved2 != 0) ||
(inputBuffer->Reserved3 != 0))
{
return IoCommonComplete(STATUS_INVALID_PARAMETER, 0, Irp);
}
//
// NOTE: when adding new formats, ensure that first two bytes
// specify the amount of additional data available.
//
if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_TOC ) ||
(inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_FULL_TOC) ||
(inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_CDTEXT ))
{
// SessionTrack field is used
}
else
if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_SESSION) ||
(inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_PMA) ||
(inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_ATIP))
{
// SessionTrack field is reserved
if (inputBuffer->SessionTrack != 0)
{
return IoCommonComplete(STATUS_INVALID_PARAMETER, 0, Irp);
}
}
else
{
return IoCommonComplete(STATUS_INVALID_PARAMETER, 0, Irp);
}
if (inputBuffer->Msf != 1)
{
return IoCommonComplete(STATUS_INVALID_PARAMETER, 0, Irp);
}
cdrom_toc = (PCDROM_TOC) Irp->AssociatedIrp.SystemBuffer;
//RtlZeroMemory(cdrom_toc, sizeof(CDROM_TOC));
cdrom_toc->Length[0] = 0;
cdrom_toc->Length[1] = 8;
cdrom_toc->FirstTrack = 1;
cdrom_toc->LastTrack = 1;
VCDRomGetTrackData(&cdrom_toc->TrackData[0],
TOC_DATA_TRACK,
0,
1,
0x96
);
VCDRomGetTrackData(&cdrom_toc->TrackData[1],
TOC_DATA_TRACK,
0,
0xAA,
0x96 + (ULONG)(DeviceExtension->EndOfFile.QuadPart >> DeviceExtension->ShiftBits)
);
return IoCommonComplete(STATUS_SUCCESS, sizeof(CDROM_TOC), Irp);
}
NTSTATUS
VCDRomGetLastSession(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION io_stack;
PCDROM_TOC_SESSION_DATA SessionData;
status = STATUS_SUCCESS;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (DeviceExtension->FileObject == NULL)
{
return IoCommonComplete(STATUS_NO_MEDIA_IN_DEVICE, 0, Irp);
}
if ((DeviceObject->Flags & DO_VERIFY_VOLUME) != 0 &&
(io_stack->Flags & SL_OVERRIDE_VERIFY_VOLUME) == 0)
{
return VCDRomSetHardErrorOrVerifyDevice(DeviceObject, Irp);
}
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(CDROM_TOC_SESSION_DATA))
{
return IoCommonComplete(STATUS_BUFFER_TOO_SMALL,
sizeof(CDROM_TOC_SESSION_DATA),
Irp);
}
SessionData = (PCDROM_TOC_SESSION_DATA) Irp->AssociatedIrp.SystemBuffer;
RtlZeroMemory(SessionData, sizeof(CDROM_TOC_SESSION_DATA));
SessionData->Length[0] = 0;
SessionData->Length[1] = 8;
SessionData->FirstCompleteSession = 1;
SessionData->LastCompleteSession = 1;
VCDRomGetTrackData(SessionData->TrackData,
TOC_DATA_TRACK,
0,
1,
0x96
);
return IoCommonComplete(STATUS_SUCCESS,
sizeof(CDROM_TOC_SESSION_DATA),
Irp);
}
NTSTATUS
VCDRomGetFileName(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION io_stack;
PVCDROM_OPEN_FILE pData;
status = STATUS_SUCCESS;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(VCDROM_OPEN_FILE))
{
return IoCommonComplete(STATUS_BUFFER_TOO_SMALL,
sizeof(VCDROM_OPEN_FILE),
Irp);
}
pData = (PVCDROM_OPEN_FILE) Irp->AssociatedIrp.SystemBuffer;
pData->Opened = (DeviceExtension->FileObject != NULL) ? 1 : 0;
if (DeviceExtension->FileName.Length == 0)
{
pData->NameLength = 0;
}
else
{
pData->NameLength = DeviceExtension->FileName.Length;
RtlCopyMemory(
pData->outputName,
DeviceExtension->FileName.Buffer,
DeviceExtension->FileName.Length
);
}
return IoCommonComplete(STATUS_SUCCESS, sizeof(VCDROM_OPEN_FILE), Irp);
}
NTSTATUS
VCDRomIoControlCreate(
IN PDRIVER_OBJECT DriverObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION io_stack;
PVCDROM_OPEN_FILE pData;
status = STATUS_SUCCESS;
DeviceObject = NULL;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(WCHAR))
{
status = STATUS_BUFFER_TOO_SMALL;
}
else
{
status = VCDRomCreateDevice(DriverObject,
'Z',
(PWSTR)Irp->AssociatedIrp.SystemBuffer,
&DeviceObject);
}
return IoCommonComplete(status, sizeof(WCHAR), Irp);
}
NTSTATUS
VCDRomCompareMemory(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_OBJECT TempDevice;
PDEVICE_EXTENSION DeviceExtension, TempExtension;
PIO_STACK_LOCATION io_stack;
PVCDROM_OPEN_DRIVE pData;
status = STATUS_SUCCESS;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength >
sizeof(VCDROM_OPEN_DRIVE))
{
return IoCommonComplete(STATUS_BUFFER_TOO_SMALL,
sizeof(VCDROM_OPEN_DRIVE),
Irp);
}
pData = (PVCDROM_OPEN_DRIVE) Irp->AssociatedIrp.SystemBuffer;
pData->Index = 0;
TempDevice = DeviceObject->DriverObject->DeviceObject;
for (; TempDevice != NULL; TempDevice = TempDevice->NextDevice)
{
ULONG Size;
PWSTR Buffer;
TempExtension = (PDEVICE_EXTENSION) TempDevice->DeviceExtension;
Size = RtlCompareMemory(
TempExtension->SymbolicLinkName.Buffer,
L"\\??" DEVICE_BASE_NAME,
TempExtension->SymbolicLinkName.Length);
if (Size != TempExtension->SymbolicLinkName.Length)
{
Buffer = TempExtension->SymbolicLinkName.Buffer;
pData->DriveBuffer[pData->Index] = Buffer[4];
pData->Index++;
}
}
return IoCommonComplete(STATUS_SUCCESS, sizeof(VCDROM_OPEN_DRIVE), Irp);
}
NTSTATUS
VCDRomDeviceControl (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PIO_STACK_LOCATION io_stack;
NTSTATUS status;
ULONG IoControlCode;
BOOLEAN bHasError;
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
IoControlCode = io_stack->Parameters.DeviceIoControl.IoControlCode;
switch (IoControlCode)
{
case IOCTL_DISK_CHECK_VERIFY: //0x74800
case IOCTL_CDROM_CHECK_VERIFY: //0x24800
case IOCTL_STORAGE_CHECK_VERIFY: //0x2D4800
//case IOCTL_STORAGE_CHECK_VERIFY2:
{
status = VCDRomCheckVerify(DeviceObject, Irp);
break;
}
case IOCTL_CDROM_EJECT_MEDIA: //0x24808
case IOCTL_STORAGE_EJECT_MEDIA: //0x2D4808
{
status = VCDRomEjectMedia(DeviceObject, Irp);
break;
}
case IOCTL_CDROM_LOAD_MEDIA: //0x2480C
case IOCTL_STORAGE_LOAD_MEDIA: //0x2D480C
{
if (device_extension->FileName.Buffer != NULL &&
device_extension->FileObject == NULL)
{
status = VCDRomLoadMedia(DeviceObject, Irp);
}
else
{
status = STATUS_SUCCESS;
IoCommonComplete(STATUS_SUCCESS, 0, Irp);
}
break;
}
case 0x4D004: //IOCTL_SCSI_PASS_THROUGH: //0x4D004
{
status = IoCommonComplete(STATUS_INVALID_DEVICE_REQUEST, 0, Irp);
break;
}
case IOCTL_DISK_GET_DRIVE_GEOMETRY: //0x70000
case IOCTL_CDROM_GET_DRIVE_GEOMETRY: //0x2404C
{
status = VCDRomGetDriveGeometry(DeviceObject, Irp);
break;
}
case IOCTL_CDROM_READ_TOC: //0x24000
{
status = VCDRomReadToc(DeviceObject, Irp);
break;
}
case IOCTL_CDROM_GET_LAST_SESSION: //0x24038
{
status = VCDRomGetLastSession(DeviceObject, Irp);
break;
}
case IOCTL_CDROM_READ_TOC_EX: //0x24054
{
status = VCDRomReadTocEx(DeviceObject, Irp);
break;
}
case 0x23310: //0x23310
{
status = VCDRomGetFileName(DeviceObject, Irp);
break;
}
case 0x23300: //0x23300
{
status = VCDRomIoControlCreate(DeviceObject->DriverObject, Irp);
break;
}
case 0x23304: //0x23304
{
status = VCDRomDeleteDevice(DeviceObject, Irp);
break;
}
case 0x23308: //0x23308
{
UNICODE_STRING FileName;
PVCDROM_OPEN_FILE pData;
pData = (PVCDROM_OPEN_FILE) Irp->AssociatedIrp.SystemBuffer;
FileName.Length = pData->NameLength;
FileName.MaximumLength = 0xFF;
FileName.Buffer = pData->outputName;
status = VCDRomDeviceNotReady(DeviceObject, &FileName, Irp);
break;
}
case 0x2330C: //0x2330C
{
status = VCDRomCompareMemory(DeviceObject, Irp);
break;
}
default:
{
KdPrint((
"VCDRom: Unknown IoControlCode %#x\n", IoControlCode
));
status = IoCommonComplete(
STATUS_INVALID_DEVICE_REQUEST,
0,
Irp
);
}
}
if (!NT_SUCCESS(status))
{
if (status == STATUS_DEVICE_NOT_READY ||
status == STATUS_IO_TIMEOUT ||
status == STATUS_MEDIA_WRITE_PROTECTED ||
status == STATUS_NO_MEDIA_IN_DEVICE ||
status == STATUS_VERIFY_REQUIRED ||
status == STATUS_UNRECOGNIZED_MEDIA ||
status == STATUS_WRONG_VOLUME)
{
bHasError = TRUE;
}
else
{
bHasError = FALSE;
}
if (bHasError)
{
IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
}
}
IoCompleteRequest(Irp, IO_CD_ROM_INCREMENT);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -