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… 
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 
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.
-
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.
-
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).
-
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”
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>