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

📄 irp.c

📁 使用DELPHI制作地虚拟光驱
💻 C
字号:
#include <ntddk.h>
#include <ntdef.h>
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <ntddcdvd.h>
#include <ntverp.h>
#include <stdio.h>
#include <ntifs.h>
#include <DeviceThread.h>
#include <VCD.h>

//////////////////////////////////////////////////////////////////////////


PDEVICE_OBJECT
CDROMDeleteDevice (
				   IN PDEVICE_OBJECT DeviceObject
				   )
{
	PDEVICE_EXTENSION   device_extension;
	PDEVICE_OBJECT      next_device_object;

	DbgPrint("CDROMDeleteDevice\n");

	ASSERT(DeviceObject != NULL);

	device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

	device_extension->terminate_thread = TRUE;

	KeSetEvent(
		&device_extension->k_event,
		(KPRIORITY) 0,
		FALSE
		);

	KeWaitForSingleObject(
		device_extension->thread_pointer,
		Executive,
		KernelMode,
		FALSE,
		NULL
		);

	ObDereferenceObject(device_extension->thread_pointer);

	if (device_extension->security_client_context != NULL)
	{
		SeDeleteClientSecurity(device_extension->security_client_context);
		ExFreePool(device_extension->security_client_context);
	}

	next_device_object = DeviceObject->NextDevice;

	IoDeleteDevice(DeviceObject);

	return next_device_object;
}
//////////////////////////////////////////////////////////////////////////

VOID
IrpUnload (
		   IN PDRIVER_OBJECT DriverObject
		   )
{
	PDEVICE_OBJECT device_object;

	DbgPrint("IrpUnload\n"); 

	device_object = DriverObject->DeviceObject;

	while (device_object)
	{
		device_object = CDROMDeleteDevice(device_object);
	}
	ZwClose(device_root_handle);
}

NTSTATUS
IrpCreateClose (
				IN PDEVICE_OBJECT   DeviceObject,
				IN PIRP             Irp
				)
{
	DbgPrint("IrpCreateClose\n");
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = FILE_OPENED;

	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}

NTSTATUS
IrpReadWrite (
			  IN PDEVICE_OBJECT   DeviceObject,
			  IN PIRP             Irp
			  )
{
	PDEVICE_EXTENSION   device_extension;
	PIO_STACK_LOCATION  io_stack;

	DbgPrint("IrpReadWrite\n");

	device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

	//如果没有媒体在光驱中就结束
	if (!device_extension->media_in_device)
	{
		Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
		Irp->IoStatus.Information = 0;

		IoCompleteRequest(Irp, IO_NO_INCREMENT);

		return STATUS_NO_MEDIA_IN_DEVICE;
	}

	io_stack = IoGetCurrentIrpStackLocation(Irp);
    //如果长度=0 
	if (io_stack->Parameters.Read.Length == 0)
	{
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = 0;

		IoCompleteRequest(Irp, IO_NO_INCREMENT);

		return STATUS_SUCCESS;
	}

	IoMarkIrpPending(Irp);

	ExInterlockedInsertTailList(
		&device_extension->list_head,
		&Irp->Tail.Overlay.ListEntry,
		&device_extension->list_lock
		);
    //触发事件
	KeSetEvent(
		&device_extension->k_event,
		(KPRIORITY) 0,
		FALSE
		);

	return STATUS_PENDING;
}

