dregs
驱动小牛
驱动小牛
  • 注册日期2004-02-19
  • 最后登录2006-05-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望5点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:3427回复:9

怎样发送irp给IoGetDeviceObjectPointer返回的设备对象?55分相赠

楼主#
更多 发布于:2004-04-15 18:24
我遇到了一个很躁人的问题 ,请求各位兄弟相助:
在我的驱动中,首先利用IoGetDeviceObjectPointer获得com1的指针,然后自己构建一个irp来configure串口(利用IOCTL_SERIAL_SET等等)
however 巨gloomy返回值0xc00000010,帖出代码,请大家砍正!!!!

RtlInitUnicodeString( &SerialDeviceName,L\"\\\\Device\\\\Serial0\" );
// open a handle to SERIAL.SYS & obtain a DEVICE_OBJECT
status = IoGetDeviceObjectPointer(
&SerialDeviceName,
FILE_ALL_ACCESS,
&pFile,
&pSerialDO);//保存在此
status = ObReferenceObjectByPointer(
pSerialDO,
FILE_ALL_ACCESS,
NULL,
KernelMode);

ObDereferenceObject(pFile);
//然后构建一个irp,发送给获得的串口指针
KeInitializeEvent(  
&Event,
NotificationEvent,
FALSE
);
// Build irp to be sent to serial driver
DeviceControlIrp = IoBuildDeviceIoControlRequest(
IOCTL_SERIAL_SET_TIMEOUTS,//以此为例子
pSerialDO,
RequestBuffer,
RequestBufferLength,
ReplyBuffer,
ReplyBufferLength,
FALSE,
&Event,
&IoStatusBlock
);
//发送给获得的串口指针
status = IoCallDriver(pSerialDO, DeviceControlIrp );
就在上面的代码出出错 返回10。
(1) IoGetDeviceObjectPointer处估计是正确的
(2) 可能是错在对获得的pSerialDO的使用上,对于这种IoGetDeviceObjectPointer获得的DEVICE_OBJECT,怎么构建irp发送给它呢?有什么规范吗?

请大家帮忙
any hint would be welcome:-)

最新喜欢:

icedogicedog
还是我
yymrhxf
驱动牛犊
驱动牛犊
  • 注册日期2002-08-07
  • 最后登录2011-10-25
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-15 19:50
都是从programming wdm第五章第二节里copy过来的,希望有所帮助。

----------------------------

This function returns two pointers: one to a FILE_OBJECT and one to a DEVICE_OBJECT.


 To help defeat elevation-of-privilege attacks, specify the most restricted access consistent with your needs. For example, if you’ll just be reading data, specify FILE_READ_DATA.

When you create an IRP for a target you discover this way, you should set the FileObject pointer in the first stack location. Furthermore, it’s a good idea to take an extra reference to the file object until after IoCallDriver returns. The following fragment illustrates both these ideas:

PIRP Irp = IoXxx(...);
PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);
ObReferenceObject(FileObject);
stack->FileObject = FileObject;<etc.>
IoCallDriver(DeviceObject, Irp);
ObDereferenceObject(FileObject);

The reason you put the file object pointer in each stack location is that the target driver might be using fields in the file object to record per-handle information. The reason you take an extra reference to the file object is that you’ll have code somewhere in your driver that dereferences the file object in order to release your hold on the target device. (See the next paragraph.) Should that code execute before the target driver’s dispatch routine returns, the target driver might be removed from memory before its dispatch routine returns. The extra reference prevents that bad result.






-----------------------------

Sometimes driver programmers decide they don’t want the clutter of two pointers to what appears to be basically the same object, so they release the file object immediately after calling IoGetDeviceObjectPointer, as shown here:

status = IoGetDeviceObjectPointer(...);
ObReferenceObject(DeviceObject);
ObDereferenceObject(FileObject);

Referencing the device object pins it in memory until you dereference it. Dereferencing the file object allows the I/O Manager to delete it right away.

Releasing the file object immediately might or might not be OK, depending on the target driver. Consider these fine points before you decide to do it:

Deferencing the file object will cause the I/O Manager to send an immediate IRP_MJ_CLEANUP to the target driver.

IRPs that the target driver queues will no longer be associated with a file object. When you eventually release the device object reference, the target driver will probably not be able to cancel any IRPs you sent it that remain on its queues.

In many situations, the I/O Manager will also send an IRP_MJ_CLOSE to the target driver. (If you’ve opened a disk file, the file system driver’s use of the system cache will probably cause the IRP_MJ_CLOSE to be deferred.) Many drivers, including the standard driver for serial ports, will now refuse to process IRPs that you send them.

Instead of claiming an extra reference to the file object around calls to IoCallDriver, you’ll want to reference the device object instead.

wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-04-16 13:28
你确保每个IOCALLDRIVER前面的函数都成功了没?
1。IoGetDeviceObjectPointer把串口的设备对象指针返回没?
2。KeInitializeEvent创建成功没?
3。IoBuildDeviceIoControlRequest的参数给对没?IRP是否真的创建好了?


