2.1.5.10.24 FSCTL_QUERY_FILE_REGIONS

Support for this operation is optional. If the object store does not implement this functionality, this operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.<116>

The server provides:

  • Open: An Open of DataFile.

  • InputBuffer: An array of bytes containing a single FILE_REGION_INPUT structure indicating the range of the DataFile to return data about, as specified in [MS-FSCC] section 2.3.55. This input structure is optional.

  • InputBufferSize: The number of bytes in InputBuffer.

  • OutputBufferSize: The maximum number of bytes to return in OutputBuffer.

Upon completion, this object store MUST return:

  • Status: An NTSTATUS code that specifies the result.

  • OutputBuffer: An array of bytes that will return a FILE_REGION_OUTPUT structure as specified in [MS-FSCC] section 2.3.56.

  • BytesReturned: The number of bytes returned in OutputBuffer.

This operation uses the following local variables:

  • A FILE_REGION_INPUT structure as specified in [MS-FSCC] section 2.3.55: InputRegion

  • 32-bit unsigned integers (initialized to zero): OutputBufferIndex, Length

  • 64-bit unsigned integers (initialized to zero): Vdl, Eof

Pseudocode for this operation is as follows:

  • If InputBufferSize == 0:

    • Set InputRegion.FileOffset = 0

    • Set InputRegion.Length = MAXLONGLONG

    • Set InputRegion.DesiredUsage = FILE_REGION_USAGE_VALID_CACHED_DATA for NTFS or Set InputRegion.DesiredUsage = FILE_REGION_USAGE_VALID_NONCACHED_DATA for ReFS<117>

  • ElseIf InputBufferSize < Sizeof(FILE_REGION_INPUT)

    • The operation MUST be failed with STATUS_BUFFER_TOO_SMALL.

  • Else:

    • Set InputRegion = InputBuffer

  • EndIf

  • If InputRegion.Length <= 0, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If (InputRegion.FileOffset + InputRegion.Length) exceeds 63 bits, the operation MUST be failed with STATUS_INVALID_PARAMETER

  • If InputRegion.DesiredUsage does NOT have flag FILE_REGION_USAGE_VALID_CACHED_DATA (for NTFS) or flag FILE_REGION_USAGE_VALID_NONCACHED_DATA (for ReFS) set, the operation MUST be failed with STATUS_INVALID_PARAMETER

  • If OutputBuffer.Length < sizeof(FILE_REGION_OUTPUT), the operation MUST be failed with STATUS_BUFFER_TOO_SMALL

  • Set Vdl = Open.File.ValidDataLength

  • Set Eof = Open.File.Eof

  • Set Length = FieldOffset(OutputBuffer.Region[0])

  • If (InputRegion.FileOffset > Eof) OR ((InputRegion.FileOffset == Eof) AND (Eof > 0)), the operation MUST return STATUS_SUCCESS, with BytesReturned set to 0.

  • If (InputRegion.FileOffset >= Vdl)

    • Set OutputBuffer.Region[OutputBufferIndex].FileOffset = InputRegion.FileOffset

    • Set OutputBuffer.Region[OutputBufferIndex].Length = min(InputRegion.Length, Eof - InputRegion.FileOffset)

    • Set OutputBuffer.Region[OutputBufferIndex].Usage = 0

    • Set OutputBuffer.Region[OutputBufferIndex].Reserved = 0

    • Set Length = Length + sizeof(FILE_REGION_INFO)

    • Set OutputBufferIndex = OutputBufferIndex + 1

    • Set OutputBuffer.TotalRegionEntryCount = OutputBuffer.TotalRegionEntryCount + 1

  • Else

    • Set OutputBuffer.Region[OutputBufferIndex].FileOffset = InputRegion.FileOffset

    • Set OutputBuffer.Region[OutputBufferIndex].Length = min((Vdl – InputRegion.FileOffset), InputRegion.Length)

    • Set OutputBuffer.Region[OutputBufferIndex].Usage = InputRegion.DesiredUsage

    • Set OutputBuffer.Region[OutputBufferIndex].Reserved = 0

    • Set Length = Length + sizeof(FILE_REGION_INFO)

    • Set OutputBufferIndex = OutputBufferIndex + 1

    • Set OutputBuffer.TotalRegionEntryCount = OutputBuffer.TotalRegionEntryCount + 1

    • If (Vdl < Eof) AND (OutputBuffer.Region[OutputBufferIndex - 1]. Length <InputRegion.Length),

      • If (Length + sizeof(FILE_REGION_INFO)) > OutputBufferSize)

      • Set OutputBuffer.TotalRegionEntryCount = OutputBuffer.TotalRegionEntryCount + 1

      • The operation MUST be failed with STATUS_BUFFER_OVERFLOW.

    • Set OutputBuffer.Region[OutputBufferIndex].FileOffset = Vdl

    • Set OutputBuffer.Region[OutputBufferIndex].Length = min(InputRegion.LengthOutputBuffer.Region[OutputBufferIndex - 1].Length, EofVdl)

    • Set OutputBuffer.Region[OutputBufferIndex].Usage = 0

    • Set OutputBuffer.Region[OutputBufferIndex].Reserved = 0;

    • Set Length = Length + sizeof(FILE_REGION_INFO)

    • Set OutputBufferIndex = OutputBufferIndex + 1

    • Set OutputBuffer.TotalRegionEntryCount = OutputBuffer.TotalRegionEntryCount + 1

  • EndIf

  • EndIf

  • Upon successful completion of the operation, the object store MUST return:

    • OutputBuffer.RegionEntryCount set to OutputBufferIndex

    • BytesReturned set to Length

    • Status set to STATUS_SUCCESS