icqreceive.c

来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C语言 代码 · 共 586 行

C
586
字号
/*__________________________________________________________________________
 Copyright (C) 2002 PGP Corporation
 All rights reserved.
 
 $Id: ICQreceive.c,v 1.21 2002/11/13 20:50:09 wjb Exp $
__________________________________________________________________________*/
#include "precomp.h"

extern UINT	g_uOLEMessage;
extern UINT	g_uStreamMessage;

void SortOutbuffList(OUTBUFFLIST **pptextobl,
					 OUTBUFFLIST **ppiconobl)
{
	OUTBUFFLIST *index,*prev,*next;
	DWORD dwPos;

	*ppiconobl=NULL;
	index=*pptextobl;
	dwPos=0;
	prev=NULL;

	while(index!=NULL)
	{
		next=index->next;

		if(index->dwType!=0)
		{
			// Header/footer

			// Record position
			index->dwPos=dwPos;

			// Remove from obl
			if(prev!=NULL)
			{
				prev->next=index->next;
			}
			else
			{
				*pptextobl=index->next;
			}

			// Add to icon list
			if(*ppiconobl==NULL)
			{
				*ppiconobl=index;
				index->next=NULL;
			}
			else
			{
				// reverse order for insertion
				index->next=*ppiconobl;
				*ppiconobl=index;
			}
		}
		else
		{
			// Normal text
			prev=index;
			dwPos=dwPos+index->dwBuffSize;
		}
	index=next;
	}
}

//extern HANDLE hReceiveMutex;

BOOL DecryptRichEditText(WNDPROC lpOldProc,HWND hDlg,DWORD msg,WPARAM wParam,LPARAM lParam)
{
	BOOL bRetVal;

	bRetVal=FALSE;

	if(*((char *)lParam)!=0)
	{
		int szLen;

		szLen=strlen((char *)lParam);

		if(szLen>60) // It's gotta be to be PGP
		{
			BOOL FYEO;
			DWORD dwOutSize;
			char *pOutput;
			BOOL bRst;
			OUTBUFFLIST *pobl;
			DWORD dwSelPos;

			WaitForSingleObject(hGlobalMutex,INFINITE);

			pobl=NULL;
			dwSelPos=0;

			if(msg==EM_REPLACESEL)
			{
				SendMessage(hDlg,EM_GETSEL,(WPARAM)&dwSelPos,
					(LPARAM)NULL);
			}

			pOutput=NULL;
			FYEO=FALSE;

			bRst=PGPscDecryptBuffer(hDlg,"PGPicq",
				PGPsc,PGPtls,
				(char *)lParam,szLen,
				NULL,NULL,NULL,&pobl,TRUE);

			if((bRst)&&(pobl!=NULL))
			{
				OUTBUFFLIST *poblindex;

				poblindex=pobl;

				while(poblindex!=NULL)
				{
					if(poblindex->FYEO)
						FYEO=TRUE;

					poblindex=poblindex->next;
				}

				if(FYEO)
					//||(PGPscGetSecureViewerPref(PGPsc))) no need for this on ICQ
				{
					PGPscConcatOutBuffList(PGPsc,pobl,
							&pOutput,&dwOutSize,&FYEO);

					PGPscTempestViewer((void *)PGPsc,hDlg,
						pOutput,dwOutSize,FYEO);

					memset(pOutput,0x00,dwOutSize);
					PGPFreeData(pOutput);
				}
				else
				{
					PPLUGININFO plugin;
					OUTBUFFLIST *piconobl,*indexobl;

					piconobl=NULL;

					SortOutbuffList(&pobl,
						&piconobl);

					PGPscConcatOutBuffList(PGPsc,pobl,
							&pOutput,&dwOutSize,&FYEO);

					if(pOutput!=NULL)
					{
						DWORD nOleErr;

						plugin=GetPluginInfo(hDlg);

						lParam=(LPARAM)pOutput;

				//		CallWindowProc(lpOldProc, 
						SendMessage(hDlg, msg, wParam, lParam);

						nOleErr = OleInitialize(NULL);

						if ((nOleErr == S_OK) || (nOleErr == S_FALSE))
						{
							indexobl=piconobl;

							while(indexobl!=NULL)
							{
								int i,check;

								check=indexobl->dwPos;

								// Correct for RE returns vs PGP CRs
								for(i=0;i<check;i++)
								{
									if(pOutput[i]==10)
										indexobl->dwPos--;
								}

					//			if(indexobl->dwType==OBL_END)
					//			{
					//				while((indexobl->dwPos>=1)&&((pOutput[indexobl->dwPos-1]==10)||
					//					(pOutput[indexobl->dwPos-1]==13)))
					//					indexobl->dwPos--;
					//			}

	// Post a private message instead of calling OLE functions.
								PostMessage (hDlg, g_uOLEMessage, 
									(WPARAM)indexobl->dwType, 
									(LPARAM)dwSelPos+indexobl->dwPos);
	/*
								InsertRichOLE(plugin,
									indexobl->dwType,
									dwSelPos+indexobl->dwPos);
	*/
								indexobl=indexobl->next;
							}
							OleUninitialize();
						}

						memset(pOutput,0x00,dwOutSize);
						PGPFreeData(pOutput);
						pOutput=NULL;

						pOutput=NULL;

						PGPscConcatOutBuffList(PGPsc,piconobl,
							&pOutput,&dwOutSize,&FYEO);

						if(pOutput!=NULL)
						{
							memset(pOutput,0x00,dwOutSize);
							PGPFreeData(pOutput);
							pOutput=NULL;
						}

						bRetVal=TRUE;
					}
				}
			}

			ReleaseMutex(hGlobalMutex);
		}
	}

	return bRetVal;
}

