recipients.cpp

来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C++ 代码 · 共 866 行 · 第 1/2 页

CPP
866
字号
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: Recipients.cpp,v 1.12 2002/11/11 21:32:19 sdas Exp $
____________________________________________________________________________*/
#include "CPGPexch.h"
#include <mapiutil.h>
#include <process.h>
#include "Globals.h"
#include "Recipients.h"
#include "Utils.h"
#include "resource.h"

#include "pgpClientPrefs.h"
#include "pgpDebug.h"
#include "pgpUtilities.h"

#ifndef PR_EMS_AB_PROXY_ADDRESSES
#define PR_EMS_AB_PROXY_ADDRESSES	PROP_TAG( PT_MV_TSTRING,    0x800F)
#endif

static void ResolveEntries(LPADRBOOK pAddrBook, LPABCONT pContainer,
						   ULONG ulNumRows, LPADRENTRY aEntries, 
						   PGPclRecipientDialogStruct *prds, 
						   DWORD *pdwNumRecip, DWORD *pdwRecipIndex);

BOOL GetSMTPAddress(ULONG ulNum, LPSTR *lppszProxy,
					PGPclRecipientDialogStruct *prds,
					DWORD *pdwRecipIndex, DWORD *pdwNumRecip,
					char *szAddress, BOOL *pbRecipAdded);


PGPError GetRecipients(IExchExtCallback *pmecb, 
					   PGPContextRef context,
					   PGPtlsContextRef tlsContext,
					   PGPclRecipientDialogStruct *prds,
					   BOOL bHasAttachments)
{
	LPADRLIST		pAddrList		= NULL;
	LPADRBOOK		pAddrBook		= NULL;
	LPABCONT		pContainer		= NULL;
	LPSRowSet		pSearch			= NULL;
	LPENTRYID		pEntryID		= NULL;
	ULONG			ulMatch			= ULONG_MAX;
	ULONG			ulObjType		= 0;
	ULONG			ulEntryID		= 0;
	ULONG			ulEntrySize		= 0;
	ULONG			ulRow			= 0;
	ULONG			ulIndex			= 0;
	ULONG			ulNumRows		= 0;
	DWORD			dwRecipIndex	= 0;
	DWORD			dwNumRecip		= 0;
	char			szTitle[256];
	HWND			hwnd			= NULL;
	BOOL			bGotRecipients	= FALSE;
	PGPPrefRef		prefs			= NULL;
	PGPBoolean		syncBefore		= FALSE;
	PGPBoolean		syncAfter		= FALSE;
	PGPError		err				= kPGPError_NoErr;

	pgpAssert(pmecb);
	pgpAssert(prds);
	pgpAssert(prds->keydbOriginal);
	pgpAssert(context != NULL);

	pmecb->GetWindow(&hwnd);
	if (!hwnd)
		hwnd = GetTopWindow(NULL);

	UIGetString(szTitle, sizeof(szTitle), IDS_RECIPIENTTITLE);

	prds->Version = kPGPCurrentRecipVersion;
	prds->hwndParent = hwnd;
	prds->szTitle = szTitle;
	prds->context = context;
	prds->tlsContext = tlsContext;
	prds->keydbSelected = NULL;
	prds->szRecipientArray = NULL;
	prds->dwOptions = kPGPclASCIIArmor;
	prds->dwFlags = 0;
	prds->dwDisableFlags =	kPGPclDisableASCIIArmor |
							kPGPclDisableWipeOriginal |
							kPGPclDisableSelfDecryptingArchive;

	if (bHasAttachments)
		prds->dwDisableFlags |= kPGPclDisableSecureViewer;
	else
		prds->dwDisableFlags |= kPGPclDisableInputIsText;

	prds->keydbAdded = NULL;

	pmecb->GetRecipients(&pAddrList);
	pmecb->GetSession(NULL, &pAddrBook);

	if (pAddrList)
	{
		SizedSPropTagArray(7, propTags) = {
			7, {PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_OBJECT_TYPE, PR_ENTRYID,
				PR_ADDRTYPE, PR_EMS_AB_PROXY_ADDRESSES, 
				PR_ORIGINAL_DISPLAY_NAME}};

		if (pAddrBook->ResolveName((ULONG) hwnd, MAPI_DIALOG, "", 
				pAddrList) != S_OK)
		{
			pAddrBook->Release();
			prds->dwNumRecipients = 0;
			err = kPGPError_UserAbort;
			goto GetRecipientsError;
		}
		
		pAddrBook->PrepareRecips(0, (LPSPropTagArray) &propTags, pAddrList);
		dwNumRecip = pAddrList->cEntries;
	}
	else
	{
		prds->dwNumRecipients = 0;
		err = kPGPError_UserAbort;
		goto GetRecipientsError;
	}
				
	pAddrBook->GetSearchPath(0, &pSearch);
	
	for (ulRow=0; ulRow<pSearch->cRows; ulRow++)
	{
		for(ulIndex=0; ulIndex<pSearch->aRow[ulRow].cValues; ulIndex++)
		{
			switch (pSearch->aRow[ulRow].lpProps[ulIndex].ulPropTag)
			{
			case PR_DISPLAY_TYPE:
				if (pSearch->aRow[ulRow].lpProps[ulIndex].Value.l == 
					DT_GLOBAL)
					ulMatch = ulRow;
				break;
				
			case PR_ENTRYID:
				ulEntrySize = pSearch->aRow[ulRow].
					lpProps[ulIndex].Value.bin.cb;
				
				pEntryID = (LPENTRYID) pSearch->aRow[ulRow].
					lpProps[ulIndex].Value.bin.lpb;
				ulEntryID = ulRow;
				break;
			}
		}
		
		if (ulMatch != ULONG_MAX)
			ulRow = pSearch->cRows;
	}
	
	if (ulMatch != ULONG_MAX)
		pAddrBook->OpenEntry(ulEntrySize, pEntryID, &IID_IABContainer,
			0, &ulObjType, (IUnknown **) &pContainer);
	
	ulNumRows = dwNumRecip;
	prds->szRecipientArray = (char **) calloc(sizeof(char *), dwNumRecip);
	
	err = PGPclPeekClientLibPrefRefs(&prefs, NULL);

	if (IsntPGPError(err))
		PGPGetPrefBoolean(prefs, kPGPPrefKeyServerSyncUnknownKeys, &syncBefore);

	ResolveEntries(pAddrBook, pContainer, ulNumRows, pAddrList->aEntries, prds, 
		&dwNumRecip, &dwRecipIndex);

	prds->dwNumRecipients = dwNumRecip;

	if (pContainer != NULL)
		pContainer->Release();

	if (pSearch != NULL)
	{
		FreeProws(pSearch);
		pSearch = NULL;
	}

	if (pAddrBook != NULL)
		pAddrBook->Release();

	// If shift is pressed, force the dialog to pop.
	if (GetAsyncKeyState( VK_SHIFT) & 0x8000)
		prds->dwDisableFlags |= kPGPclDisableAutoMode;

	bGotRecipients = PGPclRecipientDialog(prds);

	if (prds->keydbAdded != NULL)
	{
		PGPUInt32 numKeys;
		PGPKeySetRef keySet;

		PGPNewKeySet(prds->keydbAdded, &keySet);
		PGPCountKeys(keySet, &numKeys);
		if (numKeys > 0)
			PGPclImportKeys(context, tlsContext, hwnd, keySet, 
				prds->keydbOriginal, kPGPclNoDialogForValidSingletons);

		PGPFreeKeySet(keySet);
		PGPFreeKeyDB(prds->keydbAdded);
		prds->keydbAdded = NULL;
	}

	err = PGPclPeekClientLibPrefRefs(&prefs, NULL);

	if (IsntPGPError(err))
		PGPGetPrefBoolean(prefs, kPGPPrefKeyServerSyncUnknownKeys, &syncAfter);

	if (syncBefore != syncAfter)
	{
		PGPSetPrefBoolean(prefs, kPGPPrefKeyServerSyncUnknownKeys, syncBefore);
		PGPclFlushClientLibPrefs(prefs, kInvalidPGPPrefRef);
	}

	if (bGotRecipients != TRUE)
	{
		err = kPGPError_UserAbort;
		goto GetRecipientsError;
	}

	return err;

GetRecipientsError:

	FreeRecipients(prds);
	return err;
}