另外,你看看是否串口被OS锁定了不许你用,试试别的设备可以响应你的请求不
根据地的兄弟们,团结就是力量
dregs
驱动小牛
驱动小牛
  • 注册日期2004-02-19
  • 最后登录2006-05-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望5点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-04-17 09:53
谢谢两位的帮助!
各送上10分先。:-)

还是我
dregs
驱动小牛
驱动小牛
  • 注册日期2004-02-19
  • 最后登录2006-05-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望5点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-17 10:02
to yymrhxf
多谢多谢 这部分帮助很大
问题处在下面的代码上:
status = ObReferenceObjectByPointer(
pSerialDO,
FILE_ALL_ACCESS,
NULL,
KernelMode);

ObDereferenceObject(pFile);
把它们注释掉就ok了。但是我现在的疑问是:

对于这个IoGetDeviceObjectPointer 还是有些不懂。
应该什么时候调用ObDereferenceObject以及ObReferenceObject,
获得的pSerialDO,pFile什么关系??
哪位高人详细讲讲??谢先

还是我
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-19 17:59
这阵没弄这个东西了,有点儿不太记得了:((,对了,我当初用IoGetDeviceObjectPointer获得设备对象指针后好像就是直接用了,没有用ObReferenceObjectByPointer什么的,这个函数好像只是为了避免设备对象的删除的,就是说如果引用计数被增加后,如果在卸载驱动是发现还有没释放此设备对象的驱动的话,会拒绝卸载(我说的不一定对哈,印象太模糊了,对不起革命群众:)),你只要自己注意不要乱卸载这个驱动就行了,只要得到设备对象的指针其他的东西就好办了,应该没什么问题,我记得原来做就一个函数就完了吧,没帮上什么忙,不好意思了!GOOD LUCK兄弟!
根据地的兄弟们,团结就是力量
yymrhxf
驱动牛犊
驱动牛犊
  • 注册日期2002-08-07
  • 最后登录2011-10-25
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-20 09:11
..IoGetDeviceObjectPointer没什么特别的地方,它会导致IO mamager call 到相应的driver,取得你要的device object和file object。

..device object当然是一个device一个,唯一的,file object和文件句柄类似,device和文件类似,一个文件可以对应很多个句柄。

..file object的生存期对device object的引用计数有影响,file object还在,device object就不应该消失,一个file object消失,可能还有其它open的file object在引用这个device object,device object当然未必会跟着消失。

..什么时候引用或者解引用,随便你了,主要看他们在后面的代码当中会不会被用到,还得考虑上面讲的二者之间的依存关系。


dregs
驱动小牛
驱动小牛
  • 注册日期2004-02-19
  • 最后登录2006-05-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望5点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-20 14:49
great thanks to yymrhxf !

向地址由IoGetDeviceObjectPointer获得的设备对象(此处的DeviceObject)发送IRP时,应该带着文件对象.

PIRP Irp = IoBuildXxxRequest(...);
PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);
stack->FileObject = FileObject;
IoCallDriver(DeviceObject, Irp);
如下的这段什么意思呢?
IoGetDeviceObjectPointer performs several steps to locate the two pointers that it returns to you:

It uses ZwOpenFile to open a kernel handle to the named device object. Internally, this will cause the Object Manager to create a file object and to send an IRP_MJ_CREATE to the target device. ZwOpenFile returns a file handle.

It calls ObReferenceObjectByHandle to get the address of the FILE_OBJECT that the handle represents. This address becomes the FileObject return value.

It calls IoGetRelatedDeviceObject to get the address of the DEVICE_OBJECT to which the file object refers. This address becomes the DeviceObject return value.

It calls ZwClose to close the handle.
怎么打开和关闭handle都是IoGetDeviceObjectPointer自动完成的吗?
利用IoGetDeviceObjectPointer得到的串口,我们不需要打开了 ,那么需要关闭吗?



还是我
yymrhxf
驱动牛犊
驱动牛犊
  • 注册日期2002-08-07
  • 最后登录2011-10-25
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-20 15:18
用完了,如果file object还在,Dereference file object就可以了,否则对device object解引用。
hazh1363
驱动牛犊
驱动牛犊
  • 注册日期2004-05-18
  • 最后登录2004-05-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-05-19 16:42
     一个 WDM 驱动程序可以选择需要支持的 IRP_MJ_xxx 的种类,这些请求对应的函数称为
驱动程序的派遣例程(Dispatch Routine)。派遣例程 DispatchPnp 响应 PnP 管理器的 IRP_MJ_PNP
请求。DispatchPower用于响应电源管理器的 IRP_MJ_POWER 请求。所有的 WDM驱动程序都
要支持上诉 3 个请求。派遣例程 DispatchRead 用于响应用户模式 API 函数 ReadFile 引起的
IRP_MJ_READ 请求,ReadFile 用于从设备读取数据。DispatchWrite 用于响应 API 函数 WriteFile
                                      
游客

返回顶部