typedef struct
{
	char *szREmsg;
	DWORD dwREmsg;
} RICHEDITMSG;

static RICHEDITMSG rem[]=
{{"EM_GETLIMITTEXT",		(WM_USER + 37)},
{"EM_POSFROMCHAR",			(WM_USER + 38)},
{"EM_CHARFROMPOS",			(WM_USER + 39)},
{"EM_SCROLLCARET",			(WM_USER + 49)},
{"EM_CANPASTE",				(WM_USER + 50)},
{"EM_DISPLAYBAND",			(WM_USER + 51)},
{"EM_EXGETSEL",				(WM_USER + 52)},
{"EM_EXLIMITTEXT",			(WM_USER + 53)},
{"EM_EXLINEFROMCHAR",		(WM_USER + 54)},
{"EM_EXSETSEL",				(WM_USER + 55)},
{"EM_FINDTEXT",				(WM_USER + 56)},
{"EM_FORMATRANGE",			(WM_USER + 57)},
{"EM_GETCHARFORMAT",		(WM_USER + 58)},
{"EM_GETEVENTMASK",			(WM_USER + 59)},
{"EM_GETOLEINTERFACE",		(WM_USER + 60)},
{"EM_GETPARAFORMAT",		(WM_USER + 61)},
{"EM_GETSELTEXT",			(WM_USER + 62)},
{"EM_HIDESELECTION",		(WM_USER + 63)},
{"EM_PASTESPECIAL",			(WM_USER + 64)},
{"EM_REQUESTRESIZE",		(WM_USER + 65)},
{"EM_SELECTIONTYPE",		(WM_USER + 66)},
{"EM_SETBKGNDCOLOR",		(WM_USER + 67)},
{"EM_SETCHARFORMAT",		(WM_USER + 68)},
{"EM_SETEVENTMASK",			(WM_USER + 69)},
{"EM_SETOLECALLBACK",		(WM_USER + 70)},
{"EM_SETPARAFORMAT",		(WM_USER + 71)},
{"EM_SETTARGETDEVICE",		(WM_USER + 72)},
{"EM_STREAMIN",				(WM_USER + 73)},
{"EM_STREAMOUT",			(WM_USER + 74)},
{"EM_GETTEXTRANGE",			(WM_USER + 75)},
{"EM_FINDWORDBREAK",		(WM_USER + 76)},
{"EM_SETOPTIONS",			(WM_USER + 77)},
{"EM_GETOPTIONS",			(WM_USER + 78)},
{"EM_FINDTEXTEX",			(WM_USER + 79)},
{"EM_GETWORDBREAKPROCEX",	(WM_USER + 80)},
{"EM_SETWORDBREAKPROCEX",	(WM_USER + 81)},
{"EM_SETUNDOLIMIT",			(WM_USER + 82)},
{"EM_REDO",					(WM_USER + 84)},
{"EM_CANREDO",				(WM_USER + 85)},
{"EM_GETUNDONAME",			(WM_USER + 86)},
{"EM_GETREDONAME",			(WM_USER + 87)},
{"EM_STOPGROUPTYPING",		(WM_USER + 88)},
{"EM_SETTEXTMODE",			(WM_USER + 89)},
{"EM_GETTEXTMODE",			(WM_USER + 90)},
{"EM_AUTOURLDETECT",		(WM_USER + 91)},
{"EM_GETAUTOURLDETECT",		(WM_USER + 92)},
{"EM_SETPALETTE",			(WM_USER + 93)},
{"EM_GETTEXTEX",			(WM_USER + 94)},
{"EM_GETTEXTLENGTHEX",		(WM_USER + 95)},
{"EM_SHOWSCROLLBAR",		(WM_USER + 96)},
{"EM_SETTEXTEX",			(WM_USER + 97)},
{"EM_SETPUNCTUATION",		(WM_USER + 100)},
{"EM_GETPUNCTUATION",		(WM_USER + 101)},
{"EM_SETWORDWRAPMODE",		(WM_USER + 102)},
{"EM_GETWORDWRAPMODE",		(WM_USER + 103)},
{"EM_SETIMECOLOR",			(WM_USER + 104)},
{"EM_GETIMECOLOR",			(WM_USER + 105)},
{"EM_SETIMEOPTIONS",		(WM_USER + 106)},
{"EM_GETIMEOPTIONS",		(WM_USER + 107)},
{"EM_CONVPOSITION", 		(WM_USER + 108)},
{"EM_SETLANGOPTIONS",		(WM_USER + 120)},
{"EM_GETLANGOPTIONS",		(WM_USER + 121)},
{"EM_GETIMECOMPMODE",		(WM_USER + 122)},
{"EM_FINDTEXTW",			(WM_USER + 123)},
{"EM_FINDTEXTEXW",			(WM_USER + 124)},
{"EM_RECONVERSION",			(WM_USER + 125)},
{"EM_SETIMEMODEBIAS",		(WM_USER + 126)},	
{"EM_GETIMEMODEBIAS",		(WM_USER + 127)},
{"EM_SETBIDIOPTIONS",		(WM_USER + 200)},
{"EM_GETBIDIOPTIONS",		(WM_USER + 201)},
{"EM_SETTYPOGRAPHYOPTIONS",	(WM_USER + 202)},
{"EM_GETTYPOGRAPHYOPTIONS",	(WM_USER + 203)},
{"EM_SETEDITSTYLE",			(WM_USER + 204)},
{"EM_GETEDITSTYLE",			(WM_USER + 205)},
{"EM_OUTLINE",              (WM_USER + 220)},
{"EM_GETSCROLLPOS",         (WM_USER + 221)},
{"EM_SETSCROLLPOS",        (WM_USER + 222)},
{"EM_SETFONTSIZE",          (WM_USER + 223)},
{"EM_GETZOOM",				(WM_USER + 224)},
{"EM_SETZOOM",				(WM_USER + 225)}};

