#include
#define NTSTRSAFE_LIB
#include
#define COM_DRIVER_NAME L"\\Device\\Serial0" //要绑定的设备名
//延时用的
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
PDEVICE_OBJECT s_fltobj=NULL; //全局指针
PDEVICE_OBJECT s_nextobj=NULL; //全局指针
PDEVICE_OBJECT pCommunicate=NULL; //全局指针
UNICODE_STRING devicename; //定义一个字符串
UNICODE_STRING symboliclinkname; //定义一个字符串
void ccpUnload(PDRIVER_OBJECT drv); //动态卸载函数
NTSTATUS ccpAttachAllComs(PDRIVER_OBJECT driver); //绑定设备函数
NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp); //自定义IRP分发函数
NTSTATUS fengReadComplete(PDEVICE_OBJECT DeviectObject,PIRP Irp,PVOID Context); //IRP_MJ_READ回调函数
NTSTATUS CreateDevices(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath); //创建设备用于同ring3应用程序通信
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) //所有的驱动都是这个入口函数跟c语言的main函数一样
{
NTSTATUS status; //定义返回状态数据类型
size_t i;
status = CreateDevices(driver,reg_path);
if (status==STATUS_SUCCESS)
{
for(i=0;iMajorFunction[i] = ccpDispatch; //所有的分发函数都进入ccpDispatch这个函数里面去
}
driver->DriverUnload = ccpUnload; //支持动态卸载(=号后面是卸载函数)
ccpAttachAllComs(driver); //绑定设备
}
return STATUS_SUCCESS; //返回成功(STATUS_SUCCESS=成功的意思)
}
NTSTATUS CreateDevices(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{ //创建设备用于同ring3应用程序通信
NTSTATUS status;
RtlInitUnicodeString(&devicename,L"\\Device\\MyDevice"); //初始化设备名称
RtlInitUnicodeString(&symboliclinkname,L"\\??\\MyDeviceName"); //初始化符号连接名称
status = IoCreateDevice(DriverObject,0,&devicename,FILE_DEVICE_UNKNOWN,0,FALSE,&pCommunicate); //生成设备
if (status != STATUS_SUCCESS) //如果没有生成成功就返回
return status;
IoCreateSymbolicLink(&symboliclinkname,&devicename);//符号链接名称//设备名称
pCommunicate->Flags |= DO_BUFFERED_IO;
return status;
}
void ccpUnload(PDRIVER_OBJECT drv) //动态卸载函数
{
LARGE_INTEGER interval;
UNICODE_STRING uniNtNameString; //定义一个字符串
RtlInitUnicodeString(&uniNtNameString, COM_DRIVER_NAME); // 初始化一个字符串(就是COM驱动的名字)
IoDetachDevice(s_nextobj); // 首先解除绑定
interval.QuadPart = (2*1000 * DELAY_ONE_MILLISECOND); // 睡眠时间(2秒)
KeDelayExecutionThread(KernelMode,FALSE,&interval); //等待所有irp处理结束
IoDeleteDevice(s_fltobj); // 删除设备
IoDeleteDevice(pCommunicate); // 删除设备
}
NTSTATUS ccpAttachAllComs(PDRIVER_OBJECT driver) //绑定设备函数
{
NTSTATUS status; //定义返回状态数据类型
PFILE_OBJECT fileobj = NULL; //定义一个设备的文件对象指针
PDEVICE_OBJECT devobj = NULL; //定义一个设备对象指针
UNICODE_STRING uniNtNameString; //定义一个字符串
RtlInitUnicodeString(&uniNtNameString, COM_DRIVER_NAME); // 初始化一个字符串(就是COM驱动的名字)
status=IoGetDeviceObjectPointer(&uniNtNameString, FILE_ALL_ACCESS, &fileobj, &devobj); //根据设备名字获取设备对象
if(status == STATUS_SUCCESS) //如果获取设备对象成功
ObDereferenceObject(fileobj); //就取消设备的文件对象引用(因为过滤串口不需要文件对象)
status = IoCreateDevice(driver,0,NULL,devobj->DeviceType,0,FALSE,&s_fltobj); //生成设备
if (status != STATUS_SUCCESS) //如果没有生成设备就返回
return status;
// 拷贝重要标志位。
if(devobj->Flags & DO_BUFFERED_IO)
(s_fltobj)->Flags |= DO_BUFFERED_IO;
if(devobj->Flags & DO_DIRECT_IO)
(s_fltobj)->Flags |= DO_DIRECT_IO;
if(devobj->Flags & DO_BUFFERED_IO)
(s_fltobj)->Flags |= DO_BUFFERED_IO;
if(devobj->Characteristics & FILE_DEVICE_SECURE_OPEN)
(s_fltobj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
(s_fltobj)->Flags |= DO_POWER_PAGABLE;
s_nextobj = IoAttachDeviceToDeviceStack(s_fltobj,devobj); //绑定一个设备到另一个设备上
if (s_nextobj == NULL)
{
// 如果绑定失败了,销毁设备,重新来过。
IoDeleteDevice(s_fltobj);
s_fltobj = NULL;
return STATUS_UNSUCCESSFUL;
}
(s_fltobj)->Flags = (s_fltobj)->Flags & ~DO_DEVICE_INITIALIZING; //设置这个设备已经启动
return STATUS_SUCCESS;
}
NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp) //自定义IRP分发函数
{
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp); //获取当前栈空间
NTSTATUS status;
ULONG i;
if(s_fltobj== device)
{
if(irpsp->MajorFunction == IRP_MJ_POWER)
{
//如果是电源直接发送,然后返回说已经被处理了
PoStartNextPowerIrp(irp);
IoSkipCurrentIrpStackLocation(irp);
return PoCallDriver(s_nextobj,irp);
}
if(irpsp->MajorFunction == IRP_MJ_WRITE)
{
ULONG len = irpsp->Parameters.Write.Length; //获取写入数据的长度
PUCHAR buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer; //取得系统缓冲区数据
for(i=0;iMajorFunction == IRP_MJ_READ)
{
//因为读的是需要完成后才能得到,所以用回调函数来获取
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp, fengReadComplete, device, TRUE, TRUE, TRUE);
return IoCallDriver(s_nextobj,irp);
}
//其它请求直接下发(不禁止也不修改)
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(s_nextobj,irp);
}
if(pCommunicate== device)
{
if(irpsp->MajorFunction == IRP_MJ_POWER)
{
//如果是电源直接发送,然后返回说已经被处理了
PoStartNextPowerIrp(irp);
IoSkipCurrentIrpStackLocation(irp);
return PoCallDriver(pCommunicate->NextDevice,irp);
}
if(irpsp->MajorFunction == IRP_MJ_CREATE)
{
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(pCommunicate->NextDevice,irp);
}
if(irpsp->MajorFunction == IRP_MJ_CLOSE)
{
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(pCommunicate->NextDevice,irp);
}
//其它请求直接下发(不禁止也不修改)
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(pCommunicate->NextDevice,irp);
}
// 如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误。
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS fengReadComplete(PDEVICE_OBJECT DeviectObject,PIRP Irp,PVOID Context) //IRP_MJ_READ回调函数
{
PIO_STACK_LOCATION IrpSp;
ULONG i;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
if(NT_SUCCESS( Irp->IoStatus.Status)) //读成功才处理
{
PUCHAR buf = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; //取得系统缓冲区数据
for(i=0; iIoStatus.Information; i++)
{
DbgPrint("%02X, ", buf[i]);
}
}
if( Irp->PendingReturned)
IoMarkIrpPending( Irp);
return Irp->IoStatus.Status;
}
复制代码
改成这样直接蓝屏......why????