Volume Unmount checking

Hi All,
I have written a volume filter driver. In that I am mapping a file to
the memory. Once I map the file to memory I close the file handle. I am
using this file as a bitmap for logging the bits according to the writes
happpening to the volume. Now the problem arises when somebody does a chkdsk
during my file is mapped. All my writes happening to the mapped files are
not committed to the disk due to the volume is unmounted by the chkdsk. I
capture the failure of write by catching the exception when the setting bits
to the mmapped file is failed due to volume is unmounted. I do that as
following :

__try {
if(!RtlAreBitsSet(&journalFile->FileWriteInfo.bitmapHeader
,startingIndex,numberToset))
{
CjDumpMsg((“\nSetting for bits %ul to
%ul”,startingIndex,numberToset))
RtlSetBits(&journalFile->FileWriteInfo.bitmapHeader
,startingIndex,numberToset);
}
}__except(EXCEPTION_EXECUTE_HANDLER){

CjDbgPrint(DBG_FAILURE,(“__CjJMLogClusterChangetoFile :
VOLUME UNMOUNTED.JOURNAL MAY BE CORRUPT”));
CjLogEvent(ERROR_JOURNAL_MAY_BE_CORRUPT,
CjDriverGlobalParams.JournalDriver,1,“%X”,STATUS_VOLUME_DISMOUNTED);
LEAVE(__CjJMLogClusterChangetoFile);
return STATUS_VOLUME_DISMOUNTED;
}

Now my problem is that this exception is not getting fired for each write
after the volume is unmountd. So I can’t handle such failed writes because I
don’t know which write exactly failed.Can anybody tell me how can I
guarantee that for each write to mmapped file whether the wirte is
successful or the volume is unmount and the write is lost?
I want that for each RtlAreBitsSet or RtlSetBits if the volume unmounted the
code in the __except{ } case should get called.

I have mmapped the file using following code :
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_KERNEL_HANDLE ,
NULL,
NULL);

Status = ZwCreateSection(&journalFile->FileWriteInfo.sectionHandle,
SECTION_MAP_READ | SECTION_MAP_WRITE |
SECTION_EXTEND_SIZE | SECTION_QUERY,
&ObjectAttributes,
&journalFile->FileWriteInfo.Size,
PAGE_READWRITE,
SEC_RESERVE,
journalFile->FileWriteInfo.Handle);

.
.
.
.
.
Status = ZwMapViewOfSection(journalFile->FileWriteInfo.sectionHandle,
hSystemProcess,
&journalFile->
FileWriteInfo.mmapBaseAddress,
0,
PAGE_SIZE,
NULL,
(PSIZE_T)&viewSize,
ViewUnmap,
MEM_RESERVE,
PAGE_READWRITE);
.
.

Thanks,
Giri.

Typically it’s a bad idea to have a driver lower in the stack using
services provided by a driver higher in the stack unless the higher
driver is explicitly providing those services to the lower drivers.

For example writing to the file system from a driver below the file
system. Do you have a way to know that your access of the memory mapped
file isn’t going to cause the FS to recursively grab a lock that it’s
already holding while calling down into your driver?

If you are going to do this then it seems like you should be using
asynchronous I/O instead of memory mapped files (which are, by
definition, synchronous I/O) and not binding the completion of the disk
operation to the update to the map file. Of course then you have to
worry about having multiple writes to the same block in your bitmap at
the same time, so you’ll want to read the block into your cache, modify
it, issue the write and then ensure that any subsequent modification
occurs in the cached block & gets flushed out after the pending write
completes.

-p

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Giri
Sent: Wednesday, September 27, 2006 6:34 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Volume Unmount checking

Hi All,
I have written a volume filter driver. In that I am mapping a file
to the memory. Once I map the file to memory I close the file handle. I
am using this file as a bitmap for logging the bits according to the
writes happpening to the volume. Now the problem arises when somebody
does a chkdsk during my file is mapped. All my writes happening to the
mapped files are not committed to the disk due to the volume is
unmounted by the chkdsk. I capture the failure of write by catching the
exception when the setting bits to the mmapped file is failed due to
volume is unmounted. I do that as following :

__try {

if(!RtlAreBitsSet(&journalFile->FileWriteInfo.bitmapHeader,startingIndex
,numberToset))
{
CjDumpMsg((“\nSetting for bits %ul to
%ul”,startingIndex,numberToset))

RtlSetBits(&journalFile->FileWriteInfo.bitmapHeader,startingIndex,number
Toset);
}
}__except(EXCEPTION_EXECUTE_HANDLER){

CjDbgPrint(DBG_FAILURE,(“__CjJMLogClusterChangetoFile :
VOLUME UNMOUNTED.JOURNAL MAY BE CORRUPT”));

CjLogEvent(ERROR_JOURNAL_MAY_BE_CORRUPT,CjDriverGlobalParams.JournalDriv
er,1,“%X”,STATUS_VOLUME_DISMOUNTED);
LEAVE(__CjJMLogClusterChangetoFile);
return STATUS_VOLUME_DISMOUNTED;
}

Now my problem is that this exception is not getting fired for each
write after the volume is unmountd. So I can’t handle such failed writes
because I don’t know which write exactly failed.Can anybody tell me how
can I guarantee that for each write to mmapped file whether the wirte is
successful or the volume is unmount and the write is lost?
I want that for each RtlAreBitsSet or RtlSetBits if the volume unmounted
the code in the __except{ } case should get called.

I have mmapped the file using following code :
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_KERNEL_HANDLE ,
NULL,
NULL);

Status = ZwCreateSection(&journalFile->FileWriteInfo.sectionHandle,
SECTION_MAP_READ | SECTION_MAP_WRITE |
SECTION_EXTEND_SIZE | SECTION_QUERY,
&ObjectAttributes,
&journalFile->FileWriteInfo.Size,
PAGE_READWRITE,
SEC_RESERVE,
journalFile->FileWriteInfo.Handle);

.
.
.
.
.
Status = ZwMapViewOfSection(journalFile->FileWriteInfo.sectionHandle,
hSystemProcess,

&journalFile->FileWriteInfo.mmapBaseAddress,
0,
PAGE_SIZE,
NULL,
(PSIZE_T)&viewSize,
ViewUnmap,
MEM_RESERVE,
PAGE_READWRITE);
.
.

Thanks,
Giri.

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer