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.

374 lines
12 KiB

  1. // =====================================================================================
  2. // Exchange Plus ! Main
  3. // =====================================================================================
  4. #include "pch.hxx"
  5. #include "Imnapi.h"
  6. #include "Exchrep.h"
  7. #include "mapiconv.h"
  8. // =====================================================================================
  9. // Defines
  10. // =====================================================================================
  11. #define REGPATH "Software\\Microsoft\\Exchange Internet Mail Router"
  12. #define MAILNEWS_PATH "MailNews Path"
  13. #define ROUTE_TO_DISPLAY "Route To Display"
  14. #define ROUTE_TO_ADDRESS "Route To Address"
  15. #define ROUTER_DISPLAY "Microsoft Exchange Internet Mail Router"
  16. #define ROUTER_ADDRESS "exchrep"
  17. // =====================================================================================
  18. // Globals
  19. // =====================================================================================
  20. HINSTANCE g_hInst;
  21. // =====================================================================================
  22. // Prototypes
  23. // =====================================================================================
  24. VOID FreeImsg (LPIMSG lpImsg);
  25. // =====================================================================================
  26. // Dll entry point
  27. // =====================================================================================
  28. int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  29. {
  30. switch (dwReason)
  31. {
  32. case DLL_PROCESS_ATTACH:
  33. g_hInst = hInstance;
  34. return 1;
  35. case DLL_PROCESS_DETACH:
  36. return 1;
  37. }
  38. // Not Handled
  39. return 0;
  40. }
  41. // =====================================================================================
  42. // Exchange Interface entry point
  43. // =====================================================================================
  44. LPEXCHEXT CALLBACK ExchEntryPoint(void)
  45. {
  46. // Create and return Exchange Interface Object
  47. return (IExchExt *)new CExchRep;
  48. }
  49. // =====================================================================================
  50. // Inst my exchange interface object
  51. // =====================================================================================
  52. CExchRep::CExchRep ()
  53. {
  54. m_uRef = 1;
  55. m_lpSession = NULL;
  56. m_hwnd = NULL;
  57. m_hMailNews = NULL;
  58. m_lpfnHrImnRouteMessage = NULL;
  59. m_lpfnMailNewsDllInit = NULL;
  60. }
  61. // =====================================================================================
  62. // Inst my exchange interface object
  63. // =====================================================================================
  64. CExchRep::~CExchRep ()
  65. {
  66. if (m_lpSession)
  67. m_lpSession->Release ();
  68. if (m_hMailNews)
  69. {
  70. if (m_lpfnMailNewsDllInit)
  71. (*m_lpfnMailNewsDllInit)(FALSE);
  72. FreeLibrary (m_hMailNews);
  73. }
  74. }
  75. // =====================================================================================
  76. // Add Ref
  77. // =====================================================================================
  78. STDMETHODIMP_(ULONG) CExchRep::AddRef ()
  79. {
  80. ++m_uRef;
  81. return m_uRef;
  82. }
  83. // =====================================================================================
  84. // Release
  85. // =====================================================================================
  86. STDMETHODIMP_(ULONG) CExchRep::Release ()
  87. {
  88. ULONG uCount = --m_uRef;
  89. if (!uCount)
  90. delete this;
  91. return uCount;
  92. }
  93. // =====================================================================================
  94. // IExchExt - tells exchange what interfaces I am supporting
  95. // =====================================================================================
  96. STDMETHODIMP CExchRep::QueryInterface(REFIID riid, LPVOID * ppvObj)
  97. {
  98. // Locals
  99. HRESULT hr = S_OK;
  100. *ppvObj = NULL;
  101. // IUnknown or IExchExt interface, this is it dude
  102. if ((IID_IUnknown == riid) || (IID_IExchExt == riid))
  103. {
  104. *ppvObj = (LPUNKNOWN)(IExchExt *)this;
  105. }
  106. // IExchExtCommands interface ?
  107. else if (IID_IExchExtSessionEvents == riid)
  108. {
  109. *ppvObj = (LPUNKNOWN)(IExchExtSessionEvents *)this;
  110. }
  111. // Else, interface is not supported
  112. else hr = E_NOINTERFACE;
  113. // Increment Reference Count
  114. if (NULL != *ppvObj) ((LPUNKNOWN)*ppvObj)->AddRef();
  115. // Done
  116. return hr;
  117. }
  118. // =====================================================================================
  119. // Install is called
  120. // =====================================================================================
  121. STDMETHODIMP CExchRep::Install (LPEXCHEXTCALLBACK lpExchCallback, ULONG mecontext, ULONG ulFlags)
  122. {
  123. // Locals
  124. HRESULT hr = S_OK;
  125. // Only in session context
  126. if (mecontext != EECONTEXT_SESSION)
  127. return S_OK;
  128. // Get Window Handle
  129. lpExchCallback->GetWindow (&m_hwnd);
  130. // Get Session Object
  131. hr = lpExchCallback->GetSession (&m_lpSession, NULL);
  132. if (FAILED (hr) || !m_lpSession)
  133. {
  134. MessageBox (m_hwnd, "IExchExtCallback::GetSession Failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
  135. goto exit;
  136. }
  137. // Load Config
  138. LoadConfig ();
  139. exit:
  140. // Done
  141. return S_OK;
  142. }
  143. // =====================================================================================
  144. // LoadConfig
  145. // =====================================================================================
  146. VOID CExchRep::LoadConfig (VOID)
  147. {
  148. // Locals
  149. HKEY hReg = NULL;
  150. ULONG cbRegData;
  151. DWORD dwType;
  152. // Open the Reg Key
  153. if (RegOpenKeyEx (HKEY_CURRENT_USER, REGPATH, 0, KEY_ALL_ACCESS, &hReg) != ERROR_SUCCESS)
  154. {
  155. MessageBox (m_hwnd, "Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
  156. goto exit;
  157. }
  158. // Display To
  159. cbRegData = sizeof (m_szDisplayTo);
  160. dwType = REG_SZ;
  161. if (RegQueryValueEx (hReg, ROUTE_TO_DISPLAY, 0, &dwType, (LPBYTE)m_szDisplayTo, &cbRegData) != ERROR_SUCCESS)
  162. {
  163. MessageBox (m_hwnd, "Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
  164. goto exit;
  165. }
  166. // Address To
  167. cbRegData = sizeof (m_szAddressTo);
  168. dwType = REG_SZ;
  169. if (RegQueryValueEx (hReg, ROUTE_TO_ADDRESS, 0, &dwType, (LPBYTE)m_szAddressTo, &cbRegData) != ERROR_SUCCESS)
  170. {
  171. MessageBox (m_hwnd, "Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
  172. goto exit;
  173. }
  174. // Get mail news dll path
  175. cbRegData = sizeof (m_szMailNewsPath);
  176. dwType = REG_SZ;
  177. if (RegQueryValueEx (hReg, MAILNEWS_PATH, 0, &dwType, (LPBYTE)m_szMailNewsPath, &cbRegData) == ERROR_SUCCESS)
  178. {
  179. // Lets Load mailnews.dll
  180. m_hMailNews = LoadLibrary ("c:\\thor\\build\\debug\\mailnews.dll");
  181. if (m_hMailNews == NULL)
  182. {
  183. MessageBox (m_hwnd, "Unable to load mailnews.dll. Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
  184. goto exit;
  185. }
  186. // Fixup Procedure addresses
  187. m_lpfnHrImnRouteMessage = (PFNHRIMNROUTEMESSAGE)GetProcAddress (m_hMailNews, "HrImnRouteMessage");
  188. m_lpfnMailNewsDllInit = (PFNMAILNEWSDLLINIT)GetProcAddress (m_hMailNews, "MailNewsDllInit");;
  189. // Could get proc addresses
  190. if (!m_lpfnHrImnRouteMessage || !m_lpfnMailNewsDllInit)
  191. {
  192. FreeLibrary (m_hMailNews);
  193. m_hMailNews = NULL;
  194. goto exit;
  195. }
  196. // Init the dll
  197. (*m_lpfnMailNewsDllInit)(TRUE);
  198. }
  199. exit:
  200. // Cleanup
  201. if (hReg)
  202. RegCloseKey (hReg);
  203. // Done
  204. return;
  205. }
  206. // =====================================================================================
  207. // OnDeliver - This function never fail
  208. // =====================================================================================
  209. STDMETHODIMP CExchRep::OnDelivery (LPEXCHEXTCALLBACK lpExchCallback)
  210. {
  211. // Locals
  212. HRESULT hr = S_OK;
  213. LPMDB lpMdb = NULL;
  214. LPMESSAGE lpMessage = NULL;
  215. IMSG rImsg;
  216. IADDRINFO rIaddr[2];
  217. // No mailnews.dll
  218. if (!m_hMailNews || !m_lpfnHrImnRouteMessage || !m_lpfnMailNewsDllInit)
  219. goto exit;
  220. // Get object (IMessage
  221. hr = lpExchCallback->GetObject(&lpMdb, (LPMAPIPROP *)&lpMessage);
  222. if (FAILED (hr) || !lpMessage)
  223. {
  224. MessageBox (m_hwnd, "IExchExtCallback::GetObject failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
  225. goto exit;
  226. }
  227. // Convert MAPI Message to mime message
  228. hr = HrMapiToImsg (lpMessage, &rImsg);
  229. if (FAILED (hr))
  230. {
  231. MessageBox (m_hwnd, "HrMapiToImsg failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
  232. goto exit;
  233. }
  234. // Set the rout to address
  235. rIaddr[0].dwType = IADDR_TO;
  236. rIaddr[0].lpszDisplay = m_szDisplayTo;
  237. rIaddr[0].lpszAddress = m_szAddressTo;
  238. rIaddr[1].dwType = IADDR_FROM;
  239. rIaddr[1].lpszDisplay = ROUTER_DISPLAY;
  240. rIaddr[1].lpszAddress = ROUTER_ADDRESS;
  241. // Send the message
  242. hr = (*m_lpfnHrImnRouteMessage)(rIaddr, 2, &rImsg);
  243. if (FAILED (hr))
  244. {
  245. MessageBox (m_hwnd, "HrImnRouteMessage failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
  246. goto exit;
  247. }
  248. exit:
  249. // Cleanup
  250. if (lpMdb)
  251. lpMdb->Release ();
  252. if (lpMessage)
  253. lpMessage->Release ();
  254. FreeImsg (&rImsg);
  255. // Done
  256. return S_OK;
  257. }
  258. // =====================================================================================
  259. // FreeImsg
  260. // =====================================================================================
  261. VOID FreeImsg (LPIMSG lpImsg)
  262. {
  263. // Locals
  264. ULONG i;
  265. // Nothing
  266. if (lpImsg == NULL)
  267. return;
  268. // Free Stuff
  269. if (lpImsg->lpszSubject)
  270. free (lpImsg->lpszSubject);
  271. lpImsg->lpszSubject = NULL;
  272. if (lpImsg->lpszBody)
  273. free (lpImsg->lpszBody);
  274. lpImsg->lpszBody = NULL;
  275. if (lpImsg->lpstmRtf)
  276. lpImsg->lpstmRtf->Release ();
  277. lpImsg->lpstmRtf = NULL;
  278. // Walk Address list
  279. for (i=0; i<lpImsg->cAddress; i++)
  280. {
  281. if (lpImsg->lpIaddr[i].lpszAddress)
  282. free (lpImsg->lpIaddr[i].lpszAddress);
  283. lpImsg->lpIaddr[i].lpszAddress = NULL;
  284. if (lpImsg->lpIaddr[i].lpszDisplay)
  285. free (lpImsg->lpIaddr[i].lpszDisplay);
  286. lpImsg->lpIaddr[i].lpszDisplay = NULL;
  287. }
  288. // Free Address list
  289. if (lpImsg->lpIaddr)
  290. free (lpImsg->lpIaddr);
  291. lpImsg->lpIaddr = NULL;
  292. // Walk Attachment list
  293. for (i=0; i<lpImsg->cAttach; i++)
  294. {
  295. if (lpImsg->lpIatt[i].lpszFileName)
  296. free (lpImsg->lpIatt[i].lpszFileName);
  297. lpImsg->lpIatt[i].lpszFileName = NULL;
  298. if (lpImsg->lpIatt[i].lpszPathName)
  299. free (lpImsg->lpIatt[i].lpszPathName);
  300. lpImsg->lpIatt[i].lpszPathName = NULL;
  301. if (lpImsg->lpIatt[i].lpszExt)
  302. free (lpImsg->lpIatt[i].lpszExt);
  303. lpImsg->lpIatt[i].lpszExt = NULL;
  304. if (lpImsg->lpIatt[i].lpImsg)
  305. {
  306. FreeImsg (lpImsg->lpIatt[i].lpImsg);
  307. free (lpImsg->lpIatt[i].lpImsg);
  308. lpImsg->lpIatt[i].lpImsg = NULL;
  309. }
  310. if (lpImsg->lpIatt[i].lpstmAtt)
  311. lpImsg->lpIatt[i].lpstmAtt->Release ();
  312. lpImsg->lpIatt[i].lpstmAtt = NULL;
  313. }
  314. // Free the att list
  315. if (lpImsg->lpIatt)
  316. free (lpImsg->lpIatt);
  317. }