Previous post was wrotten just once i woke up, so i think i wasn’t clear
To summ up:
First of all when you open file with FILE_FLAG_NO_BUFFERING flag you must
consider data alignment, i.e. offset is on sector boundary and size is
multiple of sectors. Violation to this rule leads to read/write failings.
From point of view of FSD there can be serveral IRP_MJ_READ/IRP_MJ_WRITE
types. Cached, NonCached, Paging.
Cached comes from usual user request, like ReadFile/WriteFile and use cache
manager services to process request. NonCached comes from usual user
request also but it directs FSD to read/write data directly to/from disk
without any caching(hence, alignment requirement starts here because disk
let read or write only sectors). Paging is special request from memory
manager. When memory manager wants to flush mapped file to disk it sends
paging read request. When you access mapped view which is not in memory yet
memory manager sends paging read request to read data from disk. Cache
manager works via memory manager services. Therefore paging read/write can
be from cache manager implicitly.
Now when you open file(instance 1) and then read it or map it, on first
sending read/write request memory manager will reference FILE_OBJECT which
was passed to it. And then memory manager will use only this referenced
FILE_OBJECT to do paging read/write. Then you open file again(instance 2)
and read or write such data which forces memory manager to read/write data
to/from disk, it will be using FILE_OBJECT from previous open, i.e.
instance 1 in our example. Also, FSD doesn’t check alignment like I/O
manager do. I/O manager will fail if offset is not on sector boundary or
size is not multiple sectors. I.e. ReadFile and WriteFile will fail. I
stress that checking is done for files which was opened with
FILE_FLAG_NO_BUFFERING flag.
Network redirector checks file alignment and fails request if there is a
violation.
So, when you opened file with FILE_FLAG_NO_BUFFERING flag and then mapped
it, on first access to view memory manager sends paging IRP_MJ_READ with
offset aligned on sector boudary and size of multiple memory pages. I.e. no
violation. Therefore network redirector sent this request. And request was
processed by your FSD. Then, when your test filled buffer memory manager
will flush modified data. Therefore it sends paging IRP_MJ_WRITE which has
aligned offset but size is not multiple pages because file size is less
than mapped view. Therefore network redirector fails this request. The only
reason is FILE_FLAG_NO_BUFFERING flag was set on file opening. That forced
network redirector do these checks. That’s my theory. I didn’t prove it yet
because i have no Windows 8 under my hand, but will check this soon. It’s
rather easy to prove it. Considering memory manager behavior i’ll do next:
First case:
- Open file without FILE_FLAG_NO_BUFFERING flag
- Read data to force memory manager to reference FILE_OBJECT from step 1
- Open file with FILE_FLAG_NO_BUFFERING flag
- Map file and fill buffer
- Close both files to see if IRP_MJ_WRITE request will come
Test must succeed because memory manager will send request on FILE_OBJECT
from step 1 because it was previous referenced. Therefore network
redirector will not do checking on file alignment and forward request to
SRV2.
Second case:
- Open file with FILE_FLAG_NO_BUFFERING flag(file size must be exactly
4096 bytes)
- Map file and fill buffer
- Close file to see if IRP_MJ_WRITE request will come
Test must succeed because when memory manager will send write request,
network redirector will do checking on file alignment and it’ll be ok.
Becase file size is exactly 4096 bytes.
About local FSD and FILE_FLAG_NO_BUFFERING. As i mentioned it before, FSD
will see that IRP_MJ_WRITE is from memory manager(i.e. this is a paging
request) and do special processing. Thus there will not be any checkings of
file alignment from I/O manager and so on. FSD will not care about what
FILE_OBJECT it got unlike network redirector. First of all it’s because of
FSD is local one and presents local files unlike network redirector. As for
network redirector, its FILE_OBJECT’s are associated with opened ones on
SRV2 side. That’s why it can do this check on paging requests unlike local
FSD. Because it knows in advance that request will fail for FILE_OBJECT
that was opened with FILE_FLAG_NO_BUFFERING flag.
As for Windows 10 i think SRV2 doesn’t open file with
FILE_FLAG_NO_BUFFERING flag anymore.