Technologies

Bitsum Technologies
Empowering the Future

Order now

About us

Downloads

Development Services

Discussion Board Links

 User Services Area


Addendum 12-05-03: This article was originally written years ago. I have formatted it a little and posted it to the web on the off-chance it is actually useful to someone. These APIs may very well be documented somewhere now or maybe they have always been. However, they still don't appear in MSDN for whatever reason.

A little bit on W2K/XP/2003 EFS APIs
by Jeremy Collake
http://www.bitsum.com
jeremy@bitsum.com
-----------------------------------------------

Microsoft added the APIs Open/CloseEncryptedFileRaw, ReadEncryptedFileRaw, and WriteEncryptedFileRaw to facilitate archiving of encrypted files by backup software. Without these APIs, and not considering a hacked-out solution, backup software would be forced to do away with the EFS encryption of file(s) on the archived copies. Ironically enough, Microsoft seems to have dropped the ball late in the game and not documented these APIs! Why? I don't know. It could be they just haven't gotten around to it yet, but more likely they decided that they posed some sort of risk to the sanctity of EFS if publicly documented. Regardless, the APIs are actually quite intuitive to use, and are prototyped in winbase.h in the platform SDK. Below, I provide a brief documentation of them.

One very interesting note is that there appears to be no, or very little, validation of the EFS header. By editing a raw EFS file, you can selectively  remove users or recovery agents by overwriting the corresponding encrypted FEK. Oh well..

These are all exports of advapi32.dll.
 


WINADVAPI DWORD WINAPI OpenEncryptedFileRawA(IN LPCSTR lpFileName, IN ULONG ulFlags, IN PVOID * pvContext);

WINADVAPI DWORD WINAPI OpenEncryptedFileRawW(IN LPCWSTR lpFileName, IN ULONG ulFlags, IN PVOID * pvContext);

Parameters:

lpFileName
pointer to ansi or unicode (depending on the API version) filename of encrypted file. If this file does not have the encrypted attribute, the call fails.

ulFlags
use 0 if opening an encrypted file for read access. If opening for write access, use CREATE_FOR_IMPORT. This parameter
can also be CREATE_FOR_DIRECTORY, which I *assume* creates an encrypted directory.

*pvContext
pointer to a pointer to a context. This is, basically, the address that receives
the pointer to the file context. You will pass the returned pointer to
subsequent calls to other EFS APIs.

Returns:
0 if success, or an appropriate error code if the call failed.

Notes: This API can be used to create a new encrypted file by specifying CREATE_FOR_IMPORT as ulFlags.If the file already exists, it is overwritten.
Same rules as the CREATE_ALWAYS flag for CreateFile.

 



WINADVAPI VOID WINAPI CloseEncryptedFileRaw(IN PVOID pvContext);

Parameters:

pvContext
Pointer to the context that was returned by OpenEncryptedFileRaw.
 


WINADVAPI DWORD WINAPI ReadEncryptedFileRaw(IN PFE_EXPORT_FUNC pfExportCallback, IN PVOID pvCallbackContext, IN PVOID pvContext);

Parameters:

pfExportCallback
pointer to a callback function of type FE_EXPORT_FUNC. This function is passed the raw blocks of data as they are read. See documentation of it below.
pvCallbackContext
optional pointer or variable that is passed to the callback procedure. It  is not dereferenced.
pvContext
Pointer to the context that was returned by OpenEncryptedFileRaw.

Notes:
When this API is invoked, all raw data in the file is passed to the export function as it is read from the disk. This API does not return  until all data has been read and processed by the user supplied callback function, or the callback function aborts the read.

 



typedef DWORD (WINAPI *PFE_EXPORT_FUNC)(PBYTE pbData,PVOID pvCallbackContext,ULONG ulLength);

This is the prototype for the callback function supplied to ReadEncryptedFileRaw. This function is called sequentially for every raw block of data
read from the file.

Parameters:

pbData
pointer to the block of data read.
pvCallbackContext
value supplied to corresponding ReadEncryptedFileRaw parameter.
ulLength
size, in bytes, of the data pointed to by pbData.

Returns:
Return 0 to continue the read or any other number to abort.
 



WINADVAPI DWORD WINAPI WriteEncryptedFileRaw(IN PFE_IMPORT_FUNC pfImportCallback, IN PVOID pvCallbackContext, IN PVOID pvContext);

Parameters:

pfImportCallback
pointer to a callback function of type FE_IMPORT_FUNC. This function is called for every block of raw data to be written to the file. See documentation of it below.
pvCallbackContext
optional pointer or variable that is passed to the callback procedure. It  is not dereferenced.
pvContext
Pointer to the context that was returned by OpenEncryptedFileRaw.
 


typedef DWORD (WINAPI *PFE_IMPORT_FUNC)(PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength);

This is the prototype for the callback function supplied to WriteEncryptedFileRaw. This function is called sequentially for every raw block of data
to be written to the file.

Parameters:

pbData
pointer to the buffer where the block of data should be copied.
pvCallbackContext
value supplied to corresponding ReadEncryptedFileRaw parameter.
ulLength
pointer to the size, in bytes, of the the pbData buffer. This number of bytes should be copied to the pbData buffer.

Returns:
Return 0 to continue the write or any other number to abort. Aborting the write at any time results  in file of zero length.

 


 
WINADVAPI VOID WINAPI CloseEncryptedFileRaw(IN PVOID pvContext);

Parameters:

pvContext
Pointer to the context that was returned by OpenEncryptedFileRaw.