// --xlatdriv.c-------------------------------------------------------------------
//
// Message translation sample.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
//
// -----------------------------------------------------------------------------
#include "edk.h"
#include "convcwrp.h"
#include "gwmain.h"
#include "ipmconv.h" // for ipm_in & ipm_out conversion DLLs
#include "xlatmsg.h" // resource string identifiers
#include "xlatdriv.chk"
// constants
#define MAX_MSG_LENGTH 1024 // maximum message length
#define APPLICATION_TITLE TEXT("Message Translation Sample") // application name
#define APPLICATION_EVENT_FILE TEXT("EDKMSG.DLL") // event logging message file
// Defined for NT service shell
TCHAR szAppName[] = TEXT("XLATDRIV");
TCHAR szWindowTitle[] = APPLICATION_TITLE;
static LPMAPISESSION lpSession = NULL;
static LPMDB lpStore = NULL;
static LPMAPIFOLDER lpRootFolder = NULL;
static LPMAPIFOLDER lpMtsInFolder = NULL;
static LPMAPIFOLDER lpMtsOutFolder = NULL;
static ULONG cbGalEid = 0;
static LPENTRYID lpGalEid = NULL;
static HANDLE hEventLog = NULL;
static HINSTANCE hInst = NULL; // program instance handle
PVOID pvConvInstance = NULL;
// Prefix of output *.tmp files.
static const LPCTSTR lpszPrefix = TEXT("XLT");
// Default inbound/outbound file directory
const LPCTSTR lpszDefaultDir = TEXT(".\\");
// inbound and outbound file directory
static TCHAR lpszDirectory[MAX_PATH + 1] = TEXT("");
// Address type used for conversion (Currently "EX")
static TCHAR lpszAddressType[] = TEXT(EXCHANGE_ADDRTYPE); // address type
// Conversion options structure for the ipm_in & ipm_out conversion DLLs
static CONV_OPTIONS sConvOptions =
{
FALSE, // don't want TNEF decoding
lpszAddressType // address type
};
static ULONG nMessages = 0; // # messages converted
//$--ProcessMtsOut--------------------------------------------------------------------
//
// DESCRIPTION: Process messages arriving at MTS-OUT. This is a Windows thread
// startup routine.
//
// INPUT: lpParameter -- pointer to gateway thread context structure
// (LPGWTHREADCONTEXT).
//
// RETURNS: DWORD -- 0
//
// -----------------------------------------------------------------------------
DWORD ProcessMtsOut( // RETURNS: DWORD
IN LPVOID lpParameter) // gateway thread context structure pointer
{
HRESULT hr = NOERROR; // temporary return code
ULONG i = 0;
ULONG cRows = 0;
ULONG cValues = 0;
ULONG ulObjType = 0;
LPADRBOOK lpAdrBook = NULL;
LPMESSAGE lpEnvelope = NULL;
ULONG cbeid = 0;
LPENTRYID lpeid = NULL;
LPWSTR pszMessageClassW = NULL;
ULONG cbMessageClass = 0;
EDKCNVRES crRes = GCR_OK;
LPSPropValue lpProps = NULL;
LPSTREAM lpStream = NULL; // stream to write output to
// message output file name
TCHAR pszFileName[MAX_PATH+1] = TEXT("");
//
// Declare an environment for the conversion.
//
EDKCNVENV envTmp =
{
1,
L"SAMPLEGW.OUTBOUND", // L = UNICODE string always.
(LHANDLE)NULL,
NULL,
NULL,
NULL
};
// Stream interface flags
const ULONGulFlags=STGM_READWRITE | STGM_CREATE |
SOF_UNIQUEFILENAME | STGM_SHARE_EXCLUSIVE;
DEBUGPUBLIC("ProcessMtsOut()\n");
// check input parameters
hr = CHK_Process(lpParameter);
if ( FAILED(hr) )
{
RETURN(hr);
}
cRows = GetGWSRowSet(lpParameter)->cRows;
// Open the Address Book
hr = MAPICALL(lpSession)->OpenAddressBook(
lpSession,
0,
NULL,
AB_NO_DIALOG,
&lpAdrBook);
if(FAILED(hr))
{
goto cleanup;
}
// Initialize conversion environment structure
envTmp.lphSession = (LHANDLE)lpSession;
envTmp.lpAB = lpAdrBook;
envTmp.pGatewayDefined = &sConvOptions;
for(i = 0; i < cRows; i++)
{
// Free MAPI buffer
MAPIFREEBUFFER(pszMessageClassW);
// Release MAPI objects
ULRELEASE(lpEnvelope);
ULRELEASE(lpStream);
cValues = GetGWSRowSet(lpParameter)->aRow[i].cValues;
lpProps = GetGWSRowSet(lpParameter)->aRow[i].lpProps;
cbeid = lpProps[0].Value.bin.cb;
lpeid = (LPENTRYID)lpProps[0].Value.bin.lpb;
// Get the message in the MTS-OUT folder
hr = MAPICALL(lpMtsOutFolder)->OpenEntry(
lpMtsOutFolder,
cbeid,
lpeid,
NULL,
MAPI_MODIFY|MAPI_DEFERRED_ERRORS,
&ulObjType,
(LPUNKNOWN FAR *)&lpEnvelope);
if(FAILED(hr))
{
goto cleanup;
}
if(ulObjType != MAPI_MESSAGE)
{
goto cleanup;
}
// Initialize output file name.
lstrcpy(pszFileName, lpszDirectory);
// Open a buffered stream interface on a unique XLT*.tmp
// output file.
hr = OpenStreamOnFile(
MAPIAllocateBuffer, // allocation routine
MAPIFreeBuffer, // deallocation routine
ulFlags,// stream interface flags
pszFileName, // file name
(LPTSTR) lpszPrefix, // file prefix
&lpStream); // stream pointer
if ( FAILED(hr) )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Get the message's wide character message class.
hr = HrMAPIGetPropString(
(LPMAPIPROP) lpEnvelope, // message envelope pointer
PR_MESSAGE_CLASS_W, // wide character message class
&cbMessageClass,
&pszMessageClassW);
if ( FAILED(hr) )
{
goto cleanup;
}
//
// Perform the conversion.
//
hr = HrConvConvert(
pvConvInstance,
&envTmp,
pszMessageClassW,
lpEnvelope,
lpStream,
&crRes);
if(FAILED(hr) || crRes != GCR_OK)
{
goto cleanup;
}
// Note: Conversion DLL commits changes to stream if
// successful.
ULRELEASE(lpEnvelope);
// ---------------------------------------------------------------------
//
// Remove the converted message from the MTS-OUT folder.
//
hr = HrMAPIDeleteMessage(
lpMtsOutFolder, // MAPI folder pointer
cbeid, // # bytes in entry id
lpeid); // message entry identifier
if(FAILED(hr))
{
goto cleanup;
}
// increment message count
nMessages++;
} // end for
cleanup:
// Release MAPI and OLE objects
ULRELEASE(lpStream);
ULRELEASE(lpEnvelope);
ULRELEASE(lpAdrBook);
// Free MAPI buffers
MAPIFREEBUFFER(pszMessageClassW);
if ( (FAILED(hr) || (crRes != GCR_OK)) && (pszFileName[0] != 0) )
{
// If we failed, we may have an empty file
// siting around.
if ( lstrcmp(pszFileName, lpszDefaultDir) != 0 )
{
// Remove the empty file
DeleteFile(pszFileName);
}
}
return(0);
}
//$--ProcessMtsIn--------------------------------------------------------------------
//
// DESCRIPTION: Process files arriving in input directory. This is a Windows thread
// startup routine.
//
// INPUT: lpParameter -- pointer to gateway thread context structure
// (LPGWTHREADCONTEXT).
//
// RETURNS: DWORD -- 0
//
// -----------------------------------------------------------------------------
DWORD ProcessMtsIn( // RETURNS: DWORD
IN LPVOID lpParameter) // gateway thread context structure pointer
{
HRESULT hr = NOERROR; // temporary error code
ULONG i = 0; // index
ULONG cRows = 0; // row count
LPADRBOOK lpAdrBook = NULL; // address book pointer
LPMESSAGE lpEnvelope = NULL; // envelope pointer
EDKCNVRES crRes = GCR_OK; // result of conversion
LPSTREAM lpStream = NULL; // stream to read input from
BOOL fRetVal = FALSE; // Win32 return code
// File data
LPWIN32_FIND_DATA rgFindData = NULL;
LPWIN32_FIND_DATA lpFindData = NULL;
// message output file name
TCHAR pszFileName[MAX_PATH+1] = TEXT("");
//
// Declare an environment for the conversion.
//
EDKCNVENV envTmp =
{
1,
L"SAMPLEGW.INBOUND", // L = UNICODE string always.
(LHANDLE)NULL,
NULL,
NULL,
NULL
};
const LPCWSTR pszMessageClassW = L"ENVELOPE.IPM"; // dummy message class
DEBUGPUBLIC("ProcessMtsIn()\n");
// check input parameters
hr = CHK_Process(lpParameter);
if ( FAILED(hr) )
{
RETURN(hr);
}
cRows = GetGWFindDataSize(lpParameter);
rgFindData = GetGWFindData(lpParameter);
// Open the Address Book
hr = MAPICALL(lpSession)->OpenAddressBook(
lpSession,
0,
NULL,
AB_NO_DIALOG,
&lpAdrBook);
if(FAILED(hr))
{
goto cleanup;
}
// Initialize the conversion environment structure
envTmp.lphSession = (LHANDLE)lpSession;
envTmp.lpAB = lpAdrBook;
envTmp.pGatewayDefined = &sConvOptions;
for(i = 0; i < cRows; i++)
{
// Release MAPI objects
ULRELEASE(lpEnvelope);
ULRELEASE(lpStream);
// Build file name of incoming message
lpFindData = &rgFindData[i];
lstrcpy(pszFileName, lpszDirectory);
lstrcat(pszFileName, lpFindData->cFileName);
// Open a buffered stream on our input file.
hr = OpenStreamOnFile(
MAPIAllocateBuffer, // allocation routine
MAPIFreeBuffer, // deallocation routine
STGM_READ | STGM_SHARE_EXCLUSIVE,// open for reading
pszFileName, // file name
NULL, // prefix
&lpStream); // stream pointer
if ( (hr == MAPI_E_NO_ACCESS) || (hr == MAPI_E_NOT_FOUND) )
{
// These are not really errors
hr = NOERROR;
continue;
}
if ( FAILED(hr) )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Create the message envelope in the MTS-IN folder.
hr = MAPICALL(lpMtsInFolder)->CreateMessage(
lpMtsInFolder, // folder pointer
NULL,
MAPI_DEFERRED_ERRORS, // flags
&lpEnvelope); // message pointer
if( FAILED(hr) )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Perform the conversion.
//
hr = HrConvConvert(
pvConvInstance, // conversion instance pointer
&envTmp, // environment structure pointer
pszMessageClassW, // dummy message class
lpStream, // stream to read from
lpEnvelope, // message to convert to
&crRes); // result pointer
if(FAILED(hr) || crRes != GCR_OK)
{
goto cleanup;
}
// Note: Conversion DLL saves changes to the envelope if
// successful.
// Save changes to the MTS-IN folder
hr = MAPICALL(lpMtsInFolder)->SaveChanges(
lpMtsInFolder,
KEEP_OPEN_READWRITE); // still need access to folder
if ( FAILED(hr) )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
ULRELEASE(lpStream);
// Remove the converted file from the input directory.
fRetVal = DeleteFile(pszFileName);
if ( fRetVal == FALSE )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// increment message count
nMessages++;
} // end for
cleanup:
// Release MAPI and OLE objects
ULRELEASE(lpStream);
ULRELEASE(lpEnvelope);
ULRELEASE(lpAdrBook);
return(0);
}
// $--DisplayUserMsg----------------------------------------------------------
//
// DESCRIPTION: Utility to display message to command line user.
//
// INPUT: HINSTANCE -- XLATDRIV instance handle
// UINT -- Resource string identifier
//
// RETURNS: VOID
//
// ----------------------------------------------------------------------------
static VOID DisplayUserMsg( // RETURNS: nothing
IN HINSTANCE hInst, // program handle
IN UINT nResID, // resource string identifier
...) // additional arguments
{
INT nRetCode = 0; // return value
va_list vArgList = {0}; // variable argument list
HANDLE hFile = NULL; // file handle
TCHAR szMessage[MAX_MSG_LENGTH] = TEXT(""); // message buffer
TCHAR szFormatted[MAX_MSG_LENGTH] = TEXT(""); // formatted message
DEBUGPRIVATE("DisplayUserMsg()\n");
// No CHK_DisplayUserMsg() call.
// This function can take a NULL HINSTANCE
// Check the instance handle passed in.
if ( !hInst )
{
HR_LOG(E_FAIL);
goto cleanup;
}
nRetCode = LoadString(hInst, nResID, szMessage, MAX_MSG_LENGTH);
if ( nRetCode == 0 )
{
HR_LOG(E_FAIL);
goto cleanup;
}
// Get an optional argument list pointer
va_start(vArgList, nResID);
// Fromat the message.
_vstprintf(
szFormatted, // formatted message buffer
szMessage, // format string
vArgList); // variable argument list
va_end(vArgList);
// Display the error in a message box
MessageBox(
NULL, // use parent window handle
szFormatted, // message text
APPLICATION_TITLE, // message box title
MB_OK);
cleanup:
// close console file
CLOSEHANDLE(hFile);
// Return
return;
} // end DisplayUserMsg()
// $--HrParseOptions-----------------------------------------------------------
//
// DESCRIPTION: parse command line flags.
//
// INPUT: cArgs -- # arguments
// pArgv -- argument array
//
// OUTPUT:
// pfInbound -- inbound flag
// pfTnef -- TNEF flag
// pcThreads -- # threads
// lpszDirectory -- file directory
//
// RETURNS: HRESULT -- NOERROR if successful,
// E_INVALIDARG if bad input
// E_FAIL otherwise.
//
// ----------------------------------------------------------------------------
static HRESULT HrParseOptions(
IN DWORD cArgs, // argument count
IN LPTSTR * pArgv, // argument array
OUT BOOL * pfInbound, // inbound flag
OUT BOOL * pfTnef, // TNEF encoding desired flag
OUT DWORD * pcThreads, // # threads
OUT LPTSTR lpszDirectory) // file directory
{
// Number of flag arguments and array indeces
#define iDirection 0
#define iThreads 1
#define iLocation 2
#define iHelp1 3
#define iHelp2 4
#define iTnef 5
#define nFlags 6
HRESULT hr = NOERROR;
UINT iLoop = 0; // loop index
ULONG iFlag = 0; // flag index
LPTSTR lpFlagName = NULL; // flag name pointer
LPTSTR lpData = NULL; // flag data
HANDLE hFile = NULL; // file handle
BOOL fInbound = FALSE; // TRUE if direction inbound
BOOL fOutbound = FALSE; // TRUE if direction outbound
UINT nRet = 0; // Win32 API return code
UINT nChars = 0;
const LPCTSTR lpszInbound = TEXT("In"); // inbound value
const LPCTSTR lpszOutbound = TEXT("Out"); // outbound value
const TCHAR chBackSlash = TEXT('\\'); // back slash
// array of valid flags
LPTSTR rgFlags[nFlags] =
{
TEXT("DIRECTION"), // Inbound or outbound
TEXT("THREADS"), // # of threads
TEXT("LOCATION"), // location of input/output files
TEXT("HELP"),
TEXT("?"),
TEXT("ENCODE") // TNEF encoding/decoding desired
};
// temporary file name
TCHAR szTempFile[MAX_PATH + 1] = TEXT("");
DEBUGPRIVATE("HrParseOptions()\n");
// check input parameters
hr = CHK_HrParseOptions(cArgs, pArgv, pfInbound, pfTnef, pcThreads,
lpszDirectory);
if ( FAILED(hr) )
{
RETURN(hr);
}
// Check to make sure that we have enough arguments.
// Note: If the use originally typed
// xlatdriv notserv gdk-sample, then the arguments
// which are passed to this program are everything
// after the program name and the notserv option.
if ( cArgs < 1 )
{
hr = HR_LOG(E_INVALIDARG);
// Print out the syntax error message.
DisplayUserMsg(hInst, IDS_ERROR_USAGE);
goto cleanup;
}
// initialize output parameters
*pfInbound = FALSE;
*pfTnef = FALSE;
*pcThreads = 1;
lstrcpy(lpszDirectory, lpszDefaultDir);
// Parse each argument, looking for a supported flag
for ( iLoop = 0; iLoop < cArgs; iLoop++ )
{
hr = _HrExpandCommandLineArgument(
pArgv[iLoop], // command line argument
rgFlags, // array of flag names
nFlags, // number of flags
&iFlag, // flag index
&lpFlagName, // flag name
&lpData); // flag data
if ( FAILED(hr) )
{
DisplayUserMsg(
hInst, // instance handle
IDS_INVALID_ARG, // string identifier
pArgv[iLoop]); // argument
goto cleanup;
}
if ( lpFlagName == NULL )
{
// not a flag. We are only interested in flags
continue;
}
// switch off of flag found
switch ( iFlag )
{
case iDirection: // direction index
if ( (lpData == NULL) || (*lpData == 0) )
{
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(
hInst, // instance handle
IDS_ERROR_NOVALUE, // string identifier
lpFlagName); // argument
goto cleanup;
}
// Determine if inbound or outbound
if ( _tcsnicmp(lpData, lpszInbound, lstrlen(lpszInbound))
== 0 )
{
fInbound = TRUE;
*pfInbound = TRUE;
}
else if ( _tcsnicmp(lpData, lpszOutbound, lstrlen(lpszOutbound))
== 0 )
{
fOutbound = TRUE;
*pfInbound = FALSE;
}
else
{
// print out error.
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(
hInst, // instance handle
IDS_INVALID_VALUE, // string identifier
lpData,
lpFlagName); // argument
goto cleanup;
}
break;
case iThreads: // threads index
// Initialize number of threads
if ( (lpData == NULL) || (*lpData == 0) )
{
// print out error
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(
hInst, // instance handle
IDS_ERROR_NOVALUE, // string identifier
lpFlagName); // argument
goto cleanup;
}
*pcThreads = atol(lpData);
if ( *pcThreads == 0 )
{
// print out error
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(
hInst, // instance handle
IDS_INVALID_VALUE, // string identifier
lpData,
lpFlagName); // argument
goto cleanup;
}
break;
case iLocation: // location index
if ( (lpData == NULL) || (*lpData == 0) )
{
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(
hInst, // instance handle
IDS_ERROR_NOVALUE, // string identifier
lpFlagName); // argument
goto cleanup;
}
// Make sure that we can create a file in the
// directory.
// First, get a temporary file name
nRet = GetTempFileName(
lpData, // directory
lpszPrefix, // file prefix
0, // use time to create number
szTempFile); // file name
if ( nRet == 0 )
{
hr = HR_LOG(E_FAIL);
DisplayUserMsg(
hInst, // instance handle
IDS_INVALID_VALUE, // string identifier
lpData,
lpFlagName); // argument
goto cleanup;
}
hFile = CreateFile(
szTempFile, // file name
GENERIC_READ | GENERIC_WRITE,
0,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
if ( hFile == INVALID_HANDLE_VALUE )
{
// print out error
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(
hInst, // instance handle
IDS_INVALID_VALUE, // string identifier
lpData,
lpFlagName); // argument
goto cleanup;
}
// Close the file
CLOSEHANDLE(hFile);
// Delete the file
(VOID)DeleteFile(
szTempFile); // file name
lstrcpy(lpszDirectory, lpData);
// Append a back slash to the directory
// name if it doesn't alredy have one.
nChars = lstrlen(lpszDirectory);
if ( lpszDirectory[nChars - 1] != chBackSlash )
{
lpszDirectory[nChars] = chBackSlash;
lpszDirectory[nChars + 1] = 0; // null terminate
}
break;
case iHelp1: // help index
case iHelp2: // ? index
// print out help.
// Not really an error, but we need
// to exit early.
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(hInst, IDS_ERROR_HELP);
goto cleanup;
case iTnef: // TNEF index
// User wants TNEF encoding/decoding
// Data portion of flag is ignored.
*pfTnef = TRUE;
break;
default:
hr = HR_LOG(E_FAIL);
DisplayUserMsg(
hInst, // instance handle
IDS_INVALID_ARG, // string identifier
lpData); // argument
goto cleanup;
} // end switch
} // end for
// make sure that haven't received conflicting directions
if ( fInbound && fOutbound )
{
// print out error.
hr = HR_LOG(E_INVALIDARG);
DisplayUserMsg(
hInst, // instance handle
IDS_CONFLICTING_DIRECTION); // string identifier
goto cleanup;
}
cleanup:
RETURN(hr);
}
//$--GWMain----------------------------------------------------------------
//
// DESCRIPTION: Start threads.
//
// INPUT: none
//
// RETURNS: VOID
//
// -----------------------------------------------------------------------------
VOID GWMain( // RETURNS: VOID
VOID)
{
HRESULT hr = NOERROR;
EDK_SERVICE_CONTROL_T sc = 0;
DWORD cArgs = 0;
LPTSTR * pArgv = NULL;
BOOL fInbound = FALSE;
BOOL fTnef = FALSE;
DWORD cThreads = 1;
TCHAR szTempPath[MAX_PATH+1] = {0};
const DWORD cMessages = 1;
DWORD cch = 0;
DEBUGPUBLIC("GWMain()\n");
// Get this program's instance handle.
hInst = GetModuleHandle(NULL);
if ( hInst == NULL )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Retrieve the command line arguments
// Command line is of the form
//
// XLATDRIV [notserv] GWProfileName [flags]
//
// where flags are:
//
// /DIRECTION=Inbound or /DIRECTION=Outbound
// /THREADS=#Thread
// /LOCATION=DirectoryName (for input or output files)
// /ENCODE (TNEF encoding/decoding desired)
//
// By default, the direction is assumed to be outbound,
// TNEF encoding is assumed to be FALSE,
// the file location is assumed to be the current directory
// and the number of threads is assumed to be 1. (If
// notserv is not specified, winwrap.c assumes that XLATDRIV
// is to be run as a service.)
hr = HrServiceGetArgv(
&cArgs, // argument count pointer
&pArgv); // pointer to argument array pointer
if ( FAILED(hr) )
{
goto cleanup;
}
// Parse out options.
hr = HrParseOptions(
cArgs, // argument count
pArgv, // pointer to argument array
&fInbound, // inbound flag
&fTnef, // TNEF desired flag
&cThreads, // # threads
lpszDirectory); // file directory
if ( FAILED(hr) )
{
goto cleanup;
}
// Set TNEF flag in gateway options.
sConvOptions.fTnefEncode = fTnef;
if ( fInbound )
{
// Want to do inbound conversion.
// (Read files in and convert to messages in MTS-IN)
hr = HrGWStartNewFileHandler(
1000, // sleep interval
(ULONG) -1, // poll interval
cMessages, // # messages per thread
cThreads, // # of threads
lpszAddressType, // address type
TEXT("XLT*.TMP"), // file name template
lpszDirectory, // input file directory
(LPTHREAD_START_ROUTINE)ProcessMtsIn);
if ( FAILED(hr) )
{
goto cleanup;
}
}
else
{
cch = GetTempPath(MAX_PATH+1, szTempPath);
if((cch == 0) || (cch > (MAX_PATH+1)))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Want to do outbound conversions.
// (Read messages from MTS-OUT and convert to output
// files.
hr = HrGWStartNewMailHandler(
1000,
(ULONG)-1,
cMessages,
cThreads,
lpszAddressType,
szTempPath,
(LPTHREAD_START_ROUTINE)ProcessMtsOut);
if ( FAILED(hr) )
{
goto cleanup;
}
} // end if doing out bound conversions
cleanup:
if(FAILED(hr))
{
ServiceStop();
}
//
// Wait for a request for the service to stop.
//
hr = HR_LOG(HrServiceWaitForStop(INFINITE, &sc));
return;
}
//$--HrGWLogon-------------------------------------------------------------
//
// Logon to the gateway.
//
// -----------------------------------------------------------------------------
HRESULT HrGWLogon( // RETURNS: return code
VOID)
{
HRESULT hr = NOERROR;
lpSession = GetGWSession();
lpStore = GetGWDefaultStore();
lpRootFolder = GetGWRootFolder();
lpMtsInFolder = GetGWMtsInFolder();
lpMtsOutFolder = GetGWMtsOutFolder();
cbGalEid = GetGWGALEntryIdSize();
lpGalEid = GetGWGALEntryId();
DEBUGPUBLIC("HrGWLogon()\n");
// Open an event log for this application.
hr = HrEventOpenLog(
APPLICATION_TITLE, // application name
NULL, // executable name (will be computed)
APPLICATION_EVENT_FILE, // event message file (will be computed)
NULL, // parameter message file (will be computed)
NULL, // category message file (will be computed)
&hEventLog); // event source handle
if ( FAILED(hr) || (hEventLog == NULL) )
{
goto cleanup;
}
// Initialize conversion engine global data.
hr = HrConvInitGlobals();
if ( FAILED(hr) )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Initialize conversion engine instance data.
hr = HrConvInitInstance(hEventLog, &pvConvInstance);
if ( FAILED(hr) )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cleanup:
RETURN(hr);
}
//$--HrGWLogoff------------------------------------------------------------
//
// Logoff of the gateway.
//
// -----------------------------------------------------------------------------
HRESULT HrGWLogoff( // RETURNS: return code
VOID)
{
HRESULT hr = NOERROR;
EDKEVENTCOUNT sEventCount = {0}; // EDK event count structure
DEBUGPUBLIC("HrGWLogoff()\n");
// De-initialize conversion engine instance data.
(VOID)HrConvUninitInstance(pvConvInstance);
pvConvInstance = NULL;
// De-intialize global conversion engine data.
ConvUninitGlobals();
// Display number of messages processed.
if ( nMessages >= 0 )
{
DisplayUserMsg(
hInst, // instance handle
IDS_SUCCESS, // string identifier
nMessages); // # messages processed
}
// Determine number of messages written to the event log.
hr = HrEventGetCounts(
&sEventCount);
if ( SUCCEEDED(hr) )
{
// print out number of errors printed to the
// event log.
if ( sEventCount.cError == 1 )
{
DisplayUserMsg(
hInst,
IDS_1_ERROR);
}
else if ( sEventCount.cError > 1 )
{
DisplayUserMsg(
hInst,
IDS_NUM_ERRORS,
sEventCount.cError);
}
// Print out the number of warnings logged
if ( sEventCount.cWarning == 1 )
{
DisplayUserMsg(
hInst,
IDS_1_WARNING);
}
else if ( sEventCount.cWarning > 1 )
{
DisplayUserMsg(
hInst,
IDS_NUM_WARNINGS,
sEventCount.cWarning);
}
} // end if know # of messages logged to event file
// Close the event log.
(VOID)HrEventCloseLog();
hEventLog = NULL;
RETURN(hr);
}