|
|
/*++
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
|