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