typedef struct
{ 
	HWND hDlg;
	WNDPROC lpOldProc;
} STREAMMSG;

DWORD WINAPI
StreamMessageThreadRoutine (LPVOID lpvoid) 
{
	STREAMMSG *sm;
	WNDPROC lpOldProc;
	HWND hDlg;
	char *szText;
	DWORD dwTextLen;
	HWND hwnd1st,hwnd2nd;

	sm=(STREAMMSG *)lpvoid;

	hDlg=sm->hDlg;
	lpOldProc=sm->lpOldProc;

	// This is really screwed up. ICQ 2002A has two identical REs
	hwnd1st=FindWindowEx(GetParent(hDlg),NULL,"RichEdit20A",NULL);
	hwnd2nd=FindWindowEx(GetParent(hDlg),hwnd1st,"RichEdit20A",NULL);

	if((hwnd1st!=NULL)&&(hwnd2nd!=NULL))
	{
		if((IsWindowVisible(hwnd1st))&&(IsWindowVisible(hwnd2nd)))
		{
			// The second one is created 1st and obscured--don't mess with it
			if(hwnd1st==hDlg)
			{
				free(sm);
				ShowWindow(hDlg,SW_HIDE);
				return 0;
			}
		}
	}

	dwTextLen = SendMessage (hDlg, WM_GETTEXTLENGTH, 0, 0) + 1;

	szText = (char *)malloc(dwTextLen);

	if(szText!=NULL)
	{
		SendMessage(hDlg,WM_GETTEXT,(WPARAM)dwTextLen,(LPARAM)szText);
		szText[dwTextLen-1]=0;

		DecryptRichEditText(lpOldProc,hDlg,WM_SETTEXT,(WPARAM)1,(LPARAM)szText);

		memset(szText,0x00,dwTextLen);
		free(szText);
	}

	free(sm);

	SetWindowPos( hDlg,HWND_TOP,0,0,0,0,
			SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOSIZE);
 
	InvalidateRect(hDlg,NULL,TRUE);
	UpdateWindow(hDlg);

	return 0;
}

BOOL bFirstTime=FALSE;

LRESULT CALLBACK ReceiveWndProc(HWND hDlg, 
							 UINT msg,
							 WPARAM wParam, 
							 LPARAM lParam)
{
	WNDPROC lpOldProc;

	lpOldProc = (WNDPROC)GetProp( hDlg, "oldproc" );

	/* For testing since spy doesn't get these early msgs
	if((msg>=(WM_USER + 37))&&(msg<=(WM_USER + 225)))
	{
		DWORD rei;

		for(rei=0;rei<sizeof(rem)/sizeof(RICHEDITMSG);rei++)
		{
			if(rem[rei].dwREmsg==msg)
			{
				char *szTest;

				szTest=rem[rei].szREmsg;

				break;
			}
		}
	}*/

	if(msg==g_uOLEMessage)
	{
		InsertRichOLE(hDlg,
			(DWORD)wParam,
			(DWORD)lParam);
		return 0;
	}

	if((msg==g_uStreamMessage)&&(IsWindowVisible(hDlg)))
	{
		DWORD dwThreadID;
		STREAMMSG *sm;

		sm=(STREAMMSG *)malloc(sizeof(STREAMMSG));

		if(sm!=NULL)
		{
			sm->hDlg=hDlg;
			sm->lpOldProc=lpOldProc;

			// Spawn work thread
			CreateThread (NULL, 0, StreamMessageThreadRoutine, 
				(LPVOID)sm, 0, &dwThreadID);
		}

		return 0;
	}

	switch(msg)
	{
		case WM_CREATE:
		{
			BOOL bIsSend;
			PPLUGININFO plugin;
			HWND hwndMain,hwndICQ,hwndNick,hwndSend;
			HWND hwndBack,hwndTool,hwndSKMark;
			BOOL b2001b;

			plugin=GetPluginInfo(hDlg);

			bIsSend=IsSendMessageWindow(hDlg,
				 &hwndMain,
				 &hwndICQ,
				 &hwndNick,
				 &hwndSend,
				 &hwndSKMark,
				 &hwndTool,
				 &hwndBack,
				 &b2001b);

			if(!bIsSend)
			{
				bIsSend=IsSendMessageWindow2000a(hDlg,
					 &hwndMain,
					 &hwndICQ,
					 &hwndNick,
					 &hwndSend,
					 &hwndSKMark,
					 &hwndTool,
					 &hwndBack);

				if(bIsSend)
				{
					// Desubclass this, we don't want anything
					// to do with split window
					RemoveProp(hDlg, "oldproc");
					SetWindowLong(hDlg, GWL_WNDPROC, (DWORD) lpOldProc);

					FreePluginInfo(plugin);
					break;
				}
			}

			if(bIsSend)
			{
				// OOOPS! We're dealing with the wrong window here.
				// Switch em around!

				// Desubclass this window
				RemoveProp(hDlg, "oldproc");
				SetWindowLong(hDlg, GWL_WNDPROC, (DWORD) lpOldProc);

				// Reset the plugin info to new window
				plugin->hwndRichEdit=hDlg;
				plugin->hwndICQ=hwndICQ;
				plugin->hwndMain=hwndMain;
				plugin->hwndNick=hwndNick;
				plugin->hwndSend=hwndSend;
				plugin->hwndSKMark=hwndSKMark;
				plugin->hwndTool=hwndTool;
				plugin->hwndBack=hwndBack;
				plugin->b2001b=b2001b;

				plugin->SendID=GetDlgCtrlID(hwndSend);

				// Create the Send Key button
				InitSendKey(plugin);

				// Create the send message toolbar
				InitToolbar(plugin);

				InitGetMessageHook(&(plugin->hMsgHook));

				// Subclass the new send message window
				SetProp(hwndMain, "oldproc", 
					(HANDLE) GetWindowLong(hwndMain, GWL_WNDPROC)); 

				// Store the pointer to the plugin information
				SavePluginInfo(hwndMain, plugin); 

				SetWindowLong(hwndMain, GWL_WNDPROC, 
					(DWORD) SendMessageWndProc);
				break;
			}

			SetRichOLE(plugin,hDlg);
			break;
		}

		case WM_LBUTTONDBLCLK:
		{
			// Filter this out so user doesn't access the OLE
			// object bmps
			return 0;
		}

		case EM_SETOLECALLBACK:
		{
			return 0;
		}

		case EM_STREAMIN:
		{
			PostMessage(hDlg,g_uStreamMessage,0,0);
			break;
		}

		case EM_REPLACESEL:
		case WM_SETTEXT:
		{
			if(wParam==1)
			{
				wParam=0;
				break;
			}

			if(DecryptRichEditText(lpOldProc,hDlg,msg,wParam,lParam))
				return 0;

			break;
		}

		case WM_DESTROY:
		{
			PPLUGININFO plugin;

			plugin=GetPluginInfo(hDlg);

			FreePluginInfo(plugin);

			RemoveProp(hDlg, "oldproc");
			SetWindowLong(hDlg, GWL_WNDPROC, (DWORD) lpOldProc);
			break;
		}
	}

	return CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
}

/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

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