📄 vcdrom.c
字号:
PDEVICE_OBJECT device_object;
PDEVICE_EXTENSION device_extension;
int size = 0;
status = STATUS_SUCCESS;
device_object = NULL;
g_nVCDRomCount = 0;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VCDRomCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VCDRomCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VCDRomCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = VCDRomRead;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VCDRomDeviceControl;
DriverObject->DriverUnload = VCDRomUnload;
RtlInitUnicodeString(&device_name, DEVICE_DIR_NAME);
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&device_name,
FILE_DEVICE_CD_ROM, //0x02
FILE_REMOVABLE_MEDIA | FILE_READ_ONLY_DEVICE, //0x03
FALSE,
&device_object
);
if (!NT_SUCCESS(status))
{
device_object = NULL;
return status;
}
InitDeviceExtension(device_object);
device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
AllocateUnicodeString(
MAX_NAME_LENGTH,
&device_extension->SymbolicLinkName
);
//"\\??\\VirtualCdRom"
RtlAppendUnicodeToString(
&device_extension->SymbolicLinkName,
L"\\??" DEVICE_BASE_NAME
);
status = IoCreateSymbolicLink(
&device_extension->SymbolicLinkName,
&device_name
);
if (NT_SUCCESS(status))
{
ExInitializeFastMutex(&g_VCDRomFastMutex);
VCDRomQueryDevice(DriverObject, RegistryPath->Buffer);
}
if (!NT_SUCCESS(status) && device_object != NULL)
{
IoDeleteDevice(device_object);
}
return status;
}
#pragma code_seg("PAGE")
VOID
VCDRomUnload (
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT device_object, NextObject;
IRP Irp;
PAGED_CODE();
device_object = DriverObject->DeviceObject;
while (device_object)
{
NextObject = device_object->NextDevice;
VCDRomDeleteDevice(device_object, &Irp);
device_object = NextObject;
}
}
NTSTATUS
VCDRomDeleteDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION device_extension;
PAGED_CODE();
ASSERT(DeviceObject != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
status = IoDeleteSymbolicLink(&device_extension->SymbolicLinkName);
FreeUnicodeString(&device_extension->SymbolicLinkName);
if (device_extension->FileObject != NULL)
{
ObfDereferenceObject(device_extension->FileObject);
device_extension->FileObject = NULL;
}
FreeUnicodeString(&device_extension->FileName);
IoDeleteDevice(DeviceObject);
return IoCommonComplete(status, 0, Irp);
}
NTSTATUS
VCDRomCreateClose (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PAGED_CODE();
IoCommonComplete(0, 0, Irp);
IoCompleteRequest(Irp, IO_CD_ROM_INCREMENT); //0x01
return STATUS_SUCCESS;
}
NTSTATUS
VCDRomSetHardErrorOrVerifyDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
DeviceObject->Flags |= DO_VERIFY_VOLUME; //0x02
Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
Irp->IoStatus.Information = 0;
IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
return STATUS_VERIFY_REQUIRED; //0x80000016
}
NTSTATUS
VCDRomCallDriver(
IN PFILE_OBJECT FileObject,
IN PMDL MdlAddress,
IN PLARGE_INTEGER pByteOffset,
IN PKEVENT request_event,
IN ULONG Length,
IN PIO_STATUS_BLOCK IoStatus
)
{
NTSTATUS status;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
PIO_STACK_LOCATION io_stack;
status = STATUS_SUCCESS;
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (Irp == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
Irp->RequestorMode = KernelMode;
Irp->UserIosb = IoStatus;
Irp->UserEvent = request_event;
Irp->MdlAddress = MdlAddress;
Irp->Flags = IRP_INPUT_OPERATION | IRP_PAGING_IO | IRP_NOCACHE; //0x43
Irp->UserBuffer = (PUCHAR)MdlAddress->StartVa + MdlAddress->ByteOffset;
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
io_stack = IoGetNextIrpStackLocation(Irp);
io_stack->Parameters.Read.Length = Length;
io_stack->Parameters.Read.ByteOffset = *pByteOffset;
io_stack->MajorFunction = IRP_MJ_READ;
io_stack->FileObject = FileObject;
return IoCallDriver(DeviceObject, Irp);
}
#pragma code_seg()
NTSTATUS
VCDRomRead (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION device_extension;
PIO_STACK_LOCATION io_stack;
ULONG Length;
PLARGE_INTEGER pByteOffset;
KEVENT request_event;
IO_STATUS_BLOCK IoStatus;
ULONG StartSector, MdlFlags, Number1;
PUCHAR Buffer;
PMDL MdlAddress;
#define VCDROM_MDL_FLAGS (MDL_MAPPED_TO_SYSTEM_VA | MDL_PAGES_LOCKED | MDL_ALLOCATED_FIXED_SIZE)
status = STATUS_INVALID_PARAMETER;
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (device_extension->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)
{
status = VCDRomSetHardErrorOrVerifyDevice(DeviceObject, Irp);
IoCompleteRequest(Irp, IO_CD_ROM_INCREMENT);
return status;
}
Length = io_stack->Parameters.Read.Length;
pByteOffset = &io_stack->Parameters.Read.ByteOffset;
if (Length > Irp->MdlAddress->ByteCount)
{
return IoCommonComplete(STATUS_BUFFER_TOO_SMALL, 0, Irp);
}
KeInitializeEvent(
&request_event,
NotificationEvent, //0x00
FALSE
);
status = VCDRomCallDriver(
device_extension->FileObject,
Irp->MdlAddress,
pByteOffset,
&request_event,
Length,
&IoStatus);
if (!NT_SUCCESS(status))
{
status = IoCommonComplete(status, 0, Irp);
IoCompleteRequest(Irp, IO_CD_ROM_INCREMENT);
return status;
}
status = KeWaitForSingleObject(
&request_event,
Executive,
KernelMode,
FALSE,
NULL
);
if (!NT_SUCCESS(status))
{
status = IoCommonComplete(status, 0, Irp);
IoCompleteRequest(Irp, IO_CD_ROM_INCREMENT);
return status;
}
StartSector = (ULONG)(pByteOffset->QuadPart / device_extension->BytesPerSector);
MdlAddress = Irp->MdlAddress;
MdlFlags = MdlAddress->MdlFlags;
Number1 = 0x0B;
if (StartSector > 0x20)
{
status = IoCommonComplete(status, Length, Irp);
IoCompleteRequest(Irp, IO_CD_ROM_INCREMENT);
return status;
}
Buffer = (PUCHAR)MdlAddress->StartVa + MdlAddress->ByteOffset;
if ((MdlFlags & VCDROM_MDL_FLAGS) == VCDROM_MDL_FLAGS &&
(device_extension->Flags & 1) != 0 &&
Buffer != NULL &&
Buffer[0] == 0x00 &&
Buffer[1] == 0x4E &&
Buffer[2] == 0x53 &&
Buffer[3] == 0x52 &&
Buffer[4] == 0x30)
{
Buffer[5] = 0x30;
}
if (StartSector <= 0x20 &&
(MdlFlags & VCDROM_MDL_FLAGS) == VCDROM_MDL_FLAGS &&
(device_extension->Flags & 2) != 0 &&
Buffer != NULL &&
Buffer[0] == 0x02 &&
Buffer[1] == 0x43 &&
Buffer[2] == 0x44 &&
Buffer[3] == 0x30 &&
Buffer[4] == 0x30 &&
Buffer[5] == 0x31)
{
Buffer[5] = 0x30;
}
status = IoCommonComplete(status, Length, Irp);
IoCompleteRequest(Irp, IO_CD_ROM_INCREMENT);
return status;
}
NTSTATUS
VCDRomCheckVerify(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION io_stack;
ULONG Length;
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 IoCommonComplete(STATUS_VERIFY_REQUIRED, 0, Irp);
}
if (Irp->AssociatedIrp.SystemBuffer != NULL)
{
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&DeviceExtension->Used,
sizeof(DeviceExtension->Used));
Length = sizeof(DeviceExtension->Used);
}
else
{
Length = 0;
}
return IoCommonComplete(STATUS_SUCCESS, Length, Irp);
}
NTSTATUS
VCDRomDeviceNotReady(
IN PDEVICE_OBJECT DeviceObject,
IN PUNICODE_STRING FileName,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
status = STATUS_DEVICE_NOT_READY;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
if (DeviceExtension->FileObject == NULL)
{
status = VCDRomCreateFile(DeviceObject, FileName);
}
return IoCommonComplete(status, 0, Irp);
}
NTSTATUS
VCDRomEjectMedia(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION DeviceExtension;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
DeviceObject->Flags |= DO_VERIFY_VOLUME; //0x02
if (DeviceExtension->FileObject != NULL)
{
ObfDereferenceObject(DeviceExtension->FileObject);
DeviceExtension->Used++;
DeviceExtension->FileObject = NULL;
}
return IoCommonComplete(STATUS_SUCCESS, 0, Irp);
}
NTSTATUS
VCDRomLoadMedia(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
UNICODE_STRING FileName;
status = STATUS_SUCCESS;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
status = AllocateUnicodeString(
DeviceExtension->FileName.MaximumLength,
&FileName
);
if (!NT_SUCCESS(status))
{
return status;
}
RtlCopyUnicodeString(
&FileName,
&DeviceExtension->FileName
);
status = VCDRomDeviceNotReady(
DeviceObject,
&FileName,
Irp
);
FreeUnicodeString(&FileName);
return IoCommonComplete(status, 0, Irp);
}
NTSTATUS
VCDRomGetDriveGeometry(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION io_stack;
PDISK_GEOMETRY disk_geometry;
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(DISK_GEOMETRY))
{
return IoCommonComplete(STATUS_BUFFER_TOO_SMALL,
sizeof(DISK_GEOMETRY),
Irp);
}
disk_geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
disk_geometry->Cylinders.QuadPart = 1;
disk_geometry->MediaType = FixedMedia;
disk_geometry->TracksPerCylinder = 1;
disk_geometry->SectorsPerTrack =
(ULONG)(DeviceExtension->EndOfFile.QuadPart >> DeviceExtension->ShiftBits);
disk_geometry->BytesPerSector = DeviceExtension->BytesPerSector;
return IoCommonComplete(STATUS_SUCCESS, sizeof(DISK_GEOMETRY), Irp);
}
ULONG
VCDRomTrackDataAddress(IN ULONG InData)
{
UCHAR ucBuff[4];
RtlZeroMemory(ucBuff, sizeof(ucBuff));
ucBuff[0] = 0;
ucBuff[1] = (UCHAR)(InData / 0x1194);
ucBuff[2] = (UCHAR)((InData - (ucBuff[1] * 0x1194)) / 0x4B);
ucBuff[3] = (UCHAR)(((ucBuff[1] * 0x6C) - (ucBuff[2] * 0x4B)) + (InData & 0xFF));
return *((ULONG *)ucBuff);
}
VOID
VCDRomGetTrackData(
IN PTRACK_DATA pTrackData,
IN ULONG Control,
IN ULONG Adr,
IN ULONG TrackNumber,
IN ULONG AddressData)
{
pTrackData->Reserved = 0;
pTrackData->Reserved1 = 0;
pTrackData->Control = (UCHAR)Control;
pTrackData->Adr = (UCHAR)Adr;
pTrackData->TrackNumber = (UCHAR)TrackNumber;
*((ULONG *)pTrackData->Address) = VCDRomTrackDataAddress(AddressData);
}
NTSTATUS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -