// --gwreport.c-----------------------------------------------------------------
//
// Gateway report functions.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------
#include "edk.h"
#include "gwreport.h"
#define SZ_MTS_ID "/c=XX/a=X/p=X/l=X"
#define CENTRIES_FIRST 4
#define CENTRIES_NEXT 32
//$--HrCreateEmptyRecipList-----------------------------------------------------
//
// Create an empty list of recipients.
//
// -----------------------------------------------------------------------------
static HRESULT HrCreateEmptyRecipList( // RETURNS: return code
OUT LPADRLIST* lppAdrList) // address list
{
HRESULT hr = NOERROR;
DEBUGPRIVATE("HrCreateEmptyRecipList()\n");
hr = HrMAPICreateSizedAddressList(
CENTRIES_FIRST,
lppAdrList);
if(FAILED(hr))
{
goto cleanup;
}
else
{
(*lppAdrList)->cEntries = 0;
}
cleanup:
RETURN(hr);
}
//$--HrNDRCreateFailedRecipList-------------------------------------------------
//
// Create an empty list of failed recipients.
//
// -----------------------------------------------------------------------------
HRESULT HrNDRCreateFailedRecipList( // RETURNS: return code
OUT LPADRLIST* lppAdrList) // address list
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrNDRCreateFailedRecipList()\n");
hr = HrCreateEmptyRecipList(lppAdrList);
RETURN(hr);
}
//$--HrNDRGetFailedRecipList----------------------------------------------------
//
// Create a failed recipient entry.
//
// -----------------------------------------------------------------------------
HRESULT HrNDRGetFailedRecipList( // RETURNS: return code
IN LPADRENTRY lpAdrEntry, // address entry
IN ULONG cExtraProps, // count of extra properties
IN LPSPropValue lpExtraProps, // extra properties
OUT ULONG* lpcFailedProps, // count of failed properties
OUT LPSPropValue* lppFailedProps) // failed properties
{
HRESULT hr = NOERROR;
FILETIME ftReportTime = {0};
ULONG i = 0;
SPropValue rgProps[9] = {0};
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
ULONG cNewValues = 0;
LPSPropValue lpNewProps = NULL;
LPSPropValue lpPropT = NULL;
DEBUGPUBLIC("HrNDRGetFailedRecipList()\n");
//
// Get the current time
//
if((cExtraProps > 0) && (lpExtraProps != NULL))
{
hr = HrMAPIAppendSPropValues(
lpAdrEntry->cValues,
lpAdrEntry->rgPropVals,
cExtraProps,
lpExtraProps,
&cValues,
&lpProps);
if(FAILED(hr))
{
goto cleanup;
}
}
else
{
cValues = lpAdrEntry->cValues;
hr = ScDupPropset(
lpAdrEntry->cValues,
lpAdrEntry->rgPropVals,
MAPIAllocateBuffer,
&lpProps);
if(FAILED(hr))
{
goto cleanup;
}
}
//
// Default any missing properties.
//
lpPropT = LpValFindProp(PR_NDR_REASON_CODE, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_NDR_REASON_CODE))
{
rgProps[i ].ulPropTag = PR_NDR_REASON_CODE;
rgProps[i++].Value.l = 0;
}
lpPropT = LpValFindProp(PR_NDR_DIAG_CODE, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_NDR_DIAG_CODE))
{
rgProps[i ].ulPropTag = PR_NDR_DIAG_CODE;
rgProps[i++].Value.l = -1;
}
lpPropT = LpValFindProp(PR_REPORT_TIME, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_REPORT_TIME))
{
GetSystemTimeAsFileTime( &ftReportTime);
rgProps[i ].ulPropTag = PR_REPORT_TIME;
rgProps[i++].Value.ft = ftReportTime;
}
lpPropT = LpValFindProp(PR_REPORT_TEXT, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_REPORT_TEXT))
{
rgProps[i ].ulPropTag = PR_REPORT_TEXT;
rgProps[i++].Value.LPSZ = TEXT(" ");
}
lpPropT = LpValFindProp(PR_RECIPIENT_NUMBER, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_RECIPIENT_NUMBER))
{
rgProps[i ].ulPropTag = PR_RECIPIENT_NUMBER;
rgProps[i++].Value.l = 1;
}
lpPropT = LpValFindProp(
PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED))
{
rgProps[i ].ulPropTag = PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED;
rgProps[i++].Value.b = TRUE;
}
lpPropT = LpValFindProp(
PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED))
{
rgProps[i ].ulPropTag = PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED;
rgProps[i++].Value.b = FALSE;
}
lpPropT = LpValFindProp(
PR_READ_RECEIPT_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_READ_RECEIPT_REQUESTED))
{
rgProps[i ].ulPropTag = PR_READ_RECEIPT_REQUESTED;
rgProps[i++].Value.b = FALSE;
}
lpPropT = LpValFindProp(
PR_NON_RECEIPT_NOTIFICATION_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_NON_RECEIPT_NOTIFICATION_REQUESTED))
{
rgProps[i ].ulPropTag = PR_NON_RECEIPT_NOTIFICATION_REQUESTED;
rgProps[i++].Value.b = FALSE;
}
if(i > 0)
{
hr = HrMAPIAppendSPropValues(
cValues,
lpProps,
i,
rgProps,
&cNewValues,
&lpNewProps);
MAPIFREEBUFFER(lpProps);
if(FAILED(hr))
{
goto cleanup;
}
*lpcFailedProps = cNewValues;
*lppFailedProps = lpNewProps;
}
else
{
*lpcFailedProps = cValues;
*lppFailedProps = lpProps;
}
cleanup:
if(FAILED(hr))
{
MAPIFREEBUFFER(lpProps);
MAPIFREEBUFFER(lpNewProps);
*lpcFailedProps = 0;
*lppFailedProps = NULL;
}
RETURN(hr);
}
//$--HrAddToRecipList-----------------------------------------------------------
//
// Add a recipient entry to the list of recipients.
//
// -----------------------------------------------------------------------------
static HRESULT HrAddToRecipList( // RETURNS: return code
IN ULONG cProps, // count of properties
IN LPSPropValue lpProps, // properties
IN OUT LPADRLIST* lppAdrList) // address list
{
HRESULT hr = NOERROR;
SCODE sc = 0;
ULONG cOldEntries = 0;
ULONG cEntries = 0;
ULONG cBytes = 0;
ULONG i = 0;
LPADRENTRY lpAdrEntry = NULL;
LPADRLIST lpAdrList = NULL;
DEBUGPRIVATE("HrAddToRecipList()\n");
cEntries = (*lppAdrList)->cEntries;
cOldEntries = cEntries;
//
// Grow the address list if necessary.
//
if((cEntries == CENTRIES_FIRST) ||
((cEntries > CENTRIES_FIRST) &&
(((cEntries - CENTRIES_FIRST) % CENTRIES_NEXT) == 0)))
{
cEntries += CENTRIES_NEXT;
cBytes = CbNewADRLIST(cEntries);
sc = MAPIAllocateBuffer(cBytes, (void **)&lpAdrList);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
ZeroMemory(lpAdrList, cBytes);
lpAdrEntry = lpAdrList->aEntries;
//
// Copy existing address entries to the new address list.
//
for(i = 0; i < (*lppAdrList)->cEntries; i++)
{
lpAdrEntry[i].cValues =
(*lppAdrList)->aEntries[i].cValues;
lpAdrEntry[i].rgPropVals =
(*lppAdrList)->aEntries[i].rgPropVals;
}
MAPIFREEBUFFER(*lppAdrList);
*lppAdrList = lpAdrList;
}
//
// Add an address entry to the address list.
//
i = cOldEntries;
(*lppAdrList)->cEntries = ++i;
i--;
hr = HrMAPISetAddressList(
i,
cProps,
lpProps,
*lppAdrList);
if(FAILED(hr))
{
goto cleanup;
}
cleanup:
RETURN(hr);
}
//$--HrNDRAddToFailedRecipList--------------------------------------------------
//
// Add a recipient entry to the list of failed recipients.
//
// -----------------------------------------------------------------------------
HRESULT HrNDRAddToFailedRecipList( // RETURNS: return code
IN ULONG cFailedProps, // count of failed properties
IN LPSPropValue lpFailedProps, // failed properties
IN OUT LPADRLIST* lppAdrList) // address list
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrNDRAddToFailedRecipList()\n");
hr = HrAddToRecipList(cFailedProps, lpFailedProps, lppAdrList);
RETURN(hr);
}
//$--HrExtractProps-------------------------------------------------------------
//
// Get NDR/DR properties from the original message.
//
// -----------------------------------------------------------------------------
static HRESULT HrExtractProps( // RETURNS: return code
IN BOOL IsNdr, // report is an NDR, otherwise a DR
IN LPMESSAGE lpMessage, // message
OUT ULONG* lpcProps, // count of properties
OUT LPSPropValue* lppProps) // properties
{
HRESULT hr = NOERROR;
SCODE sc = 0;
ULONG cBytes = 0;
FILETIME ftSubmitTime = {0};
ULONG i = 0;
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
LPSTR lpszMessageClass = NULL;
LPSTR lpszReportMessageClass = NULL;
LPSTR lpsz = NULL;
ULONG cch = 0;
SizedSPropTagArray(18, rgMessagePropTags) =
{
18,
{
PR_MESSAGE_CLASS,
PR_SUBJECT,
PR_NORMALIZED_SUBJECT,
PR_SUBJECT_PREFIX,
PR_CLIENT_SUBMIT_TIME,
PR_MTS_ID,
PR_SENDER_NAME,
PR_SENDER_ENTRYID,
PR_DELETE_AFTER_SUBMIT,
PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED,
PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED,
PR_READ_RECEIPT_REQUESTED,
PR_NON_RECEIPT_NOTIFICATION_REQUESTED,
PR_CONTENT_RETURN_REQUESTED,
PR_PRIORITY,
PR_IMPORTANCE,
PR_REPORT_NAME,
PR_REPORT_ENTRYID
}
};
DEBUGPRIVATE("HrExtractProps()\n");
//
// Get report properties from the message.
//
hr = MAPICALL(lpMessage)->GetProps(
lpMessage,
(LPSPropTagArray)&rgMessagePropTags,
fMapiUnicode,
&cValues,
&lpProps);
if(FAILED(hr))
{
lpProps = NULL;
goto cleanup;
}
//
// Create report message class
//
if(lpProps[0].ulPropTag == PR_MESSAGE_CLASS)
{
lpszMessageClass = lpProps[0].Value.LPSZ;
}
if(lpszMessageClass == NULL)
{
cch = 0;
}
else
{
cch = lstrlen(lpszMessageClass);
}
if(cch == 0)
{
lpszMessageClass = TEXT("IPM.NOTE");
cch = lstrlen(lpszMessageClass);
}
cch += lstrlen(TEXT("REPORT."));
if(IsNdr == TRUE)
{
cch += lstrlen(TEXT(".NDR"));
}
else
{
cch += lstrlen(TEXT(".DR"));
}
cch++; // terminating NULL character
cBytes = cch * sizeof(CHAR);
sc = MAPIAllocateMore(cBytes, lpProps, &lpszReportMessageClass);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(lpszReportMessageClass, TEXT("REPORT."));
lstrcat(lpszReportMessageClass, lpszMessageClass);
if(IsNdr == TRUE)
{
lstrcat(lpszReportMessageClass, TEXT(".NDR"));
}
else
{
lstrcat(lpszReportMessageClass, TEXT(".DR"));
}
//
// PR_MESSAGE_CLASS
//
lpProps[0].ulPropTag = PR_MESSAGE_CLASS;
lpProps[0].Value.LPSZ = lpszReportMessageClass;
//
// PR_SUBJECT
//
if(lpProps[1].ulPropTag != PR_SUBJECT)
{
cBytes = cbStrLen("");
sc = MAPIAllocateMore(cBytes, lpProps, &lpsz);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(lpsz, TEXT(""));
lpProps[1].ulPropTag = PR_SUBJECT;
lpProps[1].Value.LPSZ = lpsz;
}
//
// PR_NORMALIZED_SUBJECT
//
if(lpProps[2].ulPropTag != PR_NORMALIZED_SUBJECT)
{
cBytes = cbStrLen("");
sc = MAPIAllocateMore(cBytes, lpProps, &lpsz);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(lpsz, TEXT(""));
lpProps[2].ulPropTag = PR_NORMALIZED_SUBJECT;
lpProps[2].Value.LPSZ = lpsz;
}
//
// PR_SUBJECT_PREFIX
//
if(lpProps[3].ulPropTag != PR_SUBJECT_PREFIX)
{
cBytes = cbStrLen("");
sc = MAPIAllocateMore(cBytes, lpProps, &lpsz);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(lpsz, TEXT(""));
lpProps[3].ulPropTag = PR_SUBJECT_PREFIX;
lpProps[3].Value.LPSZ = lpsz;
}
//
// PR_CLIENT_SUBMIT_TIME
//
if(lpProps[4].ulPropTag != PR_CLIENT_SUBMIT_TIME)
{
GetSystemTimeAsFileTime( &ftSubmitTime);
lpProps[4].ulPropTag = PR_CLIENT_SUBMIT_TIME;
lpProps[4].Value.ft = ftSubmitTime;
}
//
// PR_MTS_SUBJECT_ID
//
if(lpProps[5].ulPropTag != PR_MTS_ID)
{
cBytes = cbStrLen(SZ_MTS_ID);
sc = MAPIAllocateMore(cBytes, lpProps, &lpsz);
if(FAILED(sc))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}
lstrcpy(lpsz, TEXT(SZ_MTS_ID));
lpProps[5].ulPropTag = PR_MTS_ID;
lpProps[5].Value.bin.cb = cBytes;
lpProps[5].Value.bin.lpb = (LPBYTE) lpsz;
}
lpProps[5].ulPropTag = PR_MTS_SUBJECT_ID;
if((lpProps[16].ulPropTag == PR_REPORT_NAME) &&
(lpProps[17].ulPropTag == PR_REPORT_ENTRYID))
{
lpProps[6].ulPropTag = PR_SENDER_NAME;
lpProps[6].Value.LPSZ = lpProps[16].Value.LPSZ;
lpProps[7].ulPropTag = PR_SENDER_ENTRYID;
lpProps[7].Value.bin.cb = lpProps[17].Value.bin.cb;
lpProps[7].Value.bin.lpb = lpProps[17].Value.bin.lpb;
}
//
// PR_REPORT_DESTINATION_NAME
//
if(lpProps[6].ulPropTag != PR_SENDER_NAME)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lpProps[6].ulPropTag = PR_REPORT_DESTINATION_NAME;
//
// PR_REPORT_DESTINATION_ENTRYID
//
if(lpProps[7].ulPropTag != PR_SENDER_ENTRYID)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
lpProps[7].ulPropTag = PR_REPORT_DESTINATION_ENTRYID;
//
// PR_DELETE_AFTER_SUBMIT
//
lpProps[8].ulPropTag = PR_DELETE_AFTER_SUBMIT;
lpProps[8].Value.b = TRUE;
//
// PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED
//
if(lpProps[9].ulPropTag != PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED)
{
lpProps[9].ulPropTag = PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED;
lpProps[9].Value.b = TRUE;
}
//
// PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED
//
if(lpProps[10].ulPropTag != PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED)
{
lpProps[10].ulPropTag = PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED;
lpProps[10].Value.b = FALSE;
}
//
// PR_READ_RECEIPT_REQUESTED
//
if(lpProps[11].ulPropTag != PR_READ_RECEIPT_REQUESTED)
{
lpProps[11].ulPropTag = PR_READ_RECEIPT_REQUESTED;
lpProps[11].Value.b = FALSE;
}
//
// PR_NON_RECEIPT_NOTIFICATION_REQUESTED
//
if(lpProps[12].ulPropTag != PR_NON_RECEIPT_NOTIFICATION_REQUESTED)
{
lpProps[12].ulPropTag = PR_NON_RECEIPT_NOTIFICATION_REQUESTED;
lpProps[12].Value.b = FALSE;
}
//
// PR_CONTENT_RETURN_REQUESTED
//
if(lpProps[13].ulPropTag != PR_CONTENT_RETURN_REQUESTED)
{
lpProps[13].ulPropTag = PR_CONTENT_RETURN_REQUESTED;
lpProps[13].Value.b = TRUE;
}
//
// PR_PRIORITY
//
if(lpProps[14].ulPropTag != PR_PRIORITY)
{
lpProps[14].ulPropTag = PR_PRIORITY;
lpProps[14].Value.l = PRIO_NORMAL;
}
//
// PR_IMPORTANCE
//
if(lpProps[15].ulPropTag != PR_IMPORTANCE)
{
lpProps[15].ulPropTag = PR_IMPORTANCE;
lpProps[15].Value.l = IMPORTANCE_NORMAL;
}
*lpcProps = cValues - 2;
*lppProps = lpProps;
cleanup:
if(FAILED(hr))
{
MAPIFREEBUFFER(lpProps);
*lpcProps = 0;
*lppProps = NULL;
}
RETURN(hr);
}
//$--HrNDRGetFailedProps----------------------------------------------------------
//
// Get NDR properties from the original message.
//
// -----------------------------------------------------------------------------
HRESULT HrNDRGetFailedProps( // RETURNS: return code
IN LPMESSAGE lpMessage, // message
OUT ULONG* lpcProps, // count of properties
OUT LPSPropValue* lppProps) // properties
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrNDRGetFailedProps()\n");
hr = HrExtractProps(TRUE, lpMessage, lpcProps, lppProps);
RETURN(hr);
}
//$--HrXDRCreate----------------------------------------------------------------
//
// Create a non-delivery or delivery report.
//
// -----------------------------------------------------------------------------
static HRESULT HrXDRCreate( // RETURNS: return code
IN LPADRBOOK lpAdrBook, // address book
IN LPMAPIFOLDER lpFolder, // folder
IN LPMESSAGE lpMessage, // message
IN LPADRLIST lpAdrList, // address list
IN ULONG cProps, // count of properties
IN LPSPropValue lpProps, // properties
OUT LPMESSAGE* lppReport) // report
{
HRESULT hr = NOERROR;
LPMESSAGE lpReport = NULL;
ULONG ulAttachmentNum = 0;
LPATTACH lpAttach = NULL;
LPMESSAGE lpContent = NULL;
BOOL fReturnContent = FALSE;
SPropValue rgProps[1] = {0};
LPSPropValue lpPropT = NULL;
DEBUGPRIVATE("HrXDRCreate()\n");
*lppReport = NULL;
//
// Create a message
//
hr = MAPICALL(lpFolder)->CreateMessage(
lpFolder,
NULL,
MAPI_DEFERRED_ERRORS,
&lpReport);
if(FAILED(hr))
{
goto cleanup;
}
//
// Return content if available and requested.
//
lpPropT = LpValFindProp(
PR_CONTENT_RETURN_REQUESTED, cProps, lpProps);
if(lpPropT == NULL)
{
fReturnContent = TRUE;
}
else if(lpPropT->ulPropTag != PR_CONTENT_RETURN_REQUESTED)
{
lpPropT->ulPropTag = PR_CONTENT_RETURN_REQUESTED;
lpPropT->Value.b = TRUE;
}
else
{
fReturnContent = lpPropT->Value.b;
}
if((lpMessage != NULL) && (fReturnContent == TRUE))
{
//
// Create an embedded message
//
hr = MAPICALL(lpReport)->CreateAttach(
lpReport,
NULL,
(ULONG)0,
&ulAttachmentNum,
&lpAttach);
if(FAILED(hr))
{
goto cleanup;
}
rgProps[0].ulPropTag = PR_ATTACH_METHOD;
rgProps[0].Value.ul = ATTACH_EMBEDDED_MSG;
hr = MAPICALL(lpAttach)->SetProps(
lpAttach,
1,
rgProps,
NULL);
if(FAILED(hr))
{
goto cleanup;
}
hr = MAPICALL(lpAttach)->OpenProperty(
lpAttach,
PR_ATTACH_DATA_OBJ,
(LPIID)&IID_IMessage,
0,
MAPI_CREATE|MAPI_MODIFY|MAPI_DEFERRED_ERRORS,
(LPUNKNOWN *)&lpContent);
if(FAILED(hr))
{
goto cleanup;
}
}
if(lpAdrList != NULL)
{
hr = MAPICALL(lpReport)->ModifyRecipients(
lpReport,
0,
lpAdrList);
if(FAILED(hr))
{
goto cleanup;
}
}
//
// Set envelope properties
//
if((cProps > 0) && (lpProps != NULL))
{
hr = MAPICALL(lpReport)->SetProps(
lpReport,
cProps,
lpProps,
NULL);
if(FAILED(hr))
{
goto cleanup;
}
}
if((lpMessage != NULL) && (fReturnContent == TRUE))
{
hr = MAPICALL(lpMessage)->CopyTo(
lpMessage,
0,
NULL,
NULL,
0,
NULL,
(LPIID)&IID_IMessage,
lpContent,
0,
NULL);
if(FAILED(hr))
{
goto cleanup;
}
if(hr == MAPI_W_ERRORS_RETURNED)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}
hr = MAPICALL(lpContent)->SaveChanges(lpContent, KEEP_OPEN_READWRITE);
if(FAILED(hr))
{
goto cleanup;
}
hr = MAPICALL(lpAttach)->SaveChanges(lpAttach, KEEP_OPEN_READWRITE);
if(FAILED(hr))
{
goto cleanup;
}
}
hr = MAPICALL(lpReport)->SaveChanges(lpReport, KEEP_OPEN_READWRITE);
if(FAILED(hr))
{
goto cleanup;
}
*lppReport = lpReport;
cleanup:
ULRELEASE(lpContent);
ULRELEASE(lpAttach);
if(FAILED(hr))
{
ULRELEASE(lpReport);
*lppReport = NULL;
}
RETURN(hr);
}
//$--HrNDRCreate----------------------------------------------------------------
//
// Create a non-delivery report.
//
// -----------------------------------------------------------------------------
HRESULT HrNDRCreate( // RETURNS: return code
IN LPADRBOOK lpAdrBook, // address book
IN LPMAPIFOLDER lpFolder, // folder
IN LPMESSAGE lpMessage, // message
IN LPADRLIST lpAdrList, // address list
IN ULONG cProps, // count of properties
IN LPSPropValue lpProps, // properties
OUT LPMESSAGE* lppReport) // report
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrNDRCreate()\n");
hr = HrXDRCreate(
lpAdrBook,
lpFolder,
lpMessage,
lpAdrList,
cProps,
lpProps,
lppReport);
RETURN(hr);
}
//$--HrDRCreateDeliveredRecipList-----------------------------------------------
//
// Create an empty list of delivered recipients.
//
// -----------------------------------------------------------------------------
HRESULT HrDRCreateDeliveredRecipList( // RETURNS: return code
OUT LPADRLIST* lppAdrList) // address list
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrDRCreateDeliveredRecipList()\n");
hr = HrCreateEmptyRecipList(lppAdrList);
RETURN(hr);
}
//$--HrDRGetDeliveredRecip--------------------------------------------------
//
// Create a delivered recipient entry.
//
// -----------------------------------------------------------------------------
HRESULT HrDRGetDeliveredRecip( // RETURNS: return code
IN LPADRENTRY lpAdrEntry, // address entry
IN ULONG cExtraProps, // count of extra properties
IN LPSPropValue lpExtraProps, // extra properties
OUT ULONG* lpcDeliveredProps, // count of delivered properties
OUT LPSPropValue* lppDeliveredProps) // delivered properties
{
HRESULT hr = NOERROR;
FILETIME ftReportTime = {0};
FILETIME ftDeliverTime = {0};
ULONG i = 0;
SPropValue rgProps[9] = {0};
ULONG cValues = 0;
LPSPropValue lpProps = NULL;
ULONG cNewValues = 0;
LPSPropValue lpNewProps = NULL;
LPSPropValue lpPropT = NULL;
DEBUGPUBLIC("HrDRGetDeliveredRecip()\n");
if((cExtraProps > 0) && (lpExtraProps != NULL))
{
hr = HrMAPIAppendSPropValues(
lpAdrEntry->cValues,
lpAdrEntry->rgPropVals,
cExtraProps,
lpExtraProps,
&cValues,
&lpProps);
if(FAILED(hr))
{
goto cleanup;
}
}
else
{
cValues = lpAdrEntry->cValues;
hr = ScDupPropset(
lpAdrEntry->cValues,
lpAdrEntry->rgPropVals,
MAPIAllocateBuffer,
&lpProps);
if(FAILED(hr))
{
goto cleanup;
}
}
//
// Default any missing properties.
//
lpPropT = LpValFindProp(PR_REPORT_TIME, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_REPORT_TIME))
{
GetSystemTimeAsFileTime( &ftReportTime);
rgProps[i ].ulPropTag = PR_REPORT_TIME;
rgProps[i++].Value.ft = ftReportTime;
}
lpPropT = LpValFindProp(PR_REPORT_TEXT, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_REPORT_TEXT))
{
rgProps[i ].ulPropTag = PR_REPORT_TEXT;
rgProps[i++].Value.LPSZ = TEXT(" ");
}
lpPropT = LpValFindProp(PR_DELIVER_TIME, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_DELIVER_TIME))
{
GetSystemTimeAsFileTime( &ftDeliverTime);
rgProps[i ].ulPropTag = PR_DELIVER_TIME;
rgProps[i++].Value.ft = ftDeliverTime;
}
lpPropT = LpValFindProp(PR_REPORT_TEXT, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_REPORT_TEXT))
{
rgProps[i ].ulPropTag = PR_REPORT_TEXT;
rgProps[i++].Value.LPSZ = TEXT(" ");
}
lpPropT = LpValFindProp(PR_RECIPIENT_NUMBER, cValues, lpProps);
if((lpPropT == NULL) || (lpPropT->ulPropTag != PR_RECIPIENT_NUMBER))
{
rgProps[i ].ulPropTag = PR_RECIPIENT_NUMBER;
rgProps[i++].Value.l = 1;
}
lpPropT = LpValFindProp(
PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED))
{
rgProps[i ].ulPropTag = PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED;
rgProps[i++].Value.b = TRUE;
}
lpPropT = LpValFindProp(
PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED))
{
rgProps[i ].ulPropTag = PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED;
rgProps[i++].Value.b = FALSE;
}
lpPropT = LpValFindProp(
PR_READ_RECEIPT_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_READ_RECEIPT_REQUESTED))
{
rgProps[i ].ulPropTag = PR_READ_RECEIPT_REQUESTED;
rgProps[i++].Value.b = FALSE;
}
lpPropT = LpValFindProp(
PR_NON_RECEIPT_NOTIFICATION_REQUESTED, cValues, lpProps);
if((lpPropT == NULL) ||
(lpPropT->ulPropTag != PR_NON_RECEIPT_NOTIFICATION_REQUESTED))
{
rgProps[i ].ulPropTag = PR_NON_RECEIPT_NOTIFICATION_REQUESTED;
rgProps[i++].Value.b = FALSE;
}
if(i > 0)
{
hr = HrMAPIAppendSPropValues(
cValues,
lpProps,
i,
rgProps,
&cNewValues,
&lpNewProps);
MAPIFREEBUFFER(lpProps);
if(FAILED(hr))
{
goto cleanup;
}
*lpcDeliveredProps = cNewValues;
*lppDeliveredProps = lpNewProps;
}
else
{
*lpcDeliveredProps = cValues;
*lppDeliveredProps = lpProps;
}
cleanup:
if(FAILED(hr))
{
MAPIFREEBUFFER(lpProps);
MAPIFREEBUFFER(lpNewProps);
*lpcDeliveredProps = 0;
*lppDeliveredProps = NULL;
}
RETURN(hr);
}
//$--HrDRAddToDeliveredRecipList------------------------------------------------
//
// Add a recipient entry to the list of delivered recipients.
//
// -----------------------------------------------------------------------------
HRESULT HrDRAddToDeliveredRecipList( // RETURNS: return code
IN ULONG cDeliveredProps, // count of delivered properties
IN LPSPropValue lpDeliveredProps, // delivered properties
IN OUT LPADRLIST* lppAdrList) // address list
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrDRAddToDeliveredRecipList()\n");
hr = HrAddToRecipList(cDeliveredProps, lpDeliveredProps, lppAdrList);
RETURN(hr);
}
//$--HrDRGetProps-----------------------------------------------------------
//
// Get DR properties from the original message.
//
// -----------------------------------------------------------------------------
HRESULT HrDRGetProps( // RETURNS: return code
IN LPMESSAGE lpMessage, // message
OUT ULONG* lpcProps, // count of properties
OUT LPSPropValue* lppProps) // properties
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrDRGetProps()\n");
hr = HrExtractProps(FALSE, lpMessage, lpcProps, lppProps);
RETURN(hr);
}
//$--HrDRCreate-----------------------------------------------------------------
//
// Create a delivery report.
//
// -----------------------------------------------------------------------------
HRESULT HrDRCreate( // RETURNS: return code
IN LPADRBOOK lpAdrBook, // address book
IN LPMAPIFOLDER lpFolder, // folder
IN LPMESSAGE lpMessage, // message
IN LPADRLIST lpAdrList, // address list
IN ULONG cProps, // count of properties
IN LPSPropValue lpProps, // properties
OUT LPMESSAGE* lppReport) // report
{
HRESULT hr = NOERROR;
DEBUGPUBLIC("HrDRCreate()\n");
hr = HrXDRCreate(
lpAdrBook,
lpFolder,
lpMessage,
lpAdrList,
cProps,
lpProps,
lppReport);
RETURN(hr);
}