341 lines
9.7 KiB
C++
341 lines
9.7 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1994 Microsoft Corporation
|
||
|
|
||
|
Module Name :
|
||
|
|
||
|
dirnot.hxx
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module defines the directory notification class.
|
||
|
This object maintains information about a new client connection
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Rohan Phillips ( Rohanp ) 11-Dec-1995
|
||
|
|
||
|
Project:
|
||
|
|
||
|
SMTP Server DLL
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _SMTP_DIRNOT_HXX_
|
||
|
#define _SMTP_DIRNOT_HXX_
|
||
|
|
||
|
/************************************************************
|
||
|
* Include Headers
|
||
|
************************************************************/
|
||
|
|
||
|
//
|
||
|
// Redefine the type to indicate that this is a call-back function
|
||
|
//
|
||
|
typedef ATQ_COMPLETION PFN_ATQ_COMPLETION;
|
||
|
|
||
|
/************************************************************
|
||
|
* Symbolic Constants
|
||
|
************************************************************/
|
||
|
|
||
|
#define SMTP_DIRNOT_SIGNATURE_VALID 'DIRV'
|
||
|
#define SMTP_DIRNOT_SIGNATURE_FREE 'DIRF'
|
||
|
|
||
|
/************************************************************
|
||
|
* Type Definitions
|
||
|
************************************************************/
|
||
|
|
||
|
|
||
|
#define OUTSTANDING_NOTIFICATIONS 3
|
||
|
|
||
|
|
||
|
//
|
||
|
// forward class declrations
|
||
|
//
|
||
|
class CBuffer;
|
||
|
class SMTP_SERVER_INSTANCE;
|
||
|
//class CPickupRetryQ;
|
||
|
|
||
|
enum BUFIOSTATE {
|
||
|
CLIENT_WRITE, MESSAGE_READ
|
||
|
};
|
||
|
|
||
|
typedef struct _DIRNOT_OVERLAPPED
|
||
|
{
|
||
|
SERVEREVENT_OVERLAPPED SeoOverlapped;
|
||
|
// OVERLAPPED Overlapped;
|
||
|
CBuffer* pBuffer;
|
||
|
} DIRNOT_OVERLAPPED;
|
||
|
|
||
|
#define DIRNOT_BUFFER_SIGNATURE '3fuB'
|
||
|
#define DIRNOT_IO_BUFFER_SIGNATURE '3oiB'
|
||
|
|
||
|
// Exposed public
|
||
|
BOOL CopyRestOfMessage(HANDLE hSrcFile, HANDLE hDstFile);
|
||
|
|
||
|
class CIoBuffer
|
||
|
{
|
||
|
public:
|
||
|
static CPool Pool;
|
||
|
|
||
|
//
|
||
|
// override mem functions to use CPool functions
|
||
|
//
|
||
|
void* operator new( size_t cSize )
|
||
|
{ return Pool.Alloc(); }
|
||
|
|
||
|
void operator delete( void *pInstance )
|
||
|
{ Pool.Free( pInstance ); }
|
||
|
|
||
|
//
|
||
|
// the actual buffer area. size is set by reg entry
|
||
|
//
|
||
|
char Buffer[1];
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
class CBuffer {
|
||
|
|
||
|
public:
|
||
|
static CPool Pool;
|
||
|
|
||
|
CBuffer( BOOL bEncrypted = FALSE );
|
||
|
~CBuffer( void );
|
||
|
|
||
|
//
|
||
|
// override mem functions to use CPool functions
|
||
|
//
|
||
|
void* operator new( size_t cSize )
|
||
|
{ return Pool.Alloc(); }
|
||
|
|
||
|
void operator delete( void *pInstance )
|
||
|
{ Pool.Free(pInstance); }
|
||
|
|
||
|
//
|
||
|
// is this buffer in the right pool?
|
||
|
//
|
||
|
BOOL IsValid( DWORD Signature );
|
||
|
//
|
||
|
// get the number of bytes in the buffer
|
||
|
//
|
||
|
DWORD GetSize() { return m_cCount; }
|
||
|
//
|
||
|
// get the max number of bytes in the buffer
|
||
|
//
|
||
|
DWORD GetMaxSize() { return Pool.GetInstanceSize(); }
|
||
|
//
|
||
|
// set the expected number of bytes in the buffer
|
||
|
//
|
||
|
void SetSize( DWORD dw ) { m_cCount = dw; }
|
||
|
//
|
||
|
// get a pointer to the buffers data area
|
||
|
//
|
||
|
LPBYTE GetData() { return (LPBYTE)m_pIoBuffer; }
|
||
|
//
|
||
|
// copy data into a buffer
|
||
|
//
|
||
|
BOOL ReplaceData(PVOID src, DWORD count);
|
||
|
//
|
||
|
// clear the buffer so that it can be reused
|
||
|
//
|
||
|
void Reset(void) { m_cCount = 0; }
|
||
|
//
|
||
|
// get the IoState for this operation
|
||
|
//
|
||
|
BUFIOSTATE GetIoState(void) { return m_eIoState; }
|
||
|
//
|
||
|
// set the IoState for this operation
|
||
|
//
|
||
|
void SetIoState(BUFIOSTATE io) { m_eIoState = io; }
|
||
|
|
||
|
//
|
||
|
// signature for the class
|
||
|
//
|
||
|
DWORD m_dwSignature;
|
||
|
//
|
||
|
// the extended IO overlap structure
|
||
|
// In order for the completion port to work, the overlap
|
||
|
// structure is extended to add one pointer to the
|
||
|
// associated CBuffer object
|
||
|
//
|
||
|
DIRNOT_OVERLAPPED m_Overlapped;
|
||
|
|
||
|
private:
|
||
|
//
|
||
|
// the amount of data in the buffer
|
||
|
//
|
||
|
DWORD m_cCount;
|
||
|
//
|
||
|
// the initial IO type
|
||
|
//
|
||
|
BUFIOSTATE m_eIoState;
|
||
|
//
|
||
|
// the buffer itself must be the last member
|
||
|
//
|
||
|
CIoBuffer* m_pIoBuffer;
|
||
|
//
|
||
|
// whether this buffer will be used for encrypted data
|
||
|
//
|
||
|
BOOL m_bEncrypted;
|
||
|
};
|
||
|
|
||
|
/*++
|
||
|
class SMTP_DIRNOT
|
||
|
|
||
|
It maintains the state of the directory notifications.
|
||
|
|
||
|
--*/
|
||
|
class SMTP_DIRNOT
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
~SMTP_DIRNOT(void);
|
||
|
BOOL ProcessClient( IN DWORD cbWritten,
|
||
|
IN DWORD dwCompletionStatus,
|
||
|
IN OUT OVERLAPPED * lpo);
|
||
|
|
||
|
BOOL ProcessFile(IMailMsgProperties *pIMsg);
|
||
|
|
||
|
static SMTP_DIRNOT * CreateSmtpDirNotification (char * Dir, ATQ_COMPLETION pfnCompletion, SMTP_SERVER_INSTANCE * pInstance);
|
||
|
static DWORD WINAPI PickupInitialFiles(void * ClassPtr);
|
||
|
static DWORD WINAPI CreateNonIISFindThread(void * ClassPtr);
|
||
|
|
||
|
void CloseDirHandle (void);
|
||
|
LONG GetThreadCount(void) const {return m_cActiveThreads;}
|
||
|
PATQ_CONTEXT QueryAtqContext(void) const {return m_pAtqContext;}
|
||
|
|
||
|
void SetPickupRetryQueueEvent(void);
|
||
|
|
||
|
SMTP_SERVER_INSTANCE * QuerySmtpInstance( VOID ) const
|
||
|
{ _ASSERT(m_pInstance != NULL); return m_pInstance; }
|
||
|
|
||
|
BOOL IsSmtpInstance( VOID ) const
|
||
|
{ return m_pInstance != NULL; }
|
||
|
|
||
|
VOID SetSmtpInstance( IN SMTP_SERVER_INSTANCE * pInstance )
|
||
|
{ _ASSERT(m_pInstance == NULL); m_pInstance = pInstance; }
|
||
|
|
||
|
//
|
||
|
// IsValid()
|
||
|
// o Checks the signature of the object to determine
|
||
|
// if this is a valid SMTP_DIRNOT object.
|
||
|
//
|
||
|
// Returns: TRUE on success and FALSE if invalid.
|
||
|
//
|
||
|
BOOL IsValid( VOID) const
|
||
|
{ return ( m_Signature == SMTP_DIRNOT_SIGNATURE_VALID); }
|
||
|
|
||
|
|
||
|
//
|
||
|
// this function is also called by smtpcli.cxx to create extra delivery threads when needed.
|
||
|
//
|
||
|
void CreateLocalDeliveryThread (void);
|
||
|
|
||
|
static VOID ReadDirectoryCompletion(PVOID pvContext, DWORD cbWritten,
|
||
|
DWORD dwCompletionStatus, OVERLAPPED * lpo);
|
||
|
private :
|
||
|
|
||
|
ULONG m_Signature;
|
||
|
SMTP_SERVER_INSTANCE * m_pInstance;
|
||
|
//CPickupRetryQ * m_pRetryQ;
|
||
|
HANDLE m_hDir;
|
||
|
LONG m_cPendingIoCount;
|
||
|
LONG m_cDirChangeIoCount;
|
||
|
LONG m_cActiveThreads;
|
||
|
PATQ_CONTEXT m_pAtqContext;
|
||
|
CRITICAL_SECTION m_CritFindLock;
|
||
|
LONG m_FindThreads;
|
||
|
HANDLE m_FindFirstHandle;
|
||
|
BOOL m_bDelayedFind;
|
||
|
|
||
|
SMTP_DIRNOT (SMTP_SERVER_INSTANCE * pInstance);
|
||
|
BOOL DoFindFirstFile(BOOL bIISThread = TRUE);
|
||
|
BOOL InitializeObject (char *DirPickupName, ATQ_COMPLETION pfnCompletion);
|
||
|
BOOL CreateToList (char *AddrsList, IMailMsgRecipientsAdd *pIMsgRecips, IMailMsgProperties *pIMsg);
|
||
|
BOOL PendDirChangeNotification (void);
|
||
|
BOOL ProcessDirNotification( IN DWORD InputBufferLen, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED * lpo);
|
||
|
LONG IncPendingIoCount(void) { return InterlockedIncrement( &m_cPendingIoCount ); }
|
||
|
LONG DecPendingIoCount(void) { return InterlockedDecrement( &m_cPendingIoCount ); }
|
||
|
DWORD GetPendingIoCount(void) { return m_cPendingIoCount; }
|
||
|
|
||
|
LONG IncDirChangeIoCount(void) { return InterlockedIncrement( &m_cDirChangeIoCount ); }
|
||
|
LONG DecDirChangeIoCount(void) { return InterlockedDecrement( &m_cDirChangeIoCount ); }
|
||
|
|
||
|
LONG IncThreadCount(void) { return InterlockedIncrement( &m_cActiveThreads ); }
|
||
|
LONG DecThreadCount(void) { return InterlockedDecrement( &m_cActiveThreads ); }
|
||
|
|
||
|
VOID LockFind() { EnterCriticalSection(&m_CritFindLock); }
|
||
|
VOID UnLockFind() { LeaveCriticalSection(&m_CritFindLock); }
|
||
|
|
||
|
BOOL IncFindThreads(void)
|
||
|
{
|
||
|
LONG NewFindThreads;
|
||
|
|
||
|
NewFindThreads = InterlockedIncrement( &m_FindThreads );
|
||
|
|
||
|
if (NewFindThreads > g_MaxFindThreads)
|
||
|
{
|
||
|
InterlockedDecrement( &m_FindThreads );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
LONG DecFindThreads(void) { return InterlockedDecrement( &m_FindThreads ); }
|
||
|
|
||
|
|
||
|
HANDLE GetFindFirstHandle()
|
||
|
{
|
||
|
return m_FindFirstHandle;
|
||
|
}
|
||
|
|
||
|
VOID SetFindFirstHandle(HANDLE hFind)
|
||
|
{
|
||
|
m_FindFirstHandle = hFind;
|
||
|
}
|
||
|
|
||
|
VOID CloseFindHandle()
|
||
|
{
|
||
|
LONG NumThreads;
|
||
|
|
||
|
NumThreads = DecFindThreads();
|
||
|
|
||
|
if (NumThreads == 0)
|
||
|
{
|
||
|
_VERIFY(FindClose(m_FindFirstHandle));
|
||
|
|
||
|
m_FindFirstHandle = INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
DWORD GetNumFindThreads() { return m_FindThreads; }
|
||
|
|
||
|
|
||
|
VOID SetDelayedFindNotification (BOOL bIn) { m_bDelayedFind = bIn; }
|
||
|
BOOL GetDelayedFindNotification () { return m_bDelayedFind; }
|
||
|
HRESULT SetAvailableMailMsgProperties( IMailMsgProperties *pIMsg );
|
||
|
HRESULT GetAndPersistRFC822Headers( char* InputLine,
|
||
|
char* pszValueBuf,
|
||
|
IMailMsgProperties* pIMsg,
|
||
|
BOOL & fSeenRFC822FromAddress,
|
||
|
BOOL & fSeenRFC822ToAddress,
|
||
|
BOOL & fSeenRFC822BccAddress,
|
||
|
BOOL & fSeenRFC822CcAddress,
|
||
|
BOOL & fSeenRFC822Subject,
|
||
|
BOOL & fSeenRFC822SenderAddress,
|
||
|
BOOL & fSeenXPriority,
|
||
|
BOOL & fSeenContentType,
|
||
|
BOOL & fSetContentType );
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/************************ End of File ***********************/
|