Can i send a IRP to other Volume?

hi,
i write a driver and attach on the Volume (such as D:).In the driver,i want to send a IRP to another Volume(such as E:).i use the IoGetDeviceObjectPointer() to get the Volume’s pointer,but the return pointer is pointed to the volume’s file system Device object(device name is “\Filesystem\ntfs”).How can i get the volume’s device object pointer which under the “\FILESYSTEM\NTFS”(such as “\Ftdisk”)?

Regards

We need far more information about where you attach and the type of driver
you are using.


David J. Craig
Engineer, Sr. Staff Software Systems
Broadcom Corporation

wrote in message news:xxxxx@ntdev…
> hi,
> i write a driver and attach on the Volume (such as D:).In the driver,i
> want to send a IRP to another Volume(such as E:).i use the
> IoGetDeviceObjectPointer() to get the Volume’s pointer,but the return
> pointer is pointed to the volume’s file system Device object(device name
> is “\Filesystem\ntfs”).How can i get the volume’s device object pointer
> which under the “\FILESYSTEM\NTFS”(such as “\Ftdisk”)?
>
> Regards
>
>

D: is a symbolic link to the volume device object (named in the form \Device\HarddiskVolume1) that has been created by FTDISK.SYS and is a part of the storage stack. File system is *mounted* on a volume - it is not in the same stack with \Device\HarddiskVolume1. When a file system is mounted on a storage volume, it creates unnamed file system volume device object (VDO) to represent the volume to the file system. The file system VDO is mounted on the storage device object by means of a shared object called a volume parameter block.

In addition to unnamed file system VDO, file system driver also creates a control device object in its DriverEntry(), and this device object has to be named. Filter driver may attach its devices to both
file system (i.e control object) and unnamed file system VDOs. Judging from your statement about
getting a pointer to the named object with IoGetDeviceObjectPointer(), your device is attached to
the control object and not to the FS VDO - in any case, it has nothing to do with FTDISK, because it is is FS filter and not a storage filter.

In other words, you are filtering something, but are not sure what exactly you are filtering…

Anton Bassov

Thanks for you.
let me explain clearly.my driver is a FiDO and it works on the PDO(Driver name is Ftdisk) and under the FiDO(Driver name is VolSnap),i use the IoGetDeviceObjectPointer(“\Device\HarddiskVolumeX”) to get the \Device\HarddiskVolumeX 's Device Object Pointer.but the returned pointer is “\FileSystem\NTFS”.can i get the volume’s PDO pointer(Ftdisk)?
Regard

The IoGetDeviceObjectPointer() routine returns a pointer to the topmost device object in the named device object’s stack. This is why you cannot use it if you are interested on a particular device object, rather than it its stack. If you need a particular device object, you can use ObReferenceObjectByName()…

Anton Bassov

thanks all!
i sloved the problem.
thanks for all help

to anton bassov.
thanks for your answer.but i can not find the ObReferenceObjectByName() in the DDK,can you tell me something more about the ObReferenceObjectByName()?
Regards

> i can not find the ObReferenceObjectByName() in the

DDK,can you tell me something more about the ObReferenceObjectByName()?

Unfortunately, this functions seems to be undocumented on MSDN, so use it with care…

It is declared as following:

extern NTSTATUS ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath,IN ULONG Attributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *ObjectPtr);

Here is the sample code that uses it for getting a pointer to TCPIP’s driver object:

UNICODE_STRING name; PDRIVER_OBJECT tcpdriver;

RtlInitUnicodeString(&name, L"\Driver\Tcpip");

ObReferenceObjectByName(&name, OBJ_CASE_INSENSITIVE, NULL, 0,
IoFileObjectType, KernelMode, NULL, &tcpdriver);

Anton Bassov

Anton Bassov wrote:

UNICODE_STRING name; PDRIVER_OBJECT tcpdriver;

RtlInitUnicodeString(&name, L"\Driver\Tcpip");

ObReferenceObjectByName(&name,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoFileObjectType,
KernelMode,
NULL,
&tcpdriver);

Does is matter what object type you specify
or should you use IoDriverObjectType for driver objects
and IoDeviceObjectType for device objects
instead of IoFileObjectType?

