📄 speedcd.c
字号:
SPEEDCDInitializeVolumes(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING ParamPath,
IN PUNICODE_STRING DriveLetterString, // "Z:"
IN PUNICODE_STRING ImagePathString, // Kernel mode full file path
IN BOOLEAN bDoDiveceInitializing
)
/*++
Routine Description:
This routine is called each time a new cd image is mounted. It may be called
at initiliazation or later.
It creates and initializes a device object for the disk.
Two parameters may be configured using the registry. DiskSize specifies
the desired size (in bytes). If the requested memory is not available in
the nonpaged pool then STATUS_INSUFFICIENT_RESOURCES is returned. The
default value is 0x00100000 (1MB).
DriveLetter is used to indicate the drive letter for the SPEEDCD. The
string must be a letter, optionally followed by :.
Arguments:
DriverObject - a pointer to the object that represents this device
driver.
ParamPath - a pointer to the Parameters key under our key in the Services
section of the registry.
Return Value:
STATUS_SUCCESS if this disk is initialized; an error otherwise.
--*/
{
UNICODE_STRING Win32PathString; // Win32 Name "\DosDevices\Z:"
UNICODE_STRING KernelPrefix; // Win32 Name "\DosDevices\Z:"
UNICODE_STRING fileExtString;
UNICODE_STRING fileExtString1;
WCHAR fileExtBuffer1[100];
PDEVICE_OBJECT deviceObject = NULL; // ptr to device object
PSPEEDCD_EXTENSION diskExtension = NULL; // ptr to device extension
NTSTATUS ntStatus;
// kernel device name like "\\Device\\xxFakeCD0"
UNICODE_STRING deviceString;
WCHAR deviceBuffer[100];
UNICODE_STRING cdromNumString;
WCHAR cdromNumBuffer[20];
LONG DeviceNumOffset;
int iType;
// get the number of the cdrom device
PCONFIGURATION_INFORMATION pConfigInfo;
pConfigInfo = IoGetConfigurationInformation();
// name for the kernel device object for this drive
RtlInitUnicodeString( &deviceString,NULL);
deviceString.Buffer = deviceBuffer;
deviceString.MaximumLength = sizeof(WCHAR) * 99;
RtlInitUnicodeString( &cdromNumString,NULL);
cdromNumString.Buffer = cdromNumBuffer;
cdromNumString.MaximumLength = sizeof(WCHAR) * 19;
RtlAppendUnicodeToString(&deviceString, L"\\Device\\SPEEDCD");
if (DriveLetterString == NULL)
{
DeviceNumOffset = -1;
iType = FILE_DEVICE_UNKNOWN;
}
else
{
DeviceNumOffset = DriveLetterString->Buffer[0]- 'A';
RtlIntegerToUnicodeString(DeviceNumOffset,10,&cdromNumString);
RtlAppendUnicodeStringToString(&deviceString, &cdromNumString);
iType = FILE_DEVICE_SPEEDCD;
}
// now the device name should have the correct number on the end of it.
ntStatus = IoCreateDevice(
DriverObject, // Our Driver Object
sizeof( RAMDISK_EXTENSION ), // Size of state information
&deviceString, // Device name "\Device\SPEEDCD"
iType, // Device type
/*FILE_REMOVABLE_MEDIA|*/FILE_READ_ONLY_DEVICE,// Device characteristics
FALSE, // Exclusive device
&deviceObject ); // Returned ptr to Device Object
if ( !NT_SUCCESS( ntStatus ) )
{
SPEEDCDLogS("Couldn't create the device object");
goto SPEEDCDInitializeDiskExit;
}
//
// Initialize device object and extension.
//
deviceObject->Flags |= DO_DIRECT_IO;
deviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
diskExtension = (PSPEEDCD_EXTENSION)deviceObject->DeviceExtension;
RtlInitUnicodeString( &diskExtension->Win32NameString, NULL );
//
// Allocate and initialize a Unicode String containing the Win32 name
// for our device.
//
RtlInitUnicodeString( &Win32PathString, WIN32_PATH );
diskExtension->Win32NameString.Buffer = ExAllocatePool(
PagedPool,
sizeof(WIN32_PATH) + 30 * sizeof(WCHAR) );
if (!diskExtension->Win32NameString.Buffer) {
SPEEDCDDump(
RAMDERRORS,
("RAMDISK: Couldn't allocate buffer for the symbolic link\n")
);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto SPEEDCDInitializeDiskExit;
}
diskExtension->Win32NameString.MaximumLength = sizeof(WIN32_PATH) + sizeof(WCHAR)*29;
diskExtension->DeviceObject = deviceObject; //store a back pointer to the device object
RtlAppendUnicodeStringToString(
&diskExtension->Win32NameString, &Win32PathString );
if (!DriveLetterString)
{
RtlAppendUnicodeToString(&diskExtension->Win32NameString, L"SPEEDCD");
}else
{
RtlAppendUnicodeStringToString(
&diskExtension->Win32NameString, DriveLetterString );
}
//
// Create a symbolic link between our device name "\Device\SPEEDCD0" and
// the Win32 name (ie "\DosDevices\Z:").
//
ntStatus = IoCreateSymbolicLink(
&diskExtension->Win32NameString, &deviceString );
// save the path to the file for later use
diskExtension->DataFileName.Buffer = ExAllocatePool(PagedPool,500 * sizeof(WCHAR) );
if (!diskExtension->DataFileName.Buffer) {
SPEEDCDDump(
RAMDERRORS,
("SpeedCD: Couldn't allocate buffer for image name\n")
);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto SPEEDCDInitializeDiskExit;
}
diskExtension->DataFileName.MaximumLength = sizeof(WCHAR)*499;
diskExtension->DataFileName.Length = 0;
RtlInitUnicodeString( &KernelPrefix, L"\\??\\" );
RtlAppendUnicodeStringToString(&diskExtension->DataFileName, &KernelPrefix);
RtlAppendUnicodeStringToString(&diskExtension->DataFileName,ImagePathString);
//
// Set the Image type to the constant based on the extention.
//
RtlInitUnicodeString( &fileExtString, L".ISO");
RtlInitUnicodeString( &fileExtString1,
&(ImagePathString->Buffer[ ImagePathString->Length/sizeof(WCHAR)-4 ]));
if (RtlCompareUnicodeString(&fileExtString,&fileExtString1,TRUE) == 0)
{
SPEEDCDLogS("Setting Image Format to ISO");
diskExtension->DataFormat = FILE_FORMAT_ISO; // 0k For ISO standard format
}
else
{
SPEEDCDLogS("Setting Image Format to SPEEDCD");
diskExtension->DataFormat = FILE_FORMAT_SPEED_CD; // 64k for SPEEDCD format
}
SPEEDCDInitializeDiskExit:
if ( !NT_SUCCESS( ntStatus ) )
{
// Delete everything that this routine has allocated.
if ( deviceObject != NULL )
{
IoDeleteDevice( deviceObject );
}
}else
{
if(bDoDiveceInitializing)
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
return ntStatus;
}
NTSTATUS
SPEEDCDCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called by the I/O system when the SPEEDCD is opened or
closed.
No action is performed other than completing the request successfully.
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.
--*/
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
VOID SPEEDCDFillGeometry(PDISK_GEOMETRY pDG)
{
pDG->BytesPerSector = 0x800;
pDG->Cylinders.QuadPart = 0x92;
pDG->MediaType = RemovableMedia;
pDG->SectorsPerTrack = 0x20;
pDG->TracksPerCylinder = 0x40;
}
VOID SPEEDCDFillToc(CDROM_TOC *pToc)
{
pToc->Length[0] = 0;
pToc->Length[1] = 0x12;
pToc->FirstTrack = 1;
pToc->LastTrack = 1;
pToc->TrackData[0].Control = 0x4;
pToc->TrackData[0].Adr = 1;
pToc->TrackData[0].TrackNumber = 1;
pToc->TrackData[0].Address[0] = 0;
pToc->TrackData[0].Address[1] = 0;
pToc->TrackData[0].Address[2] = 2;
pToc->TrackData[0].Address[3] = 0;
pToc->TrackData[1].Control = 0x4;
pToc->TrackData[1].Adr = 1;
pToc->TrackData[1].TrackNumber = 0xaa;
pToc->TrackData[1].Address[0] = 0;
pToc->TrackData[1].Address[1] = 0x2e;
pToc->TrackData[1].Address[2] = 0x3b;
pToc->TrackData[1].Address[3] = 0x3a;
}
NTSTATUS
SPEEDCDDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called by the I/O system to perform a device I/O
control function.
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_SUCCESS if recognized I/O control code,
STATUS_INVALID_DEVICE_REQUEST otherwise.
--*/
{
PSPEEDCD_EXTENSION diskExtension;
PIO_STACK_LOCATION irpSp;
NTSTATUS ntStatus;
//
// Set up necessary object and extension pointers.
//
diskExtension = DeviceObject->DeviceExtension;
irpSp = IoGetCurrentIrpStackLocation( Irp );
//
// Assume failure.
//
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
//
// Determine which I/O control code was specified.
//
switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )
{
// stubs that take complex success :)
case IOCTL_CDROM_CHECK_VERIFY: // <==== old
case IOCTL_STORAGE_CHECK_VERIFY:
{
ULONG *pMediaChangeCount;
// if they want the media change count
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength !=0)
{
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG))
{
pMediaChangeCount = (PULONG)Irp->AssociatedIrp.SystemBuffer;
*pMediaChangeCount = 1;
Irp->IoStatus.Information = sizeof(ULONG);
Irp->IoStatus.Status = STATUS_SUCCESS;
}else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
}
}else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
}
// other codes that we don't want to see while we are debuging
// I get this one sometimes, but I don't know what to return!
case IOCTL_CDROM_DISK_TYPE:
SPEEDCDLogS("Ignoring: IOCTL_CDROM_DISK_TYPE");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
break;
// we get this code sometimes but don't want to see it in the debug popup
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
SPEEDCDLogS("Ignoring: IOCTL_DISK_GET_DRIVE_GEOMETRY");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
break;
//
// we need to say that the device does not handle this mode yet
//
case IOCTL_CDROM_RAW_READ:
SPEEDCDLogS("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:
SPEEDCDLogS("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)
{
SPEEDCDFillGeometry((DISK_GEOMETRY *) Irp->AssociatedIrp.SystemBuffer);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = length;
break;
}else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -