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

// =====================================================================================
// Exchange Plus ! Main
// =====================================================================================
#include "pch.hxx"
#include "Imnapi.h"
#include "Exchrep.h"
#include "mapiconv.h"
// =====================================================================================
// Defines
// =====================================================================================
#define REGPATH "Software\\Microsoft\\Exchange Internet Mail Router"
#define MAILNEWS_PATH "MailNews Path"
#define ROUTE_TO_DISPLAY "Route To Display"
#define ROUTE_TO_ADDRESS "Route To Address"
#define ROUTER_DISPLAY "Microsoft Exchange Internet Mail Router"
#define ROUTER_ADDRESS "exchrep"
// =====================================================================================
// Globals
// =====================================================================================
HINSTANCE g_hInst;
// =====================================================================================
// Prototypes
// =====================================================================================
VOID FreeImsg (LPIMSG lpImsg);
// =====================================================================================
// Dll entry point
// =====================================================================================
int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
g_hInst = hInstance;
return 1;
case DLL_PROCESS_DETACH:
return 1;
}
// Not Handled
return 0;
}
// =====================================================================================
// Exchange Interface entry point
// =====================================================================================
LPEXCHEXT CALLBACK ExchEntryPoint(void)
{
// Create and return Exchange Interface Object
return (IExchExt *)new CExchRep;
}
// =====================================================================================
// Inst my exchange interface object
// =====================================================================================
CExchRep::CExchRep ()
{
m_uRef = 1;
m_lpSession = NULL;
m_hwnd = NULL;
m_hMailNews = NULL;
m_lpfnHrImnRouteMessage = NULL;
m_lpfnMailNewsDllInit = NULL;
}
// =====================================================================================
// Inst my exchange interface object
// =====================================================================================
CExchRep::~CExchRep ()
{
if (m_lpSession)
m_lpSession->Release ();
if (m_hMailNews)
{
if (m_lpfnMailNewsDllInit)
(*m_lpfnMailNewsDllInit)(FALSE);
FreeLibrary (m_hMailNews);
}
}
// =====================================================================================
// Add Ref
// =====================================================================================
STDMETHODIMP_(ULONG) CExchRep::AddRef ()
{
++m_uRef;
return m_uRef;
}
// =====================================================================================
// Release
// =====================================================================================
STDMETHODIMP_(ULONG) CExchRep::Release ()
{
ULONG uCount = --m_uRef;
if (!uCount)
delete this;
return uCount;
}
// =====================================================================================
// IExchExt - tells exchange what interfaces I am supporting
// =====================================================================================
STDMETHODIMP CExchRep::QueryInterface(REFIID riid, LPVOID * ppvObj)
{
// Locals
HRESULT hr = S_OK;
*ppvObj = NULL;
// IUnknown or IExchExt interface, this is it dude
if ((IID_IUnknown == riid) || (IID_IExchExt == riid))
{
*ppvObj = (LPUNKNOWN)(IExchExt *)this;
}
// IExchExtCommands interface ?
else if (IID_IExchExtSessionEvents == riid)
{
*ppvObj = (LPUNKNOWN)(IExchExtSessionEvents *)this;
}
// Else, interface is not supported
else hr = E_NOINTERFACE;
// Increment Reference Count
if (NULL != *ppvObj) ((LPUNKNOWN)*ppvObj)->AddRef();
// Done
return hr;
}
// =====================================================================================
// Install is called
// =====================================================================================
STDMETHODIMP CExchRep::Install (LPEXCHEXTCALLBACK lpExchCallback, ULONG mecontext, ULONG ulFlags)
{
// Locals
HRESULT hr = S_OK;
// Only in session context
if (mecontext != EECONTEXT_SESSION)
return S_OK;
// Get Window Handle
lpExchCallback->GetWindow (&m_hwnd);
// Get Session Object
hr = lpExchCallback->GetSession (&m_lpSession, NULL);
if (FAILED (hr) || !m_lpSession)
{
MessageBox (m_hwnd, "IExchExtCallback::GetSession Failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
// Load Config
LoadConfig ();
exit:
// Done
return S_OK;
}
// =====================================================================================
// LoadConfig
// =====================================================================================
VOID CExchRep::LoadConfig (VOID)
{
// Locals
HKEY hReg = NULL;
ULONG cbRegData;
DWORD dwType;
// Open the Reg Key
if (RegOpenKeyEx (HKEY_CURRENT_USER, REGPATH, 0, KEY_ALL_ACCESS, &hReg) != ERROR_SUCCESS)
{
MessageBox (m_hwnd, "Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
// Display To
cbRegData = sizeof (m_szDisplayTo);
dwType = REG_SZ;
if (RegQueryValueEx (hReg, ROUTE_TO_DISPLAY, 0, &dwType, (LPBYTE)m_szDisplayTo, &cbRegData) != ERROR_SUCCESS)
{
MessageBox (m_hwnd, "Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
// Address To
cbRegData = sizeof (m_szAddressTo);
dwType = REG_SZ;
if (RegQueryValueEx (hReg, ROUTE_TO_ADDRESS, 0, &dwType, (LPBYTE)m_szAddressTo, &cbRegData) != ERROR_SUCCESS)
{
MessageBox (m_hwnd, "Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
// Get mail news dll path
cbRegData = sizeof (m_szMailNewsPath);
dwType = REG_SZ;
if (RegQueryValueEx (hReg, MAILNEWS_PATH, 0, &dwType, (LPBYTE)m_szMailNewsPath, &cbRegData) == ERROR_SUCCESS)
{
// Lets Load mailnews.dll
m_hMailNews = LoadLibrary ("c:\\thor\\build\\debug\\mailnews.dll");
if (m_hMailNews == NULL)
{
MessageBox (m_hwnd, "Unable to load mailnews.dll. Exchange Internet Mail Router is not configured.", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
// Fixup Procedure addresses
m_lpfnHrImnRouteMessage = (PFNHRIMNROUTEMESSAGE)GetProcAddress (m_hMailNews, "HrImnRouteMessage");
m_lpfnMailNewsDllInit = (PFNMAILNEWSDLLINIT)GetProcAddress (m_hMailNews, "MailNewsDllInit");;
// Could get proc addresses
if (!m_lpfnHrImnRouteMessage || !m_lpfnMailNewsDllInit)
{
FreeLibrary (m_hMailNews);
m_hMailNews = NULL;
goto exit;
}
// Init the dll
(*m_lpfnMailNewsDllInit)(TRUE);
}
exit:
// Cleanup
if (hReg)
RegCloseKey (hReg);
// Done
return;
}
// =====================================================================================
// OnDeliver - This function never fail
// =====================================================================================
STDMETHODIMP CExchRep::OnDelivery (LPEXCHEXTCALLBACK lpExchCallback)
{
// Locals
HRESULT hr = S_OK;
LPMDB lpMdb = NULL;
LPMESSAGE lpMessage = NULL;
IMSG rImsg;
IADDRINFO rIaddr[2];
// No mailnews.dll
if (!m_hMailNews || !m_lpfnHrImnRouteMessage || !m_lpfnMailNewsDllInit)
goto exit;
// Get object (IMessage
hr = lpExchCallback->GetObject(&lpMdb, (LPMAPIPROP *)&lpMessage);
if (FAILED (hr) || !lpMessage)
{
MessageBox (m_hwnd, "IExchExtCallback::GetObject failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
// Convert MAPI Message to mime message
hr = HrMapiToImsg (lpMessage, &rImsg);
if (FAILED (hr))
{
MessageBox (m_hwnd, "HrMapiToImsg failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
// Set the rout to address
rIaddr[0].dwType = IADDR_TO;
rIaddr[0].lpszDisplay = m_szDisplayTo;
rIaddr[0].lpszAddress = m_szAddressTo;
rIaddr[1].dwType = IADDR_FROM;
rIaddr[1].lpszDisplay = ROUTER_DISPLAY;
rIaddr[1].lpszAddress = ROUTER_ADDRESS;
// Send the message
hr = (*m_lpfnHrImnRouteMessage)(rIaddr, 2, &rImsg);
if (FAILED (hr))
{
MessageBox (m_hwnd, "HrImnRouteMessage failed", "ExchRep", MB_OK | MB_SETFOREGROUND);
goto exit;
}
exit:
// Cleanup
if (lpMdb)
lpMdb->Release ();
if (lpMessage)
lpMessage->Release ();
FreeImsg (&rImsg);
// Done
return S_OK;
}
// =====================================================================================
// FreeImsg
// =====================================================================================
VOID FreeImsg (LPIMSG lpImsg)
{
// Locals
ULONG i;
// Nothing
if (lpImsg == NULL)
return;
// Free Stuff
if (lpImsg->lpszSubject)
free (lpImsg->lpszSubject);
lpImsg->lpszSubject = NULL;
if (lpImsg->lpszBody)
free (lpImsg->lpszBody);
lpImsg->lpszBody = NULL;
if (lpImsg->lpstmRtf)
lpImsg->lpstmRtf->Release ();
lpImsg->lpstmRtf = NULL;
// Walk Address list
for (i=0; i<lpImsg->cAddress; i++)
{
if (lpImsg->lpIaddr[i].lpszAddress)
free (lpImsg->lpIaddr[i].lpszAddress);
lpImsg->lpIaddr[i].lpszAddress = NULL;
if (lpImsg->lpIaddr[i].lpszDisplay)
free (lpImsg->lpIaddr[i].lpszDisplay);
lpImsg->lpIaddr[i].lpszDisplay = NULL;
}
// Free Address list
if (lpImsg->lpIaddr)
free (lpImsg->lpIaddr);
lpImsg->lpIaddr = NULL;
// Walk Attachment list
for (i=0; i<lpImsg->cAttach; i++)
{
if (lpImsg->lpIatt[i].lpszFileName)
free (lpImsg->lpIatt[i].lpszFileName);
lpImsg->lpIatt[i].lpszFileName = NULL;
if (lpImsg->lpIatt[i].lpszPathName)
free (lpImsg->lpIatt[i].lpszPathName);
lpImsg->lpIatt[i].lpszPathName = NULL;
if (lpImsg->lpIatt[i].lpszExt)
free (lpImsg->lpIatt[i].lpszExt);
lpImsg->lpIatt[i].lpszExt = NULL;
if (lpImsg->lpIatt[i].lpImsg)
{
FreeImsg (lpImsg->lpIatt[i].lpImsg);
free (lpImsg->lpIatt[i].lpImsg);
lpImsg->lpIatt[i].lpImsg = NULL;
}
if (lpImsg->lpIatt[i].lpstmAtt)
lpImsg->lpIatt[i].lpstmAtt->Release ();
lpImsg->lpIatt[i].lpstmAtt = NULL;
}
// Free the att list
if (lpImsg->lpIatt)
free (lpImsg->lpIatt);
}