void FreeRecipients(PGPclRecipientDialogStruct *prds)
{
	DWORD dwIndex;

	if (prds == NULL)
		return;

	if (prds->szRecipientArray != NULL)
	{
		for (dwIndex=0; dwIndex<prds->dwNumRecipients; dwIndex++)
		{
			if ((prds->szRecipientArray)[dwIndex] != NULL)
			{
				free((prds->szRecipientArray)[dwIndex]);
				(prds->szRecipientArray)[dwIndex] = NULL;
			}
		}
		
		free(prds->szRecipientArray);
		prds->szRecipientArray = NULL;
	}

	if (prds->keydbSelected != NULL)
	{
		PGPFreeKeyDB(prds->keydbSelected);
		prds->keydbSelected = NULL;
	}
	
	return;
}


static void ResolveEntries(LPADRBOOK pAddrBook, LPABCONT pContainer,
						   ULONG ulNumRows, LPADRENTRY aEntries, 
						   PGPclRecipientDialogStruct *prds, DWORD *pdwNumRecip, 
						   DWORD *pdwRecipIndex)
{
	LPENTRYID		pEntryID		= NULL;
	ULONG			ulRow			= 0;
	ULONG			ulIndex			= 0;
	ULONG			ulEmailAddr		= 0;
	ULONG			ulDisplayName	= 0;
	ULONG			ulType			= 0;
	ULONG			ulEntryID		= 0;
	ULONG			ulAddrType		= 0;
	ULONG			ulNumProxies	= 0;
	ULONG			ulProxy			= 0;
	ULONG			ulEntrySize		= 0;
	ULONG			ulOriginalName	= 0;
	int				nChar			= 0;
	int				nRecipLength	= 0;
	char *			szRecip			= NULL;
	char *			szAddrType		= NULL;
	char			szSMTP[1024];
	char **			pszProxy		= NULL;
	BOOL			bGotSMTP		= TRUE;
	BOOL			bRecipAdded		= FALSE;
	
	for (ulRow=0; ulRow<ulNumRows; ulRow++)
	{
		ulEmailAddr		= ULONG_MAX;
		ulDisplayName	= ULONG_MAX;
		ulType			= ULONG_MAX;
		ulEntryID		= ULONG_MAX;
		ulAddrType		= ULONG_MAX;
		ulProxy			= ULONG_MAX;
		ulOriginalName	= ULONG_MAX;
		
		for (	ulIndex=0;
				ulIndex<aEntries[ulRow].cValues; 
				ulIndex++)
		{
			switch (aEntries[ulRow].rgPropVals[ulIndex].ulPropTag)
			{
			case PR_DISPLAY_NAME:
				ulDisplayName = ulIndex;
				break;
			
			case PR_ORIGINAL_DISPLAY_NAME:
				ulOriginalName = ulIndex;
				break;
			
			case PR_EMAIL_ADDRESS:
				ulEmailAddr = ulIndex;
				break;
			
			case PR_OBJECT_TYPE:
				ulType = ulIndex;
				break;

			case PR_ENTRYID:
				ulEntryID = ulIndex;
				break;

			case PR_ADDRTYPE:
				ulAddrType = ulIndex;
				break;

			case PR_EMS_AB_PROXY_ADDRESSES:
				ulProxy = ulIndex;
			}
		}

		if ((ulDisplayName == ULONG_MAX) && (ulEmailAddr == ULONG_MAX))
		{
			(*pdwNumRecip)--;
			continue;
		}
		
		if (ulEmailAddr != ULONG_MAX)
		{
			szRecip = aEntries[ulRow].rgPropVals[ulEmailAddr].Value.lpszA;

			if (szRecip)
			{
				if (strlen(szRecip))
				{
					ulIndex = ulEmailAddr;
				}
				else
					ulIndex = ulDisplayName;
			}
			else
				ulIndex = ulDisplayName;
		}
		else
			ulIndex = ulDisplayName;
		
		// Older versions of Exchange return an invalid number
		// of recipients, so we have to check each recipient
		// for validity
		
		// First, make sure there's a pointer to the recipient
		// entry
		if (!&(aEntries[ulRow]))
		{
			(*pdwNumRecip)--;
			continue;
		}
		
		// Now see if the recipient has any properties
		if (!(aEntries[ulRow].cValues) ||
			((aEntries[ulRow].cValues-1) < ulIndex))
		{
			(*pdwNumRecip)--;
			continue;
		}
		
		// Check to see if this is a distribution list. If so,
		// process it

		if (ulType != ULONG_MAX)
		{
			if (aEntries[ulRow].rgPropVals[ulType].Value.l ==
				MAPI_DISTLIST)
			{
				LPDISTLIST pDistList = NULL;
				LPMAPITABLE pTable = NULL;
				SizedSPropTagArray(7, tagaDistList) = {7, 
					{PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_ENTRYID, 
					PR_ADDRTYPE, PR_OBJECT_TYPE,
					PR_EMS_AB_PROXY_ADDRESSES, PR_ORIGINAL_DISPLAY_NAME}};
				SRowSet *pRows = NULL;
				ULONG ulObjType = 0;

				ulEntrySize = aEntries[ulRow].
								rgPropVals[ulEntryID].Value.bin.cb;
				
				pEntryID = (LPENTRYID) aEntries[ulRow].
								rgPropVals[ulEntryID].Value.bin.lpb;
				
				pAddrBook->OpenEntry(ulEntrySize, pEntryID, &IID_IDistList,
								0, &ulObjType, (IUnknown**)&pDistList);
				
				pDistList->GetContentsTable(0, &pTable);
				HrQueryAllRows(pTable, (SPropTagArray *)&tagaDistList, NULL, 
					NULL, 0, &pRows);
				
				(*pdwNumRecip) += pRows->cRows - 1;
				prds->szRecipientArray = (char **) 
											realloc(prds->szRecipientArray, 
											sizeof(char *) * (*pdwNumRecip));

				ResolveEntries(pAddrBook, pContainer, pRows->cRows, 
					(LPADRENTRY) pRows->aRow, prds, pdwNumRecip, 
					pdwRecipIndex);

				FreeProws(pRows);
				pRows = NULL;

				pTable->Release();
				pDistList->Release();
				continue;
			}
		}

		szRecip = aEntries[ulRow].rgPropVals[ulIndex].Value.lpszA;

		// Make sure e-mail address is an SMTP address. If not, try
		// to fetch the SMTP address

		bGotSMTP = FALSE;
		bRecipAdded = FALSE;
		
		if (ulAddrType != ULONG_MAX)
			szAddrType = aEntries[ulRow].

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?