Locking NTFS volume dismounts it?

Hi,

we are working on software that is supposed to backup the in-use
clusters of a volume. Platform is W2K and XP. In order to do that, we
first try to obtain the bitmap of used clusters on the volume as
follows:

  1. Open the volume (CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE)
  2. Lock the volume (FSCTL_LOCK_VOLUME)
  3. Get volume bitmap (FSCTL_GET_VOLUME_BITMAP)

This works just fine for FAT but for NTFS volumes,
FSCTL_GET_VOLUME_BITMAP returns ERROR_NOT_READY. According to the docs
this “indicates that the volume is an NTFS volume, and it is not
mounted”. The native NT status for ERROR_NOT_READY is, indeed,
STATUS_VOLUME_DISMOUNTED.

How can the volume be dismounted although I never sent a
FSCTL_DISMOUNT_VOLUME? FYI, I inserted a simple ReadFile() on the volume
handle after locking it down and that succeeds, yet sending a
FSCTL_IS_VOLUME_MOUNTED in addition returns zero, indicating it’s indeed
not mounted. Does the read maybe get passed down to the RAW file system
here?

Anyway, I found that FSCTL_GET_VOLUME_BITMAP for NTFS volumes succeeds
only if either

  • you don’t lock the volume at all
  • or set dwShareMode in CreateFile to FILE_SHARE_READ or zero and lock it

However, this doesn’t look right. The docs say that for
FSCTL_LOCK_VOLUME, you must set dwShareMode in CreateFile to
FILE_SHARE_READ | FILE_SHARE_WRITE. The lock is mandatory for us because
we want to ensure that we are getting a consistent bitmap and nobody
else messes with the volume while we are working with it.

I’m pulling my hair out over this one. I’ve tested on W2K SP0/SP4 and XP
SP0/SP1 and it’s always the same. Anybody knows a way to make
FSCTL_GET_VOLUME_BITMAP succeed on a locked NTFS volume?

Below is the code I used for testing.

Thanks!

//======================================================================
#define UNICODE
#define _WIN32_WINNT 0x0500

#include <stdio.h>
#include <windows.h>
#include <winioctl.h>

int wmain(int argc, TCHAR *argv)
{

TCHAR szDrive[255];
BYTE Buf[2048];
HANDLE hVolume = INVALID_HANDLE_VALUE;
DWORD dwBytesReturned;
BOOL bIsLocked = FALSE;
STARTING_LCN_INPUT_BUFFER StartLcn;

__try
{
if (argc < 2)
{
printf(“Usage: Lock [driveletter]\n”);
__leave;
}

wsprintf(szDrive, L"\\.\%c:", argv[1][0]);

if (INVALID_HANDLE_VALUE == (hVolume = CreateFile(
szDrive,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)))
{
printf(“Error %lu opening volume %ls\n”, GetLastError(), szDrive);
__leave;
}

// Lock the volume
if (!DeviceIoControl(
hVolume,
FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0,
&dwBytesReturned,
NULL))
{
printf(“Error %lu locking volume %ls\n”, GetLastError(), szDrive);
__leave;
}

bIsLocked = TRUE;

if (!DeviceIoControl(
hVolume,
FSCTL_IS_VOLUME_MOUNTED,
NULL, 0, NULL, 0,
&dwBytesReturned,
NULL
))
{
printf(“Volume %ls is no longer mounted\n”, szDrive);
}
else
{
printf(“Volume %ls is still mounted\n”, szDrive);
}

if (!ReadFile(
hVolume,
Buf, sizeof(Buf),
&dwBytesReturned, NULL))
{
printf(“Error %lu reading from volume %ls\n”, GetLastError(), szDrive);
}

StartLcn.StartingLcn.QuadPart = 0;
ZeroMemory(Buf, sizeof(Buf));

if(!DeviceIoControl(
hVolume,
FSCTL_GET_VOLUME_BITMAP,
&StartLcn, sizeof(StartLcn),
Buf, sizeof(Buf),
&dwBytesReturned,
NULL))
{
printf(“Error %lu getting cluster bitmap of volume %ls\n”, GetLastError(), szDrive);
}

}

__finally
{
if (INVALID_HANDLE_VALUE != hVolume)
{
if (bIsLocked)
DeviceIoControl(
hVolume,
FSCTL_UNLOCK_VOLUME,
NULL,
0,
NULL,
0,
&dwBytesReturned,
NULL
);

CloseHandle(hVolume);
}

}

return 0;
}
//======================================================================

Ralf.
–</winioctl.h></windows.h></stdio.h>

Are you doing this in KM or UM?

Jamey Kirby, Windows DDK MVP
StorageCraft Inc.
xxxxx@storagecraft.com
http://www.storagecraft.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ralf Buschmann
Sent: Monday, September 08, 2003 12:22 PM
To: Windows System Software Developers Interest List
Subject: [ntdev] Locking NTFS volume dismounts it?

Hi,

we are working on software that is supposed to backup the in-use
clusters of a volume. Platform is W2K and XP. In order to do that, we
first try to obtain the bitmap of used clusters on the volume as
follows:

  1. Open the volume (CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE)
  2. Lock the volume (FSCTL_LOCK_VOLUME)
  3. Get volume bitmap (FSCTL_GET_VOLUME_BITMAP)

This works just fine for FAT but for NTFS volumes,
FSCTL_GET_VOLUME_BITMAP returns ERROR_NOT_READY. According to the docs
this “indicates that the volume is an NTFS volume, and it is not
mounted”. The native NT status for ERROR_NOT_READY is, indeed,
STATUS_VOLUME_DISMOUNTED.

How can the volume be dismounted although I never sent a
FSCTL_DISMOUNT_VOLUME? FYI, I inserted a simple ReadFile() on the volume
handle after locking it down and that succeeds, yet sending a
FSCTL_IS_VOLUME_MOUNTED in addition returns zero, indicating it’s indeed
not mounted. Does the read maybe get passed down to the RAW file system
here?

Anyway, I found that FSCTL_GET_VOLUME_BITMAP for NTFS volumes succeeds
only if either

  • you don’t lock the volume at all
  • or set dwShareMode in CreateFile to FILE_SHARE_READ or zero and lock it

However, this doesn’t look right. The docs say that for
FSCTL_LOCK_VOLUME, you must set dwShareMode in CreateFile to
FILE_SHARE_READ | FILE_SHARE_WRITE. The lock is mandatory for us because
we want to ensure that we are getting a consistent bitmap and nobody
else messes with the volume while we are working with it.

I’m pulling my hair out over this one. I’ve tested on W2K SP0/SP4 and XP
SP0/SP1 and it’s always the same. Anybody knows a way to make
FSCTL_GET_VOLUME_BITMAP succeed on a locked NTFS volume?

Below is the code I used for testing.

Thanks!

//======================================================================
#define UNICODE
#define _WIN32_WINNT 0x0500

#include <stdio.h>
#include <windows.h>
#include <winioctl.h>

int wmain(int argc, TCHAR *argv)
{

TCHAR szDrive[255];
BYTE Buf[2048];
HANDLE hVolume = INVALID_HANDLE_VALUE;
DWORD dwBytesReturned;
BOOL bIsLocked = FALSE;
STARTING_LCN_INPUT_BUFFER StartLcn;

__try
{
if (argc < 2)
{
printf(“Usage: Lock [driveletter]\n”);
__leave;
}

wsprintf(szDrive, L"\\.\%c:", argv[1][0]);

if (INVALID_HANDLE_VALUE == (hVolume = CreateFile(
szDrive,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)))
{
printf(“Error %lu opening volume %ls\n”,
GetLastError(), szDrive);
__leave;
}

// Lock the volume
if (!DeviceIoControl(
hVolume,
FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0,
&dwBytesReturned,
NULL))
{
printf(“Error %lu locking volume %ls\n”,
GetLastError(), szDrive);
__leave;
}

bIsLocked = TRUE;

if (!DeviceIoControl(
hVolume,
FSCTL_IS_VOLUME_MOUNTED,
NULL, 0, NULL, 0,
&dwBytesReturned,
NULL
))
{
printf(“Volume %ls is no longer mounted\n”,
szDrive);
}
else
{
printf(“Volume %ls is still mounted\n”, szDrive);
}

if (!ReadFile(
hVolume,
Buf, sizeof(Buf),
&dwBytesReturned, NULL))
{
printf(“Error %lu reading from volume %ls\n”,
GetLastError(), szDrive);
}

StartLcn.StartingLcn.QuadPart = 0;
ZeroMemory(Buf, sizeof(Buf));

if(!DeviceIoControl(
hVolume,
FSCTL_GET_VOLUME_BITMAP,
&StartLcn, sizeof(StartLcn),
Buf, sizeof(Buf),
&dwBytesReturned,
NULL))
{
printf(“Error %lu getting cluster bitmap of volume
%ls\n”, GetLastError(), szDrive);
}

}

__finally
{
if (INVALID_HANDLE_VALUE != hVolume)
{
if (bIsLocked)
DeviceIoControl(
hVolume,
FSCTL_UNLOCK_VOLUME,
NULL,
0,
NULL,
0,
&dwBytesReturned,
NULL
);

CloseHandle(hVolume);
}

}

return 0;
}
//======================================================================

Ralf.



Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com</winioctl.h></windows.h></stdio.h>

Jamey,

you wrote on Monday, September 8, 2003, 22:19:07:

> 1. Open the volume (CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE)
> 2. Lock the volume (FSCTL_LOCK_VOLUME)
> 3. Get volume bitmap (FSCTL_GET_VOLUME_BITMAP)
>
> This works just fine for FAT but for NTFS volumes,
> FSCTL_GET_VOLUME_BITMAP returns ERROR_NOT_READY. According to the docs
> this “indicates that the volume is an NTFS volume, and it is not
> mounted”. The native NT status for ERROR_NOT_READY is, indeed,
> STATUS_VOLUME_DISMOUNTED.

JK> Are you doing this in KM or UM?

Thanks for the reply. User mode. Code was attached to my original
message (as text at bottom, that is).

Ralf.

If you open volume with share access 0 file system will effectively lock the
volume for you - you don’t need to issue FSCTL_LOCK_VOLUME.
This open fails if there are some handles opened on the volume and
subsequent open requests will fail while volume is opened.

Alexei.

“Ralf Buschmann” wrote in message news:xxxxx@ntdev…
>
> Hi,
>
> we are working on software that is supposed to backup the in-use
> clusters of a volume. Platform is W2K and XP. In order to do that, we
> first try to obtain the bitmap of used clusters on the volume as
> follows:
>
> 1. Open the volume (CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE)
> 2. Lock the volume (FSCTL_LOCK_VOLUME)
> 3. Get volume bitmap (FSCTL_GET_VOLUME_BITMAP)
>
> This works just fine for FAT but for NTFS volumes,
> FSCTL_GET_VOLUME_BITMAP returns ERROR_NOT_READY. According to the docs
> this “indicates that the volume is an NTFS volume, and it is not
> mounted”. The native NT status for ERROR_NOT_READY is, indeed,
> STATUS_VOLUME_DISMOUNTED.
>
> How can the volume be dismounted although I never sent a
> FSCTL_DISMOUNT_VOLUME? FYI, I inserted a simple ReadFile() on the volume
> handle after locking it down and that succeeds, yet sending a
> FSCTL_IS_VOLUME_MOUNTED in addition returns zero, indicating it’s indeed
> not mounted. Does the read maybe get passed down to the RAW file system
> here?
>
> Anyway, I found that FSCTL_GET_VOLUME_BITMAP for NTFS volumes succeeds
> only if either
>
> - you don’t lock the volume at all
> - or set dwShareMode in CreateFile to FILE_SHARE_READ or zero and lock it
>
> However, this doesn’t look right. The docs say that for
> FSCTL_LOCK_VOLUME, you must set dwShareMode in CreateFile to
> FILE_SHARE_READ | FILE_SHARE_WRITE. The lock is mandatory for us because
> we want to ensure that we are getting a consistent bitmap and nobody
> else messes with the volume while we are working with it.
>
> I’m pulling my hair out over this one. I’ve tested on W2K SP0/SP4 and XP
> SP0/SP1 and it’s always the same. Anybody knows a way to make
> FSCTL_GET_VOLUME_BITMAP succeed on a locked NTFS volume?
>
> Below is the code I used for testing.
>
> Thanks!
>
> //======================================================================
> #define UNICODE
> #define _WIN32_WINNT 0x0500
>
> #include <stdio.h>
> #include <windows.h>
> #include <winioctl.h>
>
> int wmain(int argc, TCHAR *argv)
> {
>
> TCHAR szDrive[255];
> BYTE Buf[2048];
> HANDLE hVolume = INVALID_HANDLE_VALUE;
> DWORD dwBytesReturned;
> BOOL bIsLocked = FALSE;
> STARTING_LCN_INPUT_BUFFER StartLcn;
>
> __try
> {
> if (argc < 2)
> {
> printf(“Usage: Lock [driveletter]\n”);
>__leave;
> }
>
> wsprintf(szDrive, L"\\.\%c:", argv[1][0]);
>
> if (INVALID_HANDLE_VALUE == (hVolume = CreateFile(
> szDrive,
> GENERIC_READ | GENERIC_WRITE,
> FILE_SHARE_READ | FILE_SHARE_WRITE,
> NULL,
> OPEN_EXISTING,
> FILE_ATTRIBUTE_NORMAL,
> NULL)))
> {
> printf(“Error %lu opening volume %ls\n”,
GetLastError(), szDrive);
> __leave;
> }
>
> // Lock the volume
> if (!DeviceIoControl(
> hVolume,
> FSCTL_LOCK_VOLUME,
> NULL, 0, NULL, 0,
> &dwBytesReturned,
> NULL))
> {
> printf(“Error %lu locking volume %ls\n”,
GetLastError(), szDrive);
>__leave;
> }
>
> bIsLocked = TRUE;
>
> if (!DeviceIoControl(
> hVolume,
> FSCTL_IS_VOLUME_MOUNTED,
> NULL, 0, NULL, 0,
> &dwBytesReturned,
> NULL
> ))
> {
> printf(“Volume %ls is no longer mounted\n”,
szDrive);
> }
> else
> {
> printf(“Volume %ls is still mounted\n”, szDrive);
> }
>
> if (!ReadFile(
> hVolume,
> Buf, sizeof(Buf),
> &dwBytesReturned, NULL))
> {
> printf(“Error %lu reading from volume %ls\n”,
GetLastError(), szDrive);
> }
>
> StartLcn.StartingLcn.QuadPart = 0;
> ZeroMemory(Buf, sizeof(Buf));
>
> if(!DeviceIoControl(
> hVolume,
> FSCTL_GET_VOLUME_BITMAP,
> &StartLcn, sizeof(StartLcn),
> Buf, sizeof(Buf),
> &dwBytesReturned,
> NULL))
> {
> printf(“Error %lu getting cluster bitmap of volume
%ls\n”, GetLastError(), szDrive);
> }
>
> }
>
> __finally
> {
> if (INVALID_HANDLE_VALUE != hVolume)
> {
> if (bIsLocked)
> DeviceIoControl(
> hVolume,
> FSCTL_UNLOCK_VOLUME,
> NULL,
> 0,
> NULL,
> 0,
> &dwBytesReturned,
> NULL
> );
>
> CloseHandle(hVolume);
> }
>
> }
>
> return 0;
> }
> //======================================================================
>
> Ralf.
> –
>
>
></winioctl.h></windows.h></stdio.h>

Alexei,

you wrote on Tuesday, September 9, 2003, 03:58:56:

