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

📄 vcdrom.c

📁 微软 发布的 虚拟光驱工具 带 c原代码 效果可以。
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -