📄 irp.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 + -