When a program queries the size of a specific file using a handle that has been given RAW access to the file, the program gets back the raw (that is, uncorrected) file size. This size includes the size of the file’s data, plus the FESF Metadata including the Solution Header. Similarly, in the current and all previous versions of FESF, when a program queries the size of a file using a handle that’s been given ENC/DEC access to the file, FESF returns the corrected size of the file. This size reflects just the size of the data in the file.
A Policy DLL's PolGetPolicyDirectoryListing callback function determines whether the sizes of FESF encrypted files returned in a directory listing will reflect the raw (uncorrected) or the corrected size of any FESF encrypted files that are within that directory. Notice that this callback applies specifically to size returned in the directory listing, not the size returned to an application when it opens a file and then queries the size of that file.
Whether the raw or corrected size is returned in a directory listing can be important when applications with RAW access use the size from the directory listing (as opposed to the size from an individual query for the file size using a RAW handle) to determine how much of a file to copy. During extended usage testing of FESF, we were surprised to find a number of applications that did this. One specific example we found is the Microsoft OneDrive application. However, we wouldn’t be surprised if other programs such as certain backup applications behaved similarly.
POL_GET_POLICY_DIRECTORY_LISTING PolGetPolicyDirectoryListing;
FE_POLICY_RESULT
PolGetPolicyDirectoryListing (
_In_ FE_POLICY_PATH_INFORMATION *PolicyPathInfo,
_In_ DWORD ThreadId
)
PolicyPathInfo [in]
A pointer to an FESF allocated FE_POLICY_PATH_INFORMATION structure describing the directory being opened.
ThreadId [in]
The identifier of the thread opening the directory.
The Policy DLL's PolGetPolicyDirectoryListing callback function returns an enumeration value of the type FE_POLICY_RESULT that determines FESF's action on directory enumerations via the opened file handle.
If PolGetPolicyDirectoryListing returns FE_POLICY_ENCRYPT_DECRYPT, then the file sizes returned, if this handle is used to enumerate the directory, will be those visible to an application given FE_POLICY_ENCRYPT_DECRYPT in response to a call to PolGetPolicyExistingFile.
If PolGetPolicyDirectoryListing returns FE_POLICY_RAW, then the enumeration will return the on-disk size, which is the size visible to an application given FE_POLICY_RAW in response to a call to PolGetPolicyExistingFile.
If PolGetPolicyDirectoryListing cannot specify an encryption policy for the file being opened, for example due to an error in processing, PolGetPolicyDirectoryListing returns the enumeration value FE_POLICY_FAIL. This will cause the thread's CreateFile operation to fail with an error. See the Remarks section for more information on the consequences of returning FE_POLICY_FAIL.
This function does not have to be implemented by Policy DLLs. If it is not implemented, then all directory enumerations will see the encrypted size (as if FE_POLICY_ENCRYPT_DECRYPT was always returned).
FESF calls a Policy DLL's PolGetPolicyDirectoryListing callback function whenever a thread successfully opens a directory. Its primary use is to ensure that processes get a coherent view of a file system – thus a process which always sees the RAW view of all files should see the RAW sizes of files in a directory enumeration. This is particularly important since some applications use the sizes returned in an operation to govern how much data they consume and if they saw the ENCDEC size then if the file was copied raw it would be truncated.
Given the ThreadID provided in this callback, PolGetPolicyDirectoryListing can call FESF-provided helper functions to retrieve additional information about the calling thread, including the directory and file name of the executing program and identity and security information of the user account under which the thread is running.
If FESF Policy Caching is enabled, FESF will remember the policy decision returned by PolGetPolicyDirectoryListing. In this case, if the process owning the ThreadID opens this file in the future FESF will automatically apply the same policy. This helps reduce system overhead by potentially avoiding a call to PolGetPolicyDirectoryListing. The duration of this caching behavior lasts as long as the Windows file cache for this directory persists, which in turn depends on numerous factors that cannot be directly controlled. The FESF Policy Cache can be flushed at any time by the Policy DLL. For more information, see FESF Policy Caching.
PolGetPolicyDirectoryListing is called as part of Windows' processing a system service call (such as CreateFile) made by the thread indicated by ThreadID for the file described by PolicyPathInfo. The call to PolGetPolicyDirectoryListing occurs after the system service call has succeeded but before the final result is returned to the thread. Because the PolGetPolicyDirectoryListing callback is blocking the system service call from completing, processing in this function must be prompt.
Policy DLLs should return FE_POLICY_FAIL from their PolGetPolicyDirectoryListing callback only when absolutely necessary.
Software version |
FESF V1.1 (or later) |
Library |
FESFPolicy.lib |
Header |
PolDllApi.h |