473 lines
12 KiB
C++
473 lines
12 KiB
C++
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Copyright (c) 1996 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
isapiext.hxx
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
SMTP ISAPI layer header file. These definitions should only be
|
||
|
available to the ISAPI layer and the SMTP service.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
keithlau June 28, 1996 Created file
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _ISAPIEXT_H_
|
||
|
#define _ISAPIEXT_H_
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// Include files
|
||
|
//
|
||
|
#include "smtpext.h"
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// Defined values
|
||
|
//
|
||
|
|
||
|
#define SSE_ISAPI_SIGNATURE 0xa5a5
|
||
|
#define SSE_EXT_SIGNATURE 0x5a5a
|
||
|
#define SSE_CONTEXT_SIGNATURE 0xaa55
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// Return codes
|
||
|
//
|
||
|
|
||
|
#define SSE_STATUS_INTERNAL_ERROR 0x1000
|
||
|
#define SSE_STATUS_EXCEPTION 0x1001
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// Type definitions
|
||
|
//
|
||
|
|
||
|
// Enumerated type for different types of extensions in the future
|
||
|
typedef enum _EXTENSION_TYPE
|
||
|
{
|
||
|
DELIVERY_EXTENSION = 0, // Delivery extension
|
||
|
MESSAGE_EXTENSION, // Message extension
|
||
|
// Add new types here ...
|
||
|
INVALID_EXTENSION_TYPE // THIS MUST ALWAYS BE THE LAST TYPE
|
||
|
|
||
|
} EXTENSION_TYPE;
|
||
|
|
||
|
// Since we use a DWORD to store extension attributes, we have
|
||
|
// a realistic upper bound for binding points
|
||
|
#define MAX_POSSIBLE_EXTENSION_TYPE 32
|
||
|
|
||
|
|
||
|
// The SMTP server fills in one of these before it calls
|
||
|
// CallDeliveryExtension()
|
||
|
typedef struct _DELIVERY_EXTENSION_BLOCK
|
||
|
{
|
||
|
HANDLE hImpersonation; // Token for user impersonation
|
||
|
|
||
|
LPSTR lpszSender; // Address of the message sender
|
||
|
LPSTR lpszRecipient; // Recipient currently being processed
|
||
|
LPSTR lpszMailboxPath; // Recipient's mailbox path
|
||
|
LPSTR lpszMessageFileName; // Message file path
|
||
|
LPBYTE lpbMapping; // Memory-mapped buffer of message
|
||
|
DWORD dwSize; // Size of memory map
|
||
|
CHAR szErrorTranscript[SSE_MAX_EXT_DLL_NAME_LEN];
|
||
|
// Buffer for returning error transcript
|
||
|
|
||
|
} DELIVERY_EXTENSION_BLOCK, *LPDELIVERY_EXTENSION_BLOCK;
|
||
|
|
||
|
// The SMTP server fills in one of these before it calls
|
||
|
// CallMessageExtension()
|
||
|
typedef struct _MESSAGE_EXTENSION_BLOCK
|
||
|
{
|
||
|
LPSTR lpszSender; // Address of the message sender
|
||
|
LPSTR lpszRecipientList; // Recipient list
|
||
|
LPSTR lpszMessageFileName; // Message file path
|
||
|
LPBYTE lpbMapping; // Memory-mapped buffer of message
|
||
|
DWORD dwSize; // Size of memory map
|
||
|
CHAR szErrorTranscript[SSE_MAX_EXT_DLL_NAME_LEN];
|
||
|
// Buffer for returning error transcript
|
||
|
|
||
|
} MESSAGE_EXTENSION_BLOCK, *LPMESSAGE_EXTENSION_BLOCK;
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// External declaration for the one and only SMTP ISAPI object instance
|
||
|
//
|
||
|
|
||
|
class SMTP_ISAPI;
|
||
|
|
||
|
// ====================================================================
|
||
|
// Entry point exposed to the SMTP service
|
||
|
//
|
||
|
|
||
|
// Entry point to initialize the ISAPI layer
|
||
|
extern "C" SMTP_ISAPI *InitializeExtensions( DWORD dwInstanceId,
|
||
|
LPSTR *aszMultiSzExtensionList );
|
||
|
|
||
|
// Entry point to shut down the ISAPI layer
|
||
|
extern "C" VOID TerminateExtensions( SMTP_ISAPI *pSdkInstance );
|
||
|
|
||
|
// Entry point for the SMTP service to call into server extensions
|
||
|
extern "C" DWORD CallDeliveryExtension( SMTP_ISAPI *pSdkInstance,
|
||
|
LPDELIVERY_EXTENSION_BLOCK lpDeb );
|
||
|
|
||
|
// Entry point for the SMTP service to call into server extensions
|
||
|
extern "C" DWORD CallMessageExtension( SMTP_ISAPI *pSdkInstance,
|
||
|
LPMESSAGE_EXTENSION_BLOCK lpMeb );
|
||
|
|
||
|
// Function to query if extensions are initialized
|
||
|
extern "C" BOOL ExtensionLayerIsInitialized( SMTP_ISAPI *pSdkInstance );
|
||
|
|
||
|
// Function to query if extensions are loaded for a particular binding point
|
||
|
extern "C" BOOL ExtensionsAreLoaded( SMTP_ISAPI *pSdkInstance,
|
||
|
EXTENSION_TYPE ExtensionType );
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// Define types for entry points
|
||
|
//
|
||
|
|
||
|
typedef BOOL (WINAPI * PFN_GETEXTENSIONVERSION)( SSE_VERSION_INFO *pVer );
|
||
|
typedef DWORD (WINAPI * PFN_EXTENSIONPROC)( SSE_EXTENSION_CONTROL_BLOCK *pServerContext );
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// Top-level SMTP ISAPI object
|
||
|
//
|
||
|
|
||
|
class SMTP_EXT;
|
||
|
class SMTP_SERVER_CONTEXT;
|
||
|
|
||
|
class SMTP_ISAPI
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SMTP_ISAPI();
|
||
|
~SMTP_ISAPI();
|
||
|
|
||
|
void *operator new (size_t cSize) { return LocalAlloc(0, cSize); }
|
||
|
void operator delete (void *pInstance) { LocalFree(pInstance); }
|
||
|
|
||
|
BOOL Initialize( DWORD dwInstanceId, LPSTR *aszMultiSzExtensionList );
|
||
|
|
||
|
VOID Terminate( VOID );
|
||
|
|
||
|
BOOL IsInitialized( VOID )
|
||
|
{
|
||
|
return(m_dwSignature == SSE_ISAPI_SIGNATURE);
|
||
|
}
|
||
|
|
||
|
DWORD CallExtension( EXTENSION_TYPE ExtensionType,
|
||
|
LPVOID lpvExtensionBlock );
|
||
|
|
||
|
LIST_ENTRY * QueryExtensionList( VOID )
|
||
|
{
|
||
|
return( &m_ExtensionList );
|
||
|
}
|
||
|
|
||
|
LIST_ENTRY * QueryContextList( VOID )
|
||
|
{
|
||
|
return( &m_ContextList );
|
||
|
}
|
||
|
|
||
|
DWORD QueryExtensionsForType( EXTENSION_TYPE ExtensionType )
|
||
|
{
|
||
|
return(m_dwExtensionsOfType[ExtensionType]);
|
||
|
}
|
||
|
|
||
|
BOOL IsExtensionTypeValid( EXTENSION_TYPE ExtensionType )
|
||
|
{
|
||
|
return( (ExtensionType < INVALID_EXTENSION_TYPE)?TRUE:FALSE );
|
||
|
}
|
||
|
|
||
|
VOID LockContextList( VOID )
|
||
|
{
|
||
|
EnterCriticalSection( &m_csContextLock );
|
||
|
}
|
||
|
|
||
|
VOID UnlockContextList( VOID )
|
||
|
{
|
||
|
LeaveCriticalSection( &m_csContextLock );
|
||
|
}
|
||
|
|
||
|
// This logs any exceptions
|
||
|
static VOID LogExceptionEvent( DWORD dwInstanceId, SMTP_EXT *lpExtension );
|
||
|
|
||
|
// Catch-all check to see if a given string terminates
|
||
|
// within the given length, should be used after IsBadStringPtr
|
||
|
static BOOL StringIsTerminated( CHAR *lpszString,
|
||
|
DWORD dwMaxLength)
|
||
|
{
|
||
|
while (dwMaxLength--)
|
||
|
if (!*lpszString++)
|
||
|
return(TRUE);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
SMTP_EXT *SearchExtensionFromList(CHAR *lpszModuleName);
|
||
|
|
||
|
DWORD ChainExtensions(SMTP_SERVER_CONTEXT *lpServerContext,
|
||
|
EXTENSION_TYPE ExtensionType);
|
||
|
|
||
|
BOOL LoadExtensionDll(CHAR *lpszModuleName,
|
||
|
EXTENSION_TYPE ExtensionType);
|
||
|
|
||
|
BOOL LoadExtensions(LPSTR lpszList,
|
||
|
EXTENSION_TYPE ExtensionType);
|
||
|
|
||
|
VOID FreeExtensionsOfType(EXTENSION_TYPE ExtensionType);
|
||
|
|
||
|
VOID FreeUnusedExtensions( VOID );
|
||
|
|
||
|
VOID FreeExtensions( VOID );
|
||
|
|
||
|
BOOL ComposeErrorTranscript(SMTP_SERVER_CONTEXT *lpServerContext,
|
||
|
CHAR *lpszExtensionName,
|
||
|
DWORD dwResult);
|
||
|
|
||
|
// These are extension type-specific conversion routines
|
||
|
BOOL CreateEcbFromDeb( SMTP_SERVER_CONTEXT *lpContext,
|
||
|
LPDELIVERY_EXTENSION_BLOCK lpDeb,
|
||
|
LPSSE_EXTENSION_CONTROL_BLOCK lpEcb);
|
||
|
|
||
|
// These are extension type-specific conversion routines
|
||
|
BOOL CreateEcbFromMeb( SMTP_SERVER_CONTEXT *lpContext,
|
||
|
LPMESSAGE_EXTENSION_BLOCK lpDeb,
|
||
|
LPSSE_EXTENSION_CONTROL_BLOCK lpEcb);
|
||
|
|
||
|
DWORD m_dwSignature; // Signature
|
||
|
|
||
|
DWORD m_dwExtensionsOfType[MAX_POSSIBLE_EXTENSION_TYPE];
|
||
|
// Counter for each binding point
|
||
|
|
||
|
DWORD m_dwInstanceId; // Server instance ID
|
||
|
|
||
|
LIST_ENTRY m_ExtensionList; // Extension List Head
|
||
|
LIST_ENTRY m_ContextList; // Server Context List Head
|
||
|
|
||
|
CRITICAL_SECTION m_csContextLock; // Server context list lock
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// SMTP server extension object, one exists for each extension loaded
|
||
|
//
|
||
|
|
||
|
class SMTP_EXT
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SMTP_EXT( SMTP_ISAPI *lpSdkInstance,
|
||
|
CHAR *lpszModuleName,
|
||
|
EXTENSION_TYPE ExtensionType,
|
||
|
HMODULE hMod,
|
||
|
PFN_EXTENSIONPROC pfnEntryPoint )
|
||
|
{
|
||
|
_ASSERT(lpszModuleName);
|
||
|
_ASSERT(lpSdkInstance);
|
||
|
_ASSERT(lpSdkInstance->StringIsTerminated(lpszModuleName,
|
||
|
SSE_MAX_EXT_DLL_NAME_LEN));
|
||
|
|
||
|
m_dwSignature = 0;
|
||
|
|
||
|
// Initialize members
|
||
|
lstrcpy(m_szModuleName, lpszModuleName);
|
||
|
m_hMod = hMod;
|
||
|
|
||
|
m_dwExtensionType = 0;
|
||
|
for (DWORD i = 0; i < MAX_POSSIBLE_EXTENSION_TYPE; i++)
|
||
|
m_pfnEntryPoint[i] = NULL;
|
||
|
IncludeExtensionType(ExtensionType, pfnEntryPoint);
|
||
|
|
||
|
m_dwSignature = SSE_EXT_SIGNATURE;
|
||
|
}
|
||
|
|
||
|
~SMTP_EXT( VOID ) {}
|
||
|
|
||
|
BOOL IsValid( VOID )
|
||
|
{
|
||
|
return( m_dwSignature == SSE_EXT_SIGNATURE );
|
||
|
}
|
||
|
|
||
|
LIST_ENTRY * QueryListEntry( VOID )
|
||
|
{
|
||
|
return( &m_ListEntry );
|
||
|
}
|
||
|
|
||
|
BOOL ExtensionTypeIncludes(EXTENSION_TYPE ExtensionType)
|
||
|
{
|
||
|
_ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
|
||
|
return( (m_dwExtensionType & (1 << ExtensionType)) != 0 );
|
||
|
}
|
||
|
|
||
|
BOOL ExtensionIsUnused( VOID )
|
||
|
{
|
||
|
return(m_dwExtensionType == 0);
|
||
|
}
|
||
|
|
||
|
PFN_EXTENSIONPROC QueryEntryPoint(EXTENSION_TYPE ExtensionType)
|
||
|
{
|
||
|
if (ExtensionTypeIncludes(ExtensionType))
|
||
|
return( m_pfnEntryPoint[ExtensionType] );
|
||
|
else
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
VOID IncludeExtensionType(EXTENSION_TYPE ExtensionType,
|
||
|
PFN_EXTENSIONPROC pfnEntryPoint)
|
||
|
{
|
||
|
_ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
|
||
|
m_dwExtensionType |= (1 << ExtensionType);
|
||
|
m_pfnEntryPoint[ExtensionType] = pfnEntryPoint;
|
||
|
}
|
||
|
|
||
|
VOID RemoveExtensionType(EXTENSION_TYPE ExtensionType)
|
||
|
{
|
||
|
_ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
|
||
|
m_dwExtensionType &= (~(1 << ExtensionType));
|
||
|
m_pfnEntryPoint[ExtensionType] = NULL;
|
||
|
}
|
||
|
|
||
|
CHAR * QueryModuleName( VOID )
|
||
|
{
|
||
|
return( m_szModuleName );
|
||
|
}
|
||
|
|
||
|
HMODULE QueryHMod( VOID )
|
||
|
{
|
||
|
return( m_hMod );
|
||
|
}
|
||
|
|
||
|
LIST_ENTRY m_ListEntry;
|
||
|
|
||
|
private:
|
||
|
|
||
|
DWORD m_dwExtensionType; // Extension type(s)
|
||
|
CHAR m_szModuleName[SSE_MAX_EXT_DLL_NAME_LEN];
|
||
|
// Name of module
|
||
|
HMODULE m_hMod; // Handle to library
|
||
|
PFN_EXTENSIONPROC m_pfnEntryPoint[MAX_POSSIBLE_EXTENSION_TYPE];
|
||
|
// Entry point into binding points
|
||
|
|
||
|
DWORD m_dwSignature; // Signature
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
// ====================================================================
|
||
|
// SMTP server context, one exists for every thread inside ISAPI
|
||
|
//
|
||
|
|
||
|
typedef LPVOID LPSSE_ECB;
|
||
|
typedef LPVOID LPSSE_SEB;
|
||
|
|
||
|
class SMTP_SERVER_CONTEXT
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SMTP_SERVER_CONTEXT(SMTP_ISAPI *pSdkInstance,
|
||
|
EXTENSION_TYPE ExtensionType,
|
||
|
LPSSE_SEB lpDeb,
|
||
|
LPSSE_ECB lpEcb,
|
||
|
HANDLE hImpersonation);
|
||
|
|
||
|
~SMTP_SERVER_CONTEXT( VOID );
|
||
|
|
||
|
BOOL Initialize( VOID );
|
||
|
|
||
|
BOOL IsValid( VOID )
|
||
|
{
|
||
|
return( m_dwSignature == SSE_CONTEXT_SIGNATURE );
|
||
|
}
|
||
|
|
||
|
LIST_ENTRY * QueryListEntry( VOID )
|
||
|
{
|
||
|
return( &m_ListEntry );
|
||
|
}
|
||
|
|
||
|
HANDLE QueryThread( VOID )
|
||
|
{
|
||
|
return( m_hCurrentThread );
|
||
|
}
|
||
|
|
||
|
SMTP_EXT * QueryExtension( VOID )
|
||
|
{
|
||
|
return( m_pCurrentExtension );
|
||
|
}
|
||
|
|
||
|
VOID SetExtension( SMTP_EXT *pExtension )
|
||
|
{
|
||
|
m_pCurrentExtension = pExtension;
|
||
|
}
|
||
|
|
||
|
EXTENSION_TYPE QueryExtensionType( VOID )
|
||
|
{
|
||
|
return( m_ExtensionType );
|
||
|
}
|
||
|
|
||
|
VOID SetExtensionType( EXTENSION_TYPE ExtensionType )
|
||
|
{
|
||
|
_ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
|
||
|
m_ExtensionType = ExtensionType;
|
||
|
}
|
||
|
|
||
|
LPSSE_ECB QueryExtensionControlBlock( VOID )
|
||
|
{
|
||
|
return( m_lpEcb );
|
||
|
}
|
||
|
|
||
|
LPSSE_SEB QueryServerExtensionBlock( VOID )
|
||
|
{
|
||
|
return( m_lpSeb );
|
||
|
}
|
||
|
|
||
|
BOOL QueryValidTimeout( VOID )
|
||
|
{
|
||
|
return( (InterlockedDecrement(&m_InterlockedState) < 0)?TRUE:FALSE );
|
||
|
}
|
||
|
|
||
|
BOOL QueryValidCompletion( VOID )
|
||
|
{
|
||
|
return( (InterlockedIncrement(&m_InterlockedState) > 0)?TRUE:FALSE );
|
||
|
}
|
||
|
|
||
|
LIST_ENTRY m_ListEntry; // Link to next server context
|
||
|
|
||
|
private:
|
||
|
|
||
|
SMTP_ISAPI *m_pSdkInstance; // Pointer to SDK instance
|
||
|
|
||
|
LPSSE_SEB m_lpSeb; // Ext. block passed from SMTP
|
||
|
// server, this is used to fill
|
||
|
// in the fields of m_lpEcb
|
||
|
|
||
|
LPSSE_ECB m_lpEcb; // Extension control block
|
||
|
|
||
|
DWORD m_dwSignature; // Signature
|
||
|
|
||
|
SMTP_EXT *m_pCurrentExtension; // Current extension object
|
||
|
EXTENSION_TYPE m_ExtensionType; // Current extension type
|
||
|
|
||
|
HANDLE m_hCurrentThread; // Handle of current thread
|
||
|
long m_InterlockedState; // Sync. variable
|
||
|
|
||
|
HANDLE m_hImpersonation; // Impersonation handle
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|