FSCTL_GET_VOLUME_BITMAP vs. locked NTFS volume

Hi,

we are experiencing some strange behavior when trying to get the cluster
bitmap of a locked NTFS volume in W2K/XP (did not test NT4). In order to
retrieve a consistent bitmap, we lock the volume prior to sending the
FSCTL_GET_VOLUME_BITMAP control code like so (error handling removed):

hVolume = CreateFile(
szVolumeName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);

DeviceIoControl(
hVolume,
FSCTL_LOCK_VOLUME,
NULL, 0,
NULL, 0,
&dwBytesReturned,
NULL
);

This all succeeds and I can then successfully send
FSCTL_GET_VOLUME_BITMAP for FAT volumes. However, it fails for NTFS
volumes with GetLastError() == ERROR_NOT_READY. The docs suggest that “a
return value from GetLastError of ERROR_NOT_READY indicates that the
volume is an NTFS volume, and it is not mounted”. But the volume is
obviously still happily mounted because I never issued a
FSCTL_DISMOUNT_VOLUME and can successfully read from the handle via
ReadFile().

Eventually it turns out that when I set dwShareMode in CreateFile() to
zero (no sharing), then FSCTL_GET_VOLUME_BITMAP succeeds for the locked
NTFS volume (and also still does for FAT).

Can anybody explain why it is like that?

Also, I’m quite confused by the following statements at the end of the
Remarks section for FSCTL_GET_VOLUME_BITMAP in the PSDK:

This operation aligns the bitmap it returns on a page boundary.

Windows XP: This operation aligns the bitmap it returns on a byte
boundary.

What does that mean? To be compatible with NT4/W2K/XP, do I need to make
sure that the output buffer I’m supplying to DeviceIoControl() is
aligned at a page boundary?

Thanks!

Ralf.

Dear Ralf,

Eventually it turns out that when I set dwShareMode in CreateFile() to
zero (no sharing), then FSCTL_GET_VOLUME_BITMAP succeeds for the
locked
NTFS volume (and also still does for FAT).

I’m shooting from the hip here, because I have no direct experience with
this, and hopefully someone else can provide a more precise response.
If you specify FILE_SHARE_READ | FILE_SHARE_WRITE when you open the
volume, that means other processes may still open handles to the volume.
FSCTL_LOCK_VOLUME merely guarantees that no file handles are currently
open on the volume, and that no file handles may be opened while the
volume is locked. Unless you specifiy 0 for the sharing mode when
getting a handle to the volume, other processes can still open handles
to the volume, To what extent such a process can manipulate the volume
while it is locked, I don’t know. If such access could interfere with
retrieval of the volume bitmap or potentially modify the volume bitmap
on NTFS volumes, then it wouldn’t be surprising that the operation fails
unless you open the volume without sharing. What’s puzzling though, is
that the docs for FSCTL_LOCK_VOLUME clearly state:

“The application must also specify the FILE_SHARE_READ and
FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile.”

Chuck

----- Original Message -----
From: “Ralf Buschmann”
To: “NT Developers Interest List”
Sent: Saturday, October 05, 2002 2:00 AM
Subject: [ntdev] FSCTL_GET_VOLUME_BITMAP vs. locked NTFS volume

> Hi,
>
> we are experiencing some strange behavior when trying to get the
cluster
> bitmap of a locked NTFS volume in W2K/XP (did not test NT4). In order
to
> retrieve a consistent bitmap, we lock the volume prior to sending the
> FSCTL_GET_VOLUME_BITMAP control code like so (error handling removed):
>
> hVolume = CreateFile(
> szVolumeName,
> GENERIC_READ | GENERIC_WRITE,
> FILE_SHARE_READ | FILE_SHARE_WRITE,
> NULL,
> OPEN_EXISTING,
> 0,
> NULL
> );
>
> DeviceIoControl(
> hVolume,
> FSCTL_LOCK_VOLUME,
> NULL, 0,
> NULL, 0,
> &dwBytesReturned,
> NULL
> );
>
> This all succeeds and I can then successfully send
> FSCTL_GET_VOLUME_BITMAP for FAT volumes. However, it fails for NTFS
> volumes with GetLastError() == ERROR_NOT_READY. The docs suggest that
“a
> return value from GetLastError of ERROR_NOT_READY indicates that the
> volume is an NTFS volume, and it is not mounted”. But the volume is
> obviously still happily mounted because I never issued a
> FSCTL_DISMOUNT_VOLUME and can successfully read from the handle via
> ReadFile().
>
> Eventually it turns out that when I set dwShareMode in CreateFile() to
> zero (no sharing), then FSCTL_GET_VOLUME_BITMAP succeeds for the
locked
> NTFS volume (and also still does for FAT).
>
> Can anybody explain why it is like that?
>
> Also, I’m quite confused by the following statements at the end of the
> Remarks section for FSCTL_GET_VOLUME_BITMAP in the PSDK:
>
> >This operation aligns the bitmap it returns on a page boundary.
> >
> >Windows XP: This operation aligns the bitmap it returns on a byte
> >boundary.
>
> What does that mean? To be compatible with NT4/W2K/XP, do I need to
make
> sure that the output buffer I’m supplying to DeviceIoControl() is
> aligned at a page boundary?
>
> Thanks!
>
> Ralf.