NTSTATUS
IrpDeviceControl (
					   IN PDEVICE_OBJECT   DeviceObject,
					   IN PIRP             Irp
					   )
{
	PDEVICE_EXTENSION   device_extension;
	PIO_STACK_LOCATION  io_stack;
	NTSTATUS            status;


	DbgPrint("IrpDeviceControl\n");

	device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

	io_stack = IoGetCurrentIrpStackLocation(Irp);

	//如果没有媒体,并且不是'打开文件'或者'查询设备'信息的请求就不处理
	if ((!device_extension->media_in_device) &&
		(io_stack->Parameters.DeviceIoControl.IoControlCode !=IOCTL_VCD_OPEN_FILE)&&
		(io_stack->Parameters.DeviceIoControl.IoControlCode !=IOCTL_VCD_QUERY_DEVICE))
	{
		Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
		Irp->IoStatus.Information = 0;

		IoCompleteRequest(Irp, IO_NO_INCREMENT);

		return STATUS_NO_MEDIA_IN_DEVICE;
	}
    
	//处理请求
	switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
	{
    //打开
	case IOCTL_VCD_OPEN_FILE:
		{
			SECURITY_QUALITY_OF_SERVICE security_quality_of_service;
            DbgPrint("IOCTL_VCD_OPEN_FILE\n");  
			//如果有媒体
			if (device_extension->media_in_device)
			{

				status = STATUS_INVALID_DEVICE_REQUEST;
				Irp->IoStatus.Information = 0;
				DbgPrint("里面有光盘!\n");
				break;
			}
            //如果参数不够长
			if (io_stack->Parameters.DeviceIoControl.InputBufferLength < MAX_PATH)
			{
				status = STATUS_INVALID_PARAMETER;
				Irp->IoStatus.Information = 0;
				DbgPrint("缓冲区不够长!\n");
				break;
			}
            
			//客户端安全的上下文
			if (device_extension->security_client_context != NULL)
			{
                DbgPrint("去掉客户端安全上下文!\n");
				SeDeleteClientSecurity(device_extension->security_client_context);
			}
			else
			{
				DbgPrint("创建客户端安全上下文!\n");
				device_extension->security_client_context =
				   ExAllocatePool(NonPagedPool, sizeof(SECURITY_CLIENT_CONTEXT));
			}

			RtlZeroMemory(&security_quality_of_service, sizeof(SECURITY_QUALITY_OF_SERVICE));

			security_quality_of_service.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
			security_quality_of_service.ImpersonationLevel = SecurityImpersonation;
			security_quality_of_service.ContextTrackingMode = SECURITY_STATIC_TRACKING;
			security_quality_of_service.EffectiveOnly = FALSE;

			SeCreateClientSecurity(
				PsGetCurrentThread(),
				&security_quality_of_service,
				FALSE,
				device_extension->security_client_context
				);

			IoMarkIrpPending(Irp);

			ExInterlockedInsertTailList(
				&device_extension->list_head,
				&Irp->Tail.Overlay.ListEntry,
				&device_extension->list_lock
				);

			KeSetEvent(
				&device_extension->k_event,
				(KPRIORITY) 0,
				FALSE
				);

			status = STATUS_PENDING;

			break;
		}
    //如果是关闭文件  
	case IOCTL_VCD_CLOSE_FILE:
		{
			DbgPrint("IOCTL_VCD_CLOSE_FILE\n"); 
			IoMarkIrpPending(Irp);

			ExInterlockedInsertTailList(
				&device_extension->list_head,
				&Irp->Tail.Overlay.ListEntry,
				&device_extension->list_lock
				);

			KeSetEvent(
				&device_extension->k_event,
				(KPRIORITY) 0,
				FALSE
				);

			status = STATUS_PENDING;

			break;
		}
    //查询设备信息
    case IOCTL_VCD_QUERY_DEVICE:
		{
		    PVCD_DEVICE_INFORMATION  vcd_device_information;

			DbgPrint("IOCTL_VCD_QUERY_DEVICE\n"); 
			if (io_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VCD_DEVICE_INFORMATION))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				Irp->IoStatus.Information = 0;
				break;
			}
            vcd_device_information = (PVCD_DEVICE_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
            RtlZeroMemory(vcd_device_information, sizeof(VCD_DEVICE_INFORMATION));
			vcd_device_information->Magic    = DEVICE_MAGIC;
			vcd_device_information->Version  = DEVICE_VERSION;
			vcd_device_information->Index    = device_extension->index;
			vcd_device_information->MediaIn  = device_extension->media_in_device;
			if(vcd_device_information->MediaIn)
			{
			   RtlCopyMemory(vcd_device_information->FileName, device_extension->oldfile_name, MAX_PATH);
			}
			sprintf(vcd_device_information->Descaption,"虚拟光驱设备\r厂家:王锐 wr960204\rEmail: wr960204@126.com\r QQ:42088303"); 
            
			status = STATUS_SUCCESS;
			Irp->IoStatus.Information = sizeof(VCD_DEVICE_INFORMATION);

			break;
		} 
	//case IOCTL_DISK_CHECK_VERIFY:
	case IOCTL_CDROM_CHECK_VERIFY:
	case IOCTL_STORAGE_CHECK_VERIFY:
	case IOCTL_STORAGE_CHECK_VERIFY2:
		{
			DbgPrint("IOCTL_CDROM_CHECK_VERIFY\n");
			status = STATUS_SUCCESS;
			Irp->IoStatus.Information = 0;
			break;
		}
    //得到光盘物理属性 
	//case IOCTL_DISK_GET_DRIVE_GEOMETRY:
	case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
		{
			PDISK_GEOMETRY  disk_geometry;
			ULONGLONG       length;

			DbgPrint("IOCTL_DISK_GET_DRIVE_GEOMETRY\n");

			if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
				sizeof(DISK_GEOMETRY))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				Irp->IoStatus.Information = 0;
				break;
			}

			disk_geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;

			length = device_extension->file_size.QuadPart;

			disk_geometry->Cylinders.QuadPart = length / SECTOR_SIZE / 32 / 2;
			disk_geometry->MediaType = FixedMedia;
			disk_geometry->TracksPerCylinder = 2;
			disk_geometry->SectorsPerTrack = 32;
			disk_geometry->BytesPerSector = SECTOR_SIZE;

			status = STATUS_SUCCESS;
			Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);

			break;
		}
    //是否可写
	case IOCTL_DISK_IS_WRITABLE:
		{
			DbgPrint("IOCTL_DISK_IS_WRITABLE\n");
		    status = STATUS_MEDIA_WRITE_PROTECTED;
    		Irp->IoStatus.Information = 0;
			break;
		}
    //媒体移走 
	//case IOCTL_DISK_MEDIA_REMOVAL:
	case IOCTL_STORAGE_MEDIA_REMOVAL:
		{
			DbgPrint("IOCTL_DISK_MEDIA_REMOVAL\n");
			status = STATUS_SUCCESS;
			Irp->IoStatus.Information = 0;
			break;
		}
    //获取光盘的内容表
	case IOCTL_CDROM_READ_TOC:
		{
			PCDROM_TOC cdrom_toc;

			DbgPrint("IOCTL_CDROM_READ_TOC\n");
			if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
				sizeof(CDROM_TOC))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				Irp->IoStatus.Information = 0;
				break;
			}

			cdrom_toc = (PCDROM_TOC) Irp->AssociatedIrp.SystemBuffer;

			RtlZeroMemory(cdrom_toc, sizeof(CDROM_TOC));

			cdrom_toc->FirstTrack = 1;
			cdrom_toc->LastTrack = 1;
			cdrom_toc->TrackData[0].Control = TOC_DATA_TRACK;

			status = STATUS_SUCCESS;
			Irp->IoStatus.Information = sizeof(CDROM_TOC);

			break;
		}
	default:
		{
			DbgPrint(
				"未知 IoControlCode %#x\n",
				io_stack->Parameters.DeviceIoControl.IoControlCode
				);

			status = STATUS_INVALID_DEVICE_REQUEST;
			Irp->IoStatus.Information = 0;
		}
	}

	if (status != STATUS_PENDING)
	{
		Irp->IoStatus.Status = status;

		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	}

	return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -