1009 lines
19 KiB
C
1009 lines
19 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1997-1999 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
efs.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
EFS (Encrypting File System) API Interfaces
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Robert Reichel (RobertRe)
|
|||
|
Robert Gu (RobertG)
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#undef WIN32_LEAN_AND_MEAN
|
|||
|
|
|||
|
#include "advapi.h"
|
|||
|
#include <windows.h>
|
|||
|
#include <feclient.h>
|
|||
|
|
|||
|
#define FE_CLIENT_DLL L"feclient.dll"
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Global Variables
|
|||
|
//
|
|||
|
|
|||
|
LPFE_CLIENT_INFO FeClientInfo = NULL;
|
|||
|
HMODULE FeClientModule = NULL;
|
|||
|
CRITICAL_SECTION FeClientLoadCritical;
|
|||
|
|
|||
|
|
|||
|
LPWSTR
|
|||
|
GetFeClientDll(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine obtains the name of the currently installed client
|
|||
|
encryption dll (which is currently hardcoded).
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns the name of the current DLL, or NULL on error.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( FE_CLIENT_DLL );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
LoadAndInitFeClient(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine finds the name of the proper client dll (by some as of
|
|||
|
yet unspecified means) and proceeds to load it and initialize it.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE on success, FALSE on failure. Callers may call GetLastError()
|
|||
|
for more error information.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
LPWSTR FeClientDllName;
|
|||
|
LPFEAPI_CLIENT_INITIALIZE ClientInitRoutine;
|
|||
|
BOOL Inited;
|
|||
|
|
|||
|
//
|
|||
|
// GetFeClientDll returns a hard coded name.
|
|||
|
// If we get this name dynamically later, we will
|
|||
|
// need to free FeClientDllName.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
FeClientDllName = GetFeClientDll();
|
|||
|
|
|||
|
EnterCriticalSection(&FeClientLoadCritical);
|
|||
|
if (FeClientInfo) {
|
|||
|
LeaveCriticalSection(&FeClientLoadCritical);
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
if (FeClientDllName) {
|
|||
|
FeClientModule = LoadLibraryW( FeClientDllName );
|
|||
|
if (FeClientModule == NULL) {
|
|||
|
DbgPrint("Unable to load client dll, error = %d\n",GetLastError());
|
|||
|
LeaveCriticalSection(&FeClientLoadCritical);
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ClientInitRoutine = (LPFEAPI_CLIENT_INITIALIZE) GetProcAddress( FeClientModule, (LPCSTR)"FeClientInitialize");
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if (NULL == ClientInitRoutine) {
|
|||
|
FreeLibrary( FeClientModule );
|
|||
|
DbgPrint("Unable to locate init routine, error = %d\n",GetLastError());
|
|||
|
LeaveCriticalSection(&FeClientLoadCritical);
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
Inited = (*ClientInitRoutine)( FE_REVISION_1_0, &FeClientInfo );
|
|||
|
|
|||
|
LeaveCriticalSection(&FeClientLoadCritical);
|
|||
|
if (!Inited) {
|
|||
|
FreeLibrary( FeClientModule );
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
EncryptFileA (
|
|||
|
LPCSTR lpFileName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
ANSI Stub to EncryptFileW
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - The name of the file to be encrypted.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE on success, FALSE on failure. Callers may call GetLastError()
|
|||
|
for more information.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
UNICODE_STRING Unicode;
|
|||
|
WCHAR UnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
|
|||
|
ANSI_STRING AnsiString;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
Unicode.Length = 0;
|
|||
|
Unicode.MaximumLength = STATIC_UNICODE_BUFFER_LENGTH * sizeof( WCHAR );
|
|||
|
Unicode.Buffer = UnicodeBuffer;
|
|||
|
|
|||
|
RtlInitAnsiString(&AnsiString,lpFileName);
|
|||
|
Status = RtlAnsiStringToUnicodeString(&Unicode,&AnsiString,FALSE);
|
|||
|
|
|||
|
if ( !NT_SUCCESS(Status) ) {
|
|||
|
if ( Status == STATUS_BUFFER_OVERFLOW ) {
|
|||
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
|||
|
} else {
|
|||
|
BaseSetLastNTError(Status);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return ( EncryptFileW( Unicode.Buffer ));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
EncryptFileW (
|
|||
|
LPCWSTR lpFileName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Win32 EncryptFile API
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be encrypted.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE on success, FALSE on failure. Callers may call GetLastError()
|
|||
|
for more information.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOL rc;
|
|||
|
DWORD Result;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Result = FeClientInfo->lpServices->EncryptFile( lpFileName );
|
|||
|
|
|||
|
if (ERROR_SUCCESS != Result) {
|
|||
|
SetLastError( Result );
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
DecryptFileA (
|
|||
|
IN LPCSTR lpFileName,
|
|||
|
IN DWORD dwRecovery
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
ANSI Stub for the DecryptFileW API
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be decrypted.
|
|||
|
|
|||
|
dwRecover - Supplies whether this is a recovery operation or a
|
|||
|
normal decryption operation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE on success, FALSE on failure. Callers may call GetLastError()
|
|||
|
for more information.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
UNICODE_STRING Unicode;
|
|||
|
WCHAR UnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
|
|||
|
ANSI_STRING AnsiString;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
Unicode.Length = 0;
|
|||
|
Unicode.MaximumLength = STATIC_UNICODE_BUFFER_LENGTH * sizeof( WCHAR );
|
|||
|
Unicode.Buffer = UnicodeBuffer;
|
|||
|
|
|||
|
RtlInitAnsiString(&AnsiString,lpFileName);
|
|||
|
Status = RtlAnsiStringToUnicodeString(&Unicode,&AnsiString,FALSE);
|
|||
|
|
|||
|
if ( !NT_SUCCESS(Status) ) {
|
|||
|
if ( Status == STATUS_BUFFER_OVERFLOW ) {
|
|||
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
|||
|
} else {
|
|||
|
BaseSetLastNTError(Status);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return ( DecryptFileW( Unicode.Buffer, dwRecovery ));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
DecryptFileW (
|
|||
|
IN LPCWSTR lpFileName,
|
|||
|
IN DWORD dwRecovery
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Win32 DecryptFile API
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be encrypted.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE on success, FALSE on failure. Callers may call GetLastError()
|
|||
|
for more information.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOL rc;
|
|||
|
DWORD Result;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Result = FeClientInfo->lpServices->DecryptFile( lpFileName, dwRecovery );
|
|||
|
|
|||
|
if (ERROR_SUCCESS != Result) {
|
|||
|
SetLastError( Result );
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
FileEncryptionStatusA (
|
|||
|
LPCSTR lpFileName,
|
|||
|
LPDWORD lpStatus
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
ANSI Stub to FileEncryptionStatusW
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - The name of the file to be checked.
|
|||
|
lpStatus - The status of the file.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE on success, FALSE on failure. Callers may call GetLastError() for more information.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ANSI_STRING AnsiString;
|
|||
|
NTSTATUS Status;
|
|||
|
UNICODE_STRING Unicode;
|
|||
|
WCHAR UnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
|
|||
|
|
|||
|
Unicode.Length = 0;
|
|||
|
Unicode.MaximumLength = STATIC_UNICODE_BUFFER_LENGTH * sizeof( WCHAR );
|
|||
|
Unicode.Buffer = UnicodeBuffer;
|
|||
|
|
|||
|
RtlInitAnsiString(&AnsiString,lpFileName);
|
|||
|
Status = RtlAnsiStringToUnicodeString(&Unicode,&AnsiString,FALSE);
|
|||
|
|
|||
|
if ( !NT_SUCCESS(Status) ) {
|
|||
|
if ( Status == STATUS_BUFFER_OVERFLOW ) {
|
|||
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
|||
|
} else {
|
|||
|
BaseSetLastNTError(Status);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return ( FileEncryptionStatusW( Unicode.Buffer, lpStatus ));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
FileEncryptionStatusW (
|
|||
|
LPCWSTR lpFileName,
|
|||
|
LPDWORD lpStatus
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Win32 FileEncryptionStatus API
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be encrypted.
|
|||
|
lpStatus - The status of the file.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE on success, FALSE on failure. Callers may call GetLastError()
|
|||
|
for more information.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
BOOL rc;
|
|||
|
DWORD Result;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return (FeClientInfo->lpServices->FileEncryptionStatus( lpFileName, lpStatus ));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
OpenEncryptedFileRawA(
|
|||
|
LPCSTR lpFileName,
|
|||
|
ULONG Flags,
|
|||
|
PVOID * Context
|
|||
|
)
|
|||
|
{
|
|||
|
ANSI_STRING AnsiString;
|
|||
|
NTSTATUS Status;
|
|||
|
UNICODE_STRING Unicode;
|
|||
|
WCHAR UnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
|
|||
|
|
|||
|
Unicode.Length = 0;
|
|||
|
Unicode.MaximumLength = STATIC_UNICODE_BUFFER_LENGTH * sizeof( WCHAR );
|
|||
|
Unicode.Buffer = UnicodeBuffer;
|
|||
|
|
|||
|
RtlInitAnsiString(&AnsiString,lpFileName);
|
|||
|
Status = RtlAnsiStringToUnicodeString(&Unicode,&AnsiString,FALSE);
|
|||
|
|
|||
|
if ( !NT_SUCCESS(Status) ) {
|
|||
|
if ( Status == STATUS_BUFFER_OVERFLOW ) {
|
|||
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
|||
|
} else {
|
|||
|
BaseSetLastNTError(Status);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return ( OpenEncryptedFileRawW( Unicode.Buffer, Flags, Context ));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
OpenEncryptedFileRawW(
|
|||
|
LPCWSTR lpFileName,
|
|||
|
ULONG Flags,
|
|||
|
PVOID * Context
|
|||
|
)
|
|||
|
{
|
|||
|
BOOL rc;
|
|||
|
DWORD Result;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(GetLastError());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return (FeClientInfo->lpServices->OpenFileRaw( lpFileName, Flags, Context ));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ReadEncryptedFileRaw(
|
|||
|
PFE_EXPORT_FUNC ExportCallback,
|
|||
|
PVOID CallbackContext,
|
|||
|
PVOID Context
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// It doesn't make sense to call this before calling OpenRaw, so don't
|
|||
|
// bother checking to see if the module is loaded or not. We'll fault
|
|||
|
// in the user process if it isn't.
|
|||
|
//
|
|||
|
|
|||
|
return (FeClientInfo->lpServices->ReadFileRaw( ExportCallback, CallbackContext, Context ));
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
WriteEncryptedFileRaw(
|
|||
|
PFE_IMPORT_FUNC ImportCallback,
|
|||
|
PVOID CallbackContext,
|
|||
|
PVOID Context
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// It doesn't make sense to call this before calling OpenRaw, so don't
|
|||
|
// bother checking to see if the module is loaded or not. We'll fault
|
|||
|
// in the user process if it isn't.
|
|||
|
//
|
|||
|
|
|||
|
return (FeClientInfo->lpServices->WriteFileRaw( ImportCallback, CallbackContext, Context ));
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
WINAPI
|
|||
|
CloseEncryptedFileRaw(
|
|||
|
PVOID Context
|
|||
|
)
|
|||
|
{
|
|||
|
FeClientInfo->lpServices->CloseFileRaw( Context );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
QueryUsersOnEncryptedFile(
|
|||
|
IN LPCWSTR lpFileName,
|
|||
|
OUT PENCRYPTION_CERTIFICATE_HASH_LIST * pUsers
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Win32 interface for adding users to an encrypted file.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be modified.
|
|||
|
|
|||
|
pUsers - Returns a list of users on the file. This parameter
|
|||
|
must be passed to FreeEncryptionCertificateHashList() when
|
|||
|
no longer needed.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 error.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ((lpFileName != NULL) && (pUsers != NULL)) {
|
|||
|
return(FeClientInfo->lpServices->QueryUsers( lpFileName, pUsers ));
|
|||
|
} else {
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
FreeEncryptionCertificateHashList(
|
|||
|
IN PENCRYPTION_CERTIFICATE_HASH_LIST pUsers
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Frees a certificate hash list as returned by QueryUsersOnEncryptedFile()
|
|||
|
and QueryRecoveryAgentsOnEncryptedFile().
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Supplies a list of users returned from QueryUsersOnEncryptedFile().
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 error.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// It is probably safe to assume that feclient.dll is loaded,
|
|||
|
// since we wouldn't have one of these structures to free
|
|||
|
// if it weren't.
|
|||
|
//
|
|||
|
|
|||
|
if (pUsers != NULL) {
|
|||
|
FeClientInfo->lpServices->FreeCertificateHashList( pUsers );
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// nothing to do
|
|||
|
//
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
QueryRecoveryAgentsOnEncryptedFile(
|
|||
|
IN LPCWSTR lpFileName,
|
|||
|
OUT PENCRYPTION_CERTIFICATE_HASH_LIST * pRecoveryAgents
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine returns a list of recovery agents on an encrypted
|
|||
|
file.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be examined.
|
|||
|
|
|||
|
pRecoveryAgents - Returns a list of recovery agents, represented
|
|||
|
by certificate hashes on the file. This list should be freed
|
|||
|
by calling FreeEncryptionCertificateHashList().
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
return-value - Description of conditions needed to return value. - or -
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ((lpFileName != NULL) && (pRecoveryAgents != NULL)) {
|
|||
|
return(FeClientInfo->lpServices->QueryRecoveryAgents( lpFileName, pRecoveryAgents ));
|
|||
|
} else {
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
RemoveUsersFromEncryptedFile(
|
|||
|
IN LPCWSTR lpFileName,
|
|||
|
IN PENCRYPTION_CERTIFICATE_HASH_LIST pHashes
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Takes a list of certificate hashes to be removed
|
|||
|
from the passed file. Any that are found are removed,
|
|||
|
the rest are ignored with no error return.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be modified.
|
|||
|
|
|||
|
pHashes - Supplies the list of hashes to be removed.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 Error
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ((lpFileName != NULL) && (pHashes != NULL)) {
|
|||
|
return(FeClientInfo->lpServices->RemoveUsers( lpFileName, pHashes ));
|
|||
|
} else {
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
AddUsersToEncryptedFile(
|
|||
|
IN LPCWSTR lpFileName,
|
|||
|
IN PENCRYPTION_CERTIFICATE_LIST pEncryptionCertificates
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine adds user keys to the passed encrypted file.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be encrypted.
|
|||
|
|
|||
|
pEncryptionCertificates - Supplies the list of certificates for
|
|||
|
new users to be added to the file.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 Error
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ((lpFileName != NULL) && (pEncryptionCertificates != NULL)) {
|
|||
|
return(FeClientInfo->lpServices->AddUsers( lpFileName, pEncryptionCertificates ));
|
|||
|
} else {
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
SetUserFileEncryptionKey(
|
|||
|
PENCRYPTION_CERTIFICATE pEncryptionCertificate
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine will set the user's current EFS key to the one
|
|||
|
contained in the passed certificate. If no certificate is
|
|||
|
passed, a new key will be generated automatically.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pEncryptionCertificate - Optionally supplies the certificate
|
|||
|
containing the new public key.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 error
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return(FeClientInfo->lpServices->SetKey( pEncryptionCertificate ));
|
|||
|
|
|||
|
/*
|
|||
|
if (pEncryptionCertificate != NULL) {
|
|||
|
return(FeClientInfo->lpServices->SetKey( pEncryptionCertificate ));
|
|||
|
} else {
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}*/
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
DuplicateEncryptionInfoFile(
|
|||
|
IN LPCWSTR SrcFileName,
|
|||
|
IN LPCWSTR DstFileName,
|
|||
|
IN DWORD dwCreationDistribution,
|
|||
|
IN DWORD dwAttributes,
|
|||
|
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine duplicates the encryption information from the source file to the
|
|||
|
destination file. Destination file will be created if not existing.
|
|||
|
|
|||
|
The destination file is overwritten.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SrcFileName - Supplies the source of the encryption information.
|
|||
|
|
|||
|
DstFileName - Supplies the target file, exclusive open is required on this file.
|
|||
|
|
|||
|
dwCreationDistribution - Create options.
|
|||
|
If dwCreationDistribution != CREATE_NEW, dwCreationDistribution = CREATE_ALWAYS
|
|||
|
|
|||
|
dwAttributes - File attributes.
|
|||
|
|
|||
|
lpSecurityAttributes - Security attributes.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
if (FeClientModule == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (SrcFileName && DstFileName) {
|
|||
|
return(FeClientInfo->lpServices->DuplicateEncryptionInfo( SrcFileName,
|
|||
|
DstFileName,
|
|||
|
dwCreationDistribution,
|
|||
|
dwAttributes,
|
|||
|
lpSecurityAttributes
|
|||
|
));
|
|||
|
} else {
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
EncryptionDisable(
|
|||
|
IN LPCWSTR DirPath,
|
|||
|
IN BOOL Disable
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine disable and enable EFS in the directory DirPath.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DirPath - Directory path.
|
|||
|
|
|||
|
Disable - TRUE to disable
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE for SUCCESS
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return(FeClientInfo->lpServices->DisableDir( DirPath, Disable ));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
WINADVAPI
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
EncryptedFileKeyInfo(
|
|||
|
IN LPCWSTR lpFileName,
|
|||
|
IN DWORD InfoClass,
|
|||
|
OUT PEFS_RPC_BLOB * KeyInfo
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Win32 interface for adding users to an encrypted file.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpFileName - Supplies the name of the file to be modified.
|
|||
|
|
|||
|
InfoClass - Information requested. Only support 1 for now.
|
|||
|
|
|||
|
KeyInfo - Returns Key info
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 error.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD rc;
|
|||
|
|
|||
|
//
|
|||
|
// See if the module has been loaded, and if not, load it into this
|
|||
|
// process.
|
|||
|
//
|
|||
|
|
|||
|
if (FeClientInfo == NULL) {
|
|||
|
rc = LoadAndInitFeClient();
|
|||
|
if (!rc) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ((lpFileName != NULL) && (KeyInfo != NULL)) {
|
|||
|
return(FeClientInfo->lpServices->GetKeyInfo( lpFileName, InfoClass, KeyInfo ));
|
|||
|
} else {
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
WINADVAPI
|
|||
|
VOID
|
|||
|
WINAPI
|
|||
|
FreeEncryptedFileKeyInfo(
|
|||
|
IN PEFS_RPC_BLOB pKeyInfo
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Frees a KeyInfo as returned by EncryptedFileKeyInfo();
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pKeyInfo - Supplies a KeyInfo returned from EncryptedFileKeyInfo().
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
No.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// It is probably safe to assume that feclient.dll is loaded,
|
|||
|
// since we wouldn't have one of these structures to free
|
|||
|
// if it weren't.
|
|||
|
//
|
|||
|
|
|||
|
if (pKeyInfo != NULL) {
|
|||
|
FeClientInfo->lpServices->FreeKeyInfo( pKeyInfo );
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// nothing to do
|
|||
|
//
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|