📄 vaporcd.c
字号:
case IOCTL_CDROM_RAW_READ:
VaporCDLogS("Ignoring: IOCTL_CDROM_RAW_READ");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
break;
//
// We need to return the drive geomotry that we have saved in the file.
//
case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
VaporCDLogS("IOCTL_CDROM_GET_DRIVE_GEOMETRY");
{
ULONG length = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
LARGE_INTEGER track;
track = RtlConvertUlongToLargeInteger(1024);
if ( length >= sizeof( DISK_GEOMETRY ) )
{
length = sizeof( DISK_GEOMETRY );
if (FILE_FORMAT_ISO == diskExtension->DataFormat)
{
VaporCDFillGeometry((DISK_GEOMETRY *) Irp->AssociatedIrp.SystemBuffer);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = length;
break;
}else
{
if (NT_SUCCESS(
VaporCDReadOffset(
&track,Irp->AssociatedIrp.SystemBuffer,length,
&diskExtension->DataFileName)
))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = length;
break;
}else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
break;
}
}
}
}
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
case IOCTL_CDROM_READ_TOC:
VaporCDLogS("IOCTL_CDROM_READ_TOC");
//*********
// Irp->IoStatus.Information = 0;
// Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
// break;
//*********
{
// PDISK_GEOMETRY outputBuffer;
ULONG length = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
LARGE_INTEGER track;
track = RtlConvertUlongToLargeInteger(2*1024);
if ( length >= sizeof( CDROM_TOC ) )
{
length = sizeof( CDROM_TOC );
if (FILE_FORMAT_ISO == diskExtension->DataFormat)
{
VaporCDFillToc((CDROM_TOC *) Irp->AssociatedIrp.SystemBuffer);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = length;
break;
}else
{
if (NT_SUCCESS(VaporCDReadOffset(&track,Irp->AssociatedIrp.SystemBuffer,length,&diskExtension->DataFileName)))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = length;
break;
}else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
break;
}
}
}
}
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
case IOCTL_CDROM_GET_LAST_SESSION:
VaporCDLogS("IOCTL_CDROM_GET_LAST_SESSION");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
break;
case IOCTL_CDROM_GET_VOLUME:
VaporCDLogS("IOCTL_CDROM_GET_VOLUME");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
break;
case IOCTL_CDROM_READ_Q_CHANNEL:
VaporCDLogS("IOCTL_CDROM_READ_Q_CHANNEL");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
break;
// ioctls that we just need to return success codes
case IOCTL_STORAGE_FIND_NEW_DEVICES:
case IOCTL_CDROM_SEEK_AUDIO_MSF:
case IOCTL_CDROM_PLAY_AUDIO_MSF:
case IOCTL_CDROM_SET_VOLUME:
case IOCTL_CDROM_STOP_AUDIO:
case IOCTL_CDROM_PAUSE_AUDIO:
case IOCTL_CDROM_RESUME_AUDIO:
case IOCTL_STORAGE_EJECT_MEDIA:
case IOCTL_CDROM_EJECT_MEDIA: // <==== old
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
// special debug ctrl code to add a device
case IOCTL_VAPORCD_ADD_DEVICE:
{
VaporCDLogS("-----Adding Device in responce to IOCTL-----");
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
sizeof(VAPORCD_ADD_DEVICE))
{
UNICODE_STRING driveLetterString;
UNICODE_STRING imagePathString;
WCHAR letterBuf[10];
VAPORCD_ADD_DEVICE * fdp;
fdp = (VAPORCD_ADD_DEVICE *)Irp->UserBuffer;
// Force the drive letter to be A-Z caps only.
if (fdp->wcDriveLetter < L'A' || fdp->wcDriveLetter > L'Z')
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
}
// init the drive letter string
letterBuf[0] = fdp->wcDriveLetter;
driveLetterString.Buffer = letterBuf;
driveLetterString.Length = 1 * sizeof (WCHAR);
driveLetterString.MaximumLength = 9 * sizeof (WCHAR);
RtlAppendUnicodeToString(&driveLetterString, L":");
// init the path string
fdp->szFileName[499] = L'\0'; // cap the end to prevent overflow
RtlInitUnicodeString( &imagePathString, fdp->szFileName);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = VaporCDInitializeVolumes(
DeviceObject->DriverObject, NULL,&driveLetterString,
&imagePathString, TRUE);
break;
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
break;
}
// special ctrl code to remove device
case IOCTL_VAPORCD_REMOVE_DEVICE:
{
VaporCDLogS("-----Unloading Device in responce to IOCTL-----");
// we need to delete only this one device that we are in now
if (diskExtension != NULL)
{
if (diskExtension->Win32NameString.Buffer != NULL)
{
IoDeleteSymbolicLink( &diskExtension->Win32NameString );
ExFreePool( diskExtension->Win32NameString.Buffer );
}
}
if (diskExtension != NULL)
IoDeleteDevice( diskExtension->DeviceObject );
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
case IOCTL_VAPORCD_GET_VERSION:
{
ULONG *pVersionNum;
// if they want the version number
VaporCDLogSL("IOCTL_VAPORCD_GET_VERSION: sizeof(ULONG)=",
sizeof(ULONG));
VaporCDLogSL("IOCTL_VAPORCD_GET_VERSION: VAPOR_CD_VERSION_NUMBER=",
VAPOR_CD_VERSION_NUMBER);
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG))
{
pVersionNum = (PULONG)Irp->AssociatedIrp.SystemBuffer;
*pVersionNum = VAPOR_CD_VERSION_NUMBER;
Irp->IoStatus.Information = sizeof(ULONG);
Irp->IoStatus.Status = STATUS_SUCCESS;
}else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
}
}
break;
default:
//
// The specified I/O control code is unrecognized by this driver.
// The I/O status field in the IRP has already been set so just
// terminate the switch.
//
{
VaporCDLogSL("ERROR: unrecognized IOCTL ",
irpSp->Parameters.DeviceIoControl.IoControlCode);
break;
}
}
//
// Finish the I/O operation by simply completing the packet and returning
// the same status as in the packet itself.
//
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return ntStatus;
}
NTSTATUS
VaporCDReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called by the I/O system to read or write to a
device that we control. It can also be called by
VaporCDDispatchDeviceControl() to do a VERIFY.
Arguments:
DeviceObject - a pointer to the object that represents the device
that I/O is to be done on.
Irp - a pointer to the I/O Request Packet for this request.
Return Value:
STATUS_INVALID_PARAMETER if parameters are invalid,
STATUS_SUCCESS otherwise.
--*/
{
PVAPORCD_EXTENSION diskExtension;
PIO_STACK_LOCATION irpSp;
PUCHAR CurrentAddress;
NTSTATUS status;
//
// Set up necessary object and extension pointers.
//
diskExtension = DeviceObject->DeviceExtension;
irpSp = IoGetCurrentIrpStackLocation( Irp );
//
// Check for invalid parameters. It is an error for the starting offset
// + length to go past the end of the buffer, or for the length to
// not be a proper multiple of the sector size.
//
// Others are possible, but we don't check them since we trust the
// file system and they aren't deadly.
//
//
// Get a system-space pointer to the user's buffer. A system
// address must be used because we may already have left the
// original caller's address space.
//
if ( Irp->MdlAddress != NULL )
{
CurrentAddress = MmGetSystemAddressForMdl( Irp->MdlAddress );
}
else
{
//
// Strictly speaking this isn't necessary, the only time we
// won't have an MDL is if we're processing IOCTL_DISK_VERIFY.
// In which case, we don't reference CurrentAddress. But at
// least this should keep the compiler from warning us.
CurrentAddress = 0;
}
VaporCDLogSL("RAMDISK: Irp of Request: 0x",(ULONG)Irp);
VaporCDLogSL(" Vmem Address of Transfer: 0x",(ULONG)CurrentAddress);
VaporCDLogSL(" - 0x",(ULONG)((PUCHAR)CurrentAddress) + irpSp->Parameters.Read.Length);
VaporCDLogSL(" Length of Transfer: 0x",(ULONG)irpSp->Parameters.Read.Length);
VaporCDLogSL(" Operation: 0x",(ULONG)irpSp->MajorFunction);
VaporCDLogSL(" Starting ByteOffset: 0x",(ULONG)irpSp->Parameters.Read.ByteOffset.LowPart);
// Irp->IoStatus.Information = irpSp->Parameters.Read.Length;
switch (irpSp->MajorFunction)
{
case IRP_MJ_READ:
{
// try to read the data from the file!!!
ULONG length = irpSp->Parameters.Read.Length;
LARGE_INTEGER track;
ULONG ulOffset;
// FILE_FORMAT_ISO or FILE_FORMAT_VAPOR_CD
if (FILE_FORMAT_ISO == diskExtension->DataFormat)
{
VaporCDLogS("Reading with ISO Format offset 0");
ulOffset = 0;
}else
{
VaporCDLogS("Reading with VaporCD Format offset 64k");
ulOffset = 64*1024;
}
VaporCDLogPU(&diskExtension->DataFileName);
VaporCDLogSL("ulOffset = ",ulOffset);
track = RtlLargeIntegerAdd(
RtlConvertUlongToLargeInteger(ulOffset), // this is the offset to get past the header
irpSp->Parameters.Read.ByteOffset);
if (NT_SUCCESS(VaporCDReadOffset(&track,CurrentAddress,length, &diskExtension->DataFileName)))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = length;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
}
// if there is an error we want to return not ready
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_DEVICE_NOT_READY;
case IRP_MJ_DEVICE_CONTROL:
//
// The only way we can get this major code is if the VERIFY
// ioctl called VaporCDDispatchReadWrite().
//
break;
default:
Irp->IoStatus.Information = 0;
break;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
VOID
VaporCDUnloadDriver(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This routine is called by the I/O system to unload the driver.
Any resources previously allocated must be freed.
Arguments:
DriverObject - a pointer to the object that represents our driver.
Return Value:
None
--*/
{
PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
VaporCDLogS("-----Unloading Driver-----");
// we need to delete all the devices that this driver has created
while ( deviceObject != NULL )
{
PVAPORCD_EXTENSION diskExtension = deviceObject->DeviceExtension;
if (diskExtension != NULL)
{
if (diskExtension->Win32NameString.Buffer != NULL)
{
IoDeleteSymbolicLink( &diskExtension->Win32NameString );
ExFreePool( diskExtension->Win32NameString.Buffer );
}
}
deviceObject = deviceObject->NextDevice;
if (diskExtension != NULL)
IoDeleteDevice( diskExtension->DeviceObject );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -