Note on lack of serialization among Policy DLL callbacks

A note is probably appropriate here about parallel operations.  The FESF system as a whole is intrinsically asynchronous. This reflects the way that the Windows OS does its work and is also considered "best practice" in terms of overall system performance and throughput.  As a result of this asynchronous design, multiple calls to the Policy DLL can take place in parallel.  FESF provides no serialization for calls into the Policy DLL.   Thus, it will be typical for multiple threads to call into the Policy DLL simultaneously.  In fact, it is even possible for the Policy DLL to get multiple simultaneous calls to the same callback function, such as PolGetPolicyNewFile for the same file.  This is possible if two threads attempt to create the file at the same time.

In the case that two different threads both simultaneously attempt to create the same file, only one of them will ultimately succeed (in kernel-mode processing). FESF will ignore the result returned by the Policy DLL from the second (and, hence, unsuccessful) attempt.  Subsequent attempts to retrieve the Key Data and Header Data will consistently return the same Key Data and Header Data that was actually used by the file.

This can get even more confusing, however, when multiple threads attempt to access an existing encrypted file simultaneously.  This could result in multiple simultaneous calls to the Policy DLL's PolGetPolicyExistingFile callback.  If the openers each provide appropriate share access, multiple openers can succeed.  So, in this case, the results returned by the Policy DLL's PolGetPolicyExistingFile callback will all be relevant.

In summary, when the FESF Policy Service calls the Policy DLL, that call is synchronous in that an associated file operation is being blocked while this call is in progress and the operation will only continue when the Policy DLL returns.  However, the FESF Policy Service will call the Policy DLL's entry points in parallel from multiple worker threads (perhaps a few hundred!).  The same callback function in the Policy DLL can be called an almost limitless number of times in parallel, and multiple different functions in the Policy DLL can also be called in parallel.  It is the job of the Policy DLL (and any user-mode components with which it communicates) to provide whatever serialization may be required.