How to initialize DataSectionObject?

Hi, I’m developing an Isolation Filter based on minifilter.
Now I have substituted the origin FileObject with my shadow FileObject in Pre Create and I have successfully catch PreAcquireSectionSync requests, but after these operations the DataSectionObject in SectionObjectPointer(origin FileObject) is still empty. In order to accomplish read/write, I think I need to initialize DataSectionObject in SectionObjectPointer(origin FileObject), right? I found an API — ZwCreateSection, but the return value of this API is PHANDLE of the Section, so I’m confused, how can I initialize the DataSectionObject?
Any help will be appreciated!

Memory manager sets the datasection object (Control area data structure). What you are doing through create section is getting a handle to a section object which is very different from the Control Area. If you needed a pointer to section object you could get it from referencing object by handle (ObRefrenceObjectByHandle) but that will not work as it is a different data structure from control area (and many other reasons).
If by shadow you mean you want to send I/O requests by your driver only down the FS stack then there are simpler and documented ways of doing that.

There are a series of articles on OSR to help you:
http://www.osronline.com/article.cfm?article=560

When you allocate and set the FsContext pointer in the top level
fileobject, the one which you own, also set the FO->SectionObjectPointer
to point to a structure which you have allocated from non-paged pool.
This usually is within the non-paged portion of the memory you allocated
for your FsContext so later you can perform operations using the SOP
knowing only the FsContext pointer. Note that you don’t initialize any
of the pointers within this structure (except to zero it at first
allocation) yourself, they are used by other modules such as MM.

There is nothing you should be touching within the SOP structure though,
it is allocated by you but owned by the system modules.

Pete

On 9/17/2014 7:58 PM, xxxxx@serpurity.com wrote:

Hi, I’m developing an Isolation Filter based on minifilter.
Now I have substituted the origin FileObject with my shadow FileObject in Pre Create and I have successfully catch PreAcquireSectionSync requests, but after these operations the DataSectionObject in SectionObjectPointer(origin FileObject) is still empty. In order to accomplish read/write, I think I need to initialize DataSectionObject in SectionObjectPointer(origin FileObject), right? I found an API — ZwCreateSection, but the return value of this API is PHANDLE of the Section, so I’m confused, how can I initialize the DataSectionObject?
Any help will be appreciated!


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

Thanks for your response, Peter.
I see that DataSectionObject has been initialized by Mm, but I still don’t quite understand how to handle with SharedCacheMap. As you have mentioned, I don’t need to initialize any part of SectionObjectPointer, but now my filter receives IRP_MJ_WRITE and I don’t know whther I should subtitue the origin FileObject with my own created one or not.
I think CachedIO(IRP_MJ_WRITE) should write data into my own SectionObjectPointer->SharedCacheMap, so is it means that I should just pass through the IRP_MJ_WRITE and do not make any change? But I received STATUS_VOLUME_DISMOUNTED as the result of IRP_MJ_WRITE. If I subtitue the origin FileObject with my own created one, the data will be written into the system owned SectionObjectPointer->SharedCacheMap.
So, how should I handle with IRP_MJ_WRITE(CACHED_IO)?

If you are taking over caching for the file then you need to handle the
cached IO just like the code in FastFat (study the code for these
pathways). That means calling CcInitializeCacheMap() on the first IO,
and then calling CcCopyRead/Write(), etc. This way you are handling the
cache interface, assuming this is what you want to do. Then for
non-cached or paging IO you would pass the request to the underlying
file system to handle accordingly. But this is where things get
complicated, or one of the places … the underlying file object owned
by the file system below you will most likely not have the correct file
sizes set since you handled the cached IO which possibly extended the
file. Thus there is a discrepancy between the sizes in the file object
you own and the one owned by the underlying file system which will lead
to the paging write not writing any data when you pass it down, or at
least not the correct ‘amount’ of data. To deal with this you need to
ensure that the file sizes are correctly handled on the underlying file
object when you process the cached write … or the setfilesize request
if that’s how it comes in. There are several ways to do this, either
sending down an explicit set_info call, specifying the new file size,
passing down the cached write (which would result in 2 copies of the
data in the system cache) or performing a non-cached write which doesn’t
always do what you want.

Pete

On 9/18/2014 8:20 AM, xxxxx@serpurity.com wrote:

Thanks for your response, Peter.
I see that DataSectionObject has been initialized by Mm, but I still don’t quite understand how to handle with SharedCacheMap. As you have mentioned, I don’t need to initialize any part of SectionObjectPointer, but now my filter receives IRP_MJ_WRITE and I don’t know whther I should subtitue the origin FileObject with my own created one or not.
I think CachedIO(IRP_MJ_WRITE) should write data into my own SectionObjectPointer->SharedCacheMap, so is it means that I should just pass through the IRP_MJ_WRITE and do not make any change? But I received STATUS_VOLUME_DISMOUNTED as the result of IRP_MJ_WRITE. If I subtitue the origin FileObject with my own created one, the data will be written into the system owned SectionObjectPointer->SharedCacheMap.
So, how should I handle with IRP_MJ_WRITE(CACHED_IO)?


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

Thanks for your help, Peter. I have finished the part of CachedIO, your advice was very helpful.
Now I do encounter the problem as you have mentioned – I need to extend the size of the file in pre-write paging io, and I think ‘sending down an explicit set_info call’ is a good idea, but I found that FltSetInformationFile can only be called in PASSIVE_LEVEL, so is it means that instead of using an existing API, I need to build my own IRP(IRP_MJ_SET_INFORMATION) and send it down?

Are you trying to extend the file when you receive the paging write? If
so, you’re going to run into deadlock cases … instead the idea is to
extend the file accordingly ‘before’ you receive the paging write. Thus
you could extend the file when you get the cached write, once you
determine it is an extending write. As well you could extend the file
when you receive an explicit SetFileInfo request to extend the file.

If you try to extend the file when you receive the paging write, locks
are already held and you are going to hit cases where the request to
extend the file will block due to these locks already taken on the file.

Pete

On 9/20/2014 2:32 AM, xxxxx@serpurity.com wrote:

Thanks for your help, Peter. I have finished the part of CachedIO, your advice was very helpful.
Now I do encounter the problem as you have mentioned – I need to extend the size of the file in pre-write paging io, and I think ‘sending down an explicit set_info call’ is a good idea, but I found that FltSetInformationFile can only be called in PASSIVE_LEVEL, so is it means that instead of using an existing API, I need to build my own IRP(IRP_MJ_SET_INFORMATION) and send it down?


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

Thanks, peter. I knew this pricinple but I forgot it, thanks for reminding.
Now I try to handle length in my pre-write routine at where my filter is responsible for handling Cached IO requests. Before working, I read the source code of fastfat, and I’m curious about one thing — I can just find code to set FcbOrDcb->Header if extendFileSize or extendValidDataLength is TRUE, but what about FALSE? I think FcbOrDcb->Header should also be refreshed if the fileSize or VDL become smaller, isn’t it?

You’re not looking in the right place. For example, I found this code in fileinfo.c:

//
// Now that File Size is down, actually do the truncate.
//
FatTruncateFileAllocation( IrpContext, Fcb, NewAllocationSize);

//
// Now check if we needed to decrease the file size accordingly.
//
if ( FileSizeTruncated ) {

//
// Tell the cache manager we reduced the file size.
// The call is unconditional, because MM always wants to know.
//

CcSetFileSizes( FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize );

}

(this is from SetAllocationInfo but there’s virtually identical code in SetFileSize).

Tony
OSR

Thanks, Tony.
I find the source code with your advice.
But this piece of source code is locate in fileinfo.c, not in the write.c. So can I assume that:

  1. In write routine it is impossible to refresh FcbOrDcb->Header when fileSize/VDL become smaller;
  2. When fileSize/VDL become smaller, there must be an IRP_MJ_SET_INFORMATION request called, so that it can run into fileinfo.c;
    Am I right?

[quote]

  1. In write routine it is impossible to refresh FcbOrDcb->Header when fileSize/VDL become smaller; 2. When fileSize/VDL become smaller, there must be an IRP_MJ_SET_INFORMATION request called, so that it can run into fileinfo.c; Am I right?

[quote]

I don’t know of any situation in which a write will make a file shrink. If you have a test program that causes this, I’d be very interested in seeing it.

In my experience, truncation is either done during create time (overwrite/supersede) or via a set information call.

Tony
OSR

> 2. When fileSize/VDL become smaller

How can this occur due to a write?

This can only occur due to a truncate.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com