Sharing violation with section objects

** NOTE: Can you move this to NTFSD? Sorry for the mistake

Hey, If a program performs the following:

  • FileHandle1 = NtCreateFile(MyFile.txt, ShareMode = 0)
  • NtCreateSection(PageProtection = PAGE_READWRITE, FileHandle = FileHandle1)
  • NtClose(FileHandle1)
  • FileHandle2 = NtCreateFile(MyFile.txt, ShareMode = 0)

The second call to CreateFile will fail with STATUS_SHARING_VIOLATION, but If I do this:

  • FileHandle1 = NtCreateFile(MyFile.txt, ShareMode = 0)
  • NtCreateSection(PageProtection = PAGE_READONLY, FileHandle = FileHandle1)
  • NtClose(FileHandle1)
  • FileHandle2 = NtCreateFile(MyFile.txt, ShareMode = 0)

The file handle will be created without any errors. It seems like holding a section with PAGE_READONLY does not cause sharing violations while holding the section with PAGE_READWRITE does cause a sharing violation.

Is it a filesystem dependent behavior? Or is it documented somewhere? I think I found the code in fastfat that handles this case (https://github.com/microsoft/Windows-driver-samples/blob/9e1a643093cac60cd333b6d69abc1e4118a12d63/filesys/fastfat/create.c#L6864)

The reason I’m asking is that I’m trying to understand how creating a section object influences file APIs. For example, I know that the file size cannot be reduced with SetEndOfFile. Are there any more cases where creating a section can fail APIs? (I guess creating a file object with WRITE_THROUGH…?)

I know that FltCreateSectionForDataScan handles these kind of cases by holding off requests that conflict with the section object. Is is safe to scan a file using FltCreateSectionForDataScan asynchronously while other processes use the file?

Thanks,
Ori

** NOTE: Can you move this to NTFSD? Sorry for the mistake

done.

@0xrepnz said:
** NOTE: Can you move this to NTFSD? Sorry for the mistake

Hey, If a program performs the following:

  • FileHandle1 = NtCreateFile(MyFile.txt, ShareMode = 0)
  • NtCreateSection(PageProtection = PAGE_READWRITE, FileHandle = FileHandle1)
  • NtClose(FileHandle1)
  • FileHandle2 = NtCreateFile(MyFile.txt, ShareMode = 0)

The second call to CreateFile will fail with STATUS_SHARING_VIOLATION, but If I do this:

  • FileHandle1 = NtCreateFile(MyFile.txt, ShareMode = 0)
  • NtCreateSection(PageProtection = PAGE_READONLY, FileHandle = FileHandle1)
  • NtClose(FileHandle1)
  • FileHandle2 = NtCreateFile(MyFile.txt, ShareMode = 0)

The file handle will be created without any errors. It seems like holding a section with PAGE_READONLY does not cause sharing violations while holding the section with PAGE_READWRITE does cause a sharing violation.

Is it a filesystem dependent behavior? Or is it documented somewhere? I think I found the code in fastfat that handles this case (https://github.com/microsoft/Windows-driver-samples/blob/9e1a643093cac60cd333b6d69abc1e4118a12d63/filesys/fastfat/create.c#L6864)

Makes sense: if I get a “no share write” handle I don’t expect the content of the file to be changing. From that perspective a writeable HANDLE or a writeable mapping are equivalent and should lead to a sharing violation.

So much stuff in the file system space is driven by way of implementation. FAT is a good place to map out a lot of behaviors because the other file systems will at least do what FAT does. Good APIs to look for are:

  1. MmFlushImageSection
  2. MmDoesFileHaveUserWritableReferences
  3. MmCanFileBeTruncated
  4. CcPurgeCacheSection - Note that this ultimately calls MmPurgeSection. Most file systems just always call CcPurgeCacheSection even if the file is purely memory mapped

The reason I’m asking is that I’m trying to understand how creating a section object influences file APIs. For example, I know that the file size cannot be reduced with SetEndOfFile. Are there any more cases where creating a section can fail APIs? (I guess creating a file object with WRITE_THROUGH…?)

I know that FltCreateSectionForDataScan handles these kind of cases by holding off requests that conflict with the section object. Is is safe to scan a file using FltCreateSectionForDataScan asynchronously while other processes use the file?

It’s more reactive than proactive…So, if something fails FltMgr will retry the operation after the sections are closed. Note that the file systems have to actively participate in this (search the FAT source for PurgeFailureModeEnableCount)

But, to answer your question: yes, generally speaking it’s safe to scan the file asynchronously. Though if you’re going to be asynchronously scanning things why not just do it in user mode?

Thanks,
Ori