// --gwmain.c-------------------------------------------------------------------
//
// Logon/logoff a gateway.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------
#define USES_IID_IMailUser
#include "edk.h"
#include "gwmain.h"
#define NOTIFY_TIMEOUT 60000
static ULONG ulNewMailAdvise = 0xFFFFFFFFU;
static HANDLE hNewMailEvent = NULL; // new mail event
static LPMAPISESSION lpSession = NULL; // session pointer
static LPMDB lpStore = NULL; // message store pointer
static LPMAPIFOLDER lpRootFolder = NULL; // root folder pointer
static LPMAPIFOLDER lpMtsInFolder = NULL; // MTS-IN folder pointer
static LPMAPIFOLDER lpMtsOutFolder = NULL; // MTS-OUT folder pointer
static LPADRBOOK lpAdrBook = NULL; // pointer to address book
static ULONG cbGalEid = 0; // count of bytes in GAL entry ID
static LPENTRYID lpGalEid = NULL; // pointer to GAL entry ID
static LPABCONT lpGalABCont = NULL; // pointer to GAL object
static BOOL IsInitMAPI = FALSE; // MAPI Initialized
static BOOL IsMAPILogon = FALSE; // MAPI Logon
CRITICAL_SECTION csNewMailList = {0};
CRITICAL_SECTION csNewFileList = {0};
static CHAR szServerName[MAX_COMPUTERNAME_LENGTH+1] = {0};
HANDLE hNewMailThread = NULL; // new mail thread
HANDLE hNewFileThread = NULL; // new file thread
DWORD dwNewMailTimeout = NOTIFY_TIMEOUT;
DWORD dwNewFileTimeout = NOTIFY_TIMEOUT;
//$--GetGWExchangeServerName------------------------------------------------------
// Get Exchange server name.
// -----------------------------------------------------------------------------
LPSTR GetGWExchangeServerName(void)
{
DEBUGPUBLIC("GetGWExchangeServerName()\n");
return(szServerName);
}
//$--GetGWSession-------------------------------------------------------------
// Get MAPI session pointer.
// -----------------------------------------------------------------------------
LPMAPISESSION GetGWSession(void)
{
DEBUGPUBLIC("GetGWSession()\n");
return(lpSession);
}
//$--GetGWDefaultStore------------------------------------------------------------
// Get default store pointer.
// -----------------------------------------------------------------------------
LPMDB GetGWDefaultStore(void)
{
DEBUGPUBLIC("GetGWDefaultStore()\n");
return(lpStore);
}
//$--GetGWRootFolder-------------------------------------------------------------
// Get root folder pointer.
// -----------------------------------------------------------------------------
LPMAPIFOLDER GetGWRootFolder(void)
{
DEBUGPUBLIC("GetGWRootFolder()\n");
return(lpRootFolder);
}
//$--GetGWMtsInFolder-------------------------------------------------------------
// Get MTS-IN folder pointer.
// -----------------------------------------------------------------------------
LPMAPIFOLDER GetGWMtsInFolder(void)
{
DEBUGPUBLIC("GetGWMtsInFolder()\n");
return(lpMtsInFolder);
}
//$--GetGWMtsOutFolder------------------------------------------------------------
// Get MTS-OUT folder pointer.
// -----------------------------------------------------------------------------
LPMAPIFOLDER GetGWMtsOutFolder(void)
{
DEBUGPUBLIC("GetGWMtsOutFolder()\n");
return(lpMtsOutFolder);
}
//$--GetGWGALEntryIdSize--------------------------------------------------------------
// Get count of bytes in GAL entry ID.
// -----------------------------------------------------------------------------
ULONG GetGWGALEntryIdSize(void)
{
DEBUGPUBLIC("GetGWGALEntryIdSize()\n");
return(cbGalEid);
}
//$--GetGWGALEntryId------------------------------------------------------------------
// Get GAL entry ID pointer.
// -----------------------------------------------------------------------------
LPENTRYID GetGWGALEntryId(void)
{
DEBUGPUBLIC("GetGWGALEntryId()\n");
return(lpGalEid);
}
//$--GetAdrBookPtr--------------------------------------------------------------
// Get address book pointer pointer.
// -----------------------------------------------------------------------------
LPADRBOOK GetAdrBookPtr(void)
{
DEBUGPUBLIC("GetAdrBookPtr()\n");
return(lpAdrBook);
}
//$--GetGWGAL------------------------------------------------------------------
// Get GAL pointer.
// -----------------------------------------------------------------------------
LPABCONT GetGWGAL(void)
{
DEBUGPUBLIC("GetGWGAL()\n");
return(lpGalABCont);
}
//$--GetGWNewMailEvent------------------------------------------------------------
// Get new mail event.
// -----------------------------------------------------------------------------
HANDLE GetGWNewMailEvent(void)
{
DEBUGPUBLIC("GetGWNewMailEvent()\n");
return(hNewMailEvent);
}
//$--GetGWNewMailStatus-----------------------------------------------------------
// Get new mail status.
// -----------------------------------------------------------------------------
BOOL GetGWNewMailStatus(void)
{
BOOL IsNewMail = TRUE;
DWORD dw = 0;
DEBUGPUBLIC("GetGWNewMailStatus()\n");
if(hNewMailEvent == NULL)
{
IsNewMail = FALSE;
goto cleanup;
}
dw = WaitForSingleObject(hNewMailEvent, 0);
if((dw != WAIT_OBJECT_0) && (dw != WAIT_ABANDONED))
{
HRESULT hr = HR_LOG(E_FAIL);
IsNewMail = FALSE;
}
cleanup:
return(IsNewMail);
}
//$--ScNewMailHandler-----------------------------------------------------------
// Handle the arrival of new messages.
// -----------------------------------------------------------------------------
static SCODE STDAPICALLTYPE ScNewMailHandler( // RETURNS: status code
IN LPVOID lpvContext, // pointer to context
IN ULONG cNotification, // count of notifications
IN LPNOTIFICATION lpNotifications) // pointer to notifications
{
DEBUGPRIVATE("ScNewMailHandler()\n");
if((hNewMailEvent != NULL) && (!SetEvent(hNewMailEvent)))
{
HRESULT hr = HR_LOG(E_FAIL);
}
return(0);
}
//$--HrGWWaitForStop----------------------------------------------------
// Wait for the gateway to stop.
// -----------------------------------------------------------------------------
HRESULT HrGWWaitForStop( // RETURNS: return code
void) // no arguments
{
HRESULT hr = NOERROR;
HANDLE hObjects[2] = {0};
DWORD dwT = WAIT_FAILED;
ULONG i = 0;
DEBUGPUBLIC("HrGWWaitForStop()\n");
if(hNewMailThread != NULL)
{
hObjects[i++] = hNewMailThread;
}
if(hNewFileThread != NULL)
{
hObjects[i++] = hNewFileThread;
}
if(i > 0)
{
dwT = WaitForMultipleObjects(i, hObjects, TRUE, INFINITE);
if(dwT == WAIT_FAILED)
{
hr = HR_LOG(E_FAIL);
}
}
RETURN(hr);
}
//$--HrGetArbValue--------------------------------------------------------------
// Get an arbitrary value - allocating memory to hold it.
// -----------------------------------------------------------------------------
static HRESULT HrGetArbValue( // RETURNS: return code
IN HKEY hk, // the key.
IN LPSTR pszValue, // value name in key.
OUT DWORD * pType, // where to put type info.
OUT DWORD * pcb, // where to put byte count info.
OUT LPVOID * ppData) // where to put the data.
{
HRESULT hr = E_FAIL;
LONG lRet = 0;
DEBUGPRIVATE("HrGetArbValue()\n");
*ppData = NULL;
//
// Get its size.
//
lRet = RegQueryValueEx(
hk,
pszValue,
NULL,
pType,
NULL,
pcb);
if(lRet != ERROR_SUCCESS)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Allocate memory for it.
//
*ppData = GlobalAlloc(GPTR, *pcb);
if(*ppData == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// get the current value
//
lRet = RegQueryValueEx(hk, pszValue, NULL, pType, *ppData, pcb);
if(lRet != ERROR_SUCCESS)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = NOERROR;
cleanup:
if(FAILED(hr))
{
if(ppData != NULL)
{
GLOBALFREE(*ppData);
}
}
RETURN(hr);
}
//$--HrCheckExchangeRunning-----------------------------------------------------
// Check if the Exchange server is running.
// -----------------------------------------------------------------------------
static HRESULT HrCheckExchangeRunning( // RETURNS: return code
IN LPSTR lpszServiceName)
{
HRESULT hr = NOERROR;
LONG lRet = 0;
DWORD dwService = 0;
DWORD dwCurrentState = 0;
DWORD dwType = 0;
DWORD cbOrig = 0;
LPSTR lpszServerName = NULL;
HKEY hkParameters = INVALID_HANDLE_VALUE;
CHAR szParametersKey[MAX_PATH+1] = {0};
//
// Open the parameters key.
//
sprintf(
szParametersKey,
"SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters",
lpszServiceName);
lRet = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
szParametersKey,
0,
KEY_READ,
&hkParameters);
if(lRet != ERROR_SUCCESS)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Get the Exchange server name.
//
hr = HrGetArbValue(
hkParameters, "HomeDSA", &dwType, &cbOrig, (LPVOID) &lpszServerName);
if(FAILED(hr) || dwType != REG_SZ)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Copy Exchange server name.
//
lstrcpyn(szServerName, lpszServerName, MAX_COMPUTERNAME_LENGTH);
szServerName[MAX_COMPUTERNAME_LENGTH] = 0;
// TODO: remove "#ifndef" and "#endif"
#ifndef DEBUG
hr = HrGetExchangeStatus(
lpszServerName,
&dwService,
&dwCurrentState);
if(FAILED(hr))
{
MODULE_ERROR1(
"The Exchange server on %s is not running!",
lpszServerName);
hr = HR_LOG(E_FAIL);
goto cleanup;
}
#endif
cleanup:
GLOBALFREE(lpszServerName);
if(hkParameters != INVALID_HANDLE_VALUE)
{
HR_LOG(HRESULT_FROM_WIN32(RegCloseKey(hkParameters)));
}
RETURN(hr);
}
//$--HrInternalGatewayLogon-----------------------------------------------------
// Logon to the gateway.
// -----------------------------------------------------------------------------
static HRESULT HrInternalGatewayLogon(void) // RETURNS: return code
{
HRESULT hr = NOERROR;
ULONG cValues = 0;
LPSPropValue lpProp = NULL;
ULONG ulObjType = 0;
ULONG cbStoreEid = 0;
LPENTRYID lpStoreEid = NULL;
SPropTagArray rgMtsInEntryId = { 1, { PR_GW_MTSIN_ENTRYID } };
ULONG cbMtsInEid = 0;
LPENTRYID lpMtsInEid = NULL;
SPropTagArray rgMtsOutEntryId = { 1, { PR_GW_MTSOUT_ENTRYID } };
ULONG cbMtsOutEid = 0;
LPENTRYID lpMtsOutEid = NULL;
CHAR szGatewayName[MAX_SERVICE_NAME_LENGTH+1] = {0};
MAPIINIT_0MapiInit = { 0 };
ULONG ulFlags = 0;
LPMAPIADVISESINK lpAdvise = NULL;
CHAR szProfileName[MAX_PATH+1] = {0};
BOOL IsProfileCreated = FALSE;
DEBUGPRIVATE("HrInternalGatewayLogon()\n");
//
// Initialize critical section for new mail list.
//
InitializeCriticalSection(&csNewMailList);
//
// Initialize critical section for new file list.
//
InitializeCriticalSection(&csNewFileList);
//
// Get gateway service name.
//
hr = HrServiceGetName(
szGatewayName);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Check if Exchange is running.
//
hr = HrCheckExchangeRunning(
szGatewayName);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Create the event object. The new mail event handler function signals
// this event when it receives a new mail notification.
hNewMailEvent = CreateEvent(
NULL, // no security attributes
FALSE, // auto-reset event
FALSE, // not-signalled
NULL); // no name
if(hNewMailEvent == (HANDLE)NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
MapiInit.ulVersion = MAPI_INIT_VERSION;
ulFlags = MAPI_NEW_SESSION|MAPI_EXTENDED|MAPI_NO_MAIL;
if(FIsService())
{// Services need special initialization.
MapiInit.ulFlags = MAPI_NT_SERVICE;
ulFlags |= MAPI_NT_SERVICE;
}
hr = MAPIInitialize(&MapiInit);
if(FAILED(hr))
{
goto cleanup;
}
IsInitMAPI = TRUE;
hr = HrCreateProfileName(
szGatewayName,
MAX_PATH+1,
szProfileName);
if(FAILED(hr))
{
goto cleanup;
}
hr = HrCreateGatewayProfile(szGatewayName, szProfileName);
if(hr == E_ACCESSDENIED)
{
MODULE_WARNING(
"Could not create profile since previous profile with same name "
"is still logged on.");
hr = NOERROR;
}
else if(FAILED(hr))
{
goto cleanup;
}
else
{
IsProfileCreated = TRUE;
}
// Create a MAPI session
hr = MAPILogonEx(
0,
szProfileName,
NULL,
ulFlags,
&lpSession);
if(FAILED(hr))
{
goto cleanup;
}
IsMAPILogon = TRUE;
#define PSESSION ((LPMAPISESSION)lpSession)
// Get entry ID of message store
hr = HrMAPIFindDefaultMsgStore(lpSession, &cbStoreEid, &lpStoreEid);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = MAPICALL(PSESSION)->OpenMsgStore(
PSESSION,
(ULONG)0,
cbStoreEid,
lpStoreEid,
NULL,
MAPI_DEFERRED_ERRORS | MDB_NO_DIALOG | MDB_WRITE,
&lpStore);
#undef PSESSION
if(FAILED(hr))
{
goto cleanup;
}
// Get the root folder in the default message store
hr = MAPICALL(lpStore)->OpenEntry(
lpStore,
(ULONG)0,
NULL,
NULL,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
&ulObjType,
(LPUNKNOWN FAR *) &lpRootFolder);
if(FAILED(hr))
{
goto cleanup;
}
// Get the MTS-IN entry ID property.
hr = MAPICALL(lpStore)->GetProps(
lpStore,
&rgMtsInEntryId,
fMapiUnicode,
&cValues,
&lpProp);
if(FAILED(hr))
{
lpProp = NULL;
goto cleanup;
}
// Check to make sure we got the right property.
if (lpProp->ulPropTag != PR_GW_MTSIN_ENTRYID)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cbMtsInEid = lpProp->Value.bin.cb;
hr = MAPIAllocateBuffer(cbMtsInEid, (void **)&lpMtsInEid);
if(FAILED(hr))
{
goto cleanup;
}
// Copy MTS-IN Entry ID
CopyMemory(lpMtsInEid,lpProp->Value.bin.lpb,cbMtsInEid);
MAPIFREEBUFFER(lpProp);
// Get the MTS-OUT entry ID property.
hr = MAPICALL(lpStore)->GetProps(
lpStore,
&rgMtsOutEntryId,
fMapiUnicode,
&cValues,
&lpProp);
if(FAILED(hr))
{
lpProp = NULL;
goto cleanup;
}
// Check to make sure we got the right property.
if(lpProp->ulPropTag != PR_GW_MTSOUT_ENTRYID)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cbMtsOutEid = lpProp->Value.bin.cb;
hr = MAPIAllocateBuffer(cbMtsOutEid, (void **)&lpMtsOutEid);
if(FAILED(hr))
{
goto cleanup;
}
// Copy MTS-OUT Entry ID
CopyMemory(lpMtsOutEid,lpProp->Value.bin.lpb,cbMtsOutEid);
MAPIFREEBUFFER(lpProp);
// Open the MTS-IN folder in the root folder
hr = MAPICALL(lpRootFolder)->OpenEntry(
lpRootFolder,
cbMtsInEid,
lpMtsInEid,
NULL,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
&ulObjType,
(LPUNKNOWN FAR *) &lpMtsInFolder);
if(FAILED(hr))
{
goto cleanup;
}
if(ulObjType != MAPI_FOLDER)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Open the MTS-OUT folder in the root folder
hr = MAPICALL(lpRootFolder)->OpenEntry(
lpRootFolder,
cbMtsOutEid,
lpMtsOutEid,
NULL,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
&ulObjType,
(LPUNKNOWN FAR *) &lpMtsOutFolder);
if(FAILED(hr))
{
goto cleanup;
}
if(ulObjType != MAPI_FOLDER)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Open the Address Book
hr = MAPICALL(lpSession)->OpenAddressBook(
lpSession,
0,
NULL,
AB_NO_DIALOG,
&lpAdrBook);
if(FAILED(hr))
{
goto cleanup;
}
hr = HrFindExchangeGlobalAddressList(
lpAdrBook,
&cbGalEid,
&lpGalEid);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrAllocAdviseSink(ScNewMailHandler, NULL, &lpAdvise);
if(FAILED(hr))
{
goto cleanup;
}
hr = MAPICALL(lpStore)->Advise(
lpStore,
cbMtsOutEid,
lpMtsOutEid,
fnevNewMail,
lpAdvise,
&ulNewMailAdvise);
if(FAILED(hr))
{
goto cleanup;
}
// Open the global recipient container
hr = MAPICALL(lpAdrBook)->OpenEntry(
lpAdrBook,
cbGalEid,
lpGalEid,
NULL,
MAPI_DEFERRED_ERRORS,
&ulObjType,
(LPUNKNOWN FAR *)&lpGalABCont);
if(FAILED(hr))
{
goto cleanup;
}
if(ulObjType != MAPI_ABCONT)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cleanup:
if(IsProfileCreated == TRUE)
{
// Mark profile for deletion
HR_LOG(HrRemoveProfile(szProfileName));
};
ULRELEASE(lpAdvise);
MAPIFREEBUFFER(lpProp);
if(FAILED(hr))
{
if((ulNewMailAdvise != 0xFFFFFFFFL) && (lpStore != NULL))
{
MAPICALL(lpStore)->Unadvise(lpStore, ulNewMailAdvise);
}
if(hNewMailEvent != NULL)
{
if(!CloseHandle(hNewMailEvent))
{
hr = HR_LOG(E_FAIL);
}
}
ULRELEASE(lpGalABCont);
ULRELEASE(lpAdrBook);
ULRELEASE(lpMtsInFolder);
ULRELEASE(lpMtsOutFolder);
ULRELEASE(lpRootFolder);
ULRELEASE(lpStore);
MAPIFREEBUFFER(lpGalEid);
if(IsMAPILogon == TRUE)
{
// Logoff a MAPI session
MAPICALL(lpSession)->Logoff(
lpSession,
(ULONG)0,
(ULONG)0,
(ULONG)0);
MAPICALL(lpSession)->Release(
lpSession);
lpSession = NULL;
}
if(IsInitMAPI == TRUE)
{
MAPIUninitialize();
IsInitMAPI = FALSE;
}
IsMAPILogon = FALSE;
}
MAPIFREEBUFFER(lpMtsInEid);
MAPIFREEBUFFER(lpMtsOutEid);
MAPIFREEBUFFER(lpStoreEid);
RETURN(hr);
}
//$--HrInternalGatewayLogoff----------------------------------------------------
// Logoff of the gateway.
// -----------------------------------------------------------------------------
static HRESULT HrInternalGatewayLogoff(void) // RETURNS: return code
{
HRESULT hr = NOERROR;
DEBUGPRIVATE("HrInternalGatewayLogoff()\n");
if((ulNewMailAdvise != 0xFFFFFFFFL) && (lpStore != NULL))
{
MAPICALL(lpStore)->Unadvise(lpStore, ulNewMailAdvise);
}
if(hNewMailEvent != NULL)
{
if(!CloseHandle(hNewMailEvent))
{
hr = HR_LOG(E_FAIL);
}
}
if(hNewMailThread != NULL)
{
if(!CloseHandle(hNewMailThread))
{
hr = HR_LOG(E_FAIL);
}
}
if(hNewFileThread != NULL)
{
if(!CloseHandle(hNewFileThread))
{
hr = HR_LOG(E_FAIL);
}
}
ULRELEASE(lpMtsInFolder);
ULRELEASE(lpMtsOutFolder);
ULRELEASE(lpRootFolder);
ULRELEASE(lpStore);
MAPIFREEBUFFER(lpGalEid);
ULRELEASE(lpGalABCont);
ULRELEASE(lpAdrBook);
if(IsMAPILogon == TRUE)
{
// Logoff a MAPI session
MAPICALL(lpSession)->Logoff(
lpSession,
(ULONG)0,
(ULONG)0,
(ULONG)0);
MAPICALL(lpSession)->Release(
lpSession);
lpSession = NULL;
}
if(IsInitMAPI == TRUE)
{
MAPIUninitialize();
IsInitMAPI = FALSE;
}
IsMAPILogon = FALSE;
DeleteCriticalSection(&csNewMailList);
DeleteCriticalSection(&csNewFileList);
RETURN(hr);
}
//$--HrServiceStartup---------------------------------------------------------
// This function is called at startup to initialize the gateway.
//------------------------------------------------------------------------------
HRESULT HrServiceStartup( // RETURNS: return code
IN HINSTANCE hInstance, // handle of current instance
IN HINSTANCE hPrevInstance, // handle of previous instance
IN HWND hwndMainWindow, // handle to main window
IN LPSTR lpszCmdLine) // pointer to command line
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
DEBUGPUBLIC("HrServiceStartup()\n");
hr = HrInternalGatewayLogon();
if(FAILED(hr))
{
goto cleanup;
}
hr = HrGWLogon();
if(FAILED(hr))
{
goto cleanup;
}
cleanup:
if(FAILED(hr))
{
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
RETURN(hr);
}
//$--ServiceMain--------------------------------------------------------------
// This function is given its own thread to execute.
//------------------------------------------------------------------------------
void ServiceMain( // RETURNS: nothing
IN HANDLE hEventShutdown) // handle to shutdown event object
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("ServiceMain()\n");
__try
{
GWMain();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
//
// Wait for the gateway to stop.
//
__try
{
hr = HrGWWaitForStop();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
}
if(FAILED(hr))
{
hr = HR_LOG(hr);
}
//
// Confirm that the gateway has stopped.
//
__try
{
hr = HrServiceConfirmStop();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
}
if(FAILED(hr))
{
hr = HR_LOG(hr);
}
ExitThread(0);
}
//$--HrServiceShutdown--------------------------------------------------------
// This function is called to shutdown the gateway.
//------------------------------------------------------------------------------
HRESULT HrServiceShutdown( // RETURNS: exit code
void)
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
DEBUGPUBLIC("HrServiceShutdown()\n");
hr = HrGWLogoff();
if(FAILED(hr))
{
goto cleanup;
}
hr = HrInternalGatewayLogoff();
if(FAILED(hr))
{
goto cleanup;
}
cleanup:
if(FAILED(hr))
{
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
RETURN(hr);
}