> Eventually it turns out that when I set dwShareMode in CreateFile()
to

zero (no sharing), then FSCTL_GET_VOLUME_BITMAP succeeds for the
locked
NTFS volume (and also still does for FAT).

Can anybody explain why it is like that?

I have been used FSCTL_GET_VOLUME_BITMAP for NON locked NTFS volumes
for more then a year. It works fine.

What does that mean? To be compatible with NT4/W2K/XP, do I need to
make
sure that the output buffer I’m supplying to DeviceIoControl() is
aligned at a page boundary?

No. Just do not specify StartingVcn which is not a multiply of 8.

Max

Chuck,

you wrote on Saturday, October 5, 2002, 00:02:44:

CB> Dear Ralf,

> Eventually it turns out that when I set dwShareMode in CreateFile() to
> zero (no sharing), then FSCTL_GET_VOLUME_BITMAP succeeds for the
> locked NTFS volume (and also still does for FAT).

CB> I’m shooting from the hip here, because I have no direct experience
CB> with this, and hopefully someone else can provide a more precise
CB> response. If you specify FILE_SHARE_READ | FILE_SHARE_WRITE when you
CB> open the volume, that means other processes may still open handles
CB> to the volume. FSCTL_LOCK_VOLUME merely guarantees that no file
CB> handles are currently open on the volume, and that no file handles
CB> may be opened while the volume is locked. Unless you specifiy 0 for
CB> the sharing mode when getting a handle to the volume, other
CB> processes can still open handles to the volume,

To my experience, both dwShareMode = 0 and FSCTL_LOCK_VOLUME have the
same effect, that is, do not permit any more handles to the volume to be
opened.

CB> To what extent such a process can manipulate the volume while it is
CB> locked, I don’t know. If such access could interfere with retrieval
CB> of the volume bitmap or potentially modify the volume bitmap on NTFS
CB> volumes, then it wouldn’t be surprising that the operation fails
CB> unless you open the volume without sharing.

I don’t think that this is how MS designed it, because the
FSCTL_GET_VOLUME_BITMAP is used by disk defragmenters and these must be
able to defrag the system volume, hence cannot rely on being able to
open a volume without sharing.

CB> What’s puzzling though, is that the docs for FSCTL_LOCK_VOLUME
CB> clearly state:

CB> “The application must also specify the FILE_SHARE_READ and
CB> FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile.”

Exactly, very interesting. Thanks for your reply!

Anyone else?

Ralf.

Maxim,

you wrote on Sunday, October 6, 2002, 17:21:32:

> Eventually it turns out that when I set dwShareMode in CreateFile()
> to zero (no sharing), then FSCTL_GET_VOLUME_BITMAP succeeds for the
> locked NTFS volume (and also still does for FAT).
>
> Can anybody explain why it is like that?

MSS> I have been used FSCTL_GET_VOLUME_BITMAP for NON locked NTFS
MSS> volumes for more then a year. It works fine.

Yeah, I know this :slight_smile: I was just wondering why NTFS works different from
FAT when the volume is locked.

> What does that mean? To be compatible with NT4/W2K/XP, do I need to
> make sure that the output buffer I’m supplying to DeviceIoControl()
> is aligned at a page boundary?

MSS> No. Just do not specify StartingVcn which is not a multiply of 8.

Somehow I doubt it means that. The “Windows XP aligns the bitmap on a
byte boundary” comment doesn’t make sense in this context. Actually, we
have seen this FSCTL writing beyond the supplied output buffer, but it
is hard to replicate. I still need to check whether aligning the buffer
fixes this.

Ralf.