📄 pgpgwtph.cpp
字号:
// to your DLL for processing. You have the ability to process
// the token and have GroupWise process it, or prevent GroupWise
// from processing, or even create new tokens to be routed through
// to GroupWise.
//
// In this example, we will demonstrate two of these concepts
// by capturing the token associated with bring up the About Dialog
// Box (Select Help | About GroupWise, from the menu).
//
// A dialog box will come up allowing you to either ignore the token
// and let GroupWise process it, or process it instead of GroupWise.
// Thus, you'll be able to see how your DLL can interact with and
// influence how GroupWise processes requests.
//
//
// Returns: The following return values are possible:
// DLL_HAN_NOT_HANDLED The token was not processed.
// DLL_HAN_NO_ERROR The token was processed. This value
// should be returned to block a token.
// DLL_HAN_NOT_FOUND The token resulted in a GroupWise "not found"
// condition.
// DLL_HAN_CANCEL The user cancelled the method.
// DLL_HAN_TOKEN_ERROR The token was not valid.
// DLL_HAN_PARM_ERROR One or more of the parameters were invalid.
//
////////////////////////////////////////////////////////////////////////////////
int WINAPI HandleToken(LPTPH_RETURNVAL lpTokenData, //received token
HWND hLinkWnd, //handle to the link window
WORD wMsg) //link window execute message.
{
LPTSTR lpReturn=NULL;//used with the Publish method
TraceHandleToken(lpTokenData, hLinkWnd, wMsg);
switch(lpTokenData->lpToken->wTokenId)
{
case BFTKN_SEND_STDMAIL://new mail item
return DLL_HAN_NOT_HANDLED;
break;
case BFTKN_READ:
/*{
HRESULT hrRet=FillTokenInfo(g_gtiLastTokenInfo, lpTokenData, hLinkWnd);
if(FAILED(hrRet))
{
pgpAssert(FALSE);//some error in getting basic information about this message
goto send_stdmail_cleanup;
}
if(FALSE == g_gtiLastTokenInfo.bIsMailMsg)
{
PgpGwTrace("Skipping one non-mail item opened.\n");
return DLL_HAN_NOT_HANDLED;//its ok for the client to go ahead and do its stuff
goto send_stdmail_cleanup;
}
else
{
//must be a new message
pgpAssert(0 == wcscmp(g_gtiLastTokenInfo.bstrMessageId, NEWMESSAGEMSGIDW));
}
send_stdmail_cleanup:
return DLL_HAN_NOT_HANDLED;
}
break;*/
return DLL_HAN_NOT_HANDLED;
break;
case BFTKN_VIEW_ATTACH:
//start watching file creation in the directory
//if(NULL == g_cadFileWatchAndDecrypt)
//{
// g_cadFileWatchAndDecrypt = new CAutoDecrypt;
// pgpAssert(NULL != g_cadFileWatchAndDecrypt);
//}
//if(NULL != g_cadFileWatchAndDecrypt)
// g_cadFileWatchAndDecrypt->Start();
return DLL_HAN_NOT_HANDLED;
break;
case BFTKN_SEND:
{
HRESULT hrRet=S_OK;
HWND hCtxtWindow=NULL;
BSTR bstrResult=NULL;
DWORD dwNoOfRecips=0;
int iHandleTokenRet=DLL_HAN_NO_ERROR;
char szTokenBuf[200]={0};
int iPlainTxtMsgLen=0;
BOOL bSkip = FALSE, bEncrypt=FALSE, bSign=FALSE;
int iNoOfAtchMents=0, iAtchMentInd=0, iAtchMentType=0;
//PGP structs
PGPclRecipientDialogStruct *prdsRecipDlgStruct=NULL;
PGPError pgpErrRet=kPGPError_NoErr;
PGPtlsContextRef tlsContext=NULL;
PGPOptionListRef polOptions=NULL;
PGPSize pgpsBufOutLen=0;
PGPUInt32 pgpuiNumOfKeys=0;
PGPKeySetRef pgpksrKeySet=NULL;
char *pOutBuf=NULL;
char *pFinalBuf=NULL;
char *pAnsiInputBuf=NULL;
char *pszTitle=NULL;
char **ppszRecipients=NULL;
PMSGINFO lpMsgInfo=NULL;
int iRet=0;
DWORD dwRet=0;
BOOL bRet=TRUE;
BOOL bAbort=FALSE;
//check if we have expired. just abort silently - since the user would
//have already got a popup for expiry at the point of first check
if(TRUE == g_bPlugInExpired)
{
PgpGwTrace("Skipping one item since we are not licensed.\n");
iHandleTokenRet=DLL_HAN_NOT_HANDLED;
goto send_cleanup;
}
hrRet=FillTokenInfo(g_gtiLastTokenInfo, lpTokenData, hLinkWnd);
if(FAILED(hrRet))
{
pgpAssert(FALSE);//some error in getting basic information about this message
DisplayMessage(GetActiveWindow(), IDS_E_FATAL);
goto send_cleanup;
}
if(FALSE == g_gtiLastTokenInfo.bIsMailMsg)
{
PgpGwTrace("Skipping one non-mail item sent.\n");
iHandleTokenRet=DLL_HAN_NOT_HANDLED;//its ok for the client to go ahead and do its stuff
goto send_cleanup;
}
//get the current mail window handle
hCtxtWindow=GetWindow(GWO_CURRENTMAIL_WINDOW);
pgpAssert(NULL != hCtxtWindow);
if(NULL == hCtxtWindow)
{
hrRet=E_FAIL;
DisplayMessage(GetActiveWindow(), IDS_E_CURRENT_MAILWND_NOT_FOUND);
goto send_cleanup;
}
//the hash must have been setup already
pgpAssert(NULL != g_pccihCmdHash);
if(NULL == g_pccihCmdHash)
{
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_FATAL);
goto send_cleanup;
}
//get the context info on this message
lpMsgInfo=g_pccihCmdHash->Get((ULONG)hCtxtWindow);
pgpAssert(NULL != lpMsgInfo);
if(NULL == lpMsgInfo)
{
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_INTERNAL);
goto send_cleanup;
}
//check the options set for this message
g_pccihCmdHash->Lock();
bSkip=((lpMsgInfo->dwState)&MIS_SKIP_OPERATION)?TRUE:FALSE;//discussion notes are skipped
bEncrypt=((lpMsgInfo->dwState)&MIS_AUTO_ENCRYPT_ON_SEND)?TRUE:FALSE;
bSign=((lpMsgInfo->dwState)&MIS_AUTO_SIGN_ON_SEND)?TRUE:FALSE;
g_pccihCmdHash->UnLock();
//if we are to skip or being told to do neither encrypt nor sign
if((TRUE == bSkip) || ((FALSE == bEncrypt) && (FALSE == bSign)))
{
iHandleTokenRet=DLL_HAN_NOT_HANDLED;//let the client do its stuff
goto send_cleanup;
}
//check if the user has the appropriate license to run us. she must have
//a desktop license or enterprise license to run groupwise plugin
if(FALSE == PgpGwExLicenseChk())
goto send_cleanup;
//check if there is any attachments in the mail
ZeroMemory(szTokenBuf, sizeof(szTokenBuf));
sprintf(szTokenBuf, "ItemAttachmentGetCount(\"%S\")",
g_gtiLastTokenInfo.bstrMessageId);
hrRet=Publish(szTokenBuf, &bstrResult);
if(FAILED(hrRet))
{
pgpAssert(FALSE);
DisplayMessage(hCtxtWindow, IDS_E_ATT_OPERATION);
goto send_cleanup;
}
//convert the attachment count string returned to number
iNoOfAtchMents=wcstol(bstrResult, L'\0', 10);
pgpAssert((LONG_MAX != iNoOfAtchMents) && (LONG_MIN != iNoOfAtchMents));
//for each attachment of the mail
for(iAtchMentInd=iNoOfAtchMents-1; iAtchMentInd >= 0; iAtchMentInd--)
{
//check what type of attachment it is
ZeroMemory(szTokenBuf, sizeof(szTokenBuf));
sprintf(szTokenBuf, "ItemAttachmentGetClass(\"%S\";%d)",
g_gtiLastTokenInfo.bstrMessageId, iAtchMentInd);
hrRet=Publish(szTokenBuf, &bstrResult);
if(FAILED(hrRet))
{
pgpAssert(FALSE);
DisplayMessage(hCtxtWindow, IDS_E_ATT_OPERATION);
goto send_cleanup;
}
iAtchMentType=wcstol(bstrResult, L'\0', 10);
pgpAssert((LONG_MAX != iAtchMentType) && (LONG_MIN != iAtchMentType));
if(egwFile != iAtchMentType)//if it is not a file attachment
{
hrRet=E_FAIL;
//we do not support encryption of ole and other type of attachments
//there is no documented way to do this. ItemAttachmentUpdate() fails
//with E_FAIL for any attachment other than attached files. When the
//NDK supports other types this code may be changed to cover them. Or
//there might be a hack to do this :) We give a message and bail out.
DisplayMessage(hCtxtWindow, IDS_E_CANTHANDLEATTS);
goto send_cleanup;
}
}
//allocate for the recipient dialog struct.
prdsRecipDlgStruct=(PGPclRecipientDialogStruct *)
calloc(sizeof(PGPclRecipientDialogStruct), 1);
pgpAssert(NULL != prdsRecipDlgStruct);
if(NULL == prdsRecipDlgStruct)
{
hrRet=E_OUTOFMEMORY;//we do not show user any error lest we might crash
goto send_cleanup;
}
//attempt to open the default key rings
pgpAssert(NULL != g_pgpContext);//we should have inited clientlib already
pgpErrRet=PGPclOpenDefaultKeyrings(g_pgpContext, kPGPOpenKeyDBFileOptions_Mutable,
&(prdsRecipDlgStruct->keydbOriginal));
pgpAssert(!IsPGPError(pgpErrRet));
if(IsPGPError(pgpErrRet))
{
pgpErrRet=PGPclOpenDefaultKeyrings(g_pgpContext, kPGPOpenKeyDBFileOptions_None,
&(prdsRecipDlgStruct->keydbOriginal));
pgpAssert(!IsPGPError(pgpErrRet));
if (IsPGPError(pgpErrRet))
{
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_OPEN_DEF_KEYRING, pgpErrRet);
goto send_cleanup;
}
}
//get a tls context for ourselves
pgpErrRet=PGPNewTLSContext(g_pgpContext, &tlsContext);
if(IsPGPError(pgpErrRet) || (NULL == tlsContext))
{
pgpAssert(FALSE);
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_INTERNAL);
goto send_cleanup;
}
//get the recipient selection dialog title from resource
bRet=SafeLoadString(IDS_RECIPIENTTITLE, &pszTitle);
pgpAssert(TRUE == bRet);//string is not found or some error condition
pgpAssert(NULL != pszTitle);//low memory ?
if((FALSE == bRet) || (NULL == pszTitle))
{
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_INTERNAL);
goto send_cleanup;
}
//let us fill in the struct now that the keyring is opened
prdsRecipDlgStruct->Version=kPGPCurrentRecipVersion;//DUKE ?? what the hell ?! -ssd
prdsRecipDlgStruct->hwndParent=hCtxtWindow;
prdsRecipDlgStruct->szTitle=pszTitle;
prdsRecipDlgStruct->context=g_pgpContext;//we inited this in InitPGP()
prdsRecipDlgStruct->tlsContext=tlsContext;
prdsRecipDlgStruct->dwOptions=kPGPclASCIIArmor;
prdsRecipDlgStruct->dwDisableFlags=kPGPclDisableWipeOriginal|
kPGPclDisableASCIIArmor|kPGPclDisableSelfDecryptingArchive;
//if we are encrypting to the recipients we need to find out more about
//the mail recipients. if we are only signing we dont care about the
//recipients
if(FALSE == bEncrypt)//clear signing
goto after_recipients_dialog;
//get a single array that has all the recipients of this message
bRet=PrepareMsgRecipientsArray(g_gtiLastTokenInfo.bstrMessageId, &ppszRecipients, dwNoOfRecips);
pgpAssert((TRUE == bRet) && (NULL != ppszRecipients) && (0 != dwNoOfRecips));
if((FALSE == bRet) || (NULL == ppszRecipients) || (0 == dwNoOfRecips))
{
iHandleTokenRet=DLL_HAN_NOT_HANDLED;//let the client show the error
goto send_cleanup;
}
//if we could not find the to recipient. NOTE: groupwise does not give us
//invalid or crossed out recipients by this method.
//if(0 == bstrToRecipients[0])
//{
// //we hope the send will fail as the recipient is missing. let
// //groupwise prompt its own error message for this.
// iHandleTokenRet=DLL_HAN_NOT_HANDLED;
// goto send_cleanup;
//}
//fill the recipients
prdsRecipDlgStruct->dwNumRecipients=dwNoOfRecips;
prdsRecipDlgStruct->szRecipientArray=ppszRecipients;
//if shift is pressed, force the dialog to pop.
if (GetAsyncKeyState(VK_SHIFT)&0x8000)
prdsRecipDlgStruct->dwDisableFlags|=kPGPclDisableAutoMode;
//finally call the client lib to do the dialog stuff-are we tired yet ? ;)
bRet=PGPclRecipientDialog(prdsRecipDlgStruct);
if(FALSE == bRet)//the user cancelled the operation
{
PgpGwTrace("User aborted the recipients dialog\n");
hrRet=E_ABORT;
goto send_cleanup;
}
//if keys for any recipients were imported from key server
//in the recipient dialog
if (NULL != prdsRecipDlgStruct->keydbAdded)
{
//create a new keyset from the added keys
pgpErrRet=PGPNewKeySet(prdsRecipDlgStruct->keydbAdded, &pgpksrKeySet);
pgpAssert(!IsPGPError(pgpErrRet));
pgpAssert(NULL != pgpksrKeySet);
if(IsPGPError(pgpErrRet) || (NULL == pgpksrKeySet))
{
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_INTERNAL);
goto send_cleanup;
}
//count the no of keys in the keyset
pgpErrRet=PGPCountKeys(pgpksrKeySet, &pgpuiNumOfKeys);
pgpAssert(!IsPGPError(pgpErrRet));
pgpAssert(0 < pgpuiNumOfKeys);
if(IsPGPError(pgpErrRet) || (0 == pgpuiNumOfKeys))//NOTE:zero keys may not be an error condition so change accordingly
{
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_INTERNAL);
goto send_cleanup;
}
//import the keyset
pgpErrRet=PGPclImportKeys(g_pgpContext, tlsContext, hCtxtWindow,
pgpksrKeySet, prdsRecipDlgStruct->keydbOriginal,
kPGPclNoDialogForValidSingletons);
//if there was an error and it was not because of the user aborting the import
//by choosing to cancel the operation
pgpAssert((kPGPError_UserAbort == pgpErrRet)?TRUE:!IsPGPError(pgpErrRet));
if((kPGPError_UserAbort != pgpErrRet) && (IsPGPError(pgpErrRet)))
{
hrRet=E_FAIL;
DisplayMessage(hCtxtWindow, IDS_E_INTERNAL);
goto send_cleanup;
}
}//end if keys were downloaded in the recipients dialog
after_recipients_dialog:
//get the message text
ZeroMemory(szTokenBuf, sizeof(szTokenBuf));
sprintf(szTokenBuf, "ItemGetText(\"%S\";10)", g_gtiLastTokenInfo.bstrMessageId);
hrRet=Publish(szTokenBuf, &bstrResult);
if(FAILED(hrRet))
{
pgpAssert(FALSE);
DisplayMessage(hCtxtWindow, IDS_E_GET_MESSAGE_TXT, hrRet);
goto send_cleanup;
}
//ansi convert the message text
pAnsiInputBuf=ConvertToAnsi(bstrResult);
pgpAssert(NULL != pAnsiInputBuf);
if(NULL == pAnsiInputBuf)
{
hrRet=E_OUTOFMEMORY;//we do not show user any error lest we might crash
goto send_cleanup;
}
//calculate the message length in bytes
iPlainTxtMsgLen=strlen(pAnsiInputBuf);
//encrypt and/or sign the message text as is required of us
pgpAssert(NULL != prdsRecipDlgStruct);
pgpAssert(!IsBadWritePtr(prdsRecipDlgStruct, sizeof(PGPclRecipientDialogStruct)));
pgpErrRet=EncryptSignBuffer(g_hInstance, hCtxtWindow, g_pgpContext,
tlsContext, CLIENTNAME, MODULEFILENAME, pAnsiInputBuf,
iPlainTxtMsgLen, prdsRecipDlgStruct, NULL,
&polOptions, (void **)&pOutBuf, &pgpsBufOutLen, bEncrypt, bSign,
FALSE, FALSE);
if(kPGPError_UserAbort == pgpErrRet)
{
PgpGwTrace("EncryptSignBuffer was aborted (license expired ?) !\n");
hrRet=E_ABORT;
iHandleTokenRet=DLL_HAN_NOT_HANDLED;//let the token go through
goto send_cleanup;
}
pgpAssert(!IsPGPError(pgpErrRet));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -