windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/smtp/inc/isapiext.hxx

473 lines
12 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
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