// --gwsample.c-----------------------------------------------------------------
//
// Sample gateway application.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------
#include "edk.h"
#include "gwmain.h"
#include "gwsample.h"
#include "attrname.h"
#include "convcwrp.h"
#include "ipmconv.h"
#include "sgwdata.h"
TCHAR szAppName[] = TEXT("GWSAMPLE");
TCHAR szWindowTitle[] = TEXT("Sample Gateway");
// Output/Input file name prefix.
TCHAR szFilePrefix[] = TEXT("SGW");
#define C_EQU TEXT("C=")
#define A_EQU TEXT("A=")
#define P_EQU TEXT("P=")
static TCHAR szServiceName[MAX_SERVICE_NAME_LENGTH+1] = {0};
static LPTSTR lpszLocalGDI = NULL;
static CRITICAL_SECTION csGatewaySeqNo = {0};
static ULONG ulGatewaySeqNo = 0;
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;
//performance code
LONG cInThreads = 0;
ULONG cInMessages = 0;
LPTSTR lpszAddressType = NULL;
LPTSTR lpszSysAdminName = NULL;
LPTSTR lpszSysAdminAddr = NULL;
LPTSTR lpszInDirectory = NULL;
LPTSTR lpszInConverter = NULL;
LPWSTR lpszInConverterW = NULL;
BOOL fInEnabled = FALSE;
ULONG cbBufferSize = 0;
LPBYTE lpbBuffer = NULL;
ULONG cBufferArraySize = 0;
LPTSTR *lppszBufferArray = NULL;
DWORD dwInSleepInterval = 0;
DWORD dwInPollInterval = 0;
LONG cOutThreads = 0;
ULONG cOutMessages = 0;
LPTSTR lpszOutDirectory = NULL;
LPTSTR lpszOutConverter = NULL;
LPWSTR lpszOutConverterW = NULL;
BOOL fOutEnabled = FALSE;
DWORD dwOutSleepInterval = 0;
DWORD dwOutPollInterval = 0;
LPTSTR lpszArchiveDirectory = NULL;
HANDLE hEventLog = NULL;
typedef struct _id_item
{
CRITICAL_SECTION *lpcs; // only used by list
LPTSTR lpszId;
struct _id_item *next;
} IDITEM, *LPIDITEM;
static CRITICAL_SECTION csInboundIdList = {0};
static CRITICAL_SECTION csOutboundIdList = {0};
static IDITEM InboundIdList = {0};
static IDITEM OutboundIdList = {0};
// Size is because country 2-3, ADMD 0-16, PRMD is 1-16 and LocalId1-32 plus
// size for "/c=/p=/a=/l=". So 3+16+16+32+12+1 = 80.
#define cbMTSIDMax (80)
//$--HrCreateIdItem-------------------------------------------------------------
// Creates an ID item.
// -----------------------------------------------------------------------------
HRESULT HrCreateIdItem( // RETURNS: return code
IN LPSTR lpszId, // identifier
OUT LPIDITEM *lppIdItem) // identifier item
{
HRESULT hr = NOERROR;
LPIDITEM lpIdItem = NULL;
ULONG cBytes = 0;
*lppIdItem = NULL;
cBytes = sizeof(IDITEM);
hr = MAPIAllocateBuffer(cBytes, (void **)&lpIdItem);
if(FAILED(hr))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
ZeroMemory(lpIdItem, cBytes);
cBytes = cbStrLen(lpszId);
hr = MAPIAllocateMore(cBytes, lpIdItem, (void **)&lpIdItem->lpszId);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lstrcpy(lpIdItem->lpszId, lpszId);
*lppIdItem = lpIdItem;
cleanup:
RETURN(hr);
}
//$--HrDestroyIdItem------------------------------------------------------------
// Destroys an ID item.
// -----------------------------------------------------------------------------
HRESULT HrDestroyIdItem( // RETURNS: return code
IN OUT LPIDITEM *lppIdItem) // identifier item
{
HRESULT hr = NOERROR;
MAPIFREEBUFFER(*lppIdItem);
RETURN(hr);
}
//$--HrLookupIdItem-------------------------------------------------------------
// Looks up an ID item.
// -----------------------------------------------------------------------------
HRESULT HrLookupIdItem( // RETURNS: return code
IN LPIDITEM lpIdList, // identifier item list
IN LPTSTR lpszId, // identifier
IN OUT LPIDITEM *lppIdItem) // identifier item
{
HRESULT hr = EDK_E_NOT_FOUND;
HRESULT hrT = NOERROR;
LPIDITEM lpIdItem = NULL;
__try
{
*lppIdItem = NULL;
lpIdItem = lpIdList->next;
while(lpIdItem != NULL)
{
if(!lstrcmpi(lpIdItem->lpszId, lpszId))
{
//
// Found identifier in ID list
//
*lppIdItem = lpIdItem;
hr = NOERROR;
goto cleanup;
}
lpIdItem = lpIdItem->next;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
cleanup:
RETURN(hr);
}
//$--HrAddIdItem----------------------------------------------------------------
// Adds an ID item to a list.
// -----------------------------------------------------------------------------
HRESULT HrAddIdItem( // RETURNS: return code
IN LPIDITEM lpIdList, // identifier item list
IN LPTSTR lpszId, // identifier
IN OUT LPIDITEM *lppIdItem) // identifier item
{
HRESULT hr = EDK_E_NOT_FOUND;
HRESULT hrT = NOERROR;
LPIDITEM lpIdItem = NULL;
EnterCriticalSection(lpIdList->lpcs);
hr = HrLookupIdItem(lpIdList, lpszId, &lpIdItem);
if(hr != EDK_E_NOT_FOUND)
{
hr = HR_LOG(EDK_E_ALREADY_EXISTS);
goto cleanup;
}
__try
{
*lppIdItem = NULL;
hr = HrCreateIdItem(
lpszId,
&lpIdItem);
if(FAILED(hr))
{
goto cleanup;
}
lpIdItem->next = lpIdList->next;
lpIdList->next = lpIdItem;
*lppIdItem = lpIdItem;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
cleanup:
LeaveCriticalSection(lpIdList->lpcs);
RETURN(hr);
}
//$--HrRemoveIdItem-------------------------------------------------------------
// Removes an ID item from a list.
// -----------------------------------------------------------------------------
HRESULT HrRemoveIdItem( // RETURNS: return code
IN LPIDITEM lpIdList, // identifier item list
IN LPIDITEM lpIdItem) // identifier item
{
HRESULT hr = EDK_E_NOT_FOUND;
HRESULT hrT = NOERROR;
LPIDITEM lpPrevIdItem = NULL;
LPIDITEM lpCurrIdItem = NULL;
EnterCriticalSection(lpIdList->lpcs);
__try
{
lpCurrIdItem = lpIdList->next;
while(lpCurrIdItem != NULL)
{
if(lpCurrIdItem == lpIdItem)
{
//
// Found identifier item in ID list
//
if(lpIdList->next == lpIdItem)
{
// item found at head of list
lpIdList->next = lpIdItem->next;
}
else
{
lpPrevIdItem->next = lpIdItem->next;
}
hr = NOERROR;
goto cleanup;
}
lpPrevIdItem = lpCurrIdItem;
lpCurrIdItem = lpCurrIdItem->next;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
cleanup:
hrT = HrDestroyIdItem(&lpIdItem);
if(FAILED(hr))
{
hrT = HR_LOG(E_FAIL);
}
LeaveCriticalSection(lpIdList->lpcs);
RETURN(hr);
}
//$--HrEmptyIdList--------------------------------------------------------------
// Empty an ID list.
// -----------------------------------------------------------------------------
HRESULT HrEmptyIdList( // RETURNS: return code
IN LPIDITEM lpIdList) // identifier item list
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPIDITEM lpIdItem = NULL;
EnterCriticalSection(lpIdList->lpcs);
__try
{
lpIdItem = lpIdList->next;
while(lpIdItem != NULL)
{
lpIdList->next = lpIdItem->next;
MAPIFREEBUFFER(lpIdItem);
lpIdItem = lpIdList->next;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
LeaveCriticalSection(lpIdList->lpcs);
RETURN(hr);
}
//$--HrCreateMtsId--------------------------------------------------------------
// Returns the newly created stringized MTS identifier. It takes in a site
// MTS identifier string that contains the country, ADMD and PRMD code and
// creates the local identifier to create a new MTS identifier.
// -----------------------------------------------------------------------------
HRESULT HrCreateMtsId( // RETURNS: return code
IN LPSTR lpszSiteMtsId, // site MTS identifier
IN LPSTR lpszGatewayName, // gateway name
IN ULONG ulSeqNo, // sequence number
OUT LPSTR lpszMTSID) // MTS identifier
{
HRESULT hr = NOERROR;
SYSTEMTIME st = {0};
CHAR rgchUTC[cbMTSIDMax] = {0};
ULONG cbMTName = 0;
LPSTR lpszMTName[cbMTSIDMax] = {0};
ULONG cbSeqNo = 0;
CHAR rgchSeqNo[9] = {0};
// Get the current time and make it a UTCTime string
GetSystemTime(&st);
sprintf(rgchUTC, "%04u%02u%02u%02u%02u%02uZ",
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond);
// format the ulSeqNo into a string and get's length
sprintf((LPSTR)rgchSeqNo, "%08lx", ulSeqNo);
cbSeqNo = strlen(rgchSeqNo);
// find out how much of the gateway name can be put into the local identifer
cbMTName = 32 - cbSeqNo - strlen(rgchUTC) - 2;
lstrcpy((LPSTR)lpszMTName, lpszGatewayName);
if(cbMTName < (ULONG)lstrlen((LPSTR)lpszMTName))
{
lpszMTName[cbMTName] = 0;
}
//
// Format of local identifier is:
// "Gateway Name-stringized UTC Time-stringized ulSeqNo"
// NOTE: DO NOT CHANGE Delimiter to "/".
//
sprintf(
lpszMTSID,
"%s;L=%s-%s-%s",
lpszSiteMtsId,
lpszMTName,
rgchUTC,
rgchSeqNo);
RETURN(hr);
}
//$--DumpPropProblems-----------------------------------------------------------
// Dumps property problems to the debug log.
//------------------------------------------------------------------------------
VOID DumpPropProblems( // RETURNS: nothing
IN LPSTR lpszFile, // source file name
IN ULONG ulLine, // source line number
IN LPSPropProblemArray lpProblems) // property problems
{
ULONG i = 0;
DEBUGPUBLIC("DumpPropProblems()\n");
if(lpProblems == NULL)
{
goto cleanup;
}
#ifdef DEBUG
for(i = 0; i < lpProblems->cProblem; i++)
{
_Assert("PROBLEM", lpszFile, ulLine, D_WARNING, 0, "%lu\t%08lx\t%08lx\n",
lpProblems->aProblem[i].ulIndex,
lpProblems->aProblem[i].ulPropTag,
lpProblems->aProblem[i].scode);
}
#endif
cleanup:
return;
}
#ifdef DEBUG
#define DUMPPROPPROBLEMS(_prob) DumpPropProblems(__FILE__,__LINE__,(_prob))
#else
#define DUMPPROPPROBLEMS(_prob) ((void)0)
#endif
//$--HrCreateEnterpriseGDI------------------------------------------------------
// Create the enterprise GDI from the input string.
// -----------------------------------------------------------------------------
HRESULT HrCreateEnterpriseGDI( // RETURNS: return code
IN LPTSTR lpsz, // pointer to input string
IN LPTSTR lpszEOT, // pointer to separator character(s)
OUT LPTSTR *lppszGDI) // pointer to enterprise GDI
{
HRESULT hr = NOERROR;
SCODE sc = 0;
ULONG cBytes = 0;
ULONG cArraySize = 0;
LPTSTR *lppszArray = NULL;
LPTSTR lpszCountry = NULL;
LPTSTR lpszAdmd = NULL;
LPTSTR lpszPrmd = NULL;
ULONG i = 0;
DEBUGPUBLIC("HrCreateEnterpriseGDI()\n");
*lppszGDI = NULL;
hr = HrStrTokAll(
lpsz,
lpszEOT,
&cArraySize,
&lppszArray);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
for(i = 0; i < cArraySize; i++)
{
if(lppszArray[i] == NULL)
{
;
}
else if(!_tcsnicmp(lppszArray[i], C_EQU, lstrlen(C_EQU)))
{
lpszCountry = lppszArray[i];
}
else if(!_tcsnicmp(lppszArray[i], A_EQU, lstrlen(A_EQU)))
{
lpszAdmd = lppszArray[i];
}
else if(!_tcsnicmp(lppszArray[i], P_EQU, lstrlen(P_EQU)))
{
lpszPrmd = lppszArray[i];
}
}
if(lpszCountry == NULL)
{
lpszCountry = TEXT("C=;");
}
if(lpszAdmd == NULL)
{
lpszAdmd = TEXT("A=;");
}
if(lpszPrmd == NULL)
{
lpszPrmd = TEXT("P=;");
}
cBytes = (lstrlen(TEXT(";;;")) +
lstrlen(lpszCountry) +
lstrlen(lpszAdmd) +
lstrlen(lpszPrmd) + 1) * sizeof(TCHAR);
sc = MAPIAllocateBuffer(cBytes, (void **)lppszGDI);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(*lppszGDI, lpszCountry);
lstrcat(*lppszGDI, TEXT(";"));
lstrcat(*lppszGDI, lpszAdmd);
lstrcat(*lppszGDI, TEXT(";"));
lstrcat(*lppszGDI, lpszPrmd);
lstrcat(*lppszGDI, TEXT(";"));
CharUpperBuff(*lppszGDI, cBytes/sizeof(TCHAR));
cleanup:
if(FAILED(hr))
{
MAPIFREEBUFFER(*lppszGDI);
}
MAPIFREEBUFFER(lppszArray);
RETURN(hr);
}
//$--HrGetMtsIdEnterpriseGDI----------------------------------------------------
// Get the enterprise GDI from the MTS-ID (or SUBJECT-MTS-ID).
// -----------------------------------------------------------------------------
HRESULT HrGetMtsIdEnterpriseGDI( // RETURNS: return code
IN LPMESSAGE lpMessage, // pointer to message
IN ULONG ulPropTag, // MTS-ID property tag
OUT LPTSTR *lppszGDI) // pointer to enterprise GDI
{
HRESULT hr = NOERROR;
ULONG cBytes = 0;
LPTSTR lpszMtsId = NULL;
DEBUGPUBLIC("HrGetMtsIdEnterpriseGDI()\n");
*lppszGDI = NULL;
hr = HrMAPIGetPropBinary(
(LPMAPIPROP)lpMessage,
ulPropTag,
&cBytes,
(LPVOID *)&lpszMtsId);
if(FAILED(hr))
{
goto cleanup;
}
hr = HrCreateEnterpriseGDI(
lpszMtsId,
TEXT("/;"),
lppszGDI);
if(FAILED(hr))
{
goto cleanup;
}
cleanup:
if(FAILED(hr))
{
MAPIFREEBUFFER(*lppszGDI);
}
MAPIFREEBUFFER(lpszMtsId);
RETURN(hr);
}
//$--HrGetTraceEnterpriseGDI----------------------------------------------------
// Get the enterprise GDI from the external trace information.
// -----------------------------------------------------------------------------
HRESULT HrGetTraceEnterpriseGDI( // RETURNS: return code
IN LPMESSAGE lpMessage, // pointer to message
IN ULONG ulPropTag, // external trace info property tag
OUT LPTSTR *lppszGDI) // pointer to enterprise GDI
{
HRESULT hr = NOERROR;
SCODE sc = 0;
ULONG cBytes = 0;
LPTRACEINFO lpTraceInfo = NULL;
LPTRACEENTRY lpTraceEntry = NULL;
FILETIME ft = {0};
LPTSTR lpszT = NULL;
LPTSTR lpszCountry = NULL;
LPTSTR lpszAdmd = NULL;
LPTSTR lpszPrmd = NULL;
ULONG i = 0;
DEBUGPUBLIC("HrGetTraceEnterpriseGDI()\n");
*lppszGDI = NULL;
hr = HrMAPIGetPropBinary(
(LPMAPIPROP)lpMessage,
ulPropTag,
&cBytes,
(LPVOID *)&lpTraceInfo);
if(FAILED(hr))
{
goto cleanup;
}
hr = HrTraceGotoFirstEntry(
lpTraceInfo,
&i,
&lpTraceEntry);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrTraceOpenEntry(
lpTraceEntry,
&i,
&ft,
&ft,
&lpszAdmd,
&lpszCountry,
&lpszPrmd,
&lpszT,
&lpszT,
&lpszT);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(lpszCountry == NULL)
{
lpszCountry = TEXT("C=;");
}
if(lpszAdmd == NULL)
{
lpszAdmd = TEXT("A=;");
}
if(lpszPrmd == NULL)
{
lpszPrmd = TEXT("P=;");
}
cBytes = (lstrlen(TEXT("C=;A=;P=;")) +
lstrlen(lpszCountry) +
lstrlen(lpszAdmd) +
lstrlen(lpszPrmd) + 1) * sizeof(TCHAR);
sc = MAPIAllocateBuffer(cBytes, (void **)lppszGDI);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(*lppszGDI, C_EQU);
lstrcat(*lppszGDI, lpszCountry);
lstrcat(*lppszGDI, TEXT(";A="));
lstrcat(*lppszGDI, lpszAdmd);
lstrcat(*lppszGDI, TEXT(";P="));
lstrcat(*lppszGDI, lpszPrmd);
lstrcat(*lppszGDI, TEXT(";"));
CharUpperBuff(*lppszGDI, cBytes/sizeof(TCHAR));
cleanup:
if(FAILED(hr))
{
MAPIFREEBUFFER(*lppszGDI);
}
MAPIFREEBUFFER(lpTraceInfo);
RETURN(hr);
}
//$--HrFixUpRecipientNumbers----------------------------------------------------
// Fix up recipient numbers.
// -----------------------------------------------------------------------------
static HRESULT HrFixUpRecipientNumbers( // RETURNS: return code
IN OUT LPADRLIST lpEnvelopeAdrList, // pointer to envelope address list
IN OUT LPADRLIST lpMessageAdrList) // pointer to message address list
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
SCODE sc = 0;
ULONG cb = 0;
ULONG* rgulOrigRecipNums = NULL;
LPSPropValue lpPropT = NULL;
ULONG i = 0;
ULONG j = 0;
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
DEBUGPRIVATE("HrFixUpRecipientNumbers()\n");
if( (!((lpMessageAdrList == NULL) || (lpMessageAdrList->cEntries == 0))) &&
(!((lpEnvelopeAdrList == NULL) || (lpEnvelopeAdrList->cEntries == 0))))
{
cb = lpMessageAdrList->cEntries * (sizeof(ULONG) + MAX_ALIGN);
sc = MAPIAllocateBuffer(cb, (void **)&rgulOrigRecipNums);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
for(i = 0; i < lpMessageAdrList->cEntries; i++)
{
rgulOrigRecipNums[i] = 0;
cValues = lpMessageAdrList->aEntries[i].cValues;
lpProps = lpMessageAdrList->aEntries[i].rgPropVals;
if(lpProps != NULL)
{
lpPropT = LpValFindProp(PR_RECIPIENT_NUMBER, cValues, lpProps);
if(lpPropT == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
rgulOrigRecipNums[i] = lpPropT->Value.ul;
lpPropT->ulPropTag =
PROP_TAG(PT_ERROR, PROP_ID(lpPropT->ulPropTag));
}
}
for(i = 0; i < lpEnvelopeAdrList->cEntries; i++)
{
cValues = lpEnvelopeAdrList->aEntries[i].cValues;
lpProps = lpEnvelopeAdrList->aEntries[i].rgPropVals;
if(lpProps != NULL)
{
lpPropT = LpValFindProp(PR_RECIPIENT_NUMBER, cValues, lpProps);
if(lpPropT == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
for(j = 0; j < lpMessageAdrList->cEntries; j++)
{
if(rgulOrigRecipNums[j] == lpPropT->Value.ul)
{
lpPropT->Value.ul = j+1;
}
}
}
}
//
// Clear recipient numbers for message address list.
//
hr = HrDeleteAddressListProperty(
PR_RECIPIENT_NUMBER,
(LPADRLIST)lpMessageAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//
// Clear row IDs for envelope address list.
//
if(!((lpEnvelopeAdrList == NULL) || (lpEnvelopeAdrList->cEntries == 0)))
{
hr = HrDeleteAddressListProperty(
PR_ROWID,
(LPADRLIST)lpEnvelopeAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//
// Clear row IDs for message address list.
//
if(!((lpMessageAdrList == NULL) || (lpMessageAdrList->cEntries == 0)))
{
hr = HrDeleteAddressListProperty(
PR_ROWID,
(LPADRLIST)lpMessageAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
cleanup:
MAPIFREEBUFFER(rgulOrigRecipNums);
RETURN(hr);
}
//$--HrDeleteSenderProps--------------------------------------------------------
// Delete sender properties from the message.
// -----------------------------------------------------------------------------
HRESULT HrDeleteSenderProps( // RETURNS: return code
IN LPMESSAGE lpMessage) // pointer to message
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPSPropProblemArray lpProblems = NULL;
SizedSPropTagArray(10, rgPropTags) =
{
10,
{
PR_SENDER_NAME,
PR_SENDER_ADDRTYPE,
PR_SENDER_EMAIL_ADDRESS,
PR_SENDER_SEARCH_KEY,
PR_SENDER_ENTRYID,
PR_SENT_REPRESENTING_NAME,
PR_SENT_REPRESENTING_ADDRTYPE,
PR_SENT_REPRESENTING_EMAIL_ADDRESS,
PR_SENT_REPRESENTING_SEARCH_KEY,
PR_SENT_REPRESENTING_ENTRYID,
}
};
DEBUGPUBLIC("HrDeleteSenderProps()\n");
hrT = MAPICALL(lpMessage)->DeleteProps(
lpMessage,
(SPropTagArray *)&rgPropTags,
&lpProblems);
if(FAILED(hrT))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
cleanup:
MAPIFREEBUFFER(lpProblems);
RETURN(hr);
}
//$--HrDeleteMtsIdProps---------------------------------------------------------
// Delete MTS-ID properties from the message.
// -----------------------------------------------------------------------------
HRESULT HrDeleteMtsIdProps( // RETURNS: return code
IN LPMESSAGE lpMessage) // pointer to message
{
HRESULT hr = NOERROR;
LPSPropProblemArray lpProblems = NULL;
SizedSPropTagArray(1, rgPropTags) =
{
1,
{
PR_MTS_ID,
}
};
DEBUGPUBLIC("HrDeleteMtsIdProps()\n");
hr = MAPICALL(lpMessage)->DeleteProps(
lpMessage,
(SPropTagArray *)&rgPropTags,
&lpProblems);
if(FAILED(hr))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
cleanup:
MAPIFREEBUFFER(lpProblems);
RETURN(hr);
}
//$--HrDeleteTraceProps---------------------------------------------------------
// Delete trace properties from the message.
// -----------------------------------------------------------------------------
HRESULT HrDeleteTraceProps( // RETURNS: return code
IN LPMESSAGE lpMessage) // pointer to message
{
HRESULT hr = NOERROR;
LPSPropProblemArray lpProblems = NULL;
SizedSPropTagArray(1, rgPropTags) =
{
1,
{
PR_TRACE_INFO,
}
};
DEBUGPUBLIC("HrDeleteTraceProps()\n");
hr = MAPICALL(lpMessage)->DeleteProps(
lpMessage,
(SPropTagArray *)&rgPropTags,
&lpProblems);
if(FAILED(hr))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
cleanup:
MAPIFREEBUFFER(lpProblems);
RETURN(hr);
}
//$--HrNonDeliverAllRecipList---------------------------------------------------
// Create a recipient list to non-deliver all recipients.
// -----------------------------------------------------------------------------
HRESULT HrNonDeliverAllRecipList( // RETURNS: return code
IN LPMESSAGE lpMessage, // message
IN LPADRLIST *lppAdrList) // address list
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPSRowSet lpRows = NULL;
LPADRLIST lpAdrList = NULL;
LPADRLIST lpAllAdrList = NULL;
LPMAPITABLE lpTable = NULL;
LPSPropValue lpPropT = NULL;
ULONG cFailedValues = 0;
LPSPropValue lpFailedProps = NULL;
ULONG i = 0;
DEBUGPUBLIC("HrNonDeliverAllRecipList()");
*lppAdrList = NULL;
//
// Get the recipient table for the message
//
hr = MAPICALL(lpMessage)->GetRecipientTable(
lpMessage,
MAPI_DEFERRED_ERRORS,
&lpTable);
if(FAILED(hr))
{
goto cleanup;
}
//
// Query all the rows
//
hr = HrQueryAllRows(
lpTable,
NULL,
NULL,
NULL,
0,
&lpRows);
if(FAILED(hr))
{
goto cleanup;
}
lpAdrList = (LPADRLIST)lpRows;
hr = HrNDRCreateFailedRecipList(
&lpAllAdrList);
if(FAILED(hr))
{
goto cleanup;
}
for(i = 0; i < lpAdrList->cEntries; i++)
{
hr = HrNDRGetFailedRecipList(
&lpAdrList->aEntries[i],
0,
NULL,
&cFailedValues,
&lpFailedProps);
if(FAILED(hr))
{
goto cleanup;
}
lpPropT = LpValFindProp(PR_RECIPIENT_NUMBER, cFailedValues, lpFailedProps);
if(lpPropT != NULL)
{
lpPropT->Value.ul = (i+1);
}
hr = HrNDRAddToFailedRecipList(
cFailedValues,
lpFailedProps,
&lpAllAdrList);
if(FAILED(hr))
{
goto cleanup;
}
MAPIFREEBUFFER(lpFailedProps);
} // end for
*lppAdrList = lpAllAdrList;
lpAllAdrList = NULL;
cleanup:
MAPIFREEBUFFER(lpFailedProps);
FREEPADRLIST(lpAdrList); // also frees lpRows
FREEPADRLIST(lpAllAdrList);
ULRELEASE(lpTable);
if(FAILED(hr))
{
FREEPADRLIST(lpAllAdrList);
*lppAdrList = NULL;
}
RETURN(hr);
}
//$--HrCreateNonDeliveryReport--------------------------------------------------
// Create a non-delivery report.
// -----------------------------------------------------------------------------
HRESULT HrCreateNonDeliveryReport( // RETURNS: return code
IN BOOL fCreateMtsId, // create MTS identifier
IN LPADRBOOK lpAdrBook, // pointer to address book
IN LPMAPIFOLDER lpFolder, // pointer to folder
IN LPMESSAGE lpMessage, // pointer to message
IN LPADRLIST lpAdrList, // pointer to address list
OUT LPMESSAGE *lppReport) // pointer to report
{
HRESULT hr = NOERROR;
LPMESSAGE lpReport = NULL;
ULONG cBytes = 0;
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
LPTSTR lpszEmailDisplayName = NULL;
LPTSTR lpszEmailAddressType = NULL;
LPTSTR lpszEmailAddress = NULL;
LPTSTR lpszEmailSearchKey = NULL;
ULONG cbEmailEid = 0;
LPENTRYID lpEmailEid = NULL;
LPSPropProblemArray lpProblems = NULL;
CHAR szGatewayName[MAX_SERVICE_NAME_LENGTH+1] = {0};
ULONG ulMtsIdSeqNo = 0;
CHAR rgchMTSID[cbMTSIDMax] = {0};
DEBUGPUBLIC("HrCreateNonDeliveryReport()\n");
*lppReport = NULL;
if(fCreateMtsId == TRUE)
{
EnterCriticalSection(&csGatewaySeqNo);
ulMtsIdSeqNo = ++ulGatewaySeqNo;
LeaveCriticalSection(&csGatewaySeqNo);
//
// Get gateway service name.
//
hr = HrServiceGetName(
szGatewayName);
if(FAILED(hr))
{
goto cleanup;
}
hr = HrCreateMtsId(
lpszLocalGDI,
szGatewayName,
ulMtsIdSeqNo,
rgchMTSID);
if(FAILED(hr))
{
goto cleanup;
}
}
hr = HrNDRGetFailedProps(
lpMessage,
&cValues,
&lpProps);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrNDRCreate(
lpAdrBook,
lpFolder,
lpMessage,
lpAdrList,
cValues,
lpProps,
&lpReport);
MAPIFREEBUFFER(lpProps);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cBytes = CbNewSPropValue(6);
hr = MAPIAllocateBuffer(cBytes, (void **)&lpProps);
if(FAILED(hr))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
ZeroMemory(lpProps, cBytes);
hr = HrCreateProxyAddress(
lpAdrBook,
lpProps,
TRUE,
SYSTEM_ADMINISTRATOR,
SYSTEM,
SYSTEM_ADMINISTRATOR,
&lpszEmailDisplayName,
&lpszEmailAddressType,
&lpszEmailAddress,
&lpszEmailSearchKey,
&cbEmailEid,
&lpEmailEid);
if(FAILED(hr))
{
goto cleanup;
}
lpProps[0].ulPropTag = PR_SENDER_NAME;
lpProps[0].Value.LPSZ = lpszEmailDisplayName;
lpProps[1].ulPropTag = PR_SENDER_ADDRTYPE;
lpProps[1].Value.LPSZ = lpszEmailAddressType;
lpProps[2].ulPropTag = PR_SENDER_EMAIL_ADDRESS;
lpProps[2].Value.LPSZ = lpszEmailAddress;
lpProps[3].ulPropTag = PR_SENDER_SEARCH_KEY;
if(lpszEmailSearchKey == NULL)
{
lpProps[3].Value.bin.cb = 0;
lpProps[3].Value.bin.lpb = NULL;
}
else
{
lpProps[3].Value.bin.cb = cbStrLen(lpszEmailSearchKey);
lpProps[3].Value.bin.lpb = lpszEmailSearchKey;
}
lpProps[4].ulPropTag = PR_SENDER_ENTRYID;
lpProps[4].Value.bin.cb = cbEmailEid;
lpProps[4].Value.bin.lpb = (LPBYTE)lpEmailEid;
lpProps[5].ulPropTag = PR_MTS_ID;
lpProps[5].Value.bin.cb = cbStrLen(rgchMTSID);
lpProps[5].Value.bin.lpb = (LPBYTE)rgchMTSID;
if(fCreateMtsId == TRUE)
{
cValues = 6;
}
else
{
cValues = 5;
}
hr = MAPICALL(lpReport)->SetProps(
lpReport,
cValues,
lpProps,
&lpProblems);
if(FAILED(hr))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
MAPIFREEBUFFER(lpProblems);
// Save changes just made to report envelope
hr = MAPICALL(lpReport)->SaveChanges(
lpReport,
KEEP_OPEN_READWRITE);
if ( FAILED(hr) )
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
*lppReport = lpReport;
cleanup:
MAPIFREEBUFFER(lpProps);
MAPIFREEBUFFER(lpProblems);
RETURN(hr);
}
//$--HrImportMessage------------------------------------------------------------
// Process an IPM/IPN in MTS-IN.
// -----------------------------------------------------------------------------
HRESULT HrImportMessage( // RETURNS: return code
IN LPADRBOOK lpAdrBook, // pointer to address book
IN LPABCONT lpGalABCont, // pointer to GAL
IN BOOL fIgnoreRespValue, // ignore responsibility value
IN BOOL fSendNDR, // TRUE if NDRs should be generated
IN DWORD dwStartProcessingTime, // start processing time
IN OUT LPMESSAGE lpEnvelope) // pointer to envelope
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPMESSAGE lpMessage = NULL;
LPATTACH lpAttach = NULL;
ULONG cEnvelopeValues = 0;
LPSPropValue lpEnvelopeProps = NULL;
ULONG cMessageValues = 0;
LPSPropValue lpMessageProps = NULL;
LPADRLIST lpOriginalEnvelopeAdrList = NULL;
LPADRLIST lpOriginalMessageAdrList = NULL;
LPADRLIST lpEnvelopeAdrList = NULL;
LPADRLIST lpMessageAdrList = NULL;
LPADRLIST lpEnvelope_NDR_AdrList = NULL;
LPADRLIST lpMessage_NDR_AdrList = NULL;
DWORD dwEndProcessingTime = 0;
DWORD dwTotalProcessingTime = 0;
DWORD dwSleepProcessingTime = 0;
ULONG cEnvelopeMesgAddr = 0;
ULONG cEnvelopeReplyAddr = 0;
ULONG cEnvelopeRecipAddr = 0;
LPADRLIST lpEnvelopeAllAdrList = NULL;
LPADRLIST lpMappedEnvelopeAdrList = NULL;
ULONG cMessageMesgAddr = 0;
ULONG cMessageReplyAddr = 0;
ULONG cMessageRecipAddr = 0;
LPADRLIST lpMessageAllAdrList = NULL;
LPADRLIST lpMappedMessageAdrList = NULL;
BOOL HasContent = TRUE;
LPSPropProblemArray lpProblems = NULL;
DEBUGPUBLIC("HrImportMessage()\n");
// Get the attachment in the envelope
hrT = MAPICALL(lpEnvelope)->OpenAttach(
lpEnvelope,
0,
NULL,
MAPI_MODIFY,
&lpAttach);
if((FAILED(hrT)) && (hrT != MAPI_E_NOT_FOUND))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(hrT == MAPI_E_NOT_FOUND)
{
//
// Message does not have an attachment.
//
HasContent = FALSE;
lpAttach = NULL;
}
if(HasContent == TRUE)
{
// Open a message interface on the attachment
hrT = MAPICALL(lpAttach)->OpenProperty(
lpAttach,
PR_ATTACH_DATA_OBJ,
(LPIID)&IID_IMessage,
0,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
(LPUNKNOWN *)&lpMessage);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//------------------------------------------------------------------------------
//
// Map envelope addresses
//
hr = HrExpandMessageAddressList(
lpEnvelope,
&cEnvelopeMesgAddr,
&cEnvelopeReplyAddr,
&cEnvelopeRecipAddr,
&lpOriginalEnvelopeAdrList,
&lpEnvelopeAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapAddrToProxy(
lpAdrBook,
lpszAddressType,
lpEnvelopeAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapGatewayProxyToAddr(
lpAdrBook,
lpszAddressType,
lpEnvelopeAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapProxyToAddr(
lpAdrBook,
lpGalABCont,
lpEnvelopeAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrCollapseMessageAddressList(
lpEnvelope,
cEnvelopeMesgAddr,
cEnvelopeReplyAddr,
cEnvelopeRecipAddr,
lpEnvelopeAllAdrList,
&cEnvelopeValues,
&lpEnvelopeProps,
&lpMappedEnvelopeAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
FREEPADRLIST(lpEnvelopeAllAdrList);
//
// TNEF encode is setting the value of PR_RESPONSIBILITY to FALSE
// for each recipient entry.
//
{
ULONG i = 0;
LPSPropValue lpPropT = NULL;
for(i = 0; i < lpOriginalEnvelopeAdrList->cEntries; i++)
{
lpPropT = LpValFindProp(
PR_RESPONSIBILITY,
lpOriginalEnvelopeAdrList->aEntries[i].cValues,
lpOriginalEnvelopeAdrList->aEntries[i].rgPropVals);
if(lpPropT != NULL)
{
lpPropT->Value.b = TRUE;
}
}
for(i = 0; i < lpMappedEnvelopeAdrList->cEntries; i++)
{
lpPropT = LpValFindProp(
PR_RESPONSIBILITY,
lpMappedEnvelopeAdrList->aEntries[i].cValues,
lpMappedEnvelopeAdrList->aEntries[i].rgPropVals);
if(lpPropT != NULL)
{
lpPropT->Value.b = TRUE;
}
}
}
if(HasContent == TRUE)
{
//
// Map message addresses
//
hr = HrExpandMessageAddressList(
lpMessage,
&cMessageMesgAddr,
&cMessageReplyAddr,
&cMessageRecipAddr,
&lpOriginalMessageAdrList,
&lpMessageAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapAddrToProxy(
lpAdrBook,
lpszAddressType,
lpMessageAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapGatewayProxyToAddr(
lpAdrBook,
lpszAddressType,
lpMessageAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapProxyToAddr(
lpAdrBook,
lpGalABCont,
lpMessageAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrCollapseMessageAddressList(
lpMessage,
cMessageMesgAddr,
cMessageReplyAddr,
cMessageRecipAddr,
lpMessageAllAdrList,
&cMessageValues,
&lpMessageProps,
&lpMappedMessageAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
FREEPADRLIST(lpMessageAllAdrList);
}
//------------------------------------------------------------------------------
hr = HrMapRecipProxyToAddr(
lpAdrBook,
TRUE,
fIgnoreRespValue,
lpGalABCont,
lpszAddressType,
lpOriginalEnvelopeAdrList,
lpMappedEnvelopeAdrList,
NULL,
NULL,
lpEnvelope,
&lpEnvelopeAdrList,
&lpEnvelope_NDR_AdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(HasContent == TRUE)
{
hr = HrMapRecipProxyToAddr(
lpAdrBook,
FALSE,
fIgnoreRespValue,
lpGalABCont,
lpszAddressType,
lpOriginalMessageAdrList,
lpMappedMessageAdrList,
lpEnvelopeAdrList,
lpEnvelope_NDR_AdrList,
lpMessage,
&lpMessageAdrList,
&lpMessage_NDR_AdrList);
FREEPADRLIST(lpOriginalMessageAdrList);
FREEPADRLIST(lpMessage_NDR_AdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
// Non-deliver any recipients that could not be mapped.
if((lpEnvelope_NDR_AdrList != NULL) &&
(lpEnvelope_NDR_AdrList->cEntries != 0) &&
(fSendNDR == TRUE))
{
LPMESSAGE lpReportEnvelope = NULL;
//
// Clear row IDs for envelope NDR address list.
//
hr = HrDeleteAddressListProperty(
PR_ROWID,
(LPADRLIST)lpEnvelope_NDR_AdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Create a non delivery report in MTS-OUT
//
hr = HrCreateNonDeliveryReport(
TRUE,
lpAdrBook,
lpMtsOutFolder,
lpMessage,
lpEnvelope_NDR_AdrList,
&lpReportEnvelope);
if(FAILED(hr))
{
;
}
else
{
HANDLE hNewMailEvent = GetGWNewMailEvent();
if((hNewMailEvent != NULL) && (!SetEvent(hNewMailEvent)))
{
hr = HR_LOG(E_FAIL);
}
}
ULRELEASE(lpReportEnvelope);
}
FREEPADRLIST(lpEnvelope_NDR_AdrList);
if((lpEnvelopeAdrList == NULL) || (lpEnvelopeAdrList->cEntries == 0))
{
FREEPADRLIST(lpEnvelopeAdrList);
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(HasContent == TRUE)
{
if((lpMessageAdrList == NULL) || (lpMessageAdrList->cEntries == 0))
{
FREEPADRLIST(lpMessageAdrList);
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//------------------------------------------------------------------------------
// Fix up recipient numbers
hr = HrFixUpRecipientNumbers(lpEnvelopeAdrList, lpMessageAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
hrT = MAPICALL(lpEnvelope)->SetProps(
lpEnvelope,
cEnvelopeValues,
lpEnvelopeProps,
&lpProblems);
if(FAILED(hrT))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
MAPIFREEBUFFER(lpProblems);
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpEnvelope,
PR_DELETE_AFTER_SUBMIT,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(HasContent == TRUE)
{
hrT = MAPICALL(lpMessage)->SetProps(
lpMessage,
cMessageValues,
lpMessageProps,
&lpProblems);
if(FAILED(hrT))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
MAPIFREEBUFFER(lpProblems);
}
//------------------------------------------------------------------------------
// Set envelope recipients
hrT = MAPICALL(lpEnvelope)->ModifyRecipients(
lpEnvelope,
0,
lpEnvelopeAdrList);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(HasContent == TRUE)
{
// Set message recipients
hrT = MAPICALL(lpMessage)->ModifyRecipients(
lpMessage,
0,
lpMessageAdrList);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//------------------------------------------------------------------------------
if(HasContent == TRUE)
{
// Save changes to the message
hrT = MAPICALL(lpMessage)->SaveChanges(
lpMessage,
MAPI_DEFERRED_ERRORS|KEEP_OPEN_READWRITE);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Save changes to attachment object
hrT = MAPICALL(lpAttach)->SaveChanges(
lpAttach,
MAPI_DEFERRED_ERRORS|KEEP_OPEN_READWRITE);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
ULRELEASE(lpMessage);
ULRELEASE(lpAttach);
}
//----------------------------------------------------------------------
dwEndProcessingTime = GetTickCount();
dwTotalProcessingTime = dwEndProcessingTime - dwStartProcessingTime;
dwSleepProcessingTime =
((dwTotalProcessingTime < dwInSleepInterval) ?
(dwInSleepInterval - dwTotalProcessingTime) : 0);
if(dwSleepProcessingTime > 0)
{
Sleep(dwSleepProcessingTime);
}
//----------------------------------------------------------------------
// Submit message
hrT = MAPICALL(lpEnvelope)->SubmitMessage(lpEnvelope, FORCE_SUBMIT);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cleanup:
MAPIFREEBUFFER(lpProblems);
FREEPADRLIST(lpEnvelopeAdrList);
FREEPADRLIST(lpMessageAdrList);
FREEPADRLIST(lpEnvelope_NDR_AdrList);
FREEPADRLIST(lpMessage_NDR_AdrList);
FREEPADRLIST(lpOriginalEnvelopeAdrList);
FREEPADRLIST(lpOriginalMessageAdrList);
FREEPADRLIST(lpEnvelopeAllAdrList);
FREEPADRLIST(lpMessageAllAdrList);
FREEPADRLIST(lpMappedEnvelopeAdrList);
FREEPADRLIST(lpMappedMessageAdrList);
MAPIFREEBUFFER(lpEnvelopeProps);
MAPIFREEBUFFER(lpMessageProps);
ULRELEASE(lpMessage);
ULRELEASE(lpAttach);
RETURN(hr);
}
//$--HrCheckExternalTraceInformation--------------------------------------------
// Process messages in MTS-IN.
// -----------------------------------------------------------------------------
HRESULT HrCheckExternalTraceInformation( // RETURNS: return code
IN LPMESSAGE lpEnvelope) // pointer to envelope
{
HRESULT hr = NOERROR;
LPTSTR lpszMtsIdGDI = NULL;
LPTSTR lpszTraceGDI = NULL;
DEBUGPUBLIC("HrCheckExternalTraceInformation()\n");
hr = HrGetMtsIdEnterpriseGDI(
lpEnvelope,
PR_MTS_ID,
&lpszMtsIdGDI);
if((FAILED(hr)) && (hr != MAPI_E_NOT_FOUND))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrGetTraceEnterpriseGDI(
lpEnvelope,
PR_TRACE_INFO,
&lpszTraceGDI);
if((FAILED(hr)) && (hr != MAPI_E_NOT_FOUND))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if((lpszMtsIdGDI == NULL) && (lpszTraceGDI == NULL))
{
// consistent
}
else if((lpszMtsIdGDI == NULL) || (lpszTraceGDI == NULL))
{
// warning
MODULE_ERROR("**** Inconsistent external trace ****");
if((lpszTraceGDI != NULL) &&
(lstrcmpi(lpszTraceGDI, lpszLocalGDI) == 0))
{
// delete MTS-ID
hr = HrDeleteMtsIdProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else if((lpszMtsIdGDI != NULL) &&
(lstrcmpi(lpszMtsIdGDI, lpszLocalGDI) == 0))
{
// delete trace
hr = HrDeleteTraceProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else
{
// delete trace
hr = HrDeleteTraceProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// delete MTS-ID
hr = HrDeleteMtsIdProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
}
else
{
if(lstrcmpi(lpszMtsIdGDI, lpszTraceGDI) != 0)
{
// warning
MODULE_ERROR("**** Inconsistent external trace ****");
if(lstrcmpi(lpszTraceGDI, lpszLocalGDI) == 0)
{
// delete MTS-ID
hr = HrDeleteMtsIdProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else if(lstrcmpi(lpszMtsIdGDI, lpszLocalGDI) == 0)
{
// delete trace
hr = HrDeleteTraceProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else
{
// delete trace
hr = HrDeleteTraceProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// delete MTS-ID
hr = HrDeleteMtsIdProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
}
else
{
// consistent
}
}
cleanup:
hr = NOERROR;
MAPIFREEBUFFER(lpszMtsIdGDI);
MAPIFREEBUFFER(lpszTraceGDI);
RETURN(hr);
}
//$--HrNonDeliverMtsInMessage---------------------------------------------------
// Non-deliver a message in MTS-IN.
// -----------------------------------------------------------------------------
HRESULT HrNonDeliverMtsInMessage( // RETURNS: zero
IN LPTSTR lpszMessageClass, // message class
IN LPMESSAGE lpEnvelope) // envelope
{
HRESULT hr = NOERROR;
LPADRBOOK lpAdrBook = NULL;
LPMESSAGE lpMessage = NULL;
LPMESSAGE lpSubjectMessage = NULL;
LPMESSAGE lpReportEnvelope = NULL;
LPADRLIST lpReportAdrList = NULL;
LPATTACH lpAttach = NULL;
BOOL HasContent = TRUE;
DEBUGPUBLIC("HrNonDeliverMtsInMessage()\n");
lpAdrBook = GetAdrBookPtr();
MODULE_ERROR1(
"**** [IN ] Unknown message class [%s] ****",
((lpszMessageClass == NULL) ? "(null)" : lpszMessageClass));
hr = HrNonDeliverAllRecipList(
lpEnvelope,
&lpReportAdrList);
if(FAILED(hr))
{
goto cleanup;
}
// Get the attachment in the envelope
hr = MAPICALL(lpEnvelope)->OpenAttach(
lpEnvelope,
0,
NULL,
MAPI_MODIFY,
&lpAttach);
if((FAILED(hr)) && (hr != MAPI_E_NOT_FOUND))
{
goto cleanup;
}
if(hr == MAPI_E_NOT_FOUND)
{
//
// Message does not have an attachment.
//
HasContent = FALSE;
lpAttach = NULL;
}
lpSubjectMessage = NULL;
if(HasContent == TRUE)
{
// Open a message interface on the attachment
hr = MAPICALL(lpAttach)->OpenProperty(
lpAttach,
PR_ATTACH_DATA_OBJ,
(LPIID)&IID_IMessage,
0,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
(LPUNKNOWN *)&lpMessage);
if(FAILED(hr))
{
goto cleanup;
}
lpSubjectMessage = lpMessage;
}
else
{
lpSubjectMessage = lpEnvelope;
}
//
// Create a non delivery report in MTS-OUT
//
if(lpSubjectMessage != NULL)
{
hr = HrCreateNonDeliveryReport(
TRUE,
lpAdrBook,
lpMtsOutFolder,
lpSubjectMessage,
lpReportAdrList,
&lpReportEnvelope);
if(FAILED(hr))
{
;
}
else
{
HANDLE hNewMailEvent = GetGWNewMailEvent();
if((hNewMailEvent != NULL) && (!SetEvent(hNewMailEvent)))
{
hr = HR_LOG(E_FAIL);
}
}
}
cleanup:
ULRELEASE(lpReportEnvelope);
ULRELEASE(lpMessage);
FREEPADRLIST(lpReportAdrList);
RETURN(hr);
}
//$--ProcessMtsIn---------------------------------------------------------------
// Process messages in MTS-IN.
// -----------------------------------------------------------------------------
DWORD ProcessMtsIn( // RETURNS: zero
IN LPVOID lpParameter) // parameter
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
ULONG i = 0;
ULONG cRows = 0;
LPMESSAGE lpEnvelope = NULL;
ULONG cbMessageClass = 0;
LPTSTR lpszMessageClass = NULL;
LPSTREAM lpStream = NULL;
TCHAR rgchFileName[MAX_PATH+1] = {0};
DWORD dwStartProcessingTime = 0;
LPADRBOOK lpAdrBook = NULL;
LPABCONT lpGalABCont = NULL;
ULONG ulObjType = 0;
SPropTagArray sptExcludeNone = {0};
LPSTnefProblemArray lptpa = NULL;
LPWIN32_FIND_DATA rgFindData = NULL;
LPWIN32_FIND_DATA lpFindData = NULL;
EDKCNVRES crRes = GCR_OK;
//
// Declare an environment for the conversion.
//
EDKCNVENV envTmp =
{
1,
lpszInConverterW,
(LHANDLE)NULL,
NULL,
NULL,
NULL
};
CONV_OPTIONS sConvOptions =
{
FALSE, // attach TNEF encapsulation
NULL // address type
};
const LPCWSTR pszMessageClassW = L"ENVELOPE.IPM";
PVOID pvConvInstance = NULL;
LPIDITEM lpIdItem = NULL;
DEBUGPUBLIC("ProcessMtsIn()\n");
//performance code
// Initialize conversion engine instance data.
hr = HrConvInitInstance(hEventLog, &pvConvInstance);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cRows = GetGWFindDataSize(lpParameter);
rgFindData = GetGWFindData(lpParameter);
lpAdrBook = GetAdrBookPtr();
lpGalABCont = GetGWGAL();
for(i = 0; i < cRows; i++)
{
dwStartProcessingTime = GetTickCount();
//------------------------------------------------------------------------------
// Build file name of incoming message
lpFindData = &rgFindData[i];
lstrcpy(rgchFileName, lpszInDirectory);
lstrcat(rgchFileName, lpFindData->cFileName);
//------------------------------------------------------------------------------
// Adding file to the "being processed" list!
// Prevents another thread from processing this file.
hr = HrAddIdItem(&InboundIdList, rgchFileName, &lpIdItem);
if(hr == EDK_E_ALREADY_EXISTS)
{
//
// Don't process this message. It is already being processed
// by another thread.
//
continue;
}
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
// Open a buffered stream on the input file.
hrT = OpenStreamOnFile(
MAPIAllocateBuffer,
MAPIFreeBuffer,
STGM_READ | STGM_SHARE_EXCLUSIVE,// stream interface flags
rgchFileName,
NULL,
&lpStream);
if(FAILED(hrT))
{
// Temporarily can't access this file.
// We MUST remove it from the being processed list, since
// this thread added it, but now can't continue to process it.
goto SKIP;
}
lpEnvelope = NULL;
hrT = MAPICALL(lpMtsInFolder)->CreateMessage(
lpMtsInFolder,
NULL,
MAPI_DEFERRED_ERRORS,
&lpEnvelope);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
// Initialize the conversion environment structure
sConvOptions.lpszAddressType = lpszAddressType;
envTmp.lphSession = (LHANDLE)lpSession;
envTmp.lpAB = lpAdrBook;
envTmp.pGatewayDefined = &sConvOptions;
//
// 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)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
// Get the message class
MAPIFREEBUFFER(lpszMessageClass);
cbMessageClass = 0;
lpszMessageClass = NULL;
hr = HrMAPIGetPropString(
(LPMAPIPROP)lpEnvelope,
PR_MESSAGE_CLASS,
&cbMessageClass,
(void **)&lpszMessageClass);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
MODULE_WARNING1(
"**** [IN ] Processing message of class [%s] ****",
((lpszMessageClass == NULL) ? "(null)" : lpszMessageClass));
//
// Check for inconsistencies in MTS-ID & external trace information.
//
hr = HrCheckExternalTraceInformation(lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Process the message
if(_tcsstr(lpszMessageClass, TEXT("ENVELOPE.IPM")) != NULL)
{
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpEnvelope,
PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpEnvelope,
PR_NON_RECEIPT_NOTIFICATION_REQUESTED,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrImportMessage(
lpAdrBook,
lpGalABCont,
FALSE,
TRUE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".NDR")) != NULL))
{
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpEnvelope,
PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrDeleteSenderProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrImportMessage(
lpAdrBook,
lpGalABCont,
TRUE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".DR")) != NULL))
{
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpEnvelope,
PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrDeleteSenderProps(
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrImportMessage(
lpAdrBook,
lpGalABCont,
TRUE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".IPNNRN")) != NULL))
{
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpEnvelope,
PR_NON_RECEIPT_NOTIFICATION_REQUESTED,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrImportMessage(
lpAdrBook,
lpGalABCont,
FALSE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".IPNRN")) != NULL))
{
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpEnvelope,
PR_READ_RECEIPT_REQUESTED,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrImportMessage(
lpAdrBook,
lpGalABCont,
FALSE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else
{
hr = HrNonDeliverMtsInMessage(
lpszMessageClass,
lpEnvelope);
if(FAILED(hr))
{
; // failed to non-deliver message
}
}
if(FAILED(hr))
{
MODULE_ERROR1(
"**** [IN ] Error while processing message of class [%s] ****",
((lpszMessageClass == NULL) ? "(null)" : lpszMessageClass));
//
// This message will be moved to the archive directory.
//
ULRELEASE(lpStream);
MAPIFREEBUFFER(lpszMessageClass);
ULRELEASE(lpEnvelope);
continue;
}
ULRELEASE(lpStream);
MAPIFREEBUFFER(lpszMessageClass);
ULRELEASE(lpEnvelope);
//performance code
if(!DeleteFile(rgchFileName))
{
hr = HR_LOG(E_FAIL);
}
//------------------------------------------------------------------------------
SKIP: // can't process this file now, so remove it from the "being processed" list.
hr = HrRemoveIdItem(&InboundIdList, lpIdItem);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
}
cleanup:
ULRELEASE(lpStream);
MAPIFREEBUFFER(lpszMessageClass);
ULRELEASE(lpEnvelope);
if(pvConvInstance != NULL)
{
// De-initialize conversion engine instance data.
(VOID)HrConvUninitInstance(pvConvInstance);
pvConvInstance = NULL;
}
return(0);
}
//$--HrExportMessage------------------------------------------------------------
// Process an IPM/IPN in MTS-OUT.
// -----------------------------------------------------------------------------
HRESULT HrExportMessage( // RETURNS: return code
IN LPADRBOOK lpAdrBook, // pointer to address book
IN BOOL fIgnoreRespValue, // ignore responsibility value
IN BOOL fSendNDR, // TRUE if NDRs should be generated
IN DWORD dwStartProcessingTime, // start processing time
IN OUT LPMESSAGE lpEnvelope) // pointer to envelope
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPMESSAGE lpMessage = NULL;
LPATTACH lpAttach = NULL;
ULONG cEnvelopeValues = 0;
LPSPropValue lpEnvelopeProps = NULL;
ULONG cMessageValues = 0;
LPSPropValue lpMessageProps = NULL;
LPADRLIST lpOriginalEnvelopeAdrList = NULL;
LPADRLIST lpOriginalMessageAdrList = NULL;
LPADRLIST lpEnvelopeAdrList = NULL;
LPADRLIST lpMessageAdrList = NULL;
LPADRLIST lpEnvelope_NDR_AdrList = NULL;
LPADRLIST lpMessage_NDR_AdrList = NULL;
DWORD dwEndProcessingTime = 0;
DWORD dwTotalProcessingTime = 0;
DWORD dwSleepProcessingTime = 0;
ULONG cbeid = 0;
LPENTRYID lpeid = NULL;
ULONG cEnvelopeMesgAddr = 0;
ULONG cEnvelopeReplyAddr = 0;
ULONG cEnvelopeRecipAddr = 0;
LPADRLIST lpEnvelopeAllAdrList = NULL;
LPADRLIST lpMappedEnvelopeAdrList = NULL;
ULONG cMessageMesgAddr = 0;
ULONG cMessageReplyAddr = 0;
ULONG cMessageRecipAddr = 0;
LPADRLIST lpMessageAllAdrList = NULL;
LPADRLIST lpMappedMessageAdrList = NULL;
BOOL HasContent = TRUE;
LPSPropProblemArray lpProblems = NULL;
DEBUGPUBLIC("HrExportMessage()\n");
// Get the attachment in the envelope
hrT = MAPICALL(lpEnvelope)->OpenAttach(
lpEnvelope,
0,
NULL,
MAPI_MODIFY,
&lpAttach);
if((FAILED(hrT)) && (hrT != MAPI_E_NOT_FOUND))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(hrT == MAPI_E_NOT_FOUND)
{
//
// Message does not have an attachment.
//
HasContent = FALSE;
lpAttach = NULL;
}
if(HasContent == TRUE)
{
// Open a message interface on the attachment
hrT = MAPICALL(lpAttach)->OpenProperty(
lpAttach,
PR_ATTACH_DATA_OBJ,
(LPIID)&IID_IMessage,
0,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
(LPUNKNOWN *)&lpMessage);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//------------------------------------------------------------------------------
//
// Map envelope addresses
//
hr = HrExpandMessageAddressList(
lpEnvelope,
&cEnvelopeMesgAddr,
&cEnvelopeReplyAddr,
&cEnvelopeRecipAddr,
&lpOriginalEnvelopeAdrList,
&lpEnvelopeAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapAddrToProxy(
lpAdrBook,
lpszAddressType,
lpEnvelopeAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapGatewayAddrToProxy(
lpAdrBook,
lpszAddressType,
lpEnvelopeAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrCollapseMessageAddressList(
lpEnvelope,
cEnvelopeMesgAddr,
cEnvelopeReplyAddr,
cEnvelopeRecipAddr,
lpEnvelopeAllAdrList,
&cEnvelopeValues,
&lpEnvelopeProps,
&lpMappedEnvelopeAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
FREEPADRLIST(lpEnvelopeAllAdrList);
if(HasContent == TRUE)
{
//
// Map message addresses
//
hr = HrExpandMessageAddressList(
lpMessage,
&cMessageMesgAddr,
&cMessageReplyAddr,
&cMessageRecipAddr,
&lpOriginalMessageAdrList,
&lpMessageAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapAddrToProxy(
lpAdrBook,
lpszAddressType,
lpMessageAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMapGatewayAddrToProxy(
lpAdrBook,
lpszAddressType,
lpMessageAllAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrCollapseMessageAddressList(
lpMessage,
cMessageMesgAddr,
cMessageReplyAddr,
cMessageRecipAddr,
lpMessageAllAdrList,
&cMessageValues,
&lpMessageProps,
&lpMappedMessageAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
FREEPADRLIST(lpMessageAllAdrList);
}
//------------------------------------------------------------------------------
hr = HrMapRecipAddrToProxy(
lpAdrBook,
TRUE,
fIgnoreRespValue,
lpszAddressType,
NULL,
lpOriginalEnvelopeAdrList,
lpMappedEnvelopeAdrList,
NULL,
NULL,
lpEnvelope,
&lpEnvelopeAdrList,
&lpEnvelope_NDR_AdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(HasContent == TRUE)
{
hr = HrMapRecipAddrToProxy(
lpAdrBook,
FALSE,
fIgnoreRespValue,
lpszAddressType,
lpOriginalEnvelopeAdrList,
lpOriginalMessageAdrList,
lpMappedMessageAdrList,
lpEnvelopeAdrList,
lpEnvelope_NDR_AdrList,
lpMessage,
&lpMessageAdrList,
&lpMessage_NDR_AdrList);
FREEPADRLIST(lpOriginalEnvelopeAdrList);
FREEPADRLIST(lpOriginalMessageAdrList);
FREEPADRLIST(lpMessage_NDR_AdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
// Non-deliver any recipients that could not be mapped.
if((lpEnvelope_NDR_AdrList != NULL) &&
(lpEnvelope_NDR_AdrList->cEntries != 0) &&
(fSendNDR == TRUE))
{
LPMESSAGE lpReportEnvelope = NULL;
//
// Clear row IDs for envelope NDR address list.
//
hr = HrDeleteAddressListProperty(
PR_ROWID,
(LPADRLIST)lpEnvelope_NDR_AdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Create a non delivery report in MTS-IN
//
hr = HrCreateNonDeliveryReport(
FALSE,
lpAdrBook,
lpMtsInFolder,
lpMessage,
lpEnvelope_NDR_AdrList,
&lpReportEnvelope);
if(FAILED(hr))
{
goto cleanup;
}
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpReportEnvelope,
PR_DELETE_AFTER_SUBMIT,
TRUE);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
ULRELEASE(lpReportEnvelope);
goto cleanup;
}
// Submit message
hrT = MAPICALL(lpReportEnvelope)->SubmitMessage(lpReportEnvelope, FORCE_SUBMIT);
if(FAILED(hrT))
{
hrT = HR_LOG(hrT);
}
ULRELEASE(lpReportEnvelope);
}
FREEPADRLIST(lpEnvelope_NDR_AdrList);
if((lpEnvelopeAdrList == NULL) || (lpEnvelopeAdrList->cEntries == 0))
{
FREEPADRLIST(lpEnvelopeAdrList);
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(HasContent == TRUE)
{
if((lpMessageAdrList == NULL) || (lpMessageAdrList->cEntries == 0))
{
FREEPADRLIST(lpMessageAdrList);
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//------------------------------------------------------------------------------
// Fix up recipient numbers
hr = HrFixUpRecipientNumbers(lpEnvelopeAdrList, lpMessageAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
hrT = MAPICALL(lpEnvelope)->SetProps(
lpEnvelope,
cEnvelopeValues,
lpEnvelopeProps,
&lpProblems);
if(FAILED(hrT))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
MAPIFREEBUFFER(lpProblems);
if(HasContent == TRUE)
{
hrT = MAPICALL(lpMessage)->SetProps(
lpMessage,
cMessageValues,
lpMessageProps,
&lpProblems);
if(FAILED(hrT))
{
lpProblems = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
DUMPPROPPROBLEMS(lpProblems);
MAPIFREEBUFFER(lpProblems);
}
//------------------------------------------------------------------------------
// Set envelope recipients
hrT = MAPICALL(lpEnvelope)->ModifyRecipients(
lpEnvelope,
0,
lpEnvelopeAdrList);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(HasContent == TRUE)
{
// Set message recipients
hrT = MAPICALL(lpMessage)->ModifyRecipients(
lpMessage,
0,
lpMessageAdrList);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//------------------------------------------------------------------------------
if(HasContent == TRUE)
{
// Save changes to the message
hrT = MAPICALL(lpMessage)->SaveChanges(
lpMessage,
MAPI_DEFERRED_ERRORS|FORCE_SAVE);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Save changes to attachment object
hrT = MAPICALL(lpAttach)->SaveChanges(
lpAttach,
MAPI_DEFERRED_ERRORS|FORCE_SAVE);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
ULRELEASE(lpMessage);
ULRELEASE(lpAttach);
}
// Save changes to the envelope
hrT = MAPICALL(lpEnvelope)->SaveChanges(
lpEnvelope,
MAPI_DEFERRED_ERRORS|KEEP_OPEN_READWRITE);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//----------------------------------------------------------------------
dwEndProcessingTime = GetTickCount();
dwTotalProcessingTime = dwEndProcessingTime - dwStartProcessingTime;
dwSleepProcessingTime =
((dwTotalProcessingTime < dwOutSleepInterval) ?
(dwOutSleepInterval - dwTotalProcessingTime) : 0);
if(dwSleepProcessingTime > 0)
{
Sleep(dwSleepProcessingTime);
}
//----------------------------------------------------------------------
cleanup:
MAPIFREEBUFFER(lpProblems);
MAPIFREEBUFFER(lpeid);
FREEPADRLIST(lpOriginalEnvelopeAdrList);
FREEPADRLIST(lpOriginalMessageAdrList);
FREEPADRLIST(lpEnvelopeAdrList);
FREEPADRLIST(lpMessageAdrList);
FREEPADRLIST(lpEnvelope_NDR_AdrList);
FREEPADRLIST(lpMessage_NDR_AdrList);
FREEPADRLIST(lpEnvelopeAllAdrList);
FREEPADRLIST(lpMessageAllAdrList);
FREEPADRLIST(lpMappedEnvelopeAdrList);
FREEPADRLIST(lpMappedMessageAdrList);
MAPIFREEBUFFER(lpEnvelopeProps);
MAPIFREEBUFFER(lpMessageProps);
ULRELEASE(lpMessage);
ULRELEASE(lpAttach);
RETURN(hr);
}
//$--HrConvertMtsOut------------------------------------------------------------
// Convert a message in MTS-OUT.
// -----------------------------------------------------------------------------
HRESULT HrConvertMtsOut( // RETURNS: return code
IN PVOID pvConvInstance, // converter instance
IN LPADRBOOK lpAdrBook, // pointer to address book
IN LPTSTR lpszMessageClass, // message class
IN LPMESSAGE lpMessage) // message
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPSRowSet lpRows = NULL;
LPADRLIST lpAdrList = NULL;
LPMAPITABLE lpTable = NULL;
BOOL fFileCreated = FALSE; // TRUE if output file created
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
LPSPropValue lpPropT = NULL;
BOOL IsMapiRecip = 0;
LPTSTR lpszAddress = NULL;
LPADRLIST lpMapiAdrList = NULL;
LPADRLIST lpNonMapiAdrList = NULL;
ULONG i = 0;
LPSTREAM lpStream = NULL;
TCHAR rgchOutFileName[MAX_PATH+1] = {0};
EDKCNVRES crRes = GCR_OK;
//
// Declare an environment for the conversion.
//
EDKCNVENV envTmp =
{
1,
lpszOutConverterW,
(LHANDLE)NULL,
NULL,
NULL,
NULL
};
CONV_OPTIONS sConvOptions =
{
FALSE, // attach TNEF encapsulation
NULL // address type
};
ULONG cbMessageClass = 0;
LPWSTR lpszMessageClassW = NULL;
ULONG iMapi = 0;
ULONG iNonMapi = 0;
SizedSPropTagArray(1, rgPropTags) =
{
1,
{
PR_REPORT_DESTINATION_ENTRYID,
}
};
// stream interface flags
const ULONGulFlags=STGM_CREATE | STGM_READWRITE |
SOF_UNIQUEFILENAME | STGM_SHARE_EXCLUSIVE;
DEBUGPUBLIC("HrConvertMtsOut()\n");
if(_tcsstr(lpszMessageClass, TEXT("ENVELOPE.IPM")) != NULL)
{
//
// Get the recipient table for the message
//
hrT = MAPICALL(lpMessage)->GetRecipientTable(
lpMessage,
MAPI_DEFERRED_ERRORS,
&lpTable);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Query all the rows
//
hr = HrQueryAllRows(
lpTable,
NULL,
NULL,
NULL,
0,
&lpRows);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Divide recipient list into MAPI and non-MAPI recipients
//
lpAdrList = (LPADRLIST)lpRows;
hr = HrMAPICreateSizedAddressList(
lpAdrList->cEntries,
&lpMapiAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrMAPICreateSizedAddressList(
lpAdrList->cEntries,
&lpNonMapiAdrList);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
for(i = 0; i < lpAdrList->cEntries; i++)
{
cValues = lpAdrList->aEntries[i].cValues;
lpProps = lpAdrList->aEntries[i].rgPropVals;
lpPropT = LpValFindProp(PR_SEND_RICH_INFO, cValues, lpProps);
if(lpPropT != NULL)
{
IsMapiRecip = lpPropT->Value.b;
}
else
{
IsMapiRecip = FALSE;
}
if(IsMapiRecip == TRUE)
{
hr = HrMAPISetAddressList(
iMapi,
cValues,
lpProps,
lpMapiAdrList);
iMapi++;
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else
{
hr = HrMAPISetAddressList(
iNonMapi,
cValues,
lpProps,
lpNonMapiAdrList);
iNonMapi++;
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
} // end for
//
// Convert message for MAPI recipients
//
if(iMapi > 0)
{
// Set envelope recipients
hrT = MAPICALL(lpMessage)->ModifyRecipients(
lpMessage,
0,
lpMapiAdrList);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hrT = MAPICALL(lpMessage)->SaveChanges(
lpMessage,
KEEP_OPEN_READWRITE);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
lstrcpy(rgchOutFileName, lpszOutDirectory);
// Open a buffered stream on our SGW*.TMP output file.
hrT = OpenStreamOnFile(
MAPIAllocateBuffer,
MAPIFreeBuffer,
ulFlags,// stream interface flags
rgchOutFileName,
szFilePrefix,
&lpStream);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
fFileCreated = TRUE; // output file has been created
//------------------------------------------------------------------------------
// Get the message class
MAPIFREEBUFFER(lpszMessageClassW);
cbMessageClass = 0;
lpszMessageClassW = NULL;
hr = HrMAPIGetPropString(
(LPMAPIPROP)lpMessage,
PR_MESSAGE_CLASS_W,
&cbMessageClass,
(void **)&lpszMessageClassW);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Initialize the conversion environment structure
sConvOptions.fTnefEncode = TRUE;
sConvOptions.lpszAddressType = lpszAddressType;
envTmp.lphSession = (LHANDLE)lpSession;
envTmp.lpAB = lpAdrBook;
envTmp.pGatewayDefined = &sConvOptions;
//
// Perform the conversion.
//
hr = HrConvConvert(
pvConvInstance, // conversion instance pointer
&envTmp, // environment structure pointer
lpszMessageClassW, // message class
lpMessage, // message to convert from
lpStream, // stream to read to
&crRes); // result pointer
if(FAILED(hr) || crRes != GCR_OK)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
ULRELEASE(lpStream);
//
// Finished processing message
//
{
BOOL fT = FALSE;
fT = SetFileAttributes(rgchOutFileName, FILE_ATTRIBUTE_NORMAL);
if(fT == FALSE)
{
hrT = HR_LOG(E_FAIL);
}
}
} // end if MAPI recipients
//
// Convert message for non-MAPI recipients
//
if(iNonMapi > 0)
{
// Set envelope recipients
hrT = MAPICALL(lpMessage)->ModifyRecipients(
lpMessage,
0,
lpNonMapiAdrList);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hrT = MAPICALL(lpMessage)->SaveChanges(
lpMessage,
KEEP_OPEN_READWRITE);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
lstrcpy(rgchOutFileName, lpszOutDirectory);
hrT = OpenStreamOnFile(
MAPIAllocateBuffer,
MAPIFreeBuffer,
STGM_CREATE | STGM_READWRITE | SOF_UNIQUEFILENAME,
rgchOutFileName,
szFilePrefix,
&lpStream);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
fFileCreated = TRUE; // output file has been created
//------------------------------------------------------------------------------
// Get the message class
MAPIFREEBUFFER(lpszMessageClassW);
cbMessageClass = 0;
lpszMessageClassW = NULL;
hr = HrMAPIGetPropString(
(LPMAPIPROP)lpMessage,
PR_MESSAGE_CLASS_W,
&cbMessageClass,
(void **)&lpszMessageClassW);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Initialize the conversion environment structure
sConvOptions.fTnefEncode = FALSE;
sConvOptions.lpszAddressType = lpszAddressType;
envTmp.lphSession = (LHANDLE)lpSession;
envTmp.lpAB = lpAdrBook;
envTmp.pGatewayDefined = &sConvOptions;
//
// Perform the conversion.
//
hr = HrConvConvert(
pvConvInstance, // conversion instance pointer
&envTmp, // environment structure pointer
lpszMessageClassW, // message class
lpMessage, // message to convert from
lpStream, // stream to read to
&crRes); // result pointer
if(FAILED(hr) || crRes != GCR_OK)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
ULRELEASE(lpStream);
//
// Finished processing message
//
{
BOOL fT = FALSE;
fT = SetFileAttributes(rgchOutFileName, FILE_ATTRIBUTE_NORMAL);
if(fT == FALSE)
{
hrT = HR_LOG(E_FAIL);
}
}
} // end if non-MAPI recipients
} // end if Interpersonal message
else if(_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL)
{
//
// Determine if the report/notification recipient is a MAPI
// or a non-MAPI recipient.
//
if((_tcsstr(lpszMessageClass, TEXT(".NDR")) != NULL) ||
(_tcsstr(lpszMessageClass, TEXT(".DR")) != NULL))
{
//
// Get destination of non-delivery/delivery report.
//
hr = MAPICALL(lpMessage)->GetProps(
lpMessage,
(SPropTagArray *)&rgPropTags,
fMapiUnicode,
&cValues,
&lpProps);
if(FAILED(hr))
{
lpProps = NULL;
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrGWResolveProxy(
lpAdrBook,
lpProps->Value.bin.cb,
(LPENTRYID)lpProps->Value.bin.lpb,
lpszAddressType,
&IsMapiRecip,
&lpszAddress);
MAPIFREEBUFFER(lpProps);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else if((_tcsstr(lpszMessageClass, TEXT(".IPNNRN")) != NULL) ||
(_tcsstr(lpszMessageClass, TEXT(".IPNRN")) != NULL))
{
//
// Get the recipient table for the non-read/read notification.
//
hrT = MAPICALL(lpMessage)->GetRecipientTable(
lpMessage,
MAPI_DEFERRED_ERRORS,
&lpTable);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Query all the rows
//
hr = HrQueryAllRows(
lpTable,
NULL,
NULL,
NULL,
0,
&lpRows);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lpAdrList = (LPADRLIST)lpRows;
cValues = lpAdrList->aEntries[i].cValues;
lpProps = lpAdrList->aEntries[i].rgPropVals;
lpPropT = LpValFindProp(PR_SEND_RICH_INFO, cValues, lpProps);
if(lpPropT != NULL)
{
IsMapiRecip = lpPropT->Value.b;
}
else
{
IsMapiRecip = FALSE;
}
FREEPADRLIST(lpAdrList);
}
else
{
IsMapiRecip = FALSE;
}
//------------------------------------------------------------------------------
lstrcpy(rgchOutFileName, lpszOutDirectory);
hrT = OpenStreamOnFile(
MAPIAllocateBuffer,
MAPIFreeBuffer,
STGM_CREATE | STGM_READWRITE | SOF_UNIQUEFILENAME,
rgchOutFileName,
szFilePrefix,
&lpStream);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
fFileCreated = TRUE; // output file has been created
//------------------------------------------------------------------------------
// Get the message class
MAPIFREEBUFFER(lpszMessageClassW);
cbMessageClass = 0;
lpszMessageClassW = NULL;
hr = HrMAPIGetPropString(
(LPMAPIPROP)lpMessage,
PR_MESSAGE_CLASS_W,
&cbMessageClass,
(void **)&lpszMessageClassW);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
// Initialize the conversion environment structure
sConvOptions.fTnefEncode = IsMapiRecip;
sConvOptions.lpszAddressType = lpszAddressType;
envTmp.lphSession = (LHANDLE)lpSession;
envTmp.lpAB = lpAdrBook;
envTmp.pGatewayDefined = &sConvOptions;
//
// Perform the conversion.
//
hr = HrConvConvert(
pvConvInstance, // conversion instance pointer
&envTmp, // environment structure pointer
lpszMessageClassW, // message class
lpMessage, // message to convert from
lpStream, // stream to read to
&crRes); // result pointer
if(FAILED(hr) || crRes != GCR_OK)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
ULRELEASE(lpStream);
//
// Finished processing message
//
{
BOOL fT = FALSE;
fT = SetFileAttributes(rgchOutFileName, FILE_ATTRIBUTE_NORMAL);
if(fT == FALSE)
{
hrT = HR_LOG(E_FAIL);
}
}
} // end if report
else
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cleanup:
if ( FAILED(hr) )
{
// delete the output file created, if any.
if ( fFileCreated == TRUE )
{
// Must release the stream first!
ULRELEASE(lpStream);
(VOID)DeleteFile(rgchOutFileName);
}
}
MAPIFREEBUFFER(lpszAddress);
MAPIFREEBUFFER(lpszMessageClassW);
FREEPADRLIST(lpAdrList); // also frees lpRows
FREEPADRLIST(lpMapiAdrList);
FREEPADRLIST(lpNonMapiAdrList);
ULRELEASE(lpStream);
ULRELEASE(lpTable);
RETURN(hr);
}
//$--HrNonDeliverMtsOutMessage--------------------------------------------------
// Non-deliver a message in MTS-OUT.
// -----------------------------------------------------------------------------
HRESULT HrNonDeliverMtsOutMessage( // RETURNS: zero
IN LPTSTR lpszMessageClass, // message class
IN LPMESSAGE lpEnvelope) // envelope
{
HRESULT hr = NOERROR;
LPADRBOOK lpAdrBook = NULL;
LPMESSAGE lpMessage = NULL;
LPMESSAGE lpSubjectMessage = NULL;
LPMESSAGE lpReportEnvelope = NULL;
LPADRLIST lpReportAdrList = NULL;
LPATTACH lpAttach = NULL;
BOOL HasContent = TRUE;
DEBUGPUBLIC("HrNonDeliverMtsOutMessage()\n");
lpAdrBook = GetAdrBookPtr();
MODULE_ERROR1(
"**** [IN ] Unknown message class [%s] ****",
((lpszMessageClass == NULL) ? "(null)" : lpszMessageClass));
hr = HrNonDeliverAllRecipList(
lpEnvelope,
&lpReportAdrList);
if(FAILED(hr))
{
goto cleanup;
}
// Get the attachment in the envelope
hr = MAPICALL(lpEnvelope)->OpenAttach(
lpEnvelope,
0,
NULL,
MAPI_MODIFY,
&lpAttach);
if((FAILED(hr)) && (hr != MAPI_E_NOT_FOUND))
{
goto cleanup;
}
if(hr == MAPI_E_NOT_FOUND)
{
//
// Message does not have an attachment.
//
HasContent = FALSE;
lpAttach = NULL;
}
lpSubjectMessage = NULL;
if(HasContent == TRUE)
{
// Open a message interface on the attachment
hr = MAPICALL(lpAttach)->OpenProperty(
lpAttach,
PR_ATTACH_DATA_OBJ,
(LPIID)&IID_IMessage,
0,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
(LPUNKNOWN *)&lpMessage);
if(FAILED(hr))
{
goto cleanup;
}
lpSubjectMessage = lpMessage;
}
else
{
lpSubjectMessage = lpEnvelope;
}
//
// Create a non delivery report in MTS-IN
//
if(lpSubjectMessage != NULL)
{
hr = HrCreateNonDeliveryReport(
FALSE,
lpAdrBook,
lpMtsInFolder,
lpSubjectMessage,
lpReportAdrList,
&lpReportEnvelope);
if(FAILED(hr))
{
goto cleanup;
}
hr = HrMAPISetPropBoolean(
(LPMAPIPROP)lpReportEnvelope,
PR_DELETE_AFTER_SUBMIT,
TRUE);
if(FAILED(hr))
{
goto cleanup;
}
// Submit message
hr = MAPICALL(lpReportEnvelope)->SubmitMessage(lpReportEnvelope, FORCE_SUBMIT);
if(FAILED(hr))
{
;
}
}
cleanup:
ULRELEASE(lpReportEnvelope);
ULRELEASE(lpMessage);
FREEPADRLIST(lpReportAdrList);
RETURN(hr);
}
//$--ProcessMtsOut--------------------------------------------------------------
// Process messages in MTS-OUT.
// -----------------------------------------------------------------------------
DWORD ProcessMtsOut( // RETURNS: zero
IN LPVOID lpParameter) // parameter
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
SCODE sc = 0;
ULONG cbeid = 0;
LPENTRYID lpeid = NULL;
ULONG ulObjType = 0;
ULONG ulPropTag = 0;
ULONG cValues = 0;
ULONG i = 0;
ULONG j = 0;
ULONG cRows = 0;
LPMESSAGE lpEnvelope = NULL;
ULONG cbMessageClass = 0;
LPTSTR lpszMessageClass = NULL;
LPSPropValue lpProps = NULL;
LPSPropTagArray lpPropTagArray = NULL;
ULONG cValuesT = 0;
LPSPropValue lpPropsT = NULL;
DWORD dwStartProcessingTime = 0;
LPADRBOOK lpAdrBook = NULL;
ULONG cbMsgEid = 0;
LPENTRYID lpMsgEid = NULL;
SizedSPropTagArray(1, rgRecipPropTag) =
{
1,
{
PR_MESSAGE_RECIPIENTS
}
};
SizedSPropTagArray(1, rgRecordKeyPropTag) =
{
1,
{
PR_RECORD_KEY
}
};
ULONG cBytes = 0;
LPTSTR lpszRecordKey = 0;
PVOID pvConvInstance = NULL;
LPIDITEM lpIdItem = NULL;
DEBUGPUBLIC("ProcessMtsOut()\n");
//performance code
// Initialize conversion engine instance data.
hr = HrConvInitInstance(hEventLog, &pvConvInstance);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cRows = GetGWSRowSet(lpParameter)->cRows;
lpAdrBook = GetAdrBookPtr();
for(i = 0; i < cRows; i++)
{
dwStartProcessingTime = GetTickCount();
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;
cbMsgEid = cbeid;
lpMsgEid = lpeid;
cValues = 0;
lpProps = NULL;
// Get the message in the MTS-OUT folder
hrT = MAPICALL(lpMtsOutFolder)->OpenEntry(
lpMtsOutFolder,
cbeid,
lpeid,
NULL,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
&ulObjType,
(LPUNKNOWN FAR *)&lpEnvelope);
cbeid = 0;
lpeid = NULL;
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(ulObjType != MAPI_MESSAGE)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
// Get the message ID
MAPIFREEBUFFER(lpPropsT);
MAPIFREEBUFFER(lpszRecordKey);
cValuesT = 0;
lpPropsT = NULL;
hr = MAPICALL(lpEnvelope)->GetProps(
lpEnvelope,
(LPSPropTagArray)&rgRecordKeyPropTag,
fMapiUnicode,
&cValuesT,
&lpPropsT);
if(FAILED(hr))
{
goto cleanup;
}
if(lpPropsT[0].ulPropTag != PR_RECORD_KEY)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(lpPropsT[0].Value.bin.cb == 0)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(lpPropsT[0].Value.bin.lpb == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cBytes = (lpPropsT[0].Value.bin.cb + sizeof(TCHAR)) * (2 * sizeof(TCHAR));
hr = MAPIAllocateBuffer(cBytes, (void **)&lpszRecordKey);
if(FAILED(hr))
{
goto cleanup;
}
HexFromBin(lpPropsT[0].Value.bin.lpb, lpPropsT[0].Value.bin.cb, lpszRecordKey);
MAPIFREEBUFFER(lpPropsT);
hr = HrAddIdItem(
&OutboundIdList,
lpszRecordKey,
&lpIdItem);
if(hr == EDK_E_ALREADY_EXISTS)
{
//
// Skip this message. It is already being processed
// by another thread.
//
MAPIFREEBUFFER(lpPropsT);
MAPIFREEBUFFER(lpszRecordKey);
ULRELEASE(lpEnvelope);
continue;
}
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
// Get the message class
MAPIFREEBUFFER(lpszMessageClass);
cbMessageClass = 0;
lpszMessageClass = NULL;
hr = HrMAPIGetPropString(
(LPMAPIPROP)lpEnvelope,
PR_MESSAGE_CLASS,
&cbMessageClass,
(void **)&lpszMessageClass);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
MODULE_WARNING1(
"**** [OUT] Processing message of class [%s] ****",
((lpszMessageClass == NULL) ? "(null)" : lpszMessageClass));
if(_tcsstr(lpszMessageClass, TEXT("ENVELOPE.IPM")) != NULL)
{
hr = HrExportMessage(
lpAdrBook,
FALSE,
TRUE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".NDR")) != NULL))
{
hr = HrExportMessage(
lpAdrBook,
TRUE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".DR")) != NULL))
{
hr = HrExportMessage(
lpAdrBook,
TRUE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".IPNNRN")) != NULL))
{
hr = HrExportMessage(
lpAdrBook,
FALSE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else if((_tcsstr(lpszMessageClass, TEXT("REPORT.IPM")) != NULL) &&
(_tcsstr(lpszMessageClass, TEXT(".IPNRN")) != NULL))
{
hr = HrExportMessage(
lpAdrBook,
FALSE,
FALSE,
dwStartProcessingTime,
lpEnvelope);
}
else
{
hr = HrNonDeliverMtsOutMessage(
lpszMessageClass,
lpEnvelope);
if(FAILED(hr))
{
; // failed to non-deliver message
}
}
if(FAILED(hr))
{
MODULE_ERROR1(
"**** [OUT] Error while processing message of class [%s] ****",
((lpszMessageClass == NULL) ? "(null)" : lpszMessageClass));
//
// This message will be moved to the archive folder.
//
MAPIFREEBUFFER(lpszMessageClass);
MAPIFREEBUFFER(lpPropsT);
MAPIFREEBUFFER(lpszRecordKey);
ULRELEASE(lpEnvelope);
continue;
}
//------------------------------------------------------------------------------
else
{
hr = HrConvertMtsOut(
pvConvInstance,
lpAdrBook,
lpszMessageClass,
lpEnvelope);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//------------------------------------------------------------------------------
ULRELEASE(lpEnvelope);
//performance code
hr = HrMAPIDeleteMessage(
lpMtsOutFolder,
cbMsgEid,
lpMsgEid);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
hr = HrRemoveIdItem(&OutboundIdList, lpIdItem);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
}
cleanup:
MAPIFREEBUFFER(lpPropsT);
MAPIFREEBUFFER(lpszRecordKey);
MAPIFREEBUFFER(lpszMessageClass);
ULRELEASE(lpEnvelope);
if(pvConvInstance != NULL)
{
// De-initialize conversion engine instance data.
(VOID)HrConvUninitInstance(pvConvInstance);
pvConvInstance = NULL;
}
return(0);
}
// $--AppendSlash----------------------------------------------------------
// This function will append a backslash to a pathname if one does not
// already exist.
// ------------------------------------------------------------------------
void AppendSlash ( // RETURNS: Nothing
IN OUT LPTSTR sz1) // pathname
{
LPTSTR sz2 = sz1;
while (*sz2) // Loop through each char until '\0'
{
sz1 = sz2;
sz2 = CharNext(sz1);
}
// Check there were no CharNext errors, then add a '\' if not there.
if (sz2 != sz1 + 1 || *sz1 != TEXT('\\'))
{
*sz2++ = TEXT('\\');
*sz2 = TEXT('\0');
}
}
//$--GWMain---------------------------------------------------------------------
// Start threads.
// -----------------------------------------------------------------------------
void GWMain(
void)
{
HRESULT hrT = NOERROR;
HRESULT hr = NOERROR;
EDK_SERVICE_CONTROL_T sc = 0;
LPMAPIPROP lpCurrentObject = NULL;
ULONG ulExtensionDataTag = 0;
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
LPSBinary lpBlobArray = NULL;
ULONG cBlobArray = 0;
ULONG i = 0;
LPBYTE lpbBlob = NULL;
ULONG cbBlob = 0;
LPSPropValue lpUnpackedProps = NULL;
ULONG cUnpackedProps = 0;
LPTSTR lpszUnpackedName = NULL;
LPTSTR lpszDir = NULL;
ULONG cBytes = 0;
LPTSTR lpsz = NULL;
SizedSPropTagArray(1, rgPropTags) =
{
1,
{
0,
}
};
DEBUGPUBLIC("GWMain()\n");
//--------------------------------------------------------------------------
//
// Get a pointer to the current object
//
hr = HrOpenSessionObject(
lpSession,
&lpCurrentObject);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Convert our MAPI Name ID to a property tag
//
hr = HrCfgPropertyTagFromNameId(
lpCurrentObject,
NM_EXTENSION_DATA,
&ulExtensionDataTag);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Now get the properties we want from the site object
//
rgPropTags.aulPropTag[0] =
PROP_TAG(MV_FLAG|PT_BINARY, PROP_ID(ulExtensionDataTag));
hr = MAPICALL(lpCurrentObject)->GetProps(
lpCurrentObject,
(LPSPropTagArray)&rgPropTags,
fMapiUnicode,
&cValues,
&lpProps);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(PROP_TYPE(lpProps[0].ulPropTag) == PT_ERROR)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lpBlobArray = lpProps->Value.MVbin.lpbin;
cBlobArray = lpProps->Value.MVbin.cValues;
for(i = 0; i < cBlobArray; i++)
{
if (!lstrcmpW(SGWBLOBNAMEW, (LPWSTR)lpBlobArray[i].lpb))
{
lpbBlob = lpBlobArray[i].lpb;
cbBlob = lpBlobArray[i].cb;
}
}
hr = HrCfgUnpackData(
cbBlob,
lpbBlob,
&lpszUnpackedName,
&cUnpackedProps,
&lpUnpackedProps);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//--------------------------------------------------------------------------
if(cUnpackedProps < 17)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lpszAddressType = lpUnpackedProps[IDX_ADDR_TYPE].Value.LPSZ;
lpszSysAdminName = lpUnpackedProps[IDX_DISP_NAME].Value.LPSZ;
lpszSysAdminAddr = lpUnpackedProps[IDX_EMAIL_ADDR].Value.LPSZ;
cInThreads = lpUnpackedProps[IDX_EDIT_THREADS_IN].Value.ul;
cInMessages = lpUnpackedProps[IDX_EDIT_MSGS_IN].Value.ul;
dwInSleepInterval = lpUnpackedProps[IDX_EDIT_SLEEP_IN].Value.ul;
lpszInDirectory = lpUnpackedProps[IDX_DIR_IN].Value.LPSZ;
dwInPollInterval = lpUnpackedProps[IDX_EDIT_POLLING_IN].Value.ul;
lpszInConverter = lpUnpackedProps[IDX_CONVERTER_IN].Value.LPSZ;
fInEnabled = lpUnpackedProps[IDX_CHECK_IN_BOUND].Value.b;
cOutThreads = lpUnpackedProps[IDX_EDIT_THREADS_OUT].Value.ul;
cOutMessages = lpUnpackedProps[IDX_EDIT_MSGS_OUT].Value.ul;
dwOutSleepInterval = lpUnpackedProps[IDX_EDIT_SLEEP_OUT].Value.ul;
lpszOutDirectory = lpUnpackedProps[IDX_DIR_OUT].Value.LPSZ;
dwOutPollInterval = lpUnpackedProps[IDX_EDIT_POLLING_OUT].Value.ul;
lpszOutConverter = lpUnpackedProps[IDX_CONVERTER_OUT].Value.LPSZ;
fOutEnabled = lpUnpackedProps[IDX_CHECK_OUT_BOUND].Value.b;
hr = HrStrToStrW(lpszInConverter, &lpszInConverterW);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = HrStrToStrW(lpszOutConverter, &lpszOutConverterW);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//
// Add trailing slash to inbound directory.
//
cBytes = cbStrLen(lpszInDirectory) + sizeof(TCHAR);
lpszDir = NULL;
hr = MAPIAllocateMore(cBytes, lpUnpackedProps, (void **)&lpszDir);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lstrcpy(lpszDir, lpszInDirectory);
AppendSlash(lpszDir);
lpszInDirectory = lpszDir;
//
// Add trailing slash to outbound directory.
//
cBytes = cbStrLen(lpszOutDirectory) + sizeof(TCHAR);
lpszDir = NULL;
hr = MAPIAllocateMore(cBytes, lpUnpackedProps, (void **)&lpszDir);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lstrcpy(lpszDir, lpszOutDirectory);
AppendSlash(lpszDir);
lpszOutDirectory = lpszDir;
//
// Add trailing slash to archive directory.
//
cBytes = cbStrLen(lpszOutDirectory) +
cbStrLen(TEXT("\\ARCHIVE")) +
sizeof(TCHAR);
lpszDir = NULL;
hr = MAPIAllocateBuffer(cBytes, (void **)&lpszDir);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lstrcpy(lpszDir, lpszOutDirectory);
AppendSlash(lpszDir);
lpszArchiveDirectory = lpszDir;
lpsz = lpszArchiveDirectory;
lpsz += lstrlen(lpszArchiveDirectory);
lpsz --;
*lpsz = 0;
while(lpsz != lpszArchiveDirectory)
{
if((*lpsz == TEXT('\\')) || (*lpsz == TEXT(':')))
{
if(*lpsz == TEXT(':'))
lpsz++;
lstrcpy(lpsz, "\\ARCHIVE\\");
break;
}
lpsz--;
}
//--------------------------------------------------------------------------
if(fInEnabled == TRUE)
{
hr = HrGWStartNewFileHandler(
dwInSleepInterval,
dwInPollInterval,
cInMessages,
cInThreads,
lpszAddressType,
TEXT("SGW*.TMP"),
lpszInDirectory,
(LPTHREAD_START_ROUTINE)ProcessMtsIn);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else
{
MODULE_WARNING("**** [IN] Processing not enabled ****");
}
//--------------------------------------------------------------------------
if(fOutEnabled == TRUE)
{
hr = HrGWStartNewMailHandler(
dwOutSleepInterval,
dwOutPollInterval,
cOutMessages,
cOutThreads,
lpszAddressType,
lpszOutDirectory,
(LPTHREAD_START_ROUTINE)ProcessMtsOut);
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
else
{
MODULE_WARNING("**** [OUT] Processing not enabled ****");
}
cleanup:
if(FAILED(hr))
{
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
MAPIFREEBUFFER(lpProps);
MAPIFREEBUFFER(lpszUnpackedName);
ULRELEASE(lpCurrentObject);
//
// Wait for a request for the gateway to stop.
//
hr = HR_LOG(HrServiceWaitForStop(INFINITE, &sc));
MAPIFREEBUFFER(lpszInConverterW);
MAPIFREEBUFFER(lpszOutConverterW);
MAPIFREEBUFFER(lpUnpackedProps);
//
// IMPORTANT: Return from this function only if the gateway is ready to stop.
//
return;
}
//$--HrGWLogon------------------------------------------------------------------
// Logon to the gateway.
// -----------------------------------------------------------------------------
HRESULT HrGWLogon( // RETURNS: return code
void) // no arguments
{
HRESULT hr = NOERROR;
SCODE sc = 0;
BOOL fStatus = TRUE;
LPTSTR lpszT = NULL;
LPMAPIPROP lpSiteAddressing = NULL;
ULONG ulGatewayProxyTag = 0;
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
ULONG i = 0;
SizedSPropTagArray(1, rgPropTags) =
{
1,
{
0,
}
};
DEBUGPUBLIC("HrGWLogon()\n");
InitializeCriticalSection(&csGatewaySeqNo);
InitializeCriticalSection(&csInboundIdList);
InitializeCriticalSection(&csOutboundIdList);
InboundIdList.lpcs = &csInboundIdList;
OutboundIdList.lpcs = &csOutboundIdList;
lpSession = GetGWSession();
lpStore = GetGWDefaultStore();
lpRootFolder = GetGWRootFolder();
lpMtsInFolder = GetGWMtsInFolder();
lpMtsOutFolder = GetGWMtsOutFolder();
cbGalEid = GetGWGALEntryIdSize();
lpGalEid = GetGWGALEntryId();
//
// Get a pointer to the site addressing object
hr = HrOpenSiteContainerAddressing(
lpSession,
&lpSiteAddressing);
if(FAILED(hr))
{
fStatus = FALSE;
goto cleanup;
}
//
// Convert our MAPI Name ID to a property tag
//
hr = HrCfgPropertyTagFromNameId(
lpSiteAddressing,
NM_GATEWAY_PROXY,
&ulGatewayProxyTag);
if(FAILED(hr))
{
fStatus = FALSE;
goto cleanup;
}
//
// Now get the properties we want from the site object
//
rgPropTags.aulPropTag[0] = ulGatewayProxyTag;
hr = MAPICALL(lpSiteAddressing)->GetProps(
lpSiteAddressing,
(LPSPropTagArray)&rgPropTags,
fMapiUnicode,
&cValues,
&lpProps);
if(FAILED(hr))
{
fStatus = FALSE;
goto cleanup;
}
if(PROP_TYPE(lpProps[0].ulPropTag) == PT_ERROR)
{
hr = HR_LOG(E_FAIL);
fStatus = FALSE;
goto cleanup;
}
if(lpProps[0].Value.MVSZ.cValues == 0)
{
hr = HR_LOG(E_FAIL);
fStatus = FALSE;
goto cleanup;
}
for(i = 0; i < (lpProps[0].Value.MVSZ.cValues); i++)
{
if(!_tcsnicmp(
lpProps[0].Value.MVSZ.LPPSZ[i],
TEXT("X400:"),
lstrlen(TEXT("X400:"))))
{
break;
}
}
sc = MAPIAllocateBuffer(
cbStrLen(lpProps[0].Value.MVSZ.LPPSZ[i]),
(void **)&lpszT);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(lpszT, lpProps[0].Value.MVSZ.LPPSZ[i]);
//
// Create the local enterprise GDI.
//
hr = HrCreateEnterpriseGDI(
lpszT,
TEXT(":;"),
&lpszLocalGDI);
if(FAILED(hr))
{
fStatus = FALSE;
goto cleanup;
}
// Open an event log for this application.
hr = HrEventOpenLog(
szAppName, // application name
NULL, // executable name (will be computed)
TEXT("EDKMSG.DLL"), // event message file
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 global conversion engine data.
hr = HrConvInitGlobals();
if ( FAILED(hr) )
{
fStatus = FALSE;
goto cleanup;
}
cleanup:
ULRELEASE(lpSiteAddressing);
MAPIFREEBUFFER(lpProps);
MAPIFREEBUFFER(lpszT);
if(fStatus == FALSE)
{
//
// Gateway logon failed.
//
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
RETURN(hr);
}
//$--HrArchiveMtsOut------------------------------------------------------------
// Archive messages in MTS-OUT which could not be delivered.
// -----------------------------------------------------------------------------
HRESULT HrArchiveMtsOut( // RETURNS: zero
VOID) // parameter
{
HRESULT hr = NOERROR;
ULONG cbeid = 0;
LPENTRYID lpeid = NULL;
ULONG ulObjType = 0;
ULONG ulPropTag = 0;
ULONG cValues = 0;
ULONG i = 0;
ULONG cRows = 0;
LPMAPIFOLDER lpArchiveFolder = NULL;
LPMAPITABLE lpTable = NULL;
LPMESSAGE lpEnvelope = NULL;
LPSPropValue lpProps = NULL;
LPSPropTagArray lpPropTagArray = NULL;
ULONG cValuesT = 0;
LPSPropValue lpPropsT = NULL;
ULONG cbMsgEid = 0;
LPENTRYID lpMsgEid = NULL;
LPSRowSet lpRows = NULL;
SizedSPropTagArray(1, rgRecordKeyPropTag) =
{
1,
{
PR_RECORD_KEY
}
};
ULONG cBytes = 0;
LPTSTR lpszRecordKey = 0;
LPIDITEM lpIdItem = NULL;
SizedSPropTagArray(1, rgPropTag) =
{
1,
{
PR_ENTRYID
}
};
DEBUGPUBLIC("HrArchiveMtsOut()\n");
//
// Find and open the MTS-OUT archive folder.
//
hr = HrMAPIFindFolder(
GetGWRootFolder(),
TEXT("ARCHIVE"),
&cbeid,
&lpeid);
if(FAILED(hr))
{
hr = MAPICALL(lpRootFolder)->CreateFolder(
lpRootFolder,
FOLDER_GENERIC,
TEXT("ARCHIVE"),
NULL,
NULL,
MAPI_DEFERRED_ERRORS,
&lpArchiveFolder);
if(FAILED(hr))
{
goto cleanup;
}
}
else
{
// Open the archive folder in the root folder
hr = MAPICALL(lpRootFolder)->OpenEntry(
lpRootFolder,
cbeid,
lpeid,
NULL,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
&ulObjType,
(LPUNKNOWN FAR *) &lpArchiveFolder);
MAPIFREEBUFFER(lpeid);
if(FAILED(hr))
{
goto cleanup;
}
if(ulObjType != MAPI_FOLDER)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}
//
// Get the contents table for the MTS-OUT
//
hr = MAPICALL(lpMtsOutFolder)->GetContentsTable(
lpMtsOutFolder,
MAPI_DEFERRED_ERRORS,
&lpTable);
if(FAILED(hr))
{
goto cleanup;
}
hr = MAPICALL(lpTable)->SetColumns(
lpTable,
(LPSPropTagArray)&rgPropTag,
TBL_BATCH);
if(FAILED(hr))
{
goto cleanup;
}
//
// Query all the rows
//
hr = HrQueryAllRows(
lpTable,
NULL,
NULL,
NULL,
0,
&lpRows);
ULRELEASE(lpTable);
if(FAILED(hr))
{
goto cleanup;
}
cRows = lpRows->cRows;
for(i = 0; i < cRows; i++)
{
cValues = lpRows->aRow[i].cValues;
lpProps = lpRows->aRow[i].lpProps;
cbeid = lpProps[0].Value.bin.cb;
lpeid = (LPENTRYID)lpProps[0].Value.bin.lpb;
cbMsgEid = cbeid;
lpMsgEid = lpeid;
cValues = 0;
lpProps = NULL;
// Get the message in the MTS-OUT folder
hr = MAPICALL(lpMtsOutFolder)->OpenEntry(
lpMtsOutFolder,
cbeid,
lpeid,
NULL,
MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
&ulObjType,
(LPUNKNOWN FAR *)&lpEnvelope);
cbeid = 0;
lpeid = NULL;
if(FAILED(hr))
{
goto cleanup;
}
if(ulObjType != MAPI_MESSAGE)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
// Get the message ID
MAPIFREEBUFFER(lpPropsT);
MAPIFREEBUFFER(lpszRecordKey);
cValuesT = 0;
lpPropsT = NULL;
hr = MAPICALL(lpEnvelope)->GetProps(
lpEnvelope,
(LPSPropTagArray)&rgRecordKeyPropTag,
fMapiUnicode,
&cValuesT,
&lpPropsT);
if(FAILED(hr))
{
goto cleanup;
}
if(lpPropsT[0].ulPropTag != PR_RECORD_KEY)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(lpPropsT[0].Value.bin.cb == 0)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
if(lpPropsT[0].Value.bin.lpb == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
cBytes = (lpPropsT[0].Value.bin.cb + sizeof(TCHAR)) * (2 * sizeof(TCHAR));
hr = MAPIAllocateBuffer(cBytes, (void **)&lpszRecordKey);
if(FAILED(hr))
{
goto cleanup;
}
HexFromBin(lpPropsT[0].Value.bin.lpb, lpPropsT[0].Value.bin.cb, lpszRecordKey);
MAPIFREEBUFFER(lpPropsT);
hr = HrLookupIdItem(
&OutboundIdList,
lpszRecordKey,
&lpIdItem);
if(hr == EDK_E_NOT_FOUND)
{
//
// Skip this message. It is a new message.
//
MAPIFREEBUFFER(lpszRecordKey);
MAPIFREEBUFFER(lpPropsT);
ULRELEASE(lpEnvelope);
continue;
}
if(FAILED(hr))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
//------------------------------------------------------------------------------
MAPIFREEBUFFER(lpszRecordKey);
MAPIFREEBUFFER(lpPropsT);
ULRELEASE(lpEnvelope);
//------------------------------------------------------------------------------
hr = HrMAPIMoveMessage(
lpMtsOutFolder,
lpArchiveFolder,
cbMsgEid,
lpMsgEid);
if(FAILED(hr))
{
; // create an entry in the debug log
}
}
cleanup:
FREEPROWS(lpRows);
MAPIFREEBUFFER(lpPropsT);
MAPIFREEBUFFER(lpszRecordKey);
ULRELEASE(lpEnvelope);
ULRELEASE(lpArchiveFolder);
ULRELEASE(lpTable);
RETURN(hr);
}
//$--HrArchiveMtsIn-------------------------------------------------------------
// Archive messages in MTS-IN which could not be delivered.
// -----------------------------------------------------------------------------
HRESULT HrArchiveMtsIn( // RETURNS: return code
VOID) // no arguments
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPIDITEM lpIdItem = NULL;
BOOL fRet = FALSE;
TCHAR rgchFileName[MAX_PATH+1] = {0};
TCHAR rgchPathName[MAX_PATH+1] = {0};
LPTSTR lpszPath = NULL;
LPIDITEM lpIdList = NULL;
//
// Find and open the MTS-IN archive directory.
//
lstrcpy(rgchPathName, lpszArchiveDirectory);
fRet = CreateDirectory(rgchPathName, NULL);
if(fRet == FALSE)
{
hr = HR_LOG(E_FAIL);
}
lpszPath = rgchPathName;
lpIdList = &InboundIdList;
EnterCriticalSection(lpIdList->lpcs);
__try
{
lpIdItem = lpIdList->next;
while(lpIdItem != NULL)
{
lpIdList->next = lpIdItem->next;
rgchFileName[0] = 0;
fRet = GetTempFileName32(lpszPath, TEXT("BAK"), 0, (LPTSTR)rgchFileName);
if(fRet == FALSE)
{
hr = HR_LOG(E_FAIL);
}
else
{
fRet = MoveFileEx(
lpIdItem->lpszId,
(LPTSTR)rgchFileName,
MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING);
if(fRet == FALSE)
{
hr = HR_LOG(E_FAIL);
}
}
lpIdItem = lpIdList->next;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(_exception_code());
hr = HR_LOG(E_FAIL);
MODULE_WARNING("**** Stopping gateway ****");
SetServiceExitCode( ERROR_INTERNAL_ERROR, NOERROR);
ServiceStop();
}
LeaveCriticalSection(lpIdList->lpcs);
RETURN(hr);
}
//$--HrGWLogoff-----------------------------------------------------------------
// Logoff of the gateway.
// -----------------------------------------------------------------------------
HRESULT HrGWLogoff( // RETURNS: return code
void) // no arguments
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
DEBUGPUBLIC("HrGWLogoff()\n");
// De-initialize conversion engine global data.
ConvUninitGlobals();
// Close the event log.
(VOID)HrEventCloseLog();
hEventLog = NULL;
MAPIFREEBUFFER(lpbBuffer);
MAPIFREEBUFFER(lppszBufferArray);
MAPIFREEBUFFER(lpszLocalGDI);
//
// Archive messages which could not be delivered.
//
hrT = HR_LOG(HrArchiveMtsIn());
hrT = HR_LOG(HrArchiveMtsOut());
hrT = HR_LOG(HrEmptyIdList(&InboundIdList));
hrT = HR_LOG(HrEmptyIdList(&OutboundIdList));
DeleteCriticalSection(&csGatewaySeqNo);
DeleteCriticalSection(&csInboundIdList);
DeleteCriticalSection(&csOutboundIdList);
MAPIFREEBUFFER(lpszArchiveDirectory);
RETURN(hr);
}