> Does is matter what object type you specify or should you use IoDriverObjectType

for driver objects and IoDeviceObjectType for device objects instead of IoFileObjectType?

In my experience IoFileObjectType works just fine for both device objects and driver objects (in fact, this is just a code that I copy-pasted from one of the projects, so that I never had a problem with it)…

In any case, you can easily establish it experimentally - I have already “experimantally established”
BSOD in case of passing NULL for ‘ObjectType’, although I’ve seen a sample on the web that does it, apparently, without a problem( or, probably, just has never been tested before getting posted)…

Anton Bassov

wrote in message news:xxxxx@ntdev…
>> Does is matter what object type you specify or should you use
>> IoDriverObjectType
>> for driver objects and IoDeviceObjectType for device objects instead of
>> IoFileObjectType?
>
> In my experience IoFileObjectType works just fine for both device objects
> and driver objects (in fact, this is just a code that I copy-pasted from
> one of the projects, so that I never had a problem with it)…
>
>

Then you have been very lucky this function does not do object type
checking, because device objects are device objects and driver objects are
driver objects. ObReferenceObjectByHandle does this checking, you check out
the blog of Doron Holan:
http://blogs.msdn.com/doronh/archive/2006/12/05/why-you-want-to-use-pobject-types-when-converting-handles-to-objects.aspx

/Daniel

> Then you have been very lucky this function does not do object type

checking, because device objects are device objects and driver objects are
driver objects. ObReferenceObjectByHandle does this checking, you check out
the blog of Doron Holan:

If you look at ntddk.h you will see that there is no such thing as either IoDeviceObjectType or IoDriverObjectType, although ntoskrnl.exe exports these symbols. At this point a question arises -
what are we supposed to do if we want to reference device or driver with some documented function, say, with ObReferenceObjectByPointer() (I assume we are using only existing WDK headers, i.e. act the way MSFT says we should act) ??? How come that they did not provide these two declarations, although declarations for all other object types are provided???

My theory is that IoFileObjectType is valid not only for file objects but for both device and driver objects as well, so that it has nothing to do with lack of proper type checking by ObReferenceObjectByName() - I am almost sure you will get STATUS_OBJECT_TYPE_MISMATCH if you pass,say, ExEventObjectType with \Device\Tcp string to it…

Anton Bassov

IoDeviceObjectType and IoDriverObjectType may not be declared in ntddk.h,
they are exported by ntoskrnl. I agree MS would do a good job of exporting
and declaring ALL object types but that is not the issue. That things may be
working here and now because object type checking is not yet implemented in
the routine for the object type that you are passing is relying on the
undocumented lack of features. It is an optional parameter which means you
can pass NULL instead, passing the wrong object type is asking for trouble,
if it doesn’t come now then at some point in the future.

/Daniel
http://www.resplendence.com

wrote in message news:xxxxx@ntdev…
>> Then you have been very lucky this function does not do object type
>> checking, because device objects are device objects and driver objects
>> are
>> driver objects. ObReferenceObjectByHandle does this checking, you check
>> out
>> the blog of Doron Holan:
>
> If you look at ntddk.h you will see that there is no such thing as either
> IoDeviceObjectType or IoDriverObjectType, although ntoskrnl.exe exports
> these symbols. At this point a question arises -
> what are we supposed to do if we want to reference device or driver with
> some documented function, say, with ObReferenceObjectByPointer() (I assume
> we are using only existing WDK headers, i.e. act the way MSFT says we
> should act) ??? How come that they did not provide these two
> declarations, although declarations for all other object types are
> provided???
>
> My theory is that IoFileObjectType is valid not only for file objects but
> for both device and driver objects as well, so that it has nothing to do
> with lack of proper type checking by ObReferenceObjectByName() - I am
> almost sure you will get STATUS_OBJECT_TYPE_MISMATCH if you pass,say,
> ExEventObjectType with \Device\Tcp string to it…
>
>
> Anton Bassov
>
>

> IoDeviceObjectType and IoDriverObjectType may not be declared in ntddk.h,

they are exported by ntoskrnl.

