能力值:
( LV2,RANK:10 )
2 楼
typedef struct _FULL_DEVOBJ_EXTENSION {
CSHORT Type;
USHORT Size;
PDEVICE_OBJECT DeviceObject;
ULONG PowerFlags;
struct _DEVICE_OBJECT_POWER_EXTENSION *Dope;
ULONG ExtensionFlags;
PVOID DeviceNode;
PDEVICE_OBJECT AttachedTo;
} FULL_DEVOBJ_EXTENSION, *PFULL_DEVOBJ_EXTENSION;
用这个就可以。注意AttachedTo成员。这个结构前面部分自nt4以来都没变过,后面的部分可以省略了,完整的结构可以看win2k, nt4, wrk源代码。
能力值:
( LV3,RANK:20 )
3 楼
奇怪了,我用LS说的测试了一下,得到的PDEVICE_OBJECT地址和在DeviceTree里面看到的都不同,但是值都是0x8xxxxxxx,比较像是设备,不过不知道是哪里的设备。
能力值:
( LV2,RANK:10 )
4 楼
注意,不是devcieExtension,是deviceObjectExtension
能力值:
( LV3,RANK:20 )
5 楼
是啊,我就是用deviceObjectExtension,而且是遍历到NULL为止,可以打印出三个设备,但都不知道是谁,如果用devcieExtension,估计早蓝屏了吧?
能力值:
( LV2,RANK:10 )
6 楼
可以用windbg的!devobj看详细信息。
能力值:
( LV3,RANK:20 )
7 楼
多谢heretic,可能是我在公司的时候看走眼了,不知道怎么就没对上?
刚才试了一下,确实是逐级往底层找设备,而且也确实是有三个设备。
多谢指点
能力值:
( LV3,RANK:20 )
8 楼
对了,我还有一个疑问,就是如果我的设备attach到usb键盘驱动设备上,但是我并没有得到对应的FILE_OBJECT以保存引用计数,这样在usb键盘拔出的时候,可能会挂掉吧?但是我只知道用ObReferenceObjectByName得到usb对应的DRIVER_OBJECT,再在里面找到对应的DEVICE_OBJECT,那我要怎么根据DEVICE_OBJECT得到对应的FILE_OBJECT,以保存引用计数呢?(我这样的想法是否正确,是不是应该保存一个FILE_OBJECT比较保险?)
另外,刚才用heretic大侠的方法,学到了不少东西,知道键盘驱动是从\Driver\ACPI里面的一个设备开始,经\Driver\i8042prt,才到\Device\KeyBoardClass0高层的,但是IoGetBaseFileSystemDeviceObject所返回的并不是最低层,而是\Device\KeyBoardClass0这一层,这个是根据什么来的?它的功能是返回最低的\Device\开头的设备吗?
能力值:
( LV2,RANK:10 )
9 楼
要引用一个DEVICE_OBJECT,直接ObReferenceObject他就对了,其实FILE_OBJECT只是间接的引用了DEVICE_OBJECT,所以不用再去打开这个device,创建一个fileObj。
IPDEVICE_OBJECT
IoGetBaseFileSystemDeviceObject(
IN PFILE_OBJECT FileObject
)
/*++
Routine Description:
This routine returns the base (lowest-level) file system volume device
object associated with a file. I.e., it locates the file system w/o
walking the attached device object list.
Arguments:
FileObject - Supplies a pointer to the file object for which the base
file system device object is to be returned.
Return Value:
The function value is the lowest level volume device object associated
w/the file.
--*/
{
PDEVICE_OBJECT deviceObject;
//
// If the file object has a mounted Vpb, use its DeviceObject.
//
if (FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL) {
deviceObject = FileObject->Vpb->DeviceObject;
//
// Otherwise, if the real device has a VPB that indicates that it is
// mounted, then use the file system device object associated with the
// VPB.
//
} else if (FileObject->DeviceObject->Vpb != NULL &&
FileObject->DeviceObject->Vpb->DeviceObject != NULL) {
deviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
//
// Otherwise, just return the real device object.
//
} else {
deviceObject = FileObject->DeviceObject;
}
ASSERT( deviceObject != NULL );
//
// Simply return the resultant file object.
//
return deviceObject;
}
他是从FILE_OBJECT里面处理的,FILE_OBJECT只会跟你打开的设备相关 ,不会到最底层。\Device\KeyBoardClass0是keyboard class driver建立的,\Driver\i8042prt是port driver。如果你不是直接打开port driver建立的device,从而得到file_object,那么不会得到它的。
能力值:
( LV3,RANK:20 )
10 楼
听君一席话,胜读十年书啊!太感谢你了。
对了,这些相关资料都是自己经验总结出来的,还是什么书上看过来的呢?
我现在遇到问题,都不知道该去什么地方找资料,很多东西网上都找不到解答,还好这边有很多热心人帮助
最后再请教几个问题,用ObReferenceObjectByName这个未公开API得到的DRIVER_OBJECT是否需要ObDereferenceObject掉?
还有IoGetDeviceObjectPointer得到的FILE_OBJECT和DEVICE_OBJECT,是不是只需要ObDereferenceObject前者?
用IoAttachDeviceToDeviceStack了以后,它在内部是不是对Source Device已经ObReferenceObject过了,我们可不可以把Source参数ObDereferenceObject掉?(因为网上下载的那个键盘过滤驱动,对USB键盘似乎没有保留引用计数,只是调用一下IoAttachDeviceToDeviceStack就完事,所以才有此疑问)
能力值:
( LV2,RANK:10 )
11 楼
1. 所有的ObRef都会使 ref_count+1,ObDeref 使得 ref_count - 1。
2. 应该ObDeref file_object,fileObj关闭的时候会自动 Deref 相应的 devObj。
3. IoAttachDeviceToDeviceStack会自动使attach的devObj的refCount+1。你不要Deref,因为你是attach到他上面的,你要保证你在的时候他不能delete了。
资料需要自己看书,看win源代码,自己写程序验证,自己总结。搞清楚原理才是最重要的,不要被一些所谓的“技巧”所迷惑了。理解了win的运作,自然可以想到无数的方法处理一件事情。
能力值:
( LV3,RANK:20 )
12 楼
Ring3到Ring0的槛不小啊……
多谢heretic大侠解惑!