As you may have seen in another thread, I am opening section views on files
to read the files from my mini-filter. The goal is to read open files like
the registry for backup.
I seem to be able to read open files just fine, but when another
application, like explorer, or a text editor, tries to open the file while I
am reading it, that application gets the error “The requested operation
cannot be performed on a file with a user-mapped section open”. I specify
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE in my FltCreateFile
call so I thought others should be able to read while I am reading.
I am doing these reads during a port call from user mode. Does that make
any section I open a “user-mapped” section? Why does it matter? Is there a
way to make my code look like kernel-mode instead of user-mode? Should I
take the trouble to read the file in a system process thread and pass the
data through a queue to the user-mode code?
Here is my current code:
InitializeObjectAttributes( &attr, &uPath, OBJ_CASE_INSENSITIVE |
OBJ_KERNEL_HANDLE, NULL, NULL );
status = FltCreateFile( gFilter, gInstance, &gReadHandle, GENERIC_READ,
&attr, &ioStatus, 0,
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE, FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
FILE_SEQUENTIAL_ONLY, NULL, 0, IO_IGNORE_SHARE_ACCESS_CHECK );
ExFreePool( uPathBuf );
status = ObReferenceObjectByHandle( gReadHandle, 0, NULL, KernelMode,
&gReadFileObj, NULL);
status = FltQueryInformationFile( gInstance, gReadFileObj, &fileInfo,
sizeof( fileInfo ), FileStandardInformation, NULL );
sectionSize.QuadPart = fileInfo.EndOfFile.QuadPart;
status = ZwCreateSection( &gSectionHandle, SECTION_MAP_READ, NULL,
§ionSize, PAGE_READWRITE, SEC_COMMIT, gReadHandle );
status = ZwMapViewOfSection( gSectionHandle, NtCurrentProcess(), &baseAddr,
0, 0, §ionOfs, §ionLen, (SECTION_INHERIT)1, 0, PAGE_READWRITE );
RtlCopyMemory( data, baseAddr + (size_t) (gFileOfs - sectionOfs.QuadPart),
dLen );
status = ZwUnmapViewOfSection( NtCurrentProcess(), baseAddr );
// Much later, after multiple mappings of views, I call ZwClose(
gSectionHandle ).