AJ> If you open volume with share access 0 file system will effectively lock the
AJ> volume for you - you don’t need to issue FSCTL_LOCK_VOLUME.
AJ> This open fails if there are some handles opened on the volume and
AJ> subsequent open requests will fail while volume is opened.

Thanks for your reply. Yes, I know this. It is just that this is not
what the documentation suggests. I simply want to understand why NTFS
reacts different from FAT here. I must be either doing something wrong
or there is some reason for why NTFS fails FSCTL_GET_VOLUME_BITMAP if
the volume was locked via FSCTL_LOCK_VOLUME and was opened with
FILE_SHARE_WRITE. It just doesn’t make sense.

AJ> “Ralf Buschmann” wrote in message news:xxxxx@ntdev…
>>
>> Hi,
>>
>> we are working on software that is supposed to backup the in-use
>> clusters of a volume. Platform is W2K and XP. In order to do that, we
>> first try to obtain the bitmap of used clusters on the volume as
>> follows:
>>
>> 1. Open the volume (CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE)
>> 2. Lock the volume (FSCTL_LOCK_VOLUME)
>> 3. Get volume bitmap (FSCTL_GET_VOLUME_BITMAP)
>>
>> This works just fine for FAT but for NTFS volumes,
>> FSCTL_GET_VOLUME_BITMAP returns ERROR_NOT_READY. According to the docs
>> this “indicates that the volume is an NTFS volume, and it is not
>> mounted”. The native NT status for ERROR_NOT_READY is, indeed,
>> STATUS_VOLUME_DISMOUNTED.
>>
>> How can the volume be dismounted although I never sent a
>> FSCTL_DISMOUNT_VOLUME? FYI, I inserted a simple ReadFile() on the volume
>> handle after locking it down and that succeeds, yet sending a
>> FSCTL_IS_VOLUME_MOUNTED in addition returns zero, indicating it’s indeed
>> not mounted. Does the read maybe get passed down to the RAW file system
>> here?
>>
>> Anyway, I found that FSCTL_GET_VOLUME_BITMAP for NTFS volumes succeeds
>> only if either
>>
>> - you don’t lock the volume at all
>> - or set dwShareMode in CreateFile to FILE_SHARE_READ or zero and lock it
>>
>> However, this doesn’t look right. The docs say that for
>> FSCTL_LOCK_VOLUME, you must set dwShareMode in CreateFile to
>> FILE_SHARE_READ | FILE_SHARE_WRITE. The lock is mandatory for us because
>> we want to ensure that we are getting a consistent bitmap and nobody
>> else messes with the volume while we are working with it.
>>
>> I’m pulling my hair out over this one. I’ve tested on W2K SP0/SP4 and XP
>> SP0/SP1 and it’s always the same. Anybody knows a way to make
>> FSCTL_GET_VOLUME_BITMAP succeed on a locked NTFS volume?
>>
>> Below is the code I used for testing.
>>
>> Thanks!
>>
>> //======================================================================
>> #define UNICODE
>> #define _WIN32_WINNT 0x0500
>>
>> #include <stdio.h>
>> #include <windows.h>
>> #include <winioctl.h>
>>
>> int wmain(int argc, TCHAR *argv)
>> {
>>
>> TCHAR szDrive[255];
>> BYTE Buf[2048];
>> HANDLE hVolume = INVALID_HANDLE_VALUE;
>> DWORD dwBytesReturned;
>> BOOL bIsLocked = FALSE;
>> STARTING_LCN_INPUT_BUFFER StartLcn;
>>
>> __try
>> {
>> if (argc < 2)
>> {
>> printf(“Usage: Lock [driveletter]\n”);
>>__leave;
>> }
>>
>> wsprintf(szDrive, L"\\.\%c:", argv[1][0]);
>>
>> if (INVALID_HANDLE_VALUE == (hVolume = CreateFile(
>> szDrive,
>> GENERIC_READ | GENERIC_WRITE,
>> FILE_SHARE_READ | FILE_SHARE_WRITE,
>> NULL,
>> OPEN_EXISTING,
>> FILE_ATTRIBUTE_NORMAL,
>> NULL)))
>> {
>> printf(“Error %lu opening volume %ls\n”,
AJ> GetLastError(), szDrive);
>> __leave;
>> }
>>
>> // Lock the volume
>> if (!DeviceIoControl(
>> hVolume,
>> FSCTL_LOCK_VOLUME,
>> NULL, 0, NULL, 0,
>> &dwBytesReturned,
>> NULL))
>> {
>> printf(“Error %lu locking volume %ls\n”,
AJ> GetLastError(), szDrive);
>>__leave;
>> }
>>
>> bIsLocked = TRUE;
>>
>> if (!DeviceIoControl(
>> hVolume,
>> FSCTL_IS_VOLUME_MOUNTED,
>> NULL, 0, NULL, 0,
>> &dwBytesReturned,
>> NULL
>> ))
>> {
>> printf(“Volume %ls is no longer mounted\n”,
AJ> szDrive);
>> }
>> else
>> {
>> printf(“Volume %ls is still mounted\n”, szDrive);
>> }
>>
>> if (!ReadFile(
>> hVolume,
>> Buf, sizeof(Buf),
>> &dwBytesReturned, NULL))
>> {
>> printf(“Error %lu reading from volume %ls\n”,
AJ> GetLastError(), szDrive);
>> }
>>
>> StartLcn.StartingLcn.QuadPart = 0;
>> ZeroMemory(Buf, sizeof(Buf));
>>
>> if(!DeviceIoControl(
>> hVolume,
>> FSCTL_GET_VOLUME_BITMAP,
>> &StartLcn, sizeof(StartLcn),
>> Buf, sizeof(Buf),
>> &dwBytesReturned,
>> NULL))
>> {
>> printf(“Error %lu getting cluster bitmap of volume
AJ> %ls\n”, GetLastError(), szDrive);
>> }
>>
>> }
>>
>> __finally
>> {
>> if (INVALID_HANDLE_VALUE != hVolume)
>> {
>> if (bIsLocked)
>> DeviceIoControl(
>> hVolume,
>> FSCTL_UNLOCK_VOLUME,
>> NULL,
>> 0,
>> NULL,
>> 0,
>> &dwBytesReturned,
>> NULL
>> );
>>
>> CloseHandle(hVolume);
>> }
>>
>> }
>>
>> return 0;
>> }
>> //======================================================================
>>
>> Ralf.
>> –
>>
>>
>>

