Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. isapiext.hxx
  5. Abstract:
  6. SMTP ISAPI layer header file. These definitions should only be
  7. available to the ISAPI layer and the SMTP service.
  8. Author:
  9. keithlau June 28, 1996 Created file
  10. Revision History:
  11. --*/
  12. #ifndef _ISAPIEXT_H_
  13. #define _ISAPIEXT_H_
  14. // ====================================================================
  15. // Include files
  16. //
  17. #include "smtpext.h"
  18. // ====================================================================
  19. // Defined values
  20. //
  21. #define SSE_ISAPI_SIGNATURE 0xa5a5
  22. #define SSE_EXT_SIGNATURE 0x5a5a
  23. #define SSE_CONTEXT_SIGNATURE 0xaa55
  24. // ====================================================================
  25. // Return codes
  26. //
  27. #define SSE_STATUS_INTERNAL_ERROR 0x1000
  28. #define SSE_STATUS_EXCEPTION 0x1001
  29. // ====================================================================
  30. // Type definitions
  31. //
  32. // Enumerated type for different types of extensions in the future
  33. typedef enum _EXTENSION_TYPE
  34. {
  35. DELIVERY_EXTENSION = 0, // Delivery extension
  36. MESSAGE_EXTENSION, // Message extension
  37. // Add new types here ...
  38. INVALID_EXTENSION_TYPE // THIS MUST ALWAYS BE THE LAST TYPE
  39. } EXTENSION_TYPE;
  40. // Since we use a DWORD to store extension attributes, we have
  41. // a realistic upper bound for binding points
  42. #define MAX_POSSIBLE_EXTENSION_TYPE 32
  43. // The SMTP server fills in one of these before it calls
  44. // CallDeliveryExtension()
  45. typedef struct _DELIVERY_EXTENSION_BLOCK
  46. {
  47. HANDLE hImpersonation; // Token for user impersonation
  48. LPSTR lpszSender; // Address of the message sender
  49. LPSTR lpszRecipient; // Recipient currently being processed
  50. LPSTR lpszMailboxPath; // Recipient's mailbox path
  51. LPSTR lpszMessageFileName; // Message file path
  52. LPBYTE lpbMapping; // Memory-mapped buffer of message
  53. DWORD dwSize; // Size of memory map
  54. CHAR szErrorTranscript[SSE_MAX_EXT_DLL_NAME_LEN];
  55. // Buffer for returning error transcript
  56. } DELIVERY_EXTENSION_BLOCK, *LPDELIVERY_EXTENSION_BLOCK;
  57. // The SMTP server fills in one of these before it calls
  58. // CallMessageExtension()
  59. typedef struct _MESSAGE_EXTENSION_BLOCK
  60. {
  61. LPSTR lpszSender; // Address of the message sender
  62. LPSTR lpszRecipientList; // Recipient list
  63. LPSTR lpszMessageFileName; // Message file path
  64. LPBYTE lpbMapping; // Memory-mapped buffer of message
  65. DWORD dwSize; // Size of memory map
  66. CHAR szErrorTranscript[SSE_MAX_EXT_DLL_NAME_LEN];
  67. // Buffer for returning error transcript
  68. } MESSAGE_EXTENSION_BLOCK, *LPMESSAGE_EXTENSION_BLOCK;
  69. // ====================================================================
  70. // External declaration for the one and only SMTP ISAPI object instance
  71. //
  72. class SMTP_ISAPI;
  73. // ====================================================================
  74. // Entry point exposed to the SMTP service
  75. //
  76. // Entry point to initialize the ISAPI layer
  77. extern "C" SMTP_ISAPI *InitializeExtensions( DWORD dwInstanceId,
  78. LPSTR *aszMultiSzExtensionList );
  79. // Entry point to shut down the ISAPI layer
  80. extern "C" VOID TerminateExtensions( SMTP_ISAPI *pSdkInstance );
  81. // Entry point for the SMTP service to call into server extensions
  82. extern "C" DWORD CallDeliveryExtension( SMTP_ISAPI *pSdkInstance,
  83. LPDELIVERY_EXTENSION_BLOCK lpDeb );
  84. // Entry point for the SMTP service to call into server extensions
  85. extern "C" DWORD CallMessageExtension( SMTP_ISAPI *pSdkInstance,
  86. LPMESSAGE_EXTENSION_BLOCK lpMeb );
  87. // Function to query if extensions are initialized
  88. extern "C" BOOL ExtensionLayerIsInitialized( SMTP_ISAPI *pSdkInstance );
  89. // Function to query if extensions are loaded for a particular binding point
  90. extern "C" BOOL ExtensionsAreLoaded( SMTP_ISAPI *pSdkInstance,
  91. EXTENSION_TYPE ExtensionType );
  92. // ====================================================================
  93. // Define types for entry points
  94. //
  95. typedef BOOL (WINAPI * PFN_GETEXTENSIONVERSION)( SSE_VERSION_INFO *pVer );
  96. typedef DWORD (WINAPI * PFN_EXTENSIONPROC)( SSE_EXTENSION_CONTROL_BLOCK *pServerContext );
  97. // ====================================================================
  98. // Top-level SMTP ISAPI object
  99. //
  100. class SMTP_EXT;
  101. class SMTP_SERVER_CONTEXT;
  102. class SMTP_ISAPI
  103. {
  104. public:
  105. SMTP_ISAPI();
  106. ~SMTP_ISAPI();
  107. void *operator new (size_t cSize) { return LocalAlloc(0, cSize); }
  108. void operator delete (void *pInstance) { LocalFree(pInstance); }
  109. BOOL Initialize( DWORD dwInstanceId, LPSTR *aszMultiSzExtensionList );
  110. VOID Terminate( VOID );
  111. BOOL IsInitialized( VOID )
  112. {
  113. return(m_dwSignature == SSE_ISAPI_SIGNATURE);
  114. }
  115. DWORD CallExtension( EXTENSION_TYPE ExtensionType,
  116. LPVOID lpvExtensionBlock );
  117. LIST_ENTRY * QueryExtensionList( VOID )
  118. {
  119. return( &m_ExtensionList );
  120. }
  121. LIST_ENTRY * QueryContextList( VOID )
  122. {
  123. return( &m_ContextList );
  124. }
  125. DWORD QueryExtensionsForType( EXTENSION_TYPE ExtensionType )
  126. {
  127. return(m_dwExtensionsOfType[ExtensionType]);
  128. }
  129. BOOL IsExtensionTypeValid( EXTENSION_TYPE ExtensionType )
  130. {
  131. return( (ExtensionType < INVALID_EXTENSION_TYPE)?TRUE:FALSE );
  132. }
  133. VOID LockContextList( VOID )
  134. {
  135. EnterCriticalSection( &m_csContextLock );
  136. }
  137. VOID UnlockContextList( VOID )
  138. {
  139. LeaveCriticalSection( &m_csContextLock );
  140. }
  141. // This logs any exceptions
  142. static VOID LogExceptionEvent( DWORD dwInstanceId, SMTP_EXT *lpExtension );
  143. // Catch-all check to see if a given string terminates
  144. // within the given length, should be used after IsBadStringPtr
  145. static BOOL StringIsTerminated( CHAR *lpszString,
  146. DWORD dwMaxLength)
  147. {
  148. while (dwMaxLength--)
  149. if (!*lpszString++)
  150. return(TRUE);
  151. return(FALSE);
  152. }
  153. private:
  154. SMTP_EXT *SearchExtensionFromList(CHAR *lpszModuleName);
  155. DWORD ChainExtensions(SMTP_SERVER_CONTEXT *lpServerContext,
  156. EXTENSION_TYPE ExtensionType);
  157. BOOL LoadExtensionDll(CHAR *lpszModuleName,
  158. EXTENSION_TYPE ExtensionType);
  159. BOOL LoadExtensions(LPSTR lpszList,
  160. EXTENSION_TYPE ExtensionType);
  161. VOID FreeExtensionsOfType(EXTENSION_TYPE ExtensionType);
  162. VOID FreeUnusedExtensions( VOID );
  163. VOID FreeExtensions( VOID );
  164. BOOL ComposeErrorTranscript(SMTP_SERVER_CONTEXT *lpServerContext,
  165. CHAR *lpszExtensionName,
  166. DWORD dwResult);
  167. // These are extension type-specific conversion routines
  168. BOOL CreateEcbFromDeb( SMTP_SERVER_CONTEXT *lpContext,
  169. LPDELIVERY_EXTENSION_BLOCK lpDeb,
  170. LPSSE_EXTENSION_CONTROL_BLOCK lpEcb);
  171. // These are extension type-specific conversion routines
  172. BOOL CreateEcbFromMeb( SMTP_SERVER_CONTEXT *lpContext,
  173. LPMESSAGE_EXTENSION_BLOCK lpDeb,
  174. LPSSE_EXTENSION_CONTROL_BLOCK lpEcb);
  175. DWORD m_dwSignature; // Signature
  176. DWORD m_dwExtensionsOfType[MAX_POSSIBLE_EXTENSION_TYPE];
  177. // Counter for each binding point
  178. DWORD m_dwInstanceId; // Server instance ID
  179. LIST_ENTRY m_ExtensionList; // Extension List Head
  180. LIST_ENTRY m_ContextList; // Server Context List Head
  181. CRITICAL_SECTION m_csContextLock; // Server context list lock
  182. };
  183. // ====================================================================
  184. // SMTP server extension object, one exists for each extension loaded
  185. //
  186. class SMTP_EXT
  187. {
  188. public:
  189. SMTP_EXT( SMTP_ISAPI *lpSdkInstance,
  190. CHAR *lpszModuleName,
  191. EXTENSION_TYPE ExtensionType,
  192. HMODULE hMod,
  193. PFN_EXTENSIONPROC pfnEntryPoint )
  194. {
  195. _ASSERT(lpszModuleName);
  196. _ASSERT(lpSdkInstance);
  197. _ASSERT(lpSdkInstance->StringIsTerminated(lpszModuleName,
  198. SSE_MAX_EXT_DLL_NAME_LEN));
  199. m_dwSignature = 0;
  200. // Initialize members
  201. lstrcpy(m_szModuleName, lpszModuleName);
  202. m_hMod = hMod;
  203. m_dwExtensionType = 0;
  204. for (DWORD i = 0; i < MAX_POSSIBLE_EXTENSION_TYPE; i++)
  205. m_pfnEntryPoint[i] = NULL;
  206. IncludeExtensionType(ExtensionType, pfnEntryPoint);
  207. m_dwSignature = SSE_EXT_SIGNATURE;
  208. }
  209. ~SMTP_EXT( VOID ) {}
  210. BOOL IsValid( VOID )
  211. {
  212. return( m_dwSignature == SSE_EXT_SIGNATURE );
  213. }
  214. LIST_ENTRY * QueryListEntry( VOID )
  215. {
  216. return( &m_ListEntry );
  217. }
  218. BOOL ExtensionTypeIncludes(EXTENSION_TYPE ExtensionType)
  219. {
  220. _ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
  221. return( (m_dwExtensionType & (1 << ExtensionType)) != 0 );
  222. }
  223. BOOL ExtensionIsUnused( VOID )
  224. {
  225. return(m_dwExtensionType == 0);
  226. }
  227. PFN_EXTENSIONPROC QueryEntryPoint(EXTENSION_TYPE ExtensionType)
  228. {
  229. if (ExtensionTypeIncludes(ExtensionType))
  230. return( m_pfnEntryPoint[ExtensionType] );
  231. else
  232. return(NULL);
  233. }
  234. VOID IncludeExtensionType(EXTENSION_TYPE ExtensionType,
  235. PFN_EXTENSIONPROC pfnEntryPoint)
  236. {
  237. _ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
  238. m_dwExtensionType |= (1 << ExtensionType);
  239. m_pfnEntryPoint[ExtensionType] = pfnEntryPoint;
  240. }
  241. VOID RemoveExtensionType(EXTENSION_TYPE ExtensionType)
  242. {
  243. _ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
  244. m_dwExtensionType &= (~(1 << ExtensionType));
  245. m_pfnEntryPoint[ExtensionType] = NULL;
  246. }
  247. CHAR * QueryModuleName( VOID )
  248. {
  249. return( m_szModuleName );
  250. }
  251. HMODULE QueryHMod( VOID )
  252. {
  253. return( m_hMod );
  254. }
  255. LIST_ENTRY m_ListEntry;
  256. private:
  257. DWORD m_dwExtensionType; // Extension type(s)
  258. CHAR m_szModuleName[SSE_MAX_EXT_DLL_NAME_LEN];
  259. // Name of module
  260. HMODULE m_hMod; // Handle to library
  261. PFN_EXTENSIONPROC m_pfnEntryPoint[MAX_POSSIBLE_EXTENSION_TYPE];
  262. // Entry point into binding points
  263. DWORD m_dwSignature; // Signature
  264. };
  265. // ====================================================================
  266. // SMTP server context, one exists for every thread inside ISAPI
  267. //
  268. typedef LPVOID LPSSE_ECB;
  269. typedef LPVOID LPSSE_SEB;
  270. class SMTP_SERVER_CONTEXT
  271. {
  272. public:
  273. SMTP_SERVER_CONTEXT(SMTP_ISAPI *pSdkInstance,
  274. EXTENSION_TYPE ExtensionType,
  275. LPSSE_SEB lpDeb,
  276. LPSSE_ECB lpEcb,
  277. HANDLE hImpersonation);
  278. ~SMTP_SERVER_CONTEXT( VOID );
  279. BOOL Initialize( VOID );
  280. BOOL IsValid( VOID )
  281. {
  282. return( m_dwSignature == SSE_CONTEXT_SIGNATURE );
  283. }
  284. LIST_ENTRY * QueryListEntry( VOID )
  285. {
  286. return( &m_ListEntry );
  287. }
  288. HANDLE QueryThread( VOID )
  289. {
  290. return( m_hCurrentThread );
  291. }
  292. SMTP_EXT * QueryExtension( VOID )
  293. {
  294. return( m_pCurrentExtension );
  295. }
  296. VOID SetExtension( SMTP_EXT *pExtension )
  297. {
  298. m_pCurrentExtension = pExtension;
  299. }
  300. EXTENSION_TYPE QueryExtensionType( VOID )
  301. {
  302. return( m_ExtensionType );
  303. }
  304. VOID SetExtensionType( EXTENSION_TYPE ExtensionType )
  305. {
  306. _ASSERT(ExtensionType < MAX_POSSIBLE_EXTENSION_TYPE);
  307. m_ExtensionType = ExtensionType;
  308. }
  309. LPSSE_ECB QueryExtensionControlBlock( VOID )
  310. {
  311. return( m_lpEcb );
  312. }
  313. LPSSE_SEB QueryServerExtensionBlock( VOID )
  314. {
  315. return( m_lpSeb );
  316. }
  317. BOOL QueryValidTimeout( VOID )
  318. {
  319. return( (InterlockedDecrement(&m_InterlockedState) < 0)?TRUE:FALSE );
  320. }
  321. BOOL QueryValidCompletion( VOID )
  322. {
  323. return( (InterlockedIncrement(&m_InterlockedState) > 0)?TRUE:FALSE );
  324. }
  325. LIST_ENTRY m_ListEntry; // Link to next server context
  326. private:
  327. SMTP_ISAPI *m_pSdkInstance; // Pointer to SDK instance
  328. LPSSE_SEB m_lpSeb; // Ext. block passed from SMTP
  329. // server, this is used to fill
  330. // in the fields of m_lpEcb
  331. LPSSE_ECB m_lpEcb; // Extension control block
  332. DWORD m_dwSignature; // Signature
  333. SMTP_EXT *m_pCurrentExtension; // Current extension object
  334. EXTENSION_TYPE m_ExtensionType; // Current extension type
  335. HANDLE m_hCurrentThread; // Handle of current thread
  336. long m_InterlockedState; // Sync. variable
  337. HANDLE m_hImpersonation; // Impersonation handle
  338. };
  339. #endif