Assertion while opening a file via shadow device

Hi,

My filter driver performs file open via its shadow device.
The shadow device just passes irp down.

I get the following Assertion Failed message, while opening
an ordinary file or directory:

*** Assertion failed: No correspondence btwn file and device in irp
(
(IrpSp->FileObject->Vpb == NULL) &&
((IrpSp->FileObject->DeviceObject != NULL) &&
(IrpSp->FileObject->DeviceObject->Vpb != NULL) &&
(IrpSp->DeviceObject ==
IrpSp->FileObject->DeviceObject->Vpb->DeviceObject))
)
||
((IrpSp->FileObject->Vpb != NULL) && (IrpSp->DeviceObject ==
IrpSp->FileObject->Vpb->DeviceObject))
||
(!FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED ))

*** Source File: D:\nt\private\ntos\cntfs\strucsup.c, line 6670

And an additional one, while opening a volume:

*** Assertion failed: !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
*** Source File: D:\nt\private\ntos\io\iosubs.c, line 7286

What should I do with it? Can I ignore them?

Thanks in advance,
Leonid.

There is a thread in the ntfsd archive at www.ntfsd.org , where someone
describes this exact assertion.

I don’t know the solution however.

Bartjan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Leonid Zhigunov
Sent: maandag 26 augustus 2002 15:11
To: File Systems Developers
Subject: [ntfsd] Assertion while opening a file via shadow device

Hi,

My filter driver performs file open via its shadow device.
The shadow device just passes irp down.

I get the following Assertion Failed message, while opening
an ordinary file or directory:

*** Assertion failed: No correspondence btwn file and device
in irp ( (IrpSp->FileObject->Vpb == NULL) &&
((IrpSp->FileObject->DeviceObject != NULL) &&
(IrpSp->FileObject->DeviceObject->Vpb != NULL) &&
(IrpSp->DeviceObject ==
IrpSp->FileObject->DeviceObject->Vpb->DeviceObject))
)
||
((IrpSp->FileObject->Vpb != NULL) && (IrpSp->DeviceObject ==
IrpSp->FileObject->Vpb->DeviceObject))
||
(!FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED ))

*** Source File: D:\nt\private\ntos\cntfs\strucsup.c, line 6670

And an additional one, while opening a volume:

*** Assertion failed: !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
*** Source File: D:\nt\private\ntos\io\iosubs.c, line 7286

What should I do with it? Can I ignore them?

Thanks in advance,
Leonid.


You are currently subscribed to ntfsd as: xxxxx@zeelandnet.nl
To unsubscribe send a blank email to %%email.unsub%%

Thank you,

I have read it, but it does not help to understand how to avoid it.

Regards,
Leonid.

“Leonid Zhigunov” wrote in message
news:xxxxx@ntfsd…
>
> Hi,
>
> My filter driver performs file open via its shadow device.
> The shadow device just passes irp down.
>
> I get the following Assertion Failed message, while opening
> an ordinary file or directory:
>
> Assertion failed: No correspondence btwn file and device in irp
> (
> (IrpSp->FileObject->Vpb == NULL) &&
> ((IrpSp->FileObject->DeviceObject != NULL) &&
> (IrpSp->FileObject->DeviceObject->Vpb != NULL) &&
> (IrpSp->DeviceObject ==
> IrpSp->FileObject->DeviceObject->Vpb->DeviceObject))
> )
> ||
> ((IrpSp->FileObject->Vpb != NULL) && (IrpSp->DeviceObject ==
> IrpSp->FileObject->Vpb->DeviceObject))
> ||
> (!FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED ))
>
>
Source File: D:\nt\private\ntos\cntfs\strucsup.c, line 6670
>
>
> And an additional one, while opening a volume:
>
> Assertion failed: !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
>
Source File: D:\nt\private\ntos\io\iosubs.c, line 7286
>
> What should I do with it? Can I ignore them?
>
> Thanks in advance,
> Leonid.
>
>
>
>
>
>
>
>

