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

📄 vcdrom.c

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