So what??? As long as they are not be declared in ntddk.h and not documented anywhere, we are
not supposed to touch them anyway. There is no mentining of these types anywhere in WDK/MSDN, and there is no suggestion to avoid using driver and device objects in Ob… calls either, so that MSFT must have provided a legitimate way to reference objects of these types. Therefore, by using IoFileObjectType instead technically you are not going around MSFT rules, but by using
IoDeviceObjectType and IoDriverObjectType you do…

passing the wrong object type is asking for trouble, if it doesn’t come now then at
some point in the future.

This would apply only if they were declared in ntddk.h and properly documented. However, once they are not, ironically, by using IoDeviceObjectType and IoDriverObjectType in your calls you are going for a bigger trouble, compared to simply replacing them with IoFileObjectType instead. Just imagine if they disappear in the future OS releases…

The above applies only to documented functions. In our case it does not really matter - once there is no mentioning of this function anywhere on MSDN, there is some certain risk of using it anyway, because MSFT folks are free to do what they want with it, including modifications of its argument list. Therefore, once you have decide to use it, be ready to be asked to provide a fix for “unpleasant surprises” at any moment…

It is an optional parameter which means you can pass NULL instead,

Actually, I tried it, but, for this or that reason, bluescreened…

Anton Bassov

At 04:53 PM 7/25/2007, xxxxx@hotmail.com wrote:

> It is an optional parameter which means you can pass NULL instead,

Actually, I tried it, but, for this or that reason, bluescreened…

Yes, I’ve seen the same, certainly on XP and I think Win2K3. What
documentation there is suggests the parameter is optional, but real
life experience proves otherwise.

Mark.

>volume’s device object pointer which under the “\FILESYSTEM\NTFS”(such as

“\Ftdisk”)?

Write sent this way will contradict the data kept in the caches and thus with
good chances violate the FS integrity.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> D: is a symbolic link to the volume device object (named in the form

\Device\HarddiskVolume1) that has been created by FTDISK.SYS and is a
part of the storage stack.

D: is created by MountMgr.sys

\Device\HarddiskVolume1 PDO is created by FtDisk.sys, and is a PnP child of
\Device\FtControl, which is created by IoReportDetectedDevice.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> The IoGetDeviceObjectPointer() routine returns a pointer to the topmost
device

object in the named device object’s stack. This is why you cannot use it if
you
are interested on a particular device object, rather than it its stack. If you
need a
particular device object, you can use ObReferenceObjectByName()…

No.

IoGetDeviceObjectPointer is a sequence of:

ZwCreateFile
ObReferenceObjectByHandle
IoGetRelatedDeviceObject
ZwClose

So, it creates and gives you the file object, which you can use in the IRP
kinds which require the file object.

ObReferenceObjectByName does not create any file object.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> IoGetDeviceObjectPointer is a sequence of:

ZwCreateFile
ObReferenceObjectByHandle
IoGetRelatedDeviceObject
ZwClose

So, it creates and gives you the file object, which you can use in the IRP
kinds which require the file object.

Correct - this is why, in addition to file object, it also returns a pointer to the topmost device object in the named device object’s stack, which does not necessarily have to be the target named device object itself - this is what IoGetRelatedDeviceObject() call that it makes is for…

ObReferenceObjectByName does not create any file object.

Correct - it just does what its name suggests, i.e. returns a pointer to the target named device object itself, and this is what the OP wants - he is unable to achieve this goals with IoGetDeviceObjectPointer() that returns a pointer to the topmost device.

Therefore, I just don’t understand what you are arguing about - your statements don’t come into any contradiction with mine in any possible way…

Anton Bassov

> > ObReferenceObjectByName does not create any file object.

Correct - it just does what its name suggests, i.e. returns a pointer to the
target
named device object itself, and this is what the OP wants - he is unable to
achieve this goals with IoGetDeviceObjectPointer() that returns a pointer to
the
topmost device.

Therefore, I just don’t understand what you are arguing about - your
statements
don’t come into any contradiction with mine in any possible way…

ObReferenceObjectByName is not a replacement for IoGetDeviceObjectPointer.

Some IRPs require the file object. You cannot send them to a device object
retrieved using ObReferenceObjectByName. You can send them to a device object
retrieved using IoGetDeviceObjectPointer.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com