cpgpexchattachedfileevents.cpp

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

CPP
1,252
字号
/*____________________________________________________________________________
	Copyright 2002 PGP Corporation
	All rights reserved.

	$Id: CPGPexchAttachedFileEvents.cpp,v 1.37 2002/11/19 02:19:38 sdas Exp $
____________________________________________________________________________*/
#include "CPGPexch.h"
#include <shlwapi.h>
#include "Globals.h"
#include "Utils.h"
#include "resource.h"

#include "EncryptSign.h"
#include "DecryptVerify.h"
#include "PGPsc.h"

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

typedef struct _ExchWipeList ExchWipeList;
struct _ExchWipeList
{
	char *szFile;
	ExchWipeList *pNext;
};


STDMETHODIMP CPGPexch::OnReadPattFromSzFile(IAttach* lpAtt, 
											LPTSTR lpszFile, 
											ULONG ulFlags)
{
	if (!lpszFile)
		return S_FALSE;

	_bHaveAttachments = TRUE;
	return S_FALSE;
}


STDMETHODIMP CPGPexch::OnWritePattToSzFile(IAttach* lpAtt, 
										   LPTSTR lpszFile, 
										   ULONG ulFlags)
{
	char *szExtension;
	char *szOutFile = NULL;
	HKEY hKey;
	char szDrive[_MAX_DRIVE];
	char szDir[_MAX_DIR];
	char szName[_MAX_FNAME];
	char szExt[_MAX_EXT];

	_bDecryptAttach = FALSE;

	if (!lpszFile)
		return S_FALSE;

	if (_context != EECONTEXT_READNOTEMESSAGE)
		return S_FALSE;

	szExtension = strrchr(lpszFile, '.');
	if (!szExtension)
		return S_FALSE;
	if (stricmp(szExtension, ".asc") && stricmp(szExtension, ".pgp"))
		return S_FALSE;

	if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szExtension, 0, KEY_QUERY_VALUE, &hKey)
		== ERROR_SUCCESS)
	{
		char szDescription[1024];
		DWORD dwSize = sizeof(szDescription);

		RegQueryValueEx(hKey, NULL, NULL, NULL, (PBYTE) szDescription, &dwSize);
		szDescription[dwSize] = 0;
		RegCloseKey(hKey);

		strcat(szDescription, "\\shell\\open\\command");
		if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szDescription, 0, KEY_QUERY_VALUE,
			&hKey) == ERROR_SUCCESS)
		{
			char szPath[_MAX_PATH];
			DWORD dwPathSize = sizeof(szDescription);
			
			RegQueryValueEx(hKey, NULL, NULL, NULL, (PBYTE) szPath, &dwPathSize);
			szPath[dwPathSize] = 0;
			RegCloseKey(hKey);

			_splitpath(szPath, szDrive, szDir, szName, szExt);
			if (stricmp(szName, "pgpmail") && stricmp(szName, "pgptray"))
				return S_FALSE;
		}
	}

	_bDecryptAttach = TRUE;
	return S_FALSE;
}


STDMETHODIMP CPGPexch::QueryDisallowOpenPatt(IAttach* lpAtt)
{
	return S_FALSE;
}


STDMETHODIMP CPGPexch::OnOpenPatt(IAttach* lpAtt)
{
	return S_FALSE;
}


STDMETHODIMP CPGPexch::OnOpenSzFile(LPTSTR lpszFile, ULONG ulFlags)
{
	char *szOutFile = NULL;
	HRESULT hr;

	if (lpszFile == NULL)
		return S_FALSE;

	if (!_bDecryptAttach)
		return S_FALSE;

	hr = OpenSavePGPAttachment(lpszFile, &szOutFile);
	
	if (szOutFile == NULL)
		return hr;

	AddToWipeList(szOutFile);
	ShellExecute(NULL, "open", szOutFile, NULL, "c:\\", SW_SHOWDEFAULT);
	PGPFreeData(szOutFile);
	return S_OK;
}


HRESULT CPGPexch::OpenSavePGPAttachment(LPTSTR lpszFile, char **pszOutFile)
{
	char *szExtension;
	char *szOutFile = NULL;
	int nError;
	char szName[256];
	char szFile[1024];
	BOOL bDummy;

	*pszOutFile = NULL;

	UIGetString(szName, sizeof(szName), IDS_LOGNAME);
	UIGetString(szFile, sizeof(szFile), IDS_DLL);

	nError = DecryptVerifyFile(UIGetInstance(), NULL, _pgpContext, 
				_tlsContext, lpszFile, szFile, lpszFile, FALSE, TRUE, 
				&szOutFile, NULL, NULL, &bDummy);

	if ((nError == kPGPError_NoErr) && (szOutFile != NULL))
	{
		szExtension = strrchr(szOutFile, '.');
		
		if (szExtension)
		{
			if (!stricmp(szExtension, ".exe") || !stricmp(szExtension, ".com") || 
				!stricmp(szExtension, ".bat") || !stricmp(szExtension, ".cmd"))
			{
				OPENFILENAME saveAs;
				char *szNewFile;
				char szTempFile[MAX_PATH];
				char szTempPath[MAX_PATH];
				char szTitle[256];

				szNewFile = (char *) PGPNewData(_memoryMgr, MAX_PATH, 0);
				strcpy(szNewFile, szOutFile);
				GetTempPath(MAX_PATH, szTempPath);
				GetTempFileName(szTempPath, "pgp", 0, szTempFile);
				CopyFile(szOutFile, szTempFile, FALSE);
				WipeMessageAttachment(szOutFile);

				UIGetString(szTitle, sizeof(szTitle), IDS_SAVEDECRYPTEDFILE);

				saveAs.lStructSize = sizeof(OPENFILENAME);
				saveAs.hwndOwner = NULL;
				saveAs.lpstrFilter = NULL;
				saveAs.lpstrCustomFilter = NULL;
				saveAs.nFilterIndex = 0;
				saveAs.lpstrFile = szNewFile;
				saveAs.nMaxFile = MAX_PATH;
				saveAs.lpstrFileTitle = NULL;
				saveAs.lpstrInitialDir = NULL;
				saveAs.lpstrTitle = szTitle;
				saveAs.Flags = OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT |
								OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
				saveAs.lpstrDefExt = NULL;

				if (GetSaveFileName(&saveAs))
					CopyFile(szTempFile, szNewFile, FALSE);

				WipeMessageAttachment(szTempFile);
				PGPFreeData(szNewFile);
				PGPFreeData(szOutFile);

				return E_ABORT;
			}
		}

		SetFileAttributes(szOutFile, FILE_ATTRIBUTE_READONLY);
		*pszOutFile = szOutFile;
		return S_OK;
	}

	if (szOutFile != NULL)
		PGPFreeData(szOutFile);

	return S_FALSE;
}


int CPGPexch::EncryptSignAttachment(HWND hwnd,
									IMessage *psmg,
									UINT nOutSize,
									SRowSet *prAttach,
									PGPclRecipientDialogStruct *prds,
									PGPOptionListRef *pSignOptions)
{
	ULONG ulRow = 0;
	ULONG ulNum = 0;
	SizedSPropTagArray(6, tagaAttach) = {
		6, {PR_ATTACH_METHOD, PR_ATTACH_TAG, PR_RENDERING_POSITION, 
			PR_ATTACH_FILENAME, PR_ATTACH_LONG_FILENAME, 
			PR_DISPLAY_NAME}};
	enum {ivalAttachMethod=0, ivalAttachTag, ivalRenderingPos, ivalFilename, 
			ivalLongFilename, ivalDisplayName};
	SPropValue *pval = NULL;
	SPropValue PropValArr[6] = {0};
	ULONG ulNumVals = 0;
	LPATTACH pAttach = NULL;
	IStream *pstrmAttach = NULL;
	STATSTG AttStreamStats = {0};
	DWORD dwAttSize = 0;
	UINT nAttOutSize = 0;
	char *pAttachText = NULL;
	char *pOutput = NULL;
	char *szFileName = NULL;
	char *szLongFileName = NULL;
	char *szExtension = NULL;
	int nError = 0;
	char szName[256] = {0};
	char szFile[256] = {0};
	HRESULT hrRet = S_OK;
	
	UIGetString(szName, sizeof(szName), IDS_LOGNAME);
	UIGetString(szFile, sizeof(szFile), IDS_DLL);

	//for each attachment found in the message
	for (ulRow=0; ulRow<prAttach->cRows; ulRow++)
	{
		ulNum = prAttach->aRow[ulRow].lpProps[0].Value.l;

		pgpAssert(NULL == pAttach);
		hrRet = psmg->OpenAttach(ulNum, NULL, MAPI_MODIFY, &pAttach);
		pgpAssert((S_OK == hrRet) && (NULL != pAttach));
		if((S_OK != hrRet) || (NULL == pAttach))
			goto attach_cleanup;

		pgpAssert(NULL == pval);
		hrRet = pAttach->GetProps((SPropTagArray *)&tagaAttach, 0, 
					&ulNumVals, &pval);
		pgpAssert((S_OK == hrRet) || (MAPI_W_ERRORS_RETURNED == hrRet));
		if((S_OK != hrRet) && (MAPI_W_ERRORS_RETURNED != hrRet))
			goto attach_cleanup;

		switch (pval[ivalAttachMethod].Value.l)
		{
			case ATTACH_BY_VALUE:
				// Don't sign attachments unless we're also encrypting them
				if (_bEncrypt)
				{
					pgpAssert(NULL == pstrmAttach);
					hrRet = pAttach->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, 
						STGM_READWRITE, MAPI_MODIFY, (LPUNKNOWN *) &pstrmAttach);
					pgpAssert((S_OK == hrRet) && (NULL != pstrmAttach));
					if((S_OK != hrRet) || (NULL == pstrmAttach))
						goto attach_cleanup;

					hrRet = pstrmAttach->Stat(&AttStreamStats, STATFLAG_NONAME);
					pgpAssert(S_OK == hrRet);
					if(S_OK != hrRet)
						goto attach_cleanup;

					dwAttSize = AttStreamStats.cbSize.LowPart;
					
					pgpAssert(NULL == pAttachText);
					pgpAssert(dwAttSize > 0);
					pAttachText = (char *) calloc(dwAttSize+1, sizeof(char));
					pgpAssert(NULL != pAttachText);
					if(NULL == pAttachText)
						goto attach_cleanup;

					hrRet = pstrmAttach->Read(pAttachText, dwAttSize, &dwAttSize);
					pgpAssert(S_OK == hrRet);
					if(FAILED(hrRet))
						goto attach_cleanup;

					pAttachText[dwAttSize] = 0;

					nError = EncryptSignBuffer(UIGetInstance(), hwnd, 
						_pgpContext, _tlsContext, szName, szFile,
						pAttachText, dwAttSize, prds, NULL, pSignOptions, 
						(VOID ** )&pOutput, &nAttOutSize, _bEncrypt, _bSign, 
						TRUE, FALSE, m_pExtMdlessCallBack, m_pemOurMdlessCallBack);
					
					if (!nError)
					{
						ULONG ulAttOutSize = nAttOutSize;
						LARGE_INTEGER li = {0};
						ULARGE_INTEGER uli = {ulAttOutSize, 0};
						ULONG ulWritten = 0;
						ULARGE_INTEGER uliSeek = {0};
						
						hrRet = pstrmAttach->Seek(li, STREAM_SEEK_SET, &uliSeek);
						pgpAssert(S_OK == hrRet);
						if(S_OK != hrRet)
							goto attach_cleanup;

						pgpAssert(NULL != pOutput);
						hrRet = pstrmAttach->Write(pOutput, ulAttOutSize, &ulWritten);
						pgpAssert(S_OK == hrRet);
						pgpAssert(ulAttOutSize == ulWritten);
						if((S_OK != hrRet) || (ulAttOutSize != ulWritten))
							goto attach_cleanup;

						hrRet = pstrmAttach->SetSize(uli);
						pgpAssert(S_OK == hrRet);
						if(S_OK != hrRet)
							goto attach_cleanup;

						hrRet = pstrmAttach->Commit(STGC_DEFAULT);
						pgpAssert(S_OK == hrRet);
						if(S_OK != hrRet)
							goto attach_cleanup;
					}

					if (pval[ivalRenderingPos].Value.l > -1)
						pval[ivalRenderingPos].Value.l = nOutSize + ulRow;
					
					szFileName = (char *) calloc(MAX_PATH, sizeof(char));
					pgpAssert(NULL != szFileName);
					if(NULL == szFileName)
						goto attach_cleanup;

					szLongFileName = (char *) calloc(MAX_PATH, sizeof(char));
					pgpAssert(NULL != szLongFileName);
					if(NULL == szLongFileName)
						goto attach_cleanup;

					strcpy(szFileName, pval[ivalFilename].Value.lpszA);
					strcpy(szLongFileName, pval[ivalLongFilename].Value.lpszA);

					szExtension = strrchr(szFileName, '.');
					if (NULL != szExtension)
						*szExtension = '\0';
					
					if (strlen(szFileName) + strlen(".asc") >= MAX_PATH)
					{
						char *szTrunc = strrchr(szFileName, '.');
						
						if (szTrunc)
							strcpy(szTrunc - 4, szTrunc);
						else
						{
							szTrunc = szFileName + strlen(szFileName) - 4;
							*szTrunc = 0;
						}
					}

					if (strlen(szLongFileName) + strlen(".asc") >= MAX_PATH)
					{
						char *szTrunc = strrchr(szLongFileName, '.');
						
						if (szTrunc)
							strcpy(szTrunc - 4, szTrunc);
						else
						{
							szTrunc = szLongFileName + strlen(szLongFileName) - 4;
							*szTrunc = 0;
						}
					}

					strcat(szFileName, ".asc");
					strcat(szLongFileName, ".asc");

					//copy the property values obtained
					memcpy(PropValArr, pval, sizeof(PropValArr));
					PropValArr[ivalFilename].Value.lpszA = NULL;
					PropValArr[ivalLongFilename].Value.lpszA = NULL;

					//allocate and copy the short file name to be set
					pgpAssert(PT_STRING8 == PROP_TYPE(PropValArr[ivalFilename].ulPropTag));
					pgpAssert(NULL == PropValArr[ivalFilename].Value.lpszA);

					PropValArr[ivalFilename].Value.lpszA = _strdup(szFileName);
					pgpAssert(NULL != PropValArr[ivalFilename].Value.lpszA);
					if(NULL == PropValArr[ivalFilename].Value.lpszA)
						goto attach_cleanup;

					//allocate for longfilename property
					pgpAssert(PT_STRING8 == PROP_TYPE(PropValArr[ivalLongFilename].ulPropTag));
					pgpAssert(NULL == PropValArr[ivalLongFilename].Value.lpszA);

					PropValArr[ivalLongFilename].Value.lpszA = _strdup(szLongFileName);
					pgpAssert(NULL != PropValArr[ivalLongFilename].Value.lpszA);
					if(NULL == PropValArr[ivalLongFilename].Value.lpszA)
						goto attach_cleanup;

					//if we could not get the display name property
					if(PT_ERROR == PROP_TYPE(PropValArr[ivalDisplayName].ulPropTag))
					{
						//make the display name property same as the long file name property
						//NOTE: we do not have a problem during freeing since we do not free
						//this buffer irrespective of display name being found or not. when 
						//it is found it points to the original getprops buffer otherwise it 
						//points to strduped buffer that was passed as long file name value
						PropValArr[ivalDisplayName].Value.lpszA = 

⌨️ 快捷键说明

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