Regarding the first assertion (in the context of CREATE IRP only),
IrpSp->DeviceObject points onto your shadow DEVICE_OBJECT, while NTSF
expects it to be its device.
Another thing is that if FileSystem->DeviceObject is initialized (non-zero)
NTFS expects it
to be set to point onto volume device on which this FS device is mounted. I
can’t recall
if FileSystem->DeviceObject is set in shadow’s create, but here is my code
that deals with this
assertion:

if( FileObject -> DeviceObject != NULL )
{
if( FileObject -> DeviceObject == m_pDeviceObject ) // Shadow’s
device object
{
InterlockedDecrement(&FileObject -> DeviceObject ->
ReferenceCount); // Is refed by I/O Mgr???
}

// If this is a disk FS then put volume device otherwise
(redirector) put FS device in FileObject
FileObject -> DeviceObject = (m_pVolumeDevice != NULL) ?
m_pVolumeDevice :

GetTargetDevice();

InterlockedIncrement(&FileObject -> DeviceObject -> ReferenceCount);
// Simulate addref???
}

// Will use “skip” IrpSp!
pIrpSp -> DeviceObject = GetTargetDevice();

Hope this helps,

Vladimir

-----Original Message-----
From: Leonid Zhigunov [mailto:xxxxx@progate.spb.ru]
Sent: Monday, August 26, 2002 7:22 AM
To: File Systems Developers
Subject: [ntfsd] Re: Assertion while opening a file via shadow device

Thank you,

I have read it, but it does not help to understand how to avoid it.

Regards,
Leonid.

“Leonid Zhigunov” wrote in message
news:xxxxx@ntfsd…
>
> Hi,
>
> My filter driver performs file open via its shadow device.
> The shadow device just passes irp down.
>
> I get the following Assertion Failed message, while opening
> an ordinary file or directory:
>
> Assertion failed: No correspondence btwn file and device in irp
> (
> (IrpSp->FileObject->Vpb == NULL) &&
> ((IrpSp->FileObject->DeviceObject != NULL) &&
> (IrpSp->FileObject->DeviceObject->Vpb != NULL) &&
> (IrpSp->DeviceObject ==
> IrpSp->FileObject->DeviceObject->Vpb->DeviceObject))
> )
> ||
> ((IrpSp->FileObject->Vpb != NULL) && (IrpSp->DeviceObject ==
> IrpSp->FileObject->Vpb->DeviceObject))
> ||
> (!FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED ))
>
>
Source File: D:\nt\private\ntos\cntfs\strucsup.c, line 6670
>
>
> And an additional one, while opening a volume:
>
> Assertion failed: !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
>
Source File: D:\nt\private\ntos\io\iosubs.c, line 7286
>
> What should I do with it? Can I ignore them?
>
> Thanks in advance,
> Leonid.
>
>
>
>
>
>
>
>


You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to %%email.unsub%%

RE: [ntfsd] Re: Assertion while opening a file via shadow deviceThanks Vladimir,

I have the following shadow device dispatch:

NTSTATUS
ShadowDeviceIrpDispatch(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION IrpSp = IoGetCurrentStackLocation(Irp);

IoSkipCurrentIrpStackLocation(Irp);
return(IoCallDriver(DeviceExtension->TargetDevice, Irp));
}

As I understand, after IoCallDriver, I/O Manager will replace
current IrpSp->DeviceObject with TargetDevice, wich is the device
object of the logical volume. Is it true?

The IrpSp->FileObject->DeviceObject contains the shadow device
object. I tried to replace it with TargetDevice (logical volume)
before calling IoCallDriver, but TargetDevice->Vpb is NULL,
so NTFS will assert this anyway.

What does your GetTargetDevice() routine do?
Why do you use it always to set IrpSp->DeviceObject, even when
change IrpSp->FileObject->DeviceObject to VolumeDevice?

Leonid.

“Vladimir Chtchetkine” wrote in message news:xxxxx@ntfsd…
Regarding the first assertion (in the context of CREATE IRP only),
IrpSp->DeviceObject points onto your shadow DEVICE_OBJECT, while NTSF expects it to be its device.
Another thing is that if FileSystem->DeviceObject is initialized (non-zero) NTFS expects it
to be set to point onto volume device on which this FS device is mounted. I can’t recall
if FileSystem->DeviceObject is set in shadow’s create, but here is my code that deals with this
assertion:

if( FileObject -> DeviceObject != NULL )
{
if( FileObject -> DeviceObject == m_pDeviceObject ) // Shadow’s device object
{
InterlockedDecrement(&FileObject -> DeviceObject -> ReferenceCount); // Is refed by I/O Mgr???
}

// If this is a disk FS then put volume device otherwise (redirector) put FS device in FileObject
FileObject -> DeviceObject = (m_pVolumeDevice != NULL) ? m_pVolumeDevice :
GetTargetDevice();

InterlockedIncrement(&FileObject -> DeviceObject -> ReferenceCount); // Simulate addref???
}

// Will use “skip” IrpSp!
pIrpSp -> DeviceObject = GetTargetDevice();

Hope this helps,

Vladimir

-----Original Message-----
From: Leonid Zhigunov [mailto:xxxxx@progate.spb.ru]
Sent: Monday, August 26, 2002 7:22 AM
To: File Systems Developers
Subject: [ntfsd] Re: Assertion while opening a file via shadow device

Thank you,

I have read it, but it does not help to understand how to avoid it.

Regards,
Leonid.

“Leonid Zhigunov” wrote in message
news:xxxxx@ntfsd…
>
> Hi,
>
> My filter driver performs file open via its shadow device.
> The shadow device just passes irp down.
>
> I get the following Assertion Failed message, while opening
> an ordinary file or directory:
>
> Assertion failed: No correspondence btwn file and device in irp
> (
> (IrpSp->FileObject->Vpb == NULL) &&
> ((IrpSp->FileObject->DeviceObject != NULL) &&
> (IrpSp->FileObject->DeviceObject->Vpb != NULL) &&
> (IrpSp->DeviceObject ==
> IrpSp->FileObject->DeviceObject->Vpb->DeviceObject))
> )
> ||
> ((IrpSp->FileObject->Vpb != NULL) && (IrpSp->DeviceObject ==
> IrpSp->FileObject->Vpb->DeviceObject))
> ||
> (!FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED ))
>
>
Source File: D:\nt\private\ntos\cntfs\strucsup.c, line 6670
>
>
> And an additional one, while opening a volume:
>
> Assertion failed: !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
>
Source File: D:\nt\private\ntos\io\iosubs.c, line 7286
>
> What should I do with it? Can I ignore them?
>
> Thanks in advance,
> Leonid.
>
>
>
>
>
>
>
>


You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to %%email.unsub%%

Leonid:

I’m sorry about misleading pIrpSp -> DeviceObject = GetTargetDevice();
I/O Mgr will indeed set it up automatically.
As far as “logical volume” goes…
To clarify terminology, there is a volume device (f.i
\Device\Harddisk0\Partition0)
of type FILE_DEVICE_DISK and a file system device of type
FILE_DEVICE_DISK_FILE_SYSTEM that is mounted on this volume.
NTFS expects FileObject->DeviceObject to be set to volume device, while
IrpSp->DeviceObject should be set to file system device (which will be
eventually set
by I/O Mgr when IRP reaches down NTFS’s file system device). So, when you
set
FileObject->DeviceObject to your target device you’re still wrong because
your target device
is file system device and this place is reserved for volume device. The
point here is that
you have to have pointer to corresponded volume device so you can set up
FileObject->DeviceObject correctly. I get it in the time of creation of my
shadow device,
along with the target file system device. There are many ways to do this but
I just
open root folder on the targeting volume, get FileObject and FileObject->Vpb
(in case of
disk file systems) will give me everything I need.
Using GetTargetDevice() is just one of my “programming habits” :slight_smile: I’m
cppper and a guideline
here is to access data members via methods rather than directly. So,
GetTargetDevice() does
nothing but
// Get target FSD
inline PDEVICE_OBJECT GetTargetDevice() const
{ return m_TargetDevice; }

P.S. In case of shadowing on top of redirector FileObject->DeviceObject
should point onto
file system device (since there is no volume and no VPB).

Best regards,

Vladimir

-----Original Message-----
From: Leonid Zhigunov [mailto:xxxxx@progate.spb.ru]
Sent: Tuesday, August 27, 2002 1:11 AM
To: File Systems Developers
Subject: [ntfsd] Re: Assertion while opening a file via shadow device

Thanks Vladimir,

I have the following shadow device dispatch:

NTSTATUS
ShadowDeviceIrpDispatch(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION IrpSp = IoGetCurrentStackLocation(Irp);

IoSkipCurrentIrpStackLocation(Irp);
return(IoCallDriver(DeviceExtension->TargetDevice, Irp));
}

As I understand, after IoCallDriver, I/O Manager will replace
current IrpSp->DeviceObject with TargetDevice, wich is the device
object of the logical volume. Is it true?

The IrpSp->FileObject->DeviceObject contains the shadow device
object. I tried to replace it with TargetDevice (logical volume)
before calling IoCallDriver, but TargetDevice->Vpb is NULL,
so NTFS will assert this anyway.

What does your GetTargetDevice() routine do?
Why do you use it always to set IrpSp->DeviceObject, even when
change IrpSp->FileObject->DeviceObject to VolumeDevice?

Leonid.

“Vladimir Chtchetkine” < xxxxx@starbase.com
mailto:xxxxx > wrote in message
news:xxxxx@ntfsd news:xxxxx

Regarding the first assertion (in the context of CREATE IRP only),
IrpSp->DeviceObject points onto your shadow DEVICE_OBJECT, while NTSF
expects it to be its device.
Another thing is that if FileSystem->DeviceObject is initialized (non-zero)
NTFS expects it
to be set to point onto volume device on which this FS device is mounted. I
can’t recall
if FileSystem->DeviceObject is set in shadow’s create, but here is my code
that deals with this
assertion:

if( FileObject -> DeviceObject != NULL )
{
if( FileObject -> DeviceObject == m_pDeviceObject ) // Shadow’s
device object
{
InterlockedDecrement(&FileObject -> DeviceObject ->
ReferenceCount); // Is refed by I/O Mgr???
}

// If this is a disk FS then put volume device otherwise
(redirector) put FS device in FileObject
FileObject -> DeviceObject = (m_pVolumeDevice != NULL) ?
m_pVolumeDevice :

GetTargetDevice();

InterlockedIncrement(&FileObject -> DeviceObject -> ReferenceCount);
// Simulate addref???
}

// Will use “skip” IrpSp!
pIrpSp -> DeviceObject = GetTargetDevice();

Hope this helps,

Vladimir

-----Original Message-----
From: Leonid Zhigunov [mailto:xxxxx@progate.spb.ru
mailto:xxxxx]
Sent: Monday, August 26, 2002 7:22 AM
To: File Systems Developers
Subject: [ntfsd] Re: Assertion while opening a file via shadow device

Thank you,

I have read it, but it does not help to understand how to avoid it.

Regards,
Leonid.

“Leonid Zhigunov” wrote in message
news:xxxxx@ntfsd news:xxxxx
>
> Hi,
>
> My filter driver performs file open via its shadow device.
> The shadow device just passes irp down.
>
> I get the following Assertion Failed message, while opening
> an ordinary file or directory:
>
> Assertion failed: No correspondence btwn file and device in irp
> (
> (IrpSp->FileObject->Vpb == NULL) &&
> ((IrpSp->FileObject->DeviceObject != NULL) &&
> (IrpSp->FileObject->DeviceObject->Vpb != NULL) &&
> (IrpSp->DeviceObject ==
> IrpSp->FileObject->DeviceObject->Vpb->DeviceObject))
> )
> ||
> ((IrpSp->FileObject->Vpb != NULL) && (IrpSp->DeviceObject ==
> IrpSp->FileObject->Vpb->DeviceObject))
> ||
> (!FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED ))
>
>
Source File: D:\nt\private\ntos\cntfs\strucsup.c, line 6670
>
>
> And an additional one, while opening a volume:
>
> Assertion failed: !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
>
Source File: D:\nt\private\ntos\io\iosubs.c, line 7286
>
> What should I do with it? Can I ignore them?
>
> Thanks in advance,
> Leonid.
>
>
>
>
>
>
>
>


You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to %%email.unsub%%</news:xxxxx></mailto:xxxxx></news:xxxxx></mailto:xxxxx>

RE: [ntfsd] Re: Assertion while opening a file via shadow deviceThanks a lot.

This is what I thought. I have not understand it straight away,
cause you name “volume device” that thing, which I expect to be
named “real device”.

Anyway, what I am doing now to avoid NTFS assertion is:

Reference = FALSE;

if (IrpSp->FileObject) {

if (IrpSp->FileObject->DeviceObject == ShadowDevice) {

InterlockedDecrement(&ShadowDevice->ReferenceCount);
Reference = TRUE;
}

if (ShadowExtension->TargetDevice->Vpb) {
IrpSp->FileObject->DeviceObject = ShadowExtension->TargetDevice;
}
else {
IrpSp->FileObject->DeviceObject = ShadowExtension->RealDevice;
}

InterlockedIncrement(&IrpSp->FileObject->DeviceObject->ReferenceCount);
}

IrpSp->DeviceObject = ShadowExtension->TargetDevice;

IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(ShadowExtension->TargetDevice, Irp);

if (Reference) {
InterlockedIncrement(&ShadowObject->ReferenceCount);
}

I have some questions or notes here.

  1. If I do not Increment Shadow’s reference count at the end,
    I got assertion from I/O Manager (DeviceObject->ReferenceCount > 0).
    I can even remove dereferencing and the beginning and this referencing
    at the end. In both cases I have no assertions.

  2. As I can see in debug output, the reference count of Shadow
    (as well as RealDevice) increases with each open. I am worry
    about the following… As I understand the close operations
    for these file objects will never go to shadow’s dispatch.
    Will the Shadow be dereferenced, when file is closed, and who will
    do this (As I suppose, after open, the I/O Manager lose information
    that file was opened on Shadow device).

  3. This mechanism works well on files and directories (both FAT and
    NTFS). But, if I perform a volume open, on NTFS it goes well, but
    on FAT32, I get an assertion from I/O Manager:
    !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN).
    Soon after I skip it, I get the message, something like
    “IFSUTIL: Could not detect volume type for ??\Volume{xxx-long_id-xx}”
    and the volume becomes inaccessible.

How I do a volume open: in filter’s (not shadow’s) create dispatch,
when I get the first open, I queue a work item to perform some
cleanup (delete temporary files and so on), and wait until it
completes. In the cleanup routine I perform file I/O via my shadow
device and set an event at the end. In this case I always get
chkdsk running. In order to avoid this, I try to perform flushing
volume after I complete cleanup, but before setting event. I open
volume using ZwCreateFile(ShadowDeviceName), obtain file object and
issue a flush buffers irp for this object.

If I do not use this mechanism in shadow’s dispatch, I get:

  • an assertion from NTFS about IrpSp->DeviceObject staff,
    when opening file/directory/volume;

  • an assertion !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
    from I/O Manager, when opening volume on both FAT32 and NTFS.

Could you comment these issues?

Maybe there is another way to avoid chkdisk running after my cleanup.
Or maybe there is another way to obtain a volume object without opening
it via ShadowDevice.

Any suggestions are highly appreciated.

Regards,
Leonid.

“Vladimir Chtchetkine” wrote in message news:xxxxx@ntfsd…
Leonid:

I’m sorry about misleading pIrpSp -> DeviceObject = GetTargetDevice();
I/O Mgr will indeed set it up automatically.
As far as “logical volume” goes…
To clarify terminology, there is a volume device (f.i \Device\Harddisk0\Partition0)
of type FILE_DEVICE_DISK and a file system device of type
FILE_DEVICE_DISK_FILE_SYSTEM that is mounted on this volume.
NTFS expects FileObject->DeviceObject to be set to volume device, while
IrpSp->DeviceObject should be set to file system device (which will be eventually set
by I/O Mgr when IRP reaches down NTFS’s file system device). So, when you set
FileObject->DeviceObject to your target device you’re still wrong because your target device
is file system device and this place is reserved for volume device. The point here is that
you have to have pointer to corresponded volume device so you can set up
FileObject->DeviceObject correctly. I get it in the time of creation of my shadow device,
along with the target file system device. There are many ways to do this but I just
open root folder on the targeting volume, get FileObject and FileObject->Vpb (in case of
disk file systems) will give me everything I need.
Using GetTargetDevice() is just one of my “programming habits” :slight_smile: I’m cppper and a guideline
here is to access data members via methods rather than directly. So, GetTargetDevice() does
nothing but
// Get target FSD
inline PDEVICE_OBJECT GetTargetDevice() const
{ return m_TargetDevice; }

P.S. In case of shadowing on top of redirector FileObject->DeviceObject should point onto
file system device (since there is no volume and no VPB).

Best regards,

Vladimir

Leonid:

your ShadowExtension->TargetDevice is FS device and it will never have a
VPB. So, you need
to check first for non-null ShadowExtension->RealDevice and then, if it’s
null, set
FileObject->DeviceObject to your TargetDevice.

As far as AddRefing goes… I didn’t dig deep into this, but my
understanding was that I/O Mgr
increments FileObject->DeviceObject refcount for each create IRP and
decrements it
on close IRP or if create IRP has failed. The assertion that you see (about
refcount) suggests
that after create IRP has been processed I/O Mgr uses some “cached” DevObj
instead of the
one that is stored in FileObject->DeviceObject. Too bad! Now we need to
analyze result of
IoCallDriver to inc back our refcount on failure ('cause it will be deced by
I/O Mgr) and given that
create IRP may be asynchronous… It’s a headache… :frowning:
I think, I will make thread on refcount (along with a couple of other Qs)
separate from this one.
Regarding your problems with chkdsk I would try (if the design allows this)
to “postpone” cleanup
until first create IRP aiming a file or folder. Most likely, first IRP that
you see in your filter is for
volume and it might be part of mount/initialize/“prepare-for-work”
procedure. It’s a pure speculation
on my side, because I don’t know much details on what’s involved in
mounting/initializing fat/ntfs.
Its just a suggestion that might work :slight_smile:

Best regards,

Vladimir

-----Original Message-----
From: Leonid Zhigunov [mailto:xxxxx@progate.spb.ru]
Sent: Tuesday, August 27, 2002 9:22 AM
To: File Systems Developers
Subject: [ntfsd] Re: Assertion while opening a file via shadow device

Thanks a lot.

This is what I thought. I have not understand it straight away,
cause you name “volume device” that thing, which I expect to be
named “real device”.

Anyway, what I am doing now to avoid NTFS assertion is:

Reference = FALSE;

if (IrpSp->FileObject) {

if (IrpSp->FileObject->DeviceObject == ShadowDevice) {

InterlockedDecrement(&ShadowDevice->ReferenceCount);
Reference = TRUE;
}

if (ShadowExtension->TargetDevice->Vpb) {
IrpSp->FileObject->DeviceObject = ShadowExtension->TargetDevice;
}
else {
IrpSp->FileObject->DeviceObject = ShadowExtension->RealDevice;
}

InterlockedIncrement(&IrpSp->FileObject->DeviceObject->ReferenceCount);
}

IrpSp->DeviceObject = ShadowExtension->TargetDevice;

IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(ShadowExtension->TargetDevice, Irp);

if (Reference) {
InterlockedIncrement(&ShadowObject->ReferenceCount);
}

I have some questions or notes here.

  1. If I do not Increment Shadow’s reference count at the end,
    I got assertion from I/O Manager (DeviceObject->ReferenceCount > 0).
    I can even remove dereferencing and the beginning and this referencing
    at the end. In both cases I have no assertions.

  2. As I can see in debug output, the reference count of Shadow
    (as well as RealDevice) increases with each open. I am worry
    about the following… As I understand the close operations
    for these file objects will never go to shadow’s dispatch.
    Will the Shadow be dereferenced, when file is closed, and who will
    do this (As I suppose, after open, the I/O Manager lose information
    that file was opened on Shadow device).

  3. This mechanism works well on files and directories (both FAT and
    NTFS). But, if I perform a volume open, on NTFS it goes well, but
    on FAT32, I get an assertion from I/O Manager:
    !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN).
    Soon after I skip it, I get the message, something like
    “IFSUTIL: Could not detect volume type for ??\Volume{xxx-long_id-xx}”
    and the volume becomes inaccessible.

How I do a volume open: in filter’s (not shadow’s) create dispatch,
when I get the first open, I queue a work item to perform some
cleanup (delete temporary files and so on), and wait until it
completes. In the cleanup routine I perform file I/O via my shadow
device and set an event at the end. In this case I always get
chkdsk running. In order to avoid this, I try to perform flushing
volume after I complete cleanup, but before setting event. I open
volume using ZwCreateFile(ShadowDeviceName), obtain file object and
issue a flush buffers irp for this object.

If I do not use this mechanism in shadow’s dispatch, I get:

  • an assertion from NTFS about IrpSp->DeviceObject staff,
    when opening file/directory/volume;

  • an assertion !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
    from I/O Manager, when opening volume on both FAT32 and NTFS.

Could you comment these issues?

Maybe there is another way to avoid chkdisk running after my cleanup.
Or maybe there is another way to obtain a volume object without opening
it via ShadowDevice.

Any suggestions are highly appreciated.

Regards,
Leonid.

“Vladimir Chtchetkine” < xxxxx@starbase.com
mailto:xxxxx > wrote in message
news:xxxxx@ntfsd news:xxxxx
Leonid:

I’m sorry about misleading pIrpSp -> DeviceObject = GetTargetDevice();
I/O Mgr will indeed set it up automatically.
As far as “logical volume” goes…
To clarify terminology, there is a volume device (f.i
\Device\Harddisk0\Partition0)
of type FILE_DEVICE_DISK and a file system device of type
FILE_DEVICE_DISK_FILE_SYSTEM that is mounted on this volume.
NTFS expects FileObject->DeviceObject to be set to volume device, while
IrpSp->DeviceObject should be set to file system device (which will be
eventually set
by I/O Mgr when IRP reaches down NTFS’s file system device). So, when you
set
FileObject->DeviceObject to your target device you’re still wrong because
your target device
is file system device and this place is reserved for volume device. The
point here is that
you have to have pointer to corresponded volume device so you can set up
FileObject->DeviceObject correctly. I get it in the time of creation of my
shadow device,
along with the target file system device. There are many ways to do this but
I just
open root folder on the targeting volume, get FileObject and FileObject->Vpb
(in case of
disk file systems) will give me everything I need.
Using GetTargetDevice() is just one of my “programming habits” :slight_smile: I’m
cppper and a guideline
here is to access data members via methods rather than directly. So,
GetTargetDevice() does
nothing but
// Get target FSD
inline PDEVICE_OBJECT GetTargetDevice() const
{ return m_TargetDevice; }

P.S. In case of shadowing on top of redirector FileObject->DeviceObject
should point onto
file system device (since there is no volume and no VPB).

Best regards,

Vladimir


You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to %%email.unsub%%</news:xxxxx></mailto:xxxxx>