AJ> —
AJ> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

AJ> You are currently subscribed to ntdev as: xxxxx@backmagic.de
AJ> To unsubscribe send a blank email to xxxxx@lists.osr.com

Ralf.
–</winioctl.h></windows.h></stdio.h>

Only if you have requested write access to the volume in question.

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

----- Original Message -----
From: “Alexei Jelvis”
Newsgroups: ntdev
To: “Windows System Software Developers Interest List”
Sent: Tuesday, September 09, 2003 5:58 AM
Subject: [ntdev] Re: Locking NTFS volume dismounts it?

> If you open volume with share access 0 file system will effectively lock the
> volume for you - you don’t need to issue FSCTL_LOCK_VOLUME.

Is it NT4 behavior?
According to W2k FAT source volume is locked based on ShareAccess only,
which is resonable.

Alexei.

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
>
> Only if you have requested write access to the volume in question.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> ----- Original Message -----
> From: “Alexei Jelvis”
> Newsgroups: ntdev
> To: “Windows System Software Developers Interest List”

> Sent: Tuesday, September 09, 2003 5:58 AM
> Subject: [ntdev] Re: Locking NTFS volume dismounts it?
>
>
> > If you open volume with share access 0 file system will effectively lock
the
> > volume for you - you don’t need to issue FSCTL_LOCK_VOLUME.
>
>
>

I don’t see anything wrong with what you are doing.
NTFS behaviour doesn’t look rigth for me as well.

Alexei.

Thanks for your reply. Yes, I know this. It is just that this is not
what the documentation suggests. I simply want to understand why NTFS
reacts different from FAT here. I must be either doing something wrong
or there is some reason for why NTFS fails FSCTL_GET_VOLUME_BITMAP if
the volume was locked via FSCTL_LOCK_VOLUME and was opened with
FILE_SHARE_WRITE. It just doesn’t make sense.

AJ> “Ralf Buschmann” wrote in message
news:xxxxx@ntdev…
> >>
> >> Hi,
> >>
> >> we are working on software that is supposed to backup the in-use
> >> clusters of a volume. Platform is W2K and XP. In order to do that, we
> >> first try to obtain the bitmap of used clusters on the volume as
> >> follows:
> >>
> >> 1. Open the volume (CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE)
> >> 2. Lock the volume (FSCTL_LOCK_VOLUME)
> >> 3. Get volume bitmap (FSCTL_GET_VOLUME_BITMAP)
> >>
> >> This works just fine for FAT but for NTFS volumes,
> >> FSCTL_GET_VOLUME_BITMAP returns ERROR_NOT_READY. According to the docs
> >> this “indicates that the volume is an NTFS volume, and it is not
> >> mounted”. The native NT status for ERROR_NOT_READY is, indeed,
> >> STATUS_VOLUME_DISMOUNTED.
> >>
> >> How can the volume be dismounted although I never sent a
> >> FSCTL_DISMOUNT_VOLUME? FYI, I inserted a simple ReadFile() on the
volume
> >> handle after locking it down and that succeeds, yet sending a
> >> FSCTL_IS_VOLUME_MOUNTED in addition returns zero, indicating it’s
indeed
> >> not mounted. Does the read maybe get passed down to the RAW file system
> >> here?
> >>
> >> Anyway, I found that FSCTL_GET_VOLUME_BITMAP for NTFS volumes succeeds
> >> only if either
> >>
> >> - you don’t lock the volume at all
> >> - or set dwShareMode in CreateFile to FILE_SHARE_READ or zero and lock
it
> >>
> >> However, this doesn’t look right. The docs say that for
> >> FSCTL_LOCK_VOLUME, you must set dwShareMode in CreateFile to
> >> FILE_SHARE_READ | FILE_SHARE_WRITE. The lock is mandatory for us
because
> >> we want to ensure that we are getting a consistent bitmap and nobody
> >> else messes with the volume while we are working with it.
> >>
> >> I’m pulling my hair out over this one. I’ve tested on W2K SP0/SP4 and
XP
> >> SP0/SP1 and it’s always the same. Anybody knows a way to make
> >> FSCTL_GET_VOLUME_BITMAP succeed on a locked NTFS volume?
> >>
> >> Below is the code I used for testing.
> >>
> >> Thanks!
> >>
> >>
//======================================================================
> >> #define UNICODE
> >> #define _WIN32_WINNT 0x0500
> >>
> >> #include <stdio.h>
> >> #include <windows.h>
> >> #include <winioctl.h>
> >>
> >> int wmain(int argc, TCHAR *argv)
> >> {
> >>
> >> TCHAR szDrive[255];
> >> BYTE Buf[2048];
> >> HANDLE hVolume = INVALID_HANDLE_VALUE;
> >> DWORD dwBytesReturned;
> >> BOOL bIsLocked = FALSE;
> >> STARTING_LCN_INPUT_BUFFER StartLcn;
> >>
> >> __try
> >> {
> >> if (argc < 2)
> >> {
> >> printf(“Usage: Lock [driveletter]\n”);
> >>__leave;
> >> }
> >>
> >> wsprintf(szDrive, L"\\.\%c:", argv[1][0]);
> >>
> >> if (INVALID_HANDLE_VALUE == (hVolume = CreateFile(
> >> szDrive,
> >> GENERIC_READ | GENERIC_WRITE,
> >> FILE_SHARE_READ | FILE_SHARE_WRITE,
> >> NULL,
> >> OPEN_EXISTING,
> >> FILE_ATTRIBUTE_NORMAL,
> >> NULL)))
> >> {
> >> printf(“Error %lu opening volume %ls\n”,
> AJ> GetLastError(), szDrive);
> >> __leave;
> >> }
> >>
> >> // Lock the volume
> >> if (!DeviceIoControl(
> >> hVolume,
> >> FSCTL_LOCK_VOLUME,
> >> NULL, 0, NULL, 0,
> >> &dwBytesReturned,
> >> NULL))
> >> {
> >> printf(“Error %lu locking volume %ls\n”,
> AJ> GetLastError(), szDrive);
> >>__leave;
> >> }
> >>
> >> bIsLocked = TRUE;
> >>
> >> if (!DeviceIoControl(
> >> hVolume,
> >> FSCTL_IS_VOLUME_MOUNTED,
> >> NULL, 0, NULL, 0,
> >> &dwBytesReturned,
> >> NULL
> >> ))
> >> {
> >> printf(“Volume %ls is no longer mounted\n”,
> AJ> szDrive);
> >> }
> >> else
> >> {
> >> printf(“Volume %ls is still mounted\n”,
szDrive);
> >> }
> >>
> >> if (!ReadFile(
> >> hVolume,
> >> Buf, sizeof(Buf),
> >> &dwBytesReturned, NULL))
> >> {
> >> printf(“Error %lu reading from volume %ls\n”,
> AJ> GetLastError(), szDrive);
> >> }
> >>
> >> StartLcn.StartingLcn.QuadPart = 0;
> >> ZeroMemory(Buf, sizeof(Buf));
> >>
> >> if(!DeviceIoControl(
> >> hVolume,
> >> FSCTL_GET_VOLUME_BITMAP,
> >> &StartLcn, sizeof(StartLcn),
> >> Buf, sizeof(Buf),
> >> &dwBytesReturned,
> >> NULL))
> >> {
> >> printf(“Error %lu getting cluster bitmap of
volume
> AJ> %ls\n”, GetLastError(), szDrive);
> >> }
> >>
> >> }
> >>
> >> __finally
> >> {
> >> if (INVALID_HANDLE_VALUE != hVolume)
> >> {
> >> if (bIsLocked)
> >> DeviceIoControl(
> >> hVolume,
> >> FSCTL_UNLOCK_VOLUME,
> >> NULL,
> >> 0,
> >> NULL,
> >> 0,
> >> &dwBytesReturned,
> >> NULL
> >> );
> >>
> >> CloseHandle(hVolume);
> >> }
> >>
> >> }
> >>
> >> return 0;
> >> }
> >>
//======================================================================
> >>
> >> Ralf.
> >> –
> >>
> >>
> >>
>
>
>
> AJ> —
> AJ> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> AJ> You are currently subscribed to ntdev as: xxxxx@backmagic.de
> AJ> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
> Ralf.
> –
>
>
></winioctl.h></windows.h></stdio.h>

> Is it NT4 behavior?

Yes.


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

According to W2k FAT source volume is locked based on ShareAccess only,
which is resonable.

Alexei.

“Maxim S. Shatskih” wrote in message
> news:xxxxx@ntdev…
> >
> > Only if you have requested write access to the volume in question.
> >
> > Maxim Shatskih, Windows DDK MVP
> > StorageCraft Corporation
> > xxxxx@storagecraft.com
> > http://www.storagecraft.com
> >
> >
> > ----- Original Message -----
> > From: “Alexei Jelvis”
> > Newsgroups: ntdev
> > To: “Windows System Software Developers Interest List”
>
> > Sent: Tuesday, September 09, 2003 5:58 AM
> > Subject: [ntdev] Re: Locking NTFS volume dismounts it?
> >
> >
> > > If you open volume with share access 0 file system will effectively lock
> the
> > > volume for you - you don’t need to issue FSCTL_LOCK_VOLUME.
> >
> >
> >
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com