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
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;
|
|
}
|