⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vaporcd.c

📁 一个虚拟光驱程序(驱动程序和exe)-VaporCDSource141
💻 C
📖 第 1 页 / 共 3 页
字号:

	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 + -