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.
 
 
 
 
 
 

448 lines
16 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
routemapi.cpp
Abstract:
This module provides the implemantation of registry manipulations to
route MAPI calls to the Microsoft Outlook mail client
Author:
Mooly Beery (moolyb) 5-Nov-2000
Revision History:
--*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <debugex.h>
// cause the module to export its methods
//#define EXPORT_MAPI_ROUTE_CALLS
#include <routemapi.h>
#include "winfax.h"
#include "faxreg.h"
#include "faxutil.h"
#define MS_OUTLOOK _T("Microsoft Outlook")
#define REG_KEY_POP_UP _T("PreFirstRun")
#define REG_KEY_POP_UP_OLD _T("{F779C4BF-4C94-4442-8844-633F0298ED0B}")
#define REG_KEY_MAPI_APPS_OLD _T("{A5159994-A7F8-4C11-8F86-B9877CE02303}")
#define REG_KEY_CLIENTS_MAIL _T("SOFTWARE\\Clients\\Mail")
#define REG_KEY_MAPI_APPS _T("SOFTWARE\\Microsoft\\Windows Messaging Subsystem\\MSMapiApps")
CRouteMAPICalls::CRouteMAPICalls()
: m_ptProcessName(NULL),
m_bMSOutlookInstalled(false),
m_bMSOutlookIsDefault(false),
m_bProcessIsRouted(false),
m_bProcessIsRoutedToMsOutlook(false)
{
}
// Function: CRouteMAPICalls::~CRouteMAPICalls
//
// Description: restores the registry to its initial state after
// SetRegistryForSetupMAPICalls was called
// if Microsoft Outlook is installed
// if it's not restore pop-ups which might result from MAPI calls
// if it is check if Microsoft Outlook is the default mail client
// if it is do nothing
// if it's not remove current process from routing all MAPI calls to Micosoft Outlook
//
// author:
// MoolyB (05-NOV-00)
//
CRouteMAPICalls::~CRouteMAPICalls()
{
DWORD rc = ERROR_SUCCESS;
TCHAR* ptPreFirstRun = NULL;
TCHAR* ptPreRouteProcess = NULL;
HKEY hMailKey = NULL;
HKEY hMapiApps = NULL;
DBG_ENTER(_T("CRouteMAPICalls::~CRouteMAPICalls"));
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
REG_KEY_CLIENTS_MAIL,
0,
KEY_ALL_ACCESS,
&hMailKey);
if (rc!=ERROR_SUCCESS)
{
// no mail clients instlled on this machine? this is strange
// anyway, no work needs to be done, since no one will pop-up
// any message and our transport provider is not added anywhere.
CALL_FAIL (GENERAL_ERR, TEXT("RegOpenKeyEx HKLM\\SOFTWARE\\Clients\\Mail"), rc);
rc = ERROR_SUCCESS;
goto exit;
}
if (m_bMSOutlookInstalled)
{
VERBOSE(DBG_MSG,_T("Microsoft Outlook Client was installed"));
// Microsoft Outlook was installed, check if we did some changes
if (m_bMSOutlookIsDefault)
{
VERBOSE(DBG_MSG,_T("Microsoft Outlook Client was the default mail client, nothing to resotre"));
goto exit;
}
else
{
VERBOSE(DBG_MSG,_T("Microsoft Outlook Client was not the default mail client"));
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
REG_KEY_MAPI_APPS,
0,
KEY_ALL_ACCESS,
&hMapiApps);
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("RegOpenKeyEx SOFTWARE\\Microsoft\\Windows Messaging Subsystem\\MSMapiApps"), rc);
goto exit;
}
if (m_bProcessIsRouted)
{
if (m_bProcessIsRoutedToMsOutlook)
{
VERBOSE(DBG_MSG,_T("The process was routed before to MS Outlook, do nothing"));
goto exit;
}
else
{
VERBOSE(DBG_MSG,_T("The process was routed before, restore key..."));
// get old one
ptPreRouteProcess = GetRegistryString(hMapiApps,REG_KEY_MAPI_APPS_OLD,NULL);
if (ptPreRouteProcess==NULL)
{
// we failed to read the previously stored _szProcessName
// fail the recovery attemp, but delete ourselves anyhow.
CALL_FAIL (GENERAL_ERR, TEXT("GetRegistryString"), rc);
rc = RegDeleteValue(hMapiApps,m_ptProcessName);
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("RegDeleteValue m_ptProcessName"), rc);
}
goto exit;
}
// delete backup
rc = RegDeleteValue(hMapiApps,REG_KEY_MAPI_APPS_OLD);
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("RegDeleteValue m_ptProcessName"), rc);
}
// set the old registry back
if (!SetRegistryString(hMapiApps,m_ptProcessName,ptPreRouteProcess))
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString"), rc);
goto exit;
}
goto exit;
}
}
else
{
VERBOSE(DBG_MSG,_T("The process was not routed before, delete key..."));
rc = RegDeleteValue(hMapiApps,m_ptProcessName);
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("RegDeleteValue REG_KEY_MAPI_APPS_OLD"), rc);
goto exit;
}
}
}
}
else
{
// Microsoft Outlook was not installed, so we suppressed the pop-up
// need to restore the pop-up to its original state
VERBOSE(DBG_MSG,_T("Microsoft Mail Client was not installed - restore pop-up"));
// I restore the pop-up by renaming the REG_SZ _PreFirstRun
// under HKLM\\SOFTWARE\\Clients\\Mail
// to PreFirstRun,
ptPreFirstRun = GetRegistryString(hMailKey,REG_KEY_POP_UP_OLD,NULL);
if (ptPreFirstRun==NULL)
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("GetRegistryString _PreFirstRun"), rc);
goto exit;
}
rc = RegDeleteValue(hMailKey,REG_KEY_POP_UP_OLD);
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString _PreFirstRun"), rc);
}
if (!SetRegistryString(hMailKey,REG_KEY_POP_UP,ptPreFirstRun))
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString PreFirstRun"), rc);
goto exit;
}
}
exit:
if (hMailKey)
{
RegCloseKey(hMailKey);
}
if (hMapiApps)
{
RegCloseKey(hMapiApps);
}
if (ptPreFirstRun)
{
MemFree(ptPreFirstRun);
}
if (ptPreRouteProcess)
{
MemFree(ptPreRouteProcess);
}
if (m_ptProcessName)
{
MemFree(m_ptProcessName);
}
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("CRouteMAPICalls::~CRouteMAPICalls"), rc);
}
}
// Function: CRouteMAPICalls::Init
//
// Description: check if Microsoft Outlook is installed
// if it's not supress any pop-ups which might result from MAPI calls
// if it is check if Microsoft Outlook is the default mail client
// if it is do nothing
// if it's not set current process to route all MAPI calls to Micosoft Outlook
//
// author:
// MoolyB (05-NOV-00)
//
DWORD CRouteMAPICalls::Init(LPCTSTR lpctstrProcessName)
{
DWORD rc = ERROR_SUCCESS;
HKEY hMailKey = NULL;
HKEY hMsOutlookKey = NULL;
HKEY hMapiApps = NULL;
TCHAR* ptPreFirstRun = NULL;
TCHAR* ptPreRouteProcess = NULL;
TCHAR* ptDefaultMailClient = NULL;
TCHAR* ptProcessName = NULL;
DBG_ENTER(_T("CRouteMAPICalls::Init"), rc);
int iSize = _tcslen(lpctstrProcessName);
if (iSize==0)
{
VERBOSE(GENERAL_ERR,_T("invalid process name"));
goto exit;
}
m_ptProcessName = (TCHAR*)MemAlloc((iSize+1)*sizeof(TCHAR));
if (m_ptProcessName==NULL)
{
VERBOSE(GENERAL_ERR,_T("failure to allocate memory"));
goto exit;
}
_tcscpy(m_ptProcessName,lpctstrProcessName);
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
REG_KEY_CLIENTS_MAIL,
0,
KEY_ALL_ACCESS,
&hMailKey);
if (rc!=ERROR_SUCCESS)
{
// no mail clients instlled on this machine? this is strange
// anyway, no work needs to be done, since no one will pop-up
// any message and our transport provider is not added anywhere.
CALL_FAIL (GENERAL_ERR, TEXT("RegOpenKeyEx HKLM\\SOFTWARE\\Clients\\Mail"), rc);
rc = ERROR_SUCCESS;
goto exit;
}
else
{
// there are a few mail clients
// check if a key called 'Microsoft Outlook' exists.
rc = RegOpenKeyEx( hMailKey,
MS_OUTLOOK,
0,
KEY_READ,
&hMsOutlookKey);
if (rc!=ERROR_SUCCESS)
{
// Microsoft Outlook is not installed
CALL_FAIL(GENERAL_ERR,_T("RegOpenKeyEx HKLM\\SOFTWARE\\Clients\\Mail\\Microsoft Outlook"),rc);
if (rc==ERROR_FILE_NOT_FOUND)
{
// suppress pop-up message
VERBOSE(DBG_MSG,_T("Microsoft Mail Client is not installed - suppress pop-up"));
// I suppress the pop-up by renaming the REG_SZ PreFirstRun
// under HKLM\\SOFTWARE\\Clients\\Mail
// to _PreFirstRun, later, we'll restore this
ptPreFirstRun = GetRegistryString(hMailKey,REG_KEY_POP_UP,NULL);
if (ptPreFirstRun==NULL)
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("GetRegistryString PreFirstRun"), rc);
goto exit;
}
if (!SetRegistryString(hMailKey,REG_KEY_POP_UP_OLD,ptPreFirstRun))
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString _PreFirstRun"), rc);
goto exit;
}
rc = RegDeleteValue(hMailKey,REG_KEY_POP_UP);
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString PreFirstRun"), rc);
// try to cleanup, even though this is bad
RegDeleteValue(hMailKey,REG_KEY_POP_UP_OLD);
goto exit;
}
}
else
{
// this is a true error in trying to open the key
// HKLM\\SOFTWARE\\Clients\\Mail\\Microsoft Outlook
goto exit;
}
}
else
{
// Microsoft Outlook is installed
m_bMSOutlookInstalled = true;
// check if it is the deafult mail client
ptDefaultMailClient = GetRegistryString(hMailKey,NULL,NULL);
if ((ptDefaultMailClient==NULL) || (_tcscmp(ptDefaultMailClient,MS_OUTLOOK)))
{
// either there's no default mail client or GetRegistryString failed
// or there is a default mail client and it's not Microsoft Outlook
// in both cases I treat as Microsoft Outlook is not the default mail client
// open HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Messaging Subsystem\MSMapiApps
// and add a REG_SZ called according to szProcessName, set it to "Microsoft Outlook"
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
REG_KEY_MAPI_APPS,
0,
KEY_ALL_ACCESS,
&hMapiApps);
if (rc!=ERROR_SUCCESS)
{
CALL_FAIL (GENERAL_ERR, TEXT("RegOpenKeyEx SOFTWARE\\Microsoft\\Windows Messaging Subsystem\\MSMapiApps"), rc);
goto exit;
}
ptProcessName = GetRegistryString(hMapiApps,m_ptProcessName,NULL);
if (ptProcessName==NULL)
{
// this is the 'good' case, no one wants to route MAPI calls from a process with
// the same name as our own
if (!SetRegistryString(hMapiApps,m_ptProcessName,MS_OUTLOOK))
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString"), rc);
goto exit;
}
}
else
{
m_bProcessIsRouted = true;
// this it bad, someone is routing MAPI calls from a process with the same name to
// another app
// check if it's routed to Microsoft Outlook, and if not, rename it and add ourselves
if (_tcscmp(ptProcessName,MS_OUTLOOK)==0)
{
m_bProcessIsRoutedToMsOutlook = true;
VERBOSE(DBG_MSG,_T("MAPI calls are already routed to Microsoft Outlook"));
goto exit;
}
else
{
// set old one to _ prefix
ptPreRouteProcess = GetRegistryString(hMapiApps,m_ptProcessName,NULL);
if (ptPreRouteProcess==NULL)
{
// we failed to read the previously stored _szProcessName
// fail the recovery attemp, but delete ourselves anyhow.
CALL_FAIL (GENERAL_ERR, TEXT("GetRegistryString"), rc);
goto exit;
}
if (!SetRegistryString(hMapiApps,REG_KEY_MAPI_APPS_OLD,ptPreRouteProcess))
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString"), rc);
goto exit;
}
// set ourselves
if (!SetRegistryString(hMapiApps,m_ptProcessName,MS_OUTLOOK))
{
rc = GetLastError();
CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryString"), rc);
goto exit;
}
}
}
}
else
{
// Microsoft Outlook is the default mail client
m_bMSOutlookIsDefault = true;
goto exit;
}
}
}
exit:
if (hMailKey)
{
RegCloseKey(hMailKey);
}
if (hMsOutlookKey)
{
RegCloseKey(hMsOutlookKey);
}
if (hMapiApps)
{
RegCloseKey(hMapiApps);
}
if (ptPreFirstRun)
{
MemFree(ptPreFirstRun);
}
if (ptDefaultMailClient)
{
MemFree(ptDefaultMailClient);
}
if (ptProcessName)
{
MemFree(ptProcessName);
}
if (ptPreRouteProcess)
{
MemFree(ptPreFirstRun);
}
return rc;
}