Chinaunix首页 | 论坛 | 博客
  • 博客访问: 433211
  • 博文数量: 72
  • 博客积分: 1583
  • 博客等级: 上尉
  • 技术积分: 775
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-23 09:36
文章分类

全部博文(72)

文章存档

2011年(72)

我的朋友

分类: WINDOWS

2011-03-05 14:51:16

1)创建设备
NTSTATUS IoCreateDevice(
    DriverObject//驱动对象
    DeviceExtensionSize//可存储用户自定义的数据结构的size
    DeviceName//过滤设备一般可设为NULL
    DeviceType//与被绑定的设备类型相同(oldDevice->DeviceType)
    DeviceCharactersistics//先直接填0,然后看看是否排斥,选择FALSE(后面再复制)
    Exclusive
    DeviceObject//要生成的过滤设备
2)设备绑定
将过滤设备绑定到被过滤设备之上,如果这个设备上面已经绑定了很多设备了,则称设备栈,我们要总是绑定到栈顶的设备
API 1(对有名称的设备)
NTSTATUS IoAttachDevice(IN PDEVICE_OBJECT SourceDevice,//用来过滤的虚拟设备
                        IN PUNICODE_STRING TargetDevice,//要被绑定的设备名称
                        OUT PDEVICE_OBJECT* AttachedDeviec)//被绑定的设备指针被返回到这个地址
 
API 2(根据设备对象的指针进行绑定)
NTSTATUS IoAttachDeviceToDeviceStackSafe(
                        IN PDEVICE_OBJECT SourceDevice,//用来过滤的虚拟设备
                        IN  PDEVICE_OBJECT TargetDevice,//要被绑定的设备名称
                        OUT PDEVICE_OBJECT* AttachedDeviec)//返回最终被绑定的设备
注意:只有在WIndows 2000SP4和XP以上的系统中才有
 
PDEVICE_OBJECT IoAttachDeviceToDeviceStack(
                        IN PDEVICE_OBJECT SourceDevice,//用来过滤的虚拟设备
                        IN  PDEVICE_OBJECT TargetDevice)//要被绑定的设备名称
函数返回最终被绑定的设备指针(如果为NULL,绑定失败)
 
3)从名字获得设备对象
NTSTATUS IoGetDeivceObjectPointer(
                       IN PUNICODE_STRING ObjectName,//设备名称
                       IN ACESS_MASK DesiredAccess,//预期的访问权限(FILE_ALL_ACCESS)
                       OUT PFILE_OBJECT *FileObject,
                       OUT PDEVICE_OBJECT*DeviceObject);
注意:使用完了以后要将文件对象“解除引用”,否则会引起内存泄漏ObDereferenceObject(fileobj)
 
4) IRP的栈空间
PIO_STACK_LOCATION irpsp=IoGetCurrentIrpStackLocation(irp)//PIRP irp
if(irpsp->MajorFunction==IRP_MJ_WRITE)
{
}
//IRP_MJ_POWER比较特殊
if(irpsp->MajorFunction == IRP_MJ_POWER)
{
        // 直接发送,然后返回说已经被处理了。
        PoStartNextPowerIrp(irp);
        IoSkipCurrentIrpStackLocation(irp);
        return PoCallDriver(s_nextobj[i],irp);
}   
 // 这些请求直接下发执行即可。我们并不禁止或者改变它。
 IoSkipCurrentIrpStackLocation(irp);
 return IoCallDriver(s_nextobj[i],irp);      
 
 
5)IRP结构中的缓冲区
irp->MDLAddress将应用层地址空间映射到内核空间
irp->UserBuffer应用层缓冲区中的地址直接放在内核空间中进行访问(如果内核进程切换访问就出错了)
irp->AssociatedIrp.SystemBuffer把应用层(R3)中内存空间中的缓冲数据拷贝到内核空间
 
//获得缓冲区
PUCHAR buf = NULL;
if(irp->MdlAddress != NULL)
   buf = PUCHAR)MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);
else
   buf = (PUCHAR)irp->UserBuffer;
if(buf == NULL)
   buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;
 
6) 动态卸载
要在卸载函数中完成解除绑定的功能,否则一旦卸载就会蓝屏
IoDetachDevice负责将绑定的设备解除绑定
IoDeleteDevice负责把我们前面用IoCreateDevice生成的设备删除掉以回收内存
KeDelayExecutionThread延时函数
 
IoDetachDevice(s_nextobj[i]);//被绑定的设备
KeDelayExecutionThread(KernelMode,FALSE,&interval);
IoDeleteDevice(s_fltobj[i]);//删除过滤设备
 
 
 
